feat: init impl

This commit is contained in:
dusk 2023-04-21 22:35:25 +03:00
parent 7f7d77749e
commit a4999bb665
Signed by: dusk
GPG Key ID: 1D8F8FAF2294D6EA
46 changed files with 2740 additions and 401 deletions

13
.eslintignore Normal file
View File

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

20
.eslintrc.cjs Normal file
View File

@ -0,0 +1,20 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['*.cjs'],
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
settings: {
'svelte3/typescript': () => require('typescript')
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020
},
env: {
browser: true,
es2017: true,
node: true
}
};

13
.gitignore vendored
View File

@ -1,2 +1,11 @@
/.direnv .DS_Store
/.helix node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
/.direnv

1
.npmrc Normal file
View File

@ -0,0 +1 @@
engine-strict=true

13
.prettierignore Normal file
View File

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

9
.prettierrc Normal file
View File

@ -0,0 +1,9 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"svelte.enable-ts-plugin": true,
"editor.tabSize": 2
}

View File

@ -1,11 +1,38 @@
# fresh project # create-svelte
### Usage Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
Start the project: ## Creating a project
``` If you're seeing this, you've probably already done this step. Congrats!
deno task start
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
``` ```
This will watch the project directory and restart as necessary. ## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

View File

@ -1,12 +0,0 @@
import { JSX } from "preact";
export default function Button(props: JSX.HTMLAttributes<HTMLButtonElement>) {
return (
<button
{...props}
class={`px-3 py-2 bg-white rounded border(gray-500 2) hover:bg-gray-200 active:bg-gray-300 disabled:(opacity-50 cursor-not-allowed) ${
props.class ?? ""
}`}
/>
);
}

View File

@ -1,12 +0,0 @@
import { JSX } from "preact";
export default function Center(props: JSX.HTMLAttributes<HTMLDivElement>) {
return (
<div
{...props}
class={`flex items-center justify-center h-full w-full ${
props.class ?? ""
}`}
/>
);
}

View File

@ -1,12 +0,0 @@
import { JSX } from "preact";
export default function Input(props: JSX.HTMLAttributes<HTMLInputElement>) {
return (
<input
{...props}
class={`px-3 py-2 bg-white rounded border(gray-500 2) disabled:(opacity-50 cursor-not-allowed) ${
props.class ?? ""
}`}
/>
);
}

View File

@ -1,10 +0,0 @@
{
"tasks": {
"start": "deno run -A --watch=static/,routes/ dev.ts"
},
"importMap": "./import_map.json",
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact"
}
}

151
deno.lock
View File

@ -1,151 +0,0 @@
{
"version": "2",
"remote": {
"https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74",
"https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49",
"https://deno.land/std@0.140.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f",
"https://deno.land/std@0.140.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d",
"https://deno.land/std@0.140.0/fs/expand_glob.ts": "0c10130d67c9b02164b03df8e43c6d6defbf8e395cb69d09e84a8586e6d72ac3",
"https://deno.land/std@0.140.0/fs/walk.ts": "117403ccd21fd322febe56ba06053b1ad5064c802170f19b1ea43214088fe95f",
"https://deno.land/std@0.140.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
"https://deno.land/std@0.140.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
"https://deno.land/std@0.140.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b",
"https://deno.land/std@0.140.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
"https://deno.land/std@0.140.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
"https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d",
"https://deno.land/std@0.140.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44",
"https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
"https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757",
"https://deno.land/std@0.173.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
"https://deno.land/std@0.173.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
"https://deno.land/std@0.173.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
"https://deno.land/std@0.173.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
"https://deno.land/std@0.173.0/path/_util.ts": "86c2375a996c1931b2f2ac71fefd5ddf0cf0e579fa4ab12d3e4c552d4223b8d8",
"https://deno.land/std@0.173.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
"https://deno.land/std@0.173.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1",
"https://deno.land/std@0.173.0/path/mod.ts": "4b83694ac500d7d31b0cdafc927080a53dc0c3027eb2895790fb155082b0d232",
"https://deno.land/std@0.173.0/path/posix.ts": "0874b341c2c6968ca38d323338b8b295ea1dae10fa872a768d812e2e7d634789",
"https://deno.land/std@0.173.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1",
"https://deno.land/std@0.173.0/path/win32.ts": "672942919dd66ce1b8c224e77d3447e2ad8254eaff13fe6946420a9f78fa141e",
"https://deno.land/std@0.177.0/async/abortable.ts": "73acfb3ed7261ce0d930dbe89e43db8d34e017b063cf0eaa7d215477bf53442e",
"https://deno.land/std@0.177.0/async/deadline.ts": "c5facb0b404eede83e38bd2717ea8ab34faa2ffb20ef87fd261fcba32ba307aa",
"https://deno.land/std@0.177.0/async/debounce.ts": "adab11d04ca38d699444ac8a9d9856b4155e8dda2afd07ce78276c01ea5a4332",
"https://deno.land/std@0.177.0/async/deferred.ts": "42790112f36a75a57db4a96d33974a936deb7b04d25c6084a9fa8a49f135def8",
"https://deno.land/std@0.177.0/async/delay.ts": "73aa04cec034c84fc748c7be49bb15cac3dd43a57174bfdb7a4aec22c248f0dd",
"https://deno.land/std@0.177.0/async/mod.ts": "f04344fa21738e5ad6bea37a6bfffd57c617c2d372bb9f9dcfd118a1b622e576",
"https://deno.land/std@0.177.0/async/mux_async_iterator.ts": "70c7f2ee4e9466161350473ad61cac0b9f115cff4c552eaa7ef9d50c4cbb4cc9",
"https://deno.land/std@0.177.0/async/pool.ts": "fd082bd4aaf26445909889435a5c74334c017847842ec035739b4ae637ae8260",
"https://deno.land/std@0.177.0/async/retry.ts": "5efa3ba450ac0c07a40a82e2df296287b5013755d232049efd7ea2244f15b20f",
"https://deno.land/std@0.177.0/async/tee.ts": "47e42d35f622650b02234d43803d0383a89eb4387e1b83b5a40106d18ae36757",
"https://deno.land/std@0.177.0/http/server.ts": "cbb17b594651215ba95c01a395700684e569c165a567e4e04bba327f41197433",
"https://deno.land/std@0.178.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
"https://deno.land/std@0.178.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
"https://deno.land/std@0.178.0/async/abortable.ts": "73acfb3ed7261ce0d930dbe89e43db8d34e017b063cf0eaa7d215477bf53442e",
"https://deno.land/std@0.178.0/async/deadline.ts": "c5facb0b404eede83e38bd2717ea8ab34faa2ffb20ef87fd261fcba32ba307aa",
"https://deno.land/std@0.178.0/async/debounce.ts": "adab11d04ca38d699444ac8a9d9856b4155e8dda2afd07ce78276c01ea5a4332",
"https://deno.land/std@0.178.0/async/deferred.ts": "42790112f36a75a57db4a96d33974a936deb7b04d25c6084a9fa8a49f135def8",
"https://deno.land/std@0.178.0/async/delay.ts": "73aa04cec034c84fc748c7be49bb15cac3dd43a57174bfdb7a4aec22c248f0dd",
"https://deno.land/std@0.178.0/async/mod.ts": "f04344fa21738e5ad6bea37a6bfffd57c617c2d372bb9f9dcfd118a1b622e576",
"https://deno.land/std@0.178.0/async/mux_async_iterator.ts": "70c7f2ee4e9466161350473ad61cac0b9f115cff4c552eaa7ef9d50c4cbb4cc9",
"https://deno.land/std@0.178.0/async/pool.ts": "fd082bd4aaf26445909889435a5c74334c017847842ec035739b4ae637ae8260",
"https://deno.land/std@0.178.0/async/retry.ts": "5efa3ba450ac0c07a40a82e2df296287b5013755d232049efd7ea2244f15b20f",
"https://deno.land/std@0.178.0/async/tee.ts": "47e42d35f622650b02234d43803d0383a89eb4387e1b83b5a40106d18ae36757",
"https://deno.land/std@0.178.0/flags/mod.ts": "d1cdefa18472ef69858a17df5cf7c98445ed27ac10e1460183081303b0ebc270",
"https://deno.land/std@0.178.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32",
"https://deno.land/std@0.178.0/fs/walk.ts": "ea95ffa6500c1eda6b365be488c056edc7c883a1db41ef46ec3bf057b1c0fe32",
"https://deno.land/std@0.178.0/http/http_status.ts": "8a7bcfe3ac025199ad804075385e57f63d055b2aed539d943ccc277616d6f932",
"https://deno.land/std@0.178.0/http/server.ts": "cbb17b594651215ba95c01a395700684e569c165a567e4e04bba327f41197433",
"https://deno.land/std@0.178.0/media_types/_db.ts": "7606d83e31f23ce1a7968cbaee852810c2cf477903a095696cdc62eaab7ce570",
"https://deno.land/std@0.178.0/media_types/_util.ts": "916efbd30b6148a716f110e67a4db29d6949bf4048997b754415dd7e42c52378",
"https://deno.land/std@0.178.0/media_types/content_type.ts": "c682589a0aeb016bfed355cc1ed6fbb3ead2ea48fc0000ac5de6a5730613ad1c",
"https://deno.land/std@0.178.0/media_types/extension.ts": "7a4ef2813d7182f724a941f38161525996e4a67abc3cf6a0f9bc2168d73a0f0e",
"https://deno.land/std@0.178.0/media_types/extensions_by_type.ts": "4358023feac696e6e9d49c0f1e76a859f03ca254df57812f31f8536890c3a443",
"https://deno.land/std@0.178.0/media_types/format_media_type.ts": "1e35e16562e5c417401ffc388a9f8f421f97f0ee06259cbe990c51bae4e6c7a8",
"https://deno.land/std@0.178.0/media_types/get_charset.ts": "8be15a1fd31a545736b91ace56d0e4c66ea0d7b3fdc5c90760e8202e7b4b1fad",
"https://deno.land/std@0.178.0/media_types/mod.ts": "d3f0b99f85053bc0b98ecc24eaa3546dfa09b856dc0bbaf60d8956d2cdd710c8",
"https://deno.land/std@0.178.0/media_types/parse_media_type.ts": "bed260d868ea271445ae41d748e7afed9b5a7f407d2777ead08cecf73e9278de",
"https://deno.land/std@0.178.0/media_types/type_by_extension.ts": "6076a7fc63181d70f92ec582fdea2c927eb2cfc7f9c9bee9d6add2aca86f2355",
"https://deno.land/std@0.178.0/media_types/vendor/mime-db.v1.52.0.ts": "6925bbcae81ca37241e3f55908d0505724358cda3384eaea707773b2c7e99586",
"https://deno.land/std@0.178.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
"https://deno.land/std@0.178.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
"https://deno.land/std@0.178.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0",
"https://deno.land/std@0.178.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
"https://deno.land/std@0.178.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1",
"https://deno.land/std@0.178.0/path/mod.ts": "4b83694ac500d7d31b0cdafc927080a53dc0c3027eb2895790fb155082b0d232",
"https://deno.land/std@0.178.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d",
"https://deno.land/std@0.178.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1",
"https://deno.land/std@0.178.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba",
"https://deno.land/std@0.178.0/semver/mod.ts": "409a2691f5a411c34e917c1e6d445a6d1d53f3fadf660e44a99dd0bf9b2ef412",
"https://deno.land/std@0.182.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
"https://deno.land/std@0.182.0/datetime/to_imf.ts": "8f9c0af8b167031ffe2e03da01a12a3b0672cc7562f89c61942a0ab0129771b2",
"https://deno.land/std@0.182.0/http/cookie.ts": "934f92d871d50852dbd7a836d721df5a9527b14381db16001b40991d30174ee4",
"https://deno.land/x/code_block_writer@11.0.3/mod.ts": "2c3448060e47c9d08604c8f40dee34343f553f33edcdfebbf648442be33205e5",
"https://deno.land/x/code_block_writer@11.0.3/utils/string_utils.ts": "60cb4ec8bd335bf241ef785ccec51e809d576ff8e8d29da43d2273b69ce2a6ff",
"https://deno.land/x/denoflate@1.2.1/mod.ts": "f5628e44b80b3d80ed525afa2ba0f12408e3849db817d47a883b801f9ce69dd6",
"https://deno.land/x/denoflate@1.2.1/pkg/denoflate.js": "b9f9ad9457d3f12f28b1fb35c555f57443427f74decb403113d67364e4f2caf4",
"https://deno.land/x/denoflate@1.2.1/pkg/denoflate_bg.wasm.js": "d581956245407a2115a3d7e8d85a9641c032940a8e810acbd59ca86afd34d44d",
"https://deno.land/x/esbuild@v0.17.11/mod.d.ts": "dc279a3a46f084484453e617c0cabcd5b8bd1920c0e562e4ea02dfc828c8f968",
"https://deno.land/x/esbuild@v0.17.11/mod.js": "4f4e61964a551d9c0baf5bb19e973cf631cf8c66ddaf01e70070f8a100fc938c",
"https://deno.land/x/esbuild@v0.17.11/wasm.d.ts": "dc279a3a46f084484453e617c0cabcd5b8bd1920c0e562e4ea02dfc828c8f968",
"https://deno.land/x/esbuild@v0.17.11/wasm.js": "4030e7b50941ec6e06704c6b5f1f6416cc0f7f35f63daf63f184b728bea79a30",
"https://deno.land/x/fresh@1.1.5/dev.ts": "a66c7d64be35bcd6a8e12eec9c27ae335044c70363a241f2e36ee776db468622",
"https://deno.land/x/fresh@1.1.5/plugins/twind.ts": "c0570d6010e29ba24ee5f43b9d3f1fe735f7fac76d9a3e680c9896373d669876",
"https://deno.land/x/fresh@1.1.5/plugins/twind/shared.ts": "023e0ffcd66668753b5049edab0de46e6d66194fb6026c679034b9bbf04ad6f3",
"https://deno.land/x/fresh@1.1.5/runtime.ts": "b02ec1e2e32cf73a33d262b7c9dcab9468ce16cd89fd424196c71003698a4ab0",
"https://deno.land/x/fresh@1.1.5/server.ts": "f379c9aad24471a71e58fb887fa57e5cc27ad9df035987eb260541c78df38e84",
"https://deno.land/x/fresh@1.1.5/src/dev/deps.ts": "aef312af6de1315fa95fc0c32e87c56301b64efeb304193d0dce0da0634144d3",
"https://deno.land/x/fresh@1.1.5/src/dev/error.ts": "21a38d240c00279662e6adde41367f1da0ae7e2836d993f818ea94aabab53e7b",
"https://deno.land/x/fresh@1.1.5/src/dev/mod.ts": "14baa66a064961afcbad74748eeb2b99ce4bb246223ed69d8cc35b073e49b039",
"https://deno.land/x/fresh@1.1.5/src/runtime/csp.ts": "9ee900e9b0b786057b1009da5976298c202d1b86d1f1e4d2510bde5f06530ac9",
"https://deno.land/x/fresh@1.1.5/src/runtime/head.ts": "0f9932874497ab6e57ed1ba01d549e843523df4a5d36ef97460e7a43e3132fdc",
"https://deno.land/x/fresh@1.1.5/src/runtime/utils.ts": "8320a874a44bdd5905c7d4b87a0e7a14a6c50a2ed133800e72ae57341e4d4faa",
"https://deno.land/x/fresh@1.1.5/src/server/bundle.ts": "2febeb5071d0647993560807ca5b2f4cd60181d370ee8612e5db728cb10db9f1",
"https://deno.land/x/fresh@1.1.5/src/server/constants.ts": "ad10dda1bc20c25c2926f6a8cfd79ef4368d70b4b03a645f65c04b3fa7d93a8c",
"https://deno.land/x/fresh@1.1.5/src/server/context.ts": "896ca59b58d0713d8429c4ec8aea4cedb0e4c09a804a2e6ec0c81379f5f83b15",
"https://deno.land/x/fresh@1.1.5/src/server/default_error_page.ts": "9a1a595a1a2b31c9b724b04db82b8af256285536db272658d831ac9ef1d3d448",
"https://deno.land/x/fresh@1.1.5/src/server/deps.ts": "e205002c298ee6bf40af1365ced243b8cd86cf39e922ec2db2c91ef022eb72ad",
"https://deno.land/x/fresh@1.1.5/src/server/htmlescape.ts": "834ac7d0caa9fc38dffd9b8613fb47aeecd4f22d5d70c51d4b20a310c085835c",
"https://deno.land/x/fresh@1.1.5/src/server/mod.ts": "72d213444334dd2e94c757a0eee0fc486c0919399ea9184d07ad042f34edd00d",
"https://deno.land/x/fresh@1.1.5/src/server/render.ts": "6f50707bd1f6e33ed84bb71ae3b0996d202b953cefc4285f5356524c7b21f01f",
"https://deno.land/x/fresh@1.1.5/src/server/types.ts": "6579aac850ea4af5cdfee8f9552fbadebb7b50841d180b75bd90466416feee86",
"https://deno.land/x/importmap@0.2.1/_util.ts": "ada9a9618b537e6c0316c048a898352396c882b9f2de38aba18fd3f2950ede89",
"https://deno.land/x/importmap@0.2.1/mod.ts": "ae3d1cd7eabd18c01a4960d57db471126b020f23b37ef14e1359bbb949227ade",
"https://deno.land/x/rutt@0.1.0/mod.ts": "4662ad4f687740ac612b779ed4c62eecebd718b56d24a07f719ec3b24464c139",
"https://deno.land/x/ts_morph@17.0.1/common/DenoRuntime.ts": "537800e840d0994f9055164e11bf33eadf96419246af0d3c453793c3ae67bdb3",
"https://deno.land/x/ts_morph@17.0.1/common/mod.ts": "01985d2ee7da8d1caee318a9d07664774fbee4e31602bc2bb6bb62c3489555ed",
"https://deno.land/x/ts_morph@17.0.1/common/ts_morph_common.d.ts": "ee7767b0c68b23c65bb607c94b6cb3512e8237fbcb7d1d8383a33235cde2c068",
"https://deno.land/x/ts_morph@17.0.1/common/ts_morph_common.js": "49a79124b941ba2b35d81ac9eb90fc33c957b2640cdb97569c1941bac5a3bbdb",
"https://deno.land/x/ts_morph@17.0.1/common/typescript.d.ts": "57e52a0882af4e835473dda27e4316cc31149866970210f9f79b940e916b7838",
"https://deno.land/x/ts_morph@17.0.1/common/typescript.js": "5dd669eb199ee2a539924c63a92e23d95df43dfe2fbe3a9d68c871648be1ad5e",
"https://deno.land/x/ts_morph@17.0.1/mod.ts": "adba9b82f24865d15d2c78ef6074b9a7457011719056c9928c800f130a617c93",
"https://deno.land/x/ts_morph@17.0.1/ts_morph.d.ts": "a54b0c51b06d84defedf5fdd59c773d803808ae7c9678f7165f7a1a6dfa7f6a3",
"https://deno.land/x/ts_morph@17.0.1/ts_morph.js": "1bb80284b9e31a4c5c2078cd533fe9b12b4b2d710267055cb655225aa88fb2df",
"https://esm.sh/*preact-render-to-string@5.2.6": "36fc509887c5dd07c3cc7ec6cd47fb3ac820c9f74c9924dc935a787842fb7f3f",
"https://esm.sh/preact@10.13.1": "ae382301328ab874e2c42bee76e261bb8d094673fe76ca7eb71917636d43d8ad",
"https://esm.sh/preact@10.13.1/hooks": "1813f80c6d648f8137a62569e35972b0716f92539f192d6db66d45b7aafea43a",
"https://esm.sh/preact@10.13.1/jsx-runtime": "0caf2b2eade93af59e89abc31816b6cb2829a9b8a82b958c0ebc1d8bec241e2a",
"https://esm.sh/stable/preact@10.13.1/deno/hooks.js": "f25445c4f9fa6742119c41db4a85a2f75ee6ea941c506ae8ad3b1568c7692c61",
"https://esm.sh/stable/preact@10.13.1/deno/jsx-runtime.js": "7c8e1b8f272996846cbac0837dcb71f6f8cfc82611b3f7819501d07c37383dc0",
"https://esm.sh/stable/preact@10.13.1/deno/preact.mjs": "9b73545225d0ed274c89f39aee524a2857c81a73060e80c2c4bdc2a6de7bec26",
"https://esm.sh/twind@0.16.19": "ae2fc340ae156813bca1ff5c5489734f234cc2254565244056a3370375f14e3b",
"https://esm.sh/twind@0.16.19/sheets": "01c41aa230494e7f7d5aeaea7ae112ab9f3c3f38ace35f1ccf015352f3bdf56f",
"https://esm.sh/v114/csstype@3.1.2/index.d.ts": "4c68749a564a6facdf675416d75789ee5a557afda8960e0803cf6711fa569288",
"https://esm.sh/v114/preact-render-to-string@5.2.6/X-ZS8q/deno/preact-render-to-string.mjs": "672116885c5e5072207c527a0ec663f5bc52774a0868ec487985109520382a55",
"https://esm.sh/v114/preact-render-to-string@5.2.6/X-ZS8q/src/index.d.ts": "b1d73703252c8570fdf2952475805f5808ba3511fefbd93a3e7bd8406de7dcd0",
"https://esm.sh/v114/preact@10.13.1/hooks/src/index.d.ts": "5c29febb624fc25d71cb0e125848c9b711e233337a08f7eacfade38fd4c14cc3",
"https://esm.sh/v114/preact@10.13.1/jsx-runtime/src/index.d.ts": "e153460ed2b3fe2ad8b93696ecd48fbf73cd628b0b0ea6692b71804a3af69dfd",
"https://esm.sh/v114/preact@10.13.1/src/index.d.ts": "65398710de6aa0a07412da79784e05e6e96763f51c7c91b77344d2d0af06385c",
"https://esm.sh/v114/preact@10.13.1/src/jsx.d.ts": "fde41cfb4944bcc5005e653c989ef8f85deb1cbb5364a1726654993937cd08d0",
"https://esm.sh/v114/style-vendorizer@2.2.3/deno/style-vendorizer.mjs": "fb725497dd9621a84f552f9b6a4f3df82af5989ff18c40e972de1bdf475c9765",
"https://esm.sh/v114/twind@0.16.19/deno/sheets.js": "dcdb26e5d2860d9fff3ad81b81625799e501d465efdc99b206d3b7cd94151913",
"https://esm.sh/v114/twind@0.16.19/deno/twind.mjs": "6fab7543c2d8f0e587272e82218082d154dc87ffb1675e622e92feb72bb37006",
"https://esm.sh/v114/twind@0.16.19/sheets/sheets.d.ts": "21a0bca806d9c088d939dc95b08531ee71a708b98da8f20fde4a7026593b73b0",
"https://esm.sh/v114/twind@0.16.19/twind.d.ts": "a7cb168607800a3a6d2eabc177d7737015bc93073c14ff9e84a0f37ead9203c0",
"https://raw.githubusercontent.com/lucacasonato/esbuild_deno_loader/8031f71afa1bbcd3237a94b11f53a2e5c5c0e7bf/deps.ts": "b7248e5b750be62613a9417f407e65ed43726d83b11f9631d6dbb58634bbd7d1",
"https://raw.githubusercontent.com/lucacasonato/esbuild_deno_loader/8031f71afa1bbcd3237a94b11f53a2e5c5c0e7bf/mod.ts": "3e507379372361162f93325a216b86f6098defb5bb60144555b507bca26d061f",
"https://raw.githubusercontent.com/lucacasonato/esbuild_deno_loader/8031f71afa1bbcd3237a94b11f53a2e5c5c0e7bf/src/deno.ts": "71bee6b14e72ca193c0686d8b4f1f47d639a64745b6f5c7576f7a3616f436f57",
"https://raw.githubusercontent.com/lucacasonato/esbuild_deno_loader/8031f71afa1bbcd3237a94b11f53a2e5c5c0e7bf/src/native_loader.ts": "2a0f5a7b68a57c4651ad48161b32532356b434597a6cf282683427482b38f6fa",
"https://raw.githubusercontent.com/lucacasonato/esbuild_deno_loader/8031f71afa1bbcd3237a94b11f53a2e5c5c0e7bf/src/portable_loader.ts": "47adb6d9a00f13a87d0a15f2af79118eb93503234008c31392d71270bc0a42fa",
"https://raw.githubusercontent.com/lucacasonato/esbuild_deno_loader/8031f71afa1bbcd3237a94b11f53a2e5c5c0e7bf/src/shared.ts": "007e8d575cb6ebcac4110f1f72188a8bec3aa29287b4ad26e98403c00bebf036"
}
}

5
dev.ts
View File

@ -1,5 +0,0 @@
#!/usr/bin/env -S deno run -A --watch=static/,routes/
import dev from "$fresh/dev.ts";
await dev(import.meta.url, "./main.ts");

View File

@ -14,9 +14,8 @@
devShells.default = config.mk-naked-shell.lib.mkNakedShell { devShells.default = config.mk-naked-shell.lib.mkNakedShell {
name = "musikspider-devshell"; name = "musikspider-devshell";
packages = with pkgs; [ packages = with pkgs; [
deno nodejs
nodePackages_latest.vscode-json-languageserver nodePackages.pnpm
taplo
]; ];
}; };
}; };

View File

@ -1,21 +0,0 @@
// DO NOT EDIT. This file is generated by fresh.
// This file SHOULD be checked into source version control.
// This file is automatically updated during development when running `dev.ts`.
import config from "./deno.json" assert { type: "json" };
import * as $0 from "./routes/index.tsx";
import * as $1 from "./routes/library.tsx";
import * as $2 from "./routes/login.tsx";
const manifest = {
routes: {
"./routes/index.tsx": $0,
"./routes/library.tsx": $1,
"./routes/login.tsx": $2,
},
islands: {},
baseUrl: import.meta.url,
config,
};
export default manifest;

View File

@ -1,13 +0,0 @@
{
"imports": {
"$fresh/": "https://deno.land/x/fresh@1.1.5/",
"preact": "https://esm.sh/preact@10.13.1",
"preact/": "https://esm.sh/preact@10.13.1/",
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@5.2.6",
"@preact/signals": "https://esm.sh/*@preact/signals@1.1.3",
"@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.2.3",
"twind": "https://esm.sh/twind@0.16.19",
"twind/": "https://esm.sh/twind@0.16.19/",
"$std/": "https://deno.land/std@0.182.0/"
}
}

13
main.ts
View File

@ -1,13 +0,0 @@
/// <reference no-default-lib="true" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/// <reference lib="dom.asynciterable" />
/// <reference lib="deno.ns" />
import { start } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";
import twindPlugin from "$fresh/plugins/twind.ts";
import twindConfig from "./twind.config.ts";
await start(manifest, { plugins: [twindPlugin(twindConfig)] });

40
package.json Normal file
View File

@ -0,0 +1,40 @@
{
"name": "musikspider",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
"@skeletonlabs/skeleton": "^1.2.0",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/adapter-static": "^2.0.2",
"@sveltejs/kit": "^1.15.4",
"@typescript-eslint/eslint-plugin": "^5.58.0",
"@typescript-eslint/parser": "^5.58.0",
"autoprefixer": "^10.4.14",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-svelte3": "^4.0.0",
"postcss": "^8.4.21",
"prettier": "^2.8.7",
"prettier-plugin-svelte": "^2.10.0",
"svelte": "^3.58.0",
"svelte-check": "^3.2.0",
"tailwindcss": "^3.3.1",
"tslib": "^2.5.0",
"typescript": "^5.0.4",
"vite": "^4.2.1"
},
"type": "module",
"dependencies": {
"svelte-infinite-loading": "^1.3.8",
"svelte-tiny-virtual-list": "^2.0.5"
}
}

2123
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View File

@ -1,19 +0,0 @@
import { getCookies } from "$std/http/cookie.ts";
export function handler(req: Request): Response {
const cookies = getCookies(req.headers);
const username = cookies["username"];
const password = cookies["password"];
if (username != null && password != null) {
return new Response("", {
status: 303,
headers: { location: "/library" },
});
} else {
return new Response("", {
status: 303,
headers: { location: "/login" },
});
}
}

View File

@ -1,37 +0,0 @@
import { Handlers, PageProps } from "$fresh/server.ts";
import { getCookies } from "$std/http/cookie.ts";
import { Head } from "$fresh/runtime.ts";
interface Data {
username: string;
password: string;
}
export const handler: Handlers<Data> = {
GET(req, ctx) {
const cookies = getCookies(req.headers);
const username = cookies["username"];
const password = cookies["password"];
if (username && password) {
return ctx.render({ username, password });
} else {
return new Response("", {
status: 303,
headers: { location: "/login" },
});
}
},
};
export default function LibraryPage({ data }: PageProps<Data>) {
const { username, password } = data;
return (
<>
<Head>
<title>musikspider</title>
</Head>
<p>Library {username} {password}</p>
</>
);
}

View File

@ -1,74 +0,0 @@
import { setCookie } from "$std/http/cookie.ts";
import { Handlers } from "$fresh/server.ts";
import { Head } from "$fresh/runtime.ts";
import Button from "../components/Button.tsx";
import Input from "../components/Input.tsx";
const LOGIN_MAX_AGE = 60 * 60 * 24 * 7;
export const handler: Handlers = {
GET(_, ctx) {
return ctx.render();
},
async POST(req, _) {
const form = await req.formData();
const username = form.get("username")!.toString();
const password = form.get("password")!.toString();
const response = new Response("", {
status: 303,
headers: { location: "/library" },
});
setCookie(response.headers, {
name: "username",
value: username,
maxAge: LOGIN_MAX_AGE,
httpOnly: true,
});
setCookie(response.headers, {
name: "password",
value: password,
maxAge: LOGIN_MAX_AGE,
httpOnly: true,
});
return response;
},
};
export default function LoginPage() {
return (
<>
<Head>
<title>musikspider</title>
</Head>
<div class="flex items-center justify-center p-4 mx-auto max-w-screen-md h-screen">
<form method="POST">
<div class="flex flex-col gap-2 max-w-xs">
<div class="flex gap-4 place-items-center">
<label for="username" class="w-1/3">username</label>
<Input
class="w-2/3"
id="username"
type="text"
name="username"
required
/>
</div>
<div class="flex gap-4 place-items-center">
<label for="password" class="w-1/3">password</label>
<Input
class="w-2/3"
id="password"
type="password"
name="password"
required
/>
</div>
<Button class="w-min" type="submit">login</Button>
</div>
</form>
</div>
</>
);
}

2
src/app.css Normal file
View File

@ -0,0 +1,2 @@
html, body { @apply h-full overflow-hidden; }
.card { @apply shadow shadow-black; }

12
src/app.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
}
export {};

15
src/app.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html class="dark" lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" data-theme="vintage">
<div style="display: contents" class="h-full overflow-hidden">%sveltekit.body%</div>
</body>
</html>

169
src/comms.ts Normal file
View File

@ -0,0 +1,169 @@
import type { TrackWithId } from "./types";
const API_VERSION: number = 20;
const HTTP_DISABLED_ERROR: string =
"server does not have HTTP resources enabled, you will not be able to stream music";
const SERVER_API_INCOMPATIBLE_ERROR: (serverApi: number) => string =
(serverApi) => `server API version (${serverApi}) is different from our supported version (${API_VERSION})`;
interface Message {
name: string;
id: string;
device_id: string;
type: MessageType;
options: any;
};
type MessageType = 'request' | 'response' | 'broadcast';
type RequestCallback = (arg0: Message | null) => void;
interface Callbacks {
onDisconnect: (authenticated: boolean, reason: string) => void;
onConnect: (initial: Message) => void;
onIncompatible: (reason: string) => void;
}
export class MetadataCommunicator {
ws: WebSocket | null;
deviceId: string;
callbacks: Map<string, RequestCallback>;
authenticated: boolean;
eventCallbacks: Callbacks;
onConnectCallbacks: (() => void)[];
constructor() {
this.callbacks = new Map();
this.deviceId = crypto.randomUUID();
this.authenticated = false;
this.eventCallbacks = {
onDisconnect: () => { },
onConnect: () => { },
onIncompatible: () => { },
};
this.onConnectCallbacks = [];
this.ws = null;
}
setCallbacks(callbacks: Callbacks) {
this.eventCallbacks = callbacks;
}
connect(address: string, password: string) {
this.close();
this.ws = new WebSocket(`ws://${address}`);
this.ws.addEventListener('open', (event) => {
this.makeRequest("authenticate", 'request', { password }, (msg) => {
if (msg!.options.authenticated) {
this.authenticated = true;
this.eventCallbacks.onConnect(msg!);
this.onConnectCallbacks.forEach((f) => f());
this.onConnectCallbacks = [];
if (!msg!.options.environment.http_server_enabled) {
this.eventCallbacks.onIncompatible(HTTP_DISABLED_ERROR);
}
const serverApiVersion = msg!.options.environment.api_version;
if (serverApiVersion != API_VERSION) {
this.eventCallbacks.onIncompatible(SERVER_API_INCOMPATIBLE_ERROR(serverApiVersion));
}
}
});
});
this.ws.addEventListener('close', (event) => {
this.eventCallbacks.onDisconnect(this.authenticated, `${event.reason} (code ${event.code})`);
this.authenticated = false;
});
this.ws.addEventListener('message', (event) => {
const parsed: Message = JSON.parse(event.data);
const maybeCallback = this.callbacks.get(parsed.id);
if (maybeCallback) {
maybeCallback(parsed);
this.callbacks.delete(parsed.id);
}
});
}
fetchTracksCount(): Promise<number> {
const options = { count_only: true };
const th = this;
return new Promise(function (resolve, reject) {
th.makeRequest("query_tracks", "request", options, (resp) => {
if (resp) {
resolve(resp.options.count);
} else {
reject(null);
}
});
});
}
fetchTracks(limit: number, offset: number, filter: string | null = null): Promise<TrackWithId[]> {
const options: any = { limit, offset };
if (filter !== null) options.filter = filter;
const th = this;
return new Promise(function (resolve, reject) {
th.makeRequest("query_tracks", "request", options, (resp) => {
if (resp) {
const data: any[] = resp.options.data;
resolve(data.map((t) => ({
id: t.id,
track: {
title: t.title,
album_id: t.album_id,
artist_id: t.artist_id,
track_num: t.track,
thumbnail_id: t.thumbnail_id,
}
})));
} else {
reject(null);
}
});
});
}
private makeRequest(name: string, type: MessageType, options: object, callback: RequestCallback) {
// return if not authenticated, allow authentication messages
if (this.isClosed() || !this.authenticated && name != "authenticate") {
callback(null);
return;
}
// Unique enough for our purposes (as request ID)
const id = Math.random().toString(36).substring(2) + Date.now().toString(36);
this.callbacks.set(id, callback);
const payload = JSON.stringify({
name,
type,
options,
device_id: this.deviceId,
id,
});
console.trace("sending metadata message: " + payload);
this.ws!.send(payload);
}
close() {
if (this.isClosed()) return;
this.ws!.close();
this.authenticated = false;
this.callbacks.clear();
}
isClosed() {
return (
this.ws === null
|| this.ws.readyState === WebSocket.CLOSED
|| this.ws.readyState === WebSocket.CLOSING
);
}
onConnect(cb: () => void) {
if (!this.isClosed() && this.authenticated) {
cb();
} else {
this.onConnectCallbacks = [...this.onConnectCallbacks, cb];
}
}
}

