@holistics/anfra-sdk 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +1 -1
- package/dist/host.js +1 -1
- package/package.json +1 -1
package/dist/app.js
CHANGED
package/dist/host.js
CHANGED
|
@@ -71,7 +71,7 @@ function serveBridge(frame, backend, callbacks = {}) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// frame-script:anfra-sdk:frame-script
|
|
74
|
-
var anfra_sdk_frame_script_default = '"use strict";(()=>{var ze=Object.defineProperty;var Pe=(t,n,e)=>n in t?ze(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e;var d=(t,n,e)=>Pe(t,typeof n!="symbol"?n+"":n,e);var $=class extends Error{constructor(e,r){super(e);d(this,"entity");this.name=new.target.name,this.entity=r,Object.setPrototypeOf(this,new.target.prototype)}},p=class extends ${},T=class extends ${constructor(e,r,i){super(e,r);d(this,"cause");this.cause=i}},P=class extends ${},V=class extends ${constructor(e,r,i){super(e,i);d(this,"status");this.status=r}};var ae="anfra-provision";var O=class{constructor(n){d(this,"listeners",new Set);d(this,"parent");this.parent=n}subscribe(n){return this.listeners.add(n),()=>{this.listeners.delete(n)}}notifyChange(){this.listeners.forEach(n=>n()),this.parent?.notifyChange()}notify(){this.notifyChange()}};var F=class extends O{constructor(e,r,i){super(r);d(this,"kind","query");d(this,"name");d(this,"declaration");d(this,"dataset");d(this,"app");d(this,"_state","idle");d(this,"_result");d(this,"_error");d(this,"_page",1);d(this,"_sort",[]);d(this,"lastRunSignature");d(this,"lastPageRows",0);d(this,"controller");if(!i.aql?.trim())throw new p(`Query \'${e}\' declares no AQL.`,e);let{pageSize:s}=i;if(s!==void 0&&!(Number.isInteger(s)&&s>=1))throw new p(`Query \'${e}\' declares pageSize ${s}; it must be a whole number of at least 1.`,e);this.name=e,this.app=r,this.declaration=i,this.dataset=r.datasetIndex(i.dataset,e)}locate(){return this.app.locate("query",this.name)}get state(){return this._state}get result(){return this._result}get error(){return this._error}get pageSize(){return this.declaration.pageSize}get page(){return this._page}get sort(){return this._sort}setSort(e){this._sort=[...e],this.notify()}get hasMore(){return!this._result||this.pageSize===void 0?!1:this.lastPageRows>=this.pageSize}signature(){let e=this.app.mappingsTo(this.name).map(r=>({field:r.field,aggregation:r.aggregation,condition:r.from.condition})).sort((r,i)=>r.field.localeCompare(i.field)||JSON.stringify(r).localeCompare(JSON.stringify(i)));return JSON.stringify({declaration:this.declaration,conditions:e,selection:this.app.selectionConditionsFor(this.name,"pending"),selectionExpression:this.app.selectionExpressionFor(this.name,"pending"),sort:this._sort,timezone:this.app.timezone,page:this._page})}get isDirty(){return this.lastRunSignature!==void 0&&this.signature()!==this.lastRunSignature}shouldRun(e=!1){return e||this.lastRunSignature===void 0||this.isDirty}abort(){this.controller?.abort()}async fetchMore(){if(this.pageSize===void 0)throw new p(`Query \'${this.name}\' declares no pageSize, so it has no more pages.`,this.name);this.hasMore&&(this._page+=1,await this.app.fetchPage(this))}select(e,r={}){this.app.select(this,Array.isArray(e)?e:[e],r.fields)}get selectedRows(){let{selection:e}=this.app;if(e?.source!==this.name)return[];let r=this._result?.rows;if(!r)return e.rows;let i=l=>JSON.stringify(e.fields.map(o=>l[o]??null)),s=new Set(e.rows.map(i));return r.filter(l=>s.has(i(l)))}markExecuting(){this._state="executing",this._error=void 0,this.notify()}markSuccess(e,r,i){if(this._state="success",this._error=void 0,this.lastRunSignature=r,this.lastPageRows=e.rows.length,i&&this._result){let s=[...this._result.rows,...e.rows];this._result={...e,rows:s,meta:{...e.meta,numRows:s.length}}}else this._result=e;this.notify()}markError(e){this._state="error",this._error=e,this.notify()}rewindPage(){this._page>1&&(this._page-=1)}resetPage(){this._page=1,this.lastPageRows=0}toJSON(){return this.declaration}};var le=["year","quarter","month","week","day","hour","minute"];function Ve(t,n){if(!le.includes(n))throw new p(`Invalid grain \'${n}\'. Expected one of: ${le.join(", ")}.`,t)}function de(t,n){return n?(Ve(t,n),{operator:"transform_date_drill",values:[`datetrunc ${n}`]}):{operator:"none"}}function Je(t){let n=t.toLowerCase();return n.includes("date")||n.includes("time")?"date":n.includes("int")||n.includes("number")||n.includes("float")||n.includes("decimal")?"number":n.includes("bool")?"boolean":"string"}function je(t,n){return JSON.stringify(t??null)===JSON.stringify(n??null)}var I=class extends O{constructor(e,r,i){super(r);d(this,"name");d(this,"app");d(this,"pending");d(this,"applied");d(this,"initial");this.name=e,this.app=r,this.initial=i,this.pending=i}locate(){return this.app.locate("control",this.name)}get condition(){return this.pending}get appliedCondition(){return this.applied}get isDirty(){return this.applied!==void 0&&!je(this.pending,this.applied)}setCondition(e){this.pending=e,this.notify()}reset(){this.setCondition(this.initial)}commit(){this.applied=this.pending}},J=class extends I{constructor(e,r,i,s,l){super(e,r,i.default??{operator:"is",values:[]});d(this,"kind","filter");d(this,"declaration");d(this,"type");d(this,"resolved");d(this,"datasetName");d(this,"backend");d(this,"loadedOptions");if(this.declaration=i,this.backend=l,i.field){if(!s)throw new p(`Filter \'${e}\' names a field but no dataset. Pass \\`dataset\\` alongside \\`field\\`.`,e);this.resolved=s.resolve(i.field,e),this.datasetName=s.descriptor.name,this.type=i.type??Je(this.resolved.type)}else{if(!i.type)throw new p(`Filter \'${e}\' is a manual filter, so it needs a \\`type\\`.`,e);this.type=i.type}this.assertValues(this.condition.values??[]),this.assertValues(i.options??[])}setCondition(e){this.assertValues(e.values??[]),super.setCondition(e)}assertValues(e){if(this.type!=="number")return;let r=e.find(i=>typeof i=="number");if(r!==void 0)throw new p(`Filter \'${this.name}\' filters numbers: give its values as strings, as query results give them (${JSON.stringify(String(r))}, not ${String(r)}), so none has lost a digit.`,this.name)}get isFieldBacked(){return this.resolved!==void 0}get options(){return this.loadedOptions??this.declaration.options??[]}async loadOptions(e,r=new AbortController().signal){let i=this.resolved?.modelName;if(!this.resolved||!i||!this.backend||!this.datasetName)return this.options;let s=await this.backend.fieldSuggestions({dataset:this.datasetName,model:i,field:this.resolved.fieldName,q:e??""},r);return this.loadedOptions=[...s??[]],this.notify(),this.loadedOptions}toJSON(){return this.declaration}},j=class extends I{constructor(e,r,i={}){super(e,r,de(e,i.default));d(this,"kind","dateDrill");d(this,"declaration");this.declaration=i}setGrain(e){this.setCondition(de(this.name,e))}toJSON(){return this.declaration}};var G=class{constructor(n,e,r,i){d(this,"kind","control");d(this,"from");d(this,"to");d(this,"field");d(this,"aggregation");this.from=n,this.to=e,this.field=r,this.aggregation=i}get id(){return`${this.from.name}.${this.to.name}.${this.field}`}toJSON(){return{kind:this.kind,id:this.id,from:{kind:this.from.kind,name:this.from.name},to:{kind:"query",name:this.to.name},field:this.field,...this.aggregation?{aggregation:this.aggregation}:{}}}},q=class{constructor(n,e){d(this,"kind","crossFilter");d(this,"from");d(this,"to");this.from=n,this.to=e}get id(){return`${this.from.name}.${this.to.name}`}toJSON(){return{kind:this.kind,id:this.id,from:{kind:"query",name:this.from.name},to:{kind:"query",name:this.to.name}}}};var Z=["sum","avg","max","min","count","count distinct","median","stdev","stdevp","var","varp"];function Ge(t,n){let e=t.length+1,r=n.length+1,i=Array.from({length:r},(s,l)=>l);for(let s=1;s<e;s++){let l=[s];for(let o=1;o<r;o++)l[o]=Math.min(i[o]+1,l[o-1]+1,i[o-1]+(t[s-1]===n[o-1]?0:1));i=l}return i[r-1]}function qe(t,n){let e,r=1/0;n.forEach(s=>{let l=Ge(t.toLowerCase(),s.toLowerCase());l<r&&(r=l,e=s)});let i=Math.max(2,Math.floor(t.length/3));return r<=i?e:void 0}function M(t,n,e){let r=qe(n,e);return r?`${t} Did you mean \'${r}\'?`:t}var U=class{constructor(n){d(this,"descriptor");d(this,"fields",new Map);d(this,"references");this.descriptor=n,n.data_models.forEach(e=>{e.fields.forEach(r=>{let i=String(e.name);this.fields.set(`${i}.${r.name}`,{modelName:i,fieldName:r.name,isMetric:!1,type:r.type,label:r.label??r.name})})}),n.metrics.forEach(e=>{this.fields.set(e.name,{fieldName:e.name,isMetric:!0,type:e.type,label:e.label??e.name})}),this.references=[...this.fields.keys()]}resolve(n,e){let r=this.fields.get(n);if(r)return r;throw new p(M(`Unknown field \'${n}\' on dataset \'${this.descriptor.name}\'.`,n,this.references),e)}};function ce(t,n,e){let r=t[n];if(r)return r;throw new p(M(`Unknown dataset \'${n}\'.`,n,Object.keys(t)),e)}function ue(t,n){if(!Z.includes(t))throw new p(M(`Invalid filter aggregation \'${t}\'.`,t,[...Z]),n)}function pe(t,n,e){if(!n)throw new p(`A ${e} needs a name.`);for(let r of t)if(r===n)throw new p(`\'${n}\' is already declared in this app.`,n)}function Ue(t,n){if(!(!n||n.operator==="none"||n.operator==="transform_date_drill"||!["is_null","not_null","is_true","is_false","transform_pop_none"].includes(n.operator)&&!n.values?.length))return{field:t.field,operator:n.operator,values:n.values??[],...n.modifier?{modifier:n.modifier}:{},...t.aggregation?{aggregation:t.aggregation}:{}}}function Ke(t,n){if(n?.operator!=="transform_date_drill")return;let e=n.values?.[0];if(typeof e!="string")return;let r=e.replace(/^datetrunc\\s+/,"");return{field:t.field,grain:r}}function He(t,n){let e=n.columns??[],r=(n.values??[]).map(s=>{let l={};return e.forEach((o,a)=>{l[o.name]=s[a]}),l}),{pageSize:i}=t;return{columns:e,rows:r,meta:{...i!==void 0?{page:n.meta?.page??t.page,pageSize:n.meta?.pageSize??i}:{},numRows:n.meta?.numRows??r.length},...n.debug?{debug:n.debug}:{}}}function We(t,n,e,r){let i=n.map(a=>Ue(a,a.from.appliedCondition)).filter(a=>a!==void 0),s=n.map(a=>Ke(a,a.from.appliedCondition)).filter(a=>a!==void 0),l=e.conditions.map(a=>({field:a.field,operator:a.operator,values:a.values})),o=e.expression?[{expr:e.expression}]:[];return{dataset:t.dataset.descriptor.name,aql:t.declaration.aql,input:{filters:[...i,...l],conditions:o,sorts:t.sort.map(a=>({field:a.field,direction:a.direction??"asc"})),dateDrills:s},...t.pageSize!==void 0?{page:t.page,pageSize:t.pageSize}:{},...r.timezone?{timezone:r.timezone}:{},...r.bustCache?{bustCache:!0}:{}}}async function ee(t,n,e,r,i){let s=We(t,n,e,r),l=await r.backend.submitQuery(s,i);return He(t,l)}function Ye(t,n){if(t===null)return"null";if(typeof t=="boolean")return t?"true":"false";if(n==="number"&&typeof t=="string")return et(t);if(typeof t=="number"){if(!Number.isFinite(t))throw new RangeError(`Cannot express ${t} in AQL.`);return Math.abs(t)>=1e21?BigInt(t).toString():String(t)}return JSON.stringify(t).split("\\u2028").join("\\\\u2028").split("\\u2029").join("\\\\u2029")}function fe(t,n,e){return n===null?`is(${t}, null)`:`${t} is ${Ye(n,e)}`}var Xe=new Set(["NaN","Infinity","-Infinity"]),Ze=/^(-?)(0|[1-9]\\d*)(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/;function et(t){let n=Ze.exec(t);if(!n)throw Xe.has(t)?new RangeError(`Cannot express ${t} in AQL.`):new TypeError(`${JSON.stringify(t)} is not a number: a number is a string in JSON\'s number syntax.`);let[,e,r,i="",s]=n;if(s===void 0)return t;let l=r+i,o=r.length+Number(s),a;return o<=0?a=`0.${"0".repeat(-o)}${l}`:o>=l.length?a=l+"0".repeat(o-l.length):a=`${l.slice(0,o)}.${l.slice(o)}`,e+a.replace(/^0+(?=\\d)/,"")}function me(t,n,e){return`${t} matches @(${n} until ${e})`}function he(t,n){if(n.length===0)throw new RangeError(`\\`${t}\\` needs at least one operand.`);return n.length===1?n[0]:`${t}(${n.join(", ")})`}var ge=t=>he("and",t),ye=t=>he("or",t);var tt=/^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?)?/,nt={week:7*864e5,day:864e5,hour:36e5,minute:6e4};function be(t){if(typeof t!="string")return;let n=tt.exec(t);if(n)return{year:Number(n[1]),month:Number(n[2])-1,day:Number(n[3]),hour:Number(n[4]??0),minute:Number(n[5]??0),second:Number(n[6]??0),hasTime:n[4]!==void 0}}function L(t,n){let e=new Date(t),r=s=>String(s).padStart(2,"0"),i=`${e.getUTCFullYear()}-${r(e.getUTCMonth()+1)}-${r(e.getUTCDate())}`;return n?`${i} ${r(e.getUTCHours())}:${r(e.getUTCMinutes())}:${r(e.getUTCSeconds())}`:i}function we(t){return Date.UTC(t.year,t.month,t.day,t.hour,t.minute,t.second)}function te(t){let n=be(t);if(n)return L(we(n),n.hasTime)}function ne(t,n){let e=be(t);if(!e)return;let{year:r,month:i,day:s,hour:l,minute:o,second:a,hasTime:c}=e;return L(n==="year"?Date.UTC(r+1,i,s,l,o,a):n==="quarter"?Date.UTC(r,i+3,s,l,o,a):n==="month"?Date.UTC(r,i+1,s,l,o,a):we(e)+nt[n],c)}function ke(t){if(t?.startsWith("datetrunc "))return t.slice(10)}function rt(t){let n=new Set;return t.filter(e=>{let r=`${typeof e}:${String(e)}`;return n.has(r)?!1:(n.add(r),!0)})}function it(t,n){let e=t.map(te);if(e.some(i=>i===void 0))return!1;let r=e.slice().sort();for(let i=1;i<r.length;i+=1)if(ne(r[i-1],n)!==r[i])return!1;return!0}function st(t,n,e){let r=n.map(te);if(r.some(a=>a===void 0))return;let i=r.slice().sort(),s=i[0],l=ne(i[i.length-1],e);if(!l)return;let o=it(n,e);return{condition:{field:t,operator:"matches",values:[`${s} until ${l}`]},admits:o?n.length:Number.POSITIVE_INFINITY,lossy:!o}}function ot(t,n,e){let r=e.filter(o=>o!=null),i=rt(r);if(!i.length)return{condition:{field:t,operator:"is_null",values:[]},admits:1,lossy:!1};let s=r.length!==e.length,l=ke(n);if(l){let o=st(t,i,l);if(o)return{...o,lossy:o.lossy||s}}return{condition:{field:t,operator:"is",values:i},admits:i.length,lossy:s}}function ve(t){return t.modelId?`${t.modelId}.${t.fieldName}`:t.fieldName}function at(t,n,e,r){try{let i=e.map(s=>ge(n.map(l=>{let o=t.get(l),a=ve(o),c=s[l]??null,b=ke(r[a]);if(b&&typeof c=="string"){let S=te(c),u=ne(c,b);if(S&&u)return me(a,S,u)}if(c!==null&&typeof c!="string"&&typeof c!="number"&&typeof c!="boolean")throw new TypeError("no AQL spelling");return fe(a,c,o.semantic_type)})));return ye(i)}catch{return}}function Se(t,n,e,r={}){let i=t.result?.columns??[],s=new Map(i.map(h=>[h.name,h]));e?.forEach(h=>{let y=s.get(h);if(y){if(y.adhoc)throw new p(`Query \'${t.name}\' cannot cross-filter on \'${h}\': it is a query-local AQL expression, which only this query\'s result carries. The target query would receive a condition naming a field it has never heard of.`,t.name);if(y.isMeasure)throw new p(`Query \'${t.name}\' cannot cross-filter on \'${h}\': it is a measure, and a selection conditions dimensions only.`,t.name);return}throw new p(M(`Query \'${t.name}\' has no column \'${h}\' in its last result.`,h,[...s.keys()]),t.name)});let l=i.filter(h=>!h.isMeasure),o=l.filter(h=>!h.adhoc).map(h=>h.name),a=e?[...e]:o;if(!n.length||!a.length)return;let c=[],b=1,S=!e&&o.length!==l.length,u=!1;a.forEach(h=>{let y=s.get(h),A=ve(y),N=ot(A,r[A],n.map(w=>w[h]));c.push(N.condition),b*=N.admits,u=u||N.lossy});let v=new Set(n.map(h=>JSON.stringify(a.map(y=>h[y]??null))));b>v.size&&(u=!0);let x=c.sort((h,y)=>h.field.localeCompare(y.field)),E={source:t.name,rows:[...n],fields:a};if(u){let h=at(s,a,n,r);if(h)return{...E,conditions:[],expression:h,lossy:S}}return{...E,conditions:x,lossy:S||u}}var C={container:"data-anfra-container",block:"data-anfra-block",query:"data-anfra-query",control:"data-anfra-control",label:"data-anfra-label"},K=`[${C.container}],[${C.block}],[${C.query}],[${C.control}]`;function xe(t){let n=/^(?:(\\d+)\\/)?([^/\\s]+)$/.exec(t);if(n)return{app:n[1]===void 0?0:Number(n[1]),name:n[2]}}var Ee=t=>(t??"").split(/\\s+/).filter(Boolean);function Ce(t,n,e,r){let i=n==="query"?C.query:C.control;return[...t.querySelectorAll(`[${i}]`)].filter(s=>Ee(s.getAttribute(i)).some(l=>{let o=xe(l);return o?.app===e&&o.name===r}))}var lt=(t,n,e)=>{let r=t[e.app];return r?Object.prototype.hasOwnProperty.call(n==="query"?r.queries:r.controls,e.name):!1};function re(t,n){var S;let e=[],r=new Map,i=new Map,s=new Map,l=new Map,o={container:new Set,block:new Set},a={},c=(u,v,x)=>{let E=u?s.get(u).children:e,h=u?`${s.get(u).key}.`:"",y={...v,key:`${h}${E.length}`,children:[]};return E.push(y),r.set(y.key,x),i.set(x,[...i.get(x)??[],y.key]),y};for(let u of t.querySelectorAll(K)){let v=u.parentElement?.closest(K)??null,x=u.getAttribute(C.container),E=u.getAttribute(C.block),h=u.getAttribute(C.label)??void 0,y=v&&(l.get(v)==="block"?v:v.closest(`[${C.block}]`)),A;if(x!==null||E!==null){let w=x!==null?"container":"block",D=(x??E??"").trim(),k=[];x!==null&&E!==null&&k.push("This element is marked as a container and as a block. It counts as a container."),D?o[w].has(D)?k.push(`Another ${w} already has the id "${D}".`):o[w].add(D):k.push(`This ${w} has no id.`),y&&k.push(`A block can\'t hold a ${w}. This one is inside the block "${y.getAttribute(C.block)}".`),A=c(v,{kind:w,id:D,...h!==void 0?{label:h}:{},problems:k},u),s.set(u,A),l.set(u,w)}let N=A?u:v;for(let w of["query","control"])for(let D of Ee(u.getAttribute(w==="query"?C.query:C.control))){let k=xe(D),R=[];if(k?lt(n,w,k)||R.push(n[k.app]?`No ${w} is called "${k.name}" in app ${k.app}.`:`The page has no app ${k.app}.`):R.push(`Can\'t read "${D}". Write the ${w}\'s name, or app/name when the page has several apps.`),c(N,{kind:w,name:k?.name??D,app:k?.app??0,problems:R},u),k&&!R.length){let Y=`${k.app}/${k.name}`,f=a[S=`${w}:${Y}`]??(a[S]={elements:new Set,blocks:new Set});f.elements.add(u);let m=A?.kind==="block"?A.id:y?.getAttribute(C.block);m&&f.blocks.add(m)}}}let b=Object.fromEntries(Object.entries(a).map(([u,v])=>[u,{markers:v.elements.size,blocks:[...v.blocks]}]));return{nodes:e,usage:b,elements:r,keysOf:i}}var dt=(t,n,e)=>`${t}:${n}/${e}`;function ct(t){let n=t.getBoundingClientRect();return`${Math.round(n.width)} \\xD7 ${Math.round(n.height)}`}function De(t,n,e){let r=ct(n);if(t.kind==="container"||t.kind==="block")return{kind:t.kind,name:t.id??"",...t.label?{label:t.label}:{},size:r};let i=e.usage[dt(t.kind,t.app??0,t.name??"")];return{kind:t.kind,name:t.name??"",...i&&i.markers>1?{note:`1 of ${i.markers}`}:{},size:r}}var _e="anfra-overlay";var ut="position:fixed;box-sizing:border-box;background:rgba(37,99,235,0.22);outline:1px solid #2563eb;outline-offset:-1px;",pt="position:fixed;max-width:60vw;display:flex;gap:6px;align-items:baseline;padding:3px 8px;border-radius:4px;background:#0f172a;color:#f8fafc;font:12px/1.4 system-ui,sans-serif;white-space:nowrap;box-shadow:0 2px 8px rgba(0,0,0,0.35);",ft={kind:"color:#94a3b8;",name:"color:#93c5fd;font-weight:700;",label:"color:#f8fafc;",note:"color:#94a3b8;",size:"color:#94a3b8;margin-left:10px;"},ie=class{constructor(n){d(this,"doc",n);d(this,"root");d(this,"shown",[]);d(this,"text",{kind:"",name:""});d(this,"timer");d(this,"reposition",()=>this.draw());let e=n.getElementById(_e);e?this.root=e:(this.root=n.createElement("div"),this.root.id=_e,this.root.setAttribute("aria-hidden","true"),this.root.setAttribute("style","position:fixed;inset:0;z-index:2147483647;pointer-events:none;display:none;"),(n.body??n.documentElement).appendChild(this.root))}show(n,e){if(this.clearTimer(),this.shown=[...n],this.text=e,!this.shown.length){this.hide();return}this.root.style.display="block",this.draw(),this.doc.addEventListener("scroll",this.reposition,{capture:!0,passive:!0}),this.doc.defaultView?.addEventListener("resize",this.reposition)}flash(n,e,r=1500){this.show(n,e),this.timer=setTimeout(()=>this.hide(),r)}hide(){this.clearTimer(),this.shown=[],this.root.style.display="none",this.root.replaceChildren(),this.doc.removeEventListener("scroll",this.reposition,{capture:!0}),this.doc.defaultView?.removeEventListener("resize",this.reposition)}get visible(){return this.shown.length>0}clearTimer(){this.timer!==void 0&&clearTimeout(this.timer),this.timer=void 0}draw(){let n=this.shown.map(o=>{let a=o.getBoundingClientRect(),c=this.doc.createElement("div");return c.setAttribute("style",`${ut}left:${a.left}px;top:${a.top}px;width:${a.width}px;height:${a.height}px;`),c}),e=this.shown[0].getBoundingClientRect(),r=this.doc.createElement("div");r.setAttribute("data-testid","anfra-overlay-label");let i=this.doc.defaultView?.innerHeight??0,s=e.top>=26?e.top-24:Math.max(4,e.top+4),l=Math.max(4,Math.min(e.left,(this.doc.defaultView?.innerWidth??0)-24));r.setAttribute("style",`${pt}left:${l}px;top:${Math.min(s,i-24)}px;`);for(let o of["kind","name","label","note","size"]){let a=this.text[o];if(!a)continue;let c=this.doc.createElement("span");c.setAttribute("style",ft[o]),c.setAttribute("data-part",o),c.textContent=a,r.appendChild(c)}this.root.replaceChildren(...n,r)}},Ae=new WeakMap;function Q(t){let n=Ae.get(t);return n||(n=new ie(t),Ae.set(t,n)),n}function H(t){typeof t.scrollIntoView=="function"&&t.scrollIntoView({block:"center",inline:"nearest",behavior:"smooth"})}var se=Object.freeze([]);function Re(t){return t instanceof Error&&t.name==="AbortError"}function $e(t,n){return t.controller!==n}function mt(t){return{name:t.name,message:t.message,...t.entity?{entity:t.entity}:{},...typeof t.status=="number"?{status:t.status}:{},...t.stack?{stack:t.stack}:{}}}function ht(t){let{result:n}=t;return{state:t.state,isDirty:t.isDirty,page:t.page,hasMore:t.hasMore,columns:n?n.columns.map(e=>({...e})):[],rowCount:n?.meta.numRows??0,selectedRowCount:t.selectedRows.length,signature:t.signature(),...t.error?{error:mt(t.error)}:{},...n?.debug?{debug:{...n.debug}}:{}}}function gt(t){let{options:n}=t;return{kind:t.kind,condition:{...t.condition},...t.appliedCondition?{appliedCondition:{...t.appliedCondition}}:{},isDirty:t.isDirty,...n?{options:[...n]}:{}}}function Oe(t){return{source:t.source,fields:[...t.fields],rowCount:t.rows.length,conditions:t.conditions.map(n=>({...n})),...t.expression?{expression:t.expression}:{},lossy:t.lossy}}function Ne(t){return t?JSON.stringify({source:t.source,conditions:t.conditions,expression:t.expression}):"none"}function Te(t,n){return t instanceof $?t:new T(t?.message??"The query failed.",n,t)}var W=class extends O{constructor(e,r,i,s){super();d(this,"title");d(this,"_timezone");d(this,"datasets");d(this,"backend");d(this,"features");d(this,"_queries",new Map);d(this,"_controls",new Map);d(this,"_mappings",[]);d(this,"_crossFilters",[]);d(this,"_selection");d(this,"_appliedSelection");d(this,"selectionCommitted",!1);d(this,"index",0);this.title=e.title,this._timezone=e.timezone,this.datasets=r,this.backend=i,this.features=s}get queries(){return Object.fromEntries(this._queries)}get controls(){return Object.fromEntries(this._controls)}get mappings(){return[...this._mappings,...this._crossFilters]}get crossFilters(){return this._crossFilters}createQuery(e,r){this.assertNameFree(e,"query");let i=new F(e,this,r);return this._queries.set(e,i),this.notify(),i}createFilter(e,r){this.assertNameFree(e,"filter");let i=r.dataset?this.datasetIndex(r.dataset,e):this.soleDataset(e,r.field),s=new J(e,this,r,i,this.backend);return this._controls.set(e,s),this.notify(),s}createDateDrill(e,r={}){if(this.features?.dateDrill===!1)throw new p(`Date drill \'${e}\' needs a capability this workspace has not enabled. Ask an admin to turn on \\`interactive_control:date_drill\\`.`,e);this.assertNameFree(e,"date drill control");let i=new j(e,this,r);return this._controls.set(e,i),this.notify(),i}mapControl(e,r,i){if(!(e instanceof I))throw new p("mapControl expects a control as its source. To let one query cross-filter another, use app.mapCrossFilter(from, to) \\u2014 a cross-filter edge names no field.");if(this._controls.get(e.name)!==e)throw new p(`Control \'${e.name}\' belongs to a different app.`,e.name);if(this._queries.get(r.name)!==r)throw new p(`Query \'${r.name}\' belongs to a different app.`,r.name);i.aggregation&&ue(i.aggregation,e.name);let s=new G(e,r,i.field,i.aggregation);if(this._mappings.some(l=>l.id===s.id))throw new p(`Mapping \'${s.id}\' is already declared.`,e.name);return this.assertAcyclic(s),this._mappings.push(s),this.notify(),s}mapCrossFilter(e,r){if(!(e instanceof F)||!(r instanceof F))throw new p("mapCrossFilter expects two queries. To let a control condition a query, use app.mapControl(from, to, { field }).");if(this._queries.get(e.name)!==e)throw new p(`Query \'${e.name}\' belongs to a different app.`,e.name);if(this._queries.get(r.name)!==r)throw new p(`Query \'${r.name}\' belongs to a different app.`,r.name);if(e===r)throw new p(`Query \'${e.name}\' cannot cross-filter itself. A source keeps its own rows so it can show what is selected; filtering it would erase the very rows the reader clicked.`,e.name);if(e.declaration.dataset!==r.declaration.dataset)throw new p(`Cross-filter \'${e.name}\' -> \'${r.name}\' spans two datasets (\'${e.declaration.dataset}\' and \'${r.declaration.dataset}\'). A selection carries field references, which mean nothing outside the dataset that resolved them.`,e.name);let i=new q(e,r);if(this._crossFilters.some(s=>s.id===i.id))throw new p(`Cross-filter \'${i.id}\' is already declared.`,e.name);return this._crossFilters.push(i),this.notify(),i}get selection(){return this._selection}get appliedSelection(){return this._appliedSelection}clearSelection(){this._selection&&(this._selection=void 0,this.notify())}setTimezone(e){this._timezone=e,this.notify()}get timezone(){return this._timezone}datasetIndex(e,r){return ce(this.datasets,e,r)}mappingsTo(e){return this._mappings.filter(r=>r.to.name===e)}selectionExpressionFor(e,r){return this.selectionFor(e,r)?.expression}selectionFor(e,r){let i=r==="pending"?this._selection:this._appliedSelection;return!i||i.source===e?void 0:this._crossFilters.some(l=>l.from.name===i.source&&l.to.name===e)?i:void 0}selectionConditionsFor(e,r){let i=r==="pending"?this._selection:this._appliedSelection;return!i||i.source===e?se:this._crossFilters.some(l=>l.from.name===i.source&&l.to.name===e)?i.conditions:se}drillTransformations(e){let r={};return this._mappings.forEach(i=>{if(i.to!==e)return;let s=i.from.appliedCondition;if(s?.operator!=="transform_date_drill")return;let[l]=s.values??[];typeof l=="string"&&(r[i.field]=l)}),r}select(e,r,i){if(this._queries.get(e.name)!==e)throw new p(`Query \'${e.name}\' belongs to a different app.`,e.name);let s=Se(e,r,i,this.drillTransformations(e));s?.lossy&&console.warn(`[anfra-sdk] The selection in \'${e.name}\' filters more broadly than it was made. Its conditions are combined field by field and ANDed, which cannot express "(A and B) or (C and D)", so the targets will also show combinations that were not selected. Select within one dimension, or narrow with \\`fields\\`, to avoid this.`),this._selection=s,this.notify()}get hasChanges(){return[...this._controls.values()].some(e=>e.isDirty)||this.isSelectionDirty}get isSelectionDirty(){return this.selectionCommitted?Ne(this._selection)!==Ne(this._appliedSelection):!1}async execute(e={}){let r=[...this._queries.values()].filter(o=>o.shouldRun(e.force));this._controls.forEach(o=>o.commit()),this._appliedSelection=this._selection,this.selectionCommitted=!0,r.forEach(o=>{o.controller?.abort(),o.resetPage()});let i={backend:this.backend,timezone:this._timezone,bustCache:e.bustCache},s=[],l=[];return await Promise.all(r.map(async o=>{let a=new AbortController;o.controller=a;let c=o.signature();o.markExecuting();try{let b=await ee(o,this.mappingsTo(o.name),{conditions:this.selectionConditionsFor(o.name,"applied"),expression:this.selectionExpressionFor(o.name,"applied")},i,a.signal);if($e(o,a))return;o.markSuccess(b,c,!1),s.push(o.name)}catch(b){if($e(o,a)||Re(b))return;o.markError(Te(b,o.name)),l.push(o.name)}finally{o.controller===a&&(o.controller=void 0)}})),{succeeded:s,failed:l}}async refresh(){return this.execute({force:!0,bustCache:!0})}abort(){this._queries.forEach(e=>e.abort())}async fetchPage(e){let r=new AbortController;e.controller=r;let i=e.signature();e.markExecuting();try{let s=await ee(e,this.mappingsTo(e.name),{conditions:this.selectionConditionsFor(e.name,"applied"),expression:this.selectionExpressionFor(e.name,"applied")},{backend:this.backend,timezone:this._timezone},r.signal);e.markSuccess(s,i,!0)}catch(s){if(e.rewindPage(),Re(s))return;let l=Te(s,e.name);throw e.markError(l),l}finally{e.controller===r&&(e.controller=void 0)}}toJSON(){let e=r=>Object.fromEntries([...this._controls.entries()].filter(([,i])=>i.kind===r).map(([i,s])=>[i,s.toJSON()]));return{...this.title?{title:this.title}:{},...this._timezone?{timezone:this._timezone}:{},queries:Object.fromEntries([...this._queries.entries()].map(([r,i])=>[r,i.toJSON()])),filters:e("filter"),dateDrills:e("dateDrill"),mappings:[...this._mappings.map(r=>r.toJSON()),...this._crossFilters.map(r=>r.toJSON())]}}toInspectJSON(){return{...this.title?{title:this.title}:{},...this._timezone?{timezone:this._timezone}:{},hasChanges:this.hasChanges,declaration:this.toJSON(),queries:Object.fromEntries([...this._queries.entries()].map(([e,r])=>[e,ht(r)])),controls:Object.fromEntries([...this._controls.entries()].map(([e,r])=>[e,gt(r)])),...this._selection?{selection:Oe(this._selection)}:{},...this._appliedSelection?{appliedSelection:Oe(this._appliedSelection)}:{}}}locate(e,r){let i=globalThis.document;if(!i)return!1;let s=Ce(i,e,this.index,r);return s.length?(H(s[0]),Q(i).flash(s,{kind:e,name:r,...s.length>1?{note:`in ${s.length} places`}:{}}),!0):!1}assertNameFree(e,r){pe([...this._queries.keys(),...this._controls.keys()],e,r)}soleDataset(e,r){if(!r)return;let i=Object.keys(this.datasets);if(i.length===1)return this.datasets[i[0]];throw new p(i.length?`Filter \'${e}\' names a field but the environment has ${i.length} datasets. Say which one: ${i.join(", ")}.`:`Filter \'${e}\' names a field but the environment has no datasets.`,e)}assertAcyclic(e){let r=[...this._mappings,e],i=new Map;r.forEach(a=>{let c=a.from.name;i.set(c,[...i.get(c)??[],a.to.name])});let s=new Set,l=new Set,o=a=>{if(s.has(a))return!0;if(l.has(a))return!1;s.add(a);let c=(i.get(a)??[]).some(o);return s.delete(a),l.add(a),c};if([...i.keys()].some(o))throw new p(`Mapping \'${e.id}\' would make the app\'s mappings cyclic.`,e.from.name)}};var Fe="0.7.0";var bt=Fe,oe=class{constructor(n){d(this,"version",bt);d(this,"_apps",[]);d(this,"datasets");d(this,"user");d(this,"indices");d(this,"backend");d(this,"features");if(!n?.datasets)throw new p("No datasets provided. The host must call createSdk({ datasets }) before an app can be declared.");if(!n.user)throw new p("No user provided. The host must call createSdk({ user }) before an app can be declared.");if(!n.backend)throw new p("No backend provided. The host must call createSdk({ backend }) before an app can run a query.");this.datasets=Object.freeze({...n.datasets}),this.user=Object.freeze({...n.user,permissions:Object.freeze({...n.user.permissions})}),this.indices=Object.fromEntries(Object.entries(n.datasets).map(([e,r])=>[e,new U(r)])),this.backend=n.backend,this.features=Object.freeze({...n.features})}createApp(n={}){let e=new W(n,this.indices,this.backend,this.features);return e.index=this._apps.length,this._apps.push(e),e}get apps(){return this._apps}};function Ie(t){return new oe(t)}var B="Anfra";function Me(t,n=globalThis){let e=n[B],r=B in n;return n[B]=t,()=>{r?n[B]=e:delete n[B]}}function Qe(t,n){let e=null,r=a=>a.target instanceof Element?a.target.closest(K):null,i=a=>{let c=r(a);c!==e&&(e=c,n.onHover(c))},s=a=>{a.preventDefault(),a.stopPropagation();let c=r(a);c&&n.onPick(c)},l=a=>{a.key==="Escape"&&n.onCancel()},o={capture:!0};return t.addEventListener("mousemove",i,o),t.addEventListener("click",s,o),t.addEventListener("keydown",l,o),()=>{t.removeEventListener("mousemove",i,o),t.removeEventListener("click",s,o),t.removeEventListener("keydown",l,o)}}function Le(){let t=new Error("Aborted");return t.name="AbortError",t}function wt(t){switch(t?.name){case"PermissionError":return new P(t.message);case"TransportError":return new V(t.message);default:return new T(t?.message||"The query failed.")}}function Be(t){let n=t.document.getElementById(ae);if(!n?.textContent)throw new Error("anfra: this frame was not provisioned by a host.");let e=JSON.parse(n.textContent),r=f=>t.parent.postMessage(f,e.hostOrigin),i=new Map,s=1,l=!1,o;t.addEventListener("message",f=>{if(f.source!==t.parent)return;let m=f.data;switch(m?.type){case"anfra:response":{let g=i.get(m.id);if(!g)return;i.delete(m.id),m.ok?g.resolve(m.result):g.reject(wt(m.error));return}case"anfra:inspect-watch":N(m.open);return;case"anfra:highlight":D(m.node);return;case"anfra:locate":k(m.target);return;case"anfra:pick-watch":R(m.on);return;default:}});function a(f,m,g){return new Promise((_,X)=>{if(g.aborted){X(Le());return}let z=s++;i.set(z,{resolve:_,reject:X}),g.addEventListener("abort",()=>{i.delete(z)&&(r({type:"anfra:cancel",id:z}),X(Le()))},{once:!0}),r({type:"anfra:request",id:z,method:f,request:m})})}let c={submitQuery:(f,m)=>a("submitQuery",f,m).then(g=>(g.debug?.executedAt&&(g.debug.executedAt=new Date(g.debug.executedAt)),g)),fieldSuggestions:(f,m)=>a("fieldSuggestions",f,m)},b=Ie({datasets:e.datasets,user:e.user,backend:c}),S=t.document,u,v="",x,E;function h(){if(o=void 0,!!l)try{u=re(S,b.apps),v=JSON.stringify(u.nodes),r({type:"anfra:inspect",apps:b.apps.map(f=>f.toInspectJSON()),structure:{nodes:u.nodes,usage:u.usage}})}catch{}}function y(){l&&o===void 0&&(o=setTimeout(h,50))}function A(){let f=t.MutationObserver;if(x||typeof f!="function")return;let m=new f(()=>{if(!(!l||o!==void 0))try{JSON.stringify(re(S,b.apps).nodes)!==v&&y()}catch{}});x=m,m.observe(S.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-anfra-container","data-anfra-block","data-anfra-query","data-anfra-control","data-anfra-label"]})}function N(f){l=f,f?(A(),h()):(x?.disconnect(),x=void 0,R(!1),Q(S).hide(),u=void 0,v="")}function w(f,m){for(let g of f){if(g.key===m)return g;let _=w(g.children,m);if(_)return _}}function D(f){let m=Q(S),g=f!==null&&u?w(u.nodes,f):void 0,_=f!==null?u?.elements.get(f):void 0;if(!g||!_||!u){m.hide();return}m.show([_],De(g,_,u))}function k(f){if("node"in f){let m=u?.elements.get(f.node);m&&H(m),D(f.node)}else b.apps[f.app]?.locate(f.kind,f.name);y()}function R(f){if(!f){E?.(),E=void 0;return}if(E)return;let m=g=>u?.keysOf.get(g)?.[0];E=Qe(S,{onHover:g=>D(g?m(g)??null:null),onPick:g=>{let _=m(g);_!==void 0&&r({type:"anfra:picked",node:_})},onCancel:()=>{R(!1),Q(S).hide(),r({type:"anfra:picked",node:null})}})}let Y=b.createApp.bind(b);b.createApp=f=>{let m=Y(f);return m.subscribe(y),y(),m},Me(b,t),r({type:"anfra:ready"})}Be(window);})();\n';
|
|
74
|
+
var anfra_sdk_frame_script_default = '"use strict";(()=>{var ze=Object.defineProperty;var Pe=(t,n,e)=>n in t?ze(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e;var d=(t,n,e)=>Pe(t,typeof n!="symbol"?n+"":n,e);var $=class extends Error{constructor(e,r){super(e);d(this,"entity");this.name=new.target.name,this.entity=r,Object.setPrototypeOf(this,new.target.prototype)}},p=class extends ${},T=class extends ${constructor(e,r,i){super(e,r);d(this,"cause");this.cause=i}},P=class extends ${},V=class extends ${constructor(e,r,i){super(e,i);d(this,"status");this.status=r}};var ae="anfra-provision";var O=class{constructor(n){d(this,"listeners",new Set);d(this,"parent");this.parent=n}subscribe(n){return this.listeners.add(n),()=>{this.listeners.delete(n)}}notifyChange(){this.listeners.forEach(n=>n()),this.parent?.notifyChange()}notify(){this.notifyChange()}};var F=class extends O{constructor(e,r,i){super(r);d(this,"kind","query");d(this,"name");d(this,"declaration");d(this,"dataset");d(this,"app");d(this,"_state","idle");d(this,"_result");d(this,"_error");d(this,"_page",1);d(this,"_sort",[]);d(this,"lastRunSignature");d(this,"lastPageRows",0);d(this,"controller");if(!i.aql?.trim())throw new p(`Query \'${e}\' declares no AQL.`,e);let{pageSize:s}=i;if(s!==void 0&&!(Number.isInteger(s)&&s>=1))throw new p(`Query \'${e}\' declares pageSize ${s}; it must be a whole number of at least 1.`,e);this.name=e,this.app=r,this.declaration=i,this.dataset=r.datasetIndex(i.dataset,e)}locate(){return this.app.locate("query",this.name)}get state(){return this._state}get result(){return this._result}get error(){return this._error}get pageSize(){return this.declaration.pageSize}get page(){return this._page}get sort(){return this._sort}setSort(e){this._sort=[...e],this.notify()}get hasMore(){return!this._result||this.pageSize===void 0?!1:this.lastPageRows>=this.pageSize}signature(){let e=this.app.mappingsTo(this.name).map(r=>({field:r.field,aggregation:r.aggregation,condition:r.from.condition})).sort((r,i)=>r.field.localeCompare(i.field)||JSON.stringify(r).localeCompare(JSON.stringify(i)));return JSON.stringify({declaration:this.declaration,conditions:e,selection:this.app.selectionConditionsFor(this.name,"pending"),selectionExpression:this.app.selectionExpressionFor(this.name,"pending"),sort:this._sort,timezone:this.app.timezone,page:this._page})}get isDirty(){return this.lastRunSignature!==void 0&&this.signature()!==this.lastRunSignature}shouldRun(e=!1){return e||this.lastRunSignature===void 0||this.isDirty}abort(){this.controller?.abort()}async fetchMore(){if(this.pageSize===void 0)throw new p(`Query \'${this.name}\' declares no pageSize, so it has no more pages.`,this.name);this.hasMore&&(this._page+=1,await this.app.fetchPage(this))}select(e,r={}){this.app.select(this,Array.isArray(e)?e:[e],r.fields)}get selectedRows(){let{selection:e}=this.app;if(e?.source!==this.name)return[];let r=this._result?.rows;if(!r)return e.rows;let i=l=>JSON.stringify(e.fields.map(o=>l[o]??null)),s=new Set(e.rows.map(i));return r.filter(l=>s.has(i(l)))}markExecuting(){this._state="executing",this._error=void 0,this.notify()}markSuccess(e,r,i){if(this._state="success",this._error=void 0,this.lastRunSignature=r,this.lastPageRows=e.rows.length,i&&this._result){let s=[...this._result.rows,...e.rows];this._result={...e,rows:s,meta:{...e.meta,numRows:s.length}}}else this._result=e;this.notify()}markError(e){this._state="error",this._error=e,this.notify()}rewindPage(){this._page>1&&(this._page-=1)}resetPage(){this._page=1,this.lastPageRows=0}toJSON(){return this.declaration}};var le=["year","quarter","month","week","day","hour","minute"];function Ve(t,n){if(!le.includes(n))throw new p(`Invalid grain \'${n}\'. Expected one of: ${le.join(", ")}.`,t)}function de(t,n){return n?(Ve(t,n),{operator:"transform_date_drill",values:[`datetrunc ${n}`]}):{operator:"none"}}function Je(t){let n=t.toLowerCase();return n.includes("date")||n.includes("time")?"date":n.includes("int")||n.includes("number")||n.includes("float")||n.includes("decimal")?"number":n.includes("bool")?"boolean":"string"}function je(t,n){return JSON.stringify(t??null)===JSON.stringify(n??null)}var I=class extends O{constructor(e,r,i){super(r);d(this,"name");d(this,"app");d(this,"pending");d(this,"applied");d(this,"initial");this.name=e,this.app=r,this.initial=i,this.pending=i}locate(){return this.app.locate("control",this.name)}get condition(){return this.pending}get appliedCondition(){return this.applied}get isDirty(){return this.applied!==void 0&&!je(this.pending,this.applied)}setCondition(e){this.pending=e,this.notify()}reset(){this.setCondition(this.initial)}commit(){this.applied=this.pending}},J=class extends I{constructor(e,r,i,s,l){super(e,r,i.default??{operator:"is",values:[]});d(this,"kind","filter");d(this,"declaration");d(this,"type");d(this,"resolved");d(this,"datasetName");d(this,"backend");d(this,"loadedOptions");if(this.declaration=i,this.backend=l,i.field){if(!s)throw new p(`Filter \'${e}\' names a field but no dataset. Pass \\`dataset\\` alongside \\`field\\`.`,e);this.resolved=s.resolve(i.field,e),this.datasetName=s.descriptor.name,this.type=i.type??Je(this.resolved.type)}else{if(!i.type)throw new p(`Filter \'${e}\' is a manual filter, so it needs a \\`type\\`.`,e);this.type=i.type}this.assertValues(this.condition.values??[]),this.assertValues(i.options??[])}setCondition(e){this.assertValues(e.values??[]),super.setCondition(e)}assertValues(e){if(this.type!=="number")return;let r=e.find(i=>typeof i=="number");if(r!==void 0)throw new p(`Filter \'${this.name}\' filters numbers: give its values as strings, as query results give them (${JSON.stringify(String(r))}, not ${String(r)}), so none has lost a digit.`,this.name)}get isFieldBacked(){return this.resolved!==void 0}get options(){return this.loadedOptions??this.declaration.options??[]}async loadOptions(e,r=new AbortController().signal){let i=this.resolved?.modelName;if(!this.resolved||!i||!this.backend||!this.datasetName)return this.options;let s=await this.backend.fieldSuggestions({dataset:this.datasetName,model:i,field:this.resolved.fieldName,q:e??""},r);return this.loadedOptions=[...s??[]],this.notify(),this.loadedOptions}toJSON(){return this.declaration}},j=class extends I{constructor(e,r,i={}){super(e,r,de(e,i.default));d(this,"kind","dateDrill");d(this,"declaration");this.declaration=i}setGrain(e){this.setCondition(de(this.name,e))}toJSON(){return this.declaration}};var G=class{constructor(n,e,r,i){d(this,"kind","control");d(this,"from");d(this,"to");d(this,"field");d(this,"aggregation");this.from=n,this.to=e,this.field=r,this.aggregation=i}get id(){return`${this.from.name}.${this.to.name}.${this.field}`}toJSON(){return{kind:this.kind,id:this.id,from:{kind:this.from.kind,name:this.from.name},to:{kind:"query",name:this.to.name},field:this.field,...this.aggregation?{aggregation:this.aggregation}:{}}}},q=class{constructor(n,e){d(this,"kind","crossFilter");d(this,"from");d(this,"to");this.from=n,this.to=e}get id(){return`${this.from.name}.${this.to.name}`}toJSON(){return{kind:this.kind,id:this.id,from:{kind:"query",name:this.from.name},to:{kind:"query",name:this.to.name}}}};var Z=["sum","avg","max","min","count","count distinct","median","stdev","stdevp","var","varp"];function Ge(t,n){let e=t.length+1,r=n.length+1,i=Array.from({length:r},(s,l)=>l);for(let s=1;s<e;s++){let l=[s];for(let o=1;o<r;o++)l[o]=Math.min(i[o]+1,l[o-1]+1,i[o-1]+(t[s-1]===n[o-1]?0:1));i=l}return i[r-1]}function qe(t,n){let e,r=1/0;n.forEach(s=>{let l=Ge(t.toLowerCase(),s.toLowerCase());l<r&&(r=l,e=s)});let i=Math.max(2,Math.floor(t.length/3));return r<=i?e:void 0}function M(t,n,e){let r=qe(n,e);return r?`${t} Did you mean \'${r}\'?`:t}var U=class{constructor(n){d(this,"descriptor");d(this,"fields",new Map);d(this,"references");this.descriptor=n,n.data_models.forEach(e=>{e.fields.forEach(r=>{let i=String(e.name);this.fields.set(`${i}.${r.name}`,{modelName:i,fieldName:r.name,isMetric:!1,type:r.type,label:r.label??r.name})})}),n.metrics.forEach(e=>{this.fields.set(e.name,{fieldName:e.name,isMetric:!0,type:e.type,label:e.label??e.name})}),this.references=[...this.fields.keys()]}resolve(n,e){let r=this.fields.get(n);if(r)return r;throw new p(M(`Unknown field \'${n}\' on dataset \'${this.descriptor.name}\'.`,n,this.references),e)}};function ce(t,n,e){let r=t[n];if(r)return r;throw new p(M(`Unknown dataset \'${n}\'.`,n,Object.keys(t)),e)}function ue(t,n){if(!Z.includes(t))throw new p(M(`Invalid filter aggregation \'${t}\'.`,t,[...Z]),n)}function pe(t,n,e){if(!n)throw new p(`A ${e} needs a name.`);for(let r of t)if(r===n)throw new p(`\'${n}\' is already declared in this app.`,n)}function Ue(t,n){if(!(!n||n.operator==="none"||n.operator==="transform_date_drill"||!["is_null","not_null","is_true","is_false","transform_pop_none"].includes(n.operator)&&!n.values?.length))return{field:t.field,operator:n.operator,values:n.values??[],...n.modifier?{modifier:n.modifier}:{},...t.aggregation?{aggregation:t.aggregation}:{}}}function Ke(t,n){if(n?.operator!=="transform_date_drill")return;let e=n.values?.[0];if(typeof e!="string")return;let r=e.replace(/^datetrunc\\s+/,"");return{field:t.field,grain:r}}function He(t,n){let e=n.columns??[],r=(n.values??[]).map(s=>{let l={};return e.forEach((o,a)=>{l[o.name]=s[a]}),l}),{pageSize:i}=t;return{columns:e,rows:r,meta:{...i!==void 0?{page:n.meta?.page??t.page,pageSize:n.meta?.pageSize??i}:{},numRows:n.meta?.numRows??r.length},...n.debug?{debug:n.debug}:{}}}function We(t,n,e,r){let i=n.map(a=>Ue(a,a.from.appliedCondition)).filter(a=>a!==void 0),s=n.map(a=>Ke(a,a.from.appliedCondition)).filter(a=>a!==void 0),l=e.conditions.map(a=>({field:a.field,operator:a.operator,values:a.values})),o=e.expression?[{expr:e.expression}]:[];return{dataset:t.dataset.descriptor.name,aql:t.declaration.aql,input:{filters:[...i,...l],conditions:o,sorts:t.sort.map(a=>({field:a.field,direction:a.direction??"asc"})),dateDrills:s},...t.pageSize!==void 0?{page:t.page,pageSize:t.pageSize}:{},...r.timezone?{timezone:r.timezone}:{},...r.bustCache?{bustCache:!0}:{}}}async function ee(t,n,e,r,i){let s=We(t,n,e,r),l=await r.backend.submitQuery(s,i);return He(t,l)}function Ye(t,n){if(t===null)return"null";if(typeof t=="boolean")return t?"true":"false";if(n==="number"&&typeof t=="string")return et(t);if(typeof t=="number"){if(!Number.isFinite(t))throw new RangeError(`Cannot express ${t} in AQL.`);return Math.abs(t)>=1e21?BigInt(t).toString():String(t)}return JSON.stringify(t).split("\\u2028").join("\\\\u2028").split("\\u2029").join("\\\\u2029")}function fe(t,n,e){return n===null?`is(${t}, null)`:`${t} is ${Ye(n,e)}`}var Xe=new Set(["NaN","Infinity","-Infinity"]),Ze=/^(-?)(0|[1-9]\\d*)(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/;function et(t){let n=Ze.exec(t);if(!n)throw Xe.has(t)?new RangeError(`Cannot express ${t} in AQL.`):new TypeError(`${JSON.stringify(t)} is not a number: a number is a string in JSON\'s number syntax.`);let[,e,r,i="",s]=n;if(s===void 0)return t;let l=r+i,o=r.length+Number(s),a;return o<=0?a=`0.${"0".repeat(-o)}${l}`:o>=l.length?a=l+"0".repeat(o-l.length):a=`${l.slice(0,o)}.${l.slice(o)}`,e+a.replace(/^0+(?=\\d)/,"")}function me(t,n,e){return`${t} matches @(${n} until ${e})`}function he(t,n){if(n.length===0)throw new RangeError(`\\`${t}\\` needs at least one operand.`);return n.length===1?n[0]:`${t}(${n.join(", ")})`}var ge=t=>he("and",t),ye=t=>he("or",t);var tt=/^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?)?/,nt={week:7*864e5,day:864e5,hour:36e5,minute:6e4};function be(t){if(typeof t!="string")return;let n=tt.exec(t);if(n)return{year:Number(n[1]),month:Number(n[2])-1,day:Number(n[3]),hour:Number(n[4]??0),minute:Number(n[5]??0),second:Number(n[6]??0),hasTime:n[4]!==void 0}}function L(t,n){let e=new Date(t),r=s=>String(s).padStart(2,"0"),i=`${e.getUTCFullYear()}-${r(e.getUTCMonth()+1)}-${r(e.getUTCDate())}`;return n?`${i} ${r(e.getUTCHours())}:${r(e.getUTCMinutes())}:${r(e.getUTCSeconds())}`:i}function we(t){return Date.UTC(t.year,t.month,t.day,t.hour,t.minute,t.second)}function te(t){let n=be(t);if(n)return L(we(n),n.hasTime)}function ne(t,n){let e=be(t);if(!e)return;let{year:r,month:i,day:s,hour:l,minute:o,second:a,hasTime:c}=e;return L(n==="year"?Date.UTC(r+1,i,s,l,o,a):n==="quarter"?Date.UTC(r,i+3,s,l,o,a):n==="month"?Date.UTC(r,i+1,s,l,o,a):we(e)+nt[n],c)}function ke(t){if(t?.startsWith("datetrunc "))return t.slice(10)}function rt(t){let n=new Set;return t.filter(e=>{let r=`${typeof e}:${String(e)}`;return n.has(r)?!1:(n.add(r),!0)})}function it(t,n){let e=t.map(te);if(e.some(i=>i===void 0))return!1;let r=e.slice().sort();for(let i=1;i<r.length;i+=1)if(ne(r[i-1],n)!==r[i])return!1;return!0}function st(t,n,e){let r=n.map(te);if(r.some(a=>a===void 0))return;let i=r.slice().sort(),s=i[0],l=ne(i[i.length-1],e);if(!l)return;let o=it(n,e);return{condition:{field:t,operator:"matches",values:[`${s} until ${l}`]},admits:o?n.length:Number.POSITIVE_INFINITY,lossy:!o}}function ot(t,n,e){let r=e.filter(o=>o!=null),i=rt(r);if(!i.length)return{condition:{field:t,operator:"is_null",values:[]},admits:1,lossy:!1};let s=r.length!==e.length,l=ke(n);if(l){let o=st(t,i,l);if(o)return{...o,lossy:o.lossy||s}}return{condition:{field:t,operator:"is",values:i},admits:i.length,lossy:s}}function ve(t){return t.modelId?`${t.modelId}.${t.fieldName}`:t.fieldName}function at(t,n,e,r){try{let i=e.map(s=>ge(n.map(l=>{let o=t.get(l),a=ve(o),c=s[l]??null,b=ke(r[a]);if(b&&typeof c=="string"){let S=te(c),u=ne(c,b);if(S&&u)return me(a,S,u)}if(c!==null&&typeof c!="string"&&typeof c!="number"&&typeof c!="boolean")throw new TypeError("no AQL spelling");return fe(a,c,o.semantic_type)})));return ye(i)}catch{return}}function Se(t,n,e,r={}){let i=t.result?.columns??[],s=new Map(i.map(h=>[h.name,h]));e?.forEach(h=>{let y=s.get(h);if(y){if(y.adhoc)throw new p(`Query \'${t.name}\' cannot cross-filter on \'${h}\': it is a query-local AQL expression, which only this query\'s result carries. The target query would receive a condition naming a field it has never heard of.`,t.name);if(y.isMeasure)throw new p(`Query \'${t.name}\' cannot cross-filter on \'${h}\': it is a measure, and a selection conditions dimensions only.`,t.name);return}throw new p(M(`Query \'${t.name}\' has no column \'${h}\' in its last result.`,h,[...s.keys()]),t.name)});let l=i.filter(h=>!h.isMeasure),o=l.filter(h=>!h.adhoc).map(h=>h.name),a=e?[...e]:o;if(!n.length||!a.length)return;let c=[],b=1,S=!e&&o.length!==l.length,u=!1;a.forEach(h=>{let y=s.get(h),A=ve(y),N=ot(A,r[A],n.map(w=>w[h]));c.push(N.condition),b*=N.admits,u=u||N.lossy});let v=new Set(n.map(h=>JSON.stringify(a.map(y=>h[y]??null))));b>v.size&&(u=!0);let x=c.sort((h,y)=>h.field.localeCompare(y.field)),E={source:t.name,rows:[...n],fields:a};if(u){let h=at(s,a,n,r);if(h)return{...E,conditions:[],expression:h,lossy:S}}return{...E,conditions:x,lossy:S||u}}var C={container:"data-anfra-container",block:"data-anfra-block",query:"data-anfra-query",control:"data-anfra-control",label:"data-anfra-label"},K=`[${C.container}],[${C.block}],[${C.query}],[${C.control}]`;function xe(t){let n=/^(?:(\\d+)\\/)?([^/\\s]+)$/.exec(t);if(n)return{app:n[1]===void 0?0:Number(n[1]),name:n[2]}}var Ee=t=>(t??"").split(/\\s+/).filter(Boolean);function Ce(t,n,e,r){let i=n==="query"?C.query:C.control;return[...t.querySelectorAll(`[${i}]`)].filter(s=>Ee(s.getAttribute(i)).some(l=>{let o=xe(l);return o?.app===e&&o.name===r}))}var lt=(t,n,e)=>{let r=t[e.app];return r?Object.prototype.hasOwnProperty.call(n==="query"?r.queries:r.controls,e.name):!1};function re(t,n){var S;let e=[],r=new Map,i=new Map,s=new Map,l=new Map,o={container:new Set,block:new Set},a={},c=(u,v,x)=>{let E=u?s.get(u).children:e,h=u?`${s.get(u).key}.`:"",y={...v,key:`${h}${E.length}`,children:[]};return E.push(y),r.set(y.key,x),i.set(x,[...i.get(x)??[],y.key]),y};for(let u of t.querySelectorAll(K)){let v=u.parentElement?.closest(K)??null,x=u.getAttribute(C.container),E=u.getAttribute(C.block),h=u.getAttribute(C.label)??void 0,y=v&&(l.get(v)==="block"?v:v.closest(`[${C.block}]`)),A;if(x!==null||E!==null){let w=x!==null?"container":"block",D=(x??E??"").trim(),k=[];x!==null&&E!==null&&k.push("This element is marked as a container and as a block. It counts as a container."),D?o[w].has(D)?k.push(`Another ${w} already has the id "${D}".`):o[w].add(D):k.push(`This ${w} has no id.`),y&&k.push(`A block can\'t hold a ${w}. This one is inside the block "${y.getAttribute(C.block)}".`),A=c(v,{kind:w,id:D,...h!==void 0?{label:h}:{},problems:k},u),s.set(u,A),l.set(u,w)}let N=A?u:v;for(let w of["query","control"])for(let D of Ee(u.getAttribute(w==="query"?C.query:C.control))){let k=xe(D),R=[];if(k?lt(n,w,k)||R.push(n[k.app]?`No ${w} is called "${k.name}" in app ${k.app}.`:`The page has no app ${k.app}.`):R.push(`Can\'t read "${D}". Write the ${w}\'s name, or app/name when the page has several apps.`),c(N,{kind:w,name:k?.name??D,app:k?.app??0,problems:R},u),k&&!R.length){let Y=`${k.app}/${k.name}`,f=a[S=`${w}:${Y}`]??(a[S]={elements:new Set,blocks:new Set});f.elements.add(u);let m=A?.kind==="block"?A.id:y?.getAttribute(C.block);m&&f.blocks.add(m)}}}let b=Object.fromEntries(Object.entries(a).map(([u,v])=>[u,{markers:v.elements.size,blocks:[...v.blocks]}]));return{nodes:e,usage:b,elements:r,keysOf:i}}var dt=(t,n,e)=>`${t}:${n}/${e}`;function ct(t){let n=t.getBoundingClientRect();return`${Math.round(n.width)} \\xD7 ${Math.round(n.height)}`}function De(t,n,e){let r=ct(n);if(t.kind==="container"||t.kind==="block")return{kind:t.kind,name:t.id??"",...t.label?{label:t.label}:{},size:r};let i=e.usage[dt(t.kind,t.app??0,t.name??"")];return{kind:t.kind,name:t.name??"",...i&&i.markers>1?{note:`1 of ${i.markers}`}:{},size:r}}var _e="anfra-overlay";var ut="position:fixed;box-sizing:border-box;background:rgba(37,99,235,0.22);outline:1px solid #2563eb;outline-offset:-1px;",pt="position:fixed;max-width:60vw;display:flex;gap:6px;align-items:baseline;padding:3px 8px;border-radius:4px;background:#0f172a;color:#f8fafc;font:12px/1.4 system-ui,sans-serif;white-space:nowrap;box-shadow:0 2px 8px rgba(0,0,0,0.35);",ft={kind:"color:#94a3b8;",name:"color:#93c5fd;font-weight:700;",label:"color:#f8fafc;",note:"color:#94a3b8;",size:"color:#94a3b8;margin-left:10px;"},ie=class{constructor(n){d(this,"doc",n);d(this,"root");d(this,"shown",[]);d(this,"text",{kind:"",name:""});d(this,"timer");d(this,"reposition",()=>this.draw());let e=n.getElementById(_e);e?this.root=e:(this.root=n.createElement("div"),this.root.id=_e,this.root.setAttribute("aria-hidden","true"),this.root.setAttribute("style","position:fixed;inset:0;z-index:2147483647;pointer-events:none;display:none;"),(n.body??n.documentElement).appendChild(this.root))}show(n,e){if(this.clearTimer(),this.shown=[...n],this.text=e,!this.shown.length){this.hide();return}this.root.style.display="block",this.draw(),this.doc.addEventListener("scroll",this.reposition,{capture:!0,passive:!0}),this.doc.defaultView?.addEventListener("resize",this.reposition)}flash(n,e,r=1500){this.show(n,e),this.timer=setTimeout(()=>this.hide(),r)}hide(){this.clearTimer(),this.shown=[],this.root.style.display="none",this.root.replaceChildren(),this.doc.removeEventListener("scroll",this.reposition,{capture:!0}),this.doc.defaultView?.removeEventListener("resize",this.reposition)}get visible(){return this.shown.length>0}clearTimer(){this.timer!==void 0&&clearTimeout(this.timer),this.timer=void 0}draw(){let n=this.shown.map(o=>{let a=o.getBoundingClientRect(),c=this.doc.createElement("div");return c.setAttribute("style",`${ut}left:${a.left}px;top:${a.top}px;width:${a.width}px;height:${a.height}px;`),c}),e=this.shown[0].getBoundingClientRect(),r=this.doc.createElement("div");r.setAttribute("data-testid","anfra-overlay-label");let i=this.doc.defaultView?.innerHeight??0,s=e.top>=26?e.top-24:Math.max(4,e.top+4),l=Math.max(4,Math.min(e.left,(this.doc.defaultView?.innerWidth??0)-24));r.setAttribute("style",`${pt}left:${l}px;top:${Math.min(s,i-24)}px;`);for(let o of["kind","name","label","note","size"]){let a=this.text[o];if(!a)continue;let c=this.doc.createElement("span");c.setAttribute("style",ft[o]),c.setAttribute("data-part",o),c.textContent=a,r.appendChild(c)}this.root.replaceChildren(...n,r)}},Ae=new WeakMap;function Q(t){let n=Ae.get(t);return n||(n=new ie(t),Ae.set(t,n)),n}function H(t){typeof t.scrollIntoView=="function"&&t.scrollIntoView({block:"center",inline:"nearest",behavior:"smooth"})}var se=Object.freeze([]);function Re(t){return t instanceof Error&&t.name==="AbortError"}function $e(t,n){return t.controller!==n}function mt(t){return{name:t.name,message:t.message,...t.entity?{entity:t.entity}:{},...typeof t.status=="number"?{status:t.status}:{},...t.stack?{stack:t.stack}:{}}}function ht(t){let{result:n}=t;return{state:t.state,isDirty:t.isDirty,page:t.page,hasMore:t.hasMore,columns:n?n.columns.map(e=>({...e})):[],rowCount:n?.meta.numRows??0,selectedRowCount:t.selectedRows.length,signature:t.signature(),...t.error?{error:mt(t.error)}:{},...n?.debug?{debug:{...n.debug}}:{}}}function gt(t){let{options:n}=t;return{kind:t.kind,condition:{...t.condition},...t.appliedCondition?{appliedCondition:{...t.appliedCondition}}:{},isDirty:t.isDirty,...n?{options:[...n]}:{}}}function Oe(t){return{source:t.source,fields:[...t.fields],rowCount:t.rows.length,conditions:t.conditions.map(n=>({...n})),...t.expression?{expression:t.expression}:{},lossy:t.lossy}}function Ne(t){return t?JSON.stringify({source:t.source,conditions:t.conditions,expression:t.expression}):"none"}function Te(t,n){return t instanceof $?t:new T(t?.message??"The query failed.",n,t)}var W=class extends O{constructor(e,r,i,s){super();d(this,"title");d(this,"_timezone");d(this,"datasets");d(this,"backend");d(this,"features");d(this,"_queries",new Map);d(this,"_controls",new Map);d(this,"_mappings",[]);d(this,"_crossFilters",[]);d(this,"_selection");d(this,"_appliedSelection");d(this,"selectionCommitted",!1);d(this,"index",0);this.title=e.title,this._timezone=e.timezone,this.datasets=r,this.backend=i,this.features=s}get queries(){return Object.fromEntries(this._queries)}get controls(){return Object.fromEntries(this._controls)}get mappings(){return[...this._mappings,...this._crossFilters]}get crossFilters(){return this._crossFilters}createQuery(e,r){this.assertNameFree(e,"query");let i=new F(e,this,r);return this._queries.set(e,i),this.notify(),i}createFilter(e,r){this.assertNameFree(e,"filter");let i=r.dataset?this.datasetIndex(r.dataset,e):this.soleDataset(e,r.field),s=new J(e,this,r,i,this.backend);return this._controls.set(e,s),this.notify(),s}createDateDrill(e,r={}){if(this.features?.dateDrill===!1)throw new p(`Date drill \'${e}\' needs a capability this workspace has not enabled. Ask an admin to turn on \\`interactive_control:date_drill\\`.`,e);this.assertNameFree(e,"date drill control");let i=new j(e,this,r);return this._controls.set(e,i),this.notify(),i}mapControl(e,r,i){if(!(e instanceof I))throw new p("mapControl expects a control as its source. To let one query cross-filter another, use app.mapCrossFilter(from, to) \\u2014 a cross-filter edge names no field.");if(this._controls.get(e.name)!==e)throw new p(`Control \'${e.name}\' belongs to a different app.`,e.name);if(this._queries.get(r.name)!==r)throw new p(`Query \'${r.name}\' belongs to a different app.`,r.name);i.aggregation&&ue(i.aggregation,e.name);let s=new G(e,r,i.field,i.aggregation);if(this._mappings.some(l=>l.id===s.id))throw new p(`Mapping \'${s.id}\' is already declared.`,e.name);return this.assertAcyclic(s),this._mappings.push(s),this.notify(),s}mapCrossFilter(e,r){if(!(e instanceof F)||!(r instanceof F))throw new p("mapCrossFilter expects two queries. To let a control condition a query, use app.mapControl(from, to, { field }).");if(this._queries.get(e.name)!==e)throw new p(`Query \'${e.name}\' belongs to a different app.`,e.name);if(this._queries.get(r.name)!==r)throw new p(`Query \'${r.name}\' belongs to a different app.`,r.name);if(e===r)throw new p(`Query \'${e.name}\' cannot cross-filter itself. A source keeps its own rows so it can show what is selected; filtering it would erase the very rows the reader clicked.`,e.name);if(e.declaration.dataset!==r.declaration.dataset)throw new p(`Cross-filter \'${e.name}\' -> \'${r.name}\' spans two datasets (\'${e.declaration.dataset}\' and \'${r.declaration.dataset}\'). A selection carries field references, which mean nothing outside the dataset that resolved them.`,e.name);let i=new q(e,r);if(this._crossFilters.some(s=>s.id===i.id))throw new p(`Cross-filter \'${i.id}\' is already declared.`,e.name);return this._crossFilters.push(i),this.notify(),i}get selection(){return this._selection}get appliedSelection(){return this._appliedSelection}clearSelection(){this._selection&&(this._selection=void 0,this.notify())}setTimezone(e){this._timezone=e,this.notify()}get timezone(){return this._timezone}datasetIndex(e,r){return ce(this.datasets,e,r)}mappingsTo(e){return this._mappings.filter(r=>r.to.name===e)}selectionExpressionFor(e,r){return this.selectionFor(e,r)?.expression}selectionFor(e,r){let i=r==="pending"?this._selection:this._appliedSelection;return!i||i.source===e?void 0:this._crossFilters.some(l=>l.from.name===i.source&&l.to.name===e)?i:void 0}selectionConditionsFor(e,r){let i=r==="pending"?this._selection:this._appliedSelection;return!i||i.source===e?se:this._crossFilters.some(l=>l.from.name===i.source&&l.to.name===e)?i.conditions:se}drillTransformations(e){let r={};return this._mappings.forEach(i=>{if(i.to!==e)return;let s=i.from.appliedCondition;if(s?.operator!=="transform_date_drill")return;let[l]=s.values??[];typeof l=="string"&&(r[i.field]=l)}),r}select(e,r,i){if(this._queries.get(e.name)!==e)throw new p(`Query \'${e.name}\' belongs to a different app.`,e.name);let s=Se(e,r,i,this.drillTransformations(e));s?.lossy&&console.warn(`[anfra-sdk] The selection in \'${e.name}\' filters more broadly than it was made. Its conditions are combined field by field and ANDed, which cannot express "(A and B) or (C and D)", so the targets will also show combinations that were not selected. Select within one dimension, or narrow with \\`fields\\`, to avoid this.`),this._selection=s,this.notify()}get hasChanges(){return[...this._controls.values()].some(e=>e.isDirty)||this.isSelectionDirty}get isSelectionDirty(){return this.selectionCommitted?Ne(this._selection)!==Ne(this._appliedSelection):!1}async execute(e={}){let r=[...this._queries.values()].filter(o=>o.shouldRun(e.force));this._controls.forEach(o=>o.commit()),this._appliedSelection=this._selection,this.selectionCommitted=!0,r.forEach(o=>{o.controller?.abort(),o.resetPage()});let i={backend:this.backend,timezone:this._timezone,bustCache:e.bustCache},s=[],l=[];return await Promise.all(r.map(async o=>{let a=new AbortController;o.controller=a;let c=o.signature();o.markExecuting();try{let b=await ee(o,this.mappingsTo(o.name),{conditions:this.selectionConditionsFor(o.name,"applied"),expression:this.selectionExpressionFor(o.name,"applied")},i,a.signal);if($e(o,a))return;o.markSuccess(b,c,!1),s.push(o.name)}catch(b){if($e(o,a)||Re(b))return;o.markError(Te(b,o.name)),l.push(o.name)}finally{o.controller===a&&(o.controller=void 0)}})),{succeeded:s,failed:l}}async refresh(){return this.execute({force:!0,bustCache:!0})}abort(){this._queries.forEach(e=>e.abort())}async fetchPage(e){let r=new AbortController;e.controller=r;let i=e.signature();e.markExecuting();try{let s=await ee(e,this.mappingsTo(e.name),{conditions:this.selectionConditionsFor(e.name,"applied"),expression:this.selectionExpressionFor(e.name,"applied")},{backend:this.backend,timezone:this._timezone},r.signal);e.markSuccess(s,i,!0)}catch(s){if(e.rewindPage(),Re(s))return;let l=Te(s,e.name);throw e.markError(l),l}finally{e.controller===r&&(e.controller=void 0)}}toJSON(){let e=r=>Object.fromEntries([...this._controls.entries()].filter(([,i])=>i.kind===r).map(([i,s])=>[i,s.toJSON()]));return{...this.title?{title:this.title}:{},...this._timezone?{timezone:this._timezone}:{},queries:Object.fromEntries([...this._queries.entries()].map(([r,i])=>[r,i.toJSON()])),filters:e("filter"),dateDrills:e("dateDrill"),mappings:[...this._mappings.map(r=>r.toJSON()),...this._crossFilters.map(r=>r.toJSON())]}}toInspectJSON(){return{...this.title?{title:this.title}:{},...this._timezone?{timezone:this._timezone}:{},hasChanges:this.hasChanges,declaration:this.toJSON(),queries:Object.fromEntries([...this._queries.entries()].map(([e,r])=>[e,ht(r)])),controls:Object.fromEntries([...this._controls.entries()].map(([e,r])=>[e,gt(r)])),...this._selection?{selection:Oe(this._selection)}:{},...this._appliedSelection?{appliedSelection:Oe(this._appliedSelection)}:{}}}locate(e,r){let i=globalThis.document;if(!i)return!1;let s=Ce(i,e,this.index,r);return s.length?(H(s[0]),Q(i).flash(s,{kind:e,name:r,...s.length>1?{note:`in ${s.length} places`}:{}}),!0):!1}assertNameFree(e,r){pe([...this._queries.keys(),...this._controls.keys()],e,r)}soleDataset(e,r){if(!r)return;let i=Object.keys(this.datasets);if(i.length===1)return this.datasets[i[0]];throw new p(i.length?`Filter \'${e}\' names a field but the environment has ${i.length} datasets. Say which one: ${i.join(", ")}.`:`Filter \'${e}\' names a field but the environment has no datasets.`,e)}assertAcyclic(e){let r=[...this._mappings,e],i=new Map;r.forEach(a=>{let c=a.from.name;i.set(c,[...i.get(c)??[],a.to.name])});let s=new Set,l=new Set,o=a=>{if(s.has(a))return!0;if(l.has(a))return!1;s.add(a);let c=(i.get(a)??[]).some(o);return s.delete(a),l.add(a),c};if([...i.keys()].some(o))throw new p(`Mapping \'${e.id}\' would make the app\'s mappings cyclic.`,e.from.name)}};var Fe="0.7.1";var bt=Fe,oe=class{constructor(n){d(this,"version",bt);d(this,"_apps",[]);d(this,"datasets");d(this,"user");d(this,"indices");d(this,"backend");d(this,"features");if(!n?.datasets)throw new p("No datasets provided. The host must call createSdk({ datasets }) before an app can be declared.");if(!n.user)throw new p("No user provided. The host must call createSdk({ user }) before an app can be declared.");if(!n.backend)throw new p("No backend provided. The host must call createSdk({ backend }) before an app can run a query.");this.datasets=Object.freeze({...n.datasets}),this.user=Object.freeze({...n.user,permissions:Object.freeze({...n.user.permissions})}),this.indices=Object.fromEntries(Object.entries(n.datasets).map(([e,r])=>[e,new U(r)])),this.backend=n.backend,this.features=Object.freeze({...n.features})}createApp(n={}){let e=new W(n,this.indices,this.backend,this.features);return e.index=this._apps.length,this._apps.push(e),e}get apps(){return this._apps}};function Ie(t){return new oe(t)}var B="Anfra";function Me(t,n=globalThis){let e=n[B],r=B in n;return n[B]=t,()=>{r?n[B]=e:delete n[B]}}function Qe(t,n){let e=null,r=a=>a.target instanceof Element?a.target.closest(K):null,i=a=>{let c=r(a);c!==e&&(e=c,n.onHover(c))},s=a=>{a.preventDefault(),a.stopPropagation();let c=r(a);c&&n.onPick(c)},l=a=>{a.key==="Escape"&&n.onCancel()},o={capture:!0};return t.addEventListener("mousemove",i,o),t.addEventListener("click",s,o),t.addEventListener("keydown",l,o),()=>{t.removeEventListener("mousemove",i,o),t.removeEventListener("click",s,o),t.removeEventListener("keydown",l,o)}}function Le(){let t=new Error("Aborted");return t.name="AbortError",t}function wt(t){switch(t?.name){case"PermissionError":return new P(t.message);case"TransportError":return new V(t.message);default:return new T(t?.message||"The query failed.")}}function Be(t){let n=t.document.getElementById(ae);if(!n?.textContent)throw new Error("anfra: this frame was not provisioned by a host.");let e=JSON.parse(n.textContent),r=f=>t.parent.postMessage(f,e.hostOrigin),i=new Map,s=1,l=!1,o;t.addEventListener("message",f=>{if(f.source!==t.parent)return;let m=f.data;switch(m?.type){case"anfra:response":{let g=i.get(m.id);if(!g)return;i.delete(m.id),m.ok?g.resolve(m.result):g.reject(wt(m.error));return}case"anfra:inspect-watch":N(m.open);return;case"anfra:highlight":D(m.node);return;case"anfra:locate":k(m.target);return;case"anfra:pick-watch":R(m.on);return;default:}});function a(f,m,g){return new Promise((_,X)=>{if(g.aborted){X(Le());return}let z=s++;i.set(z,{resolve:_,reject:X}),g.addEventListener("abort",()=>{i.delete(z)&&(r({type:"anfra:cancel",id:z}),X(Le()))},{once:!0}),r({type:"anfra:request",id:z,method:f,request:m})})}let c={submitQuery:(f,m)=>a("submitQuery",f,m).then(g=>(g.debug?.executedAt&&(g.debug.executedAt=new Date(g.debug.executedAt)),g)),fieldSuggestions:(f,m)=>a("fieldSuggestions",f,m)},b=Ie({datasets:e.datasets,user:e.user,backend:c}),S=t.document,u,v="",x,E;function h(){if(o=void 0,!!l)try{u=re(S,b.apps),v=JSON.stringify(u.nodes),r({type:"anfra:inspect",apps:b.apps.map(f=>f.toInspectJSON()),structure:{nodes:u.nodes,usage:u.usage}})}catch{}}function y(){l&&o===void 0&&(o=setTimeout(h,50))}function A(){let f=t.MutationObserver;if(x||typeof f!="function")return;let m=new f(()=>{if(!(!l||o!==void 0))try{JSON.stringify(re(S,b.apps).nodes)!==v&&y()}catch{}});x=m,m.observe(S.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-anfra-container","data-anfra-block","data-anfra-query","data-anfra-control","data-anfra-label"]})}function N(f){l=f,f?(A(),h()):(x?.disconnect(),x=void 0,R(!1),Q(S).hide(),u=void 0,v="")}function w(f,m){for(let g of f){if(g.key===m)return g;let _=w(g.children,m);if(_)return _}}function D(f){let m=Q(S),g=f!==null&&u?w(u.nodes,f):void 0,_=f!==null?u?.elements.get(f):void 0;if(!g||!_||!u){m.hide();return}m.show([_],De(g,_,u))}function k(f){if("node"in f){let m=u?.elements.get(f.node);m&&H(m),D(f.node)}else b.apps[f.app]?.locate(f.kind,f.name);y()}function R(f){if(!f){E?.(),E=void 0;return}if(E)return;let m=g=>u?.keysOf.get(g)?.[0];E=Qe(S,{onHover:g=>D(g?m(g)??null:null),onPick:g=>{let _=m(g);_!==void 0&&r({type:"anfra:picked",node:_})},onCancel:()=>{R(!1),Q(S).hide(),r({type:"anfra:picked",node:null})}})}let Y=b.createApp.bind(b);b.createApp=f=>{let m=Y(f);return m.subscribe(y),y(),m},Me(b,t),r({type:"anfra:ready"})}Be(window);})();\n';
|
|
75
75
|
|
|
76
76
|
// src/host/frameScript.ts
|
|
77
77
|
function builtFrameScript() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holistics/anfra-sdk",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Data Apps on anfra: the authoring layer (app), what hosts one (host), the core API client (api), and their shared contract (common)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|