Data-JPack
view release on metacpan or search on metacpan
share/js/02-chunkloader.js view on Meta::CPAN
updateStatus(message,mode){
//console.log("UPDATE STATUS CALLED");
let e=new CustomEvent("JPACK_STATUS",{detail: {progress: parseInt(100*this.chunksLoaded/this.chunksExpected), message:message, mode:mode}});
window.dispatchEvent(e);
}
/**
* Load the pako.js into worker pool for delfate support
* This is actaully prencoded (no compression) for dynamic loading
*/
bootstrap(){
// Path is relative to this.buildRoot
let name="app/jpack/boot/00000000000000000000000000000000/00000000000000000000000000000000.jpack";
return this.queueChunkScript(name)
.then((data)=>{
let decoder=new TextDecoder("utf-8");
let string=decoder.decode(data);
return this.pool.addScriptBody(string)
.then(()=>{
// Unload scripts
this.unloadScript(this.buildRoot+name);
this.chunksLoaded++;
this.updateStatus("Boot Complete");
return Promise.resolve();
});
});
}
//This callback is executed from a chunk script to decode/decompress the data
//
decodeData(options, dataFunc){
//console.log("decodeData script call");
let src=options.jpack_path;
options.jpack_path=options.jpack_path.substr(this.buildRoot.length);
let e=this.urlMap[options.jpack_path];
e.options=options;
e.dataFunc=dataFunc;
e.resolver(e);
this._executeNext();
}
/*Send data to worker pool for decodeing
*/
_decodeChunk(e){
switch(e.options.jpack_type){
case "app":
case "data":
case "boot":
//console.log("SENDING DATA");
//console.log(e.dataFunc());
return this.pool.queueFunction("decode",{options:e.options,string:e.dataFunc()},[])
.then((res)=>{
//res.result is the decoded chunk data to now send to channel manager
return Promise.resolve(res.result);
})
break;
default:
break;
}
}
/**
* Queues a request to download a chunk script. As chunks are large and the
* order is important, a limited number of chunks are downloaded at one time
*
* Returns a promise when the chunkscript has been downloaded, prased and
* decoded. The promise resolves to an arraybuffer of the decoded data
*
* PATHS ARE RELATIVE TO BUILD ROOT ie this.buildRoot
* This is to match the build output paths of the jpack files
*/
queueChunkScript(path){
//Add this to the queue
let promise;
let entry={path:path, dataFunc:undefined};
entry.promise=new Promise((resolve,reject)=>{
entry.resolver=resolve;
entry.rejecter=reject;
});
this.urlQueue.push(entry);
this.urlMap[path]=entry;
this._executeNext();
//This promise is resolved when the script is ready to be decoded
//ie when the dataFunc field has been assigned
return entry.promise
.then((e)=>{
//Queue the decoding into the worker pool
//console.log("ABOUT TO _decodeChunk");
return this._decodeChunk(e);
});
}
_executeNext(){
if(this.urlQueue.length>0){
let e=this.urlQueue.shift()
this._loadChunk(e); //This gives a promise but the actual loadded script calls the decode directly
}
/****************************************************************************************/
/* console.log("Working limit: ", this.workingLimit,"currently working", this.working); */
/* if((this.working<this.workingLimit) && (this.urlQueue.length>0)){ */
/* console.log("EXECUTE NEXT"); */
/* this.working++; */
/* let e=this.urlQueue.shift() */
/* this._loadChunk(e); */
/* } */
/****************************************************************************************/
}
/* loads the chunk. The returned promise is not used.
* The load is complete when the chunk calls the decodeData callback
*/
_loadChunk(entry){
//Run this when a decoder is available
let path=this.buildRoot+entry.path;
//console.log("_loadChunk", path);
return new Promise((resolve,reject)=>{
setTimeout(()=>{
this.loadScript(path).then((e)=>{
this.updateStatus("Loading data "+ entry.path);
//e.parentElement.removeChild(e);
resolve();
})
.catch((e)=>{
this.updateStatus("Error data "+ entry.path);
console.log("Caught error", entry);
entry.rejecter("Could not load script");
});
},0);
});
}
//Fails/ends when two items can not be loaded
load(path, callback, multi){
let head=path;
let segPath;;
let p= Promise.resolve();
let resolver;
let rejecter;
let last=new Promise((resolve, reject)=>{
resolver=resolve;
rejecter=reject;
( run in 1.854 second using v1.01-cache-2.11-cpan-39bf76dae61 )