-
Notifications
You must be signed in to change notification settings - Fork 6
/
bridge.js
98 lines (79 loc) · 2.19 KB
/
bridge.js
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
export class Bridge {
#adapter
#lastMessageId
#pendingMessages
#pendingCallbacks
constructor() {
this.#adapter = null
this.#lastMessageId = 0
this.#pendingMessages = []
this.#pendingCallbacks = new Map()
}
start() {
this.notifyApplicationAfterStart()
}
notifyApplicationAfterStart() {
document.dispatchEvent(new Event("web-bridge:ready"))
}
supportsComponent(component) {
if (this.#adapter) {
return this.#adapter.supportsComponent(component)
} else {
return false
}
}
send({ component, event, data, callback }) {
if (!this.#adapter) {
this.#savePendingMessage({ component, event, data, callback })
return null
}
if (!this.supportsComponent(component)) return null
const id = this.generateMessageId()
const message = { id: id, component: component, event: event, data: data || {} }
this.#adapter.receive(message)
if (callback) {
this.#pendingCallbacks.set(id, callback)
}
return id
}
receive(message) {
this.executeCallbackFor(message)
}
executeCallbackFor(message) {
const callback = this.#pendingCallbacks.get(message.id)
if (callback) {
callback(message)
}
}
removeCallbackFor(messageId) {
if (this.#pendingCallbacks.has(messageId)) {
this.#pendingCallbacks.delete(messageId)
}
}
removePendingMessagesFor(component) {
this.#pendingMessages = this.#pendingMessages.filter(message => message.component != component)
}
generateMessageId() {
const id = ++this.#lastMessageId
return id.toString()
}
setAdapter(adapter) {
this.#adapter = adapter
// Configure <html> attributes
document.documentElement.dataset.bridgePlatform = this.#adapter.platform
this.adapterDidUpdateSupportedComponents()
this.#sendPendingMessages()
}
adapterDidUpdateSupportedComponents() {
if (this.#adapter) {
document.documentElement.dataset.bridgeComponents = this.#adapter.supportedComponents.join(" ")
}
}
#savePendingMessage(message) {
this.#pendingMessages.push(message)
}
#sendPendingMessages() {
this.#pendingMessages.forEach(message => this.send(message))
this.#pendingMessages = []
}
}