@seedprotocol/arweave 0.7.3 → 0.7.4-next.784.g879c6a3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["trimOrEmpty","g","getArweaveReadGatewayHostsForPrimary","hasArweaveContentReadTransform","mergePrimaryHostWithDefaults","transformArweaveContent","DEFAULT_ARWEAVE_GRAPHQL_URL","DEFAULT_ARWEAVE_HOST","DEFAULT_SEED_GATEWAY_HYPER_KEY","DEFAULT_SEED_FEED_HYPER_KEY","getResponseMediaType","DEFAULT_GATEWAY_SIDECAR_PORT","GET_TRANSACTION_TAGS","readArweaveContentResponse","DEFAULT_GATEWAY_SIDECAR_HOST","BaseArweaveClient","setArweaveContentReadTransform","GET_ARWEAVE_TRANSACTIONS","DEFAULT_ARWEAVE_GATEWAYS","getDefaultArweaveReadGatewayHostsOrdered","resolveArweaveHostFromEnv","isKnownArweaveGatewayHostname","EAS_ATTESTATION_EXPLORER_HOST","isEasAttestationExplorerUrl","trimmed","url","parsed","parseLocalIdOrUid","id","localIdOrUid","normalizeRelationPropertyValue","value","o","LOCAL_SEED_REF","resolveSeedIdsFromRefString","fromCorrect","s","ARWEAVE_TX_ID","trimOrEmpty$1","raw","coalesceStringField","v","item","key","unwrapRelationString","fromObj","classifyMediaRef","treatAs","options","unwrapped","ids","getFeedItemStringField","direct","snake","l","alt","parts","alt2","p","normalizeFeedItemFields","out","fieldKey","descriptor","manifest","classification","getArweaveUrlForTransaction","transactionId","SEED_RSS_IMAGE_RELATION_FIELD_KEYS","trimOrEmpty","readObjectStringField","keys","obj","suffixes","rawKey","rawValue","normalizedLower","suffix","tryGatewayUrlForTxId","txId","resolveMediaUrlFromParts","fromTx","arweaveUrl","resolveFromString","mediaUrl","resolveFromObject","storageTransactionId","seedUid","link","resolveSeedRssImageRelationRef","entry","resolved","resolveSeedRssImageRelationFromItem","fieldKeys","TRANSACTION_TAGS_BATCH_SIZE","GET_TRANSACTIONS_TAGS_BY_IDS","getTransactionTagsByIds","transactionIds","client","batchSize","i","batch","result","edge","node","tag","error","DEFAULT_FAILURE_THRESHOLD","DEFAULT_OPEN_MS","failureThreshold","openDurationMs","circuits","normalizeGatewayHostKey","hostOrUrl","getOrCreate","c","resolveState","now","configureGatewayCircuitBreaker","resetGatewayCircuitBreakerForTests","isGatewayHostCircuitOpen","state","getGatewayHostCircuitState","beginGatewayHostHalfOpenProbe","recordGatewayHostSuccess","recordGatewayHostFailure","listOpenGatewayCircuitHosts","READ_GATEWAY_CACHE_TTL_MS","READ_GATEWAY_UNHEALTHY_CACHE_TTL_MS","PROBE_TIMEOUT_MS","readGatewayCache","ensureInFlight","lastHealthyReadGatewayHost","invalidateReadGatewayCache","resetArweaveReadGatewayForTests","isReadGatewayKnownHealthy","getLastHealthyReadGatewayHost","probeGateway","baseUrl","hostKey","timer","controller","effectiveSignal","signal","response","text","json","ok","selectFirstHealthyReadGateway","host","hosts","h","protocol","buildOrderedHostsForProbe","ensureReadGatewaySelected","picked","fallback","normalizeUploadApiBaseUrl","getUploadApiArweaveDataUrl","txOrDataItemId","DEFAULT_UPLOAD_STATUS_TIMEOUT_MS","getUploadPipelineTransactionStatus","uploadApiBaseUrl","timeoutMs","timeoutId","err","GATEWAY_TX_QUERY","getUploadApiArweaveStatusUrl","dataItemId","isArweaveL1AnchoringComplete","l1","status","getArweaveUploadStatus","body","queryArweaveGatewayTransaction","graphqlUrl","init","tx","queryArweaveGatewayTransactionWithFallback","defaults","preferredHost","u","ordered","PROBE_TTL_MS","sidecarProbeCache","proxyProbeCache","invalidateSidecarProbeCache","parseGatewayHost","input","sidecarOrigin","config","port","browserOrigin","origin","resolveProxyBaseUrl","proxyBaseUrl","probeUrlHealthy","cacheKey","healthy","cached","buildHttpEndpoints","buildHyperEndpoints","sidecar","buildProxyEndpoints","absoluteProxyBaseUrl","path","hostWithPath","tryProxyEndpoints","absolute","resolveSeedGatewayEndpoints","mode","shouldProbe","proxy","hyperEndpoints","getReadGatewayHostsForConfig","resolvedGatewayEndpoints","getResolvedSeedGatewayEndpoints","setResolvedSeedGatewayEndpoints","preferredReadBaseUrls","getPreferredArweaveReadBaseUrls","setPreferredArweaveReadBaseUrls","seen","urls","seedGatewayConfigFromSeedConfig","gateway","seedGatewayConfigFromClientContext","context","DEFAULT_ARWEAVE_RAW_READ_TIMEOUT_MS","pushUnique","getResolvedArweaveReadBaseUrls","getArweaveReadBaseUrls","ensureArweaveReadGatewayForFallback","fetchArweaveRawFromBaseUrl","res","fetchArweaveRawTextAcrossGateways","tried","tryUrls","base","bytes","ARWEAVE_HOST_ENV_KEYS"],"sources":["../src/easAttestationUrl.ts","../src/relationSeedRef.ts","../src/mediaRef.ts","../src/resolveSeedRssImageRelationRef.ts","../src/ArweaveClient/transactionTagsByIds.ts","../src/gateway/gatewayCircuitBreaker.ts","../src/ArweaveClient/selectReadGateway.ts","../src/ArweaveClient/uploadApiVerification.ts","../src/ArweaveClient/arweaveL1UploadApi.ts","../src/gateway/resolveSeedGatewayEndpoints.ts","../src/gateway/gatewayState.ts","../src/gateway/seedGatewayConfig.ts","../src/gateway/readBaseUrls.ts"],"sourcesContent":["const EAS_ATTESTATION_EXPLORER_HOST = /(^|\\.)easscan\\.(org|xyz)$/i\n\n/**\n * True when `url` points at an EAS attestation explorer HTML page (not fetchable media).\n */\nexport function isEasAttestationExplorerUrl(url: string): boolean {\n const trimmed = url.trim()\n if (!trimmed) return false\n try {\n const parsed = new URL(trimmed)\n if (!EAS_ATTESTATION_EXPLORER_HOST.test(parsed.hostname)) {\n return false\n }\n return /\\/attestation\\/view\\//i.test(parsed.pathname)\n } catch {\n return false\n }\n}\n","/** Same rules as getCorrectId in helpers/index (avoid barrel circular import). */\nfunction parseLocalIdOrUid(localIdOrUid: string): { localId?: string; uid?: string } {\n const id = { localId: undefined as string | undefined, uid: undefined as string | undefined }\n if (!localIdOrUid) return id\n if (localIdOrUid.length === 10) {\n id.localId = localIdOrUid\n }\n if (localIdOrUid.startsWith('0x') && localIdOrUid.length === 66) {\n id.uid = localIdOrUid\n }\n return id\n}\n\nexport function normalizeRelationPropertyValue(value: unknown): string | undefined {\n if (value == null) return undefined\n if (typeof value === 'string') {\n const t = value.trim()\n return t !== '' ? t : undefined\n }\n if (typeof value === 'object' && value !== null) {\n const o = value as { seedLocalId?: string; seedUid?: string }\n if (typeof o.seedLocalId === 'string' && o.seedLocalId.trim() !== '') {\n return o.seedLocalId.trim()\n }\n if (typeof o.seedUid === 'string' && o.seedUid.trim() !== '') {\n return o.seedUid.trim()\n }\n }\n return undefined\n}\n\nconst LOCAL_SEED_REF = /^[a-zA-Z0-9_-]{10,21}$/\n\nexport function resolveSeedIdsFromRefString(s: string): {\n seedLocalId?: string\n seedUid?: string\n} {\n const fromCorrect = parseLocalIdOrUid(s)\n if (fromCorrect.localId || fromCorrect.uid) {\n return { seedLocalId: fromCorrect.localId, seedUid: fromCorrect.uid }\n }\n if (LOCAL_SEED_REF.test(s) && !s.startsWith('0x')) {\n return { seedLocalId: s }\n }\n return {}\n}\n","import { BaseArweaveClient } from './ArweaveClient/BaseArweaveClient.js'\nimport { isEasAttestationExplorerUrl } from './easAttestationUrl.js'\nimport {\n normalizeRelationPropertyValue,\n resolveSeedIdsFromRefString,\n} from './relationSeedRef.js'\n\nexport type FeedFieldRole = 'image' | 'audio' | 'video' | 'file' | 'html' | 'text'\n\nexport type FeedFieldDescriptor = {\n role: FeedFieldRole\n treatAs?: 'arweaveTx' | 'seedUid' | 'url'\n}\n\nexport type FeedFieldManifest = Record<string, FeedFieldDescriptor>\n\nexport type ClassifyMediaRefOptions = {\n treatAs?: FeedFieldDescriptor['treatAs']\n}\n\nexport type MediaRefClassification =\n | { kind: 'empty' }\n | { kind: 'url'; href: string }\n | { kind: 'nonMediaUrl'; href: string }\n | { kind: 'seedUid'; uid: string }\n | { kind: 'seedLocalId'; localId: string }\n | { kind: 'arweaveTxId'; txId: string }\n | { kind: 'unknown'; raw: string }\n\nexport type ResolveMediaRefResult =\n | { status: 'ready'; href: string; source: 'direct' | 'gateway' | 'localBlob' }\n | { status: 'empty' }\n | {\n status: 'unresolved'\n reason: string\n classification: MediaRefClassification\n }\n\nexport type ResolveMediaRefOptions = ClassifyMediaRefOptions\n\nconst ARWEAVE_TX_ID = /^[a-zA-Z0-9_-]{43}$/\n\nfunction trimOrEmpty(raw: string | undefined | null): string {\n if (raw == null) return ''\n return typeof raw === 'string' ? raw.trim() : String(raw).trim()\n}\n\nfunction coalesceStringField(item: Record<string, unknown>, key: string): string {\n const v = item[key]\n if (v == null) return ''\n if (typeof v === 'string') return v.trim()\n if (typeof v === 'number' || typeof v === 'boolean') return String(v)\n return ''\n}\n\nfunction unwrapRelationString(raw: string): string {\n const t = raw.trim()\n if (!t) return t\n try {\n const parsed = JSON.parse(t) as unknown\n const fromObj = normalizeRelationPropertyValue(parsed)\n if (fromObj) return fromObj\n } catch {\n // not JSON\n }\n return t\n}\n\nexport function classifyMediaRef(\n raw: string,\n options?: ClassifyMediaRefOptions,\n): MediaRefClassification {\n const s = trimOrEmpty(raw)\n if (!s) {\n return { kind: 'empty' }\n }\n\n const treatAs = options?.treatAs\n if (treatAs === 'url') {\n return { kind: 'url', href: s }\n }\n if (treatAs === 'arweaveTx') {\n return { kind: 'arweaveTxId', txId: s }\n }\n if (treatAs === 'seedUid') {\n if (s.startsWith('0x') && s.length === 66) {\n return { kind: 'seedUid', uid: s }\n }\n return { kind: 'unknown', raw: s }\n }\n\n if (\n s.startsWith('http://') ||\n s.startsWith('https://') ||\n s.startsWith('blob:') ||\n s.startsWith('data:')\n ) {\n if (isEasAttestationExplorerUrl(s)) {\n return { kind: 'nonMediaUrl', href: s }\n }\n return { kind: 'url', href: s }\n }\n\n const unwrapped = unwrapRelationString(s)\n const ids = resolveSeedIdsFromRefString(unwrapped)\n if (ids.seedUid) {\n return { kind: 'seedUid', uid: ids.seedUid }\n }\n if (ids.seedLocalId) {\n return { kind: 'seedLocalId', localId: ids.seedLocalId }\n }\n\n if (unwrapped.startsWith('0x') && unwrapped.length === 66) {\n return { kind: 'seedUid', uid: unwrapped }\n }\n\n if (ARWEAVE_TX_ID.test(unwrapped) && !unwrapped.startsWith('0x')) {\n return { kind: 'arweaveTxId', txId: unwrapped }\n }\n\n return { kind: 'unknown', raw: s }\n}\n\nexport type NormalizedMediaField = {\n role: 'image' | 'audio' | 'video' | 'file'\n raw: string\n classification: MediaRefClassification\n}\n\nexport type NormalizedHtmlField = {\n role: 'html'\n raw: string\n}\n\nexport type NormalizedTextField = {\n role: 'text'\n raw: string\n}\n\nexport type NormalizedFeedFieldValue =\n | NormalizedMediaField\n | NormalizedHtmlField\n | NormalizedTextField\n\nexport function getFeedItemStringField(item: Record<string, unknown>, key: string): string {\n const direct = coalesceStringField(item, key)\n if (direct) return direct\n const snake = key.replace(/[A-Z]/g, (l) => `_${l.toLowerCase()}`)\n if (snake !== key) {\n const alt = coalesceStringField(item, snake)\n if (alt) return alt\n }\n const parts = key.split('_')\n if (parts.length > 1) {\n const camel =\n parts[0] + parts.slice(1).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join('')\n const alt2 = coalesceStringField(item, camel)\n if (alt2) return alt2\n }\n return ''\n}\n\nexport function normalizeFeedItemFields(\n item: Record<string, unknown>,\n manifest: FeedFieldManifest,\n): Record<string, NormalizedFeedFieldValue | undefined> {\n const out: Record<string, NormalizedFeedFieldValue | undefined> = {}\n for (const [fieldKey, descriptor] of Object.entries(manifest)) {\n const raw = getFeedItemStringField(item, fieldKey)\n if (!raw) {\n out[fieldKey] = undefined\n continue\n }\n if (descriptor.role === 'html') {\n out[fieldKey] = { role: 'html', raw }\n continue\n }\n if (descriptor.role === 'text') {\n out[fieldKey] = { role: 'text', raw }\n continue\n }\n const classification = classifyMediaRef(raw, { treatAs: descriptor.treatAs })\n out[fieldKey] = {\n role: descriptor.role,\n raw,\n classification,\n }\n }\n return out\n}\n\nexport function getArweaveUrlForTransaction(transactionId: string): string {\n return `${BaseArweaveClient.getBaseUrl()}/${transactionId}`\n}\n","import { BaseArweaveClient } from './ArweaveClient/BaseArweaveClient.js'\nimport { isEasAttestationExplorerUrl } from './easAttestationUrl.js'\nimport { classifyMediaRef } from './mediaRef.js'\n\nexport type SeedRssImageRelationRef = {\n storageTransactionId?: string\n arweaveUrl?: string\n seedUid?: string\n /** Gateway/raw URL suitable for image fetch; never an EAS attestation explorer page. */\n mediaUrl?: string\n}\n\nexport const SEED_RSS_IMAGE_RELATION_FIELD_KEYS = [\n 'featureImage',\n 'feature_image',\n 'image',\n 'images',\n 'coverImage',\n 'cover_image',\n 'thumbnail',\n 'thumbnail_image',\n 'thumbnailImage',\n] as const\n\nfunction trimOrEmpty(value: unknown): string {\n if (value == null) return ''\n if (typeof value === 'string') return value.trim()\n if (typeof value === 'number' || typeof value === 'boolean') return String(value)\n return ''\n}\n\nfunction readObjectStringField(obj: Record<string, unknown>, ...keys: string[]): string {\n for (const key of keys) {\n const direct = trimOrEmpty(obj[key])\n if (direct) return direct\n }\n\n const suffixes = keys.map((key) => key.split(':').pop()!.toLowerCase())\n for (const [rawKey, rawValue] of Object.entries(obj)) {\n const normalizedKey = rawKey.includes(':') ? rawKey.split(':').pop()! : rawKey\n const normalizedLower = normalizedKey.toLowerCase()\n if (suffixes.some((suffix) => normalizedLower === suffix.toLowerCase())) {\n const value = trimOrEmpty(rawValue)\n if (value) return value\n }\n }\n\n return ''\n}\n\nfunction tryGatewayUrlForTxId(txId: string): string | undefined {\n const trimmed = txId.trim()\n if (!trimmed || trimmed.startsWith('0x')) return undefined\n try {\n return `${BaseArweaveClient.getBaseUrl()}/${trimmed}`\n } catch {\n return undefined\n }\n}\n\nfunction resolveMediaUrlFromParts(parts: {\n storageTransactionId?: string\n arweaveUrl?: string\n}): string | undefined {\n const txId = parts.storageTransactionId?.trim()\n if (txId) {\n const fromTx = tryGatewayUrlForTxId(txId)\n if (fromTx) return fromTx\n }\n\n const arweaveUrl = parts.arweaveUrl?.trim()\n if (arweaveUrl && !isEasAttestationExplorerUrl(arweaveUrl)) {\n return arweaveUrl\n }\n\n return undefined\n}\n\nfunction resolveFromString(value: string): SeedRssImageRelationRef | undefined {\n const trimmed = value.trim()\n if (!trimmed) return undefined\n\n if (isEasAttestationExplorerUrl(trimmed)) {\n return undefined\n }\n\n const classification = classifyMediaRef(trimmed)\n switch (classification.kind) {\n case 'url':\n return { mediaUrl: classification.href }\n case 'arweaveTxId': {\n const mediaUrl = tryGatewayUrlForTxId(classification.txId)\n return {\n storageTransactionId: classification.txId,\n ...(mediaUrl ? { mediaUrl } : {}),\n }\n }\n case 'seedUid':\n return { seedUid: classification.uid }\n default: {\n const mediaUrl = tryGatewayUrlForTxId(trimmed)\n if (mediaUrl) {\n return {\n storageTransactionId: trimmed,\n mediaUrl,\n }\n }\n return undefined\n }\n }\n}\n\nfunction resolveFromObject(obj: Record<string, unknown>): SeedRssImageRelationRef | undefined {\n const storageTransactionId = readObjectStringField(\n obj,\n 'storageTransactionId',\n 'storage_transaction_id',\n )\n const arweaveUrl = readObjectStringField(obj, 'arweaveUrl', 'arweave_url')\n const seedUid = readObjectStringField(obj, 'seedUid', 'SeedUid', 'seed_uid')\n const link = readObjectStringField(obj, 'link', 'Link')\n\n const mediaUrl =\n resolveMediaUrlFromParts({ storageTransactionId, arweaveUrl }) ??\n (link && !isEasAttestationExplorerUrl(link) ? link : undefined)\n\n if (!storageTransactionId && !arweaveUrl && !seedUid && !mediaUrl) {\n return undefined\n }\n\n return {\n ...(storageTransactionId ? { storageTransactionId } : {}),\n ...(arweaveUrl && !isEasAttestationExplorerUrl(arweaveUrl) ? { arweaveUrl } : {}),\n ...(seedUid ? { seedUid } : {}),\n ...(mediaUrl ? { mediaUrl } : {}),\n }\n}\n\n/**\n * Resolve a Seed RSS image relation value (plain string or expanded relation object)\n * using field priority: storageTransactionId → arweaveUrl/gateway URL → seedUid.\n * EAS attestation explorer URLs are never returned as media.\n */\nexport function resolveSeedRssImageRelationRef(value: unknown): SeedRssImageRelationRef | undefined {\n if (value == null) return undefined\n\n if (typeof value === 'string') {\n return resolveFromString(value)\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n const resolved = resolveSeedRssImageRelationRef(entry)\n if (resolved?.mediaUrl || resolved?.storageTransactionId || resolved?.seedUid) {\n return resolved\n }\n }\n return undefined\n }\n\n if (typeof value === 'object') {\n return resolveFromObject(value as Record<string, unknown>)\n }\n\n return undefined\n}\n\n/**\n * Read the first configured image-relation field from a parsed RSS item record.\n */\nexport function resolveSeedRssImageRelationFromItem(\n item: Record<string, unknown>,\n fieldKeys: readonly string[] = SEED_RSS_IMAGE_RELATION_FIELD_KEYS,\n): SeedRssImageRelationRef | undefined {\n for (const key of fieldKeys) {\n if (!(key in item)) continue\n const resolved = resolveSeedRssImageRelationRef(item[key])\n if (resolved) return resolved\n }\n return undefined\n}\n","import type { GraphQLClient } from 'graphql-request'\nimport { BaseArweaveClient } from './BaseArweaveClient.js'\nimport type { TransactionTag } from '../types/arweave.js'\n\n/** Arweave GraphQL serves at most 100 transactions per page. */\nexport const TRANSACTION_TAGS_BATCH_SIZE = 100\n\n/**\n * Plain string, not a codegen document: the `graphql()` helper from the client preset only knows\n * documents present when codegen last ran.\n */\nexport const GET_TRANSACTIONS_TAGS_BY_IDS = /* GraphQL */ `\n query GetTransactionsTagsByIds($ids: [ID!], $first: Int) {\n transactions(ids: $ids, first: $first) {\n edges {\n node {\n id\n tags {\n name\n value\n }\n }\n }\n }\n }\n`\n\ntype TransactionsTagsByIdsResult = {\n transactions?: {\n edges?: Array<{ node?: { id?: string; tags?: TransactionTag[] | null } | null } | null> | null\n } | null\n}\n\n/**\n * Tags of many transactions in batched GraphQL requests (`transactions(ids: [...])`), keyed by id.\n * A transaction the gateway does not know yet (e.g. just published, not indexed) is absent from\n * the map; a failed batch is skipped (logged through `onError`) rather than failing the caller.\n */\nexport async function getTransactionTagsByIds(\n transactionIds: readonly string[],\n options?: { client?: GraphQLClient; batchSize?: number; onError?: (error: unknown) => void },\n): Promise<Map<string, TransactionTag[]>> {\n const out = new Map<string, TransactionTag[]>()\n const ids = Array.from(new Set(transactionIds.filter((id) => typeof id === 'string' && id.trim())))\n if (ids.length === 0) return out\n\n const client = options?.client ?? BaseArweaveClient.getArweaveClient()\n const batchSize = Math.max(1, Math.min(options?.batchSize ?? TRANSACTION_TAGS_BATCH_SIZE, TRANSACTION_TAGS_BATCH_SIZE))\n\n for (let i = 0; i < ids.length; i += batchSize) {\n const batch = ids.slice(i, i + batchSize)\n try {\n const result = await client.request<TransactionsTagsByIdsResult>(GET_TRANSACTIONS_TAGS_BY_IDS, {\n ids: batch,\n first: batch.length,\n })\n for (const edge of result?.transactions?.edges ?? []) {\n const node = edge?.node\n if (!node?.id) continue\n out.set(\n node.id,\n (node.tags ?? []).map((tag) => ({ name: tag.name, value: tag.value })),\n )\n }\n } catch (error) {\n options?.onError?.(error)\n }\n }\n return out\n}\n","/**\n * Process-wide circuit breaker for Arweave gateway hosts.\n *\n * After consecutive failures, a host is \"open\" for a cooldown and skipped by\n * probes / metadata fetches. After the cooldown it becomes half-open (one probe\n * allowed). Success closes the circuit.\n */\n\nexport type GatewayCircuitState = 'closed' | 'open' | 'half-open'\n\ntype HostCircuit = {\n failures: number\n openedAt: number | null\n /** When half-open, only one probe may run at a time. */\n halfOpenProbeInFlight: boolean\n}\n\nconst DEFAULT_FAILURE_THRESHOLD = 1\nconst DEFAULT_OPEN_MS = 60_000\n\nlet failureThreshold = DEFAULT_FAILURE_THRESHOLD\nlet openDurationMs = DEFAULT_OPEN_MS\nconst circuits = new Map<string, HostCircuit>()\n\n/** Strip scheme / trailing slash; lowercase host (+ optional port/path). */\nexport function normalizeGatewayHostKey(hostOrUrl: string): string {\n let t = hostOrUrl.trim()\n if (!t) return ''\n if (t.startsWith('http://')) t = t.slice(7)\n else if (t.startsWith('https://')) t = t.slice(8)\n return t.replace(/\\/$/, '').toLowerCase()\n}\n\nfunction getOrCreate(key: string): HostCircuit {\n let c = circuits.get(key)\n if (!c) {\n c = { failures: 0, openedAt: null, halfOpenProbeInFlight: false }\n circuits.set(key, c)\n }\n return c\n}\n\nfunction resolveState(c: HostCircuit, now: number): GatewayCircuitState {\n if (c.openedAt == null) return 'closed'\n if (now - c.openedAt >= openDurationMs) return 'half-open'\n return 'open'\n}\n\n/**\n * Configure failure threshold and open-state duration (mainly for tests).\n */\nexport function configureGatewayCircuitBreaker(options: {\n failureThreshold?: number\n openDurationMs?: number\n}): void {\n if (options.failureThreshold != null && options.failureThreshold >= 1) {\n failureThreshold = options.failureThreshold\n }\n if (options.openDurationMs != null && options.openDurationMs >= 0) {\n openDurationMs = options.openDurationMs\n }\n}\n\n/** Clears all host circuits and restores default thresholds (for tests). */\nexport function resetGatewayCircuitBreakerForTests(): void {\n circuits.clear()\n failureThreshold = DEFAULT_FAILURE_THRESHOLD\n openDurationMs = DEFAULT_OPEN_MS\n}\n\n/**\n * True when the host should not receive new requests (open), or a half-open\n * probe is already in flight.\n */\nexport function isGatewayHostCircuitOpen(hostOrUrl: string, now = Date.now()): boolean {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return false\n const c = circuits.get(key)\n if (!c) return false\n const state = resolveState(c, now)\n if (state === 'open') return true\n if (state === 'half-open' && c.halfOpenProbeInFlight) return true\n return false\n}\n\nexport function getGatewayHostCircuitState(\n hostOrUrl: string,\n now = Date.now(),\n): GatewayCircuitState {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return 'closed'\n const c = circuits.get(key)\n if (!c) return 'closed'\n return resolveState(c, now)\n}\n\n/**\n * Mark that a probe/request is starting against a half-open host so concurrent\n * callers skip it. No-op when closed or fully open.\n */\nexport function beginGatewayHostHalfOpenProbe(hostOrUrl: string, now = Date.now()): void {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return\n const c = getOrCreate(key)\n if (resolveState(c, now) === 'half-open') {\n c.halfOpenProbeInFlight = true\n }\n}\n\nexport function recordGatewayHostSuccess(hostOrUrl: string): void {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return\n circuits.set(key, { failures: 0, openedAt: null, halfOpenProbeInFlight: false })\n}\n\nexport function recordGatewayHostFailure(hostOrUrl: string, now = Date.now()): void {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return\n const c = getOrCreate(key)\n c.failures += 1\n c.halfOpenProbeInFlight = false\n if (c.failures >= failureThreshold) {\n c.openedAt = now\n }\n}\n\n/** Hosts currently in open (or half-open with in-flight) state. */\nexport function listOpenGatewayCircuitHosts(now = Date.now()): string[] {\n const out: string[] = []\n for (const key of circuits.keys()) {\n if (isGatewayHostCircuitOpen(key, now)) out.push(key)\n }\n return out\n}\n","import { BaseArweaveClient } from './BaseArweaveClient.js'\nimport {\n DEFAULT_ARWEAVE_HOST,\n getArweaveReadGatewayHostsForPrimary,\n} from '../constants.js'\nimport {\n beginGatewayHostHalfOpenProbe,\n isGatewayHostCircuitOpen,\n recordGatewayHostFailure,\n recordGatewayHostSuccess,\n resetGatewayCircuitBreakerForTests,\n} from '../gateway/gatewayCircuitBreaker.js'\n\nconst READ_GATEWAY_CACHE_TTL_MS = 3 * 60 * 1000\n/** Shorter TTL when no gateway passed the probe — avoid hammering while still recovering sooner. */\nconst READ_GATEWAY_UNHEALTHY_CACHE_TTL_MS = 60 * 1000\nconst PROBE_TIMEOUT_MS = 5000\n\ntype ReadGatewayCache = {\n host: string\n /** False when the last probe found no healthy gateway. */\n healthy: boolean\n expiresAt: number\n}\n\nlet readGatewayCache: ReadGatewayCache | null = null\nlet ensureInFlight: Promise<string> | null = null\n/** Last host that successfully passed /info (survives an all-fail probe cycle). */\nlet lastHealthyReadGatewayHost: string | null = null\n\n/** Clears cached read gateway (e.g. after tests or to force a fresh probe). */\nexport function invalidateReadGatewayCache(): void {\n readGatewayCache = null\n ensureInFlight = null\n}\n\n/** Clears probe cache, env override suppression, and preferred host (for tests). */\nexport function resetArweaveReadGatewayForTests(): void {\n invalidateReadGatewayCache()\n lastHealthyReadGatewayHost = null\n resetGatewayCircuitBreakerForTests()\n BaseArweaveClient.resetReadGatewaySelectionStateForTests()\n if (!BaseArweaveClient.isReadGatewayLocked()) {\n BaseArweaveClient.setPreferredReadGateway(DEFAULT_ARWEAVE_HOST)\n }\n}\n\n/**\n * True when the last {@link ensureReadGatewaySelected} probe found a healthy host\n * (or the cache still says so). False after an all-fail probe until the next success.\n */\nexport function isReadGatewayKnownHealthy(): boolean {\n if (BaseArweaveClient.isReadGatewayLocked()) return true\n if (readGatewayCache && Date.now() < readGatewayCache.expiresAt) {\n return readGatewayCache.healthy\n }\n return lastHealthyReadGatewayHost != null\n}\n\n/** Last gateway host that passed /info, if any. */\nexport function getLastHealthyReadGatewayHost(): string | null {\n return lastHealthyReadGatewayHost\n}\n\n/**\n * GET /info with timeout. Treat 2xx + JSON object as healthy.\n * Records circuit-breaker success/failure for the host.\n */\nexport async function probeGateway(baseUrl: string, signal?: AbortSignal): Promise<boolean> {\n const url = `${baseUrl.replace(/\\/$/, '')}/info`\n let hostKey = baseUrl\n try {\n hostKey = new URL(baseUrl.includes('://') ? baseUrl : `https://${baseUrl}`).host\n } catch {\n hostKey = baseUrl.replace(/^https?:\\/\\//, '').replace(/\\/$/, '')\n }\n\n if (isGatewayHostCircuitOpen(hostKey)) {\n return false\n }\n beginGatewayHostHalfOpenProbe(hostKey)\n\n let timer: ReturnType<typeof setTimeout> | undefined\n const controller = new AbortController()\n const effectiveSignal = signal ?? controller.signal\n if (!signal) {\n timer = setTimeout(() => controller.abort(), PROBE_TIMEOUT_MS)\n }\n try {\n const response = await fetch(url, {\n method: 'GET',\n signal: effectiveSignal,\n headers: { Accept: 'application/json' },\n })\n if (!response.ok) {\n recordGatewayHostFailure(hostKey)\n return false\n }\n const text = await response.text()\n if (!text.trim()) {\n recordGatewayHostFailure(hostKey)\n return false\n }\n try {\n const json = JSON.parse(text) as unknown\n const ok = typeof json === 'object' && json !== null\n if (ok) recordGatewayHostSuccess(hostKey)\n else recordGatewayHostFailure(hostKey)\n return ok\n } catch {\n recordGatewayHostFailure(hostKey)\n return false\n }\n } catch {\n recordGatewayHostFailure(hostKey)\n return false\n } finally {\n if (timer) clearTimeout(timer)\n }\n}\n\nexport async function selectFirstHealthyReadGateway(\n hosts: string[],\n protocol: 'http' | 'https' = 'https',\n signal?: AbortSignal,\n): Promise<string | null> {\n for (const host of hosts) {\n const h = host.trim().replace(/\\/$/, '')\n if (!h) continue\n if (isGatewayHostCircuitOpen(h)) continue\n const baseUrl = `${protocol}://${h}`\n if (await probeGateway(baseUrl, signal)) {\n return h\n }\n }\n return null\n}\n\nfunction buildOrderedHostsForProbe(): string[] {\n return getArweaveReadGatewayHostsForPrimary(BaseArweaveClient.getHost())\n}\n\n/**\n * Probes gateways in order and applies the first healthy host via {@link BaseArweaveClient.applyProbedReadGateway}.\n * No-op when the read gateway is locked ({@link BaseArweaveClient.setHost}).\n * Uses a short TTL cache to avoid probing on every read.\n *\n * When every probe fails, keeps the last known healthy host (if any) instead of\n * treating the preferred-but-unreachable host as selected, and caches\n * `healthy: false` so {@link isReadGatewayKnownHealthy} reflects that.\n */\nexport async function ensureReadGatewaySelected(signal?: AbortSignal): Promise<string> {\n if (BaseArweaveClient.isReadGatewayLocked()) {\n return BaseArweaveClient.getHost()\n }\n\n const now = Date.now()\n if (readGatewayCache && now < readGatewayCache.expiresAt) {\n return readGatewayCache.host\n }\n\n if (ensureInFlight) {\n return ensureInFlight\n }\n\n ensureInFlight = (async () => {\n const ordered = buildOrderedHostsForProbe()\n const protocol = BaseArweaveClient.getProtocol()\n const picked = await selectFirstHealthyReadGateway(ordered, protocol, signal)\n\n if (!BaseArweaveClient.isReadGatewayLocked()) {\n if (picked) {\n BaseArweaveClient.applyProbedReadGateway(picked)\n lastHealthyReadGatewayHost = picked\n readGatewayCache = {\n host: picked,\n healthy: true,\n expiresAt: Date.now() + READ_GATEWAY_CACHE_TTL_MS,\n }\n } else {\n const fallback = lastHealthyReadGatewayHost ?? BaseArweaveClient.getHost()\n if (\n lastHealthyReadGatewayHost &&\n BaseArweaveClient.getHost() !== lastHealthyReadGatewayHost\n ) {\n BaseArweaveClient.applyProbedReadGateway(lastHealthyReadGatewayHost)\n }\n readGatewayCache = {\n host: fallback,\n healthy: false,\n expiresAt: Date.now() + READ_GATEWAY_UNHEALTHY_CACHE_TTL_MS,\n }\n }\n } else {\n readGatewayCache = {\n host: BaseArweaveClient.getHost(),\n healthy: true,\n expiresAt: Date.now() + READ_GATEWAY_CACHE_TTL_MS,\n }\n }\n\n return readGatewayCache.host\n })()\n\n try {\n return await ensureInFlight\n } finally {\n ensureInFlight = null\n }\n}\n","import type { TransactionStatus } from '../types/arweave.js'\n\n/**\n * Trim and strip a trailing slash from an upload API base URL.\n */\nexport function normalizeUploadApiBaseUrl(baseUrl: string): string {\n return baseUrl.trim().replace(/\\/+$/, '')\n}\n\n/**\n * URL used to verify that an upload is available via the Seed upload API\n * (`GET` → HTTP 200 when present). Works for L1 transaction ids and ANS-104 data item ids.\n *\n * @param baseUrl - Upload API origin (e.g. from `ARWEAVE_UPLOAD_API_BASE_URL` / `uploadApiBaseUrl`)\n * @param txOrDataItemId - Arweave tx id or bundler data item id\n */\nexport function getUploadApiArweaveDataUrl(baseUrl: string, txOrDataItemId: string): string {\n const base = normalizeUploadApiBaseUrl(baseUrl)\n const id = encodeURIComponent(txOrDataItemId)\n return `${base}/api/upload/arweave/data/${id}`\n}\n\nconst DEFAULT_UPLOAD_STATUS_TIMEOUT_MS = 45_000\n\nexport type GetUploadPipelineTransactionStatusOptions = {\n /** Abort the request after this many ms (upload API hung / unreachable). Default 45s. */\n timeoutMs?: number\n}\n\n/**\n * Presence check against the upload API data route (same semantics as\n * {@link BaseArweaveClient.getTransactionStatus} for gateways: 200 = present, 404 = missing).\n */\nexport async function getUploadPipelineTransactionStatus(\n uploadApiBaseUrl: string,\n txOrDataItemId: string,\n options?: GetUploadPipelineTransactionStatusOptions,\n): Promise<TransactionStatus> {\n const url = getUploadApiArweaveDataUrl(uploadApiBaseUrl, txOrDataItemId)\n const timeoutMs = options?.timeoutMs ?? DEFAULT_UPLOAD_STATUS_TIMEOUT_MS\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs)\n\n try {\n const response = await fetch(url, { signal: controller.signal })\n clearTimeout(timeoutId)\n\n if (response.status === 404) {\n return { status: 404, confirmed: null }\n }\n\n if (!response.ok) {\n return { status: response.status, confirmed: null }\n }\n\n if (response.body) {\n await response.body.cancel()\n }\n\n return { status: 200, confirmed: null }\n } catch (err) {\n clearTimeout(timeoutId)\n if (err instanceof Error && err.name === 'AbortError') {\n return { status: 504, confirmed: null }\n }\n return { status: 500, confirmed: null }\n }\n}\n","import {\n getDefaultArweaveReadGatewayHostsOrdered,\n getArweaveReadGatewayHostsForPrimary,\n} from '../constants.js'\nimport { normalizeUploadApiBaseUrl } from './uploadApiVerification.js'\nimport { probeGateway } from './selectReadGateway.js'\n\n/** Response shape from `GET /api/upload/arweave/status/{dataItemId}`. */\nexport interface ArweaveUploadStatusResponse {\n dataItemId?: string\n phase?: string\n bundleId?: string\n turboStatus?: string\n turboInfo?: string\n winc?: string\n turbo?: {\n status?: string\n bundleId?: string\n info?: string\n winc?: string\n }\n l1?: {\n checked?: boolean\n httpStatus?: number\n confirmed?: boolean\n numberOfConfirmations?: number\n minConfirmationsRequired?: number\n meetsMinConfirmations?: boolean\n }\n}\n\nexport interface ArweaveGatewayTransactionQueryResult {\n /** GraphQL `transaction.id` (often same as data item id for ANS-104 items). */\n transactionId: string | null\n /** L1 bundle transaction id when the item is indexed as bundled. */\n bundledInId: string | null\n blockHeight?: number | null\n blockTimestamp?: number | null\n}\n\nconst GATEWAY_TX_QUERY = `\n query ArweaveGatewayTransaction($id: String!) {\n transaction(id: $id) {\n id\n bundledIn {\n id\n }\n block {\n height\n timestamp\n }\n }\n }\n`\n\nexport function getUploadApiArweaveStatusUrl(baseUrl: string, dataItemId: string): string {\n const base = normalizeUploadApiBaseUrl(baseUrl)\n const id = encodeURIComponent(dataItemId)\n return `${base}/api/upload/arweave/status/${id}`\n}\n\n/**\n * Whether L1 anchoring is complete per upload API status JSON.\n */\nexport function isArweaveL1AnchoringComplete(status: ArweaveUploadStatusResponse): boolean {\n const l1 = status.l1\n if (!l1) return false\n if (l1.meetsMinConfirmations === true) return true\n if (l1.confirmed === true) return true\n return false\n}\n\n/**\n * Fetches JSON from `GET /api/upload/arweave/status/{dataItemId}`.\n * Returns `null` if the response is not OK or body is not JSON.\n */\nexport async function getArweaveUploadStatus(\n uploadApiBaseUrl: string,\n dataItemId: string,\n): Promise<ArweaveUploadStatusResponse | null> {\n const url = getUploadApiArweaveStatusUrl(uploadApiBaseUrl, dataItemId)\n try {\n const response = await fetch(url)\n if (!response.ok) {\n return null\n }\n const body = (await response.json()) as ArweaveUploadStatusResponse\n return body && typeof body === 'object' ? body : null\n } catch {\n return null\n }\n}\n\n/**\n * Queries an Arweave gateway GraphQL API for transaction + bundle info.\n */\nexport async function queryArweaveGatewayTransaction(\n graphqlUrl: string,\n dataItemId: string,\n init?: Pick<RequestInit, 'signal'>,\n): Promise<ArweaveGatewayTransactionQueryResult | null> {\n const url = graphqlUrl.trim()\n if (!url) return null\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n query: GATEWAY_TX_QUERY,\n variables: { id: dataItemId },\n }),\n signal: init?.signal,\n })\n\n if (!response.ok) {\n return null\n }\n\n const json = (await response.json()) as {\n data?: {\n transaction?: {\n id?: string\n bundledIn?: { id?: string } | null\n block?: { height?: number; timestamp?: number } | null\n } | null\n }\n errors?: unknown\n }\n\n if (json.errors) {\n return null\n }\n\n const tx = json.data?.transaction\n if (!tx) {\n return {\n transactionId: null,\n bundledInId: null,\n blockHeight: null,\n blockTimestamp: null,\n }\n }\n\n return {\n transactionId: typeof tx.id === 'string' ? tx.id : null,\n bundledInId: tx.bundledIn?.id != null ? String(tx.bundledIn.id) : null,\n blockHeight: tx.block?.height ?? null,\n blockTimestamp: tx.block?.timestamp ?? null,\n }\n } catch {\n return null\n }\n}\n\n/**\n * Resolves GraphQL against the first healthy gateway (GET /info probe per host), then runs\n * {@link queryArweaveGatewayTransaction}. Host order: optional `graphqlUrl` hostname first, then\n * {@link getDefaultArweaveReadGatewayHostsOrdered}.\n */\nexport async function queryArweaveGatewayTransactionWithFallback(\n graphqlUrl: string | undefined,\n dataItemId: string,\n init?: Pick<RequestInit, 'signal'>,\n): Promise<ArweaveGatewayTransactionQueryResult | null> {\n const defaults = getDefaultArweaveReadGatewayHostsOrdered()\n const trimmed = graphqlUrl?.trim()\n let protocol: 'http' | 'https' = 'https'\n let preferredHost: string | null = null\n if (trimmed) {\n try {\n const u = new URL(trimmed)\n protocol = u.protocol === 'http:' ? 'http' : 'https'\n preferredHost = u.hostname || null\n } catch {\n preferredHost = null\n }\n }\n\n const ordered =\n preferredHost && preferredHost.length > 0\n ? getArweaveReadGatewayHostsForPrimary(preferredHost)\n : [...defaults]\n\n const signal = init?.signal\n for (const host of ordered) {\n const base = `${protocol}://${host}`\n if (!(await probeGateway(base, signal ?? undefined))) continue\n const gqlUrl = `${protocol}://${host}/graphql`\n const result = await queryArweaveGatewayTransaction(gqlUrl, dataItemId, init)\n if (result !== null) {\n return result\n }\n }\n return null\n}\n","import { probeGateway } from '../ArweaveClient/selectReadGateway.js'\nimport {\n DEFAULT_ARWEAVE_HOST,\n DEFAULT_GATEWAY_SIDECAR_HOST,\n DEFAULT_GATEWAY_SIDECAR_PORT,\n getArweaveReadGatewayHostsForPrimary,\n} from '../constants.js'\nimport type {\n ResolvedSeedGatewayEndpoints,\n SeedGatewayConfig,\n SeedGatewayTransportMode,\n} from '../types/gateway.js'\n\nconst PROBE_TTL_MS = 3 * 60 * 1000\n\nlet sidecarProbeCache: { healthy: boolean; expiresAt: number } | null = null\nconst proxyProbeCache = new Map<string, { healthy: boolean; expiresAt: number }>()\n\n/** Clears cached sidecar / proxy probes (tests / forced re-probe). */\nexport function invalidateSidecarProbeCache(): void {\n sidecarProbeCache = null\n proxyProbeCache.clear()\n}\n\nfunction parseGatewayHost(input: string | undefined): { host: string; protocol: 'http' | 'https' } {\n const raw = (input ?? DEFAULT_ARWEAVE_HOST).trim()\n if (raw.startsWith('http://')) {\n return { protocol: 'http', host: raw.slice(7).replace(/\\/$/, '') }\n }\n if (raw.startsWith('https://')) {\n return { protocol: 'https', host: raw.slice(8).replace(/\\/$/, '') }\n }\n return { protocol: 'https', host: raw.replace(/\\/$/, '') }\n}\n\nfunction sidecarOrigin(config: SeedGatewayConfig): {\n host: string\n port: number\n baseUrl: string\n} {\n const host = config.hyper?.localSidecarHost?.trim() || DEFAULT_GATEWAY_SIDECAR_HOST\n const port = config.hyper?.localSidecarPort ?? DEFAULT_GATEWAY_SIDECAR_PORT\n const hostWithPort = port === 80 || port === 443 ? host : `${host}:${port}`\n return {\n host: hostWithPort,\n port,\n baseUrl: `http://${host}:${port}`,\n }\n}\n\nfunction browserOrigin(): string | undefined {\n try {\n const g = globalThis as { window?: { location?: { origin?: string } } }\n const origin = g.window?.location?.origin\n return typeof origin === 'string' && origin.length > 0 ? origin.replace(/\\/$/, '') : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Resolve `proxyBaseUrl` to an absolute origin+path (no trailing slash).\n * Relative paths require a browser `window.location.origin` or {@link ResolveSeedGatewayEndpointsOptions.origin}.\n */\nexport function resolveProxyBaseUrl(\n proxyBaseUrl: string,\n options?: { origin?: string },\n): string {\n const raw = proxyBaseUrl.trim()\n if (!raw) {\n throw new Error('proxyBaseUrl is empty')\n }\n if (raw.startsWith('http://') || raw.startsWith('https://')) {\n return raw.replace(/\\/$/, '')\n }\n if (raw.startsWith('/')) {\n const origin = (options?.origin?.trim() || browserOrigin() || '').replace(/\\/$/, '')\n if (!origin) {\n throw new Error(\n `Relative proxyBaseUrl \"${proxyBaseUrl}\" requires a browser origin or resolve options.origin`,\n )\n }\n return `${origin}${raw.replace(/\\/$/, '')}`\n }\n return `https://${raw.replace(/\\/$/, '')}`\n}\n\nasync function probeUrlHealthy(\n baseUrl: string,\n cacheKey: 'sidecar' | string,\n signal?: AbortSignal,\n): Promise<boolean> {\n const now = Date.now()\n if (cacheKey === 'sidecar') {\n if (sidecarProbeCache && now < sidecarProbeCache.expiresAt) {\n return sidecarProbeCache.healthy\n }\n const healthy = await probeGateway(baseUrl, signal)\n sidecarProbeCache = { healthy, expiresAt: now + PROBE_TTL_MS }\n return healthy\n }\n\n const cached = proxyProbeCache.get(cacheKey)\n if (cached && now < cached.expiresAt) {\n return cached.healthy\n }\n const healthy = await probeGateway(baseUrl, signal)\n proxyProbeCache.set(cacheKey, { healthy, expiresAt: now + PROBE_TTL_MS })\n return healthy\n}\n\nfunction buildHttpEndpoints(config: SeedGatewayConfig): ResolvedSeedGatewayEndpoints {\n const { host, protocol } = parseGatewayHost(config.arweaveDomain)\n const baseUrl = `${protocol}://${host}`\n const uploadApiBaseUrl = config.uploadApiBaseUrl?.trim() || baseUrl\n return {\n mode: config.transport ?? 'http-gateway',\n arweaveHost: host,\n arweaveProtocol: protocol,\n arweaveBaseUrl: baseUrl,\n arweaveGraphqlUrl: `${protocol}://${host}/graphql`,\n uploadApiBaseUrl,\n activePath: 'http',\n gatewayHyperKey: config.hyper?.gatewayHyperKey?.trim() || undefined,\n }\n}\n\nfunction buildHyperEndpoints(config: SeedGatewayConfig): ResolvedSeedGatewayEndpoints {\n const sidecar = sidecarOrigin(config)\n const key = config.hyper?.gatewayHyperKey?.trim()\n return {\n mode: 'hyper',\n arweaveHost: sidecar.host,\n arweaveProtocol: 'http',\n arweaveBaseUrl: sidecar.baseUrl,\n arweaveGraphqlUrl: `${sidecar.baseUrl}/graphql`,\n uploadApiBaseUrl: sidecar.baseUrl,\n activePath: 'hyper-sidecar',\n gatewayHyperKey: key || undefined,\n }\n}\n\nfunction buildProxyEndpoints(\n config: SeedGatewayConfig,\n absoluteProxyBaseUrl: string,\n): ResolvedSeedGatewayEndpoints {\n const parsed = new URL(absoluteProxyBaseUrl)\n const protocol: 'http' | 'https' = parsed.protocol === 'http:' ? 'http' : 'https'\n const path = parsed.pathname.replace(/\\/$/, '')\n const hostWithPath = path ? `${parsed.host}${path}` : parsed.host\n const baseUrl = `${protocol}://${hostWithPath}`\n return {\n mode: config.transport ?? 'http-gateway',\n arweaveHost: hostWithPath,\n arweaveProtocol: protocol,\n arweaveBaseUrl: baseUrl,\n arweaveGraphqlUrl: `${baseUrl}/graphql`,\n uploadApiBaseUrl: baseUrl,\n activePath: 'http-proxy',\n gatewayHyperKey: config.hyper?.gatewayHyperKey?.trim() || undefined,\n proxyBaseUrl: absoluteProxyBaseUrl,\n }\n}\n\nexport type ResolveSeedGatewayEndpointsOptions = {\n signal?: AbortSignal\n /** Skip cache and probe sidecar / proxy again. */\n forceSidecarProbe?: boolean\n /**\n * Origin used to resolve relative `proxyBaseUrl` (e.g. `https://app.example.com`).\n * Defaults to `window.location.origin` in browsers.\n */\n origin?: string\n}\n\nasync function tryProxyEndpoints(\n config: SeedGatewayConfig,\n options?: ResolveSeedGatewayEndpointsOptions,\n): Promise<ResolvedSeedGatewayEndpoints | null> {\n const raw = config.proxyBaseUrl?.trim()\n if (!raw) return null\n\n const absolute = resolveProxyBaseUrl(raw, { origin: options?.origin })\n const shouldProbe = config.hyper?.probeSidecar !== false\n if (shouldProbe) {\n const ok = await probeUrlHealthy(absolute, `proxy:${absolute}`, options?.signal)\n if (!ok) return null\n }\n return buildProxyEndpoints(config, absolute)\n}\n\n/**\n * Resolve effective gateway + upload API URLs for the configured transport mode.\n *\n * Preference when a proxy and/or sidecar may apply:\n * configured + healthy `proxyBaseUrl` → local Hyper sidecar → public HTTP gateway.\n */\nexport async function resolveSeedGatewayEndpoints(\n config: SeedGatewayConfig,\n options?: ResolveSeedGatewayEndpointsOptions,\n): Promise<ResolvedSeedGatewayEndpoints> {\n if (options?.forceSidecarProbe) {\n invalidateSidecarProbeCache()\n }\n\n const mode: SeedGatewayTransportMode = config.transport ?? 'http-gateway'\n const shouldProbe = config.hyper?.probeSidecar !== false\n\n if (mode === 'http-gateway') {\n if (config.proxyBaseUrl?.trim()) {\n const absolute = resolveProxyBaseUrl(config.proxyBaseUrl, { origin: options?.origin })\n if (shouldProbe) {\n const ok = await probeUrlHealthy(absolute, `proxy:${absolute}`, options?.signal)\n if (!ok) {\n throw new Error(\n `Gateway HTTP proxy not reachable at ${absolute}. ` +\n 'Ensure your Node route runs createGatewayProxy (or equivalent) and mounts at proxyBaseUrl.',\n )\n }\n }\n return buildProxyEndpoints({ ...config, transport: mode }, absolute)\n }\n return buildHttpEndpoints({ ...config, transport: mode })\n }\n\n if (mode === 'hyper') {\n const proxy = await tryProxyEndpoints({ ...config, transport: mode }, options)\n if (proxy) return proxy\n\n const hyperEndpoints = buildHyperEndpoints({ ...config, transport: mode })\n if (shouldProbe) {\n const ok = await probeUrlHealthy(hyperEndpoints.arweaveBaseUrl, 'sidecar', options?.signal)\n if (!ok) {\n throw new Error(\n `Gateway Hyper sidecar not reachable at ${hyperEndpoints.arweaveBaseUrl}. ` +\n 'Run: seed-gateway connect <operator-z32-key> — or configure gateway.proxyBaseUrl for an app-server proxy.',\n )\n }\n }\n return hyperEndpoints\n }\n\n // hybrid: proxy → sidecar → public HTTP\n const proxy = await tryProxyEndpoints({ ...config, transport: mode }, options)\n if (proxy) return proxy\n\n const sidecar = sidecarOrigin(config)\n if (shouldProbe && (await probeUrlHealthy(sidecar.baseUrl, 'sidecar', options?.signal))) {\n return buildHyperEndpoints({ ...config, transport: 'hyper' })\n }\n\n const http = buildHttpEndpoints({ ...config, transport: 'http-gateway' })\n return {\n ...http,\n mode: 'hybrid',\n activePath: 'hybrid-fallback-http',\n }\n}\n\n/** Build ordered gateway host list for read fallback (sidecar/proxy first when active). */\nexport function getReadGatewayHostsForConfig(\n resolved: ResolvedSeedGatewayEndpoints,\n _defaults?: readonly string[],\n): string[] {\n if (resolved.activePath === 'hyper-sidecar' || resolved.activePath === 'http-proxy') {\n return [resolved.arweaveHost]\n }\n return getArweaveReadGatewayHostsForPrimary(resolved.arweaveHost)\n}\n","import type { ResolvedSeedGatewayEndpoints } from '../types/gateway.js'\nimport { resolveProxyBaseUrl } from './resolveSeedGatewayEndpoints.js'\n\nlet resolvedGatewayEndpoints: ResolvedSeedGatewayEndpoints | null = null\n\n/** Last endpoints applied during client init (for read-path helpers). */\nexport function getResolvedSeedGatewayEndpoints(): ResolvedSeedGatewayEndpoints | null {\n return resolvedGatewayEndpoints\n}\n\nexport function setResolvedSeedGatewayEndpoints(\n value: ResolvedSeedGatewayEndpoints | null,\n): void {\n resolvedGatewayEndpoints = value\n}\n\nlet preferredReadBaseUrls: string[] = []\n\n/**\n * Gateways tried before the resolved / public hosts for `/raw/{id}` reads — typically the gateway\n * the app uploads through (Hyper sidecar or app-server proxy), which serves data items before they\n * reach L1 or the public gateways. Does not affect upload, GraphQL or {@link BaseArweaveClient} host.\n */\nexport function getPreferredArweaveReadBaseUrls(): string[] {\n return preferredReadBaseUrls\n}\n\n/**\n * Replace the preferred read gateways. Each entry is a base URL with scheme and any path prefix\n * (`https://app.example.com/api/seed-gateway`); same-origin relative paths (`/api/seed-gateway`)\n * resolve against `window.location.origin` and are dropped when there is no origin. Pass `[]` to clear.\n */\nexport function setPreferredArweaveReadBaseUrls(urls: readonly string[]): void {\n const out: string[] = []\n const seen = new Set<string>()\n for (const raw of urls) {\n const trimmed = raw?.trim()\n if (!trimmed) continue\n let url: string\n try {\n // URL lowercases scheme and host; the path stays case-sensitive.\n const parsed = new URL(/^https?:\\/\\//i.test(trimmed) ? trimmed : resolveProxyBaseUrl(trimmed))\n url = `${parsed.origin}${parsed.pathname.replace(/\\/+$/, '')}`\n } catch {\n continue\n }\n if (seen.has(url)) continue\n seen.add(url)\n out.push(url)\n }\n preferredReadBaseUrls = out\n}\n","import type {\n ClientGatewayContextInput,\n SeedConfigGatewayInput,\n SeedGatewayConfig,\n} from '../types/seedConfig.js'\nimport { DEFAULT_SEED_GATEWAY_HYPER_KEY } from '../constants.js'\n\n/** Merge seed.config gateway fields into {@link SeedGatewayConfig}. */\nexport function seedGatewayConfigFromSeedConfig(\n config: SeedConfigGatewayInput,\n): SeedGatewayConfig {\n const gateway = config.gateway ?? {}\n return {\n transport: gateway.transport,\n arweaveDomain: config.arweaveDomain ?? gateway.arweaveDomain,\n uploadApiBaseUrl: config.uploadApiBaseUrl ?? gateway.uploadApiBaseUrl,\n proxyBaseUrl: gateway.proxyBaseUrl?.trim() || undefined,\n preferredReadBaseUrls: gateway.preferredReadBaseUrls,\n hyper: {\n gatewayHyperKey:\n gateway.hyper?.gatewayHyperKey?.trim() ||\n gateway.gatewayHyperKey?.trim() ||\n DEFAULT_SEED_GATEWAY_HYPER_KEY ||\n undefined,\n localSidecarHost: gateway.hyper?.localSidecarHost ?? gateway.localSidecarHost,\n localSidecarPort: gateway.hyper?.localSidecarPort ?? gateway.localSidecarPort,\n probeSidecar: gateway.hyper?.probeSidecar ?? gateway.probeSidecar,\n },\n }\n}\n\nexport function seedGatewayConfigFromClientContext(\n context: ClientGatewayContextInput,\n): SeedGatewayConfig {\n return {\n transport: context.gatewayTransport,\n arweaveDomain: context.arweaveDomain,\n uploadApiBaseUrl: context.uploadApiBaseUrl,\n proxyBaseUrl: context.gatewayProxyBaseUrl?.trim() || undefined,\n hyper: {\n gatewayHyperKey:\n context.gatewayHyperKey?.trim() || DEFAULT_SEED_GATEWAY_HYPER_KEY || undefined,\n localSidecarHost: context.gatewaySidecarHost,\n localSidecarPort: context.gatewaySidecarPort,\n },\n }\n}\n","import { BaseArweaveClient } from '../ArweaveClient/BaseArweaveClient.js'\nimport { ensureReadGatewaySelected } from '../ArweaveClient/selectReadGateway.js'\nimport { getArweaveReadGatewayHostsForPrimary } from '../constants.js'\nimport { getPreferredArweaveReadBaseUrls, getResolvedSeedGatewayEndpoints } from './gatewayState.js'\nimport { getReadGatewayHostsForConfig } from './resolveSeedGatewayEndpoints.js'\nimport { readArweaveContentResponse } from '../content/arweaveContent.js'\n\n/** Per-gateway timeout for {@link fetchArweaveRawFromBaseUrl}; a hung gateway must not block the next one. */\nexport const DEFAULT_ARWEAVE_RAW_READ_TIMEOUT_MS = 10_000\n\nexport type ArweaveReadBaseUrlOptions = {\n /** Hosts (no scheme) used when no gateway endpoints have been resolved, e.g. a feed's own list. */\n fallbackHosts?: readonly string[]\n}\n\nfunction pushUnique(out: string[], seen: Set<string>, url: string): void {\n const u = url.trim().replace(/\\/$/, '')\n if (!u || seen.has(u)) return\n seen.add(u)\n out.push(u)\n}\n\n/**\n * Resolved / public read gateways as base URLs (scheme + host + any path prefix), without the\n * preferred ones. Does not probe.\n */\nexport function getResolvedArweaveReadBaseUrls(options?: ArweaveReadBaseUrlOptions): string[] {\n const resolved = getResolvedSeedGatewayEndpoints()\n const protocol = BaseArweaveClient.getProtocol()\n const hosts = resolved\n ? getReadGatewayHostsForConfig(resolved)\n : options?.fallbackHosts?.length\n ? [...options.fallbackHosts]\n : getArweaveReadGatewayHostsForPrimary(BaseArweaveClient.getHost())\n\n const out: string[] = []\n const seen = new Set<string>()\n for (const host of hosts) {\n const h = host.trim()\n if (!h) continue\n pushUnique(out, seen, /^https?:\\/\\//i.test(h) ? h : `${protocol}://${h}`)\n }\n return out\n}\n\n/**\n * Ordered base URLs for `/raw/{id}` (and `/{id}`) reads: preferred gateways\n * ({@link setPreferredArweaveReadBaseUrls}) first, then the resolved / public gateways. Does not probe.\n */\nexport function getArweaveReadBaseUrls(options?: ArweaveReadBaseUrlOptions): string[] {\n const out: string[] = []\n const seen = new Set<string>()\n for (const url of getPreferredArweaveReadBaseUrls()) pushUnique(out, seen, url)\n for (const url of getResolvedArweaveReadBaseUrls(options)) pushUnique(out, seen, url)\n return out\n}\n\n/** Run the read-gateway probe unless a sidecar / proxy is already the active path. Never throws. */\nexport async function ensureArweaveReadGatewayForFallback(): Promise<void> {\n try {\n const resolved = getResolvedSeedGatewayEndpoints()\n if (resolved && (resolved.activePath === 'hyper-sidecar' || resolved.activePath === 'http-proxy')) {\n return\n }\n await ensureReadGatewaySelected()\n } catch {\n /* optional — fall through to the current host */\n }\n}\n\n/** GET `{baseUrl}/raw/{id}`; `undefined` on network error, timeout or non-2xx. */\nexport async function fetchArweaveRawFromBaseUrl(\n baseUrl: string,\n transactionId: string,\n options?: { timeoutMs?: number },\n): Promise<Response | undefined> {\n const controller = new AbortController()\n const timer = setTimeout(\n () => controller.abort(),\n options?.timeoutMs ?? DEFAULT_ARWEAVE_RAW_READ_TIMEOUT_MS,\n )\n try {\n const res = await fetch(`${baseUrl.replace(/\\/$/, '')}/raw/${encodeURIComponent(transactionId)}`, {\n method: 'GET',\n credentials: 'omit',\n signal: controller.signal,\n })\n return res.ok ? res : undefined\n } catch {\n return undefined\n } finally {\n clearTimeout(timer)\n }\n}\n\n/**\n * GET `/raw/{id}` across read gateways and return the first non-empty body as text. Preferred\n * gateways go first and are tried before any read-gateway probe; a just-published item is served\n * by the gateway it was uploaded through well before it reaches L1 or the public hosts.\n * The body goes through `transformArweaveContent` (see `content/arweaveContent.ts`).\n */\nexport async function fetchArweaveRawTextAcrossGateways(\n transactionId: string,\n options?: ArweaveReadBaseUrlOptions & { timeoutMs?: number },\n): Promise<string | undefined> {\n const tried = new Set<string>()\n const tryUrls = async (urls: string[]): Promise<string | undefined> => {\n for (const base of urls) {\n if (tried.has(base)) continue\n tried.add(base)\n const res = await fetchArweaveRawFromBaseUrl(base, transactionId, options)\n if (!res) continue\n try {\n const { bytes } = await readArweaveContentResponse(res, { transactionId })\n const text = new TextDecoder().decode(bytes)\n if (text.length > 0) return text\n } catch {\n /* body read failed — next gateway */\n }\n }\n return undefined\n }\n\n const preferred = await tryUrls(getPreferredArweaveReadBaseUrls())\n if (preferred) return preferred\n\n await ensureArweaveReadGatewayForFallback()\n return tryUrls(getResolvedArweaveReadBaseUrls(options))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["trimOrEmpty","g","mergePrimaryHostWithDefaults","isKnownArweaveGatewayHostname","DEFAULT_GATEWAY_SIDECAR_PORT","assertSingleArweaveModule","getArweaveReadGatewayHostsForPrimary","hasArweaveContentReadTransform","transformArweaveContent","ARWEAVE_HOST_ENV_KEYS","DEFAULT_GATEWAY_SIDECAR_HOST","DEFAULT_ARWEAVE_HOST","DuplicateArweaveModuleError","readArweaveContentResponse","DEFAULT_ARWEAVE_GRAPHQL_URL","GET_TRANSACTION_TAGS","resetArweaveClientOwnerForTests","DEFAULT_ARWEAVE_GATEWAYS","BaseArweaveClient","getResponseMediaType","GET_ARWEAVE_TRANSACTIONS","setArweaveContentReadTransform","DEFAULT_SEED_FEED_HYPER_KEY","resolveArweaveHostFromEnv","getDefaultArweaveReadGatewayHostsOrdered","DEFAULT_SEED_GATEWAY_HYPER_KEY","EAS_ATTESTATION_EXPLORER_HOST","isEasAttestationExplorerUrl","trimmed","url","parsed","parseLocalIdOrUid","id","localIdOrUid","normalizeRelationPropertyValue","value","o","LOCAL_SEED_REF","resolveSeedIdsFromRefString","fromCorrect","s","ARWEAVE_TX_ID","trimOrEmpty$1","raw","coalesceStringField","v","item","key","unwrapRelationString","fromObj","classifyMediaRef","treatAs","options","unwrapped","ids","getFeedItemStringField","direct","snake","l","alt","parts","alt2","p","normalizeFeedItemFields","out","fieldKey","descriptor","manifest","classification","getArweaveUrlForTransaction","transactionId","SEED_RSS_IMAGE_RELATION_FIELD_KEYS","trimOrEmpty","readObjectStringField","keys","obj","suffixes","rawKey","rawValue","normalizedLower","suffix","tryGatewayUrlForTxId","txId","resolveMediaUrlFromParts","fromTx","arweaveUrl","resolveFromString","mediaUrl","resolveFromObject","storageTransactionId","seedUid","link","resolveSeedRssImageRelationRef","entry","resolved","resolveSeedRssImageRelationFromItem","fieldKeys","TRANSACTION_TAGS_BATCH_SIZE","GET_TRANSACTIONS_TAGS_BY_IDS","getTransactionTagsByIds","transactionIds","client","batchSize","i","batch","result","edge","node","tag","error","DEFAULT_FAILURE_THRESHOLD","DEFAULT_OPEN_MS","failureThreshold","openDurationMs","circuits","normalizeGatewayHostKey","hostOrUrl","getOrCreate","c","resolveState","now","configureGatewayCircuitBreaker","resetGatewayCircuitBreakerForTests","isGatewayHostCircuitOpen","state","getGatewayHostCircuitState","beginGatewayHostHalfOpenProbe","recordGatewayHostSuccess","recordGatewayHostFailure","listOpenGatewayCircuitHosts","READ_GATEWAY_CACHE_TTL_MS","READ_GATEWAY_UNHEALTHY_CACHE_TTL_MS","PROBE_TIMEOUT_MS","readGatewayCache","ensureInFlight","lastHealthyReadGatewayHost","invalidateReadGatewayCache","resetArweaveReadGatewayForTests","isReadGatewayKnownHealthy","getLastHealthyReadGatewayHost","probeGateway","baseUrl","hostKey","timer","controller","effectiveSignal","signal","response","text","json","ok","selectFirstHealthyReadGateway","host","hosts","h","protocol","buildOrderedHostsForProbe","ensureReadGatewaySelected","picked","fallback","normalizeUploadApiBaseUrl","getUploadApiArweaveDataUrl","txOrDataItemId","DEFAULT_UPLOAD_STATUS_TIMEOUT_MS","getUploadPipelineTransactionStatus","uploadApiBaseUrl","timeoutMs","timeoutId","err","GATEWAY_TX_QUERY","getUploadApiArweaveStatusUrl","dataItemId","isArweaveL1AnchoringComplete","l1","status","getArweaveUploadStatus","body","queryArweaveGatewayTransaction","graphqlUrl","init","tx","queryArweaveGatewayTransactionWithFallback","defaults","preferredHost","u","ordered","PROBE_TTL_MS","sidecarProbeCache","proxyProbeCache","invalidateSidecarProbeCache","parseGatewayHost","input","sidecarOrigin","config","port","browserOrigin","origin","resolveProxyBaseUrl","proxyBaseUrl","probeUrlHealthy","cacheKey","healthy","cached","buildHttpEndpoints","buildHyperEndpoints","sidecar","buildProxyEndpoints","absoluteProxyBaseUrl","path","hostWithPath","tryProxyEndpoints","absolute","resolveSeedGatewayEndpoints","mode","shouldProbe","proxy","hyperEndpoints","getReadGatewayHostsForConfig","resolvedGatewayEndpoints","getResolvedSeedGatewayEndpoints","setResolvedSeedGatewayEndpoints","preferredReadBaseUrls","getPreferredArweaveReadBaseUrls","setPreferredArweaveReadBaseUrls","seen","urls","seedGatewayConfigFromSeedConfig","gateway","seedGatewayConfigFromClientContext","context","DEFAULT_ARWEAVE_RAW_READ_TIMEOUT_MS","pushUnique","getResolvedArweaveReadBaseUrls","getArweaveReadBaseUrls","ensureArweaveReadGatewayForFallback","fetchArweaveRawFromBaseUrl","res","fetchArweaveRawTextAcrossGateways","tried","tryUrls","base","bytes"],"sources":["../src/easAttestationUrl.ts","../src/relationSeedRef.ts","../src/mediaRef.ts","../src/resolveSeedRssImageRelationRef.ts","../src/ArweaveClient/transactionTagsByIds.ts","../src/gateway/gatewayCircuitBreaker.ts","../src/ArweaveClient/selectReadGateway.ts","../src/ArweaveClient/uploadApiVerification.ts","../src/ArweaveClient/arweaveL1UploadApi.ts","../src/gateway/resolveSeedGatewayEndpoints.ts","../src/gateway/gatewayState.ts","../src/gateway/seedGatewayConfig.ts","../src/gateway/readBaseUrls.ts"],"sourcesContent":["const EAS_ATTESTATION_EXPLORER_HOST = /(^|\\.)easscan\\.(org|xyz)$/i\n\n/**\n * True when `url` points at an EAS attestation explorer HTML page (not fetchable media).\n */\nexport function isEasAttestationExplorerUrl(url: string): boolean {\n const trimmed = url.trim()\n if (!trimmed) return false\n try {\n const parsed = new URL(trimmed)\n if (!EAS_ATTESTATION_EXPLORER_HOST.test(parsed.hostname)) {\n return false\n }\n return /\\/attestation\\/view\\//i.test(parsed.pathname)\n } catch {\n return false\n }\n}\n","/** Same rules as getCorrectId in helpers/index (avoid barrel circular import). */\nfunction parseLocalIdOrUid(localIdOrUid: string): { localId?: string; uid?: string } {\n const id = { localId: undefined as string | undefined, uid: undefined as string | undefined }\n if (!localIdOrUid) return id\n if (localIdOrUid.length === 10) {\n id.localId = localIdOrUid\n }\n if (localIdOrUid.startsWith('0x') && localIdOrUid.length === 66) {\n id.uid = localIdOrUid\n }\n return id\n}\n\nexport function normalizeRelationPropertyValue(value: unknown): string | undefined {\n if (value == null) return undefined\n if (typeof value === 'string') {\n const t = value.trim()\n return t !== '' ? t : undefined\n }\n if (typeof value === 'object' && value !== null) {\n const o = value as { seedLocalId?: string; seedUid?: string }\n if (typeof o.seedLocalId === 'string' && o.seedLocalId.trim() !== '') {\n return o.seedLocalId.trim()\n }\n if (typeof o.seedUid === 'string' && o.seedUid.trim() !== '') {\n return o.seedUid.trim()\n }\n }\n return undefined\n}\n\nconst LOCAL_SEED_REF = /^[a-zA-Z0-9_-]{10,21}$/\n\nexport function resolveSeedIdsFromRefString(s: string): {\n seedLocalId?: string\n seedUid?: string\n} {\n const fromCorrect = parseLocalIdOrUid(s)\n if (fromCorrect.localId || fromCorrect.uid) {\n return { seedLocalId: fromCorrect.localId, seedUid: fromCorrect.uid }\n }\n if (LOCAL_SEED_REF.test(s) && !s.startsWith('0x')) {\n return { seedLocalId: s }\n }\n return {}\n}\n","import { BaseArweaveClient } from './ArweaveClient/BaseArweaveClient.js'\nimport { isEasAttestationExplorerUrl } from './easAttestationUrl.js'\nimport {\n normalizeRelationPropertyValue,\n resolveSeedIdsFromRefString,\n} from './relationSeedRef.js'\n\nexport type FeedFieldRole = 'image' | 'audio' | 'video' | 'file' | 'html' | 'text'\n\nexport type FeedFieldDescriptor = {\n role: FeedFieldRole\n treatAs?: 'arweaveTx' | 'seedUid' | 'url'\n}\n\nexport type FeedFieldManifest = Record<string, FeedFieldDescriptor>\n\nexport type ClassifyMediaRefOptions = {\n treatAs?: FeedFieldDescriptor['treatAs']\n}\n\nexport type MediaRefClassification =\n | { kind: 'empty' }\n | { kind: 'url'; href: string }\n | { kind: 'nonMediaUrl'; href: string }\n | { kind: 'seedUid'; uid: string }\n | { kind: 'seedLocalId'; localId: string }\n | { kind: 'arweaveTxId'; txId: string }\n | { kind: 'unknown'; raw: string }\n\nexport type ResolveMediaRefResult =\n | { status: 'ready'; href: string; source: 'direct' | 'gateway' | 'localBlob' }\n | { status: 'empty' }\n | {\n status: 'unresolved'\n reason: string\n classification: MediaRefClassification\n }\n\nexport type ResolveMediaRefOptions = ClassifyMediaRefOptions\n\nconst ARWEAVE_TX_ID = /^[a-zA-Z0-9_-]{43}$/\n\nfunction trimOrEmpty(raw: string | undefined | null): string {\n if (raw == null) return ''\n return typeof raw === 'string' ? raw.trim() : String(raw).trim()\n}\n\nfunction coalesceStringField(item: Record<string, unknown>, key: string): string {\n const v = item[key]\n if (v == null) return ''\n if (typeof v === 'string') return v.trim()\n if (typeof v === 'number' || typeof v === 'boolean') return String(v)\n return ''\n}\n\nfunction unwrapRelationString(raw: string): string {\n const t = raw.trim()\n if (!t) return t\n try {\n const parsed = JSON.parse(t) as unknown\n const fromObj = normalizeRelationPropertyValue(parsed)\n if (fromObj) return fromObj\n } catch {\n // not JSON\n }\n return t\n}\n\nexport function classifyMediaRef(\n raw: string,\n options?: ClassifyMediaRefOptions,\n): MediaRefClassification {\n const s = trimOrEmpty(raw)\n if (!s) {\n return { kind: 'empty' }\n }\n\n const treatAs = options?.treatAs\n if (treatAs === 'url') {\n return { kind: 'url', href: s }\n }\n if (treatAs === 'arweaveTx') {\n return { kind: 'arweaveTxId', txId: s }\n }\n if (treatAs === 'seedUid') {\n if (s.startsWith('0x') && s.length === 66) {\n return { kind: 'seedUid', uid: s }\n }\n return { kind: 'unknown', raw: s }\n }\n\n if (\n s.startsWith('http://') ||\n s.startsWith('https://') ||\n s.startsWith('blob:') ||\n s.startsWith('data:')\n ) {\n if (isEasAttestationExplorerUrl(s)) {\n return { kind: 'nonMediaUrl', href: s }\n }\n return { kind: 'url', href: s }\n }\n\n const unwrapped = unwrapRelationString(s)\n const ids = resolveSeedIdsFromRefString(unwrapped)\n if (ids.seedUid) {\n return { kind: 'seedUid', uid: ids.seedUid }\n }\n if (ids.seedLocalId) {\n return { kind: 'seedLocalId', localId: ids.seedLocalId }\n }\n\n if (unwrapped.startsWith('0x') && unwrapped.length === 66) {\n return { kind: 'seedUid', uid: unwrapped }\n }\n\n if (ARWEAVE_TX_ID.test(unwrapped) && !unwrapped.startsWith('0x')) {\n return { kind: 'arweaveTxId', txId: unwrapped }\n }\n\n return { kind: 'unknown', raw: s }\n}\n\nexport type NormalizedMediaField = {\n role: 'image' | 'audio' | 'video' | 'file'\n raw: string\n classification: MediaRefClassification\n}\n\nexport type NormalizedHtmlField = {\n role: 'html'\n raw: string\n}\n\nexport type NormalizedTextField = {\n role: 'text'\n raw: string\n}\n\nexport type NormalizedFeedFieldValue =\n | NormalizedMediaField\n | NormalizedHtmlField\n | NormalizedTextField\n\nexport function getFeedItemStringField(item: Record<string, unknown>, key: string): string {\n const direct = coalesceStringField(item, key)\n if (direct) return direct\n const snake = key.replace(/[A-Z]/g, (l) => `_${l.toLowerCase()}`)\n if (snake !== key) {\n const alt = coalesceStringField(item, snake)\n if (alt) return alt\n }\n const parts = key.split('_')\n if (parts.length > 1) {\n const camel =\n parts[0] + parts.slice(1).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join('')\n const alt2 = coalesceStringField(item, camel)\n if (alt2) return alt2\n }\n return ''\n}\n\nexport function normalizeFeedItemFields(\n item: Record<string, unknown>,\n manifest: FeedFieldManifest,\n): Record<string, NormalizedFeedFieldValue | undefined> {\n const out: Record<string, NormalizedFeedFieldValue | undefined> = {}\n for (const [fieldKey, descriptor] of Object.entries(manifest)) {\n const raw = getFeedItemStringField(item, fieldKey)\n if (!raw) {\n out[fieldKey] = undefined\n continue\n }\n if (descriptor.role === 'html') {\n out[fieldKey] = { role: 'html', raw }\n continue\n }\n if (descriptor.role === 'text') {\n out[fieldKey] = { role: 'text', raw }\n continue\n }\n const classification = classifyMediaRef(raw, { treatAs: descriptor.treatAs })\n out[fieldKey] = {\n role: descriptor.role,\n raw,\n classification,\n }\n }\n return out\n}\n\nexport function getArweaveUrlForTransaction(transactionId: string): string {\n return `${BaseArweaveClient.getBaseUrl()}/${transactionId}`\n}\n","import { BaseArweaveClient } from './ArweaveClient/BaseArweaveClient.js'\nimport { isEasAttestationExplorerUrl } from './easAttestationUrl.js'\nimport { classifyMediaRef } from './mediaRef.js'\n\nexport type SeedRssImageRelationRef = {\n storageTransactionId?: string\n arweaveUrl?: string\n seedUid?: string\n /** Gateway/raw URL suitable for image fetch; never an EAS attestation explorer page. */\n mediaUrl?: string\n}\n\nexport const SEED_RSS_IMAGE_RELATION_FIELD_KEYS = [\n 'featureImage',\n 'feature_image',\n 'image',\n 'images',\n 'coverImage',\n 'cover_image',\n 'thumbnail',\n 'thumbnail_image',\n 'thumbnailImage',\n] as const\n\nfunction trimOrEmpty(value: unknown): string {\n if (value == null) return ''\n if (typeof value === 'string') return value.trim()\n if (typeof value === 'number' || typeof value === 'boolean') return String(value)\n return ''\n}\n\nfunction readObjectStringField(obj: Record<string, unknown>, ...keys: string[]): string {\n for (const key of keys) {\n const direct = trimOrEmpty(obj[key])\n if (direct) return direct\n }\n\n const suffixes = keys.map((key) => key.split(':').pop()!.toLowerCase())\n for (const [rawKey, rawValue] of Object.entries(obj)) {\n const normalizedKey = rawKey.includes(':') ? rawKey.split(':').pop()! : rawKey\n const normalizedLower = normalizedKey.toLowerCase()\n if (suffixes.some((suffix) => normalizedLower === suffix.toLowerCase())) {\n const value = trimOrEmpty(rawValue)\n if (value) return value\n }\n }\n\n return ''\n}\n\nfunction tryGatewayUrlForTxId(txId: string): string | undefined {\n const trimmed = txId.trim()\n if (!trimmed || trimmed.startsWith('0x')) return undefined\n try {\n return `${BaseArweaveClient.getBaseUrl()}/${trimmed}`\n } catch {\n return undefined\n }\n}\n\nfunction resolveMediaUrlFromParts(parts: {\n storageTransactionId?: string\n arweaveUrl?: string\n}): string | undefined {\n const txId = parts.storageTransactionId?.trim()\n if (txId) {\n const fromTx = tryGatewayUrlForTxId(txId)\n if (fromTx) return fromTx\n }\n\n const arweaveUrl = parts.arweaveUrl?.trim()\n if (arweaveUrl && !isEasAttestationExplorerUrl(arweaveUrl)) {\n return arweaveUrl\n }\n\n return undefined\n}\n\nfunction resolveFromString(value: string): SeedRssImageRelationRef | undefined {\n const trimmed = value.trim()\n if (!trimmed) return undefined\n\n if (isEasAttestationExplorerUrl(trimmed)) {\n return undefined\n }\n\n const classification = classifyMediaRef(trimmed)\n switch (classification.kind) {\n case 'url':\n return { mediaUrl: classification.href }\n case 'arweaveTxId': {\n const mediaUrl = tryGatewayUrlForTxId(classification.txId)\n return {\n storageTransactionId: classification.txId,\n ...(mediaUrl ? { mediaUrl } : {}),\n }\n }\n case 'seedUid':\n return { seedUid: classification.uid }\n default: {\n const mediaUrl = tryGatewayUrlForTxId(trimmed)\n if (mediaUrl) {\n return {\n storageTransactionId: trimmed,\n mediaUrl,\n }\n }\n return undefined\n }\n }\n}\n\nfunction resolveFromObject(obj: Record<string, unknown>): SeedRssImageRelationRef | undefined {\n const storageTransactionId = readObjectStringField(\n obj,\n 'storageTransactionId',\n 'storage_transaction_id',\n )\n const arweaveUrl = readObjectStringField(obj, 'arweaveUrl', 'arweave_url')\n const seedUid = readObjectStringField(obj, 'seedUid', 'SeedUid', 'seed_uid')\n const link = readObjectStringField(obj, 'link', 'Link')\n\n const mediaUrl =\n resolveMediaUrlFromParts({ storageTransactionId, arweaveUrl }) ??\n (link && !isEasAttestationExplorerUrl(link) ? link : undefined)\n\n if (!storageTransactionId && !arweaveUrl && !seedUid && !mediaUrl) {\n return undefined\n }\n\n return {\n ...(storageTransactionId ? { storageTransactionId } : {}),\n ...(arweaveUrl && !isEasAttestationExplorerUrl(arweaveUrl) ? { arweaveUrl } : {}),\n ...(seedUid ? { seedUid } : {}),\n ...(mediaUrl ? { mediaUrl } : {}),\n }\n}\n\n/**\n * Resolve a Seed RSS image relation value (plain string or expanded relation object)\n * using field priority: storageTransactionId → arweaveUrl/gateway URL → seedUid.\n * EAS attestation explorer URLs are never returned as media.\n */\nexport function resolveSeedRssImageRelationRef(value: unknown): SeedRssImageRelationRef | undefined {\n if (value == null) return undefined\n\n if (typeof value === 'string') {\n return resolveFromString(value)\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n const resolved = resolveSeedRssImageRelationRef(entry)\n if (resolved?.mediaUrl || resolved?.storageTransactionId || resolved?.seedUid) {\n return resolved\n }\n }\n return undefined\n }\n\n if (typeof value === 'object') {\n return resolveFromObject(value as Record<string, unknown>)\n }\n\n return undefined\n}\n\n/**\n * Read the first configured image-relation field from a parsed RSS item record.\n */\nexport function resolveSeedRssImageRelationFromItem(\n item: Record<string, unknown>,\n fieldKeys: readonly string[] = SEED_RSS_IMAGE_RELATION_FIELD_KEYS,\n): SeedRssImageRelationRef | undefined {\n for (const key of fieldKeys) {\n if (!(key in item)) continue\n const resolved = resolveSeedRssImageRelationRef(item[key])\n if (resolved) return resolved\n }\n return undefined\n}\n","import type { GraphQLClient } from 'graphql-request'\nimport { BaseArweaveClient } from './BaseArweaveClient.js'\nimport type { TransactionTag } from '../types/arweave.js'\n\n/** Arweave GraphQL serves at most 100 transactions per page. */\nexport const TRANSACTION_TAGS_BATCH_SIZE = 100\n\n/**\n * Plain string, not a codegen document: the `graphql()` helper from the client preset only knows\n * documents present when codegen last ran.\n */\nexport const GET_TRANSACTIONS_TAGS_BY_IDS = /* GraphQL */ `\n query GetTransactionsTagsByIds($ids: [ID!], $first: Int) {\n transactions(ids: $ids, first: $first) {\n edges {\n node {\n id\n tags {\n name\n value\n }\n }\n }\n }\n }\n`\n\ntype TransactionsTagsByIdsResult = {\n transactions?: {\n edges?: Array<{ node?: { id?: string; tags?: TransactionTag[] | null } | null } | null> | null\n } | null\n}\n\n/**\n * Tags of many transactions in batched GraphQL requests (`transactions(ids: [...])`), keyed by id.\n * A transaction the gateway does not know yet (e.g. just published, not indexed) is absent from\n * the map; a failed batch is skipped (logged through `onError`) rather than failing the caller.\n */\nexport async function getTransactionTagsByIds(\n transactionIds: readonly string[],\n options?: { client?: GraphQLClient; batchSize?: number; onError?: (error: unknown) => void },\n): Promise<Map<string, TransactionTag[]>> {\n const out = new Map<string, TransactionTag[]>()\n const ids = Array.from(new Set(transactionIds.filter((id) => typeof id === 'string' && id.trim())))\n if (ids.length === 0) return out\n\n const client = options?.client ?? BaseArweaveClient.getArweaveClient()\n const batchSize = Math.max(1, Math.min(options?.batchSize ?? TRANSACTION_TAGS_BATCH_SIZE, TRANSACTION_TAGS_BATCH_SIZE))\n\n for (let i = 0; i < ids.length; i += batchSize) {\n const batch = ids.slice(i, i + batchSize)\n try {\n const result = await client.request<TransactionsTagsByIdsResult>(GET_TRANSACTIONS_TAGS_BY_IDS, {\n ids: batch,\n first: batch.length,\n })\n for (const edge of result?.transactions?.edges ?? []) {\n const node = edge?.node\n if (!node?.id) continue\n out.set(\n node.id,\n (node.tags ?? []).map((tag) => ({ name: tag.name, value: tag.value })),\n )\n }\n } catch (error) {\n options?.onError?.(error)\n }\n }\n return out\n}\n","/**\n * Process-wide circuit breaker for Arweave gateway hosts.\n *\n * After consecutive failures, a host is \"open\" for a cooldown and skipped by\n * probes / metadata fetches. After the cooldown it becomes half-open (one probe\n * allowed). Success closes the circuit.\n */\n\nexport type GatewayCircuitState = 'closed' | 'open' | 'half-open'\n\ntype HostCircuit = {\n failures: number\n openedAt: number | null\n /** When half-open, only one probe may run at a time. */\n halfOpenProbeInFlight: boolean\n}\n\nconst DEFAULT_FAILURE_THRESHOLD = 1\nconst DEFAULT_OPEN_MS = 60_000\n\nlet failureThreshold = DEFAULT_FAILURE_THRESHOLD\nlet openDurationMs = DEFAULT_OPEN_MS\nconst circuits = new Map<string, HostCircuit>()\n\n/** Strip scheme / trailing slash; lowercase host (+ optional port/path). */\nexport function normalizeGatewayHostKey(hostOrUrl: string): string {\n let t = hostOrUrl.trim()\n if (!t) return ''\n if (t.startsWith('http://')) t = t.slice(7)\n else if (t.startsWith('https://')) t = t.slice(8)\n return t.replace(/\\/$/, '').toLowerCase()\n}\n\nfunction getOrCreate(key: string): HostCircuit {\n let c = circuits.get(key)\n if (!c) {\n c = { failures: 0, openedAt: null, halfOpenProbeInFlight: false }\n circuits.set(key, c)\n }\n return c\n}\n\nfunction resolveState(c: HostCircuit, now: number): GatewayCircuitState {\n if (c.openedAt == null) return 'closed'\n if (now - c.openedAt >= openDurationMs) return 'half-open'\n return 'open'\n}\n\n/**\n * Configure failure threshold and open-state duration (mainly for tests).\n */\nexport function configureGatewayCircuitBreaker(options: {\n failureThreshold?: number\n openDurationMs?: number\n}): void {\n if (options.failureThreshold != null && options.failureThreshold >= 1) {\n failureThreshold = options.failureThreshold\n }\n if (options.openDurationMs != null && options.openDurationMs >= 0) {\n openDurationMs = options.openDurationMs\n }\n}\n\n/** Clears all host circuits and restores default thresholds (for tests). */\nexport function resetGatewayCircuitBreakerForTests(): void {\n circuits.clear()\n failureThreshold = DEFAULT_FAILURE_THRESHOLD\n openDurationMs = DEFAULT_OPEN_MS\n}\n\n/**\n * True when the host should not receive new requests (open), or a half-open\n * probe is already in flight.\n */\nexport function isGatewayHostCircuitOpen(hostOrUrl: string, now = Date.now()): boolean {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return false\n const c = circuits.get(key)\n if (!c) return false\n const state = resolveState(c, now)\n if (state === 'open') return true\n if (state === 'half-open' && c.halfOpenProbeInFlight) return true\n return false\n}\n\nexport function getGatewayHostCircuitState(\n hostOrUrl: string,\n now = Date.now(),\n): GatewayCircuitState {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return 'closed'\n const c = circuits.get(key)\n if (!c) return 'closed'\n return resolveState(c, now)\n}\n\n/**\n * Mark that a probe/request is starting against a half-open host so concurrent\n * callers skip it. No-op when closed or fully open.\n */\nexport function beginGatewayHostHalfOpenProbe(hostOrUrl: string, now = Date.now()): void {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return\n const c = getOrCreate(key)\n if (resolveState(c, now) === 'half-open') {\n c.halfOpenProbeInFlight = true\n }\n}\n\nexport function recordGatewayHostSuccess(hostOrUrl: string): void {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return\n circuits.set(key, { failures: 0, openedAt: null, halfOpenProbeInFlight: false })\n}\n\nexport function recordGatewayHostFailure(hostOrUrl: string, now = Date.now()): void {\n const key = normalizeGatewayHostKey(hostOrUrl)\n if (!key) return\n const c = getOrCreate(key)\n c.failures += 1\n c.halfOpenProbeInFlight = false\n if (c.failures >= failureThreshold) {\n c.openedAt = now\n }\n}\n\n/** Hosts currently in open (or half-open with in-flight) state. */\nexport function listOpenGatewayCircuitHosts(now = Date.now()): string[] {\n const out: string[] = []\n for (const key of circuits.keys()) {\n if (isGatewayHostCircuitOpen(key, now)) out.push(key)\n }\n return out\n}\n","import { BaseArweaveClient } from './BaseArweaveClient.js'\nimport {\n DEFAULT_ARWEAVE_HOST,\n getArweaveReadGatewayHostsForPrimary,\n} from '../constants.js'\nimport {\n beginGatewayHostHalfOpenProbe,\n isGatewayHostCircuitOpen,\n recordGatewayHostFailure,\n recordGatewayHostSuccess,\n resetGatewayCircuitBreakerForTests,\n} from '../gateway/gatewayCircuitBreaker.js'\n\nconst READ_GATEWAY_CACHE_TTL_MS = 3 * 60 * 1000\n/** Shorter TTL when no gateway passed the probe — avoid hammering while still recovering sooner. */\nconst READ_GATEWAY_UNHEALTHY_CACHE_TTL_MS = 60 * 1000\nconst PROBE_TIMEOUT_MS = 5000\n\ntype ReadGatewayCache = {\n host: string\n /** False when the last probe found no healthy gateway. */\n healthy: boolean\n expiresAt: number\n}\n\nlet readGatewayCache: ReadGatewayCache | null = null\nlet ensureInFlight: Promise<string> | null = null\n/** Last host that successfully passed /info (survives an all-fail probe cycle). */\nlet lastHealthyReadGatewayHost: string | null = null\n\n/** Clears cached read gateway (e.g. after tests or to force a fresh probe). */\nexport function invalidateReadGatewayCache(): void {\n readGatewayCache = null\n ensureInFlight = null\n}\n\n/** Clears probe cache, env override suppression, and preferred host (for tests). */\nexport function resetArweaveReadGatewayForTests(): void {\n invalidateReadGatewayCache()\n lastHealthyReadGatewayHost = null\n resetGatewayCircuitBreakerForTests()\n BaseArweaveClient.resetReadGatewaySelectionStateForTests()\n if (!BaseArweaveClient.isReadGatewayLocked()) {\n BaseArweaveClient.setPreferredReadGateway(DEFAULT_ARWEAVE_HOST)\n }\n}\n\n/**\n * True when the last {@link ensureReadGatewaySelected} probe found a healthy host\n * (or the cache still says so). False after an all-fail probe until the next success.\n */\nexport function isReadGatewayKnownHealthy(): boolean {\n if (BaseArweaveClient.isReadGatewayLocked()) return true\n if (readGatewayCache && Date.now() < readGatewayCache.expiresAt) {\n return readGatewayCache.healthy\n }\n return lastHealthyReadGatewayHost != null\n}\n\n/** Last gateway host that passed /info, if any. */\nexport function getLastHealthyReadGatewayHost(): string | null {\n return lastHealthyReadGatewayHost\n}\n\n/**\n * GET /info with timeout. Treat 2xx + JSON object as healthy.\n * Records circuit-breaker success/failure for the host.\n */\nexport async function probeGateway(baseUrl: string, signal?: AbortSignal): Promise<boolean> {\n const url = `${baseUrl.replace(/\\/$/, '')}/info`\n let hostKey = baseUrl\n try {\n hostKey = new URL(baseUrl.includes('://') ? baseUrl : `https://${baseUrl}`).host\n } catch {\n hostKey = baseUrl.replace(/^https?:\\/\\//, '').replace(/\\/$/, '')\n }\n\n if (isGatewayHostCircuitOpen(hostKey)) {\n return false\n }\n beginGatewayHostHalfOpenProbe(hostKey)\n\n let timer: ReturnType<typeof setTimeout> | undefined\n const controller = new AbortController()\n const effectiveSignal = signal ?? controller.signal\n if (!signal) {\n timer = setTimeout(() => controller.abort(), PROBE_TIMEOUT_MS)\n }\n try {\n const response = await fetch(url, {\n method: 'GET',\n signal: effectiveSignal,\n headers: { Accept: 'application/json' },\n })\n if (!response.ok) {\n recordGatewayHostFailure(hostKey)\n return false\n }\n const text = await response.text()\n if (!text.trim()) {\n recordGatewayHostFailure(hostKey)\n return false\n }\n try {\n const json = JSON.parse(text) as unknown\n const ok = typeof json === 'object' && json !== null\n if (ok) recordGatewayHostSuccess(hostKey)\n else recordGatewayHostFailure(hostKey)\n return ok\n } catch {\n recordGatewayHostFailure(hostKey)\n return false\n }\n } catch {\n recordGatewayHostFailure(hostKey)\n return false\n } finally {\n if (timer) clearTimeout(timer)\n }\n}\n\nexport async function selectFirstHealthyReadGateway(\n hosts: string[],\n protocol: 'http' | 'https' = 'https',\n signal?: AbortSignal,\n): Promise<string | null> {\n for (const host of hosts) {\n const h = host.trim().replace(/\\/$/, '')\n if (!h) continue\n if (isGatewayHostCircuitOpen(h)) continue\n const baseUrl = `${protocol}://${h}`\n if (await probeGateway(baseUrl, signal)) {\n return h\n }\n }\n return null\n}\n\nfunction buildOrderedHostsForProbe(): string[] {\n return getArweaveReadGatewayHostsForPrimary(BaseArweaveClient.getHost())\n}\n\n/**\n * Probes gateways in order and applies the first healthy host via {@link BaseArweaveClient.applyProbedReadGateway}.\n * No-op when the read gateway is locked ({@link BaseArweaveClient.setHost}).\n * Uses a short TTL cache to avoid probing on every read.\n *\n * When every probe fails, keeps the last known healthy host (if any) instead of\n * treating the preferred-but-unreachable host as selected, and caches\n * `healthy: false` so {@link isReadGatewayKnownHealthy} reflects that.\n */\nexport async function ensureReadGatewaySelected(signal?: AbortSignal): Promise<string> {\n if (BaseArweaveClient.isReadGatewayLocked()) {\n return BaseArweaveClient.getHost()\n }\n\n const now = Date.now()\n if (readGatewayCache && now < readGatewayCache.expiresAt) {\n return readGatewayCache.host\n }\n\n if (ensureInFlight) {\n return ensureInFlight\n }\n\n ensureInFlight = (async () => {\n const ordered = buildOrderedHostsForProbe()\n const protocol = BaseArweaveClient.getProtocol()\n const picked = await selectFirstHealthyReadGateway(ordered, protocol, signal)\n\n if (!BaseArweaveClient.isReadGatewayLocked()) {\n if (picked) {\n BaseArweaveClient.applyProbedReadGateway(picked)\n lastHealthyReadGatewayHost = picked\n readGatewayCache = {\n host: picked,\n healthy: true,\n expiresAt: Date.now() + READ_GATEWAY_CACHE_TTL_MS,\n }\n } else {\n const fallback = lastHealthyReadGatewayHost ?? BaseArweaveClient.getHost()\n if (\n lastHealthyReadGatewayHost &&\n BaseArweaveClient.getHost() !== lastHealthyReadGatewayHost\n ) {\n BaseArweaveClient.applyProbedReadGateway(lastHealthyReadGatewayHost)\n }\n readGatewayCache = {\n host: fallback,\n healthy: false,\n expiresAt: Date.now() + READ_GATEWAY_UNHEALTHY_CACHE_TTL_MS,\n }\n }\n } else {\n readGatewayCache = {\n host: BaseArweaveClient.getHost(),\n healthy: true,\n expiresAt: Date.now() + READ_GATEWAY_CACHE_TTL_MS,\n }\n }\n\n return readGatewayCache.host\n })()\n\n try {\n return await ensureInFlight\n } finally {\n ensureInFlight = null\n }\n}\n","import type { TransactionStatus } from '../types/arweave.js'\n\n/**\n * Trim and strip a trailing slash from an upload API base URL.\n */\nexport function normalizeUploadApiBaseUrl(baseUrl: string): string {\n return baseUrl.trim().replace(/\\/+$/, '')\n}\n\n/**\n * URL used to verify that an upload is available via the Seed upload API\n * (`GET` → HTTP 200 when present). Works for L1 transaction ids and ANS-104 data item ids.\n *\n * @param baseUrl - Upload API origin (e.g. from `ARWEAVE_UPLOAD_API_BASE_URL` / `uploadApiBaseUrl`)\n * @param txOrDataItemId - Arweave tx id or bundler data item id\n */\nexport function getUploadApiArweaveDataUrl(baseUrl: string, txOrDataItemId: string): string {\n const base = normalizeUploadApiBaseUrl(baseUrl)\n const id = encodeURIComponent(txOrDataItemId)\n return `${base}/api/upload/arweave/data/${id}`\n}\n\nconst DEFAULT_UPLOAD_STATUS_TIMEOUT_MS = 45_000\n\nexport type GetUploadPipelineTransactionStatusOptions = {\n /** Abort the request after this many ms (upload API hung / unreachable). Default 45s. */\n timeoutMs?: number\n}\n\n/**\n * Presence check against the upload API data route (same semantics as\n * {@link BaseArweaveClient.getTransactionStatus} for gateways: 200 = present, 404 = missing).\n */\nexport async function getUploadPipelineTransactionStatus(\n uploadApiBaseUrl: string,\n txOrDataItemId: string,\n options?: GetUploadPipelineTransactionStatusOptions,\n): Promise<TransactionStatus> {\n const url = getUploadApiArweaveDataUrl(uploadApiBaseUrl, txOrDataItemId)\n const timeoutMs = options?.timeoutMs ?? DEFAULT_UPLOAD_STATUS_TIMEOUT_MS\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs)\n\n try {\n const response = await fetch(url, { signal: controller.signal })\n clearTimeout(timeoutId)\n\n if (response.status === 404) {\n return { status: 404, confirmed: null }\n }\n\n if (!response.ok) {\n return { status: response.status, confirmed: null }\n }\n\n if (response.body) {\n await response.body.cancel()\n }\n\n return { status: 200, confirmed: null }\n } catch (err) {\n clearTimeout(timeoutId)\n if (err instanceof Error && err.name === 'AbortError') {\n return { status: 504, confirmed: null }\n }\n return { status: 500, confirmed: null }\n }\n}\n","import {\n getDefaultArweaveReadGatewayHostsOrdered,\n getArweaveReadGatewayHostsForPrimary,\n} from '../constants.js'\nimport { normalizeUploadApiBaseUrl } from './uploadApiVerification.js'\nimport { probeGateway } from './selectReadGateway.js'\n\n/** Response shape from `GET /api/upload/arweave/status/{dataItemId}`. */\nexport interface ArweaveUploadStatusResponse {\n dataItemId?: string\n phase?: string\n bundleId?: string\n turboStatus?: string\n turboInfo?: string\n winc?: string\n turbo?: {\n status?: string\n bundleId?: string\n info?: string\n winc?: string\n }\n l1?: {\n checked?: boolean\n httpStatus?: number\n confirmed?: boolean\n numberOfConfirmations?: number\n minConfirmationsRequired?: number\n meetsMinConfirmations?: boolean\n }\n}\n\nexport interface ArweaveGatewayTransactionQueryResult {\n /** GraphQL `transaction.id` (often same as data item id for ANS-104 items). */\n transactionId: string | null\n /** L1 bundle transaction id when the item is indexed as bundled. */\n bundledInId: string | null\n blockHeight?: number | null\n blockTimestamp?: number | null\n}\n\nconst GATEWAY_TX_QUERY = `\n query ArweaveGatewayTransaction($id: String!) {\n transaction(id: $id) {\n id\n bundledIn {\n id\n }\n block {\n height\n timestamp\n }\n }\n }\n`\n\nexport function getUploadApiArweaveStatusUrl(baseUrl: string, dataItemId: string): string {\n const base = normalizeUploadApiBaseUrl(baseUrl)\n const id = encodeURIComponent(dataItemId)\n return `${base}/api/upload/arweave/status/${id}`\n}\n\n/**\n * Whether L1 anchoring is complete per upload API status JSON.\n */\nexport function isArweaveL1AnchoringComplete(status: ArweaveUploadStatusResponse): boolean {\n const l1 = status.l1\n if (!l1) return false\n if (l1.meetsMinConfirmations === true) return true\n if (l1.confirmed === true) return true\n return false\n}\n\n/**\n * Fetches JSON from `GET /api/upload/arweave/status/{dataItemId}`.\n * Returns `null` if the response is not OK or body is not JSON.\n */\nexport async function getArweaveUploadStatus(\n uploadApiBaseUrl: string,\n dataItemId: string,\n): Promise<ArweaveUploadStatusResponse | null> {\n const url = getUploadApiArweaveStatusUrl(uploadApiBaseUrl, dataItemId)\n try {\n const response = await fetch(url)\n if (!response.ok) {\n return null\n }\n const body = (await response.json()) as ArweaveUploadStatusResponse\n return body && typeof body === 'object' ? body : null\n } catch {\n return null\n }\n}\n\n/**\n * Queries an Arweave gateway GraphQL API for transaction + bundle info.\n */\nexport async function queryArweaveGatewayTransaction(\n graphqlUrl: string,\n dataItemId: string,\n init?: Pick<RequestInit, 'signal'>,\n): Promise<ArweaveGatewayTransactionQueryResult | null> {\n const url = graphqlUrl.trim()\n if (!url) return null\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n query: GATEWAY_TX_QUERY,\n variables: { id: dataItemId },\n }),\n signal: init?.signal,\n })\n\n if (!response.ok) {\n return null\n }\n\n const json = (await response.json()) as {\n data?: {\n transaction?: {\n id?: string\n bundledIn?: { id?: string } | null\n block?: { height?: number; timestamp?: number } | null\n } | null\n }\n errors?: unknown\n }\n\n if (json.errors) {\n return null\n }\n\n const tx = json.data?.transaction\n if (!tx) {\n return {\n transactionId: null,\n bundledInId: null,\n blockHeight: null,\n blockTimestamp: null,\n }\n }\n\n return {\n transactionId: typeof tx.id === 'string' ? tx.id : null,\n bundledInId: tx.bundledIn?.id != null ? String(tx.bundledIn.id) : null,\n blockHeight: tx.block?.height ?? null,\n blockTimestamp: tx.block?.timestamp ?? null,\n }\n } catch {\n return null\n }\n}\n\n/**\n * Resolves GraphQL against the first healthy gateway (GET /info probe per host), then runs\n * {@link queryArweaveGatewayTransaction}. Host order: optional `graphqlUrl` hostname first, then\n * {@link getDefaultArweaveReadGatewayHostsOrdered}.\n */\nexport async function queryArweaveGatewayTransactionWithFallback(\n graphqlUrl: string | undefined,\n dataItemId: string,\n init?: Pick<RequestInit, 'signal'>,\n): Promise<ArweaveGatewayTransactionQueryResult | null> {\n const defaults = getDefaultArweaveReadGatewayHostsOrdered()\n const trimmed = graphqlUrl?.trim()\n let protocol: 'http' | 'https' = 'https'\n let preferredHost: string | null = null\n if (trimmed) {\n try {\n const u = new URL(trimmed)\n protocol = u.protocol === 'http:' ? 'http' : 'https'\n preferredHost = u.hostname || null\n } catch {\n preferredHost = null\n }\n }\n\n const ordered =\n preferredHost && preferredHost.length > 0\n ? getArweaveReadGatewayHostsForPrimary(preferredHost)\n : [...defaults]\n\n const signal = init?.signal\n for (const host of ordered) {\n const base = `${protocol}://${host}`\n if (!(await probeGateway(base, signal ?? undefined))) continue\n const gqlUrl = `${protocol}://${host}/graphql`\n const result = await queryArweaveGatewayTransaction(gqlUrl, dataItemId, init)\n if (result !== null) {\n return result\n }\n }\n return null\n}\n","import { probeGateway } from '../ArweaveClient/selectReadGateway.js'\nimport {\n DEFAULT_ARWEAVE_HOST,\n DEFAULT_GATEWAY_SIDECAR_HOST,\n DEFAULT_GATEWAY_SIDECAR_PORT,\n getArweaveReadGatewayHostsForPrimary,\n} from '../constants.js'\nimport type {\n ResolvedSeedGatewayEndpoints,\n SeedGatewayConfig,\n SeedGatewayTransportMode,\n} from '../types/gateway.js'\n\nconst PROBE_TTL_MS = 3 * 60 * 1000\n\nlet sidecarProbeCache: { healthy: boolean; expiresAt: number } | null = null\nconst proxyProbeCache = new Map<string, { healthy: boolean; expiresAt: number }>()\n\n/** Clears cached sidecar / proxy probes (tests / forced re-probe). */\nexport function invalidateSidecarProbeCache(): void {\n sidecarProbeCache = null\n proxyProbeCache.clear()\n}\n\nfunction parseGatewayHost(input: string | undefined): { host: string; protocol: 'http' | 'https' } {\n const raw = (input ?? DEFAULT_ARWEAVE_HOST).trim()\n if (raw.startsWith('http://')) {\n return { protocol: 'http', host: raw.slice(7).replace(/\\/$/, '') }\n }\n if (raw.startsWith('https://')) {\n return { protocol: 'https', host: raw.slice(8).replace(/\\/$/, '') }\n }\n return { protocol: 'https', host: raw.replace(/\\/$/, '') }\n}\n\nfunction sidecarOrigin(config: SeedGatewayConfig): {\n host: string\n port: number\n baseUrl: string\n} {\n const host = config.hyper?.localSidecarHost?.trim() || DEFAULT_GATEWAY_SIDECAR_HOST\n const port = config.hyper?.localSidecarPort ?? DEFAULT_GATEWAY_SIDECAR_PORT\n const hostWithPort = port === 80 || port === 443 ? host : `${host}:${port}`\n return {\n host: hostWithPort,\n port,\n baseUrl: `http://${host}:${port}`,\n }\n}\n\nfunction browserOrigin(): string | undefined {\n try {\n const g = globalThis as { window?: { location?: { origin?: string } } }\n const origin = g.window?.location?.origin\n return typeof origin === 'string' && origin.length > 0 ? origin.replace(/\\/$/, '') : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Resolve `proxyBaseUrl` to an absolute origin+path (no trailing slash).\n * Relative paths require a browser `window.location.origin` or {@link ResolveSeedGatewayEndpointsOptions.origin}.\n */\nexport function resolveProxyBaseUrl(\n proxyBaseUrl: string,\n options?: { origin?: string },\n): string {\n const raw = proxyBaseUrl.trim()\n if (!raw) {\n throw new Error('proxyBaseUrl is empty')\n }\n if (raw.startsWith('http://') || raw.startsWith('https://')) {\n return raw.replace(/\\/$/, '')\n }\n if (raw.startsWith('/')) {\n const origin = (options?.origin?.trim() || browserOrigin() || '').replace(/\\/$/, '')\n if (!origin) {\n throw new Error(\n `Relative proxyBaseUrl \"${proxyBaseUrl}\" requires a browser origin or resolve options.origin`,\n )\n }\n return `${origin}${raw.replace(/\\/$/, '')}`\n }\n return `https://${raw.replace(/\\/$/, '')}`\n}\n\nasync function probeUrlHealthy(\n baseUrl: string,\n cacheKey: 'sidecar' | string,\n signal?: AbortSignal,\n): Promise<boolean> {\n const now = Date.now()\n if (cacheKey === 'sidecar') {\n if (sidecarProbeCache && now < sidecarProbeCache.expiresAt) {\n return sidecarProbeCache.healthy\n }\n const healthy = await probeGateway(baseUrl, signal)\n sidecarProbeCache = { healthy, expiresAt: now + PROBE_TTL_MS }\n return healthy\n }\n\n const cached = proxyProbeCache.get(cacheKey)\n if (cached && now < cached.expiresAt) {\n return cached.healthy\n }\n const healthy = await probeGateway(baseUrl, signal)\n proxyProbeCache.set(cacheKey, { healthy, expiresAt: now + PROBE_TTL_MS })\n return healthy\n}\n\nfunction buildHttpEndpoints(config: SeedGatewayConfig): ResolvedSeedGatewayEndpoints {\n const { host, protocol } = parseGatewayHost(config.arweaveDomain)\n const baseUrl = `${protocol}://${host}`\n const uploadApiBaseUrl = config.uploadApiBaseUrl?.trim() || baseUrl\n return {\n mode: config.transport ?? 'http-gateway',\n arweaveHost: host,\n arweaveProtocol: protocol,\n arweaveBaseUrl: baseUrl,\n arweaveGraphqlUrl: `${protocol}://${host}/graphql`,\n uploadApiBaseUrl,\n activePath: 'http',\n gatewayHyperKey: config.hyper?.gatewayHyperKey?.trim() || undefined,\n }\n}\n\nfunction buildHyperEndpoints(config: SeedGatewayConfig): ResolvedSeedGatewayEndpoints {\n const sidecar = sidecarOrigin(config)\n const key = config.hyper?.gatewayHyperKey?.trim()\n return {\n mode: 'hyper',\n arweaveHost: sidecar.host,\n arweaveProtocol: 'http',\n arweaveBaseUrl: sidecar.baseUrl,\n arweaveGraphqlUrl: `${sidecar.baseUrl}/graphql`,\n uploadApiBaseUrl: sidecar.baseUrl,\n activePath: 'hyper-sidecar',\n gatewayHyperKey: key || undefined,\n }\n}\n\nfunction buildProxyEndpoints(\n config: SeedGatewayConfig,\n absoluteProxyBaseUrl: string,\n): ResolvedSeedGatewayEndpoints {\n const parsed = new URL(absoluteProxyBaseUrl)\n const protocol: 'http' | 'https' = parsed.protocol === 'http:' ? 'http' : 'https'\n const path = parsed.pathname.replace(/\\/$/, '')\n const hostWithPath = path ? `${parsed.host}${path}` : parsed.host\n const baseUrl = `${protocol}://${hostWithPath}`\n return {\n mode: config.transport ?? 'http-gateway',\n arweaveHost: hostWithPath,\n arweaveProtocol: protocol,\n arweaveBaseUrl: baseUrl,\n arweaveGraphqlUrl: `${baseUrl}/graphql`,\n uploadApiBaseUrl: baseUrl,\n activePath: 'http-proxy',\n gatewayHyperKey: config.hyper?.gatewayHyperKey?.trim() || undefined,\n proxyBaseUrl: absoluteProxyBaseUrl,\n }\n}\n\nexport type ResolveSeedGatewayEndpointsOptions = {\n signal?: AbortSignal\n /** Skip cache and probe sidecar / proxy again. */\n forceSidecarProbe?: boolean\n /**\n * Origin used to resolve relative `proxyBaseUrl` (e.g. `https://app.example.com`).\n * Defaults to `window.location.origin` in browsers.\n */\n origin?: string\n}\n\nasync function tryProxyEndpoints(\n config: SeedGatewayConfig,\n options?: ResolveSeedGatewayEndpointsOptions,\n): Promise<ResolvedSeedGatewayEndpoints | null> {\n const raw = config.proxyBaseUrl?.trim()\n if (!raw) return null\n\n const absolute = resolveProxyBaseUrl(raw, { origin: options?.origin })\n const shouldProbe = config.hyper?.probeSidecar !== false\n if (shouldProbe) {\n const ok = await probeUrlHealthy(absolute, `proxy:${absolute}`, options?.signal)\n if (!ok) return null\n }\n return buildProxyEndpoints(config, absolute)\n}\n\n/**\n * Resolve effective gateway + upload API URLs for the configured transport mode.\n *\n * Preference when a proxy and/or sidecar may apply:\n * configured + healthy `proxyBaseUrl` → local Hyper sidecar → public HTTP gateway.\n */\nexport async function resolveSeedGatewayEndpoints(\n config: SeedGatewayConfig,\n options?: ResolveSeedGatewayEndpointsOptions,\n): Promise<ResolvedSeedGatewayEndpoints> {\n if (options?.forceSidecarProbe) {\n invalidateSidecarProbeCache()\n }\n\n const mode: SeedGatewayTransportMode = config.transport ?? 'http-gateway'\n const shouldProbe = config.hyper?.probeSidecar !== false\n\n if (mode === 'http-gateway') {\n if (config.proxyBaseUrl?.trim()) {\n const absolute = resolveProxyBaseUrl(config.proxyBaseUrl, { origin: options?.origin })\n if (shouldProbe) {\n const ok = await probeUrlHealthy(absolute, `proxy:${absolute}`, options?.signal)\n if (!ok) {\n throw new Error(\n `Gateway HTTP proxy not reachable at ${absolute}. ` +\n 'Ensure your Node route runs createGatewayProxy (or equivalent) and mounts at proxyBaseUrl.',\n )\n }\n }\n return buildProxyEndpoints({ ...config, transport: mode }, absolute)\n }\n return buildHttpEndpoints({ ...config, transport: mode })\n }\n\n if (mode === 'hyper') {\n const proxy = await tryProxyEndpoints({ ...config, transport: mode }, options)\n if (proxy) return proxy\n\n const hyperEndpoints = buildHyperEndpoints({ ...config, transport: mode })\n if (shouldProbe) {\n const ok = await probeUrlHealthy(hyperEndpoints.arweaveBaseUrl, 'sidecar', options?.signal)\n if (!ok) {\n throw new Error(\n `Gateway Hyper sidecar not reachable at ${hyperEndpoints.arweaveBaseUrl}. ` +\n 'Run: seed-gateway connect <operator-z32-key> — or configure gateway.proxyBaseUrl for an app-server proxy.',\n )\n }\n }\n return hyperEndpoints\n }\n\n // hybrid: proxy → sidecar → public HTTP\n const proxy = await tryProxyEndpoints({ ...config, transport: mode }, options)\n if (proxy) return proxy\n\n const sidecar = sidecarOrigin(config)\n if (shouldProbe && (await probeUrlHealthy(sidecar.baseUrl, 'sidecar', options?.signal))) {\n return buildHyperEndpoints({ ...config, transport: 'hyper' })\n }\n\n const http = buildHttpEndpoints({ ...config, transport: 'http-gateway' })\n return {\n ...http,\n mode: 'hybrid',\n activePath: 'hybrid-fallback-http',\n }\n}\n\n/** Build ordered gateway host list for read fallback (sidecar/proxy first when active). */\nexport function getReadGatewayHostsForConfig(\n resolved: ResolvedSeedGatewayEndpoints,\n _defaults?: readonly string[],\n): string[] {\n if (resolved.activePath === 'hyper-sidecar' || resolved.activePath === 'http-proxy') {\n return [resolved.arweaveHost]\n }\n return getArweaveReadGatewayHostsForPrimary(resolved.arweaveHost)\n}\n","import type { ResolvedSeedGatewayEndpoints } from '../types/gateway.js'\nimport { resolveProxyBaseUrl } from './resolveSeedGatewayEndpoints.js'\n\nlet resolvedGatewayEndpoints: ResolvedSeedGatewayEndpoints | null = null\n\n/** Last endpoints applied during client init (for read-path helpers). */\nexport function getResolvedSeedGatewayEndpoints(): ResolvedSeedGatewayEndpoints | null {\n return resolvedGatewayEndpoints\n}\n\nexport function setResolvedSeedGatewayEndpoints(\n value: ResolvedSeedGatewayEndpoints | null,\n): void {\n resolvedGatewayEndpoints = value\n}\n\nlet preferredReadBaseUrls: string[] = []\n\n/**\n * Gateways tried before the resolved / public hosts for `/raw/{id}` reads — typically the gateway\n * the app uploads through (Hyper sidecar or app-server proxy), which serves data items before they\n * reach L1 or the public gateways. Does not affect upload, GraphQL or {@link BaseArweaveClient} host.\n */\nexport function getPreferredArweaveReadBaseUrls(): string[] {\n return preferredReadBaseUrls\n}\n\n/**\n * Replace the preferred read gateways. Each entry is a base URL with scheme and any path prefix\n * (`https://app.example.com/api/seed-gateway`); same-origin relative paths (`/api/seed-gateway`)\n * resolve against `window.location.origin` and are dropped when there is no origin. Pass `[]` to clear.\n */\nexport function setPreferredArweaveReadBaseUrls(urls: readonly string[]): void {\n const out: string[] = []\n const seen = new Set<string>()\n for (const raw of urls) {\n const trimmed = raw?.trim()\n if (!trimmed) continue\n let url: string\n try {\n // URL lowercases scheme and host; the path stays case-sensitive.\n const parsed = new URL(/^https?:\\/\\//i.test(trimmed) ? trimmed : resolveProxyBaseUrl(trimmed))\n url = `${parsed.origin}${parsed.pathname.replace(/\\/+$/, '')}`\n } catch {\n continue\n }\n if (seen.has(url)) continue\n seen.add(url)\n out.push(url)\n }\n preferredReadBaseUrls = out\n}\n","import type {\n ClientGatewayContextInput,\n SeedConfigGatewayInput,\n SeedGatewayConfig,\n} from '../types/seedConfig.js'\nimport { DEFAULT_SEED_GATEWAY_HYPER_KEY } from '../constants.js'\n\n/** Merge seed.config gateway fields into {@link SeedGatewayConfig}. */\nexport function seedGatewayConfigFromSeedConfig(\n config: SeedConfigGatewayInput,\n): SeedGatewayConfig {\n const gateway = config.gateway ?? {}\n return {\n transport: gateway.transport,\n arweaveDomain: config.arweaveDomain ?? gateway.arweaveDomain,\n uploadApiBaseUrl: config.uploadApiBaseUrl ?? gateway.uploadApiBaseUrl,\n proxyBaseUrl: gateway.proxyBaseUrl?.trim() || undefined,\n preferredReadBaseUrls: gateway.preferredReadBaseUrls,\n hyper: {\n gatewayHyperKey:\n gateway.hyper?.gatewayHyperKey?.trim() ||\n gateway.gatewayHyperKey?.trim() ||\n DEFAULT_SEED_GATEWAY_HYPER_KEY ||\n undefined,\n localSidecarHost: gateway.hyper?.localSidecarHost ?? gateway.localSidecarHost,\n localSidecarPort: gateway.hyper?.localSidecarPort ?? gateway.localSidecarPort,\n probeSidecar: gateway.hyper?.probeSidecar ?? gateway.probeSidecar,\n },\n }\n}\n\nexport function seedGatewayConfigFromClientContext(\n context: ClientGatewayContextInput,\n): SeedGatewayConfig {\n return {\n transport: context.gatewayTransport,\n arweaveDomain: context.arweaveDomain,\n uploadApiBaseUrl: context.uploadApiBaseUrl,\n proxyBaseUrl: context.gatewayProxyBaseUrl?.trim() || undefined,\n hyper: {\n gatewayHyperKey:\n context.gatewayHyperKey?.trim() || DEFAULT_SEED_GATEWAY_HYPER_KEY || undefined,\n localSidecarHost: context.gatewaySidecarHost,\n localSidecarPort: context.gatewaySidecarPort,\n },\n }\n}\n","import { BaseArweaveClient } from '../ArweaveClient/BaseArweaveClient.js'\nimport { ensureReadGatewaySelected } from '../ArweaveClient/selectReadGateway.js'\nimport { getArweaveReadGatewayHostsForPrimary } from '../constants.js'\nimport { getPreferredArweaveReadBaseUrls, getResolvedSeedGatewayEndpoints } from './gatewayState.js'\nimport { getReadGatewayHostsForConfig } from './resolveSeedGatewayEndpoints.js'\nimport { readArweaveContentResponse } from '../content/arweaveContent.js'\n\n/** Per-gateway timeout for {@link fetchArweaveRawFromBaseUrl}; a hung gateway must not block the next one. */\nexport const DEFAULT_ARWEAVE_RAW_READ_TIMEOUT_MS = 10_000\n\nexport type ArweaveReadBaseUrlOptions = {\n /** Hosts (no scheme) used when no gateway endpoints have been resolved, e.g. a feed's own list. */\n fallbackHosts?: readonly string[]\n}\n\nfunction pushUnique(out: string[], seen: Set<string>, url: string): void {\n const u = url.trim().replace(/\\/$/, '')\n if (!u || seen.has(u)) return\n seen.add(u)\n out.push(u)\n}\n\n/**\n * Resolved / public read gateways as base URLs (scheme + host + any path prefix), without the\n * preferred ones. Does not probe.\n */\nexport function getResolvedArweaveReadBaseUrls(options?: ArweaveReadBaseUrlOptions): string[] {\n const resolved = getResolvedSeedGatewayEndpoints()\n const protocol = BaseArweaveClient.getProtocol()\n const hosts = resolved\n ? getReadGatewayHostsForConfig(resolved)\n : options?.fallbackHosts?.length\n ? [...options.fallbackHosts]\n : getArweaveReadGatewayHostsForPrimary(BaseArweaveClient.getHost())\n\n const out: string[] = []\n const seen = new Set<string>()\n for (const host of hosts) {\n const h = host.trim()\n if (!h) continue\n pushUnique(out, seen, /^https?:\\/\\//i.test(h) ? h : `${protocol}://${h}`)\n }\n return out\n}\n\n/**\n * Ordered base URLs for `/raw/{id}` (and `/{id}`) reads: preferred gateways\n * ({@link setPreferredArweaveReadBaseUrls}) first, then the resolved / public gateways. Does not probe.\n */\nexport function getArweaveReadBaseUrls(options?: ArweaveReadBaseUrlOptions): string[] {\n const out: string[] = []\n const seen = new Set<string>()\n for (const url of getPreferredArweaveReadBaseUrls()) pushUnique(out, seen, url)\n for (const url of getResolvedArweaveReadBaseUrls(options)) pushUnique(out, seen, url)\n return out\n}\n\n/** Run the read-gateway probe unless a sidecar / proxy is already the active path. Never throws. */\nexport async function ensureArweaveReadGatewayForFallback(): Promise<void> {\n try {\n const resolved = getResolvedSeedGatewayEndpoints()\n if (resolved && (resolved.activePath === 'hyper-sidecar' || resolved.activePath === 'http-proxy')) {\n return\n }\n await ensureReadGatewaySelected()\n } catch {\n /* optional — fall through to the current host */\n }\n}\n\n/** GET `{baseUrl}/raw/{id}`; `undefined` on network error, timeout or non-2xx. */\nexport async function fetchArweaveRawFromBaseUrl(\n baseUrl: string,\n transactionId: string,\n options?: { timeoutMs?: number },\n): Promise<Response | undefined> {\n const controller = new AbortController()\n const timer = setTimeout(\n () => controller.abort(),\n options?.timeoutMs ?? DEFAULT_ARWEAVE_RAW_READ_TIMEOUT_MS,\n )\n try {\n const res = await fetch(`${baseUrl.replace(/\\/$/, '')}/raw/${encodeURIComponent(transactionId)}`, {\n method: 'GET',\n credentials: 'omit',\n signal: controller.signal,\n })\n return res.ok ? res : undefined\n } catch {\n return undefined\n } finally {\n clearTimeout(timer)\n }\n}\n\n/**\n * GET `/raw/{id}` across read gateways and return the first non-empty body as text. Preferred\n * gateways go first and are tried before any read-gateway probe; a just-published item is served\n * by the gateway it was uploaded through well before it reaches L1 or the public hosts.\n * The body goes through `transformArweaveContent` (see `content/arweaveContent.ts`).\n */\nexport async function fetchArweaveRawTextAcrossGateways(\n transactionId: string,\n options?: ArweaveReadBaseUrlOptions & { timeoutMs?: number },\n): Promise<string | undefined> {\n const tried = new Set<string>()\n const tryUrls = async (urls: string[]): Promise<string | undefined> => {\n for (const base of urls) {\n if (tried.has(base)) continue\n tried.add(base)\n const res = await fetchArweaveRawFromBaseUrl(base, transactionId, options)\n if (!res) continue\n try {\n const { bytes } = await readArweaveContentResponse(res, { transactionId })\n const text = new TextDecoder().decode(bytes)\n if (text.length > 0) return text\n } catch {\n /* body read failed — next gateway */\n }\n }\n return undefined\n }\n\n const preferred = await tryUrls(getPreferredArweaveReadBaseUrls())\n if (preferred) return preferred\n\n await ensureArweaveReadGatewayForFallback()\n return tryUrls(getResolvedArweaveReadBaseUrls(options))\n}\n"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /** @internal Called by BaseArweaveClient when a client is registered. */
2
+ export declare function markArweaveClientOwner(): void;
3
+ export declare class DuplicateArweaveModuleError extends Error {
4
+ constructor();
5
+ }
6
+ /** Throws {@link DuplicateArweaveModuleError} when another copy of this package registered the Arweave client. */
7
+ export declare function assertSingleArweaveModule(): void;
8
+ /** @internal Tests that load fresh module copies (vi.resetModules) clear the shared marker. */
9
+ export declare function resetArweaveClientOwnerForTests(): void;
10
+ //# sourceMappingURL=moduleOwner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moduleOwner.d.ts","sourceRoot":"","sources":["../src/moduleOwner.ts"],"names":[],"mappings":"AAeA,yEAAyE;AACzE,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED,qBAAa,2BAA4B,SAAQ,KAAK;;CAWrD;AAED,kHAAkH;AAClH,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD;AAED,+FAA+F;AAC/F,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD"}
package/dist/node.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as e, r as t } from "./queries-CYWn1SYL.js";
1
+ import { n as e, r as t } from "./queries-C1tDKPXL.js";
2
2
  import { GraphQLClient as n } from "graphql-request";
3
3
  import r from "arweave";
4
4
  import i from "debug";
@@ -80,8 +80,26 @@ async function x(e, t) {
80
80
  }, t);
81
81
  }
