-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchannel.ts
76 lines (62 loc) · 2.03 KB
/
channel.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { Disposable } from "./disposer.ts"
import { Nullable, Optional } from "./utils.ts"
export interface Subscription extends Disposable { name: string }
export type Callback = (e: MessageEvent) => void
export interface Channel extends Subscription {
postMessage: (e: MessageEvent) => void
onmessage: Nullable<Callback>
}
class WrappedBC extends BroadcastChannel implements Channel {
dispose() {
this.onmessage = null
setTimeout(() => this.close(), 0)
}
}
export function create(name: string): Channel {
return new WrappedBC(name) as Channel
}
export class Cache {
channels: Map<string, Channel> = new Map
maxSize: number
constructor(maxSize: number = 100) {
this.maxSize = maxSize
}
get(name: string): Optional<Channel> {
const channel = this.channels.get(name)
if (channel) {
// delete and set entry again to update the order used
this.channels.delete(name)
this.channels.set(name, channel)
}
return channel
}
set(name: string, channel: Channel): this {
// if we already have an entry for this name...
const existing = this.channels.get(name)
if (existing) {
// remove it and dispose the channel
this.channels.delete(name)
existing.dispose()
}
this.channels.set(name, channel)
if (this.channels.size > this.maxSize) {
// schedule task to trim old entries
setTimeout(() => this.trim(), 0)
}
return this
}
dispose() {
for (const channel of this.channels.values()) channel.dispose()
this.channels.clear()
}
// delete/dispose old entries if we're over the max size
private trim() {
let overage = this.channels.size - this.maxSize
if (overage <= 0) return
for (const [ name, channel ] of this.channels.entries()) {
this.channels.delete(name)
channel.dispose()
if (--overage <= 0) break
}
}
}