@@ -120,8 +120,13 @@ export type CommitParams = {
120120 */
121121 fetch ?: typeof fetch ;
122122 abortSignal ?: AbortSignal ;
123- // Credentials are optional due to custom fetch functions or cookie auth
123+ /**
124+ * @default true
125+ *
126+ * Use xet protocol: https://huggingface.co/blog/xet-on-the-hub to upload, rather than a basic S3 PUT
127+ */
124128 useXet ?: boolean ;
129+ // Credentials are optional due to custom fetch functions or cookie auth
125130} & Partial < CredentialsParams > ;
126131
127132export interface CommitOutput {
@@ -165,24 +170,7 @@ export async function* commitIter(params: CommitParams): AsyncGenerator<CommitPr
165170 const repoId = toRepoId ( params . repo ) ;
166171 yield { event : "phase" , phase : "preuploading" } ;
167172
168- let useXet = params . useXet ;
169- if ( useXet ) {
170- const info = await ( params . fetch ?? fetch ) (
171- `${ params . hubUrl ?? HUB_URL } /api/${ repoId . type } s/${ repoId . name } ?expand[]=xetEnabled` ,
172- {
173- headers : {
174- ...( accessToken && { Authorization : `Bearer ${ accessToken } ` } ) ,
175- } ,
176- }
177- ) ;
178-
179- if ( ! info . ok ) {
180- throw await createApiError ( info ) ;
181- }
182-
183- const data = await info . json ( ) ;
184- useXet = ! ! data . xetEnabled ;
185- }
173+ let useXet = params . useXet ?? true ;
186174
187175 const lfsShas = new Map < string , string | null > ( ) ;
188176
@@ -206,10 +194,6 @@ export async function* commitIter(params: CommitParams): AsyncGenerator<CommitPr
206194 const allOperations = (
207195 await Promise . all (
208196 params . operations . map ( async ( operation ) => {
209- if ( operation . operation === "edit" && ! useXet ) {
210- throw new Error ( "Edit operation is not supported when Xet is disabled" ) ;
211- }
212-
213197 if ( operation . operation === "edit" ) {
214198 // Convert EditFile operation to a file operation with SplicedBlob
215199 const splicedBlob = SplicedBlob . create (
@@ -325,7 +309,7 @@ export async function* commitIter(params: CommitParams): AsyncGenerator<CommitPr
325309 const payload : ApiLfsBatchRequest = {
326310 operation : "upload" ,
327311 // multipart is a custom protocol for HF
328- transfers : [ "basic" , "multipart" ] ,
312+ transfers : [ "basic" , "multipart" , ... ( useXet ? [ "xet" as const ] : [ ] ) ] ,
329313 hash_algo : "sha_256" ,
330314 ...( ! params . isPullRequest && {
331315 ref : {
@@ -363,6 +347,10 @@ export async function* commitIter(params: CommitParams): AsyncGenerator<CommitPr
363347
364348 const shaToOperation = new Map ( operations . map ( ( op , i ) => [ shas [ i ] , op ] ) ) ;
365349
350+ if ( useXet && json . transfer !== "xet" ) {
351+ useXet = false ;
352+ }
353+
366354 if ( useXet ) {
367355 // First get all the files that are already uploaded out of the way
368356 for ( const obj of json . objects ) {
@@ -396,6 +384,7 @@ export async function* commitIter(params: CommitParams): AsyncGenerator<CommitPr
396384 }
397385 abortSignal ?. throwIfAborted ( ) ;
398386
387+ // todo: load writeTokenUrl from obj.actions.upload.header or obj.actions.upload.href
399388 yield { content : op . content , path : op . path , sha256 : obj . oid } ;
400389 }
401390 } ) ( ) ;
0 commit comments