feat: add filepicker package
This commit is contained in:
75
packages/filepicker/src/Streaming/StreamingReader.ts
Normal file
75
packages/filepicker/src/Streaming/StreamingReader.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { FileReaderInterface } from './../Interface/FileReader'
|
||||
import { ByteChunker } from '../Chunker/ByteChunker'
|
||||
import { OnChunkCallback, FileSelectionResponse } from '../types'
|
||||
|
||||
interface StreamingFileReaderInterface {
|
||||
getFilesFromHandles(handles: FileSystemFileHandle[]): Promise<File[]>
|
||||
}
|
||||
|
||||
/**
|
||||
* The File System Access API File Picker
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API
|
||||
*/
|
||||
export const StreamingFileReader: StreamingFileReaderInterface & FileReaderInterface = {
|
||||
getFilesFromHandles,
|
||||
selectFiles,
|
||||
readFile,
|
||||
available,
|
||||
maximumFileSize,
|
||||
}
|
||||
|
||||
function maximumFileSize(): number | undefined {
|
||||
return undefined
|
||||
}
|
||||
|
||||
function getFilesFromHandles(handles: FileSystemFileHandle[]): Promise<File[]> {
|
||||
return Promise.all(handles.map((handle) => handle.getFile()))
|
||||
}
|
||||
|
||||
async function selectFiles(): Promise<File[]> {
|
||||
let selectedFilesHandles: FileSystemFileHandle[]
|
||||
try {
|
||||
selectedFilesHandles = await window.showOpenFilePicker({ multiple: true })
|
||||
} catch (error) {
|
||||
selectedFilesHandles = []
|
||||
}
|
||||
return getFilesFromHandles(selectedFilesHandles)
|
||||
}
|
||||
|
||||
async function readFile(
|
||||
file: File,
|
||||
minimumChunkSize: number,
|
||||
onChunk: OnChunkCallback,
|
||||
): Promise<FileSelectionResponse> {
|
||||
const byteChunker = new ByteChunker(minimumChunkSize, onChunk)
|
||||
const stream = file.stream() as unknown as ReadableStream
|
||||
const reader = stream.getReader()
|
||||
|
||||
let previousChunk: Uint8Array
|
||||
|
||||
const processChunk = async (result: ReadableStreamDefaultReadResult<Uint8Array>): Promise<void> => {
|
||||
if (result.done) {
|
||||
await byteChunker.addBytes(previousChunk, true)
|
||||
return
|
||||
}
|
||||
|
||||
if (previousChunk) {
|
||||
await byteChunker.addBytes(previousChunk, false)
|
||||
}
|
||||
|
||||
previousChunk = result.value
|
||||
|
||||
return reader.read().then(processChunk)
|
||||
}
|
||||
|
||||
await reader.read().then(processChunk)
|
||||
|
||||
return {
|
||||
name: file.name,
|
||||
mimeType: file.type,
|
||||
}
|
||||
}
|
||||
|
||||
function available(): boolean {
|
||||
return window.showOpenFilePicker != undefined
|
||||
}
|
||||
Reference in New Issue
Block a user