From dbe50174e523693810e029829875a57f2c9b383d Mon Sep 17 00:00:00 2001
From: Florian <45694132+flo-bit@users.noreply.github.com>
Date: Thu, 5 Feb 2026 22:38:05 +0100
Subject: [PATCH 1/3] another small fix that doesnt belong in this branch
---
src/lib/cards/visual/FluidTextCard/FluidTextCard.svelte | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/cards/visual/FluidTextCard/FluidTextCard.svelte b/src/lib/cards/visual/FluidTextCard/FluidTextCard.svelte
index 32e370b..59c58a3 100644
--- a/src/lib/cards/visual/FluidTextCard/FluidTextCard.svelte
+++ b/src/lib/cards/visual/FluidTextCard/FluidTextCard.svelte
@@ -1773,7 +1773,7 @@
? 'bg-base-50 dark:bg-base-900'
: 'bg-black'}"
>
-
+
--
2.51.2
From 0705fd4dbfd66a3037dd7407c1e1e6faabae2685 Mon Sep 17 00:00:00 2001
From: Florian <45694132+flo-bit@users.noreply.github.com>
Date: Fri, 6 Feb 2026 01:54:37 +0100
Subject: [PATCH 2/3] add npmx likes
---
src/lib/cards/index.ts | 4 +-
.../social/NpmxLikesCard/NpmxLikesCard.svelte | 103 ++++++++++++++++++
src/lib/cards/social/NpmxLikesCard/index.ts | 31 ++++++
.../visual/FluidTextCard/FluidTextCard.svelte | 8 +-
4 files changed, 143 insertions(+), 3 deletions(-)
create mode 100644 src/lib/cards/social/NpmxLikesCard/NpmxLikesCard.svelte
create mode 100644 src/lib/cards/social/NpmxLikesCard/index.ts
diff --git a/src/lib/cards/index.ts b/src/lib/cards/index.ts
index 0e25809..708d743 100644
--- a/src/lib/cards/index.ts
+++ b/src/lib/cards/index.ts
@@ -40,6 +40,7 @@ import { FriendsCardDefinition } from './social/FriendsCard';
import { GitHubContributorsCardDefinition } from './social/GitHubContributorsCard';
import { ProductHuntCardDefinition } from './social/ProductHuntCard';
import { KickstarterCardDefinition } from './social/KickstarterCard';
+import { NpmxLikesCardDefinition } from './social/NpmxLikesCard';
// import { Model3DCardDefinition } from './visual/Model3DCard';
export const AllCardDefinitions = [
@@ -84,7 +85,8 @@ export const AllCardDefinitions = [
FriendsCardDefinition,
GitHubContributorsCardDefinition,
ProductHuntCardDefinition,
- KickstarterCardDefinition
+ KickstarterCardDefinition,
+ NpmxLikesCardDefinition
] as const;
export const CardDefinitionsByType = AllCardDefinitions.reduce(
diff --git a/src/lib/cards/social/NpmxLikesCard/NpmxLikesCard.svelte b/src/lib/cards/social/NpmxLikesCard/NpmxLikesCard.svelte
new file mode 100644
index 0000000..1d0abc8
--- /dev/null
+++ b/src/lib/cards/social/NpmxLikesCard/NpmxLikesCard.svelte
@@ -0,0 +1,103 @@
+
+
+{#snippet likeItem(like: NpmxLike)}
+
+
+
+
+
+ {getPackageName(like)}
+
+ {#if like.value.createdAt}
+
+ ago
+
+ {/if}
+
+
+
+{/snippet}
+
+
diff --git a/src/lib/cards/social/NpmxLikesCard/index.ts b/src/lib/cards/social/NpmxLikesCard/index.ts
new file mode 100644
index 0000000..d967123
--- /dev/null
+++ b/src/lib/cards/social/NpmxLikesCard/index.ts
@@ -0,0 +1,31 @@
+import type { CardDefinition } from '../../types';
+import { listRecords } from '$lib/atproto';
+import NpmxLikesCard from './NpmxLikesCard.svelte';
+
+export const NpmxLikesCardDefinition = {
+ type: 'npmxLikes',
+ contentComponent: NpmxLikesCard,
+ createNew: (card) => {
+ card.w = 4;
+ card.mobileW = 8;
+ card.h = 3;
+ card.mobileH = 6;
+ },
+ loadData: async (items, { did }) => {
+ const data = await listRecords({
+ did,
+ collection: 'dev.npmx.feed.like',
+ limit: 99
+ });
+
+ return data;
+ },
+ minW: 4,
+ canHaveLabel: true,
+
+ keywords: ['npm', 'package', 'npmx', 'likes'],
+ name: 'npmx Likes',
+
+ groups: ['Social'],
+ icon: ``
+} as CardDefinition & { type: 'npmxLikes' };
diff --git a/src/lib/cards/visual/FluidTextCard/FluidTextCard.svelte b/src/lib/cards/visual/FluidTextCard/FluidTextCard.svelte
index 59c58a3..4dc18a0 100644
--- a/src/lib/cards/visual/FluidTextCard/FluidTextCard.svelte
+++ b/src/lib/cards/visual/FluidTextCard/FluidTextCard.svelte
@@ -1773,7 +1773,11 @@
? 'bg-base-50 dark:bg-base-900'
: 'bg-black'}"
>
-
-
+
+
--
2.51.2
From 6e19d6067900e15e3ee1b5d5d8985ee732aed239 Mon Sep 17 00:00:00 2001
From: Florian <45694132+flo-bit@users.noreply.github.com>
Date: Fri, 6 Feb 2026 20:29:40 +0100
Subject: [PATCH 3/3] add npmx-leaderboard api
---
src/routes/api/npmx-leaderboard/+server.ts | 44 ++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 src/routes/api/npmx-leaderboard/+server.ts
diff --git a/src/routes/api/npmx-leaderboard/+server.ts b/src/routes/api/npmx-leaderboard/+server.ts
new file mode 100644
index 0000000..52456a6
--- /dev/null
+++ b/src/routes/api/npmx-leaderboard/+server.ts
@@ -0,0 +1,44 @@
+import { json } from '@sveltejs/kit';
+import type { RequestHandler } from './$types';
+
+const LEADERBOARD_API_URL =
+ 'https://npmx-likes-leaderboard-api-production.up.railway.app/api/leaderboard/likes';
+
+export const GET: RequestHandler = async ({ platform }) => {
+ const cacheKey = '#npmx-leaderboard:likes';
+ const cachedData = await platform?.env?.USER_DATA_CACHE?.get(cacheKey);
+
+ if (cachedData) {
+ const parsedCache = JSON.parse(cachedData);
+
+ const TWELVE_HOURS = 12 * 60 * 60 * 1000;
+ const now = Date.now();
+
+ if (now - (parsedCache.updatedAt || 0) < TWELVE_HOURS) {
+ return json(parsedCache.data);
+ }
+ }
+
+ try {
+ const response = await fetch(LEADERBOARD_API_URL);
+
+ if (!response.ok) {
+ return json(
+ { error: 'Failed to fetch npmx leaderboard ' + response.statusText },
+ { status: response.status }
+ );
+ }
+
+ const data = await response.json();
+
+ await platform?.env?.USER_DATA_CACHE?.put(
+ cacheKey,
+ JSON.stringify({ data, updatedAt: Date.now() })
+ );
+
+ return json(data);
+ } catch (error) {
+ console.error('Error fetching npmx leaderboard:', error);
+ return json({ error: 'Failed to fetch npmx leaderboard' }, { status: 500 });
+ }
+};
--
2.51.2