jsonstat-toolkit
Version:
JSON-stat JavaScript Toolkit: a library to deal with JSON-stat responses.
3 lines (2 loc) • 15.1 kB
JavaScript
// jsonstat-toolkit v2.0.0 Copyright 2025 Xavier Badosa https://jsonstat.com
var JSONstat=function(){"use strict";const t=t=>"[object ArrayBuffer]"===Object.prototype.toString.call(t.buffer),e=t=>["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"].includes(t);function n(i,l){const s=(n,i,l)=>{if(0===Object.entries(n).length)return null;let s,r=[];if(l&&!e(l.name)&&(l=null),"string"==typeof n&&(n=[n]),Array.isArray(n)||t(n)){if(n.length===i)return l&&-1===n.findIndex(t=>null==t)?l.from(n):n;if(1===n.length)return Array(i).fill(n[0])}for(s=0;s<i;s++)r.push(void 0===n[s]?null:n[s]);return r},r=t=>{const e=void 0===t.index?t.label:t.index;return Array.isArray(e)?e.length:Object.keys(e).length};let o,u;if(this.length=0,this.id=[],null!=i)switch(this.class=i.class||"bundle",this.class){case"bundle":if(this.error=null,this.length=0,null===i||"object"!=typeof i)return void(this.class=null);if(i.hasOwnProperty("error"))return void(this.error=i.error);if("dataset"===i.class||"collection"===i.class||"dimension"===i.class)return new n(i);const e=Object.keys(i);this.__tree__=i,this.length=e.length,this.id=e;break;case"dataset":this.__tree__=o=i.hasOwnProperty("__tree__")?i.__tree__:i,this.label=o.label||null,this.note=o.note||null,this.link=o.link||null,this.href=o.href||null,this.updated=o.updated||null,this.source=o.source||null,this.extension=o.extension||null;let a=0;const h=o.size||o.dimension&&o.dimension.size;if(this.size=h,this.value=o.hasOwnProperty("value")&&null!==o.value&&0!==o.value.length?o.value:{},a=Array.isArray(this.value)||t(this.value)?this.value.length:h.reduce((t,e)=>t*e,1),this.value=s(this.value,a,l),this.status=o.hasOwnProperty("status")&&null!==o.status?s(o.status,a):null,o.hasOwnProperty("dimension")){const t=o.dimension,e=o.role||!o.version&&t.role||null,n=o.id||t.id,i=h.length,l=t=>{e.hasOwnProperty(t)||(e[t]=null)};if(!Array.isArray(n)||!Array.isArray(h)||n.length!=i)return;if(this.length=i,this.id=n,e&&(l("time"),l("geo"),l("metric"),l("classification")),e&&null===e.classification){let t=[];for(const n of["time","geo","metric"]){const i=e[n];null!==i&&(t=t.concat(i))}const i=n.filter(e=>!t.includes(e));e.classification=i.length?i:null}this.role=e,this.n=a;for(let e=0,i=this.length;e<i;e++)if(t[n[e]].category.hasOwnProperty("index")){if(Array.isArray(t[n[e]].category.index)){const i={};t[n[e]].category.index.forEach((t,e)=>{i[t]=e}),t[n[e]].category.index=i}}else{let i=0;for(u in t[n[e]].category.index={},t[n[e]].category.label)t[n[e]].category.index[u]=i++}}else this.length=0;break;case"dimension":if(!i.hasOwnProperty("__tree__"))return new n({version:"2.0",class:"dataset",dimension:{d:i},id:["d"],size:[r(i.category)],value:[null]}).Dimension(0);o=i.__tree__;const c=[],f=o.category;if(!o.hasOwnProperty("category"))return;if(!f.hasOwnProperty("label"))for(u in f.label={},f.index)f.label[u]=u;for(u in f.index)c[f.index[u]]=u;this.__tree__=o,this.label=o.label||null,this.note=o.note||null,this.link=o.link||null,this.href=o.href||null,this.id=c,this.length=c.length,this.role=i.role,this.hierarchy=f.hasOwnProperty("child"),this.extension=o.extension||null;break;case"category":const d=i.child;this.id=d,this.length=null===d?0:d.length,this.index=i.index,this.label=i.label,this.note=i.note||null,this.unit=i.unit,this.coordinates=i.coord;break;case"collection":if(this.length=0,this.label=i.label||null,this.note=i.note||null,this.link=i.link||null,this.href=i.href||null,this.updated=i.updated||null,this.source=i.source||null,this.extension=i.extension||null,null!==this.link&&i.link.item){const t=i.link.item;this.length=Array.isArray(t)?t.length:0,this.length&&(this.id=t.map(t=>t.href))}}}n.prototype.Item=function(t){return null!==this&&"collection"===this.class&&this.length?"number"==typeof t?t>this.length||t<0?null:this.link.item[t]:"object"!=typeof t||null===t?this.link.item:t.class?this.link.item.filter(e=>{if(e.class!==t.class)return!1;if("dataset"===t.class&&"boolean"==typeof t.embedded){const n=e.id&&e.size&&e.dimension;return t.embedded?n:!n}return!0}):null:null},n.prototype.Dataset=function(t){if(null===this)return null;if("dataset"===this.class)return void 0!==t?this:[this];if("collection"===this.class){const e=this.Item({class:"dataset",embedded:!0});if(void 0===t)return e.map(t=>new n(t));if("number"==typeof t&&t>=0&&t<e.length)return new n(e[t]);if("string"==typeof t){const i=e.find(e=>e.href===t);if(i)return new n(i)}return null}if("bundle"!==this.class)return null;if(void 0===t)return this.id.map(t=>this.Dataset(t));if("number"==typeof t){const e=this.id[t];return void 0!==e?this.Dataset(e):null}const e=this.__tree__[t];return void 0===e?null:new n({class:"dataset",__tree__:e})},n.prototype.Dimension=function(t,e){e="boolean"!=typeof e||e;const i=(t,e)=>{if(null!==t)for(let n in t)for(let i=null!==t[n]?t[n].length:0;i--;)if(t[n][i]===e)return n;return null};if(null===this||"dataset"!==this.class)return null;if(void 0===t)return this.id.map(t=>this.Dimension(t));if("number"==typeof t){const n=this.id[t];return void 0!==n?this.Dimension(n,e):null}const l=this.role;if("object"==typeof t){if(t.hasOwnProperty("role")){const n=[];for(let s=0,r=this.id.length;s<r;s++){const r=this.id[s];i(l,r)===t.role&&n.push(this.Dimension(r,e))}return void 0===n[0]?null:n}return null}const s=this.__tree__.dimension;if(void 0===s)return null;const r=s[t];return void 0===r?null:e?new n({class:"dimension",__tree__:r,role:i(l,t)}):((t,e)=>{let n=[];for(let i in t)n[t[i]]=e[i];return n})(r.category.index,r.category.label)},n.prototype.Category=function(t){if(null===this||"dimension"!==this.class)return null;if(void 0===t)return this.id.map(t=>this.Category(t));if("number"==typeof t){const e=this.id[t];return void 0!==e?this.Category(e):null}const e=this.__tree__.category;if(void 0===e)return null;const i=e.index[t];if(void 0===i)return null;const l=e.unit&&e.unit[t]||null,s=e.coordinates&&e.coordinates[t]||null,r=e.child&&e.child[t]||null,o=e.note&&e.note[t]||null;return new n({class:"category",index:i,label:e.label[t],note:o,child:r,unit:l,coord:s})},n.prototype.Dice=function(e,i,l){let s,r,o,u;const a=(t,e)=>t.hasOwnProperty(e)&&!!t[e];if(null===this||"dataset"!==this.class||null===this.value)return null;if("object"!=typeof e)return this;"object"!=typeof i?("boolean"==typeof i&&!0===i&&(s=!0),"boolean"==typeof l&&!0===l||(l=!1)):(s=a(i,"clone"),l=a(i,"drop"),r=a(i,"stringify"),o=a(i,"ovalue"),u=a(i,"ostatus"));let h,c=[],f=[];const d=this.value,y=s?new n(JSON.parse(JSON.stringify(this))):this,p=y.status,b=(t,e)=>{const n=((t,e)=>{const n={};return Array.isArray(t[e])?(t[e].forEach((t,e)=>{null!==t&&(n[String(e)]=t)}),n):t[e]})(t,e);delete t[e],t[e]=n};Array.isArray(e)&&(e=(t=>{const e={};return t.forEach(t=>{e[t[0]]=t[1]}),e})(e)),null===e&&(e={});const g=Object.keys(e);return g.length>0&&(g.forEach(t=>{const n=e[t];Array.isArray(n)||(e[t]=[n]),0===e[t].length&&delete e[t]}),l&&(e=(t=>{const e={};return Object.keys(t).forEach(n=>{e[n]=y.Dimension(n).id.filter(e=>-1===t[n].indexOf(e))}),e})(e)),y.toTable({type:"arrobj",content:"id",status:!0}).forEach(t=>{let n=[];g.forEach(i=>{const l=e[i];let s=[];l.forEach(e=>{s.push(t[i]===e)}),n.push(-1!==s.indexOf(!0))}),-1===n.indexOf(!1)&&(c.push(t.value),f.push(t.status))}),g.forEach(t=>{const n=y.Dimension(t).id,i={};let l=0;y.size[y.id.indexOf(t)]=e[t].length,n.forEach(n=>{-1!==e[t].indexOf(n)&&(i[n]=l,l++)}),y.__tree__.dimension[t].category.index=i}),y.n=c.length,y.value=y.__tree__.value=t(d)?((t,e)=>e.from(t))(c,d.constructor):c,y.status=y.__tree__.status=null!==p?f:null),r?(h=y.__tree__,h.hasOwnProperty("id")||(h.version="2.0",h.hasOwnProperty("class")||(h.class="dataset"),h.id=h.dimension.id,h.size=h.dimension.size,delete h.dimension.id,delete h.dimension.size,h.dimension.hasOwnProperty("role")&&(h.role=h.dimension.role,delete h.dimension.role)),h.hasOwnProperty("status")&&-1!==["null","{}","[]"].indexOf(JSON.stringify(h.status))&&delete h.status,h.hasOwnProperty("role")&&(delete h.role.classification,["geo","time","metric"].forEach(t=>{null===h.role[t]&&delete h.role[t]})),o&&b(h,"value"),u&&h.hasOwnProperty("status")&&b(h,"status"),JSON.stringify(h)):y},n.prototype.Slice=function(t){return null===this||"dataset"!==this.class||0===Object.entries(this.value).length?null:void 0===t?this:(Array.isArray(t)||(t=Object.keys(t).map(e=>[e,t[e]])),this.Dice(t.map(t=>[t[0],[t[1]]])))},n.prototype.Data=function(t,e){let n,i,l=[],s=t=>{for(let e in t)if(t.hasOwnProperty(e))return e};if(null===this||"dataset"!==this.class||null===this.value)return null;if(void 0===t)return this.value.map((t,e)=>this.Data(e));if("boolean"!=typeof e&&(e=!0),"number"==typeof t){const n=this.value[t];return void 0===n?null:e?{value:n,status:this.status?this.status[t]:null}:n}let r="object";const o=this.__tree__,u=o.size||o.dimension&&o.dimension.size,a=u.length;if(Array.isArray(t)){if(!Array.isArray(t[0])){if(this.length!==t.length)return null;let i=1,s=0,r=[],o=[];for(n=0;n<a;n++)if(void 0!==t[n]){if("number"!=typeof t[n]||t[n]>=u[n])return null;i*=n>0?u[a-n]:1,s+=i*t[a-n-1]}else r.push(n),o.push(u[n]);if(r.length>1)return null;if(1===r.length){for(let i=0,s=o[0];i<s;i++){let s=[];for(n=0;n<a;n++)n!==r[0]?s.push(t[n]):s.push(i);l.push(this.Data(s,e))}return l}return e?{value:this.value[s],status:this.status?this.status[s]:null}:this.value[s]}r="array"}let h=[];const c=((t,e,n)=>{let i,l=[],r={};const o=t.dimension,u=t.id||o.id,a=t.size||o&&o.size;if("array"===n){for(i=e.length;i--;)r[e[i][0]]=e[i][1];e=r}for(let t=0,n=u.length;t<n;t++){const n=u[t],i=e[n];l.push("string"==typeof i?i:1===a[t]?s(o[n].category.index):null)}return l})(o,t,r),f=o.dimension,d=o.id||f.id;for(n=0,i=c.length;n<i;n++)h.push(f[d[n]].category.index[c[n]]);return this.Data(h,e)},n.prototype.toTable=function(t,n){if(null===this||"dataset"!==this.class||null===this.value)return null;1==arguments.length&&"function"==typeof t&&(n=t,t=null);const i=void 0!==(t=t||{field:"label",content:"label",vlabel:"Value",slabel:"Status",type:"array",status:!1,unit:!1,by:null,prefix:"",drop:[],meta:!1,comma:!1,bylabel:!1}).prefix?t.prefix:"";let l,s,r,o,u;"arrobj"!==t.type&&"objarr"!==t.type||void 0!==t.field||(t.field="id");const a="id"===t.field,h=t=>(a?"value":t)||"Value",c=t=>(a?"status":t)||"Status",f=this.__tree__;let d=!0===t.status;if("function"==typeof n){l=this.toTable(t);let e=[];const i="array"!==t.type?0:1,r="object"!==t.type?l.slice(i):l.rows.slice(0);for(u=r.length,s=0;s<u;s++){const t=n.call(this,r[s],s);void 0!==t&&e.push(t)}return"object"===t.type?{cols:l.cols,rows:e}:("array"===t.type&&e.unshift(l[0]),e)}if("arrobj"===t.type||"objarr"===t.type){let n=[],o=function(){},a={};const c=f.role&&f.role.metric,y=this,p=y.id,b=t.by&&-1!==p.indexOf(t.by)?t.by:null,g=!0===t.meta,m=void 0!==t.drop&&Array.isArray(t.drop)?t.drop:[],v=!0===t.comma,_=!0===t.bylabel,O=y.value.constructor,x=n=>{const l=h(t.vlabel);let s,r={};return"objarr"===t.type&&(s=null===b&&e(O.name)?t=>{r[t]=t===l?O.from(n,e=>e[t]):n.map(e=>e[t])}:t=>{r[t]=n.map(e=>e[t])},Object.keys(n[0]).forEach(s),n=r),g?(r={},p.forEach(t=>{const e=y.Dimension(t);r[t]={label:e.label,role:e.role,categories:{id:e.id,label:y.Dimension(t,!1)}}}),{meta:{label:y.label,source:y.source,updated:y.updated,id:p,status:d,unit:t.unit,by:b,bylabel:_,drop:null!==b&&m.length>0?m:null,prefix:null!==b?i||"":null,comma:v,dimensions:r},data:n}):n};b&&(t.field="id"),l=this.toTable({field:t.field,vlabel:t.vlabel,slabel:t.slabel,content:t.content,status:d});const A=l.shift();if(null===b&&t.unit&&c){if("id"!==t.content)for(let t=c.length;t--;){const e=this.Dimension(c[t]);a[c[t]]={};for(let n=e.length;n--;)a[c[t]][e.Category(n).label]=e.id[n]}o=function(e,n){if(-1!==c.indexOf(e)){const i=f.dimension[e].category;i.unit?tblr.unit=i.unit["id"!==t.content?a[e][n]:n]:tblr.unit=null}},t.unit=!0}else t.unit=!1;for(u=l.length,s=0;s<u;s++){let t={};for(r=l[s].length;r--;)t[A[r]]=l[s][r],o(A[r],l[s][r]);n.push(t)}if(v&&n.forEach(function(t){null!==t.value&&(t.value=String(t.value).replace(".",","))}),null!==b){const e={},l={};let s,r=[];m.forEach(function(t,e){(!y.Dimension(t)||y.Dimension(t).length>1)&&(m[e]="")});const o=p.filter(function(t){return t!==b&&-1===m.indexOf(t)}),u=y.Dimension(b),a=function(t,e){let n=[];return e.forEach(function(e){n.push(t[e])}),n.join("\t")},h=function(t,e){const n={};return e.forEach(function(e){n[e]=t[e]}),n};"id"!==t.content?_?s=function(t,e,n){t[e][`${i}${n[b]}`]=n.value}:(u.Category().forEach(function(t,e){l[t.label]=u.id[e]}),s=function(t,e,n){t[e][`${i}${l[n[b]]}`]=n.value}):s=function(t,e,n){t[e][`${i}${n[b]}`]=n.value},n.forEach(function(t){const n=a(t,o);void 0===e[n]&&(e[n]=h(t,o)),s(e,n,t,b)});for(let t in e)r.push(e[t]);return d=!1,x(r)}return x(n)}let y,p,b,g,m=[];if("object"===t.type){const t="number"==typeof this.value[0]||null===this.value[0]?"number":"string";y=function(t,e){const n=a&&t||e||t;z.push({id:t,label:n,type:"string"})},p=function(e,n,i){const l=h(e),s=c(n);i&&z.push({id:"status",label:s,type:"string"}),z.push({id:"value",label:l,type:t})},b=function(t){m.push({v:t})},g=function(t){m.push({v:t}),S.push({c:m})}}else y=function(t,e){const n=a&&t||e||t;z.push(n)},p=function(t,e,n){const i=h(t),l=c(e);n&&z.push(l),z.push(i),P.push(z)},b=function(t){m.push(t)},g=function(t){m.push(t),P.push(m)};const v=f.dimension,_=f.id||v.id,O=f.size||v.size,x=_.length;if(x!=O.length)return!1;let A=[],w=1,j=1,D=[],k=[],E=[],P=[],z=[],S=[];for(s=0;s<x;s++){const e=_[s];y(e,v[e].label),w*=O[s],j*=O[s];let n=[];for(r=0;r<O[s];r++)for(let e in v[_[s]].category.index)if(v[_[s]].category.index[e]===r){const i="id"!==t.content&&v[_[s]].category.label?v[_[s]].category.label[e]:e;n.push(i)}A.push(n),D.push(j)}for(p(t.vlabel,t.slabel,d),u=A.length,s=0;s<u;s++){let t=[];for(let e=0,n=A[s].length;e<n;e++)for(let n=0;n<w/D[s];n++)t.push(A[s][e]);k.push(t)}for(u=k.length,s=0;s<u;s++){let t=[],e=0;for(o=0;o<w;o++)t.push(k[s][e]),e++,e===k[s].length&&(e=0);E.push(t)}for(o=0;o<w;o++){m=[],u=k.length;for(let t=0;t<u;t++)b(E[t][o]);d&&b(this.status?this.status[o]:null),g(this.value[o])}return"object"===t.type?{cols:z,rows:S}:P},n.prototype.node=function(){return this.__tree__},n.prototype.toString=function(){return this.class},n.prototype.Unflatten=function(t){if(null===this||"dataset"!==this.class||null===this.value||"function"!=typeof t)return null;const e=this.id,n=this.size,i=[];for(let l=0;l<this.n;l++){const s=this.Data(l),r={};let o=l;for(let t=e.length-1;t>=0;t--){const e=this.Dimension(t),i=this.id[t],l=n[t],s=o%l,u=e.id[s];o=Math.floor(o/l),r[i]=u}const u=t(r,s,l,i);void 0!==u&&i.push(u)}return i};const i=t=>{if(!t.ok)throw new Error(`${t.status} ${t.statusText}`);return t.json()};return function(t,e,l){const s="object"==typeof e?e:{method:"GET"};return"function"!=typeof l&&(l=null),l||"function"!=typeof e||(l=e),"object"==typeof t?new n(t,l):"version"===t?"2.0.0":fetch?fetch(t,s).then(i).then(t=>new n(t,l)).catch(t=>{throw t}):void 0}}();