feat(types): extend FileSystemHandle and optimize imports for consistency
- Added `getFile` method to `FileSystemHandle` interface for enhanced TypeScript compatibility with File System Access API. - Improved maintainability by reformatting and aligning imports in `brainyData.ts`. - Standardized spacing and indentation across structured comments and interface fields. Purpose: Improve TypeScript support for file system operations and enhance code readability with consistent formatting and import management.
This commit is contained in:
parent
7cec5fb90a
commit
e1632523b4
4 changed files with 2745 additions and 2723 deletions
|
|
@ -1,333 +1,331 @@
|
||||||
import {
|
import {
|
||||||
AugmentationType,
|
AugmentationType,
|
||||||
IMemoryAugmentation,
|
IMemoryAugmentation,
|
||||||
AugmentationResponse
|
AugmentationResponse
|
||||||
} from '../types/augmentations.js'
|
} from '../types/augmentations.js'
|
||||||
import { StorageAdapter, Vector } from '../coreTypes.js'
|
import {StorageAdapter, Vector} from '../coreTypes.js'
|
||||||
import { MemoryStorage } from '../storage/opfsStorage.js'
|
import {MemoryStorage, FileSystemStorage, OPFSStorage} from '../storage/storageFactory.js'
|
||||||
import { FileSystemStorage } from '../storage/fileSystemStorage.js'
|
import {cosineDistance} from '../utils/distance.js'
|
||||||
import { OPFSStorage } from '../storage/opfsStorage.js'
|
|
||||||
import { cosineDistance } from '../utils/distance.js'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for memory augmentations that wrap a StorageAdapter
|
* Base class for memory augmentations that wrap a StorageAdapter
|
||||||
*/
|
*/
|
||||||
abstract class BaseMemoryAugmentation implements IMemoryAugmentation {
|
abstract class BaseMemoryAugmentation implements IMemoryAugmentation {
|
||||||
readonly name: string
|
readonly name: string
|
||||||
readonly description: string = 'Base memory augmentation'
|
readonly description: string = 'Base memory augmentation'
|
||||||
enabled: boolean = true
|
enabled: boolean = true
|
||||||
protected storage: StorageAdapter
|
protected storage: StorageAdapter
|
||||||
protected isInitialized = false
|
protected isInitialized = false
|
||||||
|
|
||||||
constructor(name: string, storage: StorageAdapter) {
|
constructor(name: string, storage: StorageAdapter) {
|
||||||
this.name = name
|
this.name = name
|
||||||
this.storage = storage
|
this.storage = storage
|
||||||
}
|
|
||||||
|
|
||||||
async initialize(): Promise<void> {
|
|
||||||
if (this.isInitialized) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
async initialize(): Promise<void> {
|
||||||
await this.storage.init()
|
if (this.isInitialized) {
|
||||||
this.isInitialized = true
|
return
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to initialize ${this.name}:`, error)
|
|
||||||
throw new Error(`Failed to initialize ${this.name}: ${error}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async shutDown(): Promise<void> {
|
|
||||||
this.isInitialized = false
|
|
||||||
}
|
|
||||||
|
|
||||||
async getStatus(): Promise<'active' | 'inactive' | 'error'> {
|
|
||||||
return this.isInitialized ? 'active' : 'inactive'
|
|
||||||
}
|
|
||||||
|
|
||||||
async storeData(
|
|
||||||
key: string,
|
|
||||||
data: unknown,
|
|
||||||
options?: Record<string, unknown>
|
|
||||||
): Promise<AugmentationResponse<boolean>> {
|
|
||||||
await this.ensureInitialized()
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.storage.saveMetadata(key, data)
|
|
||||||
return { success: true, data: true }
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to store data for key ${key}:`, error)
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
data: false,
|
|
||||||
error: `Failed to store data: ${error}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async retrieveData(
|
|
||||||
key: string,
|
|
||||||
options?: Record<string, unknown>
|
|
||||||
): Promise<AugmentationResponse<unknown>> {
|
|
||||||
await this.ensureInitialized()
|
|
||||||
|
|
||||||
try {
|
|
||||||
const data = await this.storage.getMetadata(key)
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
data
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to retrieve data for key ${key}:`, error)
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
data: null,
|
|
||||||
error: `Failed to retrieve data: ${error}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateData(
|
|
||||||
key: string,
|
|
||||||
data: unknown,
|
|
||||||
options?: Record<string, unknown>
|
|
||||||
): Promise<AugmentationResponse<boolean>> {
|
|
||||||
await this.ensureInitialized()
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.storage.saveMetadata(key, data)
|
|
||||||
return { success: true, data: true }
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to update data for key ${key}:`, error)
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
data: false,
|
|
||||||
error: `Failed to update data: ${error}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteData(
|
|
||||||
key: string,
|
|
||||||
options?: Record<string, unknown>
|
|
||||||
): Promise<AugmentationResponse<boolean>> {
|
|
||||||
await this.ensureInitialized()
|
|
||||||
|
|
||||||
try {
|
|
||||||
// There's no direct deleteMetadata method, so we save null
|
|
||||||
await this.storage.saveMetadata(key, null)
|
|
||||||
return { success: true, data: true }
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to delete data for key ${key}:`, error)
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
data: false,
|
|
||||||
error: `Failed to delete data: ${error}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async listDataKeys(
|
|
||||||
pattern?: string,
|
|
||||||
options?: Record<string, unknown>
|
|
||||||
): Promise<AugmentationResponse<string[]>> {
|
|
||||||
// This is a limitation of the current StorageAdapter interface
|
|
||||||
// It doesn't provide a way to list all metadata keys
|
|
||||||
// We could implement this in the future by extending the StorageAdapter interface
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
data: [],
|
|
||||||
error: 'listDataKeys is not supported by this storage adapter'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches for data in the storage using vector similarity.
|
|
||||||
* Implements the findNearest functionality by calculating distances client-side.
|
|
||||||
* @param query The query vector or data to search for
|
|
||||||
* @param k Number of results to return (default: 10)
|
|
||||||
* @param options Optional search options
|
|
||||||
*/
|
|
||||||
async search(
|
|
||||||
query: unknown,
|
|
||||||
k: number = 10,
|
|
||||||
options?: Record<string, unknown>
|
|
||||||
): Promise<AugmentationResponse<Array<{
|
|
||||||
id: string;
|
|
||||||
score: number;
|
|
||||||
data: unknown;
|
|
||||||
}>>> {
|
|
||||||
await this.ensureInitialized()
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Check if query is a vector
|
|
||||||
let queryVector: Vector
|
|
||||||
|
|
||||||
if (Array.isArray(query) && query.every(item => typeof item === 'number')) {
|
|
||||||
queryVector = query as Vector
|
|
||||||
} else {
|
|
||||||
// If query is not a vector, we can't perform vector search
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
data: [],
|
|
||||||
error: 'Query must be a vector (array of numbers) for vector search'
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Get all nodes from storage
|
try {
|
||||||
const nodes = await this.storage.getAllNouns()
|
await this.storage.init()
|
||||||
|
this.isInitialized = true
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to initialize ${this.name}:`, error)
|
||||||
|
throw new Error(`Failed to initialize ${this.name}: ${error}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate distances and prepare results
|
async shutDown(): Promise<void> {
|
||||||
const results: Array<{
|
this.isInitialized = false
|
||||||
|
}
|
||||||
|
|
||||||
|
async getStatus(): Promise<'active' | 'inactive' | 'error'> {
|
||||||
|
return this.isInitialized ? 'active' : 'inactive'
|
||||||
|
}
|
||||||
|
|
||||||
|
async storeData(
|
||||||
|
key: string,
|
||||||
|
data: unknown,
|
||||||
|
options?: Record<string, unknown>
|
||||||
|
): Promise<AugmentationResponse<boolean>> {
|
||||||
|
await this.ensureInitialized()
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.storage.saveMetadata(key, data)
|
||||||
|
return {success: true, data: true}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to store data for key ${key}:`, error)
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
data: false,
|
||||||
|
error: `Failed to store data: ${error}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async retrieveData(
|
||||||
|
key: string,
|
||||||
|
options?: Record<string, unknown>
|
||||||
|
): Promise<AugmentationResponse<unknown>> {
|
||||||
|
await this.ensureInitialized()
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await this.storage.getMetadata(key)
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to retrieve data for key ${key}:`, error)
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
data: null,
|
||||||
|
error: `Failed to retrieve data: ${error}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateData(
|
||||||
|
key: string,
|
||||||
|
data: unknown,
|
||||||
|
options?: Record<string, unknown>
|
||||||
|
): Promise<AugmentationResponse<boolean>> {
|
||||||
|
await this.ensureInitialized()
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.storage.saveMetadata(key, data)
|
||||||
|
return {success: true, data: true}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to update data for key ${key}:`, error)
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
data: false,
|
||||||
|
error: `Failed to update data: ${error}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteData(
|
||||||
|
key: string,
|
||||||
|
options?: Record<string, unknown>
|
||||||
|
): Promise<AugmentationResponse<boolean>> {
|
||||||
|
await this.ensureInitialized()
|
||||||
|
|
||||||
|
try {
|
||||||
|
// There's no direct deleteMetadata method, so we save null
|
||||||
|
await this.storage.saveMetadata(key, null)
|
||||||
|
return {success: true, data: true}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to delete data for key ${key}:`, error)
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
data: false,
|
||||||
|
error: `Failed to delete data: ${error}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async listDataKeys(
|
||||||
|
pattern?: string,
|
||||||
|
options?: Record<string, unknown>
|
||||||
|
): Promise<AugmentationResponse<string[]>> {
|
||||||
|
// This is a limitation of the current StorageAdapter interface
|
||||||
|
// It doesn't provide a way to list all metadata keys
|
||||||
|
// We could implement this in the future by extending the StorageAdapter interface
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
data: [],
|
||||||
|
error: 'listDataKeys is not supported by this storage adapter'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for data in the storage using vector similarity.
|
||||||
|
* Implements the findNearest functionality by calculating distances client-side.
|
||||||
|
* @param query The query vector or data to search for
|
||||||
|
* @param k Number of results to return (default: 10)
|
||||||
|
* @param options Optional search options
|
||||||
|
*/
|
||||||
|
async search(
|
||||||
|
query: unknown,
|
||||||
|
k: number = 10,
|
||||||
|
options?: Record<string, unknown>
|
||||||
|
): Promise<AugmentationResponse<Array<{
|
||||||
id: string;
|
id: string;
|
||||||
score: number;
|
score: number;
|
||||||
data: unknown;
|
data: unknown;
|
||||||
}> = []
|
}>>> {
|
||||||
|
await this.ensureInitialized()
|
||||||
|
|
||||||
for (const node of nodes) {
|
try {
|
||||||
// Skip nodes that don't have a vector
|
// Check if query is a vector
|
||||||
if (!node.vector || !Array.isArray(node.vector)) {
|
let queryVector: Vector
|
||||||
continue
|
|
||||||
|
if (Array.isArray(query) && query.every(item => typeof item === 'number')) {
|
||||||
|
queryVector = query as Vector
|
||||||
|
} else {
|
||||||
|
// If query is not a vector, we can't perform vector search
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
data: [],
|
||||||
|
error: 'Query must be a vector (array of numbers) for vector search'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all nodes from storage
|
||||||
|
const nodes = await this.storage.getAllNouns()
|
||||||
|
|
||||||
|
// Calculate distances and prepare results
|
||||||
|
const results: Array<{
|
||||||
|
id: string;
|
||||||
|
score: number;
|
||||||
|
data: unknown;
|
||||||
|
}> = []
|
||||||
|
|
||||||
|
for (const node of nodes) {
|
||||||
|
// Skip nodes that don't have a vector
|
||||||
|
if (!node.vector || !Array.isArray(node.vector)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get metadata for the node
|
||||||
|
const metadata = await this.storage.getMetadata(node.id)
|
||||||
|
|
||||||
|
// Calculate distance between query vector and node vector
|
||||||
|
const distance = cosineDistance(queryVector, node.vector)
|
||||||
|
|
||||||
|
// Convert distance to similarity score (1 - distance for cosine)
|
||||||
|
// This way higher scores are better (more similar)
|
||||||
|
const score = 1 - distance
|
||||||
|
|
||||||
|
results.push({
|
||||||
|
id: node.id,
|
||||||
|
score,
|
||||||
|
data: metadata
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort results by score (descending) and take top k
|
||||||
|
results.sort((a, b) => b.score - a.score)
|
||||||
|
const topResults = results.slice(0, k)
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: topResults
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to search in storage:`, error)
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
data: [],
|
||||||
|
error: `Failed to search in storage: ${error}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get metadata for the node
|
|
||||||
const metadata = await this.storage.getMetadata(node.id)
|
|
||||||
|
|
||||||
// Calculate distance between query vector and node vector
|
|
||||||
const distance = cosineDistance(queryVector, node.vector)
|
|
||||||
|
|
||||||
// Convert distance to similarity score (1 - distance for cosine)
|
|
||||||
// This way higher scores are better (more similar)
|
|
||||||
const score = 1 - distance
|
|
||||||
|
|
||||||
results.push({
|
|
||||||
id: node.id,
|
|
||||||
score,
|
|
||||||
data: metadata
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort results by score (descending) and take top k
|
|
||||||
results.sort((a, b) => b.score - a.score)
|
|
||||||
const topResults = results.slice(0, k)
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
data: topResults
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to search in storage:`, error)
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
data: [],
|
|
||||||
error: `Failed to search in storage: ${error}`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected async ensureInitialized(): Promise<void> {
|
protected async ensureInitialized(): Promise<void> {
|
||||||
if (!this.isInitialized) {
|
if (!this.isInitialized) {
|
||||||
await this.initialize()
|
await this.initialize()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory augmentation that uses in-memory storage
|
* Memory augmentation that uses in-memory storage
|
||||||
*/
|
*/
|
||||||
export class MemoryStorageAugmentation extends BaseMemoryAugmentation {
|
export class MemoryStorageAugmentation extends BaseMemoryAugmentation {
|
||||||
readonly description = 'Memory augmentation that stores data in memory'
|
readonly description = 'Memory augmentation that stores data in memory'
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
constructor(name: string) {
|
constructor(name: string) {
|
||||||
super(name, new MemoryStorage())
|
super(name, new MemoryStorage())
|
||||||
}
|
}
|
||||||
|
|
||||||
getType(): AugmentationType {
|
getType(): AugmentationType {
|
||||||
return AugmentationType.MEMORY
|
return AugmentationType.MEMORY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory augmentation that uses file system storage
|
* Memory augmentation that uses file system storage
|
||||||
*/
|
*/
|
||||||
export class FileSystemStorageAugmentation extends BaseMemoryAugmentation {
|
export class FileSystemStorageAugmentation extends BaseMemoryAugmentation {
|
||||||
readonly description = 'Memory augmentation that stores data in the file system'
|
readonly description = 'Memory augmentation that stores data in the file system'
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
constructor(name: string, rootDirectory?: string) {
|
constructor(name: string, rootDirectory?: string) {
|
||||||
super(name, new FileSystemStorage(rootDirectory))
|
super(name, new FileSystemStorage(rootDirectory || '.'))
|
||||||
}
|
}
|
||||||
|
|
||||||
getType(): AugmentationType {
|
getType(): AugmentationType {
|
||||||
return AugmentationType.MEMORY
|
return AugmentationType.MEMORY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory augmentation that uses OPFS (Origin Private File System) storage
|
* Memory augmentation that uses OPFS (Origin Private File System) storage
|
||||||
*/
|
*/
|
||||||
export class OPFSStorageAugmentation extends BaseMemoryAugmentation {
|
export class OPFSStorageAugmentation extends BaseMemoryAugmentation {
|
||||||
readonly description = 'Memory augmentation that stores data in the Origin Private File System'
|
readonly description = 'Memory augmentation that stores data in the Origin Private File System'
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
constructor(name: string) {
|
constructor(name: string) {
|
||||||
super(name, new OPFSStorage())
|
super(name, new OPFSStorage())
|
||||||
}
|
}
|
||||||
|
|
||||||
getType(): AugmentationType {
|
getType(): AugmentationType {
|
||||||
return AugmentationType.MEMORY
|
return AugmentationType.MEMORY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory function to create the appropriate memory augmentation based on the environment
|
* Factory function to create the appropriate memory augmentation based on the environment
|
||||||
*/
|
*/
|
||||||
export async function createMemoryAugmentation(
|
export async function createMemoryAugmentation(
|
||||||
name: string,
|
name: string,
|
||||||
options: {
|
options: {
|
||||||
storageType?: 'memory' | 'filesystem' | 'opfs'
|
storageType?: 'memory' | 'filesystem' | 'opfs'
|
||||||
rootDirectory?: string
|
rootDirectory?: string
|
||||||
requestPersistentStorage?: boolean
|
requestPersistentStorage?: boolean
|
||||||
} = {}
|
} = {}
|
||||||
): Promise<IMemoryAugmentation> {
|
): Promise<IMemoryAugmentation> {
|
||||||
// If a specific storage type is requested, use that
|
// If a specific storage type is requested, use that
|
||||||
if (options.storageType) {
|
if (options.storageType) {
|
||||||
switch (options.storageType) {
|
switch (options.storageType) {
|
||||||
case 'memory':
|
case 'memory':
|
||||||
return new MemoryStorageAugmentation(name)
|
return new MemoryStorageAugmentation(name)
|
||||||
case 'filesystem':
|
case 'filesystem':
|
||||||
|
return new FileSystemStorageAugmentation(name, options.rootDirectory)
|
||||||
|
case 'opfs':
|
||||||
|
return new OPFSStorageAugmentation(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, select based on environment
|
||||||
|
// Use the global isNode variable from the environment detection
|
||||||
|
const isNodeEnv = (globalThis as any).__ENV__?.isNode || (
|
||||||
|
typeof process !== 'undefined' &&
|
||||||
|
process.versions != null &&
|
||||||
|
process.versions.node != null
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isNodeEnv) {
|
||||||
|
// In Node.js, use FileSystemStorage
|
||||||
return new FileSystemStorageAugmentation(name, options.rootDirectory)
|
return new FileSystemStorageAugmentation(name, options.rootDirectory)
|
||||||
case 'opfs':
|
|
||||||
return new OPFSStorageAugmentation(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, select based on environment
|
|
||||||
// Use the global isNode variable from the environment detection
|
|
||||||
const isNodeEnv = (globalThis as any).__ENV__?.isNode || (
|
|
||||||
typeof process !== 'undefined' &&
|
|
||||||
process.versions != null &&
|
|
||||||
process.versions.node != null
|
|
||||||
)
|
|
||||||
|
|
||||||
if (isNodeEnv) {
|
|
||||||
// In Node.js, use FileSystemStorage
|
|
||||||
return new FileSystemStorageAugmentation(name, options.rootDirectory)
|
|
||||||
} else {
|
|
||||||
// In browser, try OPFS first
|
|
||||||
const opfsStorage = new OPFSStorage()
|
|
||||||
|
|
||||||
if (opfsStorage.isOPFSAvailable()) {
|
|
||||||
// Request persistent storage if specified
|
|
||||||
if (options.requestPersistentStorage) {
|
|
||||||
await opfsStorage.requestPersistentStorage()
|
|
||||||
}
|
|
||||||
return new OPFSStorageAugmentation(name)
|
|
||||||
} else {
|
} else {
|
||||||
// Fall back to memory storage
|
// In browser, try OPFS first
|
||||||
return new MemoryStorageAugmentation(name)
|
const opfsStorage = new OPFSStorage()
|
||||||
|
|
||||||
|
if (opfsStorage.isOPFSAvailable()) {
|
||||||
|
// Request persistent storage if specified
|
||||||
|
if (options.requestPersistentStorage) {
|
||||||
|
await opfsStorage.requestPersistentStorage()
|
||||||
|
}
|
||||||
|
return new OPFSStorageAugmentation(name)
|
||||||
|
} else {
|
||||||
|
// Fall back to memory storage
|
||||||
|
return new MemoryStorageAugmentation(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4888
src/brainyData.ts
4888
src/brainyData.ts
File diff suppressed because it is too large
Load diff
10
src/index.ts
10
src/index.ts
|
|
@ -83,13 +83,11 @@ export {
|
||||||
import {
|
import {
|
||||||
OPFSStorage,
|
OPFSStorage,
|
||||||
MemoryStorage,
|
MemoryStorage,
|
||||||
createStorage
|
FileSystemStorage,
|
||||||
} from './storage/opfsStorage.js'
|
|
||||||
import { FileSystemStorage } from './storage/fileSystemStorage.js'
|
|
||||||
import {
|
|
||||||
R2Storage,
|
R2Storage,
|
||||||
S3CompatibleStorage
|
S3CompatibleStorage,
|
||||||
} from './storage/s3CompatibleStorage.js'
|
createStorage
|
||||||
|
} from './storage/storageFactory.js'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
OPFSStorage,
|
OPFSStorage,
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,24 @@
|
||||||
/**
|
/**
|
||||||
* Type declarations for the File System Access API
|
* Type declarations for the File System Access API
|
||||||
* Extends the FileSystemDirectoryHandle interface to include the [Symbol.asyncIterator] method
|
* Extends the FileSystemDirectoryHandle interface to include the [Symbol.asyncIterator] method
|
||||||
|
* and FileSystemHandle to include getFile() method for TypeScript compatibility
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Extend the FileSystemDirectoryHandle interface
|
// Extend the FileSystemDirectoryHandle interface
|
||||||
interface FileSystemDirectoryHandle {
|
interface FileSystemDirectoryHandle {
|
||||||
[Symbol.asyncIterator](): AsyncIterableIterator<[string, FileSystemHandle]>;
|
[Symbol.asyncIterator](): AsyncIterableIterator<[string, FileSystemHandle]>;
|
||||||
keys(): AsyncIterableIterator<string>;
|
|
||||||
entries(): AsyncIterableIterator<[string, FileSystemHandle]>;
|
keys(): AsyncIterableIterator<string>;
|
||||||
|
|
||||||
|
entries(): AsyncIterableIterator<[string, FileSystemHandle]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extend the FileSystemHandle interface to include getFile method
|
||||||
|
// This is needed because TypeScript doesn't recognize that a FileSystemHandle
|
||||||
|
// can be a FileSystemFileHandle which has the getFile method
|
||||||
|
interface FileSystemHandle {
|
||||||
|
getFile?(): Promise<File>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export something to make this a module
|
// Export something to make this a module
|
||||||
export const fileSystemTypesLoaded = true;
|
export const fileSystemTypesLoaded = true
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue