Compare commits

...

1 Commits

Author SHA1 Message Date
k e55b5195a9 release: v0.1.1 2024-06-24 05:14:52 +02:00
41 changed files with 399 additions and 368 deletions
+12 -2
View File
@@ -1,6 +1,6 @@
# Changelog
## v. 0.1.1 - WIP
## v. 0.1.1 | 849240 - 2024/06/24
### Parser
@@ -18,6 +18,10 @@
- Added highlight effect to a legend by darkening the color of all the other series on the chart while hovering it with the mouse
- Added an API link in the legend for each dataset where applicable (when isn't generated locally)
- Save fullscreen preference in local storage and url
- Improved resize bar on desktop
- Changed resize button logo
- Changed the share button to visible on small screen too
- Improved share screen
- Fixed time range shifting not being the one in url params or saved in local storage
- Fixed time range shifting on series toggling via the legend
- Fixed time range shifting on fullscreen
@@ -27,10 +31,16 @@
- History
- Changed background for the sticky dates from blur to a solid color as it didn't appear properly in Firefox
- Build
- Added lazy loads to have split chunks after build
- Tried to add lazy loads to have split chunks after build, to have much faster load times and they worked great ! But they completely broke Safari on iOS, we can't have nice things
- Removed many libraries and did some things manually instead to improve build size
- Strip
- Temporarily removed the Home button on the strip bar on desktop as there is no landing page yet
- Settings
- Add version
- PWA
- Fixed background update
- Changed update check frequency to 1 minute (~1kb to fetch every minute which is very reasonable)
- Added a nice banner to ask the user to install the update
- Misc
- Removed tracker even though it was a very privacy friendly as it appeared to not be working properly
+1 -1
View File
@@ -2,7 +2,7 @@
## Description
TLDR: FOSS [glassnode](https://glassnode.com).
TLDR: Free, open source, verifiable and self-hostable Bitcoin on-chain data generator and visualizer
Satonomics is an open-source suite of tools that computes, distributes, and displays on-chain data, making it freely available for anyone to use.
+9 -2
View File
@@ -6,5 +6,12 @@ A web app to view the generated datasets in various charts.
## Requirements
- `node`
- `pnpm`
- Install `node`
- Install `pnpm`
- If using `cloudflare`, add cache rule to bypass the cache for `/sw.js`
## Deployment
```bash
pnpm deploy-prod
```
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "satonomics",
"description": "Satoshi Economics",
"version": "0.1.0",
"version": "0.1.1",
"license": "MIT",
"type": "module",
"scripts": {
+13 -12
View File
@@ -2368,11 +2368,11 @@ packages:
/@types/node-forge@1.3.11:
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
dependencies:
'@types/node': 20.14.7
'@types/node': 20.14.8
dev: true
/@types/node@20.14.7:
resolution: {integrity: sha512-uTr2m2IbJJucF3KUxgnGOZvYbN0QgkGyWxG6973HCpMYFy2KfcgYuIwkJQMQkt1VbBMlvWRbpshFTLxnxCZjKQ==}
/@types/node@20.14.8:
resolution: {integrity: sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==}
dependencies:
undici-types: 5.26.5
dev: true
@@ -2393,7 +2393,7 @@ packages:
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
requiresBuild: true
dependencies:
'@types/node': 20.14.7
'@types/node': 20.14.8
dev: true
optional: true
@@ -2656,7 +2656,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001636
electron-to-chromium: 1.4.808
electron-to-chromium: 1.4.810
node-releases: 2.0.14
update-browserslist-db: 1.0.16(browserslist@4.23.1)
dev: true
@@ -2793,7 +2793,7 @@ packages:
engines: {node: '>=12.13.0'}
hasBin: true
dependencies:
'@types/node': 20.14.7
'@types/node': 20.14.8
escape-string-regexp: 4.0.0
is-wsl: 2.2.0
lighthouse-logger: 1.4.2
@@ -3118,8 +3118,8 @@ packages:
jake: 10.9.1
dev: true
/electron-to-chromium@1.4.808:
resolution: {integrity: sha512-0ItWyhPYnww2VOuCGF4s1LTfbrdAV2ajy/TN+ZTuhR23AHI6rWHCrBXJ/uxoXOvRRqw8qjYVrG81HFI7x/2wdQ==}
/electron-to-chromium@1.4.810:
resolution: {integrity: sha512-Kaxhu4T7SJGpRQx99tq216gCq2nMxJo+uuT6uzz9l8TVN2stL7M06MIIXAtr9jsrLs2Glflgf2vMQRepxawOdQ==}
dev: true
/emoji-regex@8.0.0:
@@ -3182,7 +3182,7 @@ packages:
is-string: 1.0.7
is-typed-array: 1.1.13
is-weakref: 1.0.2
object-inspect: 1.13.1
object-inspect: 1.13.2
object-keys: 1.1.1
object.assign: 4.1.5
regexp.prototype.flags: 1.5.2
@@ -4461,8 +4461,9 @@ packages:
engines: {node: '>= 6'}
dev: true
/object-inspect@1.13.1:
resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
/object-inspect@1.13.2:
resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==}
engines: {node: '>= 0.4'}
dev: true
/object-keys@1.1.1:
@@ -5206,7 +5207,7 @@ packages:
call-bind: 1.0.7
es-errors: 1.3.0
get-intrinsic: 1.2.4
object-inspect: 1.13.1
object-inspect: 1.13.2
dev: true
/signal-exit@3.0.7:
@@ -1,4 +1,4 @@
import type { Generate } from "lean-qr";
import { generate } from "lean-qr";
import { chartState } from "/src/scripts/lightweightCharts/chart/state";
import { setTimeScale } from "/src/scripts/lightweightCharts/chart/time";
@@ -14,45 +14,43 @@ export function Actions({
qrcode: RWS<string>;
fullscreen?: RWS<boolean>;
}) {
const leanQRGenerate = createRWS<Generate | undefined>(undefined);
onMount(() => {
import("lean-qr").then((leanQR) => {
leanQRGenerate.set(() => leanQR.generate);
});
});
return (
<div class="flex space-x-1">
<Button
icon={() => IconTablerMaximize}
onClick={() => {
const range = chartState.range;
<Show when={fullscreen}>
{(fullscreen) => (
<Button
title="Toggle fullscreen"
icon={() =>
fullscreen()()
? IconTablerLayoutSidebarLeftExpand
: IconTablerLayoutSidebarRightExpand
}
onClick={() => {
const range = chartState.range;
fullscreen?.set((b) => !b);
fullscreen().set((b) => !b);
setTimeScale(range);
}}
classes="hidden md:block"
/>
)}
</Show>
setTimeScale(range);
}}
classes="hidden md:block"
/>
<Button
title="Share"
icon={() => IconTablerShare}
disabled={() => !leanQRGenerate()}
onClick={() => {
let generate = leanQRGenerate();
if (generate) {
qrcode.set(() =>
generate(document.location.href).toDataURL({
on: [0xff, 0xff, 0xff, 0xff],
off: [0x00, 0x00, 0x00, 0x00],
}),
);
}
qrcode.set(() =>
generate(document.location.href).toDataURL({
on: [0xff, 0xff, 0xff, 0xff],
off: [0x00, 0x00, 0x00, 0x00],
}),
);
}}
classes="hidden md:block"
/>
<Button
title="Favorite"
colors={() =>
presets.selected().isFavorite()
? "text-amber-500 bg-amber-500/15 hover:bg-amber-500/30"
@@ -70,12 +68,14 @@ export function Actions({
}
function Button({
title,
icon,
colors,
onClick,
disabled,
classes,
}: {
title: string;
icon: () => ValidComponent;
colors?: () => string;
onClick: VoidFunction;
@@ -84,6 +84,7 @@ function Button({
}) {
return (
<button
title={title}
disabled={disabled?.()}
class={classPropToString([
colors?.() || (disabled?.() ? "" : "hover:bg-orange-200/15"),
@@ -105,6 +105,7 @@ export function Legend({
<Show when={legend.url}>
{(url) => (
<a
title="Dataset"
class="-my-0.5 !-mr-1 inline-flex size-6 flex-col overflow-hidden rounded-full border border-orange-200/5 bg-orange-200 bg-opacity-5 p-1 pl-0.5 hover:bg-opacity-30"
style={{
opacity: legend.visible() ? 1 : 0.5,
@@ -3,6 +3,7 @@ import { createRWS } from "/src/solid/rws";
import { Box } from "../box";
import { Actions } from "./components/actions";
import { Chart } from "./components/chart";
import { Legend } from "./components/legend";
import { TimeScale } from "./components/timeScale";
import { Title } from "./components/title";
@@ -26,12 +27,6 @@ export function ChartFrame({
}) {
const legend = createRWS<PresetLegend>([]);
const Chart = lazy(() =>
import("./components/chart").then((d) => ({
default: d.Chart,
})),
);
return (
<div
class={classPropToString([
@@ -61,6 +56,7 @@ export function ChartFrame({
<Chart
activeResources={activeResources}
datasets={datasets}
// fetchedDatasets={fetchedDatasets}
legendSetter={legend.set}
presets={presets}
/>
@@ -1,3 +1,5 @@
import { version } from "/src/../package.json";
import { Header } from "./header";
export function SettingsFrame({
@@ -30,6 +32,8 @@ export function SettingsFrame({
<span class="slider"></span>
</label>
</div>
<hr class="border-t border-orange-200/20" />
<p>Version: {version}</p>
</div>
</div>
</div>
+24 -6
View File
@@ -2,16 +2,34 @@ export function Qrcode({ qrcode }: { qrcode: RWS<string> }) {
return (
<Show when={qrcode()}>
<div
class="absolute inset-0 z-50 flex h-full w-full items-center justify-center bg-black"
class="absolute inset-0 z-50 flex size-full justify-center bg-black"
onClick={() => {
qrcode.set("");
}}
>
<img
class="aspect-square max-h-full grow object-contain"
src={qrcode()}
style={{ "image-rendering": "pixelated" }}
/>
<div class="flex size-full max-w-md flex-col items-center justify-center bg-black px-8 py-16 text-lg">
<p class="pb-16 text-2xl font-bold">Share</p>
<div class="flex min-h-0 w-full flex-1 flex-col">
<p>You can scan the following QR Code with a phone:</p>
<img
class="aspect-square min-h-0 flex-1 grow object-contain"
src={qrcode()}
style={{ "image-rendering": "pixelated" }}
/>
</div>
<div>
<p>Or if you prefer you can send this link instead:</p>
<a
onClick={(event) => {
event.stopPropagation();
}}
href={location.href}
>
{location.href}
</a>
</div>
</div>
</div>
</Show>
);
@@ -1,7 +1,7 @@
export function AnchorLogo() {
return (
<a
class="inline-flex justify-center rounded-lg bg-gradient-to-br from-orange-500 to-orange-800 p-4"
class="inline-flex justify-center rounded-lg bg-gradient-to-br from-orange-500 to-orange-800 p-4 text-white"
href="https://app.satonomics.xyz"
title="Reload"
>
@@ -1,10 +0,0 @@
import { Button } from "./button";
export function ButtonRefresh() {
return (
<Button title="Refresh" onClick={() => document.location.reload()}>
<IconTablerRefreshAlert class="absolute size-5 animate-ping text-orange-400" />
<IconTablerRefreshAlert class="relative size-5 text-orange-300" />
</Button>
);
}
@@ -18,8 +18,12 @@ export function Clickable({
<Dynamic
component={onClick ? "button" : href ? "a" : "span"}
class={classPropToString([
selected?.() ? "bg-orange-200/10" : "opacity-50 hover:bg-orange-200/10",
"select-none rounded-lg p-3.5 hover:text-orange-400 hover:opacity-100 active:scale-90",
!href
? selected?.()
? "bg-orange-200/10"
: "text-orange-100/50"
: "text-orange-300/70",
"select-none rounded-lg p-3.5 hover:bg-orange-200/10 hover:text-orange-400 hover:opacity-100 active:scale-90",
])}
title={title}
onClick={onClick}
-8
View File
@@ -1,12 +1,10 @@
import { AnchorAPI } from "./components/anchorAPI";
import { AnchorGit } from "./components/anchorGit";
import { AnchorHome } from "./components/anchorHome";
import { AnchorLogo } from "./components/anchorLogo";
import { AnchorNostr } from "./components/anchorNostr";
import { ButtonChart } from "./components/buttonChart";
import { ButtonFavorites } from "./components/buttonFavorites";
import { ButtonHistory } from "./components/buttonHistory";
import { ButtonRefresh } from "./components/buttonRefresh";
import { ButtonSearch } from "./components/buttonSearch";
import { ButtonSettings } from "./components/buttonSettings";
import { ButtonTree } from "./components/buttonTree";
@@ -14,11 +12,9 @@ import { ButtonTree } from "./components/buttonTree";
export function StripDesktop({
selected,
setSelected,
needsRefresh,
}: {
selected: Accessor<FrameName>;
setSelected: Setter<FrameName>;
needsRefresh: Accessor<boolean>;
}) {
return (
<>
@@ -33,10 +29,6 @@ export function StripDesktop({
<div class="size-full" />
<Show when={needsRefresh()}>
<ButtonRefresh />
</Show>
<AnchorAPI />
<AnchorGit />
<AnchorNostr />
+82
View File
@@ -0,0 +1,82 @@
import { useRegisterSW } from "virtual:pwa-register/solid";
export function Update() {
// if ("serviceWorker" in navigator) {
// navigator.serviceWorker.getRegistrations().then((l) => {
// console.log(l);
// if (!l.length) return;
// wasAlreadySW.set(true);
// // navigator.serviceWorker.addEventListener("controllerchange", () => {
// // // Will show up in safari and chrome
// // console.log("sw: controller change");
// // setTimeout(() => {
// // needsRefresh.set(true);
// // }, 1000);
// // });
// });
// setTimeout(() => {
// navigator.serviceWorker
// .register("/sw.js", { scope: "/" })
// .then((registration) => {
// // Will show up on safari sw update but not on chrome
// console.log("sw: registration succeeded");
// console.log(registration);
// registration.addEventListener("updatefound", () => {
// if (wasAlreadySW()) {
// setTimeout(() => {
// needsRefresh.set(true);
// }, 1000);
// }
// // will show up on chrome sw update
// console.log("sw: update found");
// });
// })
// .catch((error) => {
// // registration failed
// console.error(`sw: registration failed with ${error}`);
// });
// }, 5000);
// }
// useRegisterSW can also return an offlineReady thingy
const {
needRefresh: [needRefresh, setNeedRefresh],
updateServiceWorker,
} = useRegisterSW({
immediate: true,
onRegisteredSW(swUrl, r) {
console.log("sw: registered: " + r?.scope);
},
onRegisterError(error: Error) {
console.log("sw: registration error", error);
},
});
return (
<Show when={needRefresh()}>
<div class="absolute inset-x-1.5 top-1.5 z-[99999] flex items-center justify-between rounded-lg bg-orange-700/75 p-1.5 shadow backdrop-blur-sm">
<div>
<span class="truncate px-1">New version available, please</span>
<button
class="mr-2 rounded-md bg-orange-50 bg-opacity-60 px-1.5 py-0.5 font-medium text-orange-950 hover:bg-opacity-100"
onClick={async () => await updateServiceWorker()}
>
install
</button>
</div>
<button
class="rounded-md bg-black/25 p-1 hover:bg-black/50"
onClick={() => setNeedRefresh(false)}
>
<IconTablerX />
</button>
</div>
</Show>
);
}
+44 -50
View File
@@ -6,6 +6,7 @@ import { chartState } from "../scripts/lightweightCharts/chart/state";
import { setTimeScale } from "../scripts/lightweightCharts/chart/time";
import { createPresets } from "../scripts/presets";
import { priceToUSLocale } from "../scripts/utils/locale";
import { run } from "../scripts/utils/run";
import { sleep } from "../scripts/utils/sleep";
import {
readBooleanFromStorage,
@@ -16,9 +17,14 @@ import { webSockets } from "../scripts/ws";
import { classPropToString } from "../solid/classes";
import { Background, LOCAL_STORAGE_MARQUEE_KEY } from "./components/background";
import { ChartFrame } from "./components/frames/chart";
import { FavoritesFrame } from "./components/frames/favorites";
import { HistoryFrame } from "./components/frames/history";
import { SearchFrame } from "./components/frames/search";
import { SettingsFrame } from "./components/frames/settings";
import { TreeFrame } from "./components/frames/tree";
import { Qrcode } from "./components/qrcode";
import { StripDesktop, StripMobile } from "./components/strip";
import { registerServiceWorker } from "./scripts/register";
import { Update } from "./components/update";
const LOCAL_STORAGE_BAR_KEY = "bar-width";
const LOCAL_STORAGE_FULLSCREEN = "fullscrenn";
@@ -26,8 +32,6 @@ const LOCAL_STORAGE_FULLSCREEN = "fullscrenn";
export const INPUT_PRESET_SEARCH_ID = "input-search-preset";
export function App() {
const needRefresh = registerServiceWorker().needRefresh[0];
const tabFocused = createRWS(true);
const qrcode = createRWS("");
@@ -38,15 +42,8 @@ export function App() {
false,
);
const activeResources = createRWS<Set<ResourceDataset<any, any>>>(new Set(), {
equals: false,
});
const datasets = createDatasets({
setActiveResources: activeResources.set,
});
const windowWidth = createRWS(window.innerWidth);
const windowWidth60p = createMemo(() => windowWidth() * 0.6);
const windowResizeCallback = () => {
windowWidth.set(window.innerWidth);
};
@@ -55,8 +52,9 @@ export function App() {
const windowSizeIsAtLeastMedium = createMemo(() => windowWidth() >= 720);
const minBarWidth = 384;
const barWidth = createRWS(
Number(localStorage.getItem(LOCAL_STORAGE_BAR_KEY)),
Number(localStorage.getItem(LOCAL_STORAGE_BAR_KEY)) || minBarWidth,
);
createEffect(() => {
@@ -81,11 +79,12 @@ export function App() {
: _selectedFrame(),
);
const presets = createPresets(datasets);
const presets = createPresets();
const marquee = createRWS(!localStorage.getItem(LOCAL_STORAGE_MARQUEE_KEY));
const resizingBarStart = createRWS<number | undefined>(undefined);
const resizingBarWidth = createRWS<number>(0);
createEffect(
() => {
@@ -98,6 +97,16 @@ export function App() {
},
);
const activeResources = createRWS<Set<ResourceDataset<any, any>>>(new Set(), {
equals: false,
});
// Can't put datasets inside a signal as it breaks lazy memo
const datasets = createDatasets({
setActiveResources: activeResources.set,
});
onMount(() => {
webSockets.openAll();
@@ -114,32 +123,6 @@ export function App() {
});
});
const FavoritesFrame = lazy(() =>
import("./components/frames/favorites").then((d) => ({
default: d.FavoritesFrame,
})),
);
const HistoryFrame = lazy(() =>
import("./components/frames/history").then((d) => ({
default: d.HistoryFrame,
})),
);
const SearchFrame = lazy(() =>
import("./components/frames/search").then((d) => ({
default: d.SearchFrame,
})),
);
const SettingsFrame = lazy(() =>
import("./components/frames/settings").then((d) => ({
default: d.SettingsFrame,
})),
);
const Qrcode = lazy(() =>
import("./components/qrcode").then((d) => ({
default: d.Qrcode,
})),
);
const documentVisibilityChange = () =>
tabFocused.set(document.visibilityState === "visible");
document.addEventListener("visibilitychange", documentVisibilityChange);
@@ -186,10 +169,18 @@ export function App() {
"user-select": resizingBarStart() !== undefined ? "none" : undefined,
}}
onMouseMove={(event) => {
const start = resizingBarStart();
const startingClientX = resizingBarStart();
if (start !== undefined) {
barWidth.set(event.x - start + 384);
if (startingClientX !== undefined) {
barWidth.set(
Math.min(
Math.max(
resizingBarWidth() + event.clientX - startingClientX,
minBarWidth,
),
windowWidth60p(),
),
);
setTimeScale(resizeInitialRange());
}
@@ -200,6 +191,7 @@ export function App() {
onTouchCancel={() => resizingBarStart.set(undefined)}
>
<Qrcode qrcode={qrcode} />
<Update />
<div class="flex size-full flex-col md:flex-row md:p-3">
<Show when={!windowSizeIsAtLeastMedium() || !fullscreen()}>
@@ -213,15 +205,16 @@ export function App() {
<StripDesktop
selected={selectedFrame}
setSelected={_selectedFrame.set}
needsRefresh={needRefresh}
/>
</div>
<div
class="flex h-full min-h-0 md:min-w-[384px]"
class="flex h-full min-h-0"
style={{
...(windowSizeIsAtLeastMedium()
? {
width: `min(${barWidth()}px, 75dvw)`,
"min-width": `${minBarWidth}px`,
width: `${barWidth()}px`,
"max-width": `${windowWidth60p()}px`,
}
: {}),
}}
@@ -270,21 +263,22 @@ export function App() {
onMouseDown={(event) => {
resizeInitialRange.set(chartState.range);
resizingBarStart() === undefined &&
// TODO: set size of bar instead
if (resizingBarStart() === undefined) {
resizingBarStart.set(event.clientX);
resizingBarWidth.set(barWidth());
}
}}
onTouchStart={(event) => {
resizeInitialRange.set(chartState.range);
resizingBarStart() === undefined &&
if (resizingBarStart() === undefined) {
resizingBarStart.set(event.touches[0].clientX);
resizingBarWidth.set(barWidth());
}
}}
onDblClick={() => {
resizeInitialRange.set(chartState.range);
barWidth.set(0);
setTimeScale(resizeInitialRange());
}}
/>
-67
View File
@@ -1,67 +0,0 @@
import { useRegisterSW } from "virtual:pwa-register/solid";
import { FIVE_MINUTES_IN_MS } from "/src/scripts/utils/time";
export function registerServiceWorker() {
return useRegisterSW({
onRegisteredSW(swUrl, registered) {
console.log("sw: registered", registered);
if (registered) {
const callback = async () => {
if (!(!registered.installing && navigator)) return;
if ("connection" in navigator && !navigator.onLine) return;
const resp = await fetch(swUrl, {
cache: "no-store",
headers: {
cache: "no-store",
"cache-control": "no-cache",
},
});
if (resp?.status === 200) {
await registered.update();
}
};
callback();
setInterval(callback, FIVE_MINUTES_IN_MS);
}
},
onRegisterError(error) {
console.log("sw: registration error", error);
},
onNeedRefresh() {
console.log("sw: needs refresh");
},
});
}
// From update.tsx
// onMount(async () => {
// if ('serviceWorker' in navigator) {
// try {
// const registration = await navigator.serviceWorker.register('/sw.js')
// registration.addEventListener('updatefound', () => {
// const worker = registration.installing
// worker?.addEventListener('statechange', () => {
// if (
// worker.state === 'activated' &&
// navigator.serviceWorker.controller
// ) {
// ;(Object.entries(props.resources) as Entries<ResourcesHTTP>)
// .map(([_, value]) => value.fetch)
// .forEach((fetch) => fetch())
// setTimeout(() => updateAvailable.set(true), FIVE_SECOND_IN_MS)
// }
// })
// })
// } catch {}
// }
// })
+3 -5
View File
@@ -3,6 +3,8 @@ import { render } from "solid-js/web";
import "./styles.css";
import { App } from "./app";
const root = document.getElementById("root");
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
@@ -11,8 +13,4 @@ if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
);
}
render(() => {
const App = lazy(() => import("./app").then((d) => ({ default: d.App })));
return <App />;
}, root!);
render(App, root!);
+16 -11
View File
@@ -1,30 +1,35 @@
import groupedKeysToPath from "/src/../../datasets/grouped_keys_to_url_path.json";
import { createResourceDataset } from "./resource";
export { averages } from "./consts/averages";
export function createDateDatasets({
setActiveResources,
groupedKeysToURLPath,
}: {
setActiveResources: Setter<Set<ResourceDataset<any, any>>>;
groupedKeysToURLPath: GroupedKeysToURLPath["date"];
}) {
type Key = keyof typeof groupedKeysToPath.date;
type Key = keyof typeof groupedKeysToURLPath;
type ResourceData = ReturnType<typeof createResourceDataset<"date">>;
const resourceDatasets = {} as Record<Exclude<Key, "ohlc">, ResourceData>;
type ResourceDatasets = Record<Exclude<Key, "ohlc">, ResourceData>;
Object.entries(groupedKeysToPath.date).forEach(([_key, path]) => {
for (const _key in groupedKeysToURLPath) {
const key = _key as Key;
if (key !== "ohlc") {
resourceDatasets[key] = createResourceDataset<"date">({
scale: "date",
path,
setActiveResources,
});
const path = groupedKeysToURLPath[key];
(groupedKeysToURLPath as any as ResourceDatasets)[key] =
createResourceDataset<"date">({
scale: "date",
path,
setActiveResources,
});
}
});
}
const resourceDatasets = groupedKeysToURLPath as any as ResourceDatasets;
const price = createResourceDataset<"date", OHLC>({
scale: "date",
+17 -11
View File
@@ -1,27 +1,33 @@
import groupedKeysToPath from "/src/../../datasets/grouped_keys_to_url_path.json";
import { createResourceDataset } from "./resource";
export function createHeightDatasets({
setActiveResources,
groupedKeysToURLPath,
}: {
setActiveResources: Setter<Set<ResourceDataset<any, any>>>;
groupedKeysToURLPath: GroupedKeysToURLPath["height"];
}) {
type Key = keyof typeof groupedKeysToPath.height;
type Key = keyof typeof groupedKeysToURLPath;
type ResourceData = ReturnType<typeof createResourceDataset<"height">>;
const resourceDatasets = {} as Record<Exclude<Key, "ohlc">, ResourceData>;
type ResourceDatasets = Record<Exclude<Key, "ohlc">, ResourceData>;
Object.keys(groupedKeysToPath.height).forEach(([_key, path]) => {
for (const _key in groupedKeysToURLPath) {
const key = _key as Key;
if (key !== "ohlc") {
resourceDatasets[key] = createResourceDataset<"height">({
scale: "height",
path,
setActiveResources,
});
const path = groupedKeysToURLPath[key];
(groupedKeysToURLPath as any as ResourceDatasets)[key] =
createResourceDataset<"height">({
scale: "height",
path,
setActiveResources,
});
}
});
}
const resourceDatasets = groupedKeysToURLPath as any as ResourceDatasets;
const price = createResourceDataset<"height", OHLC>({
scale: "height",
+14 -2
View File
@@ -1,3 +1,5 @@
import groupedKeysToURLPath from "/src/../../datasets/grouped_keys_to_url_path.json";
import { createDateDatasets } from "./date";
import { createHeightDatasets } from "./height";
@@ -10,8 +12,18 @@ export function createDatasets({
}: {
setActiveResources: Setter<Set<ResourceDataset<any, any>>>;
}) {
const date = createDateDatasets({
setActiveResources,
groupedKeysToURLPath: groupedKeysToURLPath.date,
});
const height = createHeightDatasets({
setActiveResources,
groupedKeysToURLPath: groupedKeysToURLPath.height,
});
return {
date: createDateDatasets({ setActiveResources }),
height: createHeightDatasets({ setActiveResources }),
date,
height,
} satisfies Record<ResourceScale, any>;
}
+6 -5
View File
@@ -22,9 +22,10 @@ export function createResourceDataset<
setActiveResources: Setter<Set<ResourceDataset<any, any>>>;
}) {
const baseURL = `${
location.hostname === "localhost"
? "http://localhost:3110"
: "https://api.satonomics.xyz"
// location.hostname === "localhost"
// ? "http://localhost:3110"
// : "https://api.satonomics.xyz"
"https://api.satonomics.xyz"
}${path}`;
type Dataset = Scale extends "date"
@@ -36,8 +37,8 @@ export function createResourceDataset<
>;
const fetchedJSONs = new Array(
(new Date().getFullYear() - new Date("2009-01-01").getFullYear()) *
(scale === "date" ? 2 : 8),
(new Date().getFullYear() - new Date("2009-01-01").getFullYear() + 2) *
(scale === "date" ? 1 : 6),
)
.fill(null)
.map((): FetchedResult<Scale, Type> => {
+3
View File
@@ -96,3 +96,6 @@ interface OHLC {
low: number;
close: number;
}
type GroupedKeysToURLPath =
typeof import("/src/../../datasets/grouped_keys_to_url_path.json");
@@ -17,7 +17,7 @@ const debouncedUpdateURLParams = debounce((range: TimeRange | null) => {
writeURLParam(URL_PARAMS_RANGE_TO_KEY, String(range.to));
localStorage.setItem(LOCAL_STORAGE_RANGE_KEY, JSON.stringify(range));
}, 1000);
}, 500);
export function initTimeScale({
activeResources,
@@ -101,8 +101,6 @@ export function getInitialRange(): TimeRange {
export function setTimeScale(range: TimeRange | null) {
if (range) {
console.log(range);
setTimeout(() => {
chartState.chart?.timeScale().setVisibleRange(range);
}, 1);
@@ -9,10 +9,8 @@ import { applyMultipleSeries, SeriesType } from "../templates/multiple";
export function createPresets({
scale,
datasets,
}: {
scale: ResourceScale;
datasets: Datasets;
}): PartialPresetFolder {
return {
name: "Addresses",
@@ -112,7 +110,6 @@ export function createPresets({
name: "By Size",
tree: addressCohortsBySize.map(({ key, name }) =>
createAddressPresetFolder({
datasets,
scale,
color: colors[key],
name,
@@ -125,7 +122,6 @@ export function createPresets({
name: "By Type",
tree: addressCohortsByType.map(({ key, name }) =>
createAddressPresetFolder({
datasets,
scale,
color: colors[key],
name,
@@ -138,13 +134,11 @@ export function createPresets({
}
function createAddressPresetFolder<Scale extends ResourceScale>({
datasets,
scale,
color,
name,
datasetKey,
}: {
datasets: Datasets;
scale: Scale;
name: string;
datasetKey: AddressCohortKey;
@@ -156,7 +150,6 @@ function createAddressPresetFolder<Scale extends ResourceScale>({
createAddressCountPreset({ scale, name, datasetKey, color }),
...createCohortPresetList({
title: name,
datasets,
scale,
name,
color,
@@ -170,7 +163,6 @@ function createAddressPresetFolder<Scale extends ResourceScale>({
tree: createCohortPresetList({
title: `${liquidity.name} ${name}`,
name: `${liquidity.name} ${name}`,
datasets,
scale,
color,
datasetKey: `${liquidity.key}_${datasetKey}`,
+77 -68
View File
@@ -3,13 +3,9 @@ import { applyMultipleSeries, SeriesType } from "../templates/multiple";
export function createPresets<Scale extends ResourceScale>({
scale,
datasets: _datasets,
}: {
scale: Scale;
datasets: Datasets;
}) {
const datasets = _datasets[scale];
return {
name: "Cointime Economics",
tree: [
@@ -29,27 +25,27 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Vaulted Price",
color: colors.vaultedness,
dataset: datasets.vaulted_price,
dataset: params.datasets[scale].vaulted_price,
},
{
title: "Active Price",
color: colors.liveliness,
dataset: datasets.active_price,
dataset: params.datasets[scale].active_price,
},
{
title: "True Market Mean",
color: colors.trueMarketMeanPrice,
dataset: datasets.true_market_mean,
dataset: params.datasets[scale].true_market_mean,
},
{
title: "Realized Price",
color: colors.bitcoin,
dataset: datasets.realized_price,
dataset: params.datasets[scale].realized_price,
},
{
title: "Cointime",
color: colors.cointimePrice,
dataset: datasets.cointime_price,
dataset: params.datasets[scale].cointime_price,
},
],
});
@@ -71,7 +67,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Active Price",
color: colors.liveliness,
dataset: datasets.active_price,
dataset: params.datasets[scale].active_price,
},
],
});
@@ -95,7 +91,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Vaulted Price",
color: colors.vaultedness,
dataset: datasets.vaulted_price,
dataset: params.datasets[scale].vaulted_price,
},
],
});
@@ -119,7 +115,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "True Market Mean",
color: colors.trueMarketMeanPrice,
dataset: datasets.true_market_mean,
dataset: params.datasets[scale].true_market_mean,
},
],
});
@@ -143,7 +139,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Cointime",
color: colors.cointimePrice,
dataset: datasets.cointime_price,
dataset: params.datasets[scale].cointime_price,
},
],
});
@@ -174,22 +170,22 @@ export function createPresets<Scale extends ResourceScale>({
title: "Market Cap",
color: colors.white,
dataset: datasets.market_cap,
dataset: params.datasets[scale].market_cap,
},
{
title: "Realized Cap",
color: colors.realizedCap,
dataset: datasets.realized_cap,
dataset: params.datasets[scale].realized_cap,
},
{
title: "Investor Cap",
color: colors.investorCap,
dataset: datasets.investor_cap,
dataset: params.datasets[scale].investor_cap,
},
{
title: "Thermo Cap",
color: colors.thermoCap,
dataset: datasets.thermo_cap,
dataset: params.datasets[scale].thermo_cap,
},
],
});
@@ -212,7 +208,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Thermo Cap",
color: colors.thermoCap,
dataset: datasets.thermo_cap,
dataset: params.datasets[scale].thermo_cap,
},
],
});
@@ -235,7 +231,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Investor Cap",
color: colors.investorCap,
dataset: datasets.investor_cap,
dataset: params.datasets[scale].investor_cap,
},
],
});
@@ -257,7 +253,8 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Ratio",
color: colors.bitcoin,
dataset: datasets.thermo_cap_to_investor_cap_ratio,
dataset:
params.datasets[scale].thermo_cap_to_investor_cap_ratio,
},
],
});
@@ -284,17 +281,17 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Coinblocks Created",
color: colors.coinblocksCreated,
dataset: datasets.coinblocks_created,
dataset: params.datasets[scale].coinblocks_created,
},
{
title: "Coinblocks Destroyed",
color: colors.coinblocksDestroyed,
dataset: datasets.coinblocks_destroyed,
dataset: params.datasets[scale].coinblocks_destroyed,
},
{
title: "Coinblocks Stored",
color: colors.coinblocksStored,
dataset: datasets.coinblocks_stored,
dataset: params.datasets[scale].coinblocks_stored,
},
],
});
@@ -316,7 +313,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Coinblocks Created",
color: colors.coinblocksCreated,
dataset: datasets.coinblocks_created,
dataset: params.datasets[scale].coinblocks_created,
},
],
});
@@ -338,7 +335,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Coinblocks Destroyed",
color: colors.coinblocksDestroyed,
dataset: datasets.coinblocks_destroyed,
dataset: params.datasets[scale].coinblocks_destroyed,
},
],
});
@@ -360,7 +357,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Coinblocks Stored",
color: colors.coinblocksStored,
dataset: datasets.coinblocks_stored,
dataset: params.datasets[scale].coinblocks_stored,
},
],
});
@@ -387,17 +384,20 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Cumulative Coinblocks Created",
color: colors.coinblocksCreated,
dataset: datasets.cumulative_coinblocks_created,
dataset:
params.datasets[scale].cumulative_coinblocks_created,
},
{
title: "Cumulative Coinblocks Destroyed",
color: colors.coinblocksDestroyed,
dataset: datasets.cumulative_coinblocks_destroyed,
dataset:
params.datasets[scale].cumulative_coinblocks_destroyed,
},
{
title: "Cumulative Coinblocks Stored",
color: colors.coinblocksStored,
dataset: datasets.cumulative_coinblocks_stored,
dataset:
params.datasets[scale].cumulative_coinblocks_stored,
},
],
});
@@ -419,7 +419,8 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Cumulative Coinblocks Created",
color: colors.coinblocksCreated,
dataset: datasets.cumulative_coinblocks_created,
dataset:
params.datasets[scale].cumulative_coinblocks_created,
},
],
});
@@ -441,7 +442,8 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Cumulative Coinblocks Destroyed",
color: colors.coinblocksDestroyed,
dataset: datasets.cumulative_coinblocks_destroyed,
dataset:
params.datasets[scale].cumulative_coinblocks_destroyed,
},
],
});
@@ -463,7 +465,8 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Cumulative Coinblocks Stored",
color: colors.coinblocksStored,
dataset: datasets.cumulative_coinblocks_stored,
dataset:
params.datasets[scale].cumulative_coinblocks_stored,
},
],
});
@@ -490,7 +493,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Liveliness",
color: colors.liveliness,
dataset: datasets.liveliness,
dataset: params.datasets[scale].liveliness,
},
],
});
@@ -512,7 +515,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Vaultedness",
color: colors.vaultedness,
dataset: datasets.vaultedness,
dataset: params.datasets[scale].vaultedness,
},
],
});
@@ -534,12 +537,12 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Liveliness",
color: colors.liveliness,
dataset: datasets.liveliness,
dataset: params.datasets[scale].liveliness,
},
{
title: "Vaultedness",
color: colors.vaultedness,
dataset: datasets.vaultedness,
dataset: params.datasets[scale].vaultedness,
},
],
});
@@ -561,7 +564,8 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Activity To Vaultedness Ratio",
color: colors.activityToVaultednessRatio,
dataset: datasets.activity_to_vaultedness_ratio,
dataset:
params.datasets[scale].activity_to_vaultedness_ratio,
},
],
});
@@ -583,12 +587,13 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Concurrent Liveliness 14d Median",
color: `${colors.liveliness}66`,
dataset: datasets.concurrent_liveliness_2w_median,
dataset:
params.datasets[scale].concurrent_liveliness_2w_median,
},
{
title: "Concurrent Liveliness",
color: colors.liveliness,
dataset: datasets.concurrent_liveliness,
dataset: params.datasets[scale].concurrent_liveliness,
},
],
});
@@ -611,13 +616,14 @@ export function createPresets<Scale extends ResourceScale>({
title: "Liveliness Incremental Change",
color: colors.darkLiveliness,
seriesType: SeriesType.Based,
dataset: datasets.liveliness_net_change,
dataset: params.datasets[scale].liveliness_net_change,
},
{
title: "Liveliness Incremental Change 14 Day Median",
color: colors.liveliness,
seriesType: SeriesType.Based,
dataset: datasets.liveliness_net_change_2w_median,
dataset:
params.datasets[scale].liveliness_net_change_2w_median,
},
],
});
@@ -644,7 +650,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Vaulted Supply",
color: colors.vaultedness,
dataset: datasets.vaulted_supply,
dataset: params.datasets[scale].vaulted_supply,
},
],
});
@@ -666,7 +672,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Active Supply",
color: colors.liveliness,
dataset: datasets.active_supply,
dataset: params.datasets[scale].active_supply,
},
],
});
@@ -688,17 +694,17 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Circulating Supply",
color: colors.coinblocksCreated,
dataset: datasets.supply,
dataset: params.datasets[scale].supply,
},
{
title: "Vaulted Supply",
color: colors.vaultedness,
dataset: datasets.vaulted_supply,
dataset: params.datasets[scale].vaulted_supply,
},
{
title: "Active Supply",
color: colors.liveliness,
dataset: datasets.active_supply,
dataset: params.datasets[scale].active_supply,
},
],
});
@@ -722,13 +728,13 @@ export function createPresets<Scale extends ResourceScale>({
// id: 'min-vaulted',
// title: 'Min Vaulted Supply',
// color: colors.vaultedness,
// dataset: params.datasets.dateToMinVaultedSupply,
// dataset: params.params.datasets[scale].dateToMinVaultedSupply,
// },
// {
// id: 'max-active',
// title: 'Max Active Supply',
// color: colors.liveliness,
// dataset: params.datasets.dateToMaxActiveSupply,
// dataset: params.params.datasets[scale].dateToMaxActiveSupply,
// },
// ],
// })
@@ -750,7 +756,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Vaulted Supply Net Change",
color: colors.vaultedness,
dataset: datasets.vaulted_supply,
dataset: params.datasets[scale].vaulted_supply,
},
],
});
@@ -772,7 +778,7 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Active Supply Net Change",
color: colors.liveliness,
dataset: datasets.active_supply_net_change,
dataset: params.datasets[scale].active_supply_net_change,
},
],
});
@@ -794,14 +800,15 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Active Supply Net Change",
color: `${colors.liveliness}80`,
dataset: datasets.active_supply_3m_net_change,
dataset: params.datasets[scale].active_supply_3m_net_change,
seriesType: SeriesType.Based,
},
{
title: "Vaulted Supply Net Change",
color: `${colors.vaultedPrice}80`,
seriesType: SeriesType.Based,
dataset: datasets.vaulted_supply_3m_net_change,
dataset:
params.datasets[scale].vaulted_supply_3m_net_change,
},
],
});
@@ -826,7 +833,7 @@ export function createPresets<Scale extends ResourceScale>({
// title: 'Vaulted Supply Annualized Net Change',
// color: colors.vaultedness,
// dataset:
// datasets.vaultedAnnualizedSupplyNetChange,
// params.datasets[scale].vaultedAnnualizedSupplyNetChange,
// },
// ],
// })
@@ -851,13 +858,13 @@ export function createPresets<Scale extends ResourceScale>({
// id: 'vaulting-rate',
// title: 'Vaulting Rate',
// color: colors.vaultedness,
// dataset: datasets.vaultingRate,
// dataset: params.datasets[scale].vaultingRate,
// },
// {
// id: 'nominal-inflation-rate',
// title: 'Nominal Inflation Rate',
// color: colors.orange,
// dataset: params.datasets.dateToYearlyInflationRate,
// dataset: params.params.datasets[scale].dateToYearlyInflationRate,
// },
// ],
// })
@@ -883,7 +890,7 @@ export function createPresets<Scale extends ResourceScale>({
// title: 'Change From Issuance',
// color: colors.emerald,
// dataset:
// params.datasets
// params.params.datasets[scale]
// [scale].activeSupplyChangeFromIssuance90dChange,
// },
// {
@@ -891,14 +898,14 @@ export function createPresets<Scale extends ResourceScale>({
// title: 'Change From Transactions',
// color: colors.rose,
// dataset:
// params.datasets
// params.params.datasets[scale]
// [scale].activeSupplyChangeFromTransactions90dChange,
// },
// // {
// // id: 'active',
// // title: 'Active Supply',
// // color: colors.liveliness,
// // dataset: datasets.activeSupply,
// // dataset: params.datasets[scale].activeSupply,
// // },
// ],
// })
@@ -921,17 +928,17 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Circulating Supply",
color: colors.coinblocksCreated,
dataset: datasets.supply,
dataset: params.datasets[scale].supply,
},
{
title: "Vaulted Supply",
color: colors.vaultedness,
dataset: datasets.vaulted_supply,
dataset: params.datasets[scale].vaulted_supply,
},
{
title: "Supply in profit",
color: colors.bitcoin,
dataset: datasets.supply_in_profit,
dataset: params.datasets[scale].supply_in_profit,
},
],
});
@@ -953,17 +960,17 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Circulating Supply",
color: colors.coinblocksCreated,
dataset: datasets.supply,
dataset: params.datasets[scale].supply,
},
{
title: "Active Supply",
color: colors.liveliness,
dataset: datasets.active_supply,
dataset: params.datasets[scale].active_supply,
},
{
title: "Supply in Loss",
color: colors.bitcoin,
dataset: datasets.supply_in_loss,
dataset: params.datasets[scale].supply_in_loss,
},
],
});
@@ -988,12 +995,14 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Cointime Adjusted",
color: colors.coinblocksCreated,
dataset: datasets.cointime_adjusted_yearly_inflation_rate,
dataset:
params.datasets[scale]
.cointime_adjusted_yearly_inflation_rate,
},
{
title: "Nominal",
color: colors.bitcoin,
dataset: datasets.yearly_inflation_rate,
dataset: params.datasets[scale].yearly_inflation_rate,
},
],
});
@@ -1016,12 +1025,12 @@ export function createPresets<Scale extends ResourceScale>({
{
title: "Cointime Adjusted",
color: colors.coinblocksCreated,
dataset: datasets.cointime_adjusted_velocity,
dataset: params.datasets[scale].cointime_adjusted_velocity,
},
{
title: "Nominal",
color: colors.bitcoin,
dataset: datasets.transaction_velocity,
dataset: params.datasets[scale].transaction_velocity,
},
],
});
+1 -12
View File
@@ -9,13 +9,7 @@ import { colors } from "../../utils/colors";
import { createCohortPresetFolder } from "../templates/cohort";
import { applyMultipleSeries } from "../templates/multiple";
export function createPresets({
scale,
datasets,
}: {
scale: ResourceScale;
datasets: Datasets;
}) {
export function createPresets({ scale }: { scale: ResourceScale }) {
return {
name: "Hodlers",
tree: [
@@ -62,7 +56,6 @@ export function createPresets({
},
...xthCohorts.map(({ key, name, legend }) =>
createCohortPresetFolder({
datasets,
scale,
color: colors[key],
name: legend,
@@ -74,7 +67,6 @@ export function createPresets({
name: "Up To X",
tree: upToCohorts.map(({ key, name }) =>
createCohortPresetFolder({
datasets,
scale,
color: colors[key],
name,
@@ -87,7 +79,6 @@ export function createPresets({
name: "From X To Y",
tree: fromXToYCohorts.map(({ key, name }) =>
createCohortPresetFolder({
datasets,
scale,
color: colors[key],
name,
@@ -100,7 +91,6 @@ export function createPresets({
name: "From X",
tree: fromXCohorts.map(({ key, name }) =>
createCohortPresetFolder({
datasets,
scale,
color: colors[key],
name,
@@ -113,7 +103,6 @@ export function createPresets({
name: "Years",
tree: yearCohorts.map(({ key, name }) =>
createCohortPresetFolder({
datasets,
scale,
color: colors[key],
name,
+5 -6
View File
@@ -19,7 +19,7 @@ export const LOCAL_STORAGE_HISTORY_KEY = "history";
export const LOCAL_STORAGE_SELECTED_KEY = "preset";
export const LOCAL_STORAGE_VISITED_KEY = "visited";
export function createPresets(datasets: Datasets): Presets {
export function createPresets(): Presets {
const partialTree = [
{
name: "Dashboards (Coming soon)",
@@ -31,21 +31,20 @@ export function createPresets(datasets: Datasets): Presets {
{
name: "By Date",
tree: [
createMarketPresets({ scale: "date", datasets }),
createMarketPresets({ scale: "date" }),
createBlocksPresets(),
createMinersPresets("date"),
createTransactionsPresets("date"),
...createCohortPresetList({
datasets,
scale: "date",
color: colors.bitcoin,
datasetKey: "",
name: "",
title: "",
}),
createHodlersPresets({ scale: "date", datasets }),
createAddressesPresets({ scale: "date", datasets }),
createCoinblocksPresets({ scale: "date", datasets }),
createHodlersPresets({ scale: "date" }),
createAddressesPresets({ scale: "date" }),
createCoinblocksPresets({ scale: "date" }),
],
} satisfies PartialPresetFolder,
{
@@ -3,7 +3,7 @@ import { colors } from "/src/scripts/utils/colors";
import { applyMultipleSeries } from "../../templates/multiple";
export function createPresets(datasets: Datasets): PartialPresetFolder {
export function createPresets(): PartialPresetFolder {
const scale: ResourceScale = "date";
return {
@@ -28,7 +28,6 @@ export function createPresets(datasets: Datasets): PartialPresetFolder {
},
...averages.map(({ name, key }) =>
createPresetFolder({
datasets,
scale,
color: colors[`_${key}`],
name,
@@ -41,12 +40,10 @@ export function createPresets(datasets: Datasets): PartialPresetFolder {
function createPresetFolder({
scale,
datasets,
color,
name,
key,
}: {
datasets: Datasets;
scale: ResourceScale;
color: string;
name: string;
@@ -69,7 +66,7 @@ function createPresetFolder({
{
title: `SMA`,
color,
dataset: datasets.date[`price_${key}_sma`],
dataset: params.datasets.date[`price_${key}_sma`],
},
],
});
+4 -10
View File
@@ -4,13 +4,7 @@ import { createPresets as createAveragesPresets } from "./averages";
import { createPresets as createIndicatorsPresets } from "./indicators";
import { createPresets as createReturnsPresets } from "./returns";
export function createPresets({
scale,
datasets,
}: {
scale: ResourceScale;
datasets: Datasets;
}) {
export function createPresets({ scale }: { scale: ResourceScale }) {
return {
name: "Market",
tree: [
@@ -67,9 +61,9 @@ export function createPresets({
},
...(scale === "date"
? ([
createAveragesPresets(datasets),
createReturnsPresets(datasets),
createIndicatorsPresets(datasets),
createAveragesPresets(),
createReturnsPresets(),
createIndicatorsPresets(),
] satisfies PartialPresetTree)
: []),
],
@@ -1,4 +1,4 @@
export function createPresets(datasets: Datasets) {
export function createPresets() {
return {
name: "Indicators",
tree: [],
@@ -5,7 +5,7 @@ import {
import { applyMultipleSeries, SeriesType } from "../../templates/multiple";
export function createPresets(datasets: Datasets) {
export function createPresets() {
return {
name: "Returns",
tree: [
@@ -15,7 +15,6 @@ export function createPresets(datasets: Datasets) {
...totalReturns.map(({ name, key }) =>
createPreset({
scale: "date",
datasets,
name,
title: `${name} Total`,
key: `${key}_total`,
@@ -29,7 +28,6 @@ export function createPresets(datasets: Datasets) {
...compoundReturns.map(({ name, key }) =>
createPreset({
scale: "date",
datasets,
name,
title: `${name} Compound`,
key: `${key}_compound`,
@@ -43,13 +41,11 @@ export function createPresets(datasets: Datasets) {
function createPreset({
scale,
datasets,
name,
title,
key,
}: {
scale: ResourceScale;
datasets: Datasets;
name: string;
title: string;
key: `${TotalReturnKey}_total` | `${CompoundReturnKey}_compound`;
@@ -70,7 +66,7 @@ function createPreset({
{
title: `Return (%)`,
seriesType: SeriesType.Based,
dataset: datasets.date[`price_${key}_return`],
dataset: params.datasets.date[`price_${key}_return`],
},
],
});
@@ -3,14 +3,12 @@ import { colors } from "../../utils/colors";
import { applyMultipleSeries, SeriesType } from "./multiple";
export function createCohortPresetFolder<Scale extends ResourceScale>({
datasets,
scale,
color,
name,
datasetKey,
title,
}: {
datasets: Datasets;
scale: Scale;
name: string;
datasetKey: AnyPossibleCohortKey;
@@ -21,7 +19,6 @@ export function createCohortPresetFolder<Scale extends ResourceScale>({
name,
tree: createCohortPresetList({
title,
datasets,
name,
scale,
color,
@@ -32,14 +29,12 @@ export function createCohortPresetFolder<Scale extends ResourceScale>({
export function createCohortPresetList<Scale extends ResourceScale>({
name,
datasets,
scale,
color,
datasetKey,
title,
}: {
name: string;
datasets: Datasets;
scale: Scale;
datasetKey: AnyPossibleCohortKey;
title: string;
+4
View File
@@ -21,6 +21,10 @@
}
}
a {
@apply text-orange-300 hover:underline;
}
mark {
@apply bg-transparent p-0 text-orange-400;
}
+5 -3
View File
@@ -22,8 +22,8 @@ declare global {
const IconTablerArrowForward: typeof import('~icons/tabler/arrow-forward.jsx')['default']
const IconTablerArrowRight: (typeof import("~icons/tabler/arrow-right.jsx"))["default"]
const IconTablerArrowsCross: typeof import('~icons/tabler/arrows-cross.jsx')['default']
const IconTablerArrowsMaximize: (typeof import("~icons/tabler/arrows-maximize.jsx"))["default"]
const IconTablerArrowsMinimize: (typeof import("~icons/tabler/arrows-minimize.jsx"))["default"]
const IconTablerArrowsMaximize: typeof import('~icons/tabler/arrows-maximize.jsx')['default']
const IconTablerArrowsMinimize: typeof import('~icons/tabler/arrows-minimize.jsx')['default']
const IconTablerArrowsSearch: (typeof import("~icons/tabler/arrows-search.jsx"))["default"]
const IconTablerArrowsShuffle: (typeof import("~icons/tabler/arrows-shuffle.jsx"))["default"]
const IconTablerArrowsShuffle2: typeof import('~icons/tabler/arrows-shuffle2.jsx')['default']
@@ -146,6 +146,8 @@ declare global {
const IconTablerInfoSmall: (typeof import("~icons/tabler/info-small.jsx"))["default"]
const IconTablerInfoSquareRounded: (typeof import("~icons/tabler/info-square-rounded.jsx"))["default"]
const IconTablerJetpack: typeof import('~icons/tabler/jetpack.jsx')['default']
const IconTablerLayoutSidebarLeftExpand: typeof import('~icons/tabler/layout-sidebar-left-expand.jsx')['default']
const IconTablerLayoutSidebarRightExpand: typeof import('~icons/tabler/layout-sidebar-right-expand.jsx')['default']
const IconTablerLetterB: typeof import('~icons/tabler/letter-b.jsx')['default']
const IconTablerLetterG: typeof import('~icons/tabler/letter-g.jsx')['default']
const IconTablerLetterK: typeof import('~icons/tabler/letter-k.jsx')['default']
@@ -233,7 +235,7 @@ declare global {
const IconTablerWallet: typeof import('~icons/tabler/wallet.jsx')['default']
const IconTablerWeight: typeof import('~icons/tabler/weight.jsx')['default']
const IconTablerWind: typeof import('~icons/tabler/wind.jsx')['default']
const IconTablerX: (typeof import("~icons/tabler/x.jsx"))["default"]
const IconTablerX: typeof import('~icons/tabler/x.jsx')['default']
const IconTablerZoomFilled: typeof import('~icons/tabler/zoom-filled.jsx')['default']
const Index: typeof import('solid-js')['Index']
const Link: typeof import('@solidjs/router')['Link']
+1 -3
View File
@@ -15,11 +15,9 @@ export default defineConfig({
solidPlugin(),
VitePWA({
registerType: "prompt",
injectRegister: false,
workbox: {
skipWaiting: true,
clientsClaim: true,
cleanupOutdatedCaches: true,
globPatterns: ["**/*.{js,css,html,ico,png,svg,json,woff2,ttf,md}"],
},
manifest: false,
+1 -1
View File
@@ -1272,7 +1272,7 @@ dependencies = [
[[package]]
name = "parser"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"allocative",
"bincode",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "parser"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+2 -2
View File
@@ -1463,7 +1463,7 @@ dependencies = [
[[package]]
name = "parser"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"allocative",
"bincode",
@@ -1907,7 +1907,7 @@ dependencies = [
[[package]]
name = "server"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"axum",
"bincode",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "server"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
[dependencies]
+1 -1
View File
@@ -17,7 +17,7 @@ pub struct Route {
#[derive(Clone, Default, Deref, DerefMut)]
pub struct Routes(pub Grouped<HashMap<String, Route>>);
const DATASETS_PATH: &str = "../datasets_bkp";
const DATASETS_PATH: &str = "../datasets";
impl Routes {
pub fn build() -> Self {