mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-26 17:01:20 -08:00
refactor(core): CORE-03 add typed resource scopes and cleanup adapters
This commit is contained in:
1 parent
362c616998
commit
3e38dd0d19
12 files changed
+1242
-6
No files matched your search
@@ -0,0 +1,65 @@
|
||||
export type Cleanup = () => undefined
|
||||
|
||||
export class ResourceCleanupError extends Error {
|
||||
constructor(readonly errors: unknown[]) {
|
||||
super('Failed to release ArtPlayer resources')
|
||||
this.name = 'ResourceCleanupError'
|
||||
}
|
||||
}
|
||||
|
||||
export default class ResourceScope {
|
||||
private cleanups = new Set<() => void>()
|
||||
private disposed = false
|
||||
|
||||
get closed(): boolean {
|
||||
return this.disposed
|
||||
}
|
||||
|
||||
add(cleanup: Cleanup): () => void {
|
||||
let active = true
|
||||
const release = () => {
|
||||
if (!active)
|
||||
return
|
||||
active = false
|
||||
this.cleanups.delete(release)
|
||||
cleanup()
|
||||
}
|
||||
if (this.closed)
|
||||
release()
|
||||
else
|
||||
this.cleanups.add(release)
|
||||
return release
|
||||
}
|
||||
|
||||
child(): ResourceScope {
|
||||
const child = new ResourceScope()
|
||||
const release = this.add(() => {
|
||||
child.dispose()
|
||||
})
|
||||
child.add(() => {
|
||||
release()
|
||||
})
|
||||
return child
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
if (this.closed)
|
||||
return
|
||||
this.disposed = true
|
||||
const errors: unknown[] = []
|
||||
// Unwind dependencies; release removes each registration before invoking it.
|
||||
for (const release of Array.from(this.cleanups).reverse()) {
|
||||
try {
|
||||
release()
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof ResourceCleanupError)
|
||||
errors.push(...error.errors)
|
||||
else
|
||||
errors.push(error)
|
||||
}
|
||||
}
|
||||
if (errors.length)
|
||||
throw new ResourceCleanupError(errors)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user