46 lines
1.4 KiB
JavaScript
46 lines
1.4 KiB
JavaScript
import { createSimAdminClient } from '../core.js'
|
|
|
|
function sameInstance(a, b) {
|
|
return a && b && JSON.stringify(a) === JSON.stringify(b)
|
|
}
|
|
|
|
export class ClientRegistry {
|
|
constructor({ createClient = createSimAdminClient } = {}) {
|
|
this.createClient = createClient
|
|
this.clients = new Map()
|
|
}
|
|
reconcile(instances) {
|
|
const previous = this.clients
|
|
const nextClients = new Map()
|
|
const staged = []
|
|
try {
|
|
for (const instance of instances) {
|
|
const current = previous.get(instance.id)
|
|
const next = current && sameInstance(current.instance, instance) ? current : this.createClient(instance)
|
|
nextClients.set(instance.id, next)
|
|
if (next !== current && ![...previous.values()].includes(next)) staged.push(next)
|
|
}
|
|
} catch (error) {
|
|
for (const client of staged) { client.close?.(); client.jar?.clear?.() }
|
|
throw error
|
|
}
|
|
this.clients = nextClients
|
|
for (const [id, client] of previous) {
|
|
if (nextClients.get(id) !== client) { client.close?.(); client.jar?.clear?.() }
|
|
}
|
|
return this
|
|
}
|
|
get(id) { return this.clients.get(id) }
|
|
values() { return this.clients.values() }
|
|
delete(id) {
|
|
const client = this.clients.get(id)
|
|
if (!client) return false
|
|
client.close?.()
|
|
client.jar?.clear?.()
|
|
return this.clients.delete(id)
|
|
}
|
|
close() {
|
|
for (const id of [...this.clients.keys()]) this.delete(id)
|
|
}
|
|
}
|