@seedprotocol/arweave 0.6.5 → 0.6.7
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/ArweaveClient/selectReadGateway.d.ts +12 -0
- package/dist/ArweaveClient/selectReadGateway.d.ts.map +1 -1
- package/dist/gateway/gatewayCircuitBreaker.d.ts +35 -0
- package/dist/gateway/gatewayCircuitBreaker.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +246 -154
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
export declare function invalidateReadGatewayCache(): void;
|
|
3
3
|
/** Clears probe cache, env override suppression, and preferred host (for tests). */
|
|
4
4
|
export declare function resetArweaveReadGatewayForTests(): void;
|
|
5
|
+
/**
|
|
6
|
+
* True when the last {@link ensureReadGatewaySelected} probe found a healthy host
|
|
7
|
+
* (or the cache still says so). False after an all-fail probe until the next success.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isReadGatewayKnownHealthy(): boolean;
|
|
10
|
+
/** Last gateway host that passed /info, if any. */
|
|
11
|
+
export declare function getLastHealthyReadGatewayHost(): string | null;
|
|
5
12
|
/**
|
|
6
13
|
* GET /info with timeout. Treat 2xx + JSON object as healthy.
|
|
14
|
+
* Records circuit-breaker success/failure for the host.
|
|
7
15
|
*/
|
|
8
16
|
export declare function probeGateway(baseUrl: string, signal?: AbortSignal): Promise<boolean>;
|
|
9
17
|
export declare function selectFirstHealthyReadGateway(hosts: string[], protocol?: 'http' | 'https', signal?: AbortSignal): Promise<string | null>;
|
|
@@ -11,6 +19,10 @@ export declare function selectFirstHealthyReadGateway(hosts: string[], protocol?
|
|
|
11
19
|
* Probes gateways in order and applies the first healthy host via {@link BaseArweaveClient.applyProbedReadGateway}.
|
|
12
20
|
* No-op when the read gateway is locked ({@link BaseArweaveClient.setHost}).
|
|
13
21
|
* Uses a short TTL cache to avoid probing on every read.
|
|
22
|
+
*
|
|
23
|
+
* When every probe fails, keeps the last known healthy host (if any) instead of
|
|
24
|
+
* treating the preferred-but-unreachable host as selected, and caches
|
|
25
|
+
* `healthy: false` so {@link isReadGatewayKnownHealthy} reflects that.
|
|
14
26
|
*/
|
|
15
27
|
export declare function ensureReadGatewaySelected(signal?: AbortSignal): Promise<string>;
|
|
16
28
|
//# sourceMappingURL=selectReadGateway.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectReadGateway.d.ts","sourceRoot":"","sources":["../../src/ArweaveClient/selectReadGateway.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"selectReadGateway.d.ts","sourceRoot":"","sources":["../../src/ArweaveClient/selectReadGateway.ts"],"names":[],"mappings":"AA8BA,+EAA+E;AAC/E,wBAAgB,0BAA0B,IAAI,IAAI,CAGjD;AAED,oFAAoF;AACpF,wBAAgB,+BAA+B,IAAI,IAAI,CAQtD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAMnD;AAED,mDAAmD;AACnD,wBAAgB,6BAA6B,IAAI,MAAM,GAAG,IAAI,CAE7D;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAmD1F;AAED,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,GAAE,MAAM,GAAG,OAAiB,EACpC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA0DrF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-wide circuit breaker for Arweave gateway hosts.
|
|
3
|
+
*
|
|
4
|
+
* After consecutive failures, a host is "open" for a cooldown and skipped by
|
|
5
|
+
* probes / metadata fetches. After the cooldown it becomes half-open (one probe
|
|
6
|
+
* allowed). Success closes the circuit.
|
|
7
|
+
*/
|
|
8
|
+
export type GatewayCircuitState = 'closed' | 'open' | 'half-open';
|
|
9
|
+
/** Strip scheme / trailing slash; lowercase host (+ optional port/path). */
|
|
10
|
+
export declare function normalizeGatewayHostKey(hostOrUrl: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Configure failure threshold and open-state duration (mainly for tests).
|
|
13
|
+
*/
|
|
14
|
+
export declare function configureGatewayCircuitBreaker(options: {
|
|
15
|
+
failureThreshold?: number;
|
|
16
|
+
openDurationMs?: number;
|
|
17
|
+
}): void;
|
|
18
|
+
/** Clears all host circuits and restores default thresholds (for tests). */
|
|
19
|
+
export declare function resetGatewayCircuitBreakerForTests(): void;
|
|
20
|
+
/**
|
|
21
|
+
* True when the host should not receive new requests (open), or a half-open
|
|
22
|
+
* probe is already in flight.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isGatewayHostCircuitOpen(hostOrUrl: string, now?: number): boolean;
|
|
25
|
+
export declare function getGatewayHostCircuitState(hostOrUrl: string, now?: number): GatewayCircuitState;
|
|
26
|
+
/**
|
|
27
|
+
* Mark that a probe/request is starting against a half-open host so concurrent
|
|
28
|
+
* callers skip it. No-op when closed or fully open.
|
|
29
|
+
*/
|
|
30
|
+
export declare function beginGatewayHostHalfOpenProbe(hostOrUrl: string, now?: number): void;
|
|
31
|
+
export declare function recordGatewayHostSuccess(hostOrUrl: string): void;
|
|
32
|
+
export declare function recordGatewayHostFailure(hostOrUrl: string, now?: number): void;
|
|
33
|
+
/** Hosts currently in open (or half-open with in-flight) state. */
|
|
34
|
+
export declare function listOpenGatewayCircuitHosts(now?: number): string[];
|
|
35
|
+
//# sourceMappingURL=gatewayCircuitBreaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gatewayCircuitBreaker.d.ts","sourceRoot":"","sources":["../../src/gateway/gatewayCircuitBreaker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAA;AAgBjE,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMjE;AAiBD;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,IAAI,CAOP;AAED,4EAA4E;AAC5E,wBAAgB,kCAAkC,IAAI,IAAI,CAIzD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,OAAO,CASrF;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,GAAG,SAAa,GACf,mBAAmB,CAMrB;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI,CAOvF;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAIhE;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI,CASlF;AAED,mEAAmE;AACnE,wBAAgB,2BAA2B,CAAC,GAAG,SAAa,GAAG,MAAM,EAAE,CAMtE"}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from './ArweaveClient/selectReadGateway.js';
|
|
|
14
14
|
export * from './ArweaveClient/uploadApiVerification.js';
|
|
15
15
|
export * from './ArweaveClient/arweaveL1UploadApi.js';
|
|
16
16
|
export * from './gateway/gatewayState.js';
|
|
17
|
+
export * from './gateway/gatewayCircuitBreaker.js';
|
|
17
18
|
export * from './gateway/resolveSeedGatewayEndpoints.js';
|
|
18
19
|
export * from './gateway/seedGatewayConfig.js';
|
|
19
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,wBAAwB,CAAA;AACtC,cAAc,eAAe,CAAA;AAC7B,cAAc,qCAAqC,CAAA;AACnD,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,YAAY,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AAC9F,cAAc,4BAA4B,CAAA;AAC1C,cAAc,sCAAsC,CAAA;AACpD,OAAO,EAAE,iBAAiB,IAAI,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACzF,YAAY,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AACvE,cAAc,sCAAsC,CAAA;AACpD,cAAc,0CAA0C,CAAA;AACxD,cAAc,uCAAuC,CAAA;AACrD,cAAc,2BAA2B,CAAA;AACzC,cAAc,0CAA0C,CAAA;AACxD,cAAc,gCAAgC,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,wBAAwB,CAAA;AACtC,cAAc,eAAe,CAAA;AAC7B,cAAc,qCAAqC,CAAA;AACnD,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,YAAY,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AAC9F,cAAc,4BAA4B,CAAA;AAC1C,cAAc,sCAAsC,CAAA;AACpD,OAAO,EAAE,iBAAiB,IAAI,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACzF,YAAY,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AACvE,cAAc,sCAAsC,CAAA;AACpD,cAAc,0CAA0C,CAAA;AACxD,cAAc,uCAAuC,CAAA;AACrD,cAAc,2BAA2B,CAAA;AACzC,cAAc,oCAAoC,CAAA;AAClD,cAAc,0CAA0C,CAAA;AACxD,cAAc,gCAAgC,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { a as e, c as t, d as n, f as r, g as i, h as a, i as o, l as s, m as
|
|
1
|
+
import { a as e, c as t, d as n, f as r, g as i, h as a, i as o, l as s, m as ee, n as c, o as te, p as l, r as u, s as d, t as ne, u as re } from "./queries-BLXr3teJ.js";
|
|
2
2
|
//#region src/easAttestationUrl.ts
|
|
3
|
-
var
|
|
4
|
-
function
|
|
3
|
+
var ie = /(^|\.)easscan\.(org|xyz)$/i;
|
|
4
|
+
function f(e) {
|
|
5
5
|
let t = e.trim();
|
|
6
6
|
if (!t) return !1;
|
|
7
7
|
try {
|
|
8
8
|
let e = new URL(t);
|
|
9
|
-
return
|
|
9
|
+
return ie.test(e.hostname) ? /\/attestation\/view\//i.test(e.pathname) : !1;
|
|
10
10
|
} catch {
|
|
11
11
|
return !1;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/relationSeedRef.ts
|
|
16
|
-
function
|
|
16
|
+
function ae(e) {
|
|
17
17
|
let t = {
|
|
18
18
|
localId: void 0,
|
|
19
19
|
uid: void 0
|
|
20
20
|
};
|
|
21
21
|
return e ? (e.length === 10 && (t.localId = e), e.startsWith("0x") && e.length === 66 && (t.uid = e), t) : t;
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function p(e) {
|
|
24
24
|
if (e != null) {
|
|
25
25
|
if (typeof e == "string") {
|
|
26
26
|
let t = e.trim();
|
|
@@ -33,35 +33,35 @@ function g(e) {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
var
|
|
37
|
-
function
|
|
38
|
-
let t =
|
|
36
|
+
var oe = /^[a-zA-Z0-9_-]{10,21}$/;
|
|
37
|
+
function m(e) {
|
|
38
|
+
let t = ae(e);
|
|
39
39
|
return t.localId || t.uid ? {
|
|
40
40
|
seedLocalId: t.localId,
|
|
41
41
|
seedUid: t.uid
|
|
42
|
-
} :
|
|
42
|
+
} : oe.test(e) && !e.startsWith("0x") ? { seedLocalId: e } : {};
|
|
43
43
|
}
|
|
44
44
|
//#endregion
|
|
45
45
|
//#region src/mediaRef.ts
|
|
46
|
-
var
|
|
47
|
-
function
|
|
46
|
+
var se = /^[a-zA-Z0-9_-]{43}$/;
|
|
47
|
+
function ce(e) {
|
|
48
48
|
return e == null ? "" : typeof e == "string" ? e.trim() : String(e).trim();
|
|
49
49
|
}
|
|
50
|
-
function
|
|
50
|
+
function h(e, t) {
|
|
51
51
|
let n = e[t];
|
|
52
52
|
return n == null ? "" : typeof n == "string" ? n.trim() : typeof n == "number" || typeof n == "boolean" ? String(n) : "";
|
|
53
53
|
}
|
|
54
|
-
function
|
|
54
|
+
function le(e) {
|
|
55
55
|
let t = e.trim();
|
|
56
56
|
if (!t) return t;
|
|
57
57
|
try {
|
|
58
|
-
let e =
|
|
58
|
+
let e = p(JSON.parse(t));
|
|
59
59
|
if (e) return e;
|
|
60
60
|
} catch {}
|
|
61
61
|
return t;
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
let n =
|
|
63
|
+
function g(e, t) {
|
|
64
|
+
let n = ce(e);
|
|
65
65
|
if (!n) return { kind: "empty" };
|
|
66
66
|
let r = t?.treatAs;
|
|
67
67
|
if (r === "url") return {
|
|
@@ -79,14 +79,14 @@ function b(e, t) {
|
|
|
79
79
|
kind: "unknown",
|
|
80
80
|
raw: n
|
|
81
81
|
};
|
|
82
|
-
if (n.startsWith("http://") || n.startsWith("https://") || n.startsWith("blob:") || n.startsWith("data:")) return
|
|
82
|
+
if (n.startsWith("http://") || n.startsWith("https://") || n.startsWith("blob:") || n.startsWith("data:")) return f(n) ? {
|
|
83
83
|
kind: "nonMediaUrl",
|
|
84
84
|
href: n
|
|
85
85
|
} : {
|
|
86
86
|
kind: "url",
|
|
87
87
|
href: n
|
|
88
88
|
};
|
|
89
|
-
let i =
|
|
89
|
+
let i = le(n), a = m(i);
|
|
90
90
|
return a.seedUid ? {
|
|
91
91
|
kind: "seedUid",
|
|
92
92
|
uid: a.seedUid
|
|
@@ -96,7 +96,7 @@ function b(e, t) {
|
|
|
96
96
|
} : i.startsWith("0x") && i.length === 66 ? {
|
|
97
97
|
kind: "seedUid",
|
|
98
98
|
uid: i
|
|
99
|
-
} :
|
|
99
|
+
} : se.test(i) && !i.startsWith("0x") ? {
|
|
100
100
|
kind: "arweaveTxId",
|
|
101
101
|
txId: i
|
|
102
102
|
} : {
|
|
@@ -104,25 +104,25 @@ function b(e, t) {
|
|
|
104
104
|
raw: n
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
|
-
function
|
|
108
|
-
let n =
|
|
107
|
+
function _(e, t) {
|
|
108
|
+
let n = h(e, t);
|
|
109
109
|
if (n) return n;
|
|
110
110
|
let r = t.replace(/[A-Z]/g, (e) => `_${e.toLowerCase()}`);
|
|
111
111
|
if (r !== t) {
|
|
112
|
-
let t =
|
|
112
|
+
let t = h(e, r);
|
|
113
113
|
if (t) return t;
|
|
114
114
|
}
|
|
115
115
|
let i = t.split("_");
|
|
116
116
|
if (i.length > 1) {
|
|
117
|
-
let t =
|
|
117
|
+
let t = h(e, i[0] + i.slice(1).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(""));
|
|
118
118
|
if (t) return t;
|
|
119
119
|
}
|
|
120
120
|
return "";
|
|
121
121
|
}
|
|
122
|
-
function
|
|
122
|
+
function ue(e, t) {
|
|
123
123
|
let n = {};
|
|
124
124
|
for (let [r, i] of Object.entries(t)) {
|
|
125
|
-
let t =
|
|
125
|
+
let t = _(e, r);
|
|
126
126
|
if (!t) {
|
|
127
127
|
n[r] = void 0;
|
|
128
128
|
continue;
|
|
@@ -141,7 +141,7 @@ function oe(e, t) {
|
|
|
141
141
|
};
|
|
142
142
|
continue;
|
|
143
143
|
}
|
|
144
|
-
let a =
|
|
144
|
+
let a = g(t, { treatAs: i.treatAs });
|
|
145
145
|
n[r] = {
|
|
146
146
|
role: i.role,
|
|
147
147
|
raw: t,
|
|
@@ -150,12 +150,12 @@ function oe(e, t) {
|
|
|
150
150
|
}
|
|
151
151
|
return n;
|
|
152
152
|
}
|
|
153
|
-
function
|
|
154
|
-
return `${
|
|
153
|
+
function de(e) {
|
|
154
|
+
return `${u.getBaseUrl()}/${e}`;
|
|
155
155
|
}
|
|
156
156
|
//#endregion
|
|
157
157
|
//#region src/resolveSeedRssImageRelationRef.ts
|
|
158
|
-
var
|
|
158
|
+
var fe = [
|
|
159
159
|
"featureImage",
|
|
160
160
|
"feature_image",
|
|
161
161
|
"image",
|
|
@@ -166,49 +166,49 @@ var S = [
|
|
|
166
166
|
"thumbnail_image",
|
|
167
167
|
"thumbnailImage"
|
|
168
168
|
];
|
|
169
|
-
function
|
|
169
|
+
function pe(e) {
|
|
170
170
|
return e == null ? "" : typeof e == "string" ? e.trim() : typeof e == "number" || typeof e == "boolean" ? String(e) : "";
|
|
171
171
|
}
|
|
172
|
-
function
|
|
172
|
+
function v(e, ...t) {
|
|
173
173
|
for (let n of t) {
|
|
174
|
-
let t =
|
|
174
|
+
let t = pe(e[n]);
|
|
175
175
|
if (t) return t;
|
|
176
176
|
}
|
|
177
177
|
let n = t.map((e) => e.split(":").pop().toLowerCase());
|
|
178
178
|
for (let [t, r] of Object.entries(e)) {
|
|
179
179
|
let e = (t.includes(":") ? t.split(":").pop() : t).toLowerCase();
|
|
180
180
|
if (n.some((t) => e === t.toLowerCase())) {
|
|
181
|
-
let e =
|
|
181
|
+
let e = pe(r);
|
|
182
182
|
if (e) return e;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
return "";
|
|
186
186
|
}
|
|
187
|
-
function
|
|
187
|
+
function y(e) {
|
|
188
188
|
let t = e.trim();
|
|
189
189
|
if (t && !t.startsWith("0x")) try {
|
|
190
|
-
return `${
|
|
190
|
+
return `${u.getBaseUrl()}/${t}`;
|
|
191
191
|
} catch {
|
|
192
192
|
return;
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
|
-
function
|
|
195
|
+
function me(e) {
|
|
196
196
|
let t = e.storageTransactionId?.trim();
|
|
197
197
|
if (t) {
|
|
198
|
-
let e =
|
|
198
|
+
let e = y(t);
|
|
199
199
|
if (e) return e;
|
|
200
200
|
}
|
|
201
201
|
let n = e.arweaveUrl?.trim();
|
|
202
|
-
if (n && !
|
|
202
|
+
if (n && !f(n)) return n;
|
|
203
203
|
}
|
|
204
|
-
function
|
|
204
|
+
function he(e) {
|
|
205
205
|
let t = e.trim();
|
|
206
|
-
if (!t ||
|
|
207
|
-
let n =
|
|
206
|
+
if (!t || f(t)) return;
|
|
207
|
+
let n = g(t);
|
|
208
208
|
switch (n.kind) {
|
|
209
209
|
case "url": return { mediaUrl: n.href };
|
|
210
210
|
case "arweaveTxId": {
|
|
211
|
-
let e =
|
|
211
|
+
let e = y(n.txId);
|
|
212
212
|
return {
|
|
213
213
|
storageTransactionId: n.txId,
|
|
214
214
|
...e ? { mediaUrl: e } : {}
|
|
@@ -216,7 +216,7 @@ function ce(e) {
|
|
|
216
216
|
}
|
|
217
217
|
case "seedUid": return { seedUid: n.uid };
|
|
218
218
|
default: {
|
|
219
|
-
let e =
|
|
219
|
+
let e = y(t);
|
|
220
220
|
return e ? {
|
|
221
221
|
storageTransactionId: t,
|
|
222
222
|
mediaUrl: e
|
|
@@ -224,109 +224,201 @@ function ce(e) {
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
|
-
function
|
|
228
|
-
let t =
|
|
227
|
+
function ge(e) {
|
|
228
|
+
let t = v(e, "storageTransactionId", "storage_transaction_id"), n = v(e, "arweaveUrl", "arweave_url"), r = v(e, "seedUid", "SeedUid", "seed_uid"), i = v(e, "link", "Link"), a = me({
|
|
229
229
|
storageTransactionId: t,
|
|
230
230
|
arweaveUrl: n
|
|
231
|
-
}) ?? (i && !
|
|
231
|
+
}) ?? (i && !f(i) ? i : void 0);
|
|
232
232
|
if (t || n || r || a) return {
|
|
233
233
|
...t ? { storageTransactionId: t } : {},
|
|
234
|
-
...n && !
|
|
234
|
+
...n && !f(n) ? { arweaveUrl: n } : {},
|
|
235
235
|
...r ? { seedUid: r } : {},
|
|
236
236
|
...a ? { mediaUrl: a } : {}
|
|
237
237
|
};
|
|
238
238
|
}
|
|
239
|
-
function
|
|
239
|
+
function b(e) {
|
|
240
240
|
if (e != null) {
|
|
241
|
-
if (typeof e == "string") return
|
|
241
|
+
if (typeof e == "string") return he(e);
|
|
242
242
|
if (Array.isArray(e)) {
|
|
243
243
|
for (let t of e) {
|
|
244
|
-
let e =
|
|
244
|
+
let e = b(t);
|
|
245
245
|
if (e?.mediaUrl || e?.storageTransactionId || e?.seedUid) return e;
|
|
246
246
|
}
|
|
247
247
|
return;
|
|
248
248
|
}
|
|
249
|
-
if (typeof e == "object") return
|
|
249
|
+
if (typeof e == "object") return ge(e);
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
|
-
function
|
|
252
|
+
function _e(e, t = fe) {
|
|
253
253
|
for (let n of t) {
|
|
254
254
|
if (!(n in e)) continue;
|
|
255
|
-
let t =
|
|
255
|
+
let t = b(e[n]);
|
|
256
256
|
if (t) return t;
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
//#endregion
|
|
260
|
+
//#region src/gateway/gatewayCircuitBreaker.ts
|
|
261
|
+
var x = 1, S = 6e4, C = x, w = S, T = /* @__PURE__ */ new Map();
|
|
262
|
+
function E(e) {
|
|
263
|
+
let t = e.trim();
|
|
264
|
+
return t ? (t.startsWith("http://") ? t = t.slice(7) : t.startsWith("https://") && (t = t.slice(8)), t.replace(/\/$/, "").toLowerCase()) : "";
|
|
265
|
+
}
|
|
266
|
+
function D(e) {
|
|
267
|
+
let t = T.get(e);
|
|
268
|
+
return t || (t = {
|
|
269
|
+
failures: 0,
|
|
270
|
+
openedAt: null,
|
|
271
|
+
halfOpenProbeInFlight: !1
|
|
272
|
+
}, T.set(e, t)), t;
|
|
273
|
+
}
|
|
274
|
+
function O(e, t) {
|
|
275
|
+
return e.openedAt == null ? "closed" : t - e.openedAt >= w ? "half-open" : "open";
|
|
276
|
+
}
|
|
277
|
+
function ve(e) {
|
|
278
|
+
e.failureThreshold != null && e.failureThreshold >= 1 && (C = e.failureThreshold), e.openDurationMs != null && e.openDurationMs >= 0 && (w = e.openDurationMs);
|
|
279
|
+
}
|
|
280
|
+
function k() {
|
|
281
|
+
T.clear(), C = x, w = S;
|
|
282
|
+
}
|
|
283
|
+
function A(e, t = Date.now()) {
|
|
284
|
+
let n = E(e);
|
|
285
|
+
if (!n) return !1;
|
|
286
|
+
let r = T.get(n);
|
|
287
|
+
if (!r) return !1;
|
|
288
|
+
let i = O(r, t);
|
|
289
|
+
return !!(i === "open" || i === "half-open" && r.halfOpenProbeInFlight);
|
|
290
|
+
}
|
|
291
|
+
function ye(e, t = Date.now()) {
|
|
292
|
+
let n = E(e);
|
|
293
|
+
if (!n) return "closed";
|
|
294
|
+
let r = T.get(n);
|
|
295
|
+
return r ? O(r, t) : "closed";
|
|
296
|
+
}
|
|
297
|
+
function j(e, t = Date.now()) {
|
|
298
|
+
let n = E(e);
|
|
299
|
+
if (!n) return;
|
|
300
|
+
let r = D(n);
|
|
301
|
+
O(r, t) === "half-open" && (r.halfOpenProbeInFlight = !0);
|
|
302
|
+
}
|
|
303
|
+
function M(e) {
|
|
304
|
+
let t = E(e);
|
|
305
|
+
t && T.set(t, {
|
|
306
|
+
failures: 0,
|
|
307
|
+
openedAt: null,
|
|
308
|
+
halfOpenProbeInFlight: !1
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
function N(e, t = Date.now()) {
|
|
312
|
+
let n = E(e);
|
|
313
|
+
if (!n) return;
|
|
314
|
+
let r = D(n);
|
|
315
|
+
r.failures += 1, r.halfOpenProbeInFlight = !1, r.failures >= C && (r.openedAt = t);
|
|
316
|
+
}
|
|
317
|
+
function be(e = Date.now()) {
|
|
318
|
+
let t = [];
|
|
319
|
+
for (let n of T.keys()) A(n, e) && t.push(n);
|
|
320
|
+
return t;
|
|
321
|
+
}
|
|
322
|
+
//#endregion
|
|
260
323
|
//#region src/ArweaveClient/selectReadGateway.ts
|
|
261
|
-
var
|
|
262
|
-
function
|
|
263
|
-
|
|
324
|
+
var P = 18e4, xe = 6e4, Se = 5e3, F = null, I = null, L = null;
|
|
325
|
+
function R() {
|
|
326
|
+
F = null, I = null;
|
|
327
|
+
}
|
|
328
|
+
function Ce() {
|
|
329
|
+
R(), L = null, k(), u.resetReadGatewaySelectionStateForTests(), u.isReadGatewayLocked() || u.setPreferredReadGateway(d);
|
|
264
330
|
}
|
|
265
|
-
function
|
|
266
|
-
|
|
331
|
+
function we() {
|
|
332
|
+
return u.isReadGatewayLocked() ? !0 : F && Date.now() < F.expiresAt ? F.healthy : L != null;
|
|
267
333
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
334
|
+
function Te() {
|
|
335
|
+
return L;
|
|
336
|
+
}
|
|
337
|
+
async function z(e, t) {
|
|
338
|
+
let n = `${e.replace(/\/$/, "")}/info`, r = e;
|
|
339
|
+
try {
|
|
340
|
+
r = new URL(e.includes("://") ? e : `https://${e}`).host;
|
|
341
|
+
} catch {
|
|
342
|
+
r = e.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
|
343
|
+
}
|
|
344
|
+
if (A(r)) return !1;
|
|
345
|
+
j(r);
|
|
346
|
+
let i, a = new AbortController(), o = t ?? a.signal;
|
|
347
|
+
t || (i = setTimeout(() => a.abort(), Se));
|
|
271
348
|
try {
|
|
272
349
|
let e = await fetch(n, {
|
|
273
350
|
method: "GET",
|
|
274
|
-
signal:
|
|
351
|
+
signal: o,
|
|
275
352
|
headers: { Accept: "application/json" }
|
|
276
353
|
});
|
|
277
|
-
if (!e.ok) return !1;
|
|
354
|
+
if (!e.ok) return N(r), !1;
|
|
278
355
|
let t = await e.text();
|
|
279
|
-
if (!t.trim()) return !1;
|
|
356
|
+
if (!t.trim()) return N(r), !1;
|
|
280
357
|
try {
|
|
281
|
-
let e = JSON.parse(t);
|
|
282
|
-
return
|
|
358
|
+
let e = JSON.parse(t), n = typeof e == "object" && !!e;
|
|
359
|
+
return n ? M(r) : N(r), n;
|
|
283
360
|
} catch {
|
|
284
|
-
return !1;
|
|
361
|
+
return N(r), !1;
|
|
285
362
|
}
|
|
286
363
|
} catch {
|
|
287
|
-
return !1;
|
|
364
|
+
return N(r), !1;
|
|
288
365
|
} finally {
|
|
289
|
-
|
|
366
|
+
i && clearTimeout(i);
|
|
290
367
|
}
|
|
291
368
|
}
|
|
292
|
-
async function
|
|
369
|
+
async function B(e, t = "https", n) {
|
|
293
370
|
for (let r of e) {
|
|
294
371
|
let e = r.trim().replace(/\/$/, "");
|
|
295
|
-
if (e && await
|
|
372
|
+
if (e && !A(e) && await z(`${t}://${e}`, n)) return e;
|
|
296
373
|
}
|
|
297
374
|
return null;
|
|
298
375
|
}
|
|
299
|
-
function
|
|
300
|
-
return r(
|
|
301
|
-
}
|
|
302
|
-
async function
|
|
303
|
-
if (
|
|
304
|
-
if (
|
|
305
|
-
if (
|
|
306
|
-
|
|
307
|
-
let t = await
|
|
308
|
-
|
|
309
|
-
host:
|
|
310
|
-
|
|
311
|
-
|
|
376
|
+
function Ee() {
|
|
377
|
+
return r(u.getHost());
|
|
378
|
+
}
|
|
379
|
+
async function De(e) {
|
|
380
|
+
if (u.isReadGatewayLocked()) return u.getHost();
|
|
381
|
+
if (F && Date.now() < F.expiresAt) return F.host;
|
|
382
|
+
if (I) return I;
|
|
383
|
+
I = (async () => {
|
|
384
|
+
let t = await B(Ee(), u.getProtocol(), e);
|
|
385
|
+
if (u.isReadGatewayLocked()) F = {
|
|
386
|
+
host: u.getHost(),
|
|
387
|
+
healthy: !0,
|
|
388
|
+
expiresAt: Date.now() + P
|
|
389
|
+
};
|
|
390
|
+
else if (t) u.applyProbedReadGateway(t), L = t, F = {
|
|
391
|
+
host: t,
|
|
392
|
+
healthy: !0,
|
|
393
|
+
expiresAt: Date.now() + P
|
|
394
|
+
};
|
|
395
|
+
else {
|
|
396
|
+
let e = L ?? u.getHost();
|
|
397
|
+
L && u.getHost() !== L && u.applyProbedReadGateway(L), F = {
|
|
398
|
+
host: e,
|
|
399
|
+
healthy: !1,
|
|
400
|
+
expiresAt: Date.now() + xe
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
return F.host;
|
|
312
404
|
})();
|
|
313
405
|
try {
|
|
314
|
-
return await
|
|
406
|
+
return await I;
|
|
315
407
|
} finally {
|
|
316
|
-
|
|
408
|
+
I = null;
|
|
317
409
|
}
|
|
318
410
|
}
|
|
319
411
|
//#endregion
|
|
320
412
|
//#region src/ArweaveClient/uploadApiVerification.ts
|
|
321
|
-
function
|
|
413
|
+
function V(e) {
|
|
322
414
|
return e.trim().replace(/\/+$/, "");
|
|
323
415
|
}
|
|
324
|
-
function
|
|
325
|
-
return `${
|
|
416
|
+
function H(e, t) {
|
|
417
|
+
return `${V(e)}/api/upload/arweave/data/${encodeURIComponent(t)}`;
|
|
326
418
|
}
|
|
327
|
-
var
|
|
328
|
-
async function
|
|
329
|
-
let r =
|
|
419
|
+
var Oe = 45e3;
|
|
420
|
+
async function ke(e, t, n) {
|
|
421
|
+
let r = H(e, t), i = n?.timeoutMs ?? Oe, a = new AbortController(), o = setTimeout(() => a.abort(), i);
|
|
330
422
|
try {
|
|
331
423
|
let e = await fetch(r, { signal: a.signal });
|
|
332
424
|
return clearTimeout(o), e.status === 404 ? {
|
|
@@ -351,16 +443,16 @@ async function R(e, t, n) {
|
|
|
351
443
|
}
|
|
352
444
|
//#endregion
|
|
353
445
|
//#region src/ArweaveClient/arweaveL1UploadApi.ts
|
|
354
|
-
var
|
|
355
|
-
function
|
|
356
|
-
return `${
|
|
446
|
+
var Ae = "\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";
|
|
447
|
+
function U(e, t) {
|
|
448
|
+
return `${V(e)}/api/upload/arweave/status/${encodeURIComponent(t)}`;
|
|
357
449
|
}
|
|
358
|
-
function
|
|
450
|
+
function je(e) {
|
|
359
451
|
let t = e.l1;
|
|
360
452
|
return t ? t.meetsMinConfirmations === !0 || t.confirmed === !0 : !1;
|
|
361
453
|
}
|
|
362
|
-
async function
|
|
363
|
-
let n =
|
|
454
|
+
async function Me(e, t) {
|
|
455
|
+
let n = U(e, t);
|
|
364
456
|
try {
|
|
365
457
|
let e = await fetch(n);
|
|
366
458
|
if (!e.ok) return null;
|
|
@@ -370,7 +462,7 @@ async function he(e, t) {
|
|
|
370
462
|
return null;
|
|
371
463
|
}
|
|
372
464
|
}
|
|
373
|
-
async function
|
|
465
|
+
async function W(e, t, n) {
|
|
374
466
|
let r = e.trim();
|
|
375
467
|
if (!r) return null;
|
|
376
468
|
try {
|
|
@@ -378,7 +470,7 @@ async function V(e, t, n) {
|
|
|
378
470
|
method: "POST",
|
|
379
471
|
headers: { "Content-Type": "application/json" },
|
|
380
472
|
body: JSON.stringify({
|
|
381
|
-
query:
|
|
473
|
+
query: Ae,
|
|
382
474
|
variables: { id: t }
|
|
383
475
|
}),
|
|
384
476
|
signal: n?.signal
|
|
@@ -402,38 +494,38 @@ async function V(e, t, n) {
|
|
|
402
494
|
return null;
|
|
403
495
|
}
|
|
404
496
|
}
|
|
405
|
-
async function
|
|
406
|
-
let i =
|
|
497
|
+
async function Ne(e, t, n) {
|
|
498
|
+
let i = l(), a = e?.trim(), o = "https", s = null;
|
|
407
499
|
if (a) try {
|
|
408
500
|
let e = new URL(a);
|
|
409
501
|
o = e.protocol === "http:" ? "http" : "https", s = e.hostname || null;
|
|
410
502
|
} catch {
|
|
411
503
|
s = null;
|
|
412
504
|
}
|
|
413
|
-
let
|
|
414
|
-
for (let e of
|
|
415
|
-
if (!await
|
|
416
|
-
let r = await
|
|
505
|
+
let ee = s && s.length > 0 ? r(s) : [...i], c = n?.signal;
|
|
506
|
+
for (let e of ee) {
|
|
507
|
+
if (!await z(`${o}://${e}`, c ?? void 0)) continue;
|
|
508
|
+
let r = await W(`${o}://${e}/graphql`, t, n);
|
|
417
509
|
if (r !== null) return r;
|
|
418
510
|
}
|
|
419
511
|
return null;
|
|
420
512
|
}
|
|
421
513
|
//#endregion
|
|
422
514
|
//#region src/gateway/gatewayState.ts
|
|
423
|
-
var
|
|
424
|
-
function
|
|
425
|
-
return
|
|
515
|
+
var G = null;
|
|
516
|
+
function Pe() {
|
|
517
|
+
return G;
|
|
426
518
|
}
|
|
427
|
-
function
|
|
428
|
-
|
|
519
|
+
function Fe(e) {
|
|
520
|
+
G = e;
|
|
429
521
|
}
|
|
430
522
|
//#endregion
|
|
431
523
|
//#region src/gateway/resolveSeedGatewayEndpoints.ts
|
|
432
|
-
var
|
|
433
|
-
function
|
|
434
|
-
|
|
524
|
+
var K = 18e4, q = null, J = /* @__PURE__ */ new Map();
|
|
525
|
+
function Y() {
|
|
526
|
+
q = null, J.clear();
|
|
435
527
|
}
|
|
436
|
-
function
|
|
528
|
+
function Ie(e) {
|
|
437
529
|
let t = (e ?? "ar.seedprotocol.io").trim();
|
|
438
530
|
return t.startsWith("http://") ? {
|
|
439
531
|
protocol: "http",
|
|
@@ -446,7 +538,7 @@ function ye(e) {
|
|
|
446
538
|
host: t.replace(/\/$/, "")
|
|
447
539
|
};
|
|
448
540
|
}
|
|
449
|
-
function
|
|
541
|
+
function X(e) {
|
|
450
542
|
let t = e.hyper?.localSidecarHost?.trim() || "127.0.0.1", n = e.hyper?.localSidecarPort ?? 1984;
|
|
451
543
|
return {
|
|
452
544
|
host: n === 80 || n === 443 ? t : `${t}:${n}`,
|
|
@@ -454,7 +546,7 @@ function q(e) {
|
|
|
454
546
|
baseUrl: `http://${t}:${n}`
|
|
455
547
|
};
|
|
456
548
|
}
|
|
457
|
-
function
|
|
549
|
+
function Le() {
|
|
458
550
|
try {
|
|
459
551
|
let e = globalThis.window?.location?.origin;
|
|
460
552
|
return typeof e == "string" && e.length > 0 ? e.replace(/\/$/, "") : void 0;
|
|
@@ -462,37 +554,37 @@ function be() {
|
|
|
462
554
|
return;
|
|
463
555
|
}
|
|
464
556
|
}
|
|
465
|
-
function
|
|
557
|
+
function Z(e, t) {
|
|
466
558
|
let n = e.trim();
|
|
467
559
|
if (!n) throw Error("proxyBaseUrl is empty");
|
|
468
560
|
if (n.startsWith("http://") || n.startsWith("https://")) return n.replace(/\/$/, "");
|
|
469
561
|
if (n.startsWith("/")) {
|
|
470
|
-
let r = (t?.origin?.trim() ||
|
|
562
|
+
let r = (t?.origin?.trim() || Le() || "").replace(/\/$/, "");
|
|
471
563
|
if (!r) throw Error(`Relative proxyBaseUrl "${e}" requires a browser origin or resolve options.origin`);
|
|
472
564
|
return `${r}${n.replace(/\/$/, "")}`;
|
|
473
565
|
}
|
|
474
566
|
return `https://${n.replace(/\/$/, "")}`;
|
|
475
567
|
}
|
|
476
|
-
async function
|
|
568
|
+
async function Q(e, t, n) {
|
|
477
569
|
let r = Date.now();
|
|
478
570
|
if (t === "sidecar") {
|
|
479
|
-
if (
|
|
480
|
-
let t = await
|
|
481
|
-
return
|
|
571
|
+
if (q && r < q.expiresAt) return q.healthy;
|
|
572
|
+
let t = await z(e, n);
|
|
573
|
+
return q = {
|
|
482
574
|
healthy: t,
|
|
483
|
-
expiresAt: r +
|
|
575
|
+
expiresAt: r + K
|
|
484
576
|
}, t;
|
|
485
577
|
}
|
|
486
|
-
let i =
|
|
578
|
+
let i = J.get(t);
|
|
487
579
|
if (i && r < i.expiresAt) return i.healthy;
|
|
488
|
-
let a = await
|
|
489
|
-
return
|
|
580
|
+
let a = await z(e, n);
|
|
581
|
+
return J.set(t, {
|
|
490
582
|
healthy: a,
|
|
491
|
-
expiresAt: r +
|
|
583
|
+
expiresAt: r + K
|
|
492
584
|
}), a;
|
|
493
585
|
}
|
|
494
|
-
function
|
|
495
|
-
let { host: t, protocol: n } =
|
|
586
|
+
function $(e) {
|
|
587
|
+
let { host: t, protocol: n } = Ie(e.arweaveDomain), r = `${n}://${t}`, i = e.uploadApiBaseUrl?.trim() || r;
|
|
496
588
|
return {
|
|
497
589
|
mode: e.transport ?? "http-gateway",
|
|
498
590
|
arweaveHost: t,
|
|
@@ -504,8 +596,8 @@ function X(e) {
|
|
|
504
596
|
gatewayHyperKey: e.hyper?.gatewayHyperKey?.trim() || void 0
|
|
505
597
|
};
|
|
506
598
|
}
|
|
507
|
-
function
|
|
508
|
-
let t =
|
|
599
|
+
function Re(e) {
|
|
600
|
+
let t = X(e), n = e.hyper?.gatewayHyperKey?.trim();
|
|
509
601
|
return {
|
|
510
602
|
mode: "hyper",
|
|
511
603
|
arweaveHost: t.host,
|
|
@@ -517,7 +609,7 @@ function Z(e) {
|
|
|
517
609
|
gatewayHyperKey: n || void 0
|
|
518
610
|
};
|
|
519
611
|
}
|
|
520
|
-
function
|
|
612
|
+
function ze(e, t) {
|
|
521
613
|
let n = new URL(t), r = n.protocol === "http:" ? "http" : "https", i = n.pathname.replace(/\/$/, ""), a = i ? `${n.host}${i}` : n.host, o = `${r}://${a}`;
|
|
522
614
|
return {
|
|
523
615
|
mode: e.transport ?? "http-gateway",
|
|
@@ -531,53 +623,53 @@ function Q(e, t) {
|
|
|
531
623
|
proxyBaseUrl: t
|
|
532
624
|
};
|
|
533
625
|
}
|
|
534
|
-
async function
|
|
626
|
+
async function Be(e, t) {
|
|
535
627
|
let n = e.proxyBaseUrl?.trim();
|
|
536
628
|
if (!n) return null;
|
|
537
|
-
let r =
|
|
538
|
-
return e.hyper?.probeSidecar !== !1 && !await
|
|
629
|
+
let r = Z(n, { origin: t?.origin });
|
|
630
|
+
return e.hyper?.probeSidecar !== !1 && !await Q(r, `proxy:${r}`, t?.signal) ? null : ze(e, r);
|
|
539
631
|
}
|
|
540
|
-
async function
|
|
541
|
-
t?.forceSidecarProbe &&
|
|
632
|
+
async function Ve(e, t) {
|
|
633
|
+
t?.forceSidecarProbe && Y();
|
|
542
634
|
let n = e.transport ?? "http-gateway", r = e.hyper?.probeSidecar !== !1;
|
|
543
635
|
if (n === "http-gateway") {
|
|
544
636
|
if (e.proxyBaseUrl?.trim()) {
|
|
545
|
-
let i =
|
|
546
|
-
if (r && !await
|
|
547
|
-
return
|
|
637
|
+
let i = Z(e.proxyBaseUrl, { origin: t?.origin });
|
|
638
|
+
if (r && !await Q(i, `proxy:${i}`, t?.signal)) throw Error(`Gateway HTTP proxy not reachable at ${i}. Ensure your Node route runs createGatewayProxy (or equivalent) and mounts at proxyBaseUrl.`);
|
|
639
|
+
return ze({
|
|
548
640
|
...e,
|
|
549
641
|
transport: n
|
|
550
642
|
}, i);
|
|
551
643
|
}
|
|
552
|
-
return
|
|
644
|
+
return $({
|
|
553
645
|
...e,
|
|
554
646
|
transport: n
|
|
555
647
|
});
|
|
556
648
|
}
|
|
557
649
|
if (n === "hyper") {
|
|
558
|
-
let i = await
|
|
650
|
+
let i = await Be({
|
|
559
651
|
...e,
|
|
560
652
|
transport: n
|
|
561
653
|
}, t);
|
|
562
654
|
if (i) return i;
|
|
563
|
-
let a =
|
|
655
|
+
let a = Re({
|
|
564
656
|
...e,
|
|
565
657
|
transport: n
|
|
566
658
|
});
|
|
567
|
-
if (r && !await
|
|
659
|
+
if (r && !await Q(a.arweaveBaseUrl, "sidecar", t?.signal)) throw Error(`Gateway Hyper sidecar not reachable at ${a.arweaveBaseUrl}. Run: seed gateway tunnel connect <operator-z32-key> — or configure gateway.proxyBaseUrl for an app-server proxy.`);
|
|
568
660
|
return a;
|
|
569
661
|
}
|
|
570
|
-
let i = await
|
|
662
|
+
let i = await Be({
|
|
571
663
|
...e,
|
|
572
664
|
transport: n
|
|
573
665
|
}, t);
|
|
574
666
|
if (i) return i;
|
|
575
|
-
let a =
|
|
576
|
-
return r && await
|
|
667
|
+
let a = X(e);
|
|
668
|
+
return r && await Q(a.baseUrl, "sidecar", t?.signal) ? Re({
|
|
577
669
|
...e,
|
|
578
670
|
transport: "hyper"
|
|
579
671
|
}) : {
|
|
580
|
-
|
|
672
|
+
...$({
|
|
581
673
|
...e,
|
|
582
674
|
transport: "http-gateway"
|
|
583
675
|
}),
|
|
@@ -585,12 +677,12 @@ async function xe(e, t) {
|
|
|
585
677
|
activePath: "hybrid-fallback-http"
|
|
586
678
|
};
|
|
587
679
|
}
|
|
588
|
-
function
|
|
680
|
+
function He(e, t) {
|
|
589
681
|
return e.activePath === "hyper-sidecar" || e.activePath === "http-proxy" ? [e.arweaveHost] : r(e.arweaveHost);
|
|
590
682
|
}
|
|
591
683
|
//#endregion
|
|
592
684
|
//#region src/gateway/seedGatewayConfig.ts
|
|
593
|
-
function
|
|
685
|
+
function Ue(e) {
|
|
594
686
|
let t = e.gateway ?? {};
|
|
595
687
|
return {
|
|
596
688
|
transport: t.transport,
|
|
@@ -605,7 +697,7 @@ function Ce(e) {
|
|
|
605
697
|
}
|
|
606
698
|
};
|
|
607
699
|
}
|
|
608
|
-
function
|
|
700
|
+
function We(e) {
|
|
609
701
|
return {
|
|
610
702
|
transport: e.gatewayTransport,
|
|
611
703
|
arweaveDomain: e.arweaveDomain,
|
|
@@ -619,6 +711,6 @@ function we(e) {
|
|
|
619
711
|
};
|
|
620
712
|
}
|
|
621
713
|
//#endregion
|
|
622
|
-
export { o as ARWEAVE_HOST_ENV_KEYS,
|
|
714
|
+
export { o as ARWEAVE_HOST_ENV_KEYS, u as ArweaveClient, u as BaseArweaveClient, e as DEFAULT_ARWEAVE_GATEWAYS, te as DEFAULT_ARWEAVE_GRAPHQL_URL, d as DEFAULT_ARWEAVE_HOST, t as DEFAULT_GATEWAY_SIDECAR_HOST, s as DEFAULT_GATEWAY_SIDECAR_PORT, re as DEFAULT_SEED_FEED_HYPER_KEY, n as DEFAULT_SEED_GATEWAY_HYPER_KEY, ne as GET_ARWEAVE_TRANSACTIONS, c as GET_TRANSACTION_TAGS, fe as SEED_RSS_IMAGE_RELATION_FIELD_KEYS, j as beginGatewayHostHalfOpenProbe, g as classifyMediaRef, ve as configureGatewayCircuitBreaker, De as ensureReadGatewaySelected, r as getArweaveReadGatewayHostsForPrimary, Me as getArweaveUploadStatus, de as getArweaveUrlForTransaction, l as getDefaultArweaveReadGatewayHostsOrdered, _ as getFeedItemStringField, ye as getGatewayHostCircuitState, Te as getLastHealthyReadGatewayHost, He as getReadGatewayHostsForConfig, Pe as getResolvedSeedGatewayEndpoints, H as getUploadApiArweaveDataUrl, U as getUploadApiArweaveStatusUrl, ke as getUploadPipelineTransactionStatus, R as invalidateReadGatewayCache, Y as invalidateSidecarProbeCache, je as isArweaveL1AnchoringComplete, f as isEasAttestationExplorerUrl, A as isGatewayHostCircuitOpen, ee as isKnownArweaveGatewayHostname, we as isReadGatewayKnownHealthy, be as listOpenGatewayCircuitHosts, a as mergePrimaryHostWithDefaults, ue as normalizeFeedItemFields, E as normalizeGatewayHostKey, p as normalizeRelationPropertyValue, V as normalizeUploadApiBaseUrl, z as probeGateway, W as queryArweaveGatewayTransaction, Ne as queryArweaveGatewayTransactionWithFallback, N as recordGatewayHostFailure, M as recordGatewayHostSuccess, Ce as resetArweaveReadGatewayForTests, k as resetGatewayCircuitBreakerForTests, i as resolveArweaveHostFromEnv, Z as resolveProxyBaseUrl, Ve as resolveSeedGatewayEndpoints, m as resolveSeedIdsFromRefString, _e as resolveSeedRssImageRelationFromItem, b as resolveSeedRssImageRelationRef, We as seedGatewayConfigFromClientContext, Ue as seedGatewayConfigFromSeedConfig, B as selectFirstHealthyReadGateway, Fe as setResolvedSeedGatewayEndpoints };
|
|
623
715
|
|
|
624
716
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/easAttestationUrl.ts","../src/relationSeedRef.ts","../src/mediaRef.ts","../src/resolveSeedRssImageRelationRef.ts","../src/ArweaveClient/selectReadGateway.ts","../src/ArweaveClient/uploadApiVerification.ts","../src/ArweaveClient/arweaveL1UploadApi.ts","../src/gateway/gatewayState.ts","../src/gateway/resolveSeedGatewayEndpoints.ts","../src/gateway/seedGatewayConfig.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 { BaseArweaveClient } from './BaseArweaveClient.js'\nimport {\n DEFAULT_ARWEAVE_HOST,\n getArweaveReadGatewayHostsForPrimary,\n} from '../constants.js'\n\nconst READ_GATEWAY_CACHE_TTL_MS = 3 * 60 * 1000\nconst PROBE_TIMEOUT_MS = 5000\n\nlet readGatewayCache: { host: string; expiresAt: number } | null = null\nlet ensureInFlight: Promise<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 BaseArweaveClient.resetReadGatewaySelectionStateForTests()\n if (!BaseArweaveClient.isReadGatewayLocked()) {\n BaseArweaveClient.setPreferredReadGateway(DEFAULT_ARWEAVE_HOST)\n }\n}\n\n/**\n * GET /info with timeout. Treat 2xx + JSON object as healthy.\n */\nexport async function probeGateway(baseUrl: string, signal?: AbortSignal): Promise<boolean> {\n const url = `${baseUrl.replace(/\\/$/, '')}/info`\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) return false\n const text = await response.text()\n if (!text.trim()) return false\n try {\n const json = JSON.parse(text) as unknown\n return typeof json === 'object' && json !== null\n } catch {\n return false\n }\n } catch {\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 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 */\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 }\n }\n\n readGatewayCache = {\n host: BaseArweaveClient.getHost(),\n expiresAt: Date.now() + READ_GATEWAY_CACHE_TTL_MS,\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 type { ResolvedSeedGatewayEndpoints } from '../types/gateway.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","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 tunnel 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 {\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 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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/easAttestationUrl.ts","../src/relationSeedRef.ts","../src/mediaRef.ts","../src/resolveSeedRssImageRelationRef.ts","../src/gateway/gatewayCircuitBreaker.ts","../src/ArweaveClient/selectReadGateway.ts","../src/ArweaveClient/uploadApiVerification.ts","../src/ArweaveClient/arweaveL1UploadApi.ts","../src/gateway/gatewayState.ts","../src/gateway/resolveSeedGatewayEndpoints.ts","../src/gateway/seedGatewayConfig.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","/**\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 type { ResolvedSeedGatewayEndpoints } from '../types/gateway.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","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 tunnel 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 {\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 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"],"mappings":"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"}
|