Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(loader-utils): Remove fs dependency in FileProviderFile. #2677

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class Tiles3DArchiveFileSystem extends ZipFileSystem {
* @returns - Response with file data
*/
async fetch(filename: string): Promise<Response> {
const fileProvider = await this.fileProvider;
const fileProvider = this.fileProvider;
if (!fileProvider) {
throw new Error('No data detected in the zip archive');
}
Expand All @@ -61,7 +61,7 @@ export class Tiles3DArchiveFileSystem extends ZipFileSystem {
return;
}

const fileProvider = await this.fileProvider;
const fileProvider = this.fileProvider;
if (!fileProvider) {
throw new Error('No data detected in the zip archive');
}
Expand Down
9 changes: 2 additions & 7 deletions modules/core/src/lib/fetch/read-array-buffer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
//
import {fs} from '@loaders.gl/loader-utils';

// loaders.gl, MIT license
/**
* Reads a chunk from a random access file
* @param file
Expand All @@ -9,13 +7,10 @@ import {fs} from '@loaders.gl/loader-utils';
* @returns
*/
export async function readArrayBuffer(
file: Blob | ArrayBuffer | string | number,
file: Blob | ArrayBuffer | string,
start: number,
length: number
): Promise<ArrayBuffer> {
if (typeof file === 'number') {
return await fs._readToArrayBuffer(file, start, length);
}
// TODO - we can do better for ArrayBuffer and string
if (!(file instanceof Blob)) {
file = new Blob([file]);
Expand Down
3 changes: 2 additions & 1 deletion modules/core/src/lib/fetch/read-file.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// File read
import {isBrowser, resolvePath, fs, toArrayBuffer} from '@loaders.gl/loader-utils';
import {isBrowser, resolvePath, toArrayBuffer} from '@loaders.gl/loader-utils';
import {assert} from '@loaders.gl/loader-utils';
import * as fs from 'fs';

// TODO - this is not tested
// const isDataURL = (url) => url.startsWith('data:');
Expand Down
6 changes: 4 additions & 2 deletions modules/core/src/lib/fetch/write-file.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// file write
import {isBrowser, assert, resolvePath} from '@loaders.gl/loader-utils';
import {fs, toBuffer} from '@loaders.gl/loader-utils';
import {toBuffer} from '@loaders.gl/loader-utils';
import * as fs from 'fs';
import * as fsPromises from 'fs/promises';

export async function writeFile(
filePath: string,
Expand All @@ -9,7 +11,7 @@ export async function writeFile(
): Promise<void> {
filePath = resolvePath(filePath);
if (!isBrowser) {
await fs.writeFile(filePath, toBuffer(arrayBufferOrString), {flag: 'w'});
await fsPromises.writeFile(filePath, toBuffer(arrayBufferOrString), {flag: 'w'});
}
assert(false);
}
Expand Down
17 changes: 6 additions & 11 deletions modules/loader-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,23 +110,12 @@ export {promisify1, promisify2} from './lib/node/promisify';
import * as path from './lib/path-utils/path';
export {path};

// Use instead of importing 'fs' to avoid node dependencies`
import * as fs from './lib/node/fs';
export {fs};

// Use instead of importing 'stream' to avoid node dependencies`
import * as stream from './lib/node/stream';
export {stream};

// EXPERIMENTAL: FILE SYSTEMS

export type {FileProvider} from './lib/file-provider/file-provider';
export {isFileProvider} from './lib/file-provider/file-provider';

export {FileHandle} from './lib/file-provider/file-handle';
export {FileHandleFile} from './lib/file-provider/file-handle-file';
export {DataViewFile} from './lib/file-provider/data-view-file';

export type {ReadableFile, WritableFile, Stat} from './lib/files/file';
export {BlobFile} from './lib/files/blob-file';
export {HttpFile} from './lib/files/http-file';
Expand All @@ -135,6 +124,12 @@ export {NodeFileFacade as NodeFile} from './lib/files/node-file-facade';
export type {FileSystem, RandomAccessFileSystem} from './lib/filesystems/filesystem';
export {NodeFileSystemFacade as NodeFilesystem} from './lib/filesystems/node-filesystem-facade';

// TODO - replace with ReadableFile
export type {FileProvider} from './lib/file-provider/file-provider';
export {isFileProvider} from './lib/file-provider/file-provider';
export {FileHandleFile} from './lib/file-provider/file-handle-file';
export {DataViewFile} from './lib/file-provider/data-view-file';

// EXPERIMENTAL: DATA SOURCES
export type {Service} from './service-types';

Expand Down
5 changes: 4 additions & 1 deletion modules/loader-utils/src/lib/file-provider/data-view-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ const toNumber = (bigint: bigint) => {
return Number(bigint);
};

/** Provides file data using DataView */
/**
* Provides file data using DataView
* @deprecated - will be replaced with ReadableFile
*/
export class DataViewFile implements FileProvider {
/** The DataView from which data is provided */
private file: DataView;
Expand Down
72 changes: 28 additions & 44 deletions modules/loader-utils/src/lib/file-provider/file-handle-file.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,37 @@
// loaders.gl, MIT license

import {FileProvider} from './file-provider';
import {FileHandle} from './file-handle';
import {resolvePath} from '../path-utils/file-aliases';
import {NodeFileFacade as NodeFile} from '../files/node-file-facade';

/**
* Provides file data using node fs library
* @deprecated - will be replaced with ReadableFile
*/
export class FileHandleFile implements FileProvider {
/**
* Returns a new copy of FileHandleFile
* @param path The path to the file in file system
*/
static async from(path: string): Promise<FileHandleFile> {
path = resolvePath(path);
const fileDescriptor = await FileHandle.open(path);
return new FileHandleFile(fileDescriptor, fileDescriptor.stat.size);
}
/** The FileHandle from which data is provided */
private file: NodeFile;

/**
* The FileHandle from which data is provided
*/
private fileDescriptor: FileHandle;

/**
* The file length in bytes
*/
/** The file length in bytes */
private size: bigint;

private constructor(fileDescriptor: FileHandle, size: bigint) {
this.fileDescriptor = fileDescriptor;
this.size = size;
/** Create a new FileHandleFile */
constructor(path: string) {
this.file = new NodeFile(path, 'r');
this.size = this.file.bigsize;
}

/** Close file */
async destroy(): Promise<void> {
await this.fileDescriptor.close();
await this.file.close();
}

/**
* Gets an unsigned 8-bit integer at the specified byte offset from the start of the file.
* @param offset The offset, in bytes, from the start of the file where to read the data.
*/
async getUint8(offset: bigint): Promise<number> {
const val = new Uint8Array(
(await this.fileDescriptor.read(Buffer.alloc(1), 0, 1, offset)).buffer.buffer
).at(0);
async getUint8(offset: number | bigint): Promise<number> {
const arrayBuffer = await this.file.read(offset, 1);
const val = new Uint8Array(arrayBuffer).at(0);
if (val === undefined) {
throw new Error('something went wrong');
}
Expand All @@ -54,10 +42,9 @@ export class FileHandleFile implements FileProvider {
* Gets an unsigned 16-bit integer at the specified byte offset from the start of the file.
* @param offset The offset, in bytes, from the start of the file where to read the data.
*/
async getUint16(offset: bigint): Promise<number> {
const val = new Uint16Array(
(await this.fileDescriptor.read(Buffer.alloc(2), 0, 2, offset)).buffer.buffer
).at(0);
async getUint16(offset: number | bigint): Promise<number> {
const arrayBuffer = await this.file.read(offset, 2);
const val = new Uint16Array(arrayBuffer).at(0);
if (val === undefined) {
throw new Error('something went wrong');
}
Expand All @@ -68,10 +55,9 @@ export class FileHandleFile implements FileProvider {
* Gets an unsigned 32-bit integer at the specified byte offset from the start of the file.
* @param offset The offset, in bytes, from the start of the file where to read the data.
*/
async getUint32(offset: bigint): Promise<number> {
const val = new Uint32Array(
(await this.fileDescriptor.read(Buffer.alloc(4), 0, 4, offset)).buffer.buffer
).at(0);
async getUint32(offset: number | bigint): Promise<number> {
const arrayBuffer = await this.file.read(offset, 4);
const val = new Uint32Array(arrayBuffer).at(0);
if (val === undefined) {
throw new Error('something went wrong');
}
Expand All @@ -82,10 +68,9 @@ export class FileHandleFile implements FileProvider {
* Gets an unsigned 32-bit integer at the specified byte offset from the start of the file.
* @param offset The offset, in bytes, from the start of the file where to read the data.
*/
async getBigUint64(offset: bigint): Promise<bigint> {
const val = new BigInt64Array(
(await this.fileDescriptor.read(Buffer.alloc(8), 0, 8, offset)).buffer.buffer
).at(0);
async getBigUint64(offset: number | bigint): Promise<bigint> {
const arrayBuffer = await this.file.read(offset, 8);
const val = new BigInt64Array(arrayBuffer).at(0);
if (val === undefined) {
throw new Error('something went wrong');
}
Expand All @@ -94,17 +79,16 @@ export class FileHandleFile implements FileProvider {

/**
* returns an ArrayBuffer whose contents are a copy of this file bytes from startOffset, inclusive, up to endOffset, exclusive.
* @param startOffsset The offset, in byte, from the start of the file where to start reading the data.
* @param startOffset The offset, in byte, from the start of the file where to start reading the data.
* @param endOffset The offset, in bytes, from the start of the file where to end reading the data.
*/
async slice(startOffsset: bigint, endOffset: bigint): Promise<ArrayBuffer> {
const bigLength = endOffset - startOffsset;
async slice(startOffset: bigint, endOffset: bigint): Promise<ArrayBuffer> {
const bigLength = endOffset - startOffset;
if (bigLength > Number.MAX_SAFE_INTEGER) {
throw new Error('too big slice');
}
const length = Number(bigLength);
return (await this.fileDescriptor.read(Buffer.alloc(length), 0, length, startOffsset)).buffer
.buffer;
return await this.file.read(startOffset, length);
}

/**
Expand Down
79 changes: 0 additions & 79 deletions modules/loader-utils/src/lib/file-provider/file-handle.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* Interface for providing file data
* @deprecated - will be replaced with ReadableFile
*/
export interface FileProvider {
/**
Expand Down
3 changes: 3 additions & 0 deletions modules/loader-utils/src/lib/files/blob-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import {ReadableFile} from './file';
export class BlobFile implements ReadableFile {
readonly handle: Blob;
readonly size: number;
readonly bigsize: bigint;
readonly url: string;

constructor(blob: Blob | File | ArrayBuffer) {
this.handle = blob instanceof ArrayBuffer ? new Blob([blob]) : blob;
this.size = blob instanceof ArrayBuffer ? blob.byteLength : blob.size;
this.bigsize = BigInt(this.size);
this.url = blob instanceof File ? blob.name : '';
}

Expand All @@ -18,6 +20,7 @@ export class BlobFile implements ReadableFile {
async stat() {
return {
size: this.handle.size,
bigsize: BigInt(this.handle.size),
isDirectory: false
};
}
Expand Down
18 changes: 13 additions & 5 deletions modules/loader-utils/src/lib/files/file.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
// loaders.gl, MIT license

export type Stat = {
size: number;
bigsize: bigint;
isDirectory: boolean;
};

export interface ReadableFile {
/** The underlying file handle (Blob, Node.js file descriptor etc) */
handle: unknown;
readonly handle: unknown;
/** Length of file in bytes, if available */
size: number;
readonly size: number;
/** Length of file in bytes, if available */
readonly bigsize: bigint;
/** Url, if available */
readonly url: string;

/** Read data */
read(start?: number, end?: number): Promise<ArrayBuffer>;
read(start?: number | bigint, length?: number): Promise<ArrayBuffer>;
/** Read data */
fetchRange?(offset: number, length: number, signal?: AbortSignal): Promise<Response>;
fetchRange?(offset: number | bigint, length: number, signal?: AbortSignal): Promise<Response>;
/** Get information about file */
stat?(): Promise<Stat>;
/** Close the file */
Expand All @@ -21,7 +29,7 @@ export interface ReadableFile {
export interface WritableFile {
handle: unknown;
/** Write to file. The number of bytes written will be returned */
write: (arrayBuffer: ArrayBuffer, offset?: number, length?: number) => Promise<number>;
write: (arrayBuffer: ArrayBuffer, offset?: number | bigint, length?: number) => Promise<number>;
/** Get information about the file */
stat?(): Promise<Stat>;
/** Close the file */
Expand Down
Loading
Loading