UNPKG

2.63 kBJavaScriptView Raw
1import v4 from 'uuid-v4'
2
3export class Unpack {
4 constructor() {
5 this.id = v4()
6 this.worker = new Worker(window.URL.createObjectURL(new Blob([require('../dist/bundle.js')])))
7 this.promises = {}
8 this.requests = 0
9
10 this.worker.addEventListener(
11 'message',
12 message => {
13 switch (message.data.action) {
14 case 'Finished':
15 var resolve = this.promises[message.data.task].resolve
16 delete this.promises[message.data.task]
17 resolve(message.data)
18
19 if (--this.requests < 0) this.requests = 0
20 break
21
22 case 'Result':
23 if (!!this.promises[message.data.task].callback) {
24 this.promises[message.data.task].callback(message.data.result)
25 }
26 break
27 }
28 },
29 false,
30 )
31 }
32
33 // Post message to worker
34 post(obj, callback) {
35 obj.parent = this.id
36 obj.task = v4()
37 let task = { callback: callback }
38 this.promises[obj.task] = task
39 task.promise = new Promise(resolve => {
40 task.resolve = resolve
41 if (obj.type === 'Binary') {
42 this.worker.postMessage(obj, [obj.data.buffer])
43 } else {
44 this.worker.postMessage(JSON.stringify(obj))
45 }
46 })
47 return task.promise
48 }
49
50 // This will race for a unused core
51 static getFreeCore() {
52 let core = undefined
53 for (let candidate of cores) {
54 if (candidate.requests == 0 && Object.keys(candidate.promises).length == 0) {
55 core = candidate
56 break
57 }
58 }
59
60 if (core === undefined) {
61 const sorted = cores.sort((a, b) => a.requests > b.requests)
62 const candidates = sorted.filter(c => c.requests === sorted[0].requests)
63 core = candidates[Math.round(Math.random() * (candidates.length - 1))]
64 }
65
66 core.requests++
67 return core
68 }
69
70 static callWorkers(props) {
71 for (let core of cores) {
72 core.worker.postMessage(props)
73 }
74 }
75}
76
77// Create a worker for each core
78let cores = Array.from(new Array(navigator.hardwareConcurrency || 4), () => new Unpack())
79
80// Packs ArrayBuffer into deflated base64 for ClassCAD stream consumption
81export default function unpack(object, callback) {
82 return Unpack.getFreeCore().post(object, callback)
83}