···11+# sv
22+33+Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
44+55+## Creating a project
66+77+If you're seeing this, you've probably already done this step. Congrats!
88+99+```bash
1010+# create a new project in the current directory
1111+npx sv create
1212+1313+# create a new project in my-app
1414+npx sv create my-app
1515+```
1616+1717+## Developing
1818+1919+Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
2020+2121+```bash
2222+npm run dev
2323+2424+# or start the server and open the app in a new browser tab
2525+npm run dev -- --open
2626+```
2727+2828+## Building
2929+3030+To create a production version of your app:
3131+3232+```bash
3333+npm run build
3434+```
3535+3636+You can preview the production build with `npm run preview`.
3737+3838+> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
···11+import { TURSO_AUTH_TOKEN, TURSO_DATABASE_URL } from '$env/static/private';
22+import { createClient } from '@libsql/client';
33+44+const client = createClient({
55+ url: TURSO_DATABASE_URL, // Your Turso database URL
66+ authToken: TURSO_AUTH_TOKEN // Your Turso authentication token
77+});
88+99+// Function to get all languages in the database
1010+export async function getAllLanguages() {
1111+ const result = await client.execute({
1212+ sql: `SELECT DISTINCT lang FROM hashtags WHERE lang IS NOT NULL;`,
1313+ args: []
1414+ });
1515+ return result.rows.map((row) => row.lang);
1616+}
1717+1818+// Helper function to get top hashtags within a specified time frame
1919+export async function getTopHashtags(hours: number, lang: string | null = null) {
2020+ const timestampThreshold = Date.now() * 1000 - hours * 3600 * 1000_000;
2121+ let sql = `
2222+ SELECT tag, SUM(count) AS total_count
2323+ FROM hashtags
2424+ WHERE timestamp >= ?
2525+ `;
2626+ const args: (number | string)[] = [timestampThreshold];
2727+2828+ if (lang) {
2929+ if (lang === 'en') {
3030+ sql += ` AND (lang = ? OR lang = '')`;
3131+ args.push(lang);
3232+ } else {
3333+ sql += ` AND lang = ?`;
3434+ args.push(lang);
3535+ }
3636+ }
3737+3838+ sql += `
3939+ GROUP BY tag
4040+ ORDER BY total_count DESC
4141+ LIMIT 50;
4242+ `;
4343+4444+ const result = await client.execute({ sql, args });
4545+ return result.rows;
4646+}
4747+4848+// Function to get top 100 hashtags of the last hour
4949+export async function getTopHashtagsLastHour(lang = null) {
5050+ return await getTopHashtags(1, lang);
5151+}
5252+5353+// Function to get top 100 hashtags of the last 24 hours
5454+export async function getTopHashtagsLast24Hours(lang = null) {
5555+ return await getTopHashtags(24, lang);
5656+}
5757+5858+// Function to get the last update timestamp
5959+export async function getLastUpdateTimestamp() {
6060+ const result = await client.execute({
6161+ sql: `SELECT MAX(timestamp) AS last_timestamp FROM hashtags;`,
6262+ args: []
6363+ });
6464+ return result.rows[0].last_timestamp;
6565+}
···11+import adapter from '@sveltejs/adapter-static';
22+import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
33+44+/** @type {import('@sveltejs/kit').Config} */
55+const config = {
66+ // Consult https://svelte.dev/docs/kit/integrations
77+ // for more information about preprocessors
88+ preprocess: vitePreprocess(),
99+1010+ kit: {
1111+ // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
1212+ // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
1313+ // See https://svelte.dev/docs/kit/adapters for more information about adapters.
1414+ adapter: adapter(),
1515+ paths: {
1616+ base: '/bluesky-trending'
1717+ }
1818+ }
1919+};
2020+2121+export default config;
···11+{
22+ "extends": "./.svelte-kit/tsconfig.json",
33+ "compilerOptions": {
44+ "allowJs": true,
55+ "checkJs": true,
66+ "esModuleInterop": true,
77+ "forceConsistentCasingInFileNames": true,
88+ "resolveJsonModule": true,
99+ "skipLibCheck": true,
1010+ "sourceMap": true,
1111+ "strict": true,
1212+ "moduleResolution": "bundler"
1313+ }
1414+ // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
1515+ // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
1616+ //
1717+ // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
1818+ // from the referenced tsconfig.json - TypeScript does not merge them in
1919+}