commit 7cd40951ea3bbcc811eedfafb12455c4ac6d4ebb
parent e8413220dc0320132e8d5c9d3a8d5279ef5e5ac7
Author: triesap <triesap@radroots.dev>
Date: Sun, 26 Oct 2025 23:03:10 +0000
Add listing index loaders and event hydration helpers; refactor market listing/profile routes to use shared loaders and unified types.
Diffstat:
5 files changed, 57 insertions(+), 43 deletions(-)
diff --git a/app/src/lib/utils/listing/index.ts b/app/src/lib/utils/listing/index.ts
@@ -0,0 +1,39 @@
+import { _env } from "$lib/utils/_env";
+import { type HttpFetch, fetch_json } from "@radroots/apps-lib";
+import type { RadrootsListingEventMetadata } from "@radroots/events-bindings";
+import type { RadrootsEventsIndexedManifest } from "@radroots/events-indexed-bindings";
+
+export type ListingRoutesKind = "country" | "author" | "npub" | "nip05";
+
+const { RADROOTS_MARKET_RELAY_INDEXES_URL: idx_url } = _env;
+
+export type ListingIndexedData = {
+ manifest: RadrootsEventsIndexedManifest;
+ events: RadrootsListingEventMetadata[];
+};
+
+export async function fetch_listing_indexes(
+ fetch_fn: HttpFetch,
+ kind: ListingRoutesKind
+): Promise<string[]> {
+ const url = `${idx_url}/events/30402/${kind}/indexes.json`;
+ return fetch_json<string[]>(fetch_fn, url);
+}
+
+export async function load_listing_indexed(
+ fetch_fn: HttpFetch,
+ kind: ListingRoutesKind,
+ key: string
+): Promise<ListingIndexedData> {
+ const manifest_url = `${idx_url}/events/30402/${kind}/${key}/manifest.json`;
+ const manifest = await fetch_json<RadrootsEventsIndexedManifest>(fetch_fn, manifest_url);
+
+ let events: RadrootsListingEventMetadata[] = [];
+ if (manifest.shards.length > 0) {
+ const shard = manifest.shards[0];
+ const shard_url = `${idx_url}/events/30402/${kind}/${key}/${shard.file}?v=${shard.sha256}`;
+ events = await fetch_json<RadrootsListingEventMetadata[]>(fetch_fn, shard_url);
+ }
+
+ return { manifest, events };
+}
diff --git a/app/src/routes/(market)/(listing)/[0=country]/+page.ts b/app/src/routes/(market)/(listing)/[0=country]/+page.ts
@@ -1,21 +1,14 @@
import { _env } from "$lib/utils/_env";
+import { load_listing_indexed } from "$lib/utils/listing";
import type { RadrootsListingEventMetadata } from "@radroots/events-bindings";
import type { RadrootsEventsIndexedManifest } from "@radroots/events-indexed-bindings";
-
-import { error } from "@sveltejs/kit";
import type { EntryGenerator, PageLoad } from "./$types";
const { RADROOTS_MARKET_RELAY_INDEXES_URL: idx_url } = _env;
export const entries: EntryGenerator = async () => {
- const [
- events_0_country_indexes,
- ]: [
- string[]
- ] = await Promise.all([
- fetch(`${idx_url}/events/30402/country/indexes.json`).then(r => r.json())
- ]);
- return events_0_country_indexes.map(i => ({ 0: i }))
+ const indexes: string[] = await fetch(`${idx_url}/events/30402/country/indexes.json`).then((r) => r.json());
+ return indexes.map((i) => ({ 0: i }));
};
type PageLoadData = {
@@ -26,31 +19,13 @@ type PageLoadData = {
export const load: PageLoad<PageLoadData> = async ({ fetch, params }) => {
const { 0: country } = params;
+ const indexed = await load_listing_indexed(fetch, "country", country);
- const [
- res_country_manifest,
- ] = await Promise.all([
- fetch(`${idx_url}/events/30402/country/${country}/manifest.json`)
- ]);
-
- if (!res_country_manifest.ok) error(404, { message: `country:${country}` });
-
- const manifest: RadrootsEventsIndexedManifest = await res_country_manifest.json();
-
- let events: RadrootsListingEventMetadata[] = [];
- if (manifest.shards.length > 0) {
- const shard = manifest.shards[0];
- const res_country_shard = await fetch(`${idx_url}/events/30402/country/${country}/${shard.file}?v=${shard.sha256}`);
- if (!res_country_shard.ok) error(500, { message: `load:${country}:${shard.file}` });
- events = await res_country_shard.json();
- }
-
- const data: PageLoadData = {
+ return {
country,
- manifest,
- events,
- }
- return data;
-}
+ manifest: indexed.manifest,
+ events: indexed.events,
+ };
+};
export const prerender = true;
diff --git a/app/src/routes/(market)/(profile)/[0=nip05]/+page.ts b/app/src/routes/(market)/(profile)/[0=nip05]/+page.ts
@@ -1,15 +1,15 @@
import { _env } from "$lib/utils/_env";
import { load_profile_indexed } from "$lib/utils/profile";
-import type { EntryGenerator as entry_generator, PageLoad as page_load } from "./$types";
+import type { EntryGenerator, PageLoad } from "./$types";
const { RADROOTS_MARKET_RELAY_INDEXES_URL: idx_url } = _env;
-export const entries: entry_generator = async () => {
+export const entries: EntryGenerator = async () => {
const indexes: string[] = await fetch(`${idx_url}/events/0/nip05/indexes.json`).then(r => r.json());
return indexes.map(i => ({ 0: i }));
};
-export const load: page_load = async ({ fetch, params }) => {
+export const load: PageLoad = async ({ fetch, params }) => {
const { 0: nip05 } = params;
return load_profile_indexed(fetch, "nip05", nip05);
};
diff --git a/app/src/routes/(market)/(profile)/profile/[0=npub]/+page.ts b/app/src/routes/(market)/(profile)/profile/[0=npub]/+page.ts
@@ -1,15 +1,15 @@
import { _env } from "$lib/utils/_env";
import { load_profile_indexed } from "$lib/utils/profile";
-import type { EntryGenerator as entry_generator, PageLoad as page_load } from "./$types";
+import type { EntryGenerator, PageLoad } from "./$types";
const { RADROOTS_MARKET_RELAY_INDEXES_URL: idx_url } = _env;
-export const entries: entry_generator = async () => {
+export const entries: EntryGenerator = async () => {
const indexes: string[] = await fetch(`${idx_url}/events/0/npub/indexes.json`).then(r => r.json());
return indexes.map(i => ({ 0: i }));
};
-export const load: page_load = async ({ fetch, params }) => {
+export const load: PageLoad = async ({ fetch, params }) => {
const { 0: npub } = params;
return load_profile_indexed(fetch, "npub", npub);
};
diff --git a/app/src/routes/(market)/(profile)/profile/[0=public_key]/+page.ts b/app/src/routes/(market)/(profile)/profile/[0=public_key]/+page.ts
@@ -1,15 +1,15 @@
import { _env } from "$lib/utils/_env";
import { load_profile_indexed } from "$lib/utils/profile";
-import type { EntryGenerator as entry_generator, PageLoad as page_load } from "./$types";
+import type { EntryGenerator, PageLoad } from "./$types";
const { RADROOTS_MARKET_RELAY_INDEXES_URL: idx_url } = _env;
-export const entries: entry_generator = async () => {
+export const entries: EntryGenerator = async () => {
const indexes: string[] = await fetch(`${idx_url}/events/0/author/indexes.json`).then(r => r.json());
return indexes.map(i => ({ 0: i }));
};
-export const load: page_load = async ({ fetch, params }) => {
+export const load: PageLoad = async ({ fetch, params }) => {
const { 0: public_key } = params;
return load_profile_indexed(fetch, "author", public_key);
};