@le-space/browser 0.1.26 → 0.1.27
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 +20 -0
- package/index.d.ts +46 -1
- package/index.js +80 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,25 @@ The package should stay UI-neutral. It should provide browser-safe helpers, but
|
|
|
13
13
|
it should not own app-specific Svelte state, prepaid product logic, or wallet
|
|
14
14
|
UX.
|
|
15
15
|
|
|
16
|
+
## Client Surface
|
|
17
|
+
|
|
18
|
+
The preferred public entrypoint is a typed browser client factory:
|
|
19
|
+
|
|
20
|
+
- `createAlephBrowserClient({ apiHost?, crnListUrl? })`
|
|
21
|
+
|
|
22
|
+
That client should remain small and stable. It currently owns:
|
|
23
|
+
|
|
24
|
+
- balance lookup
|
|
25
|
+
- CRN listing
|
|
26
|
+
- instance listing
|
|
27
|
+
- message envelope lookup
|
|
28
|
+
- deployment result inspection and polling
|
|
29
|
+
- Aleph message broadcast helpers
|
|
30
|
+
|
|
31
|
+
Lower-level helper functions remain exported too, but new extractions should
|
|
32
|
+
prefer hanging reusable behavior off the client surface unless there is a good
|
|
33
|
+
reason to keep them as standalone utilities.
|
|
34
|
+
|
|
16
35
|
## Planned v1 Scope
|
|
17
36
|
|
|
18
37
|
The first real extraction wave should cover:
|
|
@@ -23,6 +42,7 @@ The first real extraction wave should cover:
|
|
|
23
42
|
- balance fetch
|
|
24
43
|
- CRN fetch
|
|
25
44
|
- instance listing
|
|
45
|
+
- typed browser client factory
|
|
26
46
|
- Aleph message broadcast helpers
|
|
27
47
|
- deployment polling and result inspection
|
|
28
48
|
- runtime detail inspection
|
package/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ interface BrowserPackagePlan {
|
|
|
6
6
|
declare const BROWSER_PACKAGE_PLAN: BrowserPackagePlan;
|
|
7
7
|
type MessageStatus = 'processed' | 'pending' | 'rejected' | 'unknown';
|
|
8
8
|
type ReferenceStatus = MessageStatus | 'missing';
|
|
9
|
+
type AlephSenderChain = 'ETH';
|
|
10
|
+
type AlephMessageType = 'INSTANCE' | 'FORGET' | 'AGGREGATE';
|
|
9
11
|
interface BalanceResponse {
|
|
10
12
|
address: string;
|
|
11
13
|
balance: string;
|
|
@@ -141,6 +143,41 @@ interface DeploymentInspectionResult {
|
|
|
141
143
|
rejectionReason: string | null;
|
|
142
144
|
references: MessageReference[];
|
|
143
145
|
}
|
|
146
|
+
interface AlephBroadcastMessage {
|
|
147
|
+
sender: string;
|
|
148
|
+
chain: AlephSenderChain;
|
|
149
|
+
signature: string;
|
|
150
|
+
type: AlephMessageType;
|
|
151
|
+
item_hash: string;
|
|
152
|
+
item_type: 'inline';
|
|
153
|
+
item_content: string;
|
|
154
|
+
time: number;
|
|
155
|
+
channel: string;
|
|
156
|
+
}
|
|
157
|
+
interface AlephBroadcastResponse {
|
|
158
|
+
publication_status?: {
|
|
159
|
+
status: string;
|
|
160
|
+
failed?: unknown[];
|
|
161
|
+
};
|
|
162
|
+
message_status?: MessageStatus;
|
|
163
|
+
[key: string]: unknown;
|
|
164
|
+
}
|
|
165
|
+
interface BroadcastResult {
|
|
166
|
+
response: AlephBroadcastResponse;
|
|
167
|
+
httpStatus: number;
|
|
168
|
+
}
|
|
169
|
+
interface AlephBrowserClient {
|
|
170
|
+
apiHost: string;
|
|
171
|
+
crnListUrl: string;
|
|
172
|
+
fetchBalance(address: string): Promise<BalanceResponse>;
|
|
173
|
+
fetchCrns(): Promise<Crn[]>;
|
|
174
|
+
fetchInstances(address: string): Promise<InstanceMessage[]>;
|
|
175
|
+
fetchMessageEnvelope(itemHash: string): Promise<AlephMessageEnvelope | null>;
|
|
176
|
+
inspectDeploymentResult(itemHash: string, rootfsRef?: string): Promise<DeploymentInspectionResult>;
|
|
177
|
+
waitForDeploymentResult(itemHash: string, rootfsRef?: string, attempts?: number, delayMs?: number): Promise<DeploymentInspectionResult>;
|
|
178
|
+
broadcastInstanceMessage(message: AlephBroadcastMessage, sync?: boolean): Promise<BroadcastResult>;
|
|
179
|
+
broadcastAlephMessage(message: AlephBroadcastMessage, sync?: boolean): Promise<BroadcastResult>;
|
|
180
|
+
}
|
|
144
181
|
interface RootfsRequiredPortForward {
|
|
145
182
|
port: number;
|
|
146
183
|
tcp?: boolean;
|
|
@@ -190,6 +227,14 @@ declare function fetchInstances(address: string, apiHost?: string): Promise<Inst
|
|
|
190
227
|
declare function fetchMessageEnvelope(itemHash: string, apiHost?: string): Promise<AlephMessageEnvelope | null>;
|
|
191
228
|
declare function inspectDeploymentResult(itemHash: string, rootfsRef?: string, apiHost?: string): Promise<DeploymentInspectionResult>;
|
|
192
229
|
declare function waitForDeploymentResult(itemHash: string, rootfsRef?: string, apiHost?: string, attempts?: number, delayMs?: number): Promise<DeploymentInspectionResult>;
|
|
230
|
+
declare function broadcastInstanceMessage(message: AlephBroadcastMessage, apiHost?: string, sync?: boolean): Promise<BroadcastResult>;
|
|
231
|
+
declare function broadcastAlephMessage(message: AlephBroadcastMessage, apiHost?: string, sync?: boolean): Promise<BroadcastResult>;
|
|
232
|
+
|
|
233
|
+
interface CreateAlephBrowserClientOptions {
|
|
234
|
+
apiHost?: string;
|
|
235
|
+
crnListUrl?: string;
|
|
236
|
+
}
|
|
237
|
+
declare function createAlephBrowserClient(options?: CreateAlephBrowserClientOptions): AlephBrowserClient;
|
|
193
238
|
|
|
194
239
|
declare const ITEM_HASH_RE: RegExp;
|
|
195
240
|
declare const DEFAULT_ROOTFS_MANIFEST_URL = "./rootfs-manifest.json";
|
|
@@ -206,4 +251,4 @@ declare const DEFAULT_ALEPH_AGGREGATE_ADDRESS = "0xFba561a84A537fCaa567bb7A2257e
|
|
|
206
251
|
declare function parseInstancePricing(payload: unknown): InstancePricing;
|
|
207
252
|
declare function fetchInstancePricing(apiHost?: string, aggregateAddress?: string): Promise<PricingState>;
|
|
208
253
|
|
|
209
|
-
export { type AlephMessageEnvelope, BROWSER_PACKAGE_PLAN, type BalanceResponse, type BrowserExtractionPhase, type BrowserPackagePlan, type ComputeUnit, 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, fetchBalance, fetchCrns, fetchInstancePricing, fetchInstances, fetchMessageEnvelope, fetchWithTimeout, inspectDeploymentResult, loadRootfsManifest, normalizeMessageStatus, parseInstancePricing, resolveRootfsReference, validateRootfsManifest, verifyRootfsExists, waitForDeploymentResult };
|
|
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 };
|
package/index.js
CHANGED
|
@@ -181,6 +181,83 @@ async function waitForDeploymentResult(itemHash, rootfsRef, apiHost = DEFAULT_AL
|
|
|
181
181
|
}
|
|
182
182
|
return lastResult;
|
|
183
183
|
}
|
|
184
|
+
function isInvalidMessageFormatResponse(response, payload) {
|
|
185
|
+
if (response.status !== 422) return false;
|
|
186
|
+
const details = payload.details;
|
|
187
|
+
if (typeof details === "string" && details.includes("InvalidMessageFormat")) return true;
|
|
188
|
+
if (details && typeof details === "object") {
|
|
189
|
+
const detailMessage = details.message;
|
|
190
|
+
if (typeof detailMessage === "string" && detailMessage.includes("InvalidMessageFormat")) return true;
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
async function postBroadcastPayload(body, apiHost) {
|
|
195
|
+
const rawResponse = await fetchWithTimeout(`${apiHost}/api/v0/messages`, {
|
|
196
|
+
method: "POST",
|
|
197
|
+
headers: { "content-type": "application/json" },
|
|
198
|
+
body: JSON.stringify(body)
|
|
199
|
+
});
|
|
200
|
+
const response = await rawResponse.json().catch(() => ({}));
|
|
201
|
+
return {
|
|
202
|
+
response,
|
|
203
|
+
httpStatus: rawResponse.status,
|
|
204
|
+
rawResponse
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
async function broadcastInstanceMessage(message, apiHost = DEFAULT_ALEPH_API_HOST, sync = false) {
|
|
208
|
+
const attempts = [{ sync, message }, { ...message, sync }, { ...message }];
|
|
209
|
+
for (let index = 0; index < attempts.length; index += 1) {
|
|
210
|
+
const result = await postBroadcastPayload(attempts[index], apiHost);
|
|
211
|
+
if (result.rawResponse.ok || result.httpStatus === 202) {
|
|
212
|
+
return {
|
|
213
|
+
response: result.response,
|
|
214
|
+
httpStatus: result.httpStatus
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
const canRetry = index < attempts.length - 1 && isInvalidMessageFormatResponse(result.rawResponse, result.response);
|
|
218
|
+
if (!canRetry) {
|
|
219
|
+
throw new Error(`Broadcast failed: ${result.httpStatus} ${JSON.stringify(result.response)}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
throw new Error("Broadcast failed: no compatible request format was accepted");
|
|
223
|
+
}
|
|
224
|
+
async function broadcastAlephMessage(message, apiHost = DEFAULT_ALEPH_API_HOST, sync = false) {
|
|
225
|
+
return broadcastInstanceMessage(message, apiHost, sync);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/client.ts
|
|
229
|
+
function createAlephBrowserClient(options = {}) {
|
|
230
|
+
const apiHost = options.apiHost ?? DEFAULT_ALEPH_API_HOST;
|
|
231
|
+
const crnListUrl = options.crnListUrl ?? DEFAULT_CRN_LIST_URL;
|
|
232
|
+
return {
|
|
233
|
+
apiHost,
|
|
234
|
+
crnListUrl,
|
|
235
|
+
fetchBalance(address) {
|
|
236
|
+
return fetchBalance(address, apiHost);
|
|
237
|
+
},
|
|
238
|
+
fetchCrns() {
|
|
239
|
+
return fetchCrns(crnListUrl);
|
|
240
|
+
},
|
|
241
|
+
fetchInstances(address) {
|
|
242
|
+
return fetchInstances(address, apiHost);
|
|
243
|
+
},
|
|
244
|
+
fetchMessageEnvelope(itemHash) {
|
|
245
|
+
return fetchMessageEnvelope(itemHash, apiHost);
|
|
246
|
+
},
|
|
247
|
+
inspectDeploymentResult(itemHash, rootfsRef) {
|
|
248
|
+
return inspectDeploymentResult(itemHash, rootfsRef, apiHost);
|
|
249
|
+
},
|
|
250
|
+
waitForDeploymentResult(itemHash, rootfsRef, attempts, delayMs) {
|
|
251
|
+
return waitForDeploymentResult(itemHash, rootfsRef, apiHost, attempts, delayMs);
|
|
252
|
+
},
|
|
253
|
+
broadcastInstanceMessage(message, sync) {
|
|
254
|
+
return broadcastInstanceMessage(message, apiHost, sync);
|
|
255
|
+
},
|
|
256
|
+
broadcastAlephMessage(message, sync) {
|
|
257
|
+
return broadcastAlephMessage(message, apiHost, sync);
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
184
261
|
|
|
185
262
|
// src/rootfs.ts
|
|
186
263
|
var ITEM_HASH_RE = /^[a-fA-F0-9]{64}$/u;
|
|
@@ -399,6 +476,9 @@ export {
|
|
|
399
476
|
DEFAULT_IPFS_GATEWAY_BASE_URL,
|
|
400
477
|
DEFAULT_ROOTFS_MANIFEST_URL,
|
|
401
478
|
ITEM_HASH_RE,
|
|
479
|
+
broadcastAlephMessage,
|
|
480
|
+
broadcastInstanceMessage,
|
|
481
|
+
createAlephBrowserClient,
|
|
402
482
|
fetchBalance,
|
|
403
483
|
fetchCrns,
|
|
404
484
|
fetchInstancePricing,
|