-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
115 lines (103 loc) · 3.33 KB
/
index.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const ReferenceMap = require('reference-map')
const createIframe = require('create-iframe')
const IframeStream = require('iframe-stream').IframeStream
const dnode = require('dnode')
module.exports = class IframeContainer {
constructor (kernel) {
this.kernel = kernel
this._iframeInit = false
this._refs = new ReferenceMap()
}
_startup () {
if (!this._iframeInit) {
const code = this.kernel.code
if (code) {
let res
const self = this
const promise = new Promise((resolve, reject) => {
res = resolve
})
this.iframe = createIframe(code, {
container: document.body,
sandbox: ['allow-scripts', 'allow-same-origin']
}).iframe
this.iframeStream = IframeStream(this.iframe)
const d = dnode(function (remote) {
self.remote = remote
this.getPort = (name, cb) => {
const port = self.kernel.ports.get(name)
cb(self._refs.add(port))
}
this.bindPort = async (name, port, cb) => {
port = self._refs.get(port)
await self.kernel.ports.bind(name, port)
cb()
}
this.deletePort = (name, cb) => {
self.kernel.ports.delete(name)
cb()
}
this.createInstance = async (message, cb) => {
message = self._refs.get(message.msgRef)
await self.kernel.createInstance(IframeContainer.type, message)
cb()
}
this.createMessage = (data, ports, cb) => {
const message = self.kernel.createMessage({
data: data,
ports: ports.map(ref => self._refs.get(ref))
})
const json = Object.assign({}, message.toJSON())
json.msgRef = self._refs.add(message)
json.ports = message.ports.map(port => self._refs.add(port))
cb(json)
}
this.createChannel = cb => {
const ports = self.kernel.ports.createChannel()
const port1 = self._refs.add(ports[0])
const port2 = self._refs.add(ports[1])
cb([port1, port2])
}
this.send = async (port, message, cb) => {
port = self._refs.get(port)
message = self._refs.get(message.msgRef)
await self.kernel.send(port, message)
cb()
}
this.id = cb => {
cb(self.kernel.id)
}
self._iframeInit = true
d.on('remote', res)
})
d.pipe(this.iframeStream).pipe(d)
return promise
}
}
}
async onStartup () {
console.log('start up')
await this._startup()
if (this.remote.onStartup) {
return new Promise((resolve, reject) => {
this.remote.onStartup(resolve)
})
}
}
async onCreation (message) {
delete message._opts.data
await this._startup()
return this.onMessage(message, 'onCreation')
}
// the function is called for each message that a container gets
async onMessage (message, method = 'onMessage') {
debugger
const json = Object.assign({}, message.toJSON())
json.msgRef = this._refs.add(message)
json.ports = message.ports.map(port => this._refs.add(port))
return new Promise((resolve, reject) => {
this.remote[method](json, resolve)
})
}
onIdle () {}
}