@cef-ai/widget-runtime 0.2.0 → 0.2.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.
@@ -132,7 +132,12 @@ async function registerCredentials(ctx, delegationToken, label) {
132
132
  * revoke-each-other race anymore.
133
133
  */
134
134
  function createCredCore(cfg) {
135
- const fetchImpl = cfg.fetchImpl ?? globalThis.fetch;
135
+ // Bind to globalThis: browsers (Blink/WebKit) brand-check fetch's receiver
136
+ // against window and throw "Illegal invocation" when it's called detached
137
+ // (`const f = globalThis.fetch; f(...)`). Node's fetch doesn't brand-check and
138
+ // tests inject cfg.fetchImpl, so an unbound default stayed green in CI but
139
+ // broke every real browser upload on the first /auth call.
140
+ const fetchImpl = cfg.fetchImpl ?? globalThis.fetch.bind(globalThis);
136
141
  const awsClientFactory = cfg.awsClientFactory ?? ((creds) => new AwsClient({ accessKeyId: creds.accessKeyId, secretAccessKey: creds.secretAccessKey, region: creds.region, service: 's3', ...(creds.sessionToken ? { sessionToken: creds.sessionToken } : {}) }));
137
142
  const label = cfg.credentialLabel ?? CREDENTIAL_LABEL;
138
143
  const ctx = {
@@ -304,7 +304,7 @@ ${V.stack}`),rt.warn(re),W&&W.listenerCount("error")>0&&W.emit("error",re)}let P
304
304
  `),this.credentialString=[this.datetime.slice(0,8),this.region,this.service,"aws4_request"].join("/"),this.signQuery&&(this.service==="s3"&&!S.has("X-Amz-Expires")&&S.set("X-Amz-Expires","86400"),S.set("X-Amz-Algorithm","AWS4-HMAC-SHA256"),S.set("X-Amz-Credential",this.accessKeyId+"/"+this.credentialString),S.set("X-Amz-SignedHeaders",this.signedHeaders)),this.service==="s3")try{this.encodedPath=decodeURIComponent(this.url.pathname.replace(/\+/g," "))}catch{this.encodedPath=this.url.pathname}else this.encodedPath=this.url.pathname.replace(/\/+/g,"/");B||(this.encodedPath=encodeURIComponent(this.encodedPath).replace(/%2F/g,"/")),this.encodedPath=Sp(this.encodedPath);let E=new Set;this.encodedSearch=[...this.url.searchParams].filter(([A])=>{if(!A)return!1;if(this.service==="s3"){if(E.has(A))return!1;E.add(A)}return!0}).map(A=>A.map(C=>Sp(encodeURIComponent(C)))).sort(([A,C],[q,U])=>A<q?-1:A>q?1:C<U?-1:C>U?1:0).map(A=>A.join("=")).join("&")}async sign(){return this.signQuery?(this.url.searchParams.set("X-Amz-Signature",await this.signature()),this.sessionToken&&this.appendSessionToken&&this.url.searchParams.set("X-Amz-Security-Token",this.sessionToken)):this.headers.set("Authorization",await this.authHeader()),{method:this.method,url:this.url,headers:this.headers,body:this.body}}async authHeader(){return["AWS4-HMAC-SHA256 Credential="+this.accessKeyId+"/"+this.credentialString,"SignedHeaders="+this.signedHeaders,"Signature="+await this.signature()].join(", ")}async signature(){let t=this.datetime.slice(0,8),r=[this.secretAccessKey,t,this.region,this.service].join(),o=this.cache.get(r);if(!o){let n=await us("AWS4"+this.secretAccessKey,t),c=await us(n,this.region),i=await us(c,this.service);o=await us(i,"aws4_request"),this.cache.set(r,o)}return Wu(await us(o,await this.stringToSign()))}async stringToSign(){return["AWS4-HMAC-SHA256",this.datetime,this.credentialString,Wu(await xp(await this.canonicalString()))].join(`
305
305
  `)}async canonicalString(){return[this.method.toUpperCase(),this.encodedPath,this.encodedSearch,this.canonicalHeaders+`
306
306
  `,this.signedHeaders,await this.hexBodyHash()].join(`
307
- `)}async hexBodyHash(){let t=this.headers.get("X-Amz-Content-Sha256")||(this.service==="s3"&&this.signQuery?"UNSIGNED-PAYLOAD":null);if(t==null){if(this.body&&typeof this.body!="string"&&!("byteLength"in this.body))throw new Error("body must be a string, ArrayBuffer or ArrayBufferView, unless you include the X-Amz-Content-Sha256 header");t=Wu(await xp(this.body||""))}return t}};async function us(e,t){let r=await crypto.subtle.importKey("raw",typeof e=="string"?Vu.encode(e):e,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]);return crypto.subtle.sign("HMAC",r,Vu.encode(t))}async function xp(e){return crypto.subtle.digest("SHA-256",typeof e=="string"?Vu.encode(e):e)}var kp=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];function Wu(e){let t=new Uint8Array(e),r="";for(let o=0;o<t.length;o++){let n=t[o];r+=kp[n>>>4&15],r+=kp[n&15]}return r}function Sp(e){return e.replace(/[!'()*]/g,t=>"%"+t.charCodeAt(0).toString(16).toUpperCase())}function kg(e,t){let{hostname:r,pathname:o}=e;if(r.endsWith(".on.aws")){let a=r.match(/^[^.]{1,63}\.lambda-url\.([^.]{1,63})\.on\.aws$/);return a!=null?["lambda",a[1]||""]:["",""]}if(r.endsWith(".r2.cloudflarestorage.com"))return["s3","auto"];if(r.endsWith(".backblazeb2.com")){let a=r.match(/^(?:[^.]{1,63}\.)?s3\.([^.]{1,63})\.backblazeb2\.com$/);return a!=null?["s3",a[1]||""]:["",""]}let n=r.replace("dualstack.","").match(/([^.]{1,63})\.(?:([^.]{0,63})\.)?amazonaws\.com(?:\.cn)?$/),c=n&&n[1]||"",i=n&&n[2];if(i==="us-gov")i="us-gov-west-1";else if(i==="s3"||i==="s3-accelerate")i="us-east-1",c="s3";else if(c==="iot")r.startsWith("iot.")?c="execute-api":r.startsWith("data.jobs.iot.")?c="iot-jobs-data":c=o==="/mqtt"?"iotdevicegateway":"iotdata";else if(c==="autoscaling"){let a=(t.get("X-Amz-Target")||"").split(".")[0];a==="AnyScaleFrontendService"?c="application-autoscaling":a==="AnyScaleScalingPlannerFrontendService"&&(c="autoscaling-plans")}else i==null&&c.startsWith("s3-")?(i=c.slice(3).replace(/^fips-|^external-1/,""),c="s3"):c.endsWith("-fips")?c=c.slice(0,-5):i&&/-\d$/.test(c)&&!/-\d$/.test(i)&&([c,i]=[i,c]);return[vg[c]||c,i||""]}function Ep(e,t){let r=new ArrayBuffer(44+e.length*2),o=new DataView(r),n=(i,a)=>{for(let m=0;m<a.length;m++)o.setUint8(i+m,a.charCodeAt(m))};n(0,"RIFF"),o.setUint32(4,36+e.length*2,!0),n(8,"WAVE"),n(12,"fmt "),o.setUint32(16,16,!0),o.setUint16(20,1,!0),o.setUint16(22,1,!0),o.setUint32(24,t,!0),o.setUint32(28,t*2,!0),o.setUint16(32,2,!0),o.setUint16(34,16,!0),n(36,"data"),o.setUint32(40,e.length*2,!0);let c=44;for(let i=0;i<e.length;i++,c+=2){let a=Math.max(-1,Math.min(1,e[i]));o.setInt16(c,a<0?a*32768:a*32767,!0)}return r}function Mp(e,t,r){let o=t*r,n=[];for(let c=0;c<e.length;c+=o)n.push(e.subarray(c,Math.min(c+o,e.length)));return n.length?n:[e]}async function Pp(e){let t=await e.arrayBuffer(),r=window.OfflineAudioContext||window.webkitOfflineAudioContext,o=new(window.AudioContext||window.webkitAudioContext),n=await o.decodeAudioData(t.slice(0));o.close();let c=Math.ceil(n.duration*16e3),i=new r(1,c,16e3),a=i.createBufferSource();return a.buffer=n,a.connect(i.destination),a.start(),(await i.startRendering()).getChannelData(0).slice()}function ja(e){let t=[],r=typeof e=="bigint"?e:BigInt(e);r<0n&&(r&=0xffffffffffffffffn);do{let o=Number(r&0x7fn);r>>=7n,t.push(r>0n?o|128:o)}while(r>0n);return new Uint8Array(t)}function co(...e){let t=e.reduce((n,c)=>n+c.length,0),r=new Uint8Array(t),o=0;for(let n of e)r.set(n,o),o+=n.length;return r}var Op=(e,t)=>ja(e*8+t),Ra=(e,t)=>co(Op(e,0),ja(t)),xi=(e,t)=>co(Op(e,2),ja(t.length),t);function Sg(e,t,r){return co(Ra(1,e),xi(2,t),xi(3,r))}function Eg({subject:e,canDelegate:t,bucketId:r,operations:o,expiresAt:n}){let c=[xi(2,e),Ra(3,t?1:0)];return r!==void 0&&c.push(Ra(4,typeof r=="bigint"?r:BigInt(r))),o.length>0&&c.push(xi(5,co(...o.map(i=>ja(i))))),c.push(Ra(6,n)),co(...c)}var Mg=(e,t)=>co(xi(1,e),xi(2,t)),Ku=Object.freeze({PUT:1,GET:2,DELETE:3}),Tp=Object.freeze({ED_25519:0,SR_25519:1});async function Ap(e){let{signerPair:t,signerType:r,subject:o,bucketId:n,expiresIn:c=30*24*60*60*1e3,operations:i=[Ku.PUT,Ku.GET,Ku.DELETE]}=e,a=Date.now()+c,m=Eg({subject:o,canDelegate:!0,operations:i,expiresAt:a,...n!==void 0?{bucketId:n}:{}}),f=xi(2,m),y=await t.sign(f),h=r==="ed25519"?Tp.ED_25519:Tp.SR_25519,v=Sg(h,t.publicKey,y);return zo(Mg(v,m))}async function Rp(e,t){let r=e.segmentSeconds??25,o=await t.decode(e.blob),n=o.length/t.sampleRate;e.softCapSeconds&&n>e.softCapSeconds&&e.onWarn?.(`Recording is ${Math.round(n/60)} min; long uploads may be slow.`);let c=Mp(o,t.sampleRate,r),i=[];for(let a=0;a<c.length;a++)i.push(await t.upload(Ep(c[a],t.sampleRate),a)),e.onProgress?.(a+1,c.length);return t.upload.finalizeUrls?await t.upload.finalizeUrls(i):i}async function Pg(e){let t=await crypto.subtle.digest("SHA-256",e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength));return Array.from(new Uint8Array(t)).map(r=>r.toString(16).padStart(2,"0")).join("")}async function Na(e,t,r,o=""){let n=new TextEncoder().encode(o),c=await e(n);return{"Content-Type":"application/json","X-Public-Key":xr(t),"X-Signature":xr(c).slice(2),"X-Signature-Type":r}}var Tg="widget-runtime",Og=/credential limit reached/i;function Ag(e,t=Date.now()){return!(e.revoked||e.expires_at&&Date.parse(e.expires_at)<=t)}async function Rg(e){let t=await e.fetchImpl(`${e.gatewayUrl}/auth/credentials`,{headers:await Na(e.sign,e.publicKey,e.sigType)});if(!t.ok)throw new Error(`GET ${e.gatewayUrl}/auth/credentials \u2192 ${t.status} ${await t.text()}`);let r=await t.json();return Array.isArray(r)?r:r.credentials??[]}async function jp(e,t){let r=JSON.stringify({access_key_id:t}),o=await e.fetchImpl(`${e.gatewayUrl}/auth/credentials`,{method:"DELETE",headers:await Na(e.sign,e.publicKey,e.sigType,r),body:r});if(!o.ok)throw new Error(`DELETE ${e.gatewayUrl}/auth/credentials (${t}) \u2192 ${o.status} ${await o.text()}`)}async function jg(e,t,r){let o=JSON.stringify({delegation_token:t,label:r}),n=async()=>e.fetchImpl(`${e.gatewayUrl}/auth/credentials`,{method:"POST",headers:await Na(e.sign,e.publicKey,e.sigType,o),body:o}),c=await n();if(c.status===400){let i=await c.text();if(!Og.test(i))throw new Error(`POST ${e.gatewayUrl}/auth/credentials \u2192 400 ${i}`);let f=(await Rg(e)).filter(y=>Ag(y)&&y.label===r).sort((y,h)=>Date.parse(y.created_at??"")-Date.parse(h.created_at??""))[0];if(!f)throw new Error(`POST ${e.gatewayUrl}/auth/credentials \u2192 400 ${i}. The wallet is at its live-credential cap and no row is labeled "${r}", so nothing can be reclaimed automatically. Revoke an unused credential (GET /auth/credentials to list; DELETE with a signed {"access_key_id"} body), then retry.`);console.warn(`[widget-runtime] credential cap reached \u2014 revoking oldest "${r}" credential ${f.access_key_id} and retrying`),await jp(e,f.access_key_id),c=await n()}if(!c.ok)throw new Error(`POST ${e.gatewayUrl}/auth/credentials \u2192 ${c.status} ${await c.text()}`);return await c.json()}function Ng(e){let t=e.fetchImpl??globalThis.fetch,r=e.awsClientFactory??(f=>new Aa({accessKeyId:f.accessKeyId,secretAccessKey:f.secretAccessKey,region:f.region,service:"s3",...f.sessionToken?{sessionToken:f.sessionToken}:{}})),o=e.credentialLabel??Tg,n={fetchImpl:t,gatewayUrl:e.gatewayUrl,sign:e.signerPair.sign,publicKey:e.signerPair.publicKey,sigType:e.sigType},c=null,i=null;async function a(){let f=await t(`${e.gatewayUrl}/auth/info`,{headers:await Na(n.sign,n.publicKey,e.sigType)});if(!f.ok)throw new Error(`GET ${e.gatewayUrl}/auth/info \u2192 ${f.status} ${await f.text()}`);let y=await f.json(),h=await Ap({signerPair:{sign:n.sign,publicKey:n.publicKey},signerType:e.sigType,subject:or(y.gateway_public_key)});return jg(n,h,o)}function m(){return i||(i=(async()=>{c||(c=a().catch(y=>{throw c=null,y}));let f=await c;return r({accessKeyId:f.access_key_id,secretAccessKey:f.secret_access_key,region:e.region,...f.session_token?{sessionToken:f.session_token}:{}})})().catch(f=>{throw i=null,f})),i}return{gatewayUrl:e.gatewayUrl,bucketId:e.bucketId,region:e.region,readTtl:e.readTtlSeconds??21600,aws:m,async refresh(){let f=c?await c.catch(()=>null):null;if(c=null,i=null,await m(),f)try{await jp(n,f.access_key_id)}catch(y){console.warn(`[widget-runtime] revoke of replaced credential failed (non-fatal): ${y instanceof Error?y.message:String(y)}`)}}}}function Np(e){let t=Ng(e),r=e.keyPrefix??`widget-audio/${crypto.randomUUID()}`,o=new Map;async function n(i,a){return e.readMode==="public"?a:(await i.sign(`${a}?X-Amz-Expires=${t.readTtl}`,{aws:{signQuery:!0}})).url}let c=async function(a,m){let f=new Uint8Array(a),y=await Pg(f),h=e.region,v=`${e.gatewayUrl}/${e.bucketId}/${r}/${m}.wav`,w=4,O=0,B="";for(let R=1;R<=w;R++){let k=await t.aws();console.log("[wr-up] PUT region=",h,"bucket=",e.bucketId,"index=",m,"attempt=",R,"bytes=",f.length,"sha=",y.slice(0,16));let S=await k.fetch(v,{method:"PUT",body:new Blob([f],{type:"audio/wav"}),headers:{"Content-Type":"audio/wav","X-Amz-Content-Sha256":y,...e.readMode==="public"?{"x-amz-acl":"public-read"}:{}}});if(S.ok)return o.set(m,v),await n(k,v);if(O=S.status,B=await S.text(),(S.status===403||S.status===401)&&R<w){R>=2&&await t.refresh(),await new Promise(E=>setTimeout(E,600*R));continue}break}throw new Error(`PUT ${v} \u2192 ${O} ${B}`)};return c.finalizeUrls=async i=>{if(o.size===0)return i;let a=await t.aws(),m=[...o.entries()].sort(([y],[h])=>y-h),f=[];for(let[,y]of m)f.push(await n(a,y));return f},c}$u();function Dg(e){typeof document<"u"&&document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e,{once:!0}):e()}function Xg(){let e=window.WidgetSandbox?.manifest;if(!e)return;let t=fp(),r=null,o=()=>r||(r=(async()=>{let i=await t.requestIdentity();if(i)return{source:"host",publicKey:i.pubkey,sigType:i.sigType,sign:m=>t.sign(m)};let a=await bp(e.wallet);return{source:"wallet",publicKey:a.pubkey(),sigType:a.sigType,sign:m=>a.signRawBytes(m)}})().catch(i=>{throw r=null,i}),r),n={resolveIdentity:async()=>{let i=await o();return{source:i.source,publicKey:i.publicKey,sigType:i.sigType}},buildVaultClient:(i,a)=>{let m=a.sigType??"ed25519",f=v=>o().then(w=>w.sign(v)),y=Fu(a.publicKey,m,f);return wp(i,()=>new ji({endpoint:i.endpoints.vault,garEndpoint:i.endpoints.gar,marketplaceEndpoint:i.endpoints.marketplace,s3GatewayAuthInfoUrl:i.endpoints.s3GatewayAuthInfo,signer:y}))}},c;if(e.kind==="submit"||e.kind==="conversation"||e.kind==="composite"){let i=null,a=()=>i||(i=(async()=>{let f=await o(),y=dp(f.publicKey,f.sign),h=Fu(f.publicKey,f.sigType,f.sign),w=await new ji({endpoint:e.endpoints.vault,garEndpoint:e.endpoints.gar,marketplaceEndpoint:e.endpoints.marketplace,s3GatewayAuthInfoUrl:e.endpoints.s3GatewayAuthInfo,signer:h}).vault.ensure({onboard:!1});return Np({signerPair:y,sigType:f.sigType,gatewayUrl:e.endpoints.s3GatewayAuthInfo.replace(/\/auth\/info\/?$/,""),bucketId:w.bucketId,region:w.region})})().catch(f=>{throw i=null,f}),i);c={uploadAudio:(f,y)=>a().then(h=>Rp({blob:f,segmentSeconds:y?.segmentSeconds,softCapSeconds:y?.softCapSeconds,onProgress:y?.onProgress,onWarn:y?.onWarn},{decode:Pp,upload:h,sampleRate:16e3}))}}window.WidgetRuntime=vp(e,n),window.registerCompositePanel=Kp,e.kind&&e.kind!=="custom"&&e.config&&Dg(()=>{let i=document.getElementById("app");i&&Promise.resolve().then(()=>(_u(),Zp)).then(({mountKind:a})=>a(i,e.config,window.WidgetRuntime,c))})}Xg();})();
307
+ `)}async hexBodyHash(){let t=this.headers.get("X-Amz-Content-Sha256")||(this.service==="s3"&&this.signQuery?"UNSIGNED-PAYLOAD":null);if(t==null){if(this.body&&typeof this.body!="string"&&!("byteLength"in this.body))throw new Error("body must be a string, ArrayBuffer or ArrayBufferView, unless you include the X-Amz-Content-Sha256 header");t=Wu(await xp(this.body||""))}return t}};async function us(e,t){let r=await crypto.subtle.importKey("raw",typeof e=="string"?Vu.encode(e):e,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]);return crypto.subtle.sign("HMAC",r,Vu.encode(t))}async function xp(e){return crypto.subtle.digest("SHA-256",typeof e=="string"?Vu.encode(e):e)}var kp=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];function Wu(e){let t=new Uint8Array(e),r="";for(let o=0;o<t.length;o++){let n=t[o];r+=kp[n>>>4&15],r+=kp[n&15]}return r}function Sp(e){return e.replace(/[!'()*]/g,t=>"%"+t.charCodeAt(0).toString(16).toUpperCase())}function kg(e,t){let{hostname:r,pathname:o}=e;if(r.endsWith(".on.aws")){let a=r.match(/^[^.]{1,63}\.lambda-url\.([^.]{1,63})\.on\.aws$/);return a!=null?["lambda",a[1]||""]:["",""]}if(r.endsWith(".r2.cloudflarestorage.com"))return["s3","auto"];if(r.endsWith(".backblazeb2.com")){let a=r.match(/^(?:[^.]{1,63}\.)?s3\.([^.]{1,63})\.backblazeb2\.com$/);return a!=null?["s3",a[1]||""]:["",""]}let n=r.replace("dualstack.","").match(/([^.]{1,63})\.(?:([^.]{0,63})\.)?amazonaws\.com(?:\.cn)?$/),c=n&&n[1]||"",i=n&&n[2];if(i==="us-gov")i="us-gov-west-1";else if(i==="s3"||i==="s3-accelerate")i="us-east-1",c="s3";else if(c==="iot")r.startsWith("iot.")?c="execute-api":r.startsWith("data.jobs.iot.")?c="iot-jobs-data":c=o==="/mqtt"?"iotdevicegateway":"iotdata";else if(c==="autoscaling"){let a=(t.get("X-Amz-Target")||"").split(".")[0];a==="AnyScaleFrontendService"?c="application-autoscaling":a==="AnyScaleScalingPlannerFrontendService"&&(c="autoscaling-plans")}else i==null&&c.startsWith("s3-")?(i=c.slice(3).replace(/^fips-|^external-1/,""),c="s3"):c.endsWith("-fips")?c=c.slice(0,-5):i&&/-\d$/.test(c)&&!/-\d$/.test(i)&&([c,i]=[i,c]);return[vg[c]||c,i||""]}function Ep(e,t){let r=new ArrayBuffer(44+e.length*2),o=new DataView(r),n=(i,a)=>{for(let m=0;m<a.length;m++)o.setUint8(i+m,a.charCodeAt(m))};n(0,"RIFF"),o.setUint32(4,36+e.length*2,!0),n(8,"WAVE"),n(12,"fmt "),o.setUint32(16,16,!0),o.setUint16(20,1,!0),o.setUint16(22,1,!0),o.setUint32(24,t,!0),o.setUint32(28,t*2,!0),o.setUint16(32,2,!0),o.setUint16(34,16,!0),n(36,"data"),o.setUint32(40,e.length*2,!0);let c=44;for(let i=0;i<e.length;i++,c+=2){let a=Math.max(-1,Math.min(1,e[i]));o.setInt16(c,a<0?a*32768:a*32767,!0)}return r}function Mp(e,t,r){let o=t*r,n=[];for(let c=0;c<e.length;c+=o)n.push(e.subarray(c,Math.min(c+o,e.length)));return n.length?n:[e]}async function Pp(e){let t=await e.arrayBuffer(),r=window.OfflineAudioContext||window.webkitOfflineAudioContext,o=new(window.AudioContext||window.webkitAudioContext),n=await o.decodeAudioData(t.slice(0));o.close();let c=Math.ceil(n.duration*16e3),i=new r(1,c,16e3),a=i.createBufferSource();return a.buffer=n,a.connect(i.destination),a.start(),(await i.startRendering()).getChannelData(0).slice()}function ja(e){let t=[],r=typeof e=="bigint"?e:BigInt(e);r<0n&&(r&=0xffffffffffffffffn);do{let o=Number(r&0x7fn);r>>=7n,t.push(r>0n?o|128:o)}while(r>0n);return new Uint8Array(t)}function co(...e){let t=e.reduce((n,c)=>n+c.length,0),r=new Uint8Array(t),o=0;for(let n of e)r.set(n,o),o+=n.length;return r}var Op=(e,t)=>ja(e*8+t),Ra=(e,t)=>co(Op(e,0),ja(t)),xi=(e,t)=>co(Op(e,2),ja(t.length),t);function Sg(e,t,r){return co(Ra(1,e),xi(2,t),xi(3,r))}function Eg({subject:e,canDelegate:t,bucketId:r,operations:o,expiresAt:n}){let c=[xi(2,e),Ra(3,t?1:0)];return r!==void 0&&c.push(Ra(4,typeof r=="bigint"?r:BigInt(r))),o.length>0&&c.push(xi(5,co(...o.map(i=>ja(i))))),c.push(Ra(6,n)),co(...c)}var Mg=(e,t)=>co(xi(1,e),xi(2,t)),Ku=Object.freeze({PUT:1,GET:2,DELETE:3}),Tp=Object.freeze({ED_25519:0,SR_25519:1});async function Ap(e){let{signerPair:t,signerType:r,subject:o,bucketId:n,expiresIn:c=30*24*60*60*1e3,operations:i=[Ku.PUT,Ku.GET,Ku.DELETE]}=e,a=Date.now()+c,m=Eg({subject:o,canDelegate:!0,operations:i,expiresAt:a,...n!==void 0?{bucketId:n}:{}}),f=xi(2,m),y=await t.sign(f),h=r==="ed25519"?Tp.ED_25519:Tp.SR_25519,v=Sg(h,t.publicKey,y);return zo(Mg(v,m))}async function Rp(e,t){let r=e.segmentSeconds??25,o=await t.decode(e.blob),n=o.length/t.sampleRate;e.softCapSeconds&&n>e.softCapSeconds&&e.onWarn?.(`Recording is ${Math.round(n/60)} min; long uploads may be slow.`);let c=Mp(o,t.sampleRate,r),i=[];for(let a=0;a<c.length;a++)i.push(await t.upload(Ep(c[a],t.sampleRate),a)),e.onProgress?.(a+1,c.length);return t.upload.finalizeUrls?await t.upload.finalizeUrls(i):i}async function Pg(e){let t=await crypto.subtle.digest("SHA-256",e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength));return Array.from(new Uint8Array(t)).map(r=>r.toString(16).padStart(2,"0")).join("")}async function Na(e,t,r,o=""){let n=new TextEncoder().encode(o),c=await e(n);return{"Content-Type":"application/json","X-Public-Key":xr(t),"X-Signature":xr(c).slice(2),"X-Signature-Type":r}}var Tg="widget-runtime",Og=/credential limit reached/i;function Ag(e,t=Date.now()){return!(e.revoked||e.expires_at&&Date.parse(e.expires_at)<=t)}async function Rg(e){let t=await e.fetchImpl(`${e.gatewayUrl}/auth/credentials`,{headers:await Na(e.sign,e.publicKey,e.sigType)});if(!t.ok)throw new Error(`GET ${e.gatewayUrl}/auth/credentials \u2192 ${t.status} ${await t.text()}`);let r=await t.json();return Array.isArray(r)?r:r.credentials??[]}async function jp(e,t){let r=JSON.stringify({access_key_id:t}),o=await e.fetchImpl(`${e.gatewayUrl}/auth/credentials`,{method:"DELETE",headers:await Na(e.sign,e.publicKey,e.sigType,r),body:r});if(!o.ok)throw new Error(`DELETE ${e.gatewayUrl}/auth/credentials (${t}) \u2192 ${o.status} ${await o.text()}`)}async function jg(e,t,r){let o=JSON.stringify({delegation_token:t,label:r}),n=async()=>e.fetchImpl(`${e.gatewayUrl}/auth/credentials`,{method:"POST",headers:await Na(e.sign,e.publicKey,e.sigType,o),body:o}),c=await n();if(c.status===400){let i=await c.text();if(!Og.test(i))throw new Error(`POST ${e.gatewayUrl}/auth/credentials \u2192 400 ${i}`);let f=(await Rg(e)).filter(y=>Ag(y)&&y.label===r).sort((y,h)=>Date.parse(y.created_at??"")-Date.parse(h.created_at??""))[0];if(!f)throw new Error(`POST ${e.gatewayUrl}/auth/credentials \u2192 400 ${i}. The wallet is at its live-credential cap and no row is labeled "${r}", so nothing can be reclaimed automatically. Revoke an unused credential (GET /auth/credentials to list; DELETE with a signed {"access_key_id"} body), then retry.`);console.warn(`[widget-runtime] credential cap reached \u2014 revoking oldest "${r}" credential ${f.access_key_id} and retrying`),await jp(e,f.access_key_id),c=await n()}if(!c.ok)throw new Error(`POST ${e.gatewayUrl}/auth/credentials \u2192 ${c.status} ${await c.text()}`);return await c.json()}function Ng(e){let t=e.fetchImpl??globalThis.fetch.bind(globalThis),r=e.awsClientFactory??(f=>new Aa({accessKeyId:f.accessKeyId,secretAccessKey:f.secretAccessKey,region:f.region,service:"s3",...f.sessionToken?{sessionToken:f.sessionToken}:{}})),o=e.credentialLabel??Tg,n={fetchImpl:t,gatewayUrl:e.gatewayUrl,sign:e.signerPair.sign,publicKey:e.signerPair.publicKey,sigType:e.sigType},c=null,i=null;async function a(){let f=await t(`${e.gatewayUrl}/auth/info`,{headers:await Na(n.sign,n.publicKey,e.sigType)});if(!f.ok)throw new Error(`GET ${e.gatewayUrl}/auth/info \u2192 ${f.status} ${await f.text()}`);let y=await f.json(),h=await Ap({signerPair:{sign:n.sign,publicKey:n.publicKey},signerType:e.sigType,subject:or(y.gateway_public_key)});return jg(n,h,o)}function m(){return i||(i=(async()=>{c||(c=a().catch(y=>{throw c=null,y}));let f=await c;return r({accessKeyId:f.access_key_id,secretAccessKey:f.secret_access_key,region:e.region,...f.session_token?{sessionToken:f.session_token}:{}})})().catch(f=>{throw i=null,f})),i}return{gatewayUrl:e.gatewayUrl,bucketId:e.bucketId,region:e.region,readTtl:e.readTtlSeconds??21600,aws:m,async refresh(){let f=c?await c.catch(()=>null):null;if(c=null,i=null,await m(),f)try{await jp(n,f.access_key_id)}catch(y){console.warn(`[widget-runtime] revoke of replaced credential failed (non-fatal): ${y instanceof Error?y.message:String(y)}`)}}}}function Np(e){let t=Ng(e),r=e.keyPrefix??`widget-audio/${crypto.randomUUID()}`,o=new Map;async function n(i,a){return e.readMode==="public"?a:(await i.sign(`${a}?X-Amz-Expires=${t.readTtl}`,{aws:{signQuery:!0}})).url}let c=async function(a,m){let f=new Uint8Array(a),y=await Pg(f),h=e.region,v=`${e.gatewayUrl}/${e.bucketId}/${r}/${m}.wav`,w=4,O=0,B="";for(let R=1;R<=w;R++){let k=await t.aws();console.log("[wr-up] PUT region=",h,"bucket=",e.bucketId,"index=",m,"attempt=",R,"bytes=",f.length,"sha=",y.slice(0,16));let S=await k.fetch(v,{method:"PUT",body:new Blob([f],{type:"audio/wav"}),headers:{"Content-Type":"audio/wav","X-Amz-Content-Sha256":y,...e.readMode==="public"?{"x-amz-acl":"public-read"}:{}}});if(S.ok)return o.set(m,v),await n(k,v);if(O=S.status,B=await S.text(),(S.status===403||S.status===401)&&R<w){R>=2&&await t.refresh(),await new Promise(E=>setTimeout(E,600*R));continue}break}throw new Error(`PUT ${v} \u2192 ${O} ${B}`)};return c.finalizeUrls=async i=>{if(o.size===0)return i;let a=await t.aws(),m=[...o.entries()].sort(([y],[h])=>y-h),f=[];for(let[,y]of m)f.push(await n(a,y));return f},c}$u();function Dg(e){typeof document<"u"&&document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e,{once:!0}):e()}function Xg(){let e=window.WidgetSandbox?.manifest;if(!e)return;let t=fp(),r=null,o=()=>r||(r=(async()=>{let i=await t.requestIdentity();if(i)return{source:"host",publicKey:i.pubkey,sigType:i.sigType,sign:m=>t.sign(m)};let a=await bp(e.wallet);return{source:"wallet",publicKey:a.pubkey(),sigType:a.sigType,sign:m=>a.signRawBytes(m)}})().catch(i=>{throw r=null,i}),r),n={resolveIdentity:async()=>{let i=await o();return{source:i.source,publicKey:i.publicKey,sigType:i.sigType}},buildVaultClient:(i,a)=>{let m=a.sigType??"ed25519",f=v=>o().then(w=>w.sign(v)),y=Fu(a.publicKey,m,f);return wp(i,()=>new ji({endpoint:i.endpoints.vault,garEndpoint:i.endpoints.gar,marketplaceEndpoint:i.endpoints.marketplace,s3GatewayAuthInfoUrl:i.endpoints.s3GatewayAuthInfo,signer:y}))}},c;if(e.kind==="submit"||e.kind==="conversation"||e.kind==="composite"){let i=null,a=()=>i||(i=(async()=>{let f=await o(),y=dp(f.publicKey,f.sign),h=Fu(f.publicKey,f.sigType,f.sign),w=await new ji({endpoint:e.endpoints.vault,garEndpoint:e.endpoints.gar,marketplaceEndpoint:e.endpoints.marketplace,s3GatewayAuthInfoUrl:e.endpoints.s3GatewayAuthInfo,signer:h}).vault.ensure({onboard:!1});return Np({signerPair:y,sigType:f.sigType,gatewayUrl:e.endpoints.s3GatewayAuthInfo.replace(/\/auth\/info\/?$/,""),bucketId:w.bucketId,region:w.region})})().catch(f=>{throw i=null,f}),i);c={uploadAudio:(f,y)=>a().then(h=>Rp({blob:f,segmentSeconds:y?.segmentSeconds,softCapSeconds:y?.softCapSeconds,onProgress:y?.onProgress,onWarn:y?.onWarn},{decode:Pp,upload:h,sampleRate:16e3}))}}window.WidgetRuntime=vp(e,n),window.registerCompositePanel=Kp,e.kind&&e.kind!=="custom"&&e.config&&Dg(()=>{let i=document.getElementById("app");i&&Promise.resolve().then(()=>(_u(),Zp)).then(({mountKind:a})=>a(i,e.config,window.WidgetRuntime,c))})}Xg();})();
308
308
  /*! Bundled license information:
309
309
 
310
310
  @cere/embed-wallet/dist/bundle.umd.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cef-ai/widget-runtime",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",