11<script setup lang="ts">
2- import { shallowRef, unref, watch, onBeforeMount, type ShallowRef } from 'vue'
2+ import { shallowRef, unref, computed, watch, onBeforeMount, type ShallowRef } from 'vue'
33
44import PlaneAnimation from './PlaneAnimation.vue';
55import ShipAnimation from './ShipAnimation.vue';
@@ -15,7 +15,7 @@ import type { DatasetSrc, DatasetMetadata, ManualMetadata } from '@orcestra/util
1515import * as yaml from 'js-yaml';
1616
1717import { useHelia } from '../plugins/HeliaProvider';
18- import type { Helia } from 'helia';
18+ import type { Helia, Provider } from 'helia';
1919import type { CID } from 'multiformats';
2020import PathView from './PathView.vue';
2121
@@ -27,6 +27,8 @@ const metadata: ShallowRef<DatasetSrc | DatasetMetadata | undefined> = shallowRe
2727
2828const stac_item = shallowRef();
2929
30+ const providers = shallowRef<Provider[]>([]);
31+
3032async function resolve_cids(helia: Helia, src: string): Promise<{root_cid?: CID, item_cid?: CID}> {
3133 if (!helia) {
3234 return {};
@@ -38,7 +40,48 @@ async function resolve_cids(helia: Helia, src: string): Promise<{root_cid?: CID,
3840 return {root_cid, item_cid};
3941}
4042
43+ const knownPeers: Record<string, string> = {
44+ "12D3KooWN1cJjVBqXmCmaNF6yihB9vTuSSeSHJ2kw6waaQ5Mvmsm": "DKRZ",
45+ "12D3KooWBWikPAjn7SeWVY5uzi42mncf2qdYZu88eFjroVaQ46jw": "GWDG Cloud",
46+ "12D3KooWL3E6UMhVPHq8tyCKoAybRxQQgE2uGVLVphtmqNhaegE2": "Pi 5 (MPIM)",
47+ "12D3KooWDxsa98TAgDRVRby6bPxvnHfqBdL1hHBqMqP2PWoSHmcJ": "Pi (lkluft)",
48+ };
49+
50+ function parseProvider(provider: Provider): string | undefined {
51+ if (provider.id.type === "url") {
52+ const url = new TextDecoder().decode(provider.id.toMultihash().digest);
53+ if (url.match(/^https?:\/\/127.0.0.1[:\/]/)) {
54+ return "local gateway";
55+ }
56+ if (url.match(/^https:\/\/.+\.orcestra-campaign\.org\//)) {
57+ return "ORCESTRA Gateway";
58+ }
59+ if (url.match(/^https:\/\/trustless-gateway.link\//)) {
60+ return "public gateway";
61+ }
62+ }
63+ const short = knownPeers[provider.id.toString()];
64+ if (short !== undefined) {
65+ return short;
66+ }
67+ for(const ma of provider.multiaddrs) {
68+ if (ma.toString().match(/^\/dns.\/[^\/]+\.pinata\.cloud\//)) {
69+ return "Pinata";
70+ }
71+ }
72+ return undefined;
73+ }
74+
75+ const updateProviders = async() => {
76+ if (metadata.value?.item_cid) {
77+ for await (const provider of heliaProvider.helia.value.routing.findProviders(metadata.value?.item_cid)) {
78+ providers.value = [...providers.value, provider];
79+ }
80+ }
81+ }
82+
4183const update = async () => {
84+ providers.value = [];
4285 if (heliaProvider.loading.value) return;
4386 const store = getStore(props.src, {helia: heliaProvider.helia.value});
4487 const raw_metadata = await store.get("/dataset_meta.yaml");
@@ -57,6 +100,7 @@ const update = async () => {
57100 console.log(metadata.value);
58101 metadata.value = {...metadata.value, ...await resolve_cids(heliaProvider.helia.value, props.src)};
59102 console.log(metadata.value);
103+ updateProviders(); // execute asynchronously
60104 if (metadata.value) {
61105 for await (const item of parseMetadata(unref(metadata.value))) {
62106 stac_item.value = item;
@@ -66,6 +110,32 @@ const update = async () => {
66110
67111onBeforeMount(update);
68112watch([() => props.src, heliaProvider?.loading], update);
113+
114+ const providedBy = computed(() => {
115+ const parsed = [];
116+ const others = [];
117+ for (const provider of providers.value) {
118+ const p = parseProvider(unref(provider));
119+ if (p !== undefined) {
120+ parsed.push(p);
121+ } else {
122+ others.push(provider.id.toString());
123+ }
124+ }
125+ if (parsed.length > 0) {
126+ if (others.length > 0) {
127+ return parsed.join(", ") + " and " + others.length + " others";
128+ } else {
129+ return parsed.join(", ")
130+ }
131+ } else {
132+ if (others.length > 0) {
133+ return others.length + " nodes";
134+ } else {
135+ return "no one ¯\_(ツ)_/¯";
136+ }
137+ }
138+ })
69139</script>
70140
71141<template>
@@ -77,4 +147,5 @@ watch([() => props.src, heliaProvider?.loading], update);
77147 <PathView v-if="metadata?.src" :src="metadata?.src as string" :item_cid="metadata?.item_cid" />
78148 <ItemView v-if="stac_item" :item="stac_item" />
79149 <Animation v-else />
150+ <div v-if="metadata?.item_cid">Dataset is provided by {{ providedBy }}.</div>
80151</template>
0 commit comments