feat: add persistent storage support for OPFS
Introduced an optional `requestPersistentStorage` flag to enable persistent storage permission requests in the browser. Updated `OPFSStorage` to include methods for requesting and checking persistent storage status, and modified `createStorage` to handle the new flag.
This commit is contained in:
parent
5f4e6ccc70
commit
ac5955a922
2 changed files with 74 additions and 2 deletions
|
|
@ -29,6 +29,12 @@ export interface BrainyDataConfig {
|
|||
* Embedding function to convert data to vectors
|
||||
*/
|
||||
embeddingFunction?: EmbeddingFunction
|
||||
|
||||
/**
|
||||
* Request persistent storage when running in a browser
|
||||
* This will prompt the user for permission to use persistent storage
|
||||
*/
|
||||
requestPersistentStorage?: boolean
|
||||
}
|
||||
|
||||
export class BrainyData<T = any> {
|
||||
|
|
@ -36,6 +42,7 @@ export class BrainyData<T = any> {
|
|||
private storage: StorageAdapter | null = null
|
||||
private isInitialized = false
|
||||
private embeddingFunction: EmbeddingFunction
|
||||
private requestPersistentStorage: boolean
|
||||
|
||||
/**
|
||||
* Create a new vector database
|
||||
|
|
@ -52,6 +59,9 @@ export class BrainyData<T = any> {
|
|||
|
||||
// Set embedding function if provided, otherwise use default
|
||||
this.embeddingFunction = config.embeddingFunction || defaultEmbeddingFunction
|
||||
|
||||
// Set persistent storage request flag
|
||||
this.requestPersistentStorage = config.requestPersistentStorage || false
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -66,7 +76,9 @@ export class BrainyData<T = any> {
|
|||
try {
|
||||
// Initialize storage if not provided in constructor
|
||||
if (!this.storage) {
|
||||
this.storage = await createStorage()
|
||||
this.storage = await createStorage({
|
||||
requestPersistentStorage: this.requestPersistentStorage
|
||||
})
|
||||
}
|
||||
|
||||
// Initialize storage
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ export class OPFSStorage implements StorageAdapter {
|
|||
private metadataDir: FileSystemDirectoryHandle | null = null
|
||||
private isInitialized = false
|
||||
private isAvailable = false
|
||||
private isPersistentRequested = false
|
||||
private isPersistentGranted = false
|
||||
|
||||
constructor() {
|
||||
// Check if OPFS is available
|
||||
|
|
@ -78,6 +80,51 @@ export class OPFSStorage implements StorageAdapter {
|
|||
return this.isAvailable
|
||||
}
|
||||
|
||||
/**
|
||||
* Request persistent storage permission from the user
|
||||
* @returns Promise that resolves to true if permission was granted, false otherwise
|
||||
*/
|
||||
public async requestPersistentStorage(): Promise<boolean> {
|
||||
if (!this.isAvailable) {
|
||||
console.warn('Cannot request persistent storage: OPFS is not available')
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
// Check if persistence is already granted
|
||||
this.isPersistentGranted = await navigator.storage.persisted()
|
||||
|
||||
if (!this.isPersistentGranted) {
|
||||
// Request permission for persistent storage
|
||||
this.isPersistentGranted = await navigator.storage.persist()
|
||||
}
|
||||
|
||||
this.isPersistentRequested = true
|
||||
return this.isPersistentGranted
|
||||
} catch (error) {
|
||||
console.warn('Failed to request persistent storage:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if persistent storage is granted
|
||||
* @returns Promise that resolves to true if persistent storage is granted, false otherwise
|
||||
*/
|
||||
public async isPersistent(): Promise<boolean> {
|
||||
if (!this.isAvailable) {
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
this.isPersistentGranted = await navigator.storage.persisted()
|
||||
return this.isPersistentGranted
|
||||
} catch (error) {
|
||||
console.warn('Failed to check persistent storage status:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a node to storage
|
||||
*/
|
||||
|
|
@ -650,8 +697,12 @@ export class MemoryStorage implements StorageAdapter {
|
|||
|
||||
/**
|
||||
* Factory function to create the appropriate storage adapter based on the environment
|
||||
* @param options Configuration options for storage
|
||||
* @returns Promise that resolves to a StorageAdapter instance
|
||||
*/
|
||||
export async function createStorage(): Promise<StorageAdapter> {
|
||||
export async function createStorage(options: {
|
||||
requestPersistentStorage?: boolean
|
||||
} = {}): Promise<StorageAdapter> {
|
||||
// Check if we're in a Node.js environment
|
||||
const isNode = typeof process !== 'undefined' &&
|
||||
process.versions != null &&
|
||||
|
|
@ -671,6 +722,15 @@ export async function createStorage(): Promise<StorageAdapter> {
|
|||
const opfsStorage = new OPFSStorage()
|
||||
|
||||
if (opfsStorage.isOPFSAvailable()) {
|
||||
// Request persistent storage if specified
|
||||
if (options.requestPersistentStorage) {
|
||||
const isPersistentGranted = await opfsStorage.requestPersistentStorage()
|
||||
if (isPersistentGranted) {
|
||||
console.log('Persistent storage permission granted')
|
||||
} else {
|
||||
console.warn('Persistent storage permission denied')
|
||||
}
|
||||
}
|
||||
return opfsStorage
|
||||
} else {
|
||||
console.warn('OPFS is not available, falling back to in-memory storage')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue