Compare commits
2 commits
main
...
astra/styl
Author | SHA1 | Date | |
---|---|---|---|
62f9551d2f | |||
ca5c7064cf |
14 changed files with 209 additions and 584 deletions
21
LICENSE
21
LICENSE
|
@ -1,21 +0,0 @@
|
||||||
# MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2025 Witchcraft Systems
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
61
README.md
61
README.md
|
@ -1,62 +1,3 @@
|
||||||
# pds-dash
|
# pds-dash
|
||||||
|
|
||||||
a frontend dashboard with stats for your ATProto PDS.
|
Frontend with stats for your ATProto PDS
|
||||||
|
|
||||||
## setup
|
|
||||||
|
|
||||||
### prerequisites
|
|
||||||
|
|
||||||
- [deno](https://deno.com/manual/getting_started/installation)
|
|
||||||
|
|
||||||
### installing
|
|
||||||
|
|
||||||
clone the repo, install dependencies using deno:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
deno install
|
|
||||||
```
|
|
||||||
|
|
||||||
### development server
|
|
||||||
|
|
||||||
local develompent server with hot reloading:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
deno task dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### building
|
|
||||||
|
|
||||||
to build the optimized bundle run:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
deno task build
|
|
||||||
```
|
|
||||||
|
|
||||||
the output will be in the `dist/` directory.
|
|
||||||
|
|
||||||
## deploying
|
|
||||||
|
|
||||||
we use our own CI/CD workflow at [`.forgejo/workflows/deploy.yaml`](.forgejo/workflows/deploy.yaml), but it boils down to building the project bundle and deploying it to a web server. it'll probably make more sense to host it on the same domain as your PDS, but it doesn't affect anything if you host it somewhere else.
|
|
||||||
|
|
||||||
## configuring
|
|
||||||
|
|
||||||
[`config.ts`](config.ts) is the main configuration file, you can find more information in the file itself.
|
|
||||||
|
|
||||||
## theming
|
|
||||||
|
|
||||||
the colors are designated in [`src/app.css`](src/app.css) as variables, go crazy with them
|
|
||||||
|
|
||||||
the rest is done by editing the css files and style tags directly, good luck
|
|
||||||
|
|
||||||
relevant files:
|
|
||||||
|
|
||||||
- [`src/App.svelte`](src/App.svelte)
|
|
||||||
- [`src/app.css`](src/app.css)
|
|
||||||
- [`src/lib/AccountComponent.svelte`](src/lib/AccountComponent.svelte)
|
|
||||||
- [`src/lib/PostComponent.svelte`](src/lib/PostComponent.svelte)
|
|
||||||
|
|
||||||
the favicon is located at [`public/favicon.ico`](public/favicon.ico)
|
|
||||||
|
|
||||||
## license
|
|
||||||
|
|
||||||
MIT
|
|
23
config.ts
23
config.ts
|
@ -9,29 +9,20 @@ export class Config {
|
||||||
static readonly PDS_URL: string = "https://pds.witchcraft.systems";
|
static readonly PDS_URL: string = "https://pds.witchcraft.systems";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base URL of the frontend service for linking to replies/quotes/accounts etc.
|
* The base URL of the frontend service for linking to replies
|
||||||
* @default "https://deer.social"
|
* @default "https://deer.social"
|
||||||
*/
|
*/
|
||||||
static readonly FRONTEND_URL: string = "https://deer.social";
|
static readonly FRONTEND_URL: string = "https://deer.social";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of posts to fetch from the PDS per request
|
* Maximum number of posts to show in the feed (across all users)
|
||||||
* Should be around 20 for about 10 users on the pds
|
* @default 100
|
||||||
* The more users you have, the lower the number should be
|
|
||||||
* since sorting is slow and is done on the frontend
|
|
||||||
* @default 20
|
|
||||||
*/
|
*/
|
||||||
static readonly MAX_POSTS: number = 20;
|
static readonly MAX_POSTS: number = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Footer text for the dashboard, you probably want to change this
|
* Footer text for the dashboard
|
||||||
|
* @default "Astrally projected from witchcraft.systems"
|
||||||
*/
|
*/
|
||||||
static readonly FOOTER_TEXT: string =
|
static readonly FOOTER_TEXT: string = "Astrally projected from <a href='https://witchcraft.systems' target='_blank'>witchcraft.systems</a>";
|
||||||
"Astrally projected from <a href='https://witchcraft.systems' target='_blank'>witchcraft.systems</a><br><br><a href='https://git.witchcraft.systems/scientific-witchery/pds-dash' target='_blank'>Source</a> (<a href='https://github.com/witchcraft-systems/pds-dash/' target='_blank'>github mirror</a>)";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to show the posts that are in the future
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
static readonly SHOW_FUTURE_POSTS: boolean = false;
|
|
||||||
}
|
}
|
234
deno.lock
generated
234
deno.lock
generated
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "5",
|
"version": "4",
|
||||||
"specifiers": {
|
"specifiers": {
|
||||||
"npm:@atcute/bluesky@^2.0.2": "2.0.2_@atcute+client@3.0.1",
|
"npm:@atcute/bluesky@^2.0.2": "2.0.2_@atcute+client@3.0.1",
|
||||||
"npm:@atcute/client@^3.0.1": "3.0.1",
|
"npm:@atcute/client@^3.0.1": "3.0.1",
|
||||||
|
@ -7,9 +7,7 @@
|
||||||
"npm:@sveltejs/vite-plugin-svelte@^5.0.3": "5.0.3_svelte@5.28.1__acorn@8.14.1_vite@6.3.2__picomatch@4.0.2",
|
"npm:@sveltejs/vite-plugin-svelte@^5.0.3": "5.0.3_svelte@5.28.1__acorn@8.14.1_vite@6.3.2__picomatch@4.0.2",
|
||||||
"npm:@tsconfig/svelte@^5.0.4": "5.0.4",
|
"npm:@tsconfig/svelte@^5.0.4": "5.0.4",
|
||||||
"npm:moment@^2.30.1": "2.30.1",
|
"npm:moment@^2.30.1": "2.30.1",
|
||||||
"npm:mutex-ts@^1.2.1": "1.2.1",
|
|
||||||
"npm:svelte-check@^4.1.5": "4.1.6_svelte@5.28.1__acorn@8.14.1_typescript@5.7.3",
|
"npm:svelte-check@^4.1.5": "4.1.6_svelte@5.28.1__acorn@8.14.1_typescript@5.7.3",
|
||||||
"npm:svelte-infinite-loading@^1.4.0": "1.4.0",
|
|
||||||
"npm:svelte@^5.23.1": "5.28.1_acorn@8.14.1",
|
"npm:svelte@^5.23.1": "5.28.1_acorn@8.14.1",
|
||||||
"npm:typescript@~5.7.2": "5.7.3",
|
"npm:typescript@~5.7.2": "5.7.3",
|
||||||
"npm:vite@^6.3.1": "6.3.2_picomatch@4.0.2"
|
"npm:vite@^6.3.1": "6.3.2_picomatch@4.0.2"
|
||||||
|
@ -55,129 +53,79 @@
|
||||||
"integrity": "sha512-GEhUCk9c4XbNxi+0YZHZsV4fYNd6HejfWuN4Ti4c02DauX+LyX5WY1Y3WfyZ8Pxxl0zqhs+MLtW98cMh86vv6g=="
|
"integrity": "sha512-GEhUCk9c4XbNxi+0YZHZsV4fYNd6HejfWuN4Ti4c02DauX+LyX5WY1Y3WfyZ8Pxxl0zqhs+MLtW98cMh86vv6g=="
|
||||||
},
|
},
|
||||||
"@esbuild/aix-ppc64@0.25.2": {
|
"@esbuild/aix-ppc64@0.25.2": {
|
||||||
"integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==",
|
"integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag=="
|
||||||
"os": ["aix"],
|
|
||||||
"cpu": ["ppc64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/android-arm64@0.25.2": {
|
"@esbuild/android-arm64@0.25.2": {
|
||||||
"integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==",
|
"integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w=="
|
||||||
"os": ["android"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/android-arm@0.25.2": {
|
"@esbuild/android-arm@0.25.2": {
|
||||||
"integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==",
|
"integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA=="
|
||||||
"os": ["android"],
|
|
||||||
"cpu": ["arm"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/android-x64@0.25.2": {
|
"@esbuild/android-x64@0.25.2": {
|
||||||
"integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==",
|
"integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg=="
|
||||||
"os": ["android"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/darwin-arm64@0.25.2": {
|
"@esbuild/darwin-arm64@0.25.2": {
|
||||||
"integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==",
|
"integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA=="
|
||||||
"os": ["darwin"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/darwin-x64@0.25.2": {
|
"@esbuild/darwin-x64@0.25.2": {
|
||||||
"integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==",
|
"integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA=="
|
||||||
"os": ["darwin"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/freebsd-arm64@0.25.2": {
|
"@esbuild/freebsd-arm64@0.25.2": {
|
||||||
"integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==",
|
"integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w=="
|
||||||
"os": ["freebsd"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/freebsd-x64@0.25.2": {
|
"@esbuild/freebsd-x64@0.25.2": {
|
||||||
"integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==",
|
"integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ=="
|
||||||
"os": ["freebsd"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/linux-arm64@0.25.2": {
|
"@esbuild/linux-arm64@0.25.2": {
|
||||||
"integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==",
|
"integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/linux-arm@0.25.2": {
|
"@esbuild/linux-arm@0.25.2": {
|
||||||
"integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==",
|
"integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["arm"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/linux-ia32@0.25.2": {
|
"@esbuild/linux-ia32@0.25.2": {
|
||||||
"integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==",
|
"integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["ia32"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/linux-loong64@0.25.2": {
|
"@esbuild/linux-loong64@0.25.2": {
|
||||||
"integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==",
|
"integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["loong64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/linux-mips64el@0.25.2": {
|
"@esbuild/linux-mips64el@0.25.2": {
|
||||||
"integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==",
|
"integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["mips64el"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/linux-ppc64@0.25.2": {
|
"@esbuild/linux-ppc64@0.25.2": {
|
||||||
"integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==",
|
"integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["ppc64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/linux-riscv64@0.25.2": {
|
"@esbuild/linux-riscv64@0.25.2": {
|
||||||
"integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==",
|
"integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["riscv64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/linux-s390x@0.25.2": {
|
"@esbuild/linux-s390x@0.25.2": {
|
||||||
"integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==",
|
"integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["s390x"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/linux-x64@0.25.2": {
|
"@esbuild/linux-x64@0.25.2": {
|
||||||
"integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==",
|
"integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/netbsd-arm64@0.25.2": {
|
"@esbuild/netbsd-arm64@0.25.2": {
|
||||||
"integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==",
|
"integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw=="
|
||||||
"os": ["netbsd"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/netbsd-x64@0.25.2": {
|
"@esbuild/netbsd-x64@0.25.2": {
|
||||||
"integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==",
|
"integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg=="
|
||||||
"os": ["netbsd"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/openbsd-arm64@0.25.2": {
|
"@esbuild/openbsd-arm64@0.25.2": {
|
||||||
"integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==",
|
"integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg=="
|
||||||
"os": ["openbsd"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/openbsd-x64@0.25.2": {
|
"@esbuild/openbsd-x64@0.25.2": {
|
||||||
"integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==",
|
"integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw=="
|
||||||
"os": ["openbsd"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/sunos-x64@0.25.2": {
|
"@esbuild/sunos-x64@0.25.2": {
|
||||||
"integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==",
|
"integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA=="
|
||||||
"os": ["sunos"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/win32-arm64@0.25.2": {
|
"@esbuild/win32-arm64@0.25.2": {
|
||||||
"integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==",
|
"integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q=="
|
||||||
"os": ["win32"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/win32-ia32@0.25.2": {
|
"@esbuild/win32-ia32@0.25.2": {
|
||||||
"integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==",
|
"integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg=="
|
||||||
"os": ["win32"],
|
|
||||||
"cpu": ["ia32"]
|
|
||||||
},
|
},
|
||||||
"@esbuild/win32-x64@0.25.2": {
|
"@esbuild/win32-x64@0.25.2": {
|
||||||
"integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==",
|
"integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA=="
|
||||||
"os": ["win32"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@jridgewell/gen-mapping@0.3.8": {
|
"@jridgewell/gen-mapping@0.3.8": {
|
||||||
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
|
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
|
||||||
|
@ -204,104 +152,64 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"@rollup/rollup-android-arm-eabi@4.40.0": {
|
"@rollup/rollup-android-arm-eabi@4.40.0": {
|
||||||
"integrity": "sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==",
|
"integrity": "sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg=="
|
||||||
"os": ["android"],
|
|
||||||
"cpu": ["arm"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-android-arm64@4.40.0": {
|
"@rollup/rollup-android-arm64@4.40.0": {
|
||||||
"integrity": "sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==",
|
"integrity": "sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w=="
|
||||||
"os": ["android"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-darwin-arm64@4.40.0": {
|
"@rollup/rollup-darwin-arm64@4.40.0": {
|
||||||
"integrity": "sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==",
|
"integrity": "sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ=="
|
||||||
"os": ["darwin"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-darwin-x64@4.40.0": {
|
"@rollup/rollup-darwin-x64@4.40.0": {
|
||||||
"integrity": "sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==",
|
"integrity": "sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA=="
|
||||||
"os": ["darwin"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-freebsd-arm64@4.40.0": {
|
"@rollup/rollup-freebsd-arm64@4.40.0": {
|
||||||
"integrity": "sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==",
|
"integrity": "sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg=="
|
||||||
"os": ["freebsd"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-freebsd-x64@4.40.0": {
|
"@rollup/rollup-freebsd-x64@4.40.0": {
|
||||||
"integrity": "sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==",
|
"integrity": "sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw=="
|
||||||
"os": ["freebsd"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-arm-gnueabihf@4.40.0": {
|
"@rollup/rollup-linux-arm-gnueabihf@4.40.0": {
|
||||||
"integrity": "sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==",
|
"integrity": "sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["arm"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-arm-musleabihf@4.40.0": {
|
"@rollup/rollup-linux-arm-musleabihf@4.40.0": {
|
||||||
"integrity": "sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==",
|
"integrity": "sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["arm"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-arm64-gnu@4.40.0": {
|
"@rollup/rollup-linux-arm64-gnu@4.40.0": {
|
||||||
"integrity": "sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==",
|
"integrity": "sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-arm64-musl@4.40.0": {
|
"@rollup/rollup-linux-arm64-musl@4.40.0": {
|
||||||
"integrity": "sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==",
|
"integrity": "sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-loongarch64-gnu@4.40.0": {
|
"@rollup/rollup-linux-loongarch64-gnu@4.40.0": {
|
||||||
"integrity": "sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==",
|
"integrity": "sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["loong64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-powerpc64le-gnu@4.40.0": {
|
"@rollup/rollup-linux-powerpc64le-gnu@4.40.0": {
|
||||||
"integrity": "sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==",
|
"integrity": "sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["ppc64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-riscv64-gnu@4.40.0": {
|
"@rollup/rollup-linux-riscv64-gnu@4.40.0": {
|
||||||
"integrity": "sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==",
|
"integrity": "sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["riscv64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-riscv64-musl@4.40.0": {
|
"@rollup/rollup-linux-riscv64-musl@4.40.0": {
|
||||||
"integrity": "sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==",
|
"integrity": "sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["riscv64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-s390x-gnu@4.40.0": {
|
"@rollup/rollup-linux-s390x-gnu@4.40.0": {
|
||||||
"integrity": "sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==",
|
"integrity": "sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["s390x"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-x64-gnu@4.40.0": {
|
"@rollup/rollup-linux-x64-gnu@4.40.0": {
|
||||||
"integrity": "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==",
|
"integrity": "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-linux-x64-musl@4.40.0": {
|
"@rollup/rollup-linux-x64-musl@4.40.0": {
|
||||||
"integrity": "sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==",
|
"integrity": "sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw=="
|
||||||
"os": ["linux"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-win32-arm64-msvc@4.40.0": {
|
"@rollup/rollup-win32-arm64-msvc@4.40.0": {
|
||||||
"integrity": "sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==",
|
"integrity": "sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ=="
|
||||||
"os": ["win32"],
|
|
||||||
"cpu": ["arm64"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-win32-ia32-msvc@4.40.0": {
|
"@rollup/rollup-win32-ia32-msvc@4.40.0": {
|
||||||
"integrity": "sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==",
|
"integrity": "sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA=="
|
||||||
"os": ["win32"],
|
|
||||||
"cpu": ["ia32"]
|
|
||||||
},
|
},
|
||||||
"@rollup/rollup-win32-x64-msvc@4.40.0": {
|
"@rollup/rollup-win32-x64-msvc@4.40.0": {
|
||||||
"integrity": "sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==",
|
"integrity": "sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ=="
|
||||||
"os": ["win32"],
|
|
||||||
"cpu": ["x64"]
|
|
||||||
},
|
},
|
||||||
"@sveltejs/acorn-typescript@1.0.5_acorn@8.14.1": {
|
"@sveltejs/acorn-typescript@1.0.5_acorn@8.14.1": {
|
||||||
"integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==",
|
"integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==",
|
||||||
|
@ -338,8 +246,7 @@
|
||||||
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="
|
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="
|
||||||
},
|
},
|
||||||
"acorn@8.14.1": {
|
"acorn@8.14.1": {
|
||||||
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="
|
||||||
"bin": true
|
|
||||||
},
|
},
|
||||||
"aria-query@5.3.2": {
|
"aria-query@5.3.2": {
|
||||||
"integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="
|
"integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="
|
||||||
|
@ -367,7 +274,7 @@
|
||||||
},
|
},
|
||||||
"esbuild@0.25.2": {
|
"esbuild@0.25.2": {
|
||||||
"integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==",
|
"integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==",
|
||||||
"optionalDependencies": [
|
"dependencies": [
|
||||||
"@esbuild/aix-ppc64",
|
"@esbuild/aix-ppc64",
|
||||||
"@esbuild/android-arm",
|
"@esbuild/android-arm",
|
||||||
"@esbuild/android-arm64",
|
"@esbuild/android-arm64",
|
||||||
|
@ -393,9 +300,7 @@
|
||||||
"@esbuild/win32-arm64",
|
"@esbuild/win32-arm64",
|
||||||
"@esbuild/win32-ia32",
|
"@esbuild/win32-ia32",
|
||||||
"@esbuild/win32-x64"
|
"@esbuild/win32-x64"
|
||||||
],
|
]
|
||||||
"scripts": true,
|
|
||||||
"bin": true
|
|
||||||
},
|
},
|
||||||
"esm-env@1.2.2": {
|
"esm-env@1.2.2": {
|
||||||
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="
|
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="
|
||||||
|
@ -410,15 +315,10 @@
|
||||||
"integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
|
"integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"picomatch"
|
"picomatch"
|
||||||
],
|
|
||||||
"optionalPeers": [
|
|
||||||
"picomatch"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"fsevents@2.3.3": {
|
"fsevents@2.3.3": {
|
||||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="
|
||||||
"os": ["darwin"],
|
|
||||||
"scripts": true
|
|
||||||
},
|
},
|
||||||
"is-reference@3.0.3": {
|
"is-reference@3.0.3": {
|
||||||
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
|
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
|
||||||
|
@ -447,12 +347,8 @@
|
||||||
"ms@2.1.3": {
|
"ms@2.1.3": {
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
},
|
},
|
||||||
"mutex-ts@1.2.1": {
|
|
||||||
"integrity": "sha512-OkcXgf0viuCgYdnm48kiNQ9PzC5OzISQ261svHr/Ybc2vBYC/5xfLXn44hQ+dYRX74v7MCSqV/LKPEbpYdDybw=="
|
|
||||||
},
|
|
||||||
"nanoid@3.3.11": {
|
"nanoid@3.3.11": {
|
||||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="
|
||||||
"bin": true
|
|
||||||
},
|
},
|
||||||
"picocolors@1.1.1": {
|
"picocolors@1.1.1": {
|
||||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
|
||||||
|
@ -474,9 +370,6 @@
|
||||||
"rollup@4.40.0": {
|
"rollup@4.40.0": {
|
||||||
"integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==",
|
"integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"@types/estree"
|
|
||||||
],
|
|
||||||
"optionalDependencies": [
|
|
||||||
"@rollup/rollup-android-arm-eabi",
|
"@rollup/rollup-android-arm-eabi",
|
||||||
"@rollup/rollup-android-arm64",
|
"@rollup/rollup-android-arm64",
|
||||||
"@rollup/rollup-darwin-arm64",
|
"@rollup/rollup-darwin-arm64",
|
||||||
|
@ -497,9 +390,9 @@
|
||||||
"@rollup/rollup-win32-arm64-msvc",
|
"@rollup/rollup-win32-arm64-msvc",
|
||||||
"@rollup/rollup-win32-ia32-msvc",
|
"@rollup/rollup-win32-ia32-msvc",
|
||||||
"@rollup/rollup-win32-x64-msvc",
|
"@rollup/rollup-win32-x64-msvc",
|
||||||
|
"@types/estree",
|
||||||
"fsevents"
|
"fsevents"
|
||||||
],
|
]
|
||||||
"bin": true
|
|
||||||
},
|
},
|
||||||
"sade@1.8.1": {
|
"sade@1.8.1": {
|
||||||
"integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
|
"integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
|
||||||
|
@ -520,11 +413,7 @@
|
||||||
"sade",
|
"sade",
|
||||||
"svelte",
|
"svelte",
|
||||||
"typescript"
|
"typescript"
|
||||||
],
|
]
|
||||||
"bin": true
|
|
||||||
},
|
|
||||||
"svelte-infinite-loading@1.4.0": {
|
|
||||||
"integrity": "sha512-Jo+f/yr/HmZQuIiiKKzAHVFXdAUWHW2RBbrcQTil8JVk1sCm/riy7KTJVzjBgQvHasrFQYKF84zvtc9/Y4lFYg=="
|
|
||||||
},
|
},
|
||||||
"svelte@5.28.1_acorn@8.14.1": {
|
"svelte@5.28.1_acorn@8.14.1": {
|
||||||
"integrity": "sha512-iOa9WmfNG95lSOSJdMhdjJ4Afok7IRAQYXpbnxhd5EINnXseG0GVa9j6WPght4eX78XfFez45Fi+uRglGKPV/Q==",
|
"integrity": "sha512-iOa9WmfNG95lSOSJdMhdjJ4Afok7IRAQYXpbnxhd5EINnXseG0GVa9j6WPght4eX78XfFez45Fi+uRglGKPV/Q==",
|
||||||
|
@ -553,31 +442,24 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"typescript@5.7.3": {
|
"typescript@5.7.3": {
|
||||||
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
|
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="
|
||||||
"bin": true
|
|
||||||
},
|
},
|
||||||
"vite@6.3.2_picomatch@4.0.2": {
|
"vite@6.3.2_picomatch@4.0.2": {
|
||||||
"integrity": "sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==",
|
"integrity": "sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"esbuild",
|
"esbuild",
|
||||||
"fdir",
|
"fdir",
|
||||||
|
"fsevents",
|
||||||
"picomatch",
|
"picomatch",
|
||||||
"postcss",
|
"postcss",
|
||||||
"rollup",
|
"rollup",
|
||||||
"tinyglobby"
|
"tinyglobby"
|
||||||
],
|
]
|
||||||
"optionalDependencies": [
|
|
||||||
"fsevents"
|
|
||||||
],
|
|
||||||
"bin": true
|
|
||||||
},
|
},
|
||||||
"vitefu@1.0.6_vite@6.3.2__picomatch@4.0.2": {
|
"vitefu@1.0.6_vite@6.3.2__picomatch@4.0.2": {
|
||||||
"integrity": "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==",
|
"integrity": "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"vite"
|
"vite"
|
||||||
],
|
|
||||||
"optionalPeers": [
|
|
||||||
"vite"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"zimmerframe@1.1.2": {
|
"zimmerframe@1.1.2": {
|
||||||
|
@ -593,9 +475,7 @@
|
||||||
"npm:@sveltejs/vite-plugin-svelte@^5.0.3",
|
"npm:@sveltejs/vite-plugin-svelte@^5.0.3",
|
||||||
"npm:@tsconfig/svelte@^5.0.4",
|
"npm:@tsconfig/svelte@^5.0.4",
|
||||||
"npm:moment@^2.30.1",
|
"npm:moment@^2.30.1",
|
||||||
"npm:mutex-ts@^1.2.1",
|
|
||||||
"npm:svelte-check@^4.1.5",
|
"npm:svelte-check@^4.1.5",
|
||||||
"npm:svelte-infinite-loading@^1.4.0",
|
|
||||||
"npm:svelte@^5.23.1",
|
"npm:svelte@^5.23.1",
|
||||||
"npm:typescript@~5.7.2",
|
"npm:typescript@~5.7.2",
|
||||||
"npm:vite@^6.3.1"
|
"npm:vite@^6.3.1"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
|
|
@ -13,9 +13,7 @@
|
||||||
"@atcute/bluesky": "^2.0.2",
|
"@atcute/bluesky": "^2.0.2",
|
||||||
"@atcute/client": "^3.0.1",
|
"@atcute/client": "^3.0.1",
|
||||||
"@atcute/identity-resolver": "^0.1.2",
|
"@atcute/identity-resolver": "^0.1.2",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1"
|
||||||
"mutex-ts": "^1.2.1",
|
|
||||||
"svelte-infinite-loading": "^1.4.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||||
|
|
|
@ -1,36 +1,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import PostComponent from "./lib/PostComponent.svelte";
|
import PostComponent from "./lib/PostComponent.svelte";
|
||||||
import AccountComponent from "./lib/AccountComponent.svelte";
|
import AccountComponent from "./lib/AccountComponent.svelte";
|
||||||
import InfiniteLoading from "svelte-infinite-loading";
|
import { fetchAllPosts, Post, getAllMetadataFromPds } from "./lib/pdsfetch";
|
||||||
import { getNextPosts, Post, getAllMetadataFromPds } from "./lib/pdsfetch";
|
|
||||||
import { Config } from "../config";
|
import { Config } from "../config";
|
||||||
|
const postsPromise = fetchAllPosts();
|
||||||
const accountsPromise = getAllMetadataFromPds();
|
const accountsPromise = getAllMetadataFromPds();
|
||||||
import { onMount } from "svelte";
|
|
||||||
|
|
||||||
let posts: Post[] = [];
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
// Fetch initial posts
|
|
||||||
getNextPosts().then((initialPosts) => {
|
|
||||||
posts = initialPosts;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// Infinite loading function
|
|
||||||
const onInfinite = ({
|
|
||||||
detail: { loaded, complete },
|
|
||||||
}: {
|
|
||||||
detail: { loaded: () => void; complete: () => void };
|
|
||||||
}) => {
|
|
||||||
getNextPosts().then((newPosts) => {
|
|
||||||
console.log("Loading next posts...");
|
|
||||||
if (newPosts.length > 0) {
|
|
||||||
posts = [...posts, ...newPosts];
|
|
||||||
loaded();
|
|
||||||
} else {
|
|
||||||
complete();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
@ -52,18 +26,22 @@
|
||||||
<p>Error: {error.message}</p>
|
<p>Error: {error.message}</p>
|
||||||
{/await}
|
{/await}
|
||||||
|
|
||||||
|
{#await postsPromise}
|
||||||
|
<p>Loading...</p>
|
||||||
|
{:then postsData}
|
||||||
<div id="Feed">
|
<div id="Feed">
|
||||||
<div id="spacer"></div>
|
<div id="spacer"></div>
|
||||||
{#each posts as postObject}
|
{#each postsData as postObject}
|
||||||
<PostComponent post={postObject as Post} />
|
<PostComponent post={postObject as Post} />
|
||||||
{/each}
|
{/each}
|
||||||
<InfiniteLoading on:infinite={onInfinite} distance={3000} />
|
|
||||||
<div id="spacer"></div>
|
<div id="spacer"></div>
|
||||||
</div>
|
</div>
|
||||||
|
{/await}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
/* desktop style */
|
/* desktop style */
|
||||||
|
|
||||||
#Content {
|
#Content {
|
||||||
|
@ -78,9 +56,9 @@
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
}
|
}
|
||||||
#Feed {
|
#Feed {
|
||||||
overflow-y: scroll;
|
|
||||||
width: 65%;
|
width: 65%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
overflow-y: scroll;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
@ -129,7 +107,7 @@
|
||||||
margin-top: 5%;
|
margin-top: 5%;
|
||||||
}
|
}
|
||||||
#Account {
|
#Account {
|
||||||
width: 85%;
|
width: auto;
|
||||||
padding-left: 5%;
|
padding-left: 5%;
|
||||||
padding-right: 5%;
|
padding-right: 5%;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
@ -143,7 +121,7 @@
|
||||||
margin-left: 10%;
|
margin-left: 10%;
|
||||||
margin-right: 10%;
|
margin-right: 10%;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
overflow-y: visible;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#spacer {
|
#spacer {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "ProggyClean";
|
font-family: 'ProggyClean';
|
||||||
src: url(https://witchcraft.systems/ProggyCleanNerdFont-Regular.ttf);
|
src: url(https://witchcraft.systems/ProggyCleanNerdFont-Regular.ttf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,14 +62,10 @@ body {
|
||||||
min-width: 320px;
|
min-width: 320px;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
font-family: "ProggyClean", monospace;
|
font-family: 'ProggyClean', monospace;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
border-color: var(--border-color);
|
border-color: var(--border-color);
|
||||||
overflow-wrap: break-word;
|
|
||||||
word-wrap: normal;
|
|
||||||
word-break: break-word;
|
|
||||||
hyphens: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
@ -79,7 +75,6 @@ h1 {
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
max-width: 1400px;
|
max-width: 1400px;
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
|
|
@ -32,18 +32,17 @@
|
||||||
#accountName {
|
#accountName {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
max-width: 80%;
|
|
||||||
|
|
||||||
/* replace overflow with ellipsis */
|
/* replace overflow with ellipsis */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
max-width: 80%;
|
||||||
}
|
}
|
||||||
#avatar {
|
#avatar {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
object-fit: cover;
|
|
||||||
border-right: var(--border-color) 1px solid;
|
border-right: var(--border-color) 1px solid;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -113,7 +113,7 @@
|
||||||
<div id="carouselControls">
|
<div id="carouselControls">
|
||||||
<button
|
<button
|
||||||
id="prevBtn"
|
id="prevBtn"
|
||||||
onclick={prevImage}
|
on:click={prevImage}
|
||||||
disabled={currentImageIndex === 0}>←</button
|
disabled={currentImageIndex === 0}>←</button
|
||||||
>
|
>
|
||||||
<div id="carouselIndicators">
|
<div id="carouselIndicators">
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
id="nextBtn"
|
id="nextBtn"
|
||||||
onclick={nextImage}
|
on:click={nextImage}
|
||||||
disabled={currentImageIndex === post.imagesCid.length - 1}
|
disabled={currentImageIndex === post.imagesCid.length - 1}
|
||||||
>→</button
|
>→</button
|
||||||
>
|
>
|
||||||
|
@ -141,17 +141,11 @@
|
||||||
controls
|
controls
|
||||||
></video>
|
></video>
|
||||||
{/if}
|
{/if}
|
||||||
{#if post.gifLink}
|
|
||||||
<img
|
|
||||||
id="embedVideo"
|
|
||||||
src="{post.gifLink}"
|
|
||||||
alt="Post GIF"
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
@ -177,21 +171,12 @@
|
||||||
height: 60px;
|
height: 60px;
|
||||||
}
|
}
|
||||||
#displayName {
|
#displayName {
|
||||||
display: block;
|
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow-wrap:normal;
|
|
||||||
word-wrap: break-word;
|
|
||||||
word-break: break-word;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
#handle {
|
#handle {
|
||||||
display: block;
|
|
||||||
color: var(--border-color);
|
color: var(--border-color);
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -212,7 +197,6 @@
|
||||||
background-color: var(--content-background-color);
|
background-color: var(--content-background-color);
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
white-space: pre-line;
|
|
||||||
}
|
}
|
||||||
#replyingText {
|
#replyingText {
|
||||||
font-size: 0.7em;
|
font-size: 0.7em;
|
||||||
|
@ -229,30 +213,18 @@
|
||||||
#postText {
|
#postText {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow-wrap: break-word;
|
|
||||||
word-wrap: normal;
|
|
||||||
word-break: break-word;
|
|
||||||
hyphens: none;
|
|
||||||
}
|
}
|
||||||
#headerText {
|
#headerText {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
word-break: break-word;
|
overflow-wrap: break-word;
|
||||||
max-width: 80%;
|
|
||||||
max-height: 95%;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
align-self: flex-start;
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: auto;
|
|
||||||
}
|
}
|
||||||
#avatar {
|
#avatar {
|
||||||
height: 60px;
|
height: 100%;
|
||||||
width: 60px;
|
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
overflow: hidden;
|
|
||||||
object-fit: cover;
|
|
||||||
border-right: var(--border-color) 1px solid;
|
border-right: var(--border-color) 1px solid;
|
||||||
}
|
}
|
||||||
#carouselContainer {
|
#carouselContainer {
|
||||||
|
|
|
@ -13,21 +13,16 @@ import {
|
||||||
WebDidDocumentResolver,
|
WebDidDocumentResolver,
|
||||||
} from "@atcute/identity-resolver";
|
} from "@atcute/identity-resolver";
|
||||||
import { Config } from "../../config";
|
import { Config } from "../../config";
|
||||||
import { Mutex } from "mutex-ts"
|
|
||||||
// import { ComAtprotoRepoListRecords.Record } from "@atcute/client/lexicons";
|
// import { ComAtprotoRepoListRecords.Record } from "@atcute/client/lexicons";
|
||||||
// import { AppBskyFeedPost } from "@atcute/client/lexicons";
|
// import { AppBskyFeedPost } from "@atcute/client/lexicons";
|
||||||
// import { AppBskyActorDefs } from "@atcute/client/lexicons";
|
// import { AppBskyActorDefs } from "@atcute/client/lexicons";
|
||||||
|
|
||||||
interface AccountMetadata {
|
interface AccountMetadata {
|
||||||
did: At.Did;
|
did: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
handle: string;
|
handle: string;
|
||||||
avatarCid: string | null;
|
avatarCid: string | null;
|
||||||
currentCursor?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let accountsMetadata: AccountMetadata[] = [];
|
|
||||||
|
|
||||||
interface atUriObject {
|
interface atUriObject {
|
||||||
repo: string;
|
repo: string;
|
||||||
collection: string;
|
collection: string;
|
||||||
|
@ -47,7 +42,6 @@ class Post {
|
||||||
replyingUri: atUriObject | null;
|
replyingUri: atUriObject | null;
|
||||||
imagesCid: string[] | null;
|
imagesCid: string[] | null;
|
||||||
videosLinkCid: string | null;
|
videosLinkCid: string | null;
|
||||||
gifLink: string | null;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
record: ComAtprotoRepoListRecords.Record,
|
record: ComAtprotoRepoListRecords.Record,
|
||||||
|
@ -71,11 +65,10 @@ class Post {
|
||||||
this.quotingUri = null;
|
this.quotingUri = null;
|
||||||
this.imagesCid = null;
|
this.imagesCid = null;
|
||||||
this.videosLinkCid = null;
|
this.videosLinkCid = null;
|
||||||
this.gifLink = null;
|
|
||||||
switch (post.embed?.$type) {
|
switch (post.embed?.$type) {
|
||||||
case "app.bsky.embed.images":
|
case "app.bsky.embed.images":
|
||||||
this.imagesCid = post.embed.images.map(
|
this.imagesCid = post.embed.images.map((imageRecord: any) =>
|
||||||
(imageRecord: any) => imageRecord.image.ref.$link,
|
imageRecord.image.ref.$link
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "app.bsky.embed.video":
|
case "app.bsky.embed.video":
|
||||||
|
@ -88,8 +81,8 @@ class Post {
|
||||||
this.quotingUri = processAtUri(post.embed.record.record.uri);
|
this.quotingUri = processAtUri(post.embed.record.record.uri);
|
||||||
switch (post.embed.media.$type) {
|
switch (post.embed.media.$type) {
|
||||||
case "app.bsky.embed.images":
|
case "app.bsky.embed.images":
|
||||||
this.imagesCid = post.embed.media.images.map(
|
this.imagesCid = post.embed.media.images.map((imageRecord) =>
|
||||||
(imageRecord) => imageRecord.image.ref.$link,
|
imageRecord.image.ref.$link
|
||||||
);
|
);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -99,11 +92,6 @@ class Post {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "app.bsky.embed.external": // assuming that external embeds are gifs for now
|
|
||||||
if (post.embed.external.uri.includes(".gif")) {
|
|
||||||
this.gifLink = post.embed.external.uri;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,11 +115,9 @@ const getDidsFromPDS = async (): Promise<At.Did[]> => {
|
||||||
const { data } = await rpc.get("com.atproto.sync.listRepos", {
|
const { data } = await rpc.get("com.atproto.sync.listRepos", {
|
||||||
params: {},
|
params: {},
|
||||||
});
|
});
|
||||||
return data.repos.map((repo: any) => repo.did) as At.Did[];
|
return data.repos.map((repo: any) => (repo.did)) as At.Did[];
|
||||||
};
|
};
|
||||||
const getAccountMetadata = async (
|
const getAccountMetadata = async (did: `did:${string}:${string}`) : Promise<AccountMetadata> => {
|
||||||
did: `did:${string}:${string}`,
|
|
||||||
) => {
|
|
||||||
// gonna assume self exists in the app.bsky.actor.profile
|
// gonna assume self exists in the app.bsky.actor.profile
|
||||||
try {
|
try {
|
||||||
const { data } = await rpc.get("com.atproto.repo.getRecord", {
|
const { data } = await rpc.get("com.atproto.repo.getRecord", {
|
||||||
|
@ -153,9 +139,15 @@ const getAccountMetadata = async (
|
||||||
account.avatarCid = value.avatar.ref["$link"];
|
account.avatarCid = value.avatar.ref["$link"];
|
||||||
}
|
}
|
||||||
return account;
|
return account;
|
||||||
} catch (e) {
|
}
|
||||||
|
catch (e) {
|
||||||
console.error(`Error fetching metadata for ${did}:`, e);
|
console.error(`Error fetching metadata for ${did}:`, e);
|
||||||
return null;
|
return {
|
||||||
|
did: "error",
|
||||||
|
displayName: "",
|
||||||
|
avatarCid: null,
|
||||||
|
handle: "error",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -166,7 +158,31 @@ const getAllMetadataFromPds = async (): Promise<AccountMetadata[]> => {
|
||||||
return await getAccountMetadata(repo);
|
return await getAccountMetadata(repo);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
return metadata.filter((account) => account !== null) as AccountMetadata[];
|
return metadata.filter(account => account.did !== "error");
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchPosts = async (did: string) => {
|
||||||
|
try {
|
||||||
|
const { data } = await rpc.get("com.atproto.repo.listRecords", {
|
||||||
|
params: {
|
||||||
|
repo: did as At.Identifier,
|
||||||
|
collection: "app.bsky.feed.post",
|
||||||
|
limit: Config.MAX_POSTS,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
records: data.records as ComAtprotoRepoListRecords.Record[],
|
||||||
|
did: did,
|
||||||
|
error: false
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Error fetching posts for ${did}:`, e);
|
||||||
|
return {
|
||||||
|
records: [],
|
||||||
|
did: did,
|
||||||
|
error: true
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const identityResolve = async (did: At.Did) => {
|
const identityResolve = async (did: At.Did) => {
|
||||||
|
@ -202,151 +218,27 @@ const blueskyHandleFromDid = async (did: At.Did) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
interface PostsAcc {
|
const fetchAllPosts = async () => {
|
||||||
posts: ComAtprotoRepoListRecords.Record[];
|
const users: AccountMetadata[] = await getAllMetadataFromPds();
|
||||||
account: AccountMetadata;
|
const postRecords = await Promise.all(
|
||||||
}
|
users.map(async (metadata: AccountMetadata) =>
|
||||||
const getCutoffDate = (postAccounts: PostsAcc[]) => {
|
await fetchPosts(metadata.did)
|
||||||
const now = Date.now();
|
),
|
||||||
let cutoffDate: Date | null = null;
|
|
||||||
postAccounts.forEach((postAcc) => {
|
|
||||||
const latestPost = new Date(
|
|
||||||
(postAcc.posts[postAcc.posts.length - 1].value as AppBskyFeedPost.Record)
|
|
||||||
.createdAt,
|
|
||||||
);
|
);
|
||||||
if (!cutoffDate) {
|
const validPostRecords = postRecords.filter(record => !record.error);
|
||||||
cutoffDate = latestPost;
|
const posts: Post[] = validPostRecords.flatMap((userFetch) =>
|
||||||
} else {
|
userFetch.records.map((record) => {
|
||||||
if (latestPost > cutoffDate) {
|
const user = users.find((user: AccountMetadata) =>
|
||||||
cutoffDate = latestPost;
|
user.did == userFetch.did
|
||||||
}
|
);
|
||||||
}
|
if (!user) {
|
||||||
});
|
throw new Error(`User with DID ${userFetch.did} not found`);
|
||||||
if (cutoffDate) {
|
|
||||||
return cutoffDate;
|
|
||||||
} else {
|
|
||||||
return new Date(now);
|
|
||||||
}
|
}
|
||||||
|
return new Post(record, user);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
posts.sort((a, b) => b.timestamp - a.timestamp);
|
||||||
|
return posts.slice(0, Config.MAX_POSTS);
|
||||||
};
|
};
|
||||||
|
export { fetchAllPosts, getAllMetadataFromPds, Post };
|
||||||
const filterPostsByDate = (posts: PostsAcc[], cutoffDate: Date) => {
|
|
||||||
// filter posts for each account that are older than the cutoff date and save the cursor of the last post included
|
|
||||||
const filteredPosts: PostsAcc[] = posts.map((postAcc) => {
|
|
||||||
const filtered = postAcc.posts.filter((post) => {
|
|
||||||
const postDate = new Date(
|
|
||||||
(post.value as AppBskyFeedPost.Record).createdAt,
|
|
||||||
);
|
|
||||||
return postDate >= cutoffDate;
|
|
||||||
});
|
|
||||||
if (filtered.length > 0) {
|
|
||||||
postAcc.account.currentCursor = processAtUri(filtered[filtered.length - 1].uri).rkey;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
posts: filtered,
|
|
||||||
account: postAcc.account,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return filteredPosts;
|
|
||||||
};
|
|
||||||
|
|
||||||
const postsMutex = new Mutex();
|
|
||||||
// nightmare function. However it works so I am not touching it
|
|
||||||
const getNextPosts = async () => {
|
|
||||||
const release = await postsMutex.obtain();
|
|
||||||
if (!accountsMetadata.length) {
|
|
||||||
accountsMetadata = await getAllMetadataFromPds();
|
|
||||||
}
|
|
||||||
|
|
||||||
const postsAcc: PostsAcc[] = await Promise.all(
|
|
||||||
accountsMetadata.map(async (account) => {
|
|
||||||
const posts = await fetchPostsForUser(
|
|
||||||
account.did,
|
|
||||||
account.currentCursor || null,
|
|
||||||
);
|
|
||||||
if (posts) {
|
|
||||||
return {
|
|
||||||
posts: posts,
|
|
||||||
account: account,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
posts: [],
|
|
||||||
account: account,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
const recordsFiltered = postsAcc.filter((postAcc) =>
|
|
||||||
postAcc.posts.length > 0
|
|
||||||
);
|
|
||||||
const cutoffDate = getCutoffDate(recordsFiltered);
|
|
||||||
const recordsCutoff = filterPostsByDate(recordsFiltered, cutoffDate);
|
|
||||||
// update the accountMetadata with the new cursor
|
|
||||||
accountsMetadata = accountsMetadata.map((account) => {
|
|
||||||
const postAcc = recordsCutoff.find(
|
|
||||||
(postAcc) => postAcc.account.did == account.did,
|
|
||||||
);
|
|
||||||
if (postAcc) {
|
|
||||||
account.currentCursor = postAcc.account.currentCursor;
|
|
||||||
}
|
|
||||||
return account;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// throw the records in a big single array
|
|
||||||
let records = recordsCutoff.flatMap((postAcc) => postAcc.posts);
|
|
||||||
// sort the records by timestamp
|
|
||||||
records = records.sort((a, b) => {
|
|
||||||
const aDate = new Date(
|
|
||||||
(a.value as AppBskyFeedPost.Record).createdAt,
|
|
||||||
).getTime();
|
|
||||||
const bDate = new Date(
|
|
||||||
(b.value as AppBskyFeedPost.Record).createdAt,
|
|
||||||
).getTime();
|
|
||||||
return bDate - aDate;
|
|
||||||
});
|
|
||||||
// filter out posts that are in the future
|
|
||||||
if (!Config.SHOW_FUTURE_POSTS) {
|
|
||||||
const now = Date.now();
|
|
||||||
records = records.filter((post) => {
|
|
||||||
const postDate = new Date(
|
|
||||||
(post.value as AppBskyFeedPost.Record).createdAt,
|
|
||||||
).getTime();
|
|
||||||
return postDate <= now;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const newPosts = records.map((record) => {
|
|
||||||
const account = accountsMetadata.find(
|
|
||||||
(account) => account.did == processAtUri(record.uri).repo,
|
|
||||||
);
|
|
||||||
if (!account) {
|
|
||||||
throw new Error(
|
|
||||||
`Account with DID ${processAtUri(record.uri).repo} not found`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return new Post(record, account);
|
|
||||||
});
|
|
||||||
// release the mutex
|
|
||||||
release();
|
|
||||||
return newPosts;
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchPostsForUser = async (did: At.Did, cursor: string | null) => {
|
|
||||||
try {
|
|
||||||
const { data } = await rpc.get("com.atproto.repo.listRecords", {
|
|
||||||
params: {
|
|
||||||
repo: did as At.Identifier,
|
|
||||||
collection: "app.bsky.feed.post",
|
|
||||||
limit: Config.MAX_POSTS,
|
|
||||||
cursor: cursor || undefined,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return data.records as ComAtprotoRepoListRecords.Record[];
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`Error fetching posts for ${did}:`, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export { getAllMetadataFromPds, getNextPosts, Post };
|
|
||||||
export type { AccountMetadata };
|
export type { AccountMetadata };
|
||||||
|
|
12
src/main.ts
12
src/main.ts
|
@ -1,9 +1,9 @@
|
||||||
import { mount } from "svelte";
|
import { mount } from 'svelte'
|
||||||
import "./app.css";
|
import './app.css'
|
||||||
import App from "./App.svelte";
|
import App from './App.svelte'
|
||||||
|
|
||||||
const app = mount(App, {
|
const app = mount(App, {
|
||||||
target: document.getElementById("app")!,
|
target: document.getElementById('app')!,
|
||||||
});
|
})
|
||||||
|
|
||||||
export default app;
|
export default app
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
|
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
|
||||||
// for more information about preprocessors
|
// for more information about preprocessors
|
||||||
preprocess: vitePreprocess(),
|
preprocess: vitePreprocess(),
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from 'vite'
|
||||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [svelte()],
|
plugins: [svelte()],
|
||||||
});
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue