11/**
2- * Synapse Core - Curio HTTP Operations
2+ * Synapse Core - Service Provider HTTP Operations
33 *
44 * @example
55 * ```ts
6- * import * as Curio from '@filoz/synapse-core/curio '
6+ * import * as SP from '@filoz/synapse-core/sp '
77 * ```
88 *
99 * @packageDocumentation
1010 */
1111
12- import { HttpError , request } from 'iso-web/http'
13- import type { Simplify as Curio } from 'type-fest'
14- import type { Address , Hex } from 'viem'
12+ import { HttpError , request , TimeoutError } from 'iso-web/http'
13+ import type { Simplify } from 'type-fest'
14+ import { type Address , type Hex , isHex } from 'viem'
1515import {
1616 AddPiecesError ,
1717 CreateDataSetError ,
1818 FindPieceError ,
1919 GetDataSetError ,
20- InvalidPDPLocationHeaderError ,
20+ LocationHeaderError ,
2121 PollDataSetCreationStatusError ,
2222 PollForAddPiecesStatusError ,
2323 PostPieceError ,
@@ -27,10 +27,15 @@ import type { PieceCID } from './piece.ts'
2727import * as Piece from './piece.ts'
2828import { createPieceUrl } from './utils/piece-url.ts'
2929
30- const TIMEOUT = 180000
31- const RETRIES = Infinity
32- const FACTOR = 1
33- const MIN_TIMEOUT = 4000 // interval between retries in milliseconds
30+ let TIMEOUT = 180000
31+ export const RETRIES = Infinity
32+ export const FACTOR = 1
33+ export const MIN_TIMEOUT = 4000 // interval between retries in milliseconds
34+
35+ // Just for testing purposes
36+ export function setTimeout ( timeout : number ) {
37+ TIMEOUT = timeout
38+ }
3439
3540/**
3641 * The options for the create data set on PDP API.
@@ -76,14 +81,14 @@ export async function createDataSet(options: PDPCreateDataSetOptions) {
7681 throw response . error
7782 }
7883
79- const location = response . result . headers . get ( 'Location' ) ?? ''
80- const hash = location . split ( '/' ) . pop ( )
81- if ( ! hash ) {
82- throw new InvalidPDPLocationHeaderError ( location )
84+ const location = response . result . headers . get ( 'Location' )
85+ const hash = location ? .split ( '/' ) . pop ( )
86+ if ( ! location || ! hash || ! isHex ( hash ) ) {
87+ throw new LocationHeaderError ( location )
8388 }
8489
8590 return {
86- hash : hash as `0x${ string } ` ,
91+ txHash : hash ,
8792 statusUrl : new URL ( location , options . endpoint ) . toString ( ) ,
8893 }
8994}
@@ -156,12 +161,14 @@ export type GetDataSetOptions = {
156161export type GetDataSetResponse = {
157162 id : number
158163 nextChallengeEpoch : number
159- pieces : CurioPiece [ ]
164+ pieces : SPPiece [ ]
160165}
161166
162- export type CurioPiece = {
167+ export type SPPiece = {
163168 pieceCid : string
164169 pieceId : number
170+ subPieceCid : string
171+ subPieceOffset : number
165172}
166173
167174/**
@@ -184,6 +191,7 @@ export async function getDataSet(options: GetDataSetOptions) {
184191 }
185192 throw response . error
186193 }
194+
187195 return response . result
188196}
189197
@@ -195,8 +203,8 @@ export type GetPiecesForDataSetOptions = {
195203 cdn : boolean
196204}
197205
198- export type CurioPieceWithUrl = Curio <
199- CurioPiece & {
206+ export type SPPieceWithUrl = Simplify <
207+ SPPiece & {
200208 pieceUrl : string
201209 }
202210>
@@ -254,7 +262,6 @@ export async function uploadPiece(options: UploadPieceOptions) {
254262 headers : {
255263 'Content-Type' : 'application/json' ,
256264 } ,
257- timeout : TIMEOUT ,
258265 } )
259266
260267 if ( response . error ) {
@@ -272,10 +279,10 @@ export async function uploadPiece(options: UploadPieceOptions) {
272279 }
273280
274281 // Extract upload ID from Location header
275- const location = response . result . headers . get ( 'Location' ) ?? ''
276- const uploadUuid = location . split ( '/' ) . pop ( )
277- if ( uploadUuid == null ) {
278- throw new InvalidPDPLocationHeaderError ( location )
282+ const location = response . result . headers . get ( 'Location' )
283+ const uploadUuid = location ? .split ( '/' ) . pop ( )
284+ if ( ! location || ! uploadUuid ) {
285+ throw new LocationHeaderError ( location )
279286 }
280287
281288 const uploadResponse = await request . put ( new URL ( `pdp/piece/upload/${ uploadUuid } ` , options . endpoint ) , {
@@ -284,6 +291,7 @@ export async function uploadPiece(options: UploadPieceOptions) {
284291 'Content-Type' : 'application/octet-stream' ,
285292 'Content-Length' : options . data . length . toString ( ) ,
286293 } ,
294+ timeout : false ,
287295 } )
288296
289297 if ( uploadResponse . error ) {
@@ -319,22 +327,21 @@ export async function findPiece(options: FindPieceOptions): Promise<PieceCID> {
319327 const params = new URLSearchParams ( { pieceCid : pieceCid . toString ( ) } )
320328
321329 const response = await request . json . get < { pieceCid : string } > ( new URL ( `pdp/piece?${ params . toString ( ) } ` , endpoint ) , {
322- onResponse ( response ) {
323- if ( ! response . ok ) {
324- throw new Error ( `Piece not found: ${ pieceCid . toString ( ) } ` )
325- }
326- } ,
327330 retry : {
331+ statusCodes : [ 404 ] ,
328332 retries : RETRIES ,
329333 factor : FACTOR ,
330334 } ,
331335 timeout : TIMEOUT ,
332336 } )
333337
334338 if ( response . error ) {
335- if ( response . error instanceof HttpError ) {
339+ if ( HttpError . is ( response . error ) ) {
336340 throw new FindPieceError ( await response . error . response . text ( ) )
337341 }
342+ if ( TimeoutError . is ( response . error ) ) {
343+ throw new FindPieceError ( 'Timeout waiting for piece to be found' )
344+ }
338345 throw response . error
339346 }
340347 const data = response . result
@@ -344,7 +351,6 @@ export async function findPiece(options: FindPieceOptions): Promise<PieceCID> {
344351export type AddPiecesOptions = {
345352 endpoint : string
346353 dataSetId : bigint
347- clientDataSetId : bigint
348354 nextPieceId : bigint
349355 pieces : PieceCID [ ]
350356 extraData : Hex
@@ -358,7 +364,6 @@ export type AddPiecesOptions = {
358364 * @param options - The options for the add pieces.
359365 * @param options.endpoint - The endpoint of the PDP API.
360366 * @param options.dataSetId - The ID of the data set.
361- * @param options.clientDataSetId - The ID of the client data set.
362367 * @param options.nextPieceId - The next piece ID.
363368 * @param options.pieces - The pieces to add.
364369 * @param options.extraData - The extra data for the add pieces.
@@ -386,10 +391,10 @@ export async function addPieces(options: AddPiecesOptions) {
386391 }
387392 throw response . error
388393 }
389- const location = response . result . headers . get ( 'Location' ) ?? ''
390- const txHash = location . split ( '/' ) . pop ( )
391- if ( ! txHash ) {
392- throw new InvalidPDPLocationHeaderError ( location )
394+ const location = response . result . headers . get ( 'Location' )
395+ const txHash = location ? .split ( '/' ) . pop ( )
396+ if ( ! location || ! txHash || ! isHex ( txHash ) ) {
397+ throw new LocationHeaderError ( location )
393398 }
394399
395400 return {
0 commit comments