Replace idb with idb-keyval for draft media storage
Simplifies web IndexedDB storage by using idb-keyval instead of the full idb library. This reduces bundle size and aligns with the pattern used in src/storage/archive/db/index.web.ts. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -172,7 +172,6 @@
|
|||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
"hls.js": "^1.6.2",
|
"hls.js": "^1.6.2",
|
||||||
"idb-keyval": "^6.2.2",
|
"idb-keyval": "^6.2.2",
|
||||||
"idb": "^8.0.3",
|
|
||||||
"js-sha256": "^0.9.0",
|
"js-sha256": "^0.9.0",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"lande": "^1.0.10",
|
"lande": "^1.0.10",
|
||||||
|
|||||||
@@ -2,37 +2,19 @@
|
|||||||
* Web IndexedDB storage for draft media.
|
* Web IndexedDB storage for draft media.
|
||||||
* Media is stored by localRefPath key (unique identifier stored in server draft).
|
* Media is stored by localRefPath key (unique identifier stored in server draft).
|
||||||
*/
|
*/
|
||||||
import {type DBSchema, type IDBPDatabase, openDB} from 'idb'
|
import {createStore, del, get, keys, set} from 'idb-keyval'
|
||||||
|
|
||||||
import {logger} from './logger'
|
import {logger} from './logger'
|
||||||
|
|
||||||
const DB_NAME = 'bsky-draft-media'
|
const DB_NAME = 'bsky-draft-media'
|
||||||
const DB_VERSION = 1
|
const STORE_NAME = 'media'
|
||||||
|
|
||||||
interface DraftMediaDB extends DBSchema {
|
type MediaRecord = {
|
||||||
media: {
|
|
||||||
key: string // localRefPath
|
|
||||||
value: {
|
|
||||||
blob: Blob
|
blob: Blob
|
||||||
createdAt: string
|
createdAt: string
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let dbPromise: Promise<IDBPDatabase<DraftMediaDB>> | null = null
|
const store = createStore(DB_NAME, STORE_NAME)
|
||||||
|
|
||||||
async function getDB(): Promise<IDBPDatabase<DraftMediaDB>> {
|
|
||||||
if (!dbPromise) {
|
|
||||||
dbPromise = openDB<DraftMediaDB>(DB_NAME, DB_VERSION, {
|
|
||||||
upgrade(db) {
|
|
||||||
if (!db.objectStoreNames.contains('media')) {
|
|
||||||
db.createObjectStore('media')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return dbPromise
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a path/URL to a Blob
|
* Convert a path/URL to a Blob
|
||||||
@@ -73,8 +55,6 @@ export async function saveMediaToLocal(
|
|||||||
localRefPath: string,
|
localRefPath: string,
|
||||||
sourcePath: string,
|
sourcePath: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const db = await getDB()
|
|
||||||
|
|
||||||
let blob: Blob
|
let blob: Blob
|
||||||
try {
|
try {
|
||||||
blob = await toBlob(sourcePath)
|
blob = await toBlob(sourcePath)
|
||||||
@@ -88,13 +68,13 @@ export async function saveMediaToLocal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await db.put(
|
await set(
|
||||||
'media',
|
localRefPath,
|
||||||
{
|
{
|
||||||
blob,
|
blob,
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
},
|
},
|
||||||
localRefPath,
|
store,
|
||||||
)
|
)
|
||||||
// Update cache
|
// Update cache
|
||||||
mediaExistsCache.set(localRefPath, true)
|
mediaExistsCache.set(localRefPath, true)
|
||||||
@@ -111,8 +91,7 @@ export async function saveMediaToLocal(
|
|||||||
export async function loadMediaFromLocal(
|
export async function loadMediaFromLocal(
|
||||||
localRefPath: string,
|
localRefPath: string,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const db = await getDB()
|
const record = await get<MediaRecord>(localRefPath, store)
|
||||||
const record = await db.get('media', localRefPath)
|
|
||||||
|
|
||||||
if (!record) {
|
if (!record) {
|
||||||
throw new Error(`Media file not found: ${localRefPath}`)
|
throw new Error(`Media file not found: ${localRefPath}`)
|
||||||
@@ -127,8 +106,7 @@ export async function loadMediaFromLocal(
|
|||||||
export async function deleteMediaFromLocal(
|
export async function deleteMediaFromLocal(
|
||||||
localRefPath: string,
|
localRefPath: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const db = await getDB()
|
await del(localRefPath, store)
|
||||||
await db.delete('media', localRefPath)
|
|
||||||
mediaExistsCache.delete(localRefPath)
|
mediaExistsCache.delete(localRefPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,10 +130,9 @@ export function mediaExists(localRefPath: string): boolean {
|
|||||||
|
|
||||||
async function populateCacheInternal(): Promise<void> {
|
async function populateCacheInternal(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const db = await getDB()
|
const allKeys = await keys(store)
|
||||||
const keys = await db.getAllKeys('media')
|
for (const key of allKeys) {
|
||||||
for (const key of keys) {
|
mediaExistsCache.set(key as string, true)
|
||||||
mediaExistsCache.set(key, true)
|
|
||||||
}
|
}
|
||||||
cachePopulated = true
|
cachePopulated = true
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -12886,11 +12886,6 @@ idb-keyval@^6.2.2:
|
|||||||
resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.2.tgz#b0171b5f73944854a3291a5cdba8e12768c4854a"
|
resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.2.tgz#b0171b5f73944854a3291a5cdba8e12768c4854a"
|
||||||
integrity sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==
|
integrity sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==
|
||||||
|
|
||||||
idb@^8.0.3:
|
|
||||||
version "8.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/idb/-/idb-8.0.3.tgz#c91e558f15a8d53f1d7f53a094d226fc3ad71fd9"
|
|
||||||
integrity sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg==
|
|
||||||
|
|
||||||
ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1:
|
ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||||
|
|||||||
Reference in New Issue
Block a user