-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathworker-makecode.js
127 lines (117 loc) · 3.35 KB
/
worker-makecode.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
116
117
118
119
120
121
122
123
124
125
126
127
const EDITOR_URL = 'https://arcade.makecode.com'
const { parentPort } = require('node:worker_threads')
const { JSDOM } = require('jsdom')
const jsdom = new JSDOM(`
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Blocks Embedding Test Page</title>
<style>
html {font-family: Arial, Helvetica, sans-serif}
.boxdiv {padding:5px; display:inline-block; border: solid; background-color: lightgray}
</style>
</head>
<body>
</body>
</html>
`, {
resources: 'usable',
runScripts: 'dangerously',
})
const { ArrayBuffer, TextDecoder, TextEncoder } = require('node:util')
jsdom.TextEncoder = TextEncoder
jsdom.TextDecoder = TextDecoder
jsdom.ArrayBuffer = ArrayBuffer
jsdom.Uint8Array = Uint8Array
const __queue = []
var __assignedId = -1
var __currentFile = ''
var __ready = false
function injectRenderer() {
var f = jsdom.window.document.getElementById("makecoderenderer")
// check iframe already added to the DOM
if (f) {
return
}
f = jsdom.window.document.createElement("iframe")
f.id = "makecoderenderer"
f.style.position = "absolute"
f.style.left = 0
f.style.bottom = 0
f.style.width = "1px"
f.style.height = "1px"
f.src = EDITOR_URL +
(EDITOR_URL[EDITOR_URL.length - 1] == '/' ? '' : '/') +
'--docs?render=1'
jsdom.window.document.body.appendChild(f)
}
function outputMessage(msg) {
console.log(msg)
}
function renderNextFile() {
if (__queue.length == 0) {
return
}
__ready = false
__currentFile = __queue[0]
__queue.splice(0, 1)
var code = `let counter = 0
game.onUpdateInterval(5000, function () {
console.log("Entering the 'on game update every 5000 ms' block.")
counter += 1
console.logValue("Number of times run", counter)
})
`
var isSnippet = false
var msg = {
type: "renderblocks",
id: Math.random(),
code: code.toString(),
options: {
snippetMode: isSnippet,
}
}
console.log(`Worker ${__assignedId} rendering file ${__currentFile}.`)
var f = jsdom.window.document.getElementById("makecoderenderer")
f.contentWindow.postMessage(msg, EDITOR_URL)
}
jsdom.window.addEventListener('message', function (ev) {
var msg = ev.data
if (msg.source != 'makecode') return
console.log(msg.type)
switch (msg.type) {
case 'renderready':
console.log(`Worker ${__assignedId} renderer is ready.`)
parentPort.emit('online')
__ready = true
if (__queue.length > 0) {
renderNextFile()
}
break
case 'renderblocks':
outputMessage(msg)
__ready = true
parentPort.postMessage({
id: __assignedId,
msg: `Done with file ${__currentFile}.`,
file: __currentFile,
})
if (__queue.length > 0) {
renderNextFile()
}
break
}
}, false)
parentPort.on('message', message => {
__assignedId = message.id
fileName = message.task
console.log(`Worker ${__assignedId}: Received request to process file ${fileName}`)
__queue.push(fileName)
if (__ready) {
renderNextFile()
} else {
injectRenderer()
}
})