82
82
  //#endregion
83
+ //#region src/moduleOwner.ts
84
+ var S = Symbol.for("@seedprotocol/arweave:clientOwner"), C = Object.freeze({ package: "@seedprotocol/arweave" });
85
+ function w() {
86
+ globalThis[S] = C;
87
+ }
88
+ var T = class extends Error {
89
+ constructor() {
90
+ super("Two copies of @seedprotocol/arweave are loaded, and the Arweave client was registered on the other copy (e.g. by SeedClient). Reads through this copy would use a different client and gateway. Make sure every @seedprotocol/* package is the same version and installed once (`npm ls @seedprotocol/arweave`). With Vite, use seedVitePlugin (or list @seedprotocol/arweave and @seedprotocol/query in optimizeDeps.include and resolve.dedupe) so they are pre-bundled together."), this.name = "DuplicateArweaveModuleError";
91
+ }
92
+ };
93
+ function E() {
94
+ let e = globalThis[S];
95
+ if (e !== void 0 && e !== C) throw new T();
96
+ }
97
+ function D() {
98
+ delete globalThis[S];
99
+ }
100
+ //#endregion
83
101
  //#region src/ArweaveClient/BaseArweaveClient.ts
84
- function S(e) {
102
+ function O(e) {
85
103
  let t = e.trim();
86
104
  return t.startsWith("http://") ? {
87
105
  protocol: "http",
@@ -94,11 +112,11 @@ function S(e) {
94
112
  host: t.replace(/\/$/, "")
95
113
  };
96
114
  }
97
- var C = e, w = "https", T = !1, E = !1, D = class e {
115
+ var k = e, A = "https", j = !1, M = !1, N = class e {
98
116
  static _impl = null;
99
117
  static configure(t) {
100
118
  if (!t) throw Error("Cannot configure ArweaveClient with undefined or null. Ensure the platform-specific ArweaveClient is properly created.");
101
- e._impl = t;
119
+ e._impl = t, w();
102
120
  }
103
121
  static isConfigured() {
104
122
  return e._impl != null;
@@ -109,9 +127,9 @@ var C = e, w = "https", T = !1, E = !1, D = class e {
109
127
  }
110
128
  static resolveGateway() {
111
129
  let e = u();
112
- return e && !T && !E ? S(e) : {
113
- protocol: w,
114
- host: C
130
+ return e && !j && !M ? O(e) : {
131
+ protocol: A,
132
+ host: k
115
133
  };
116
134
  }
117
135
  static getHost() {
@@ -150,22 +168,22 @@ var C = e, w = "https", T = !1, E = !1, D = class e {
150
168
  return `${e}://${t}`;
151
169
  }
152
170
  static setHost(e) {
153
- let t = S(e);
154
- C = t.host, w = t.protocol, T = !0, E = !1;
171
+ let t = O(e);
172
+ k = t.host, A = t.protocol, j = !0, M = !1;
155
173
  }
156
174
  static isReadGatewayLocked() {
157
- return T;
175
+ return j;
158
176
  }
159
177
  static resetReadGatewaySelectionStateForTests() {
160
- E = !1;
178
+ M = !1;
161
179
  }
162
180
  static setPreferredReadGateway(e) {
163
- let t = S(e);
164
- C = t.host, w = t.protocol, T = !1;
181
+ let t = O(e);
182
+ k = t.host, A = t.protocol, j = !1;
165
183
  }
166
184
  static applyProbedReadGateway(e) {
167
- let t = S(e);
168
- C = t.host, w = t.protocol, T = !1, E = !0;
185
+ let t = O(e);
186
+ k = t.host, A = t.protocol, j = !1, M = !0;
169
187
  }
170
188
  static getEndpoint() {
171
189
  return `${this.getBaseUrl()}/graphql`;
@@ -197,7 +215,7 @@ var C = e, w = "https", T = !1, E = !1, D = class e {
197
215
  static downloadFiles(t) {
198
216
  return e.requireImpl().downloadFiles(t);
199
217
  }
200
- }, O = {
218
+ }, P = {
201
219
  "\n query GetTransactionTags($transactionId: ID!) {\n tags: transaction(id: $transactionId) {\n id\n tags {\n name\n value\n }\n }\n }\n": {
202
220
  kind: "Document",
203
221
  definitions: [{
@@ -551,13 +569,13 @@ var C = e, w = "https", T = !1, E = !1, D = class e {
551
569
  }]
552
570
  }
553
571
  };
554
- function k(e) {
555
- return O[e] ?? {};
572
+ function F(e) {
573
+ return P[e] ?? {};
556
574
  }
557
575
  //#endregion
558
576
  //#region src/ArweaveClient/queries.ts
559
- var A = k("\n query GetTransactionTags($transactionId: ID!) {\n tags: transaction(id: $transactionId) {\n id\n tags {\n name\n value\n }\n }\n }\n"), j = k("\n query GetArweaveTransactions(\n $owners: [String!]\n $first: Int\n $after: String\n ) {\n transactions(owners: $owners, first: $first, after: $after) {\n edges {\n cursor\n node {\n id\n anchor\n signature\n block {\n id\n height\n }\n data {\n size\n type\n }\n tags {\n name\n value\n }\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n");
577
+ var I = F("\n query GetTransactionTags($transactionId: ID!) {\n tags: transaction(id: $transactionId) {\n id\n tags {\n name\n value\n }\n }\n }\n"), L = F("\n query GetArweaveTransactions(\n $owners: [String!]\n $first: Int\n $after: String\n ) {\n transactions(owners: $owners, first: $first, after: $after) {\n edges {\n cursor\n node {\n id\n anchor\n signature\n block {\n id\n height\n }\n data {\n size\n type\n }\n tags {\n name\n value\n }\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n");
560
578
  //#endregion
561
- export { f as _, v as a, m as b, y as c, a as d, e as f, n as g, t as h, b as i, c as l, i as m, A as n, x as o, r as p, D as r, _ as s, j as t, o as u, p as v, u as x, h as y };
579
+ export { m as C, h as S, i as _, E as a, f as b, v as c, y as d, c as f, r as g, e as h, T as i, x as l, a as m, I as n, D as o, o as p, N as r, b as s, L as t, _ as u, t as v, u as w, p as x, n as y };
562
580
 
563
- //# sourceMappingURL=queries-CYWn1SYL.js.map
581
+ //# sourceMappingURL=queries-C1tDKPXL.js.map