11
src/components/a.svelte Normal file
View File

@ -0,0 +1,11 @@
<script lang="ts">
import { page } from '$app/stores';
export let href: string;
$: isOnPage = href === $page.route.id;
</script>
<a {href} class="btn {isOnPage ? 'variant-ghost-primary' : 'hover:variant-soft-primary'}">
<slot />
</a>

View File

@ -0,0 +1,10 @@
<script>
import Link from './a.svelte';
</script>
<nav class="flex">
<Link href="/">t</Link>
<Link href="/albums">a</Link>
<Link href="/artists">a</Link>
<Link href="/settings">s</Link>
</nav>

View File

@ -0,0 +1,20 @@
<script lang="ts">
import type { Track } from '../types';
import { address, token } from '../stores';
export let track: Track;
$: url = `http://${$address}/thumbnail/${track.thumbnail_id}?token=${$token}`;
</script>
<div class="card flex gap-2">
<!-- svelte-ignore a11y-missing-attribute -->
<div class="rounded placeholder w-12 h-12">
<img
src={url}
loading="lazy"
class="w-12 h-12"
on:error={(ev) => (ev.target.style.display = 'none')}
/>
</div>
{track.track_num} - {track.title}
</div>

81
src/routes/+layout.svelte Normal file
View File

@ -0,0 +1,81 @@
<script>
// Your selected Skeleton theme:
import '@skeletonlabs/skeleton/themes/theme-vintage.css';
// This contains the bulk of Skeletons required styles:
import '@skeletonlabs/skeleton/styles/all.css';
import '../app.css';
import { AppShell, Toast, toastStore } from '@skeletonlabs/skeleton';
import Navbar from '../components/navbar.svelte';
import { address, token, tracks, tracksSorted } from '../stores';
import { _metadataComm as comm } from './+layout';
comm.setCallbacks({
onConnect: () => {
toastStore.trigger({
message: 'Successfully connected to the server',
background: 'variant-filled-success'
});
},
onDisconnect: (authenticated, reason) => {
const errorMessage = authenticated ? 'Disconnected' : 'Error while connecting to the server';
toastStore.trigger({
message: `${errorMessage}: ${reason}`,
background: 'variant-filled-error',
autohide: false
});
},
onIncompatible: (reason) => {
toastStore.trigger({
message: `Possible incompatible environment: ${reason}`,
background: 'variant-filled-warning',
autohide: false
});
}
});
comm.connect($address, $token);
comm.onConnect(() => {
comm
.fetchTracksCount()
.then((count) => {
let remaining = count;
console.log(count);
while (remaining > 0) {
const offset = count - remaining;
comm.fetchTracks(500, offset).then((ts) => {
tracks.update((map) => {
ts.forEach((t) => map.set(t.id, t.track));
return map;
});
tracksSorted.update((map) => {
ts.forEach((t, index) => map.set(index + offset, t.id));
return map;
});
});
remaining -= 500;
}
})
.catch(() => null);
});
</script>
<svelte:head>
<title>musikspider</title>
</svelte:head>
<AppShell>
<svelte:fragment slot="footer">
<div class="flex w-screen place-content-center">
<div class="card m-2 sm:hidden z-1 fixed bottom-[48px]"><Navbar /></div>
</div>
<div class="flex flex-col">
<div class="card m-2 max-md:m-0 px-4 flex flex-1 items-center min-h-[48px]">
now playing
<div class="mx-auto max-sm:hidden"><Navbar /></div>
<div class="max-sm:ml-auto">volume</div>
</div>
</div>
</svelte:fragment>
<slot />
</AppShell>
<Toast />

