Compare commits

...

2 Commits

Author SHA1 Message Date
anonpenguin23
54c61e6a47 Add getBinary method to StorageClient for IPFS content retrieval
- Implemented a new method `getBinary` to retrieve content from IPFS by CID, returning the full Response object.
- Added retry logic with exponential backoff for handling eventual consistency in IPFS Cluster, allowing up to 8 attempts for content retrieval.
- Enhanced documentation with usage examples and detailed parameter descriptions for better clarity.
2025-11-08 12:02:35 +02:00
anonpenguin23
a02c7474ab Enhance StorageClient upload method to support optional pinning
- Updated the upload method to accept an options parameter for controlling the pinning behavior of uploaded content.
- Default pinning behavior remains true, but can be set to false through the options.
- Improved documentation to reflect the new options parameter and its usage in examples.
2025-11-08 08:34:29 +02:00

View File

@ -35,11 +35,13 @@ export class StorageClient {
}
/**
* Upload content to IPFS and pin it.
* Upload content to IPFS and optionally pin it.
* Supports both File objects (browser) and Buffer/ReadableStream (Node.js).
*
* @param file - File to upload (File, Blob, or Buffer)
* @param name - Optional filename
* @param options - Optional upload options
* @param options.pin - Whether to pin the content (default: true). Pinning happens asynchronously on the backend.
* @returns Upload result with CID
*
* @example
@ -53,12 +55,15 @@ export class StorageClient {
* // Node.js
* const fs = require('fs');
* const fileBuffer = fs.readFileSync('image.jpg');
* const result = await client.storage.upload(fileBuffer, 'image.jpg');
* const result = await client.storage.upload(fileBuffer, 'image.jpg', { pin: true });
* ```
*/
async upload(
file: File | Blob | ArrayBuffer | Uint8Array | ReadableStream<Uint8Array>,
name?: string
name?: string,
options?: {
pin?: boolean;
}
): Promise<StorageUploadResponse> {
// Create FormData for multipart upload
const formData = new FormData();
@ -101,6 +106,10 @@ export class StorageClient {
);
}
// Add pin flag (default: true)
const shouldPin = options?.pin !== false; // Default to true
formData.append("pin", shouldPin ? "true" : "false");
return this.httpClient.uploadFile<StorageUploadResponse>(
"/v1/storage/upload",
formData,
@ -192,6 +201,64 @@ export class StorageClient {
throw lastError || new Error("Failed to retrieve content");
}
/**
* Retrieve content from IPFS by CID and return the full Response object
* Useful when you need access to response headers (e.g., content-length)
*
* @param cid - Content ID to retrieve
* @returns Response object with body stream and headers
*
* @example
* ```ts
* const response = await client.storage.getBinary(cid);
* const contentLength = response.headers.get('content-length');
* const reader = response.body.getReader();
* // ... read stream
* ```
*/
async getBinary(cid: string): Promise<Response> {
// Retry logic for content retrieval - content may not be immediately available
// after upload due to eventual consistency in IPFS Cluster
// IPFS Cluster pins can take 2-3+ seconds to complete across all nodes
const maxAttempts = 8;
let lastError: Error | null = null;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
const response = await this.httpClient.getBinary(
`/v1/storage/get/${cid}`
);
if (!response) {
throw new Error("Response is null");
}
return response;
} catch (error: any) {
lastError = error;
// Check if this is a 404 error (content not found)
const isNotFound =
error?.httpStatus === 404 ||
error?.message?.includes("not found") ||
error?.message?.includes("404");
// If it's not a 404 error, or this is the last attempt, give up
if (!isNotFound || attempt === maxAttempts) {
throw error;
}
// Wait before retrying (exponential backoff: 400ms, 800ms, 1200ms, etc.)
// This gives up to ~12 seconds total wait time, covering typical pin completion
const backoffMs = attempt * 2500;
await new Promise((resolve) => setTimeout(resolve, backoffMs));
}
}
// This should never be reached, but TypeScript needs it
throw lastError || new Error("Failed to retrieve content");
}
/**
* Unpin a CID
*