@le-space/browser 0.1.27 → 0.1.29
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/README.md +2 -0
- package/index.d.ts +29 -1
- package/index.js +69 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,6 +25,8 @@ That client should remain small and stable. It currently owns:
|
|
|
25
25
|
- CRN listing
|
|
26
26
|
- instance listing
|
|
27
27
|
- message envelope lookup
|
|
28
|
+
- scheduler allocation lookup
|
|
29
|
+
- CRN allocation notify
|
|
28
30
|
- deployment result inspection and polling
|
|
29
31
|
- Aleph message broadcast helpers
|
|
30
32
|
|
package/index.d.ts
CHANGED
|
@@ -143,6 +143,27 @@ interface DeploymentInspectionResult {
|
|
|
143
143
|
rejectionReason: string | null;
|
|
144
144
|
references: MessageReference[];
|
|
145
145
|
}
|
|
146
|
+
interface InstanceAllocationNode {
|
|
147
|
+
node_id?: string;
|
|
148
|
+
url?: string;
|
|
149
|
+
ipv6?: string | null;
|
|
150
|
+
supports_ipv6?: boolean;
|
|
151
|
+
}
|
|
152
|
+
interface InstanceAllocationPeriod {
|
|
153
|
+
start_timestamp?: string;
|
|
154
|
+
duration_seconds?: number;
|
|
155
|
+
}
|
|
156
|
+
interface InstanceAllocation {
|
|
157
|
+
source: 'scheduler' | 'manual';
|
|
158
|
+
crnHash?: string | null;
|
|
159
|
+
crnUrl?: string | null;
|
|
160
|
+
node?: InstanceAllocationNode | null;
|
|
161
|
+
vmIpv6?: string | null;
|
|
162
|
+
period?: InstanceAllocationPeriod | null;
|
|
163
|
+
}
|
|
164
|
+
interface AllocationNotifyResult {
|
|
165
|
+
status: 'confirmed' | 'unconfirmed';
|
|
166
|
+
}
|
|
146
167
|
interface AlephBroadcastMessage {
|
|
147
168
|
sender: string;
|
|
148
169
|
chain: AlephSenderChain;
|
|
@@ -169,10 +190,13 @@ interface BroadcastResult {
|
|
|
169
190
|
interface AlephBrowserClient {
|
|
170
191
|
apiHost: string;
|
|
171
192
|
crnListUrl: string;
|
|
193
|
+
schedulerApiHost: string;
|
|
172
194
|
fetchBalance(address: string): Promise<BalanceResponse>;
|
|
173
195
|
fetchCrns(): Promise<Crn[]>;
|
|
174
196
|
fetchInstances(address: string): Promise<InstanceMessage[]>;
|
|
175
197
|
fetchMessageEnvelope(itemHash: string): Promise<AlephMessageEnvelope | null>;
|
|
198
|
+
fetchSchedulerAllocation(itemHash: string): Promise<InstanceAllocation | null>;
|
|
199
|
+
notifyCrnAllocation(crnUrl: string, itemHash: string): Promise<AllocationNotifyResult>;
|
|
176
200
|
inspectDeploymentResult(itemHash: string, rootfsRef?: string): Promise<DeploymentInspectionResult>;
|
|
177
201
|
waitForDeploymentResult(itemHash: string, rootfsRef?: string, attempts?: number, delayMs?: number): Promise<DeploymentInspectionResult>;
|
|
178
202
|
broadcastInstanceMessage(message: AlephBroadcastMessage, sync?: boolean): Promise<BroadcastResult>;
|
|
@@ -220,10 +244,13 @@ declare function fetchWithTimeout(input: RequestInfo | URL, init?: RequestInit,
|
|
|
220
244
|
|
|
221
245
|
declare const DEFAULT_ALEPH_API_HOST = "https://api2.aleph.im";
|
|
222
246
|
declare const DEFAULT_CRN_LIST_URL = "https://crns-list.aleph.sh/crns.json";
|
|
247
|
+
declare const DEFAULT_ALEPH_SCHEDULER_API_HOST = "https://scheduler.api.aleph.cloud";
|
|
223
248
|
declare function normalizeMessageStatus(status: unknown): MessageStatus;
|
|
224
249
|
declare function fetchBalance(address: string, apiHost?: string): Promise<BalanceResponse>;
|
|
225
250
|
declare function fetchCrns(url?: string): Promise<Crn[]>;
|
|
226
251
|
declare function fetchInstances(address: string, apiHost?: string): Promise<InstanceMessage[]>;
|
|
252
|
+
declare function fetchSchedulerAllocation(itemHash: string, schedulerApiHost?: string): Promise<InstanceAllocation | null>;
|
|
253
|
+
declare function notifyCrnAllocation(crnUrl: string, itemHash: string): Promise<AllocationNotifyResult>;
|
|
227
254
|
declare function fetchMessageEnvelope(itemHash: string, apiHost?: string): Promise<AlephMessageEnvelope | null>;
|
|
228
255
|
declare function inspectDeploymentResult(itemHash: string, rootfsRef?: string, apiHost?: string): Promise<DeploymentInspectionResult>;
|
|
229
256
|
declare function waitForDeploymentResult(itemHash: string, rootfsRef?: string, apiHost?: string, attempts?: number, delayMs?: number): Promise<DeploymentInspectionResult>;
|
|
@@ -233,6 +260,7 @@ declare function broadcastAlephMessage(message: AlephBroadcastMessage, apiHost?:
|
|
|
233
260
|
interface CreateAlephBrowserClientOptions {
|
|
234
261
|
apiHost?: string;
|
|
235
262
|
crnListUrl?: string;
|
|
263
|
+
schedulerApiHost?: string;
|
|
236
264
|
}
|
|
237
265
|
declare function createAlephBrowserClient(options?: CreateAlephBrowserClientOptions): AlephBrowserClient;
|
|
238
266
|
|
|
@@ -251,4 +279,4 @@ declare const DEFAULT_ALEPH_AGGREGATE_ADDRESS = "0xFba561a84A537fCaa567bb7A2257e
|
|
|
251
279
|
declare function parseInstancePricing(payload: unknown): InstancePricing;
|
|
252
280
|
declare function fetchInstancePricing(apiHost?: string, aggregateAddress?: string): Promise<PricingState>;
|
|
253
281
|
|
|
254
|
-
export { type AlephBroadcastMessage, type AlephBroadcastResponse, type AlephBrowserClient, type AlephMessageEnvelope, type AlephMessageType, type AlephSenderChain, BROWSER_PACKAGE_PLAN, type BalanceResponse, type BroadcastResult, type BrowserExtractionPhase, type BrowserPackagePlan, type ComputeUnit, type CreateAlephBrowserClientOptions, type Crn, type CrnListResponse, type CrnLocation, type CrnUsage, DEFAULT_ALEPH_AGGREGATE_ADDRESS, DEFAULT_ALEPH_API_HOST, DEFAULT_CRN_LIST_URL, DEFAULT_IPFS_GATEWAY_BASE_URL, DEFAULT_ROOTFS_MANIFEST_URL, type DeploymentInspectionResult, type GatewayProbeStatus, ITEM_HASH_RE, type InstanceMessage, type InstancePricing, type LoadRootfsManifestOptions, type MessageReference, type MessageStatus, type PaymentMode, type Price, type PricingState, type ReferenceStatus, type RootfsManifest, type RootfsManifestState, type RootfsRequiredPortForward, type RootfsResolution, type Tier, broadcastAlephMessage, broadcastInstanceMessage, createAlephBrowserClient, fetchBalance, fetchCrns, fetchInstancePricing, fetchInstances, fetchMessageEnvelope, fetchWithTimeout, inspectDeploymentResult, loadRootfsManifest, normalizeMessageStatus, parseInstancePricing, resolveRootfsReference, validateRootfsManifest, verifyRootfsExists, waitForDeploymentResult };
|
|
282
|
+
export { type AlephBroadcastMessage, type AlephBroadcastResponse, type AlephBrowserClient, type AlephMessageEnvelope, type AlephMessageType, type AlephSenderChain, type AllocationNotifyResult, BROWSER_PACKAGE_PLAN, type BalanceResponse, type BroadcastResult, type BrowserExtractionPhase, type BrowserPackagePlan, type ComputeUnit, type CreateAlephBrowserClientOptions, type Crn, type CrnListResponse, type CrnLocation, type CrnUsage, DEFAULT_ALEPH_AGGREGATE_ADDRESS, DEFAULT_ALEPH_API_HOST, DEFAULT_ALEPH_SCHEDULER_API_HOST, DEFAULT_CRN_LIST_URL, DEFAULT_IPFS_GATEWAY_BASE_URL, DEFAULT_ROOTFS_MANIFEST_URL, type DeploymentInspectionResult, type GatewayProbeStatus, ITEM_HASH_RE, type InstanceAllocation, type InstanceAllocationNode, type InstanceAllocationPeriod, type InstanceMessage, type InstancePricing, type LoadRootfsManifestOptions, type MessageReference, type MessageStatus, type PaymentMode, type Price, type PricingState, type ReferenceStatus, type RootfsManifest, type RootfsManifestState, type RootfsRequiredPortForward, type RootfsResolution, type Tier, broadcastAlephMessage, broadcastInstanceMessage, createAlephBrowserClient, fetchBalance, fetchCrns, fetchInstancePricing, fetchInstances, fetchMessageEnvelope, fetchSchedulerAllocation, fetchWithTimeout, inspectDeploymentResult, loadRootfsManifest, normalizeMessageStatus, notifyCrnAllocation, parseInstancePricing, resolveRootfsReference, validateRootfsManifest, verifyRootfsExists, waitForDeploymentResult };
|
package/index.js
CHANGED
|
@@ -50,6 +50,7 @@ async function fetchWithTimeout(input, init = {}, timeoutMs = 15e3) {
|
|
|
50
50
|
// src/aleph-api.ts
|
|
51
51
|
var DEFAULT_ALEPH_API_HOST = "https://api2.aleph.im";
|
|
52
52
|
var DEFAULT_CRN_LIST_URL = "https://crns-list.aleph.sh/crns.json";
|
|
53
|
+
var DEFAULT_ALEPH_SCHEDULER_API_HOST = "https://scheduler.api.aleph.cloud";
|
|
53
54
|
function normalizeMessageStatus(status) {
|
|
54
55
|
if (typeof status !== "string") return "unknown";
|
|
55
56
|
const normalized = status.toLowerCase();
|
|
@@ -58,6 +59,16 @@ function normalizeMessageStatus(status) {
|
|
|
58
59
|
}
|
|
59
60
|
return "unknown";
|
|
60
61
|
}
|
|
62
|
+
function asString(value) {
|
|
63
|
+
return typeof value === "string" && value.trim() ? value : null;
|
|
64
|
+
}
|
|
65
|
+
function asNumber(value) {
|
|
66
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
67
|
+
}
|
|
68
|
+
function isUnconfirmedNetworkError(error) {
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
return error instanceof TypeError || message.includes("Failed to fetch") || message.includes("Request timed out");
|
|
71
|
+
}
|
|
61
72
|
async function fetchBalance(address, apiHost = DEFAULT_ALEPH_API_HOST) {
|
|
62
73
|
const response = await fetchWithTimeout(`${apiHost}/api/v0/addresses/${address}/balance`, {
|
|
63
74
|
cache: "no-cache"
|
|
@@ -89,6 +100,53 @@ async function fetchInstances(address, apiHost = DEFAULT_ALEPH_API_HOST) {
|
|
|
89
100
|
status: typeof message.status === "string" && message.status.trim() ? message.status : message.confirmed ? "processed" : message.status
|
|
90
101
|
}));
|
|
91
102
|
}
|
|
103
|
+
async function fetchSchedulerAllocation(itemHash, schedulerApiHost = DEFAULT_ALEPH_SCHEDULER_API_HOST) {
|
|
104
|
+
const response = await fetchWithTimeout(`${schedulerApiHost}/api/v0/allocation/${itemHash}`, {
|
|
105
|
+
cache: "no-cache"
|
|
106
|
+
});
|
|
107
|
+
if (response.status === 404) return null;
|
|
108
|
+
if (!response.ok) throw new Error(`Scheduler allocation request failed: ${response.status}`);
|
|
109
|
+
const payload = await response.json();
|
|
110
|
+
const node = payload.node;
|
|
111
|
+
return {
|
|
112
|
+
source: "scheduler",
|
|
113
|
+
crnUrl: asString(node?.url),
|
|
114
|
+
node: node ? {
|
|
115
|
+
node_id: asString(node.node_id) ?? void 0,
|
|
116
|
+
url: asString(node.url) ?? void 0,
|
|
117
|
+
ipv6: asString(node.ipv6),
|
|
118
|
+
supports_ipv6: typeof node.supports_ipv6 === "boolean" ? node.supports_ipv6 : void 0
|
|
119
|
+
} : null,
|
|
120
|
+
vmIpv6: asString(payload.vm_ipv6),
|
|
121
|
+
period: payload.period ? {
|
|
122
|
+
start_timestamp: asString(payload.period.start_timestamp) ?? void 0,
|
|
123
|
+
duration_seconds: asNumber(payload.period.duration_seconds) ?? void 0
|
|
124
|
+
} : null
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async function notifyCrnAllocation(crnUrl, itemHash) {
|
|
128
|
+
const normalizedCrnUrl = crnUrl.replace(/\/+$/, "");
|
|
129
|
+
try {
|
|
130
|
+
const response = await fetchWithTimeout(`${normalizedCrnUrl}/control/allocation/notify`, {
|
|
131
|
+
method: "POST",
|
|
132
|
+
headers: {
|
|
133
|
+
"content-type": "text/plain;charset=UTF-8"
|
|
134
|
+
},
|
|
135
|
+
body: JSON.stringify({ instance: itemHash }),
|
|
136
|
+
mode: "cors"
|
|
137
|
+
});
|
|
138
|
+
if (!response.ok) {
|
|
139
|
+
const responseText = await response.text().catch(() => "");
|
|
140
|
+
throw new Error(`CRN allocation notify failed: ${response.status}${responseText ? ` ${responseText}` : ""}`);
|
|
141
|
+
}
|
|
142
|
+
return { status: "confirmed" };
|
|
143
|
+
} catch (error) {
|
|
144
|
+
if (isUnconfirmedNetworkError(error)) {
|
|
145
|
+
return { status: "unconfirmed" };
|
|
146
|
+
}
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
92
150
|
function messageTypeFromEnvelope(payload) {
|
|
93
151
|
if (!payload) return null;
|
|
94
152
|
const type = payload.type ?? payload.message?.type ?? (Array.isArray(payload.messages) ? payload.messages[0]?.type : void 0);
|
|
@@ -229,9 +287,11 @@ async function broadcastAlephMessage(message, apiHost = DEFAULT_ALEPH_API_HOST,
|
|
|
229
287
|
function createAlephBrowserClient(options = {}) {
|
|
230
288
|
const apiHost = options.apiHost ?? DEFAULT_ALEPH_API_HOST;
|
|
231
289
|
const crnListUrl = options.crnListUrl ?? DEFAULT_CRN_LIST_URL;
|
|
290
|
+
const schedulerApiHost = options.schedulerApiHost ?? DEFAULT_ALEPH_SCHEDULER_API_HOST;
|
|
232
291
|
return {
|
|
233
292
|
apiHost,
|
|
234
293
|
crnListUrl,
|
|
294
|
+
schedulerApiHost,
|
|
235
295
|
fetchBalance(address) {
|
|
236
296
|
return fetchBalance(address, apiHost);
|
|
237
297
|
},
|
|
@@ -244,6 +304,12 @@ function createAlephBrowserClient(options = {}) {
|
|
|
244
304
|
fetchMessageEnvelope(itemHash) {
|
|
245
305
|
return fetchMessageEnvelope(itemHash, apiHost);
|
|
246
306
|
},
|
|
307
|
+
fetchSchedulerAllocation(itemHash) {
|
|
308
|
+
return fetchSchedulerAllocation(itemHash, schedulerApiHost);
|
|
309
|
+
},
|
|
310
|
+
notifyCrnAllocation(crnUrl, itemHash) {
|
|
311
|
+
return notifyCrnAllocation(crnUrl, itemHash);
|
|
312
|
+
},
|
|
247
313
|
inspectDeploymentResult(itemHash, rootfsRef) {
|
|
248
314
|
return inspectDeploymentResult(itemHash, rootfsRef, apiHost);
|
|
249
315
|
},
|
|
@@ -472,6 +538,7 @@ export {
|
|
|
472
538
|
BROWSER_PACKAGE_PLAN,
|
|
473
539
|
DEFAULT_ALEPH_AGGREGATE_ADDRESS,
|
|
474
540
|
DEFAULT_ALEPH_API_HOST,
|
|
541
|
+
DEFAULT_ALEPH_SCHEDULER_API_HOST,
|
|
475
542
|
DEFAULT_CRN_LIST_URL,
|
|
476
543
|
DEFAULT_IPFS_GATEWAY_BASE_URL,
|
|
477
544
|
DEFAULT_ROOTFS_MANIFEST_URL,
|
|
@@ -484,10 +551,12 @@ export {
|
|
|
484
551
|
fetchInstancePricing,
|
|
485
552
|
fetchInstances,
|
|
486
553
|
fetchMessageEnvelope,
|
|
554
|
+
fetchSchedulerAllocation,
|
|
487
555
|
fetchWithTimeout,
|
|
488
556
|
inspectDeploymentResult,
|
|
489
557
|
loadRootfsManifest,
|
|
490
558
|
normalizeMessageStatus,
|
|
559
|
+
notifyCrnAllocation,
|
|
491
560
|
parseInstancePricing,
|
|
492
561
|
resolveRootfsReference,
|
|
493
562
|
validateRootfsManifest,
|