6
src/routes/+layout.ts Normal file
View File

@ -0,0 +1,6 @@
import { MetadataCommunicator } from "../comms";
export const ssr = false;
export const prerender = false;
export const _metadataComm = new MetadataCommunicator();

14
src/routes/+page.svelte Normal file
View File

@ -0,0 +1,14 @@
<script lang="ts">
import VirtualList from 'svelte-tiny-virtual-list';
import { tracks, tracksSorted } from '../stores';
import Track from '../components/track.svelte';
$: trackCount = $tracksSorted.size;
let trackItemSize = 60;
</script>
<VirtualList height={trackCount * trackItemSize} itemSize={trackItemSize} itemCount={trackCount}>
<div slot="item" let:index let:style {style}>
<Track track={$tracks.get($tracksSorted.get(index) ?? BigInt(0))} />
</div>
</VirtualList>

View File

@ -0,0 +1,18 @@
<script>
import { token, address } from '../../stores';
import Input from './input.svelte';
import { _metadataComm as comm } from '../+layout';
$: reconnect = () => comm.connect($address, $token);
</script>
<div class="flex flex-col gap-4 m-8 max-md:m-2">
<div class="card grid gap-1 p-4 max-w-md">
<h3>server settings</h3>
<Input store={address} name="address" />
<Input store={token} name="token" type="password" />
<button class="btn variant-filled hover:variant-filled-primary w-min" on:click={reconnect}
>connect</button
>
</div>
</div>

View File

@ -0,0 +1,16 @@
<script lang="ts">
export let store: any;
export let name: string;
export let type = 'text';
</script>
<label class="label grid grid-cols-2 items-center gap-3">
<span class="badge variant-filled w-min text-sm">{name}</span>
<input
class="input"
value={$store}
{name}
{type}
on:change={(ev) => store.set(ev.currentTarget.value)}
/>
</label>

14
src/stores.ts Normal file
View File

@ -0,0 +1,14 @@
import { writable } from 'svelte/store';
import type { ResourceId, Track } from './types';
function writableStorage(key: string, defaultValue: string) {
const store = writable(localStorage.getItem(key) ?? defaultValue);
store.subscribe(value => localStorage.setItem(key, value));
return store;
}
export const address = writableStorage("address", "127.0.0.1:5505");
export const token = writableStorage("token", "");
export const tracks = writable<Map<ResourceId, Track>>(new Map());
export const tracksSorted = writable<Map<number, ResourceId>>(new Map());

24
src/types.ts Normal file
View File

@ -0,0 +1,24 @@
export type ResourceId = bigint;
export interface Track {
title: string,
track_num: number,
album_id: ResourceId,
artist_id: ResourceId,
thumbnail_id: ResourceId,
}
export interface TrackWithId {
id: ResourceId,
track: Track,
}
export interface Artist {
name: string,
}
export interface Album {
title: string,
artist_id: ResourceId,
thumbnail_id: ResourceId,
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,6 +0,0 @@
<svg width="40" height="40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M34.092 8.845C38.929 20.652 34.092 27 30 30.5c1 3.5-2.986 4.222-4.5 2.5-4.457 1.537-13.512 1.487-20-5C2 24.5 4.73 16.714 14 11.5c8-4.5 16-7 20.092-2.655Z" fill="#FFDB1E"/>
<path d="M14 11.5c6.848-4.497 15.025-6.38 18.368-3.47C37.5 12.5 21.5 22.612 15.5 25c-6.5 2.587-3 8.5-6.5 8.5-3 0-2.5-4-5.183-7.75C2.232 23.535 6.16 16.648 14 11.5Z" fill="#fff" stroke="#FFDB1E"/>
<path d="M28.535 8.772c4.645 1.25-.365 5.695-4.303 8.536-3.732 2.692-6.606 4.21-7.923 4.83-.366.173-1.617-2.252-1.617-1 0 .417-.7 2.238-.934 2.326-1.365.512-4.223 1.29-5.835 1.29-3.491 0-1.923-4.754 3.014-9.122.892-.789 1.478-.645 2.283-.645-.537-.773-.534-.917.403-1.546C17.79 10.64 23 8.77 25.212 8.42c.366.014.82.35.82.629.41-.14 2.095-.388 2.503-.278Z" fill="#FFE600"/>
<path d="M14.297 16.49c.985-.747 1.644-1.01 2.099-2.526.566.121.841-.08 1.29-.701.324.466 1.657.608 2.453.701-.715.451-1.057.852-1.452 2.106-1.464-.611-3.167-.302-4.39.42Z" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

13
svelte.config.js Normal file
View File

@ -0,0 +1,13 @@
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/kit/vite';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
adapter: adapter()
}
};
export default config;

17
tailwind.config.js Normal file
View File

@ -0,0 +1,17 @@
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./src/**/*.{html,js,svelte,ts}',
require('path').join(require.resolve(
'@skeletonlabs/skeleton'),
'../**/*.{html,js,svelte,ts}'
),
],
theme: {
extend: {},
},
plugins: [
...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()
],
darkMode: 'class',
}

17
tsconfig.json Normal file
View File

@ -0,0 +1,17 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

View File

@ -1,5 +0,0 @@
import { Options } from "$fresh/plugins/twind.ts";
export default {
selfURL: import.meta.url,
} as Options;

6
vite.config.ts Normal file
View File

@ -0,0 +1,6 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [sveltekit()]
});