Skip to content

Commit 18a370a

Browse files
refactor: address comments.
1 parent 74e2451 commit 18a370a

1 file changed

Lines changed: 80 additions & 22 deletions

File tree

src/modules/workspace-storage.js

Lines changed: 80 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { cdnImports, importFromCdnWithFallback } from './cdn.js'
33
const workspaceDbName = 'knighted-develop-workspaces'
44
const workspaceDbVersion = 1
55
const workspaceStoreName = 'prWorkspaces'
6+
const workspaceByRepoIndexName = 'byRepo'
7+
const workspaceByLastModifiedIndexName = 'byLastModified'
68

79
const normalizeTabRecord = tab => {
810
if (!tab || typeof tab !== 'object') {
@@ -93,8 +95,8 @@ const openWorkspaceDb = async ({ loadRuntime } = {}) => {
9395
const store = db.createObjectStore(workspaceStoreName, {
9496
keyPath: 'id',
9597
})
96-
store.createIndex('byRepo', 'repo')
97-
store.createIndex('byLastModified', 'lastModified')
98+
store.createIndex(workspaceByRepoIndexName, 'repo')
99+
store.createIndex(workspaceByLastModifiedIndexName, 'lastModified')
98100
}
99101
},
100102
})
@@ -112,7 +114,10 @@ export const createWorkspaceStorageAdapter = ({ loadRuntime } = {}) => {
112114

113115
const ensureDb = () => {
114116
if (!dbPromise) {
115-
dbPromise = openWorkspaceDb({ loadRuntime })
117+
dbPromise = openWorkspaceDb({ loadRuntime }).catch(error => {
118+
dbPromise = null
119+
throw error
120+
})
116121
}
117122

118123
return dbPromise
@@ -135,15 +140,24 @@ export const createWorkspaceStorageAdapter = ({ loadRuntime } = {}) => {
135140

136141
const listWorkspaces = async ({ repo } = {}) => {
137142
const db = await ensureDb()
138-
const items = await db.getAll(workspaceStoreName)
143+
const hasRepoFilter = typeof repo === 'string' && repo.length > 0
139144

140-
const normalized = items.map(normalizeWorkspaceRecord)
141-
const filtered =
142-
typeof repo === 'string' && repo.length > 0
143-
? normalized.filter(item => item.repo === repo)
144-
: normalized
145+
if (hasRepoFilter) {
146+
const byRepo = await db.getAllFromIndex(
147+
workspaceStoreName,
148+
workspaceByRepoIndexName,
149+
repo,
150+
)
145151

146-
return filtered.sort(byLastModifiedDesc)
152+
return byRepo.map(normalizeWorkspaceRecord).sort(byLastModifiedDesc)
153+
}
154+
155+
const byLastModified = await db.getAllFromIndex(
156+
workspaceStoreName,
157+
workspaceByLastModifiedIndexName,
158+
)
159+
160+
return byLastModified.map(normalizeWorkspaceRecord).reverse()
147161
}
148162

149163
const upsertWorkspace = async record => {
@@ -186,17 +200,37 @@ export const createWorkspaceStorageAdapter = ({ loadRuntime } = {}) => {
186200
const existingIndex = nextTabs.findIndex(tab => tab.id === tabId)
187201
const previous = existingIndex >= 0 ? nextTabs[existingIndex] : null
188202

189-
const next = normalizeTabRecord({
190-
...previous,
203+
const nextTabRecord = {
204+
...(previous ?? {}),
191205
id: tabId,
192-
name,
193-
path,
194-
language,
195-
content,
196-
scroll,
197-
isActive,
198206
lastModified: Date.now(),
199-
})
207+
}
208+
209+
if (name !== undefined) {
210+
nextTabRecord.name = name
211+
}
212+
213+
if (path !== undefined) {
214+
nextTabRecord.path = path
215+
}
216+
217+
if (language !== undefined) {
218+
nextTabRecord.language = language
219+
}
220+
221+
if (content !== undefined) {
222+
nextTabRecord.content = content
223+
}
224+
225+
if (scroll !== undefined) {
226+
nextTabRecord.scroll = scroll
227+
}
228+
229+
if (isActive !== undefined) {
230+
nextTabRecord.isActive = isActive
231+
}
232+
233+
const next = normalizeTabRecord(nextTabRecord)
200234

201235
if (!next) {
202236
throw new Error('Unable to persist tab content because tab record is invalid.')
@@ -255,6 +289,7 @@ export const createWorkspaceStorageAdapter = ({ loadRuntime } = {}) => {
255289

256290
export const createDebouncedWorkspaceSaver = ({
257291
save,
292+
onError,
258293
waitMs = 800,
259294
now = () => Date.now(),
260295
schedule = setTimeout,
@@ -269,6 +304,18 @@ export const createDebouncedWorkspaceSaver = ({
269304
let inFlight = Promise.resolve()
270305
let lastScheduledAt = 0
271306

307+
const reportSaveError = ({ error, payload }) => {
308+
if (typeof onError !== 'function') {
309+
return
310+
}
311+
312+
try {
313+
onError(error, payload)
314+
} catch {
315+
/* Swallow reporter failures so saving can continue. */
316+
}
317+
}
318+
272319
const flush = async () => {
273320
if (!pendingPayload) {
274321
return
@@ -277,8 +324,15 @@ export const createDebouncedWorkspaceSaver = ({
277324
const payload = pendingPayload
278325
pendingPayload = null
279326

280-
inFlight = inFlight.then(() => save(payload))
281-
await inFlight
327+
const continueChain = inFlight.catch(() => undefined)
328+
inFlight = continueChain.then(() => save(payload))
329+
330+
try {
331+
await inFlight
332+
} catch (error) {
333+
reportSaveError({ error, payload })
334+
throw error
335+
}
282336
}
283337

284338
const queue = payload => {
@@ -291,7 +345,11 @@ export const createDebouncedWorkspaceSaver = ({
291345

292346
timer = schedule(async () => {
293347
timer = null
294-
await flush()
348+
try {
349+
await flush()
350+
} catch {
351+
/* Background flush errors are surfaced through onError when provided. */
352+
}
295353
}, waitMs)
296354
}
297355

0 commit comments

Comments
 (0)