Skip to content
Open
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
1 change: 1 addition & 0 deletions src/contexts/MaiaEngineContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const MaiaEngineContextProvider: React.FC<{ children: ReactNode }> = ({
model:
process.env.NEXT_PUBLIC_MAIA_MODEL_URL ??
'https://raw.githubusercontent.com/CSSLab/maia-platform-frontend/e23a50e/public/maia2/maia_rapid.onnx',
modelVersion: process.env.NEXT_PUBLIC_MAIA_MODEL_VERSION ?? '1',
setStatus: setStatus,
setProgress: setProgress,
setError: setError,
Expand Down
7 changes: 5 additions & 2 deletions src/lib/engine/maia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { MaiaModelStorage } from './storage'

interface MaiaOptions {
model: string
modelVersion: string
setStatus: (status: MaiaStatus) => void
setProgress: (progress: number) => void
setError: (error: string) => void
Expand All @@ -14,11 +15,13 @@ interface MaiaOptions {
class Maia {
private model!: InferenceSession
private modelUrl: string
private modelVersion: string
private options: MaiaOptions
private storage: MaiaModelStorage

constructor(options: MaiaOptions) {
this.modelUrl = options.model
this.modelVersion = options.modelVersion
this.options = options
this.storage = new MaiaModelStorage()

Expand All @@ -30,7 +33,7 @@ class Maia {
await this.storage.requestPersistentStorage()

console.log('Attempting to get model from IndexedDB...')
const buffer = await this.storage.getModel(this.modelUrl)
const buffer = await this.storage.getModel(this.modelUrl, this.modelVersion)

if (buffer) {
console.log('Model found in IndexedDB, initializing...')
Expand Down Expand Up @@ -94,7 +97,7 @@ class Maia {
position += chunk.length
}

await this.storage.storeModel(this.modelUrl, buffer.buffer)
await this.storage.storeModel(this.modelUrl, this.modelVersion, buffer.buffer)

await this.initializeModel(buffer.buffer)
this.options.setStatus('ready')
Expand Down
47 changes: 37 additions & 10 deletions src/lib/engine/storage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
interface ModelStorage {
id: string
url: string
version: string
data: Blob
timestamp: number
size: number
Expand Down Expand Up @@ -34,7 +35,11 @@ export class MaiaModelStorage {
})
}

async storeModel(modelUrl: string, buffer: ArrayBuffer): Promise<void> {
async storeModel(
modelUrl: string,
modelVersion: string,
buffer: ArrayBuffer,
): Promise<void> {
try {
const db = await this.openDB()
const transaction = db.transaction([this.storeName], 'readwrite')
Expand All @@ -43,6 +48,7 @@ export class MaiaModelStorage {
const modelData: ModelStorage = {
id: 'maia-rapid-model',
url: modelUrl,
version: modelVersion,
data: new Blob([buffer]),
timestamp: Date.now(),
size: buffer.byteLength,
Expand All @@ -61,7 +67,10 @@ export class MaiaModelStorage {
}
}

async getModel(modelUrl: string): Promise<ArrayBuffer | null> {
async getModel(
modelUrl: string,
modelVersion: string,
): Promise<ArrayBuffer | null> {
console.log('Storage: getModel called with URL:', modelUrl)

try {
Expand Down Expand Up @@ -95,18 +104,36 @@ export class MaiaModelStorage {
return null
}

// Check if URL matches (for cache invalidation)
if (modelData.url !== modelUrl) {
console.log('Storage: Model URL changed, clearing old cache')
console.log('Storage: Cached URL:', modelData.url)
console.log('Storage: Requested URL:', modelUrl)
// Version mismatch = genuinely new model, must re-download.
if (modelData.version && modelData.version !== modelVersion) {
console.log('Storage: Model version changed, clearing old cache')
console.log('Storage: Cached version:', modelData.version)
console.log('Storage: Required version:', modelVersion)
await this.deleteModel()
console.log(
'Storage: Old cache cleared, model needs to be re-downloaded',
)
return null
}

// URL changed but same version (e.g. moved hosts) — keep the cache,
// just update the stored URL so future loads match immediately.
if (modelData.url !== modelUrl || modelData.version !== modelVersion) {
console.log('Storage: Updating stored URL/version')
try {
const rwTx = db.transaction([this.storeName], 'readwrite')
const rwStore = rwTx.objectStore(this.storeName)
await new Promise<void>((resolve, reject) => {
const req = rwStore.put({
...modelData,
url: modelUrl,
version: modelVersion,
})
req.onsuccess = () => resolve()
req.onerror = () => reject(req.error)
})
} catch (e) {
console.warn('Storage: Failed to update stored URL/version:', e)
}
}

console.log('Storage: Converting Blob to ArrayBuffer...')
// Convert Blob back to ArrayBuffer
const buffer = await modelData.data.arrayBuffer()
Expand Down
Loading