UNPKG

thematic-earth

Version:

HTML-based, whole-Earth thematic maps using locally hosted data layers

2 lines 5.23 kB
/* Copyright (c) 2023 Read Write Tools. Legal use subject to the Thematic Earth Software License Agreement. */ import*as PackageGrammar from'../packages/package-grammar.js';import JsonPackage from'../packages/json-package.class.js';import TessPackage from'../packages/tess-package.class.js';import ParamPackage from'../packages/param-package.class.js';import PS from'../enum/package-state.enum.js';import expect from'../dev/expect.js';import terminal from'../dev/terminal.js';export default class PackageHandler{static allPackages=[];constructor(a){this.thematicEarthElement=a,this.url=null,this.payload=null,this.payloadLength=null,this.payloadOffset=null,this.currentEntry=null,this.packageState=PS.PARSING_OUTSIDE,this.curlyBraceCount=0,this.lineNumber=0,this.packageEntries=[],this.spatialDataId=0,this.layerId=0,Object.seal(this)}async retrieveData(a){expect(a,'String');try{this.url=a;var e=await fetch(a,{cache:'no-cache',referrerPolicy:'no-referrer'});if(200!=e.status&&304!=e.status)throw new Error(`Request for ${a} returned with ${e.status}`);this.payload=await e.text(),this.payloadLength=this.payload.length,this.payloadOffset=0,this.packageEntries=[],this.currentEntry=null,this.packageState=PS.PARSING_OUTSIDE,this.curlyBraceCount=0,this.lineNumber=0;var t=new URL(a,window.location.href);PackageHandler.allPackages.push(t.href),this.parseEntries(),this.sortEntries(),this.validateEntries(),this.thematicEarthElement.signal.broadcast('package/packageAdded',this.summarizePackage()),await this.processEntries()}catch(a){terminal.caught(a)}}summarizePackage(){var a={};for(let e=0;e<this.packageEntries.length;e++){a[this.packageEntries[e].entryName]=this.packageEntries[e].summarizePackage()}return a}parseEntries(){this.readProlog()&&this.readPayload(),this.curlyBraceCount<0&&terminal.abnormal(`Caution: Unmatched curly brace count (${this.curlyBraceCount} extra closing "}" encountered) when parsing package file ${this.url}`),this.curlyBraceCount>0&&terminal.abnormal(`Caution: Unmatched curly brace count (${this.curlyBraceCount} extra opening "{" encountered) when parsing package file ${this.url}`);var a=this.payloadLength-this.payloadOffset;0!=a&&terminal.abnormal(`Premature end of parsing, ${a} bytes at end of package file ${this.url} were not parsed`)}readProlog(){expect(this.payload,'String');var a='!tepl 1.0',e=0+a.length,t=this.payload.substring(0,e);return this.payloadOffset=e+1,this.lineNumber++,a==t||(terminal.abnormal(`Expected !tepl 1.0 but found ${t} while reading package ${this.url} prolog`),!1)}readPayload(){for(;this.payloadOffset<this.payloadLength;){var a=this.readLine(),e=this.cleanupRawLine(a);''!=e&&(this.packageState==PS.PARSING_OUTSIDE?this.parseOutsideEntry(e):this.parseInsideEntry(e))}this.packageState=PS.PROCESSING}parseOutsideEntry(a){var e=a.indexOf('{');if(-1!=e){this.curlyBraceCount++;var t=a.substr(0,e).trim();this.startNewEntry(t)}else terminal.warning(`Skipping line "${a}" while parsing package ${this.url} at line ${this.lineNumber}`)}startNewEntry(a){var e=PackageGrammar.entryTypes[a];if(null!=e){switch(e){case'param-package':this.currentEntry=new ParamPackage(this,a);break;case'tess-package':this.currentEntry=new TessPackage(this,a);break;case'json-package':this.currentEntry=new JsonPackage(this,a);break;default:return void terminal.logic(`Unhandled packageType ${e}`)}this.packageEntries.push(this.currentEntry),this.packageState=PS.PARSING_INSIDE}else terminal.warning(`Skipping unknown entry name "${a}" while parsing package ${this.url} at line ${this.lineNumber}`)}parseInsideEntry(a){for(let e=0;e<a.length;e++)if('{'==a.charAt(e)&&this.curlyBraceCount++,'}'==a.charAt(e)&&(this.curlyBraceCount--,0==this.curlyBraceCount))return void(this.packageState=PS.PARSING_OUTSIDE);this.currentEntry.parseLine(a)}sortEntries(){this.packageEntries.sort(((a,e)=>{var t=PackageGrammar.processingOrder[a.entryName],r=PackageGrammar.processingOrder[e.entryName];return t<r?-1:t>r?1:0}))}validateEntries(){for(let e=0;e<this.packageEntries.length;e++){var a=this.packageEntries[e];switch(a.entryName){case'MenuOptions':case'PanelOptions':case'Layer':case'Legend':case'Citation':case'Metadata':case'Startup':a.validateParams();break;case'SpatialOptions':a.validateSpatialOptions();break;case'Packages':case'Tess':case'SpatialData':break;default:terminal.logic(`Unexpected entryName ${a.entryName}`)}}}async processEntries(){for(let a=0;a<this.packageEntries.length;a++)await this.packageEntries[a].processEntry()}async processDeclaredPackages(a){expect(a,'Object');for(let s of Object.keys(a)){var e=a[s],t=new URL(e,window.location.href);if(1==PackageHandler.allPackages.includes(t.href))return void terminal.warning(`The package identified as ${s} (${t.href}) has already been added. Skipping.`);var r=new PackageHandler(this.thematicEarthElement);await r.retrieveData(e)}}readLine(){for(var a=this.payloadOffset,e=0,t='';'\n'!=t;)if(t=this.payload.charAt(a+e),a+ ++e>this.payloadLength)throw new Error('reached end of file before it was expected');return this.payloadOffset=a+e,this.lineNumber++,this.payload.substr(a,e-1)}cleanupRawLine(a){var e=a.lastIndexOf('//');return 0==e?'':e>0&&':'!=a.charAt(e-1)?(a=a.substr(0,e),this.cleanupRawLine(a)):a.trim()}}