Notification summary
This commit is contained in:
parent
237ce498b7
commit
b27bb47007
@ -13,6 +13,7 @@
|
||||
"@snort/system": "workspace:*",
|
||||
"@snort/system-react": "workspace:*",
|
||||
"@snort/system-wasm": "workspace:*",
|
||||
"@snort/system-web": "workspace:*",
|
||||
"@szhsin/react-menu": "^3.3.1",
|
||||
"@types/use-sync-external-store": "^0.0.4",
|
||||
"@void-cat/api": "^1.0.4",
|
||||
@ -30,6 +31,7 @@
|
||||
"react-router-dom": "^6.5.0",
|
||||
"react-textarea-autosize": "^8.4.0",
|
||||
"react-twitter-embed": "^4.0.4",
|
||||
"recharts": "^2.8.0",
|
||||
"use-long-press": "^3.2.0",
|
||||
"use-sync-external-store": "^1.2.0",
|
||||
"uuid": "^9.0.0",
|
||||
|
@ -342,6 +342,11 @@
|
||||
<symbol id="shield-tick" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M9 11.5L11 13.5L15.5 8.99999M20 12C20 16.9084 14.646 20.4784 12.698 21.6149C12.4766 21.744 12.3659 21.8086 12.2097 21.8421C12.0884 21.8681 11.9116 21.8681 11.7903 21.8421C11.6341 21.8086 11.5234 21.744 11.302 21.6149C9.35396 20.4784 4 16.9084 4 12V7.21759C4 6.41808 4 6.01833 4.13076 5.6747C4.24627 5.37113 4.43398 5.10027 4.67766 4.88552C4.9535 4.64243 5.3278 4.50207 6.0764 4.22134L11.4382 2.21067C11.6461 2.13271 11.75 2.09373 11.857 2.07827C11.9518 2.06457 12.0482 2.06457 12.143 2.07827C12.25 2.09373 12.3539 2.13271 12.5618 2.21067L17.9236 4.22134C18.6722 4.50207 19.0465 4.64243 19.3223 4.88552C19.566 5.10027 19.7537 5.37113 19.8692 5.6747C20 6.01833 20 6.41808 20 7.21759V12Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</symbol>
|
||||
<symbol id="at-sign" viewBox="0 0 21 20" fill="none">
|
||||
<g>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.0453 1.07385C11.0306 0.603671 8.91602 0.82887 7.04549 1.71284C5.17495 2.5968 3.65845 4.08754 2.74257 5.94266C1.82669 7.79778 1.5653 9.90817 2.00091 11.9307C2.43651 13.9532 3.54348 15.7689 5.14183 17.0825C6.74018 18.3961 8.7359 19.1304 10.8045 19.166C12.8731 19.2015 14.8929 18.5363 16.5354 17.2784C16.9008 16.9986 16.9702 16.4755 16.6904 16.1101C16.4105 15.7447 15.8875 15.6754 15.5221 15.9552C14.1782 16.9844 12.5256 17.5287 10.8331 17.4995C9.14066 17.4704 7.5078 16.8697 6.20006 15.7949C4.89232 14.7201 3.98661 13.2346 3.63021 11.5798C3.27381 9.92499 3.48767 8.1983 4.23703 6.68048C4.98638 5.16265 6.22716 3.94296 7.7576 3.21971C9.28804 2.49647 11.0181 2.31221 12.6666 2.69691C14.315 3.08161 15.7848 4.01263 16.837 5.33858C17.8892 6.66453 18.462 8.30748 18.4621 10.0002V10.8335C18.4621 11.2755 18.2865 11.6994 17.9739 12.012C17.6614 12.3245 17.2374 12.5001 16.7954 12.5001C16.3534 12.5001 15.9295 12.3245 15.6169 12.012C15.3043 11.6994 15.1288 11.2755 15.1288 10.8335V6.6668C15.1288 6.20656 14.7557 5.83347 14.2954 5.83347C13.8353 5.83347 13.4622 6.2064 13.4621 6.66651C12.7657 6.14343 11.9001 5.83348 10.9621 5.83348C8.6609 5.83348 6.79542 7.69896 6.79542 10.0001C6.79542 12.3013 8.6609 14.1668 10.9621 14.1668C12.2022 14.1668 13.3157 13.6251 14.079 12.7654C14.186 12.9159 14.3061 13.0582 14.4384 13.1905C15.0635 13.8156 15.9114 14.1668 16.7954 14.1668C17.6795 14.1668 18.5273 13.8156 19.1524 13.1905C19.7776 12.5654 20.1288 11.7175 20.1288 10.8335V10.0001C20.1286 7.93119 19.4286 5.92319 18.1426 4.30257C16.8565 2.68195 15.0601 1.54404 13.0453 1.07385ZM13.4621 9.99665V10.0036C13.4602 11.3827 12.3416 12.5001 10.9621 12.5001C9.58138 12.5001 8.46209 11.3809 8.46209 10.0001C8.46209 8.61943 9.58138 7.50014 10.9621 7.50014C12.3416 7.50014 13.4602 8.61754 13.4621 9.99665Z" fill="currentColor"/>
|
||||
</g>
|
||||
</symbol>
|
||||
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 93 KiB |
@ -1,4 +1,6 @@
|
||||
import { UserProfileCache, UserRelaysCache, RelayMetricCache } from "@snort/system";
|
||||
import { SnortSystemDb } from "@snort/system-web";
|
||||
|
||||
import { EventInteractionCache } from "./EventInteractionCache";
|
||||
import { ChatCache } from "./ChatCache";
|
||||
import { Payments } from "./PaymentsCache";
|
||||
@ -6,9 +8,11 @@ import { GiftWrapCache } from "./GiftWrapCache";
|
||||
import { NotificationsCache } from "./Notifications";
|
||||
import { FollowsFeedCache } from "./FollowsFeed";
|
||||
|
||||
export const UserCache = new UserProfileCache();
|
||||
export const UserRelays = new UserRelaysCache();
|
||||
export const RelayMetrics = new RelayMetricCache();
|
||||
export const SystemDb = new SnortSystemDb();
|
||||
export const UserCache = new UserProfileCache(SystemDb.users);
|
||||
export const UserRelays = new UserRelaysCache(SystemDb.userRelays);
|
||||
export const RelayMetrics = new RelayMetricCache(SystemDb.relayMetrics);
|
||||
|
||||
export const Chats = new ChatCache();
|
||||
export const PaymentsCache = new Payments();
|
||||
export const InteractionCache = new EventInteractionCache();
|
||||
|
@ -1,6 +1,6 @@
|
||||
.reactions-modal .modal-body {
|
||||
padding: 24px 32px;
|
||||
background-color: #1b1b1b;
|
||||
background-color: var(--gray-superdark);
|
||||
border-radius: 16px;
|
||||
position: relative;
|
||||
min-height: 33vh;
|
||||
|
@ -34,7 +34,7 @@
|
||||
border-radius: 100px;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
padding: 10px 16px;
|
||||
padding: 6px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
|
@ -31,7 +31,7 @@ export const TabElement = ({ t, tab, setTab }: TabElementProps) => {
|
||||
const Tabs = ({ tabs, tab, setTab }: TabsProps) => {
|
||||
const horizontalScroll = useHorizontalScroll();
|
||||
return (
|
||||
<div className="tabs p" ref={horizontalScroll}>
|
||||
<div className="tabs" ref={horizontalScroll}>
|
||||
{tabs.map(t => (
|
||||
<TabElement tab={tab} setTab={setTab} t={t} />
|
||||
))}
|
||||
|
@ -52,3 +52,29 @@
|
||||
max-width: 100%;
|
||||
max-height: 300px; /* Cap images in notifications to 300px height */
|
||||
}
|
||||
|
||||
.summary-icon {
|
||||
padding: 4px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
color: var(--gray-light) !important;
|
||||
}
|
||||
|
||||
.summary-icon:not(.active):hover {
|
||||
background-color: var(--gray-dark);
|
||||
}
|
||||
|
||||
.summary-icon.active {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.summary-tooltip {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 16px;
|
||||
background: var(--gray-superdark);
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
import "./Notifications.css";
|
||||
import { useEffect, useMemo, useSyncExternalStore } from "react";
|
||||
import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
||||
import { EventExt, EventKind, NostrEvent, NostrLink, NostrPrefix, TaggedNostrEvent, parseZap } from "@snort/system";
|
||||
import { unwrap } from "@snort/shared";
|
||||
import { unixNow, unwrap } from "@snort/shared";
|
||||
import { useUserProfile } from "@snort/system-react";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Bar, BarChart, Tooltip, XAxis, YAxis } from "recharts";
|
||||
|
||||
import useLogin from "Hooks/useLogin";
|
||||
import { markNotificationsRead } from "Login";
|
||||
import { Notifications, UserCache } from "Cache";
|
||||
import { dedupe, findTag, orderDescending } from "SnortUtils";
|
||||
import { dedupe, findTag, orderAscending, orderDescending } from "SnortUtils";
|
||||
import Icon from "Icons/Icon";
|
||||
import ProfileImage from "Element/User/ProfileImage";
|
||||
import useModeration from "Hooks/useModeration";
|
||||
@ -20,6 +21,8 @@ import { formatShort } from "Number";
|
||||
import { LiveEvent } from "Element/LiveEvent";
|
||||
import ProfilePreview from "Element/User/ProfilePreview";
|
||||
import { getDisplayName } from "Element/User/DisplayName";
|
||||
import { Day } from "Const";
|
||||
import Tabs, { Tab } from "Element/Tabs";
|
||||
|
||||
function notificationContext(ev: TaggedNostrEvent) {
|
||||
switch (ev.kind) {
|
||||
@ -93,12 +96,175 @@ export default function NotificationsPage({ onClick }: { onClick?: (link: NostrL
|
||||
|
||||
return (
|
||||
<div className="main-content">
|
||||
<NotificationSummary evs={notifications as TaggedNostrEvent[]} />
|
||||
|
||||
{login.publicKey &&
|
||||
[...timeGrouped.entries()].map(([k, g]) => <NotificationGroup key={k} evs={g} onClick={onClick} />)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface StatSlot {
|
||||
time: string;
|
||||
reactions: number;
|
||||
reposts: number;
|
||||
quotes: number;
|
||||
mentions: number;
|
||||
zaps: number;
|
||||
}
|
||||
|
||||
const enum NotificationSummaryPeriod {
|
||||
Daily,
|
||||
Weekly,
|
||||
}
|
||||
|
||||
const enum NotificationSummaryFilter {
|
||||
Reactions = 1,
|
||||
Reposts = 2,
|
||||
Mentions = 4,
|
||||
Zaps = 8,
|
||||
All = 255,
|
||||
}
|
||||
|
||||
function NotificationSummary({ evs }: { evs: Array<TaggedNostrEvent> }) {
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
const [period, setPeriod] = useState(NotificationSummaryPeriod.Daily);
|
||||
const [filter, setFilter] = useState(NotificationSummaryFilter.All);
|
||||
|
||||
const periodTabs = [
|
||||
{
|
||||
value: NotificationSummaryPeriod.Daily,
|
||||
text: <FormattedMessage defaultMessage="Daily" />,
|
||||
},
|
||||
{
|
||||
value: NotificationSummaryPeriod.Weekly,
|
||||
text: <FormattedMessage defaultMessage="Weekly" />,
|
||||
},
|
||||
] as Array<Tab>;
|
||||
|
||||
const hasFlag = (v: number, f: NotificationSummaryFilter) => {
|
||||
return (v & f) > 0;
|
||||
};
|
||||
|
||||
const getWeek = (d: Date) => {
|
||||
const onejan = new Date(d.getFullYear(), 0, 1);
|
||||
const today = new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
||||
const dayOfYear = (today.getTime() - onejan.getTime() + 86400000) / 86400000;
|
||||
return Math.ceil(dayOfYear / 7);
|
||||
};
|
||||
|
||||
const stats = useMemo(() => {
|
||||
return orderAscending(evs)
|
||||
.filter(a => (period === NotificationSummaryPeriod.Daily ? a.created_at > unixNow() - 14 * Day : true))
|
||||
.reduce(
|
||||
(acc, v) => {
|
||||
const date = new Date(v.created_at * 1000);
|
||||
const key =
|
||||
period === NotificationSummaryPeriod.Daily
|
||||
? `${date.getMonth() + 1}/${date.getDate()}`
|
||||
: getWeek(date).toString();
|
||||
acc[key] ??= {
|
||||
time: key,
|
||||
reactions: 0,
|
||||
reposts: 0,
|
||||
quotes: 0,
|
||||
mentions: 0,
|
||||
zaps: 0,
|
||||
};
|
||||
|
||||
if (v.kind === EventKind.Reaction) {
|
||||
acc[key].reactions++;
|
||||
} else if (v.kind === EventKind.Repost) {
|
||||
acc[key].reposts++;
|
||||
} else if (v.kind === EventKind.ZapReceipt) {
|
||||
acc[key].zaps++;
|
||||
}
|
||||
if (v.kind === EventKind.TextNote) {
|
||||
acc[key].mentions++;
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, StatSlot>,
|
||||
);
|
||||
}, [evs, period]);
|
||||
|
||||
const filterIcon = (f: NotificationSummaryFilter, icon: string, iconActiveClass?: string) => {
|
||||
const active = hasFlag(filter, f);
|
||||
return (
|
||||
<div className={`summary-icon${active ? " active" : ""}`} onClick={() => setFilter(v => v ^ f)}>
|
||||
<Icon name={icon} className={active ? iconActiveClass : undefined} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex-column g12 p bb">
|
||||
<div className="flex f-space">
|
||||
<h2>
|
||||
<FormattedMessage defaultMessage="Summary" description="Notifications summary" />
|
||||
</h2>
|
||||
<div className="flex g8">
|
||||
{filterIcon(NotificationSummaryFilter.Reactions, "heart-solid", "text-heart")}
|
||||
{filterIcon(NotificationSummaryFilter.Zaps, "zap-solid", "text-zap")}
|
||||
{filterIcon(NotificationSummaryFilter.Reposts, "reverse-left", "text-repost")}
|
||||
{filterIcon(NotificationSummaryFilter.Mentions, "at-sign", "text-mention")}
|
||||
</div>
|
||||
</div>
|
||||
<Tabs tabs={periodTabs} tab={unwrap(periodTabs.find(a => a.value === period))} setTab={t => setPeriod(t.value)} />
|
||||
<div ref={ref}>
|
||||
<BarChart
|
||||
width={ref.current?.clientWidth}
|
||||
height={200}
|
||||
data={Object.values(stats)}
|
||||
margin={{ left: 0, right: 0 }}
|
||||
style={{ userSelect: "none" }}>
|
||||
<XAxis dataKey="time" />
|
||||
<YAxis />
|
||||
{hasFlag(filter, NotificationSummaryFilter.Reactions) && (
|
||||
<Bar dataKey="reactions" fill="var(--heart)" stackId="" />
|
||||
)}
|
||||
{hasFlag(filter, NotificationSummaryFilter.Reposts) && (
|
||||
<Bar dataKey="reposts" fill="var(--repost)" stackId="" />
|
||||
)}
|
||||
{hasFlag(filter, NotificationSummaryFilter.Mentions) && (
|
||||
<Bar dataKey="mentions" fill="var(--mention)" stackId="" />
|
||||
)}
|
||||
{hasFlag(filter, NotificationSummaryFilter.Zaps) && <Bar dataKey="zaps" fill="var(--zap)" stackId="" />}
|
||||
<Tooltip
|
||||
cursor={{ fill: "rgba(255,255,255,0.2)" }}
|
||||
content={({ active, payload }) => {
|
||||
if (active && payload && payload.length) {
|
||||
return (
|
||||
<div className="summary-tooltip">
|
||||
<div className="flex-column g12">
|
||||
<Icon name="heart-solid" className="text-heart" />
|
||||
{formatShort(payload.find(a => a.name === "reactions")?.value as number)}
|
||||
</div>
|
||||
<div className="flex-column g12">
|
||||
<Icon name="zap-solid" className="text-zap" />
|
||||
{formatShort(payload.find(a => a.name === "zaps")?.value as number)}
|
||||
</div>
|
||||
<div className="flex-column g12">
|
||||
<Icon name="reverse-left" className="text-repost" />
|
||||
{formatShort(payload.find(a => a.name === "reposts")?.value as number)}
|
||||
</div>
|
||||
<div className="flex-column g12">
|
||||
<Icon name="at-sign" className="text-mention" />
|
||||
{formatShort(payload.find(a => a.name === "mentions")?.value as number)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}}
|
||||
/>
|
||||
</BarChart>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function NotificationGroup({ evs, onClick }: { evs: Array<TaggedNostrEvent>; onClick?: (link: NostrLink) => void }) {
|
||||
const { ref, inView } = useInView({ triggerOnce: true });
|
||||
const { formatMessage } = useIntl();
|
||||
|
@ -328,6 +328,10 @@ export function orderDescending<T>(arr: Array<T & { created_at: number }>) {
|
||||
return arr.sort((a, b) => (b.created_at > a.created_at ? 1 : -1));
|
||||
}
|
||||
|
||||
export function orderAscending<T>(arr: Array<T & { created_at: number }>) {
|
||||
return arr.sort((a, b) => (b.created_at > a.created_at ? -1 : 1));
|
||||
}
|
||||
|
||||
export interface Magnet {
|
||||
dn?: string | string[];
|
||||
tr?: string | string[];
|
||||
|
@ -15,6 +15,8 @@
|
||||
--live: #f83838;
|
||||
--heart: #ef4444;
|
||||
--zap: #ff710a;
|
||||
--mention: #961ee1;
|
||||
--repost: #1ecbe1;
|
||||
--gray-superlight: #eee;
|
||||
--bg-secondary: #2a2a2a;
|
||||
--gray-light: #999;
|
||||
@ -137,6 +139,10 @@ code {
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.bb {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
background: var(--primary-gradient);
|
||||
}
|
||||
@ -149,6 +155,10 @@ code {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.p4 {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.p24 {
|
||||
padding: 24px;
|
||||
}
|
||||
@ -619,6 +629,38 @@ div.form-col {
|
||||
background-color: var(--success);
|
||||
}
|
||||
|
||||
.bg-zap {
|
||||
background-color: var(--zap);
|
||||
}
|
||||
|
||||
.bg-heart {
|
||||
background-color: var(--heart);
|
||||
}
|
||||
|
||||
.bg-mention {
|
||||
background-color: var(--mention);
|
||||
}
|
||||
|
||||
.bg-repost {
|
||||
background-color: var(--repost);
|
||||
}
|
||||
|
||||
.text-zap {
|
||||
color: var(--zap);
|
||||
}
|
||||
|
||||
.text-heart {
|
||||
color: var(--heart);
|
||||
}
|
||||
|
||||
.text-mention {
|
||||
color: var(--mention);
|
||||
}
|
||||
|
||||
.text-repost {
|
||||
color: var(--repost);
|
||||
}
|
||||
|
||||
.tweet {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -664,11 +706,6 @@ div.form-col {
|
||||
font-weight: 600;
|
||||
font-size: 26px;
|
||||
line-height: 36px;
|
||||
margin: 12px 0 0 0;
|
||||
}
|
||||
|
||||
.main-content .h4 {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.main-content .profile-preview {
|
||||
|
@ -42,7 +42,7 @@ import { SubscribeRoutes } from "Pages/subscribe";
|
||||
import ZapPoolPage from "Pages/ZapPool";
|
||||
import DebugPage from "Pages/Debug";
|
||||
import { db } from "Db";
|
||||
import { preload, RelayMetrics, UserCache, UserRelays } from "Cache";
|
||||
import { preload, RelayMetrics, SystemDb, UserCache, UserRelays } from "Cache";
|
||||
import { LoginStore } from "Login";
|
||||
import { SnortDeckLayout } from "Pages/DeckLayout";
|
||||
import FreeNostrAddressPage from "./Pages/FreeNostrAddressPage";
|
||||
@ -77,6 +77,7 @@ export const System = new NostrSystem({
|
||||
profileCache: UserCache,
|
||||
relayMetrics: RelayMetrics,
|
||||
queryOptimizer: WasmQueryOptimizer,
|
||||
db: SystemDb,
|
||||
authHandler: async (c, r) => {
|
||||
const { id } = LoginStore.snapshot();
|
||||
const pub = LoginStore.getPublisher(id);
|
||||
|
@ -42,6 +42,9 @@
|
||||
"/Xf4UW": {
|
||||
"defaultMessage": "Send anonymous usage metrics"
|
||||
},
|
||||
"/clOBU": {
|
||||
"defaultMessage": "Weekly"
|
||||
},
|
||||
"/d6vEc": {
|
||||
"defaultMessage": "Make your profile easier to find and share"
|
||||
},
|
||||
@ -704,6 +707,10 @@
|
||||
"PCSt5T": {
|
||||
"defaultMessage": "Preferences"
|
||||
},
|
||||
"PJeJFc": {
|
||||
"defaultMessage": "Summary",
|
||||
"description": "Notifications summary"
|
||||
},
|
||||
"PLSbmL": {
|
||||
"defaultMessage": "Your mnemonic phrase"
|
||||
},
|
||||
@ -1508,5 +1515,8 @@
|
||||
},
|
||||
"zwb6LR": {
|
||||
"defaultMessage": "<b>Mint:</b> {url}"
|
||||
},
|
||||
"zxvhnE": {
|
||||
"defaultMessage": "Daily"
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
"/PCavi": "Public",
|
||||
"/RD0e2": "Nostr uses digital signature technology to provide tamper proof notes which can safely be replicated to many relays to provide redundant storage of your content.",
|
||||
"/Xf4UW": "Send anonymous usage metrics",
|
||||
"/clOBU": "Weekly",
|
||||
"/d6vEc": "Make your profile easier to find and share",
|
||||
"/n5KSF": "{n} ms",
|
||||
"00LcfG": "Load more",
|
||||
@ -231,6 +232,7 @@
|
||||
"P7FD0F": "System (Default)",
|
||||
"P7nJT9": "Total today (UTC): {amount} sats",
|
||||
"PCSt5T": "Preferences",
|
||||
"PJeJFc": "Summary",
|
||||
"PLSbmL": "Your mnemonic phrase",
|
||||
"PaN7t3": "Preview on {site}",
|
||||
"PamNxw": "Unknown file header: {name}",
|
||||
@ -493,5 +495,6 @@
|
||||
"zjJZBd": "You're ready!",
|
||||
"zonsdq": "Failed to load LNURL service",
|
||||
"zvCDao": "Automatically show latest notes",
|
||||
"zwb6LR": "<b>Mint:</b> {url}"
|
||||
"zwb6LR": "<b>Mint:</b> {url}",
|
||||
"zxvhnE": "Daily"
|
||||
}
|
||||
|
25
packages/system-web/package.json
Normal file
25
packages/system-web/package.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "@snort/system-web",
|
||||
"version": "1.0.0",
|
||||
"description": "Web based components @snort/system",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"repository": "https://git.v0l.io/Kieran/snort",
|
||||
"author": "Kieran",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "rm -rf dist && tsc"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@snort/shared": "^1.0.6",
|
||||
"@snort/system": "^1.0.21",
|
||||
"dexie": "^3.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
import { DexieLike, DexieTableLike } from "@snort/shared";
|
||||
import { MetadataCache, RelayMetrics, UsersRelays } from ".";
|
||||
import { NostrEvent } from "../nostr";
|
||||
import { NostrEvent, MetadataCache, RelayMetrics, UsersRelays } from "@snort/system";
|
||||
import Dexie, { Table } from "dexie";
|
||||
|
||||
const NAME = "snort-system";
|
||||
const VERSION = 2;
|
||||
@ -12,13 +11,12 @@ const STORES = {
|
||||
events: "++id, pubkey, created_at",
|
||||
};
|
||||
|
||||
export class SnortSystemDb extends DexieLike {
|
||||
export class SnortSystemDb extends Dexie {
|
||||
ready = false;
|
||||
users!: DexieTableLike<MetadataCache>;
|
||||
relayMetrics!: DexieTableLike<RelayMetrics>;
|
||||
userRelays!: DexieTableLike<UsersRelays>;
|
||||
events!: DexieTableLike<NostrEvent>;
|
||||
dms!: DexieTableLike<NostrEvent>;
|
||||
users!: Table<MetadataCache>;
|
||||
relayMetrics!: Table<RelayMetrics>;
|
||||
userRelays!: Table<UsersRelays>;
|
||||
events!: Table<NostrEvent>;
|
||||
|
||||
constructor() {
|
||||
super(NAME);
|
18
packages/system-web/tsconfig.json
Normal file
18
packages/system-web/tsconfig.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src",
|
||||
"target": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"esModuleInterop": true,
|
||||
"noImplicitOverride": true,
|
||||
"jsx": "react-jsx",
|
||||
"strict": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSourceMap": true,
|
||||
"outDir": "dist",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"files": ["src/index.ts"]
|
||||
}
|
7
packages/system/src/cache/events.ts
vendored
7
packages/system/src/cache/events.ts
vendored
@ -1,10 +1,9 @@
|
||||
import { NostrEvent } from "nostr";
|
||||
import { db } from ".";
|
||||
import { FeedCache } from "@snort/shared";
|
||||
import { DexieTableLike, FeedCache } from "@snort/shared";
|
||||
|
||||
export class EventsCache extends FeedCache<NostrEvent> {
|
||||
constructor() {
|
||||
super("EventsCache", db.events);
|
||||
constructor(table?: DexieTableLike<NostrEvent>) {
|
||||
super("EventsCache", table);
|
||||
}
|
||||
|
||||
key(of: NostrEvent): string {
|
||||
|
14
packages/system/src/cache/index.ts
vendored
14
packages/system/src/cache/index.ts
vendored
@ -1,8 +1,5 @@
|
||||
import { FullRelaySettings, HexKey, NostrEvent, UserMetadata } from "..";
|
||||
import { hexToBech32, unixNowMs } from "@snort/shared";
|
||||
import { SnortSystemDb } from "./db";
|
||||
|
||||
export const db = new SnortSystemDb();
|
||||
import { hexToBech32, unixNowMs, DexieTableLike } from "@snort/shared";
|
||||
|
||||
export interface MetadataCache extends UserMetadata {
|
||||
/**
|
||||
@ -71,3 +68,12 @@ export function mapEventToProfile(ev: NostrEvent) {
|
||||
console.error("Failed to parse JSON", ev, e);
|
||||
}
|
||||
}
|
||||
|
||||
export interface SnortSystemDb {
|
||||
users: DexieTableLike<MetadataCache>;
|
||||
relayMetrics: DexieTableLike<RelayMetrics>;
|
||||
userRelays: DexieTableLike<UsersRelays>;
|
||||
events: DexieTableLike<NostrEvent>;
|
||||
|
||||
isAvailable(): Promise<boolean>;
|
||||
}
|
||||
|
8
packages/system/src/cache/relay-metric.ts
vendored
8
packages/system/src/cache/relay-metric.ts
vendored
@ -1,9 +1,9 @@
|
||||
import { db, RelayMetrics } from ".";
|
||||
import { FeedCache } from "@snort/shared";
|
||||
import { RelayMetrics } from ".";
|
||||
import { DexieTableLike, FeedCache } from "@snort/shared";
|
||||
|
||||
export class RelayMetricCache extends FeedCache<RelayMetrics> {
|
||||
constructor() {
|
||||
super("RelayMetrics", db.relayMetrics);
|
||||
constructor(table?: DexieTableLike<RelayMetrics>) {
|
||||
super("RelayMetrics", table);
|
||||
}
|
||||
|
||||
key(of: RelayMetrics): string {
|
||||
|
12
packages/system/src/cache/user-metadata.ts
vendored
12
packages/system/src/cache/user-metadata.ts
vendored
@ -1,12 +1,12 @@
|
||||
import { db, MetadataCache } from ".";
|
||||
import { fetchNip05Pubkey, FeedCache, LNURL } from "@snort/shared";
|
||||
import { MetadataCache } from ".";
|
||||
import { fetchNip05Pubkey, FeedCache, LNURL, DexieTableLike } from "@snort/shared";
|
||||
|
||||
export class UserProfileCache extends FeedCache<MetadataCache> {
|
||||
#zapperQueue: Array<{ pubkey: string; lnurl: string }> = [];
|
||||
#nip5Queue: Array<{ pubkey: string; nip05: string }> = [];
|
||||
|
||||
constructor() {
|
||||
super("UserCache", db.users);
|
||||
constructor(table?: DexieTableLike<MetadataCache>) {
|
||||
super("UserCache", table);
|
||||
this.#processZapperQueue();
|
||||
this.#processNip5Queue();
|
||||
}
|
||||
@ -24,10 +24,10 @@ export class UserProfileCache extends FeedCache<MetadataCache> {
|
||||
}
|
||||
|
||||
async search(q: string): Promise<Array<MetadataCache>> {
|
||||
if (db.ready) {
|
||||
if (this.table) {
|
||||
// on-disk cache will always have more data
|
||||
return (
|
||||
await db.users
|
||||
await this.table
|
||||
.where("npub")
|
||||
.startsWithIgnoreCase(q)
|
||||
.or("name")
|
||||
|
8
packages/system/src/cache/user-relays.ts
vendored
8
packages/system/src/cache/user-relays.ts
vendored
@ -1,9 +1,9 @@
|
||||
import { db, UsersRelays } from ".";
|
||||
import { FeedCache } from "@snort/shared";
|
||||
import { UsersRelays } from ".";
|
||||
import { DexieTableLike, FeedCache } from "@snort/shared";
|
||||
|
||||
export class UserRelaysCache extends FeedCache<UsersRelays> {
|
||||
constructor() {
|
||||
super("UserRelays", db.userRelays);
|
||||
constructor(table?: DexieTableLike<UsersRelays>) {
|
||||
super("UserRelays", table);
|
||||
}
|
||||
|
||||
key(of: UsersRelays): string {
|
||||
|
@ -16,8 +16,8 @@ import {
|
||||
UserProfileCache,
|
||||
UserRelaysCache,
|
||||
RelayMetricCache,
|
||||
db,
|
||||
UsersRelays,
|
||||
SnortSystemDb,
|
||||
} from ".";
|
||||
import { EventsCache } from "./cache/events";
|
||||
import { RelayCache } from "./gossip-model";
|
||||
@ -87,19 +87,21 @@ export class NostrSystem extends ExternalStore<SystemSnapshot> implements System
|
||||
relayMetrics?: FeedCache<RelayMetrics>;
|
||||
eventsCache?: FeedCache<NostrEvent>;
|
||||
queryOptimizer?: QueryOptimizer;
|
||||
db?: SnortSystemDb;
|
||||
}) {
|
||||
super();
|
||||
this.#handleAuth = props.authHandler;
|
||||
this.#relayCache = props.relayCache ?? new UserRelaysCache();
|
||||
this.#profileCache = props.profileCache ?? new UserProfileCache();
|
||||
this.#relayMetricsCache = props.relayMetrics ?? new RelayMetricCache();
|
||||
this.#eventsCache = props.eventsCache ?? new EventsCache();
|
||||
this.#relayCache = props.relayCache ?? new UserRelaysCache(props.db?.userRelays);
|
||||
this.#profileCache = props.profileCache ?? new UserProfileCache(props.db?.users);
|
||||
this.#relayMetricsCache = props.relayMetrics ?? new RelayMetricCache(props.db?.relayMetrics);
|
||||
this.#eventsCache = props.eventsCache ?? new EventsCache(props.db?.events);
|
||||
this.#queryOptimizer = props.queryOptimizer ?? DefaultQueryOptimizer;
|
||||
|
||||
this.#profileLoader = new ProfileLoaderService(this, this.#profileCache);
|
||||
this.#relayMetrics = new RelayMetricHandler(this.#relayMetricsCache);
|
||||
this.#cleanup();
|
||||
}
|
||||
|
||||
HandleAuth?: AuthHandler | undefined;
|
||||
|
||||
get ProfileLoader() {
|
||||
@ -122,7 +124,6 @@ export class NostrSystem extends ExternalStore<SystemSnapshot> implements System
|
||||
* Setup caches
|
||||
*/
|
||||
async Init() {
|
||||
db.ready = await db.isAvailable();
|
||||
const t = [
|
||||
this.#relayCache.preload(),
|
||||
this.#profileCache.preload(),
|
||||
|
353
yarn.lock
353
yarn.lock
@ -1376,6 +1376,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/runtime@npm:^7.1.2":
|
||||
version: 7.23.1
|
||||
resolution: "@babel/runtime@npm:7.23.1"
|
||||
dependencies:
|
||||
regenerator-runtime: ^0.14.0
|
||||
checksum: 0cd0d43e6e7dc7f9152fda8c8312b08321cda2f56ef53d6c22ebdd773abdc6f5d0a69008de90aa41908d00e2c1facb24715ff121274e689305c858355ff02c70
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.8.4":
|
||||
version: 7.22.11
|
||||
resolution: "@babel/runtime@npm:7.22.11"
|
||||
@ -2692,6 +2701,7 @@ __metadata:
|
||||
"@snort/system": "workspace:*"
|
||||
"@snort/system-react": "workspace:*"
|
||||
"@snort/system-wasm": "workspace:*"
|
||||
"@snort/system-web": "workspace:*"
|
||||
"@szhsin/react-menu": ^3.3.1
|
||||
"@types/debug": ^4.1.8
|
||||
"@types/jest": ^29.5.1
|
||||
@ -2735,6 +2745,7 @@ __metadata:
|
||||
react-router-dom: ^6.5.0
|
||||
react-textarea-autosize: ^8.4.0
|
||||
react-twitter-embed: ^4.0.4
|
||||
recharts: ^2.8.0
|
||||
source-map-loader: ^4.0.1
|
||||
terser-webpack-plugin: ^5.3.9
|
||||
tinybench: ^2.5.1
|
||||
@ -2799,6 +2810,17 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@snort/system-web@workspace:*, @snort/system-web@workspace:packages/system-web":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@snort/system-web@workspace:packages/system-web"
|
||||
dependencies:
|
||||
"@snort/shared": ^1.0.6
|
||||
"@snort/system": ^1.0.21
|
||||
dexie: ^3.2.4
|
||||
typescript: ^5.2.2
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@snort/system@^1.0.21, @snort/system@workspace:*, @snort/system@workspace:packages/system":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@snort/system@workspace:packages/system"
|
||||
@ -3161,6 +3183,75 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-array@npm:^3.0.3":
|
||||
version: 3.0.8
|
||||
resolution: "@types/d3-array@npm:3.0.8"
|
||||
checksum: d5a678f1dc3af05bc6beb675d59a11d9b2ad4ea59fb5b6c2b99980fec947d89a9562f3ac3a8d192a4f38152d3a4b9ee9cf4e2a30788eaacaed5de4a6da514e10
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-color@npm:*":
|
||||
version: 3.1.1
|
||||
resolution: "@types/d3-color@npm:3.1.1"
|
||||
checksum: 1fa67a6d11386c2727c942ab0ddffaca2289ba01d2f3cd0723afc78c291e9515dbdc6de082466d9e9c360d7c67ddbf313707456c0daa9aa14acb2d48cb3bcabb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-ease@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "@types/d3-ease@npm:3.0.0"
|
||||
checksum: 1be7c993643b5a08332e0ee146375a3845545d8deb423db5d152e0b061524385d2345ceccf968f75f605247b940dd3f9a144335fee2e7d935cddaf187afb7095
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-interpolate@npm:^3.0.1":
|
||||
version: 3.0.2
|
||||
resolution: "@types/d3-interpolate@npm:3.0.2"
|
||||
dependencies:
|
||||
"@types/d3-color": "*"
|
||||
checksum: 86a1c4853c70663cba970d5c57dca995f604a70684b17bc5ff3ba83ce4e2c13f0105af29bb383ee70c4ccb1920c0dd4aeb352ae8721864d4a503a110260b9b13
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-path@npm:*":
|
||||
version: 3.0.0
|
||||
resolution: "@types/d3-path@npm:3.0.0"
|
||||
checksum: af7f45ea912cddd794c03384baba856f11e1f9b57a49d05a66a61968dafaeb86e0e42394883118b9b8ccadce21a5f25b1f9a88ad05235e1dc6d24c3e34a379ff
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-scale@npm:^4.0.2":
|
||||
version: 4.0.5
|
||||
resolution: "@types/d3-scale@npm:4.0.5"
|
||||
dependencies:
|
||||
"@types/d3-time": "*"
|
||||
checksum: f462a3f2ec8767bb6762953ed65087b4037d9f8c57c84b1ffc62d55b7633975611e053c2f36cef063bf123196fbb5741b257760b2a745ede9544851f7d150d60
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-shape@npm:^3.1.0":
|
||||
version: 3.1.3
|
||||
resolution: "@types/d3-shape@npm:3.1.3"
|
||||
dependencies:
|
||||
"@types/d3-path": "*"
|
||||
checksum: ad17781ab4ce4b796954b86de7e14566c731726d39a1db7d73eaf50668a71e996d715450a0ff9f2720755e1b8643c3e88d47d45101a75c9d4ddbef51a636f6a0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-time@npm:*, @types/d3-time@npm:^3.0.0":
|
||||
version: 3.0.1
|
||||
resolution: "@types/d3-time@npm:3.0.1"
|
||||
checksum: 32b0c4d33574df167717f37d5d69f60fa1aeebb0218823239734a48e6a33024a7f5aadd079e94d833b42bfc0c3e2d9fa7d7ac93f75981f59ef2a46838d008a61
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-timer@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "@types/d3-timer@npm:3.0.0"
|
||||
checksum: 1ec86b3808de6ecfa93cfdf34254761069658af0cc1d9540e8353dbcba161cdf1296a0724187bd17433b2ff16563115fd20b85fc89d5e809ff28f9b1ab134b42
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/debug@npm:^4.1.8":
|
||||
version: 4.1.8
|
||||
resolution: "@types/debug@npm:4.1.8"
|
||||
@ -5010,6 +5101,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"classnames@npm:^2.2.5":
|
||||
version: 2.3.2
|
||||
resolution: "classnames@npm:2.3.2"
|
||||
checksum: 2c62199789618d95545c872787137262e741f9db13328e216b093eea91c85ef2bfb152c1f9e63027204e2559a006a92eb74147d46c800a9f96297ae1d9f96f4e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"clean-css@npm:^5.2.2":
|
||||
version: 5.3.2
|
||||
resolution: "clean-css@npm:5.3.2"
|
||||
@ -5553,6 +5651,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"css-unit-converter@npm:^1.1.1":
|
||||
version: 1.1.2
|
||||
resolution: "css-unit-converter@npm:1.1.2"
|
||||
checksum: 07888033346a5128f34dbe2f72884c966d24e9f29db24416dcde92860242490617ef9a178ac193a92f730834bbeea026cdc7027701d92ba9bbbe59db7a37eb2a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"css-what@npm:^6.0.1, css-what@npm:^6.1.0":
|
||||
version: 6.1.0
|
||||
resolution: "css-what@npm:6.1.0"
|
||||
@ -5675,6 +5780,99 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:^3.1.6":
|
||||
version: 3.2.4
|
||||
resolution: "d3-array@npm:3.2.4"
|
||||
dependencies:
|
||||
internmap: 1 - 2
|
||||
checksum: a5976a6d6205f69208478bb44920dd7ce3e788c9dceb86b304dbe401a4bfb42ecc8b04c20facde486e9adcb488b5d1800d49393a3f81a23902b68158e12cddd0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-color@npm:1 - 3":
|
||||
version: 3.1.0
|
||||
resolution: "d3-color@npm:3.1.0"
|
||||
checksum: 4931fbfda5d7c4b5cfa283a13c91a954f86e3b69d75ce588d06cde6c3628cebfc3af2069ccf225e982e8987c612aa7948b3932163ce15eb3c11cd7c003f3ee3b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-ease@npm:^3.0.1":
|
||||
version: 3.0.1
|
||||
resolution: "d3-ease@npm:3.0.1"
|
||||
checksum: 06e2ee5326d1e3545eab4e2c0f84046a123dcd3b612e68858219aa034da1160333d9ce3da20a1d3486d98cb5c2a06f7d233eee1bc19ce42d1533458bd85dedcd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-format@npm:1 - 3":
|
||||
version: 3.1.0
|
||||
resolution: "d3-format@npm:3.1.0"
|
||||
checksum: f345ec3b8ad3cab19bff5dead395bd9f5590628eb97a389b1dd89f0b204c7c4fc1d9520f13231c2c7cf14b7c9a8cf10f8ef15bde2befbab41454a569bd706ca2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:^3.0.1":
|
||||
version: 3.0.1
|
||||
resolution: "d3-interpolate@npm:3.0.1"
|
||||
dependencies:
|
||||
d3-color: 1 - 3
|
||||
checksum: a42ba314e295e95e5365eff0f604834e67e4a3b3c7102458781c477bd67e9b24b6bb9d8e41ff5521050a3f2c7c0c4bbbb6e187fd586daa3980943095b267e78b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-path@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "d3-path@npm:3.1.0"
|
||||
checksum: 2306f1bd9191e1eac895ec13e3064f732a85f243d6e627d242a313f9777756838a2215ea11562f0c7630c7c3b16a19ec1fe0948b1c82f3317fac55882f6ee5d8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-scale@npm:^4.0.2":
|
||||
version: 4.0.2
|
||||
resolution: "d3-scale@npm:4.0.2"
|
||||
dependencies:
|
||||
d3-array: 2.10.0 - 3
|
||||
d3-format: 1 - 3
|
||||
d3-interpolate: 1.2.0 - 3
|
||||
d3-time: 2.1.1 - 3
|
||||
d3-time-format: 2 - 4
|
||||
checksum: a9c770d283162c3bd11477c3d9d485d07f8db2071665f1a4ad23eec3e515e2cefbd369059ec677c9ac849877d1a765494e90e92051d4f21111aa56791c98729e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-shape@npm:^3.1.0":
|
||||
version: 3.2.0
|
||||
resolution: "d3-shape@npm:3.2.0"
|
||||
dependencies:
|
||||
d3-path: ^3.1.0
|
||||
checksum: de2af5fc9a93036a7b68581ca0bfc4aca2d5a328aa7ba7064c11aedd44d24f310c20c40157cb654359d4c15c3ef369f95ee53d71221017276e34172c7b719cfa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-time-format@npm:2 - 4":
|
||||
version: 4.1.0
|
||||
resolution: "d3-time-format@npm:4.1.0"
|
||||
dependencies:
|
||||
d3-time: 1 - 3
|
||||
checksum: 7342bce28355378152bbd4db4e275405439cabba082d9cd01946d40581140481c8328456d91740b0fe513c51ec4a467f4471ffa390c7e0e30ea30e9ec98fcdf4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:^3.0.0":
|
||||
version: 3.1.0
|
||||
resolution: "d3-time@npm:3.1.0"
|
||||
dependencies:
|
||||
d3-array: 2 - 3
|
||||
checksum: 613b435352a78d9f31b7f68540788186d8c331b63feca60ad21c88e9db1989fe888f97f242322ebd6365e45ec3fb206a4324cd4ca0dfffa1d9b5feb856ba00a7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d3-timer@npm:^3.0.1":
|
||||
version: 3.0.1
|
||||
resolution: "d3-timer@npm:3.0.1"
|
||||
checksum: 1cfddf86d7bca22f73f2c427f52dfa35c49f50d64e187eb788dcad6e927625c636aa18ae4edd44d084eb9d1f81d8ca4ec305dae7f733c15846a824575b789d73
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dargs@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "dargs@npm:7.0.0"
|
||||
@ -5728,6 +5926,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"decimal.js-light@npm:^2.4.1":
|
||||
version: 2.5.1
|
||||
resolution: "decimal.js-light@npm:2.5.1"
|
||||
checksum: f5a2c7eac1c4541c8ab8a5c8abea64fc1761cefc7794bd5f8afd57a8a78d1b51785e0c4e4f85f4895a043eaa90ddca1edc3981d1263eb6ddce60f32bf5fe66c9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"decimal.js@npm:^10.4.2":
|
||||
version: 10.4.3
|
||||
resolution: "decimal.js@npm:10.4.3"
|
||||
@ -5947,6 +6152,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dom-helpers@npm:^3.4.0":
|
||||
version: 3.4.0
|
||||
resolution: "dom-helpers@npm:3.4.0"
|
||||
dependencies:
|
||||
"@babel/runtime": ^7.1.2
|
||||
checksum: 58d9f1c4a96daf77eddc63ae1236b826e1cddd6db66bbf39b18d7e21896d99365b376593352d52a60969d67fa4a8dbef26adc1439fa2c1b355efa37cacbaf637
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dom-serializer@npm:^1.0.1":
|
||||
version: 1.4.1
|
||||
resolution: "dom-serializer@npm:1.4.1"
|
||||
@ -6490,7 +6704,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.4":
|
||||
"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.1, eventemitter3@npm:^4.0.4":
|
||||
version: 4.0.7
|
||||
resolution: "eventemitter3@npm:4.0.7"
|
||||
checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374
|
||||
@ -6605,6 +6819,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-equals@npm:^5.0.0":
|
||||
version: 5.0.1
|
||||
resolution: "fast-equals@npm:5.0.1"
|
||||
checksum: fbb3b6a74f3a0fa930afac151ff7d01639159b4fddd2678b5d50708e0ba38e9ec14602222d10dadb8398187342692c04fbef5a62b1cfcc7942fe03e754e064bc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0":
|
||||
version: 3.3.1
|
||||
resolution: "fast-glob@npm:3.3.1"
|
||||
@ -7689,6 +7910,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"internmap@npm:1 - 2":
|
||||
version: 2.0.3
|
||||
resolution: "internmap@npm:2.0.3"
|
||||
checksum: 7ca41ec6aba8f0072fc32fa8a023450a9f44503e2d8e403583c55714b25efd6390c38a87161ec456bf42d7bc83aab62eb28f5aef34876b1ac4e60693d5e1d241
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"interpret@npm:^1.0.0":
|
||||
version: 1.4.0
|
||||
resolution: "interpret@npm:1.4.0"
|
||||
@ -9058,7 +9286,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.20, lodash@npm:^4.17.21":
|
||||
"lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21":
|
||||
version: 4.17.21
|
||||
resolution: "lodash@npm:4.17.21"
|
||||
checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7
|
||||
@ -10879,6 +11107,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"postcss-value-parser@npm:^3.3.0":
|
||||
version: 3.3.1
|
||||
resolution: "postcss-value-parser@npm:3.3.1"
|
||||
checksum: 62cd26e1cdbcf2dcc6bcedf3d9b409c9027bc57a367ae20d31dd99da4e206f730689471fd70a2abe866332af83f54dc1fa444c589e2381bf7f8054c46209ce16
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0":
|
||||
version: 4.2.0
|
||||
resolution: "postcss-value-parser@npm:4.2.0"
|
||||
@ -11040,7 +11275,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
|
||||
"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
|
||||
version: 15.8.1
|
||||
resolution: "prop-types@npm:15.8.1"
|
||||
dependencies:
|
||||
@ -11217,7 +11452,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-is@npm:^16.13.1, react-is@npm:^16.7.0":
|
||||
"react-is@npm:^16.10.2, react-is@npm:^16.13.1, react-is@npm:^16.7.0":
|
||||
version: 16.13.1
|
||||
resolution: "react-is@npm:16.13.1"
|
||||
checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f
|
||||
@ -11231,6 +11466,25 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-lifecycles-compat@npm:^3.0.4":
|
||||
version: 3.0.4
|
||||
resolution: "react-lifecycles-compat@npm:3.0.4"
|
||||
checksum: a904b0fc0a8eeb15a148c9feb7bc17cec7ef96e71188280061fc340043fd6d8ee3ff233381f0e8f95c1cf926210b2c4a31f38182c8f35ac55057e453d6df204f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-resize-detector@npm:^8.0.4":
|
||||
version: 8.1.0
|
||||
resolution: "react-resize-detector@npm:8.1.0"
|
||||
dependencies:
|
||||
lodash: ^4.17.21
|
||||
peerDependencies:
|
||||
react: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
checksum: 45e6b87ea7331406bed2a806d0cea98c1467d53a7cfcdf19c2dd55a3460047917d3b175d9cceea6f314b65eb54858cbb981acffd007d67aa16388e517dafb83e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-router-dom@npm:^6.5.0":
|
||||
version: 6.15.0
|
||||
resolution: "react-router-dom@npm:6.15.0"
|
||||
@ -11255,6 +11509,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-smooth@npm:^2.0.2":
|
||||
version: 2.0.4
|
||||
resolution: "react-smooth@npm:2.0.4"
|
||||
dependencies:
|
||||
fast-equals: ^5.0.0
|
||||
react-transition-group: 2.9.0
|
||||
peerDependencies:
|
||||
prop-types: ^15.6.0
|
||||
react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
checksum: 21731e2f9ebc9594eae0f0d875526185392a87c00abf013c9769ed642a4077b62c04c1001b2527a196aabafb87af208f6c7107db674538c4bb95c253ed123447
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-textarea-autosize@npm:^8.4.0":
|
||||
version: 8.5.3
|
||||
resolution: "react-textarea-autosize@npm:8.5.3"
|
||||
@ -11268,6 +11536,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-transition-group@npm:2.9.0":
|
||||
version: 2.9.0
|
||||
resolution: "react-transition-group@npm:2.9.0"
|
||||
dependencies:
|
||||
dom-helpers: ^3.4.0
|
||||
loose-envify: ^1.4.0
|
||||
prop-types: ^15.6.2
|
||||
react-lifecycles-compat: ^3.0.4
|
||||
peerDependencies:
|
||||
react: ">=15.0.0"
|
||||
react-dom: ">=15.0.0"
|
||||
checksum: d8c9e50aabdc2cfc324e5cdb0ad1c6eecb02e1c0cd007b26d5b30ccf49015e900683dd489348c71fba4055858308d9ba7019e0d37d0e8d37bd46ed098788f670
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-transition-state@npm:^1.1.5":
|
||||
version: 1.1.5
|
||||
resolution: "react-transition-state@npm:1.1.5"
|
||||
@ -11421,6 +11704,36 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"recharts-scale@npm:^0.4.4":
|
||||
version: 0.4.5
|
||||
resolution: "recharts-scale@npm:0.4.5"
|
||||
dependencies:
|
||||
decimal.js-light: ^2.4.1
|
||||
checksum: e970377190a610e684a32c7461c7684ac3603c2e0ac0020bbba1eea9d099b38138143a8e80bf769bb49c0b7cecf22a2f5c6854885efed2d56f4540d4aa7052bd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"recharts@npm:^2.8.0":
|
||||
version: 2.8.0
|
||||
resolution: "recharts@npm:2.8.0"
|
||||
dependencies:
|
||||
classnames: ^2.2.5
|
||||
eventemitter3: ^4.0.1
|
||||
lodash: ^4.17.19
|
||||
react-is: ^16.10.2
|
||||
react-resize-detector: ^8.0.4
|
||||
react-smooth: ^2.0.2
|
||||
recharts-scale: ^0.4.4
|
||||
reduce-css-calc: ^2.1.8
|
||||
victory-vendor: ^36.6.8
|
||||
peerDependencies:
|
||||
prop-types: ^15.6.0
|
||||
react: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
|
||||
checksum: 4638bd5c6c2af8f5c79de5e13cce0e38f06e0bbb0a3c4df27a9b12632fd72c0a0604c8246f55e830f323dfa84a3da7cb2634c2243bb9c775d899fd71f9d4c87a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rechoir@npm:^0.6.2":
|
||||
version: 0.6.2
|
||||
resolution: "rechoir@npm:0.6.2"
|
||||
@ -11439,6 +11752,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"reduce-css-calc@npm:^2.1.8":
|
||||
version: 2.1.8
|
||||
resolution: "reduce-css-calc@npm:2.1.8"
|
||||
dependencies:
|
||||
css-unit-converter: ^1.1.1
|
||||
postcss-value-parser: ^3.3.0
|
||||
checksum: 8fd27c06c4b443b84749a69a8b97d10e6ec7d142b625b41923a8807abb22b9e37e44df14e26cc606a802957be07bdce5e8ee2976a6952a7b438a7727007101e9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"regenerate-unicode-properties@npm:^10.1.0":
|
||||
version: 10.1.0
|
||||
resolution: "regenerate-unicode-properties@npm:10.1.0"
|
||||
@ -13401,6 +13724,28 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"victory-vendor@npm:^36.6.8":
|
||||
version: 36.6.11
|
||||
resolution: "victory-vendor@npm:36.6.11"
|
||||
dependencies:
|
||||
"@types/d3-array": ^3.0.3
|
||||
"@types/d3-ease": ^3.0.0
|
||||
"@types/d3-interpolate": ^3.0.1
|
||||
"@types/d3-scale": ^4.0.2
|
||||
"@types/d3-shape": ^3.1.0
|
||||
"@types/d3-time": ^3.0.0
|
||||
"@types/d3-timer": ^3.0.0
|
||||
d3-array: ^3.1.6
|
||||
d3-ease: ^3.0.1
|
||||
d3-interpolate: ^3.0.1
|
||||
d3-scale: ^4.0.2
|
||||
d3-shape: ^3.1.0
|
||||
d3-time: ^3.0.0
|
||||
d3-timer: ^3.0.1
|
||||
checksum: 55800076dfa6abedf7758840986a302778a904678d4b66fe47d977c48b6f9484276b780871e6e5105b31c1eb936e9f1331ee39afcc2869bf65ceb7d456143172
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vinyl-file@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "vinyl-file@npm:3.0.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user