palbase 0.17.1 → 0.18.0

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.
Files changed (54) hide show
  1. package/dist/ai/index.js +2 -2
  2. package/dist/backend/engine.js +2 -2
  3. package/dist/backend/env.js +1 -1
  4. package/dist/backend/index.js +3 -3
  5. package/dist/backend/stack.js +1 -1
  6. package/dist/backend/test.js +2 -2
  7. package/dist/chunks/{OER3S5NN.js → 32XY6IBN.js} +2 -2
  8. package/dist/chunks/{ZSUSEU5H.js → 3GWBIPGH.js} +2 -2
  9. package/dist/chunks/{Y6NZV7LU.js → 4HFD24QY.js} +1 -1
  10. package/dist/chunks/{XT3I7PG3.js → 4S4ODZVM.js} +2 -2
  11. package/dist/chunks/{KBDCHYSD.js → 6IMY2J5W.js} +1 -1
  12. package/dist/chunks/{B2IIU37G.js → 7QFBZLAK.js} +1 -1
  13. package/dist/chunks/{LAHIVWPV.js → 7R4WTDHI.js} +1 -1
  14. package/dist/chunks/{VXT46THA.js → ART5HP5M.js} +2 -2
  15. package/dist/chunks/{22M4UQVQ.js → BKGX3AZA.js} +2 -2
  16. package/dist/chunks/{6WGPEHCE.js → BW5DFI3C.js} +1 -1
  17. package/dist/chunks/{7C7HACEZ.js → CAZYHE64.js} +2 -2
  18. package/dist/chunks/EVBWED24.js +22 -0
  19. package/dist/chunks/{DWRLUP7O.js → FT7G3QQ4.js} +2 -2
  20. package/dist/chunks/{NJFKRHS6.js → JKA2W4E5.js} +2 -2
  21. package/dist/chunks/{K23K6ZFG.js → KRQZOF2L.js} +2 -2
  22. package/dist/chunks/{FWX3RGVS.js → OC32TP3L.js} +2 -2
  23. package/dist/chunks/{2PIDGENK.js → PMQOJ7FF.js} +2 -2
  24. package/dist/chunks/{E27BZ5SM.js → PPK2UEAY.js} +2 -2
  25. package/dist/chunks/{3UVLEWTM.js → T2O6XEQO.js} +1 -1
  26. package/dist/chunks/{3Y4K6F6T.js → VQXYHAU4.js} +2 -2
  27. package/dist/chunks/{R7PRW7FG.js → XF3JEDIQ.js} +1 -1
  28. package/dist/chunks/{LR5ONXTF.js → XHNZDLR4.js} +2 -2
  29. package/dist/chunks/{CYLNEHKQ.js → ZXV3ZKVM.js} +2 -2
  30. package/dist/cli.js +2 -2
  31. package/dist/refuse/ai.js +1 -1
  32. package/dist/refuse/backend.js +1 -1
  33. package/dist/refuse/server.js +1 -1
  34. package/dist/server/index.js +2 -2
  35. package/dist/server/testing.js +2 -2
  36. package/dist/web/index.js +2 -2
  37. package/dist/web/message.js +2 -2
  38. package/dist/web/palbe.js +2 -2
  39. package/dist/web/paywall.js +2 -2
  40. package/dist/web/push-sw.js +1 -1
  41. package/dist/web/ssr.js +2 -2
  42. package/dist/web/vite.js +2 -2
  43. package/package.json +2 -2
  44. package/types/internal/src/messaging/engine.d.ts +31 -0
  45. package/types/internal/src/messaging/files.d.ts +11 -0
  46. package/types/internal/src/messaging/index.d.ts +5 -0
  47. package/types/internal/src/messaging/local.d.ts +31 -0
  48. package/types/internal/src/messaging/outbox.d.ts +53 -0
  49. package/types/internal/src/messaging/store.d.ts +67 -0
  50. package/types/internal/src/modules/purchases.d.ts +2 -2
  51. package/types/web/src/client.d.ts +5 -0
  52. package/types/web/src/index.d.ts +1 -0
  53. package/types/web/src/messaging.d.ts +280 -0
  54. package/dist/chunks/LIKE2KDM.js +0 -22
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
2
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
3
3
  var uy=Object.defineProperty;var Ze=(e,t)=>{for(var n in t)uy(e,n,{get:t[n],enumerable:!0})};import{parseArgs as Vy}from"node:util";var cy=Symbol.for("palbase.data"),gy=globalThis,yl=gy[cy]??=new WeakSet;function hy(e){return e instanceof Date||ArrayBuffer.isView(e)||e instanceof ArrayBuffer}function fa(e){let t=[e];for(;t.length>0;){let n=t.pop();if(!(typeof n!="object"||n===null||yl.has(n)||hy(n))){yl.add(n);for(let s of Array.isArray(n)?n:Object.values(n))t.push(s)}}return e}var my="X-PoW-Challenge-ID",fy="X-PoW-Nonce";function bl(e){if(typeof e!="object"||e===null)return null;let t=e;if(t.error!=="pow_required"||typeof t.challenge!="object"||t.challenge===null)return null;let{id:n,prefix:s,difficulty:a}=t.challenge;return typeof n!="string"||typeof s!="string"||typeof a!="number"||!Number.isInteger(a)||a<0?null:{id:n,prefix:s,difficulty:a}}function yy(e){return 8*2**e}var qn;async function by(){if(qn)return qn;let e=globalThis;if(e.process?.versions?.node!==void 0||e.process?.versions?.bun!==void 0)try{let s=(await import("node:crypto")).createHash;if(typeof s=="function")return qn=a=>new Uint8Array(s("sha256").update(a).digest()),qn}catch{}let t=new TextEncoder;return qn=async n=>new Uint8Array(await crypto.subtle.digest("SHA-256",t.encode(n))),qn}function wy(e){let t=0;for(let n of e){if(n===0){t+=8;continue}return t+Math.clz32(n)-24}return t}var vy=4096,_y=typeof globalThis.setImmediate=="function"?()=>new Promise(e=>globalThis.setImmediate(e)):()=>new Promise(e=>setTimeout(e,0));async function wl(e,t={}){if(e.difficulty>24)throw new Error(`proof-of-work: difficulty ${e.difficulty} is above auth's ceiling of 24`);let n=await by(),s=yy(e.difficulty),a=Date.now()+(t.timeLimitMs??12e4);for(let r=0;r<s;r++){if(r%vy===0&&r>0){if(await _y(),t.signal?.aborted)throw t.signal.reason??new DOMException("proof-of-work aborted","AbortError");if(Date.now()>a)throw new Error(`proof-of-work: gave up on difficulty ${e.difficulty} after ${r} attempts`)}let i=n(e.prefix+r),o=i instanceof Uint8Array?i:await i;if(wy(o)>=e.difficulty)return{[my]:e.id,[fy]:String(r)}}throw new Error(`proof-of-work: no nonce for difficulty ${e.difficulty} within ${s} attempts`)}var x=class extends Error{status;code;requestId;retryAfter;body;op;get isNetworkError(){return this.code==="network_error"}constructor(t){super(t.message,t.cause===void 0?void 0:{cause:t.cause}),this.name="PalbaseError",this.op=t.op,this.status=t.status,this.code=t.code,this.requestId=t.requestId,this.retryAfter=t.retryAfter,this.body=t.body}};function g(e,t,n){let s=String(n);if(s===""||s==="."||s==="..")throw new x({op:e,status:0,code:"invalid_path_parameter",message:`${e}: ${t} cannot be ${s===""?"empty":JSON.stringify(s)}`});return encodeURIComponent(s)}var ky=new Set(["apikey","authorization"]),Sy=64*1024;function Hr(e){let t=ya(e.baseUrl),n=e.fetch??globalThis.fetch,s=e.solveProofOfWork??!0,a=async(r,i)=>{let o=Ay(t,r),l=new Headers;for(let[f,w]of Object.entries(r.headers??{}))w!=null&&!ky.has(f.toLowerCase())&&l.set(f,String(w));for(let[f,w]of Object.entries(i))l.set(f,w);await Ry(r,e.credentials,l),l.has("accept")||l.set("accept","application/json");let d={method:r.method,headers:l,redirect:"manual",signal:r.signal,...r.keepalive?{keepalive:!0}:{}};r.body&&r.body.value!==void 0&&(l.set("content-type",r.body.contentType),d.body=Ty(r.body.kind,r.body.value),Kn(d.body)||(d.duplex="half"));let p;try{p=r.onUploadProgress&&e.xmlHttpRequest?await $y(e.xmlHttpRequest,r.op,o,d,r.onUploadProgress):await n(o,d)}catch(f){throw r.signal?.aborted||f instanceof x?f:new x({op:r.op,status:0,code:"network_error",message:`${r.op}: the request did not reach ${t.origin}`,cause:f})}let u=r.answers[p.status];if(u===void 0)throw p.status>=200&&p.status<300?(await p.body?.cancel(),new x({op:r.op,status:p.status,code:"undeclared_answer",message:`${r.op}: the server answered ${p.status}, which its contract does not declare; the request may have taken effect`})):await Cy(r.op,p);let c;switch(u){case"json":try{c=fa(await p.json())}catch(f){throw new x({op:r.op,status:p.status,code:"invalid_json",message:`${r.op}: the answer is not JSON`,cause:f})}break;case"raw":c=p;break;default:await p.body?.cancel(),c=void 0}return{status:p.status,data:c,headers:p.headers}};return{async send(r){try{return await a(r,{})}catch(i){let o=s&&i instanceof x&&i.status===403?bl(i.body):null,l=r.body?.value;if(!o||r.body?.kind==="raw"&&!Kn(l))throw i;let d=i,p;try{p=await wl(o,{signal:r.signal})}catch(u){throw r.signal?.aborted?u:new x({op:r.op,status:403,code:"pow_unsolved",message:`${r.op}: ${u instanceof Error?u.message:String(u)}`,requestId:d.requestId,body:d.body,cause:u})}return a(r,p)}}}}function $y(e,t,n,s,a){return new Promise((r,i)=>{let o=s.signal;if(o?.aborted)return i(o.reason);let l=new e,d=()=>l.abort();o?.addEventListener("abort",d,{once:!0});let p=u=>{o?.removeEventListener("abort",d),u()};l.open(s.method??"GET",n.href),l.responseType="arraybuffer",new Headers(s.headers).forEach((u,c)=>l.setRequestHeader(c,u)),l.upload&&(l.upload.onprogress=u=>{u.lengthComputable&&a(u.loaded,u.total)}),l.onload=()=>p(()=>{if(l.responseURL!==""&&l.responseURL!==n.href){i(new x({op:t,status:0,code:"undeclared_redirect",message:`${t}: the server redirected; the answer is another address's, and was not read`}));return}if(l.status<200||l.status>599)return i(new TypeError(`${t}: answered ${l.status}`));let u=l.status===204||l.status===205||l.status===304;r(new Response(u?null:l.response,{status:l.status,statusText:l.statusText,headers:Py(l.getAllResponseHeaders())}))}),l.onerror=()=>p(()=>i(new TypeError(`${t}: the request failed`))),l.onabort=()=>p(()=>i(o?.reason??new DOMException("The request was aborted","AbortError"))),l.send(s.body)})}function Py(e){let t=new Headers;for(let n of e.split(/\r?\n/)){let s=n.indexOf(":");if(!(s<=0))try{t.append(n.slice(0,s).trim(),n.slice(s+1).trim())}catch{}}return t}function ya(e){let t;try{t=new URL(e)}catch{throw new TypeError(`baseUrl ${JSON.stringify(e)} is not an absolute URL`)}let n=t.hostname==="localhost"||t.hostname.endsWith(".localhost")||t.hostname==="127.0.0.1"||t.hostname==="[::1]";if(t.protocol!=="https:"&&!(t.protocol==="http:"&&n))throw new TypeError(`baseUrl must be https (http only for a loopback address): ${t.origin}`);if(t.username||t.password||t.search||t.hash)throw new TypeError("baseUrl carries no user, query or fragment");if(t.pathname!=="/"&&t.pathname!=="")throw new TypeError("baseUrl is the project origin alone, with no path");return t}function Ay(e,t){if(!t.path.startsWith("/")||t.path.startsWith("//"))throw new x({op:t.op,status:0,code:"invalid_path",message:`${t.op}: path ${JSON.stringify(t.path)} is not absolute`});let n=new URL(t.path+Ey(t.query),e);if(n.origin!==e.origin)throw new x({op:t.op,status:0,code:"invalid_path",message:`${t.op}: path leaves the project's origin`});return n}async function Ry(e,t,n){if(e.auth.length===0)return;let s=e.auth.some(i=>i.includes("userJWT"))?await t.accessToken?.():void 0,a=i=>{switch(i){case"ApiKeyAuth":return!!(t.publishableKey??t.secretKey);case"SecretKeyAuth":case"AdminAuth":return!!t.secretKey;case"userJWT":return!!s;default:return!1}},r=e.auth.filter(i=>i.every(a)).reduce((i,o)=>i===void 0||o.length>i.length?o:i,void 0);if(!r)throw new x({op:e.op,status:0,code:"missing_credential",message:`${e.op} needs one of: ${e.auth.map(i=>i.length===0?"nothing":i.join(" + ")).join(" | ")}`});for(let i of r)i==="ApiKeyAuth"?n.set("apikey",t.publishableKey??t.secretKey):i==="SecretKeyAuth"||i==="AdminAuth"?n.set("apikey",t.secretKey):i==="userJWT"&&n.set("authorization",`Bearer ${s}`)}function Ty(e,t){switch(e){case"json":return JSON.stringify(t);case"form":{let n=new URLSearchParams;for(let[s,a]of Object.entries(t))Xr(n,s,a);return n}case"raw":return t}}function Kn(e){return!!(e==null||typeof e=="string"||e instanceof URLSearchParams||e instanceof Blob||e instanceof FormData||e instanceof ArrayBuffer||ArrayBuffer.isView(e))}function Ey(e){if(!e)return"";let t=new URLSearchParams;for(let[s,a]of Object.entries(e))Xr(t,s,a);let n=t.toString();return n===""?"":`?${n}`}function Xr(e,t,n){if(n!=null){if(Array.isArray(n)){for(let s of n)Xr(e,t,s);return}if(n instanceof Date){e.append(t,n.toISOString());return}e.append(t,typeof n=="object"?JSON.stringify(n):String(n))}}async function Cy(e,t){let n=await jy(t,Sy).catch(()=>""),s;try{s=n===""?void 0:JSON.parse(n)}catch{s=n}let a=Oy(s)?s:void 0,r=Number(t.headers.get("retry-after")),i=t.status>=300&&t.status<400;return new x({op:e,status:t.status,code:a?.error??(i?"undeclared_redirect":`http_${t.status}`),message:a?.error_description??(i?`${e}: the server redirected (${t.status}); the request was not followed, its credentials stay here`:`${e}: ${t.status} ${t.statusText}`.trim()),requestId:a?.request_id??t.headers.get("x-request-id")??void 0,retryAfter:a?.retry_after??(Number.isFinite(r)&&r>0?r:void 0),body:s})}async function jy(e,t){if(!e.body)return"";let n=e.body.getReader(),s=[],a=0;for(;a<t;){let{done:o,value:l}=await n.read();if(o)break;s.push(l),a+=l.byteLength}await n.cancel().catch(()=>{});let r=new Uint8Array(Math.min(a,t)),i=0;for(let o of s){let l=Math.min(o.byteLength,r.byteLength-i);if(r.set(o.subarray(0,l),i),i+=l,i>=r.byteLength)break}return new TextDecoder().decode(r)}function Oy(e){return typeof e=="object"&&e!==null&&typeof e.error=="string"}var ba={project:{type:"string",short:"P",value:"project",description:"the project (name or id; org/project when the name is in two organizations)"},env:{type:"string",short:"E",value:"env",description:"the project's environment (slug or ref)"},json:{type:"boolean",description:"print the answer as JSON"},"non-interactive":{type:"boolean",description:"never ask: refuse what would need a question"},yes:{type:"boolean",short:"y",description:"confirm a change to a production environment without asking"},debug:{type:"boolean",description:"print each request the command sends"},help:{type:"boolean",short:"h",description:"show help"}};var y=class extends Error{exitCode;hint;code;reported;constructor(t,n,s={}){super(n),this.name="CliError",this.code=t,this.hint=s.hint,this.exitCode=s.exitCode??1,this.reported=s.reported??!1}};function m(e,t){return new y("usage",e,{hint:t,exitCode:2})}var wa=class{io;json;constructor(t,n){this.io=t,this.json=n}result(t,n){this.json?this.io.stdout(`${JSON.stringify(t,null,2)}
4
4
  `):n()}line(t=""){this.io.stdout(`${G(t)}
5
5
  `)}note(t){this.io.stderr(`${G(t)}
@@ -9,7 +9,7 @@ var uy=Object.defineProperty;var Ze=(e,t)=>{for(var n in t)uy(e,n,{get:t[n],enum
9
9
  `);let i;try{i=await this.io.fetch(t,{method:n.method,headers:{...n.headers,...a},body:n.body,signal:n.signal,...s?{}:{duplex:"half"},redirect:"manual"})}catch(l){throw n.signal?.aborted?l:new y("network_error",`${new URL(t).origin} could not be reached: ${l instanceof Error?l.message:String(l)}`)}if(this.debug&&this.io.stderr(`< ${i.status} ${i.headers.get("x-request-id")??""}
10
10
  `),i.status!==503||!s||r>=Fy||!zy.has(await Qr(i)??""))return i;await i.body?.cancel();let o=Number(i.headers.get("retry-after")??"");await this.io.sleep((Number.isFinite(o)&&o>0?Math.min(o,30):1)*1e3)}}async exchange(t,n,s){let a=await this.token(),r=await this.send(t,n,s,a.value);if(r.status===401&&a.renewable){let i=await this.renew(await this.currentSession());r=await this.send(t,n,s,i.access_token)}return{res:r,renewable:a.renewable}}async answered(t,n,s,a){if(s.status===204)return;let r=await s.text(),i=r===""?void 0:Jy(r);if(s.ok)return i;let o=i??{};throw s.status===401?o.error==="token_not_for_machines"?Ml(new URL(this.cloud.studioApi).host):a?Gn():this.tokenRefused("Studio"):new x({op:`${t} ${n}`,status:s.status,code:o.error??`http_${s.status}`,message:o.error_description??`Studio answered ${s.status}`,requestId:o.request_id??s.headers.get("x-request-id")??void 0,body:i})}tokenRefused(t){return(this.io.env.PALBASE_TOKEN??"").startsWith("pbe_")?new y("token_refused",`${t} refused PALBASE_TOKEN, an environment's token: it ended (a few hours at most), it was revoked, or what minted it no longer holds`,{hint:"mint another: palbase env:tokens:create --scope <scope> (an admin), or with the environment's secret key (Studio's POST /environments/{ref}/tokens)"}):new y("token_refused",`${t} refused PALBASE_TOKEN: it was revoked, it ended, or the one who made it no longer holds its role`,{hint:"an admin makes a new one: palbase tokens:create <name>"})}async token(){let t=this.io.env.PALBASE_TOKEN;return t&&t!==""?{value:t,renewable:!1}:{value:(await this.currentSession()).access_token,renewable:!0}}async renew(t){let n=await jl(this.io,this.cloud,t);return await this.state.writeSession(n),this.session=n,n}async send(t,n,s,a){let r=`${this.cloud.studioApi}${By}${n}`;this.debug&&this.io.stderr(`> ${t} ${r}
11
11
  `);try{let i=await this.io.fetch(r,{method:t,headers:{authorization:`Bearer ${a}`,accept:"application/json",...s===void 0?{}:{"content-type":"application/json"}},body:s===void 0?void 0:JSON.stringify(s),redirect:"manual"});return this.debug&&this.io.stderr(`< ${i.status} ${i.headers.get("x-request-id")??""}
12
- `),i}catch(i){throw new y("network_error",`Studio (${this.cloud.studioApi}) could not be reached: ${i instanceof Error?i.message:String(i)}`)}}};function Ml(e){return new y("token_not_for_machines",`the platform's edge refused PALBASE_TOKEN at ${e}, taking it for a machine's address (token_not_for_machines): the token itself was not refused`,{hint:"nothing is wrong with the token: run this again in a few minutes, and tell Palbase if it lasts"})}async function Qr(e){let t=await e.clone().json().catch(()=>null),n=t&&typeof t=="object"?t.error:void 0;return typeof n=="string"&&/^(console|token|edge)_/.test(n)?n:void 0}function Jy(e){try{return JSON.parse(e)}catch{return e}}var Ll={version:"0.17.1"};var $a=Ll.version;async function Gl(e,t,n){let s=new Map(n.map(i=>[i.name,i])),a=e.includes("--json"),r=e.includes("--debug");try{let{name:i,at:o}=Hy(e);if(i===void 0)return e.includes("--version")?(t.stdout(`palbase ${$a}
12
+ `),i}catch(i){throw new y("network_error",`Studio (${this.cloud.studioApi}) could not be reached: ${i instanceof Error?i.message:String(i)}`)}}};function Ml(e){return new y("token_not_for_machines",`the platform's edge refused PALBASE_TOKEN at ${e}, taking it for a machine's address (token_not_for_machines): the token itself was not refused`,{hint:"nothing is wrong with the token: run this again in a few minutes, and tell Palbase if it lasts"})}async function Qr(e){let t=await e.clone().json().catch(()=>null),n=t&&typeof t=="object"?t.error:void 0;return typeof n=="string"&&/^(console|token|edge)_/.test(n)?n:void 0}function Jy(e){try{return JSON.parse(e)}catch{return e}}var Ll={version:"0.18.0"};var $a=Ll.version;async function Gl(e,t,n){let s=new Map(n.map(i=>[i.name,i])),a=e.includes("--json"),r=e.includes("--debug");try{let{name:i,at:o}=Hy(e);if(i===void 0)return e.includes("--version")?(t.stdout(`palbase ${$a}
13
13
  `),0):(t.stdout(Kl(n)),e.length===0||e.includes("--help")||e.includes("-h")?0:2);if(i==="help"){let S=e[o+1],$=S===void 0?void 0:s.get(S);if(S!==void 0&&!$)throw Dl(S,n);return t.stdout($?ql($):Kl(n)),0}let l=s.get(i);if(!l)throw Dl(i,n);let d=[...e.slice(0,o),...e.slice(o+1)];if(d.includes("--help")||d.includes("-h"))return t.stdout(ql(l)),0;let{flags:p,positionals:u}=Xy(l,d),c=l.args??{min:0,max:0};if(u.length<c.min)throw m(`${l.name} needs ${c.min===1?"an argument":`${c.min} arguments`}`,ti(l));if(u.length>c.max)throw m(`${l.name} takes ${c.max===0?"no argument":`at most ${c.max}`}: ${JSON.stringify(u.slice(c.max))} is left over`,ti(l));let f={project:p.project,env:p.env,json:p.json===!0,nonInteractive:p["non-interactive"]===!0,yes:p.yes===!0,debug:p.debug===!0},w=Pl(t.env),v=new va(Tl(t.configDir,w)),T={io:t,state:v,out:new wa(t,f.json),global:f,args:u,flags:p,interactive:t.interactive&&!f.nonInteractive,cloud:w,studio:new Sa(t,w,v,f.debug)};return await l.run(T)??0}catch(i){return Yy(i,t,a,r)}}function Hy(e){let t=new Set;for(let[n,s]of Object.entries(ba))s.type==="string"&&(t.add(`--${n}`),s.short&&t.add(`-${s.short}`));for(let n=0;n<e.length;n++){let s=e[n];if(s==="--")return{at:-1};if(t.has(s)){n++;continue}if(!s.startsWith("-"))return{name:s,at:n}}return{at:-1}}function Xy(e,t){let n={...ba,...e.flags??{}},s={};for(let[a,r]of Object.entries(n))s[a]={type:r.type,...r.short?{short:r.short}:{},...r.multiple?{multiple:!0}:{}};try{let{values:a,positionals:r}=Vy({args:t,options:s,strict:!0,allowPositionals:!0});return{flags:a,positionals:r}}catch(a){throw m(a instanceof Error?a.message.replace(/^.*?: /,""):String(a),`palbase help ${e.name}`)}}function Yy(e,t,n,s){let a="error",r,i,o=1,l;return e instanceof y?(a=e.code,r=e.message,i=e.hint,o=e.exitCode):e instanceof x?(a=e.code,r=e.message,l=e.requestId):r=e instanceof Error?e.message:String(e),n&&e instanceof y&&e.reported||(n?t.stdout(`${JSON.stringify({error:a,message:r,...i?{hint:i}:{},...l?{request_id:l}:{}},null,2)}
14
14
  `):(t.stderr(`error: ${G(r)}${l?` (request ${G(l)})`:""}
15
15
  `),i&&t.stderr(` ${G(i)}
package/dist/refuse/ai.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
2
  throw new Error("palbase/ai is for servers: it speaks with the project secret key, which never goes into a browser or a mobile app \u2014 call your backend, and let it ask the model");
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
2
  throw new Error("palbase/backend is a server framework: it runs on your backend, never in a browser or a mobile app \u2014 apps use palbase/web (or the native SDKs)");
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
2
  throw new Error("palbase/server is for servers: its secret key never goes into a browser or a mobile app \u2014 apps use palbase/web (or the native SDKs) with the publishable key");
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
2
- import{a as e,b as f,c as g,d as h,e as i,f as j,g as k,h as l,i as m,j as n,k as o,l as p,m as q,n as r,o as s,p as t,q as u,r as v,s as w,t as x,u as y}from"../chunks/VXT46THA.js";import{a as c,b as d}from"../chunks/Y6NZV7LU.js";import"../chunks/LAHIVWPV.js";import"../chunks/B2IIU37G.js";import{m as b}from"../chunks/CYLNEHKQ.js";import"../chunks/DWRLUP7O.js";import{b as a}from"../chunks/3Y4K6F6T.js";import"../chunks/KBDCHYSD.js";import"../chunks/3UVLEWTM.js";export{o as AuthUnavailable,b as EVENT_TYPES,c as FieldError,d as Fields,a as PalbaseError,t as ReservationSettled,n as TokenError,q as TokenVerifier,f as Transit,e as TransitRefusal,g as TransitRequest,i as WebhookSignatureError,h as createServer,s as isEntitled,y as loadSecrets,v as pages,x as platformOwn,w as processOwn,r as requestAddress,p as sessionStanding,l as signatureHeader,k as verifySignature,j as verifyWebhook,m as verifyWebhookRequest,u as withReservation};
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
+ import{a as e,b as f,c as g,d as h,e as i,f as j,g as k,h as l,i as m,j as n,k as o,l as p,m as q,n as r,o as s,p as t,q as u,r as v,s as w,t as x,u as y}from"../chunks/ART5HP5M.js";import{a as c,b as d}from"../chunks/4HFD24QY.js";import"../chunks/7R4WTDHI.js";import"../chunks/7QFBZLAK.js";import{n as b}from"../chunks/ZXV3ZKVM.js";import"../chunks/FT7G3QQ4.js";import{b as a}from"../chunks/VQXYHAU4.js";import"../chunks/6IMY2J5W.js";import"../chunks/T2O6XEQO.js";export{o as AuthUnavailable,b as EVENT_TYPES,c as FieldError,d as Fields,a as PalbaseError,t as ReservationSettled,n as TokenError,q as TokenVerifier,f as Transit,e as TransitRefusal,g as TransitRequest,i as WebhookSignatureError,h as createServer,s as isEntitled,y as loadSecrets,v as pages,x as platformOwn,w as processOwn,r as requestAddress,p as sessionStanding,l as signatureHeader,k as verifySignature,j as verifyWebhook,m as verifyWebhookRequest,u as withReservation};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
2
- import{a,b,c,d,e}from"../chunks/22M4UQVQ.js";import"../chunks/Y6NZV7LU.js";import"../chunks/KBDCHYSD.js";import"../chunks/3UVLEWTM.js";export{b as TestApiError,e as api,c as createTestApi,a as testFields,d as testRun};
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
+ import{a,b,c,d,e}from"../chunks/BKGX3AZA.js";import"../chunks/4HFD24QY.js";import"../chunks/6IMY2J5W.js";import"../chunks/T2O6XEQO.js";export{b as TestApiError,e as api,c as createTestApi,a as testFields,d as testRun};
package/dist/web/index.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
2
- import{a as M,b as j,c as q,d as G,e as N,f as U,g as D,h as H,i as J,j as B,k as F,l as K,m as W,n as X,o as Y,p as Z,q as ee}from"../chunks/LIKE2KDM.js";import{a as _,b as Q,f as z}from"../chunks/FWX3RGVS.js";import"../chunks/7C7HACEZ.js";import"../chunks/E27BZ5SM.js";import"../chunks/R7PRW7FG.js";import{b as E,c as T,d as x,f as O,g as A,j as R,k as $,l as V,m as v,o as S}from"../chunks/LAHIVWPV.js";import"../chunks/LR5ONXTF.js";import"../chunks/CYLNEHKQ.js";import"../chunks/DWRLUP7O.js";import{b as L}from"../chunks/3Y4K6F6T.js";import"../chunks/KBDCHYSD.js";import"../chunks/3UVLEWTM.js";var te="oai-events";async function ne(e){if(typeof e?.start!="function")throw new TypeError("connectVoice: start(sdp) is the round trip to the app's backend, which starts the voice (chats.voice.start) and answers { id, sdp }");let r=e.rtc??se(),t=e.signal;t?.throwIfAborted();let f=e.audio??ae(),l=e.microphone===void 0,c=e.microphone??await r.getUserMedia({audio:!0});if(t?.aborted){if(l)for(let n of c.getTracks())n.stop();throw t.reason}let o=new r.RTCPeerConnection,s=!1,u=()=>{if(!s){if(s=!0,m.close(),o.close(),l)for(let n of c.getTracks())n.stop();f.srcObject!==null&&(f.srcObject=null)}};o.addEventListener("track",n=>{f.srcObject=n.streams[0]??new MediaStream([n.track]),f.play?.()?.catch?.(()=>{})}),o.addEventListener("connectionstatechange",()=>e.onState?.(o.connectionState));for(let n of c.getAudioTracks())o.addTrack(n,c);let m=o.createDataChannel(te);m.addEventListener("message",n=>{let p=oe(n.data);p!==void 0&&e.onError?.(p)});let d=()=>u();t?.addEventListener("abort",d,{once:!0});try{await o.setLocalDescription(await o.createOffer()),t?.throwIfAborted(),await re(o,e.iceTimeoutMs??1e4,t);let n=o.localDescription?.sdp;if(!n)throw new Error("connectVoice: the peer connection made no offer");let p=await e.start(n);if(t?.throwIfAborted(),typeof p?.id!="string"||p.id===""||typeof p.sdp!="string"||p.sdp==="")throw new TypeError("connectVoice: start answered no voice \u2014 it is { id, sdp }, chats.voice.start's answer as the backend got it");return await o.setRemoteDescription({type:"answer",sdp:p.sdp}),t?.removeEventListener("abort",d),{id:p.id,peer:o,audio:f,microphone:c,get muted(){return c.getAudioTracks().every(h=>!h.enabled)},mute(h){for(let w of c.getAudioTracks())w.enabled=!h},close:u}}catch(n){throw t?.removeEventListener("abort",d),u(),t?.aborted?t.reason:n}}function re(e,r,t){return e.iceGatheringState==="complete"?Promise.resolve():t?.aborted?Promise.reject(t.reason):new Promise((f,l)=>{let c=()=>{clearTimeout(u),e.removeEventListener("icegatheringstatechange",o),t?.removeEventListener("abort",s)},o=()=>{e.iceGatheringState==="complete"&&(c(),f())},s=()=>{c(),l(t?.reason)},u=setTimeout(()=>{c(),l(new Error(`connectVoice: the network candidates were not gathered in ${r} ms`))},r);e.addEventListener("icegatheringstatechange",o),t?.addEventListener("abort",s,{once:!0})})}function oe(e){if(typeof e=="string")try{let r=JSON.parse(e);return r.type!=="error"?void 0:typeof r.error?.message=="string"?r.error.message:typeof r.error?.code=="string"?r.error.code:"the voice failed"}catch{return}}function se(){let e=globalThis;if(typeof e.RTCPeerConnection!="function"||typeof e.navigator?.mediaDevices?.getUserMedia!="function")throw new TypeError("connectVoice: this runtime has no WebRTC (RTCPeerConnection, navigator.mediaDevices): a chat's voice is a browser's");let r=e.navigator.mediaDevices;return{RTCPeerConnection:e.RTCPeerConnection,getUserMedia:t=>r.getUserMedia(t)}}function ae(){let e=globalThis.document;if(!e)throw new TypeError("connectVoice: give audio \u2014 the element the voice plays in \u2014 where there is no document");let r=e.createElement("audio");return r.autoplay=!0,r}var i=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0;function ie(e,r,t){let f=i(i(i(e)?.components)?.schemas)??{},l=(d,n)=>{let p=new Set,h=(C,g,y)=>{let a=i(C);if(!a)return;if(typeof a.$ref=="string"){if(y.has(a.$ref)||!a.$ref.startsWith("#/components/schemas/"))return;h(f[a.$ref.slice(21)],g,new Set(y).add(a.$ref));return}if(a[E]===!0){p.add(g);return}for(let b of["anyOf","oneOf","allOf"]){let k=a[b];if(Array.isArray(k))for(let I of k)h(I,g,y)}let P=i(a.properties);if(P)for(let[b,k]of Object.entries(P))h(k,`${g}/${v(b)}`,y);i(a.items)&&h(a.items,`${g}/*`,y);for(let b of["additionalProperties","patternProperties","prefixItems"])if(a[b]!==void 0&&w(a[b],new Set(y)))throw new Error(`${t}: an encrypted field is a named property \u2014 not every key of a record, nor a tuple's place`)},w=(C,g)=>{if(Array.isArray(C))return C.some(a=>w(a,g));let y=i(C);return y?y[E]===!0?!0:typeof y.$ref=="string"&&!g.has(y.$ref)&&y.$ref.startsWith("#/components/schemas/")?(g.add(y.$ref),w(f[y.$ref.slice(21)],g)):Object.values(y).some(a=>typeof a=="object"&&a!==null&&w(a,g)):!1};return h(d,n,new Set),[...p]},c=d=>i(i(i(d)?.["application/json"])?.schema),o=[];o.push(...l(c(i(r.requestBody)?.content),"/body"));for(let d of Array.isArray(r.parameters)?r.parameters:[]){let n=i(d);if(!n)continue;let p=l(n.schema,`/query/${v(String(n.name))}`);if(p.length!==0){if(n.in!=="query")throw new Error(`${t}: ${String(n.in)} parameter ${String(n.name)} is marked encrypted \u2014 a body's or a query's field is`);if(p.some(h=>h.split("/").length!==3))throw new Error(`${t}: an encrypted query field is one of the query's own names`);o.push(...p)}}let s=i(r.responses)??{},u=Object.keys(s).filter(d=>/^2\d\d$/.test(d)).sort((d,n)=>d==="200"?-1:n==="200"?1:d.localeCompare(n)),m=u.length>0?l(c(i(s[u[0]])?.content),"/response"):[];if(o.length+m.length!==0){if(r["x-palbase-sse"]!==void 0&&m.length>0)throw new Error(`${t}: a streamed answer carries no encrypted field`);if(r["x-palbase-upload"]!==void 0)throw new Error(`${t}: an upload goes through storage, which seals nothing \u2014 it carries no encrypted field`);return{request:o,response:m}}}async function ce(e){let r=`${e.method.toUpperCase()} ${e.path}`,t=i(i(i(i(e.contract)?.paths)?.[e.path])?.[e.method.toLowerCase()]),f=t?ie(e.contract,t,r):void 0;if(!f)return{body:e.body,query:e.query,open:async s=>s};let{key:l,header:c}=await A(e.key.kid,x(e.key.publicKey),O(e.projectId,e.method,e.path,e.params??[])),o=(s,u)=>s==null?s:S(s,u,f.request,(m,d)=>R(l,m,d));return{header:c,body:await o(e.body,"/body"),query:await o(e.query,"/query"),open:s=>s===void 0?Promise.resolve(s):S(s,"/response",f.response,async(u,m)=>{if(!$(m))throw new T("unopenable",`${r}: ${u} came plain where the contract says it is encrypted`);return V(l,u,m)})}}export{D as Analytics,_ as BackendError,G as Channel,H as Consent,Z as Flags,z as GatewayError,F as InApp,J as Inbox,U as Installation,W as Notify,L as PalbaseError,X as Purchases,N as RealtimeSocket,B as SESSION_START,M as SessionChangedError,K as WebPush,ne as connectVoice,ee as createClient,ce as encryptedCall,Q as isBackendError,q as localStore,j as memoryStore,Y as redemptionToken};
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
+ import{a as L,b as j,c as q,d as G,e as D,f as N,g as U,h as F,i as B,j as H,k as J,l as K,m as W,n as X,o as Y,p as Z,q as ee,r as te,s as ne,t as re,u as oe,v as se,w as ae}from"../chunks/EVBWED24.js";import{a as _,b as Q,f as z}from"../chunks/OC32TP3L.js";import"../chunks/CAZYHE64.js";import"../chunks/PPK2UEAY.js";import"../chunks/XF3JEDIQ.js";import{b as E,c as T,d as O,f as x,g as A,j as R,k as V,l as $,m as S,o as v}from"../chunks/7R4WTDHI.js";import"../chunks/XHNZDLR4.js";import"../chunks/ZXV3ZKVM.js";import"../chunks/FT7G3QQ4.js";import{b as I}from"../chunks/VQXYHAU4.js";import"../chunks/6IMY2J5W.js";import"../chunks/T2O6XEQO.js";var ie="oai-events";async function ce(e){if(typeof e?.start!="function")throw new TypeError("connectVoice: start(sdp) is the round trip to the app's backend, which starts the voice (chats.voice.start) and answers { id, sdp }");let r=e.rtc??ye(),t=e.signal;t?.throwIfAborted();let f=e.audio??fe(),u=e.microphone===void 0,c=e.microphone??await r.getUserMedia({audio:!0});if(t?.aborted){if(u)for(let n of c.getTracks())n.stop();throw t.reason}let o=new r.RTCPeerConnection,s=!1,l=()=>{if(!s){if(s=!0,m.close(),o.close(),u)for(let n of c.getTracks())n.stop();f.srcObject!==null&&(f.srcObject=null)}};o.addEventListener("track",n=>{f.srcObject=n.streams[0]??new MediaStream([n.track]),f.play?.()?.catch?.(()=>{})}),o.addEventListener("connectionstatechange",()=>e.onState?.(o.connectionState));for(let n of c.getAudioTracks())o.addTrack(n,c);let m=o.createDataChannel(ie);m.addEventListener("message",n=>{let p=pe(n.data);p!==void 0&&e.onError?.(p)});let d=()=>l();t?.addEventListener("abort",d,{once:!0});try{await o.setLocalDescription(await o.createOffer()),t?.throwIfAborted(),await de(o,e.iceTimeoutMs??1e4,t);let n=o.localDescription?.sdp;if(!n)throw new Error("connectVoice: the peer connection made no offer");let p=await e.start(n);if(t?.throwIfAborted(),typeof p?.id!="string"||p.id===""||typeof p.sdp!="string"||p.sdp==="")throw new TypeError("connectVoice: start answered no voice \u2014 it is { id, sdp }, chats.voice.start's answer as the backend got it");return await o.setRemoteDescription({type:"answer",sdp:p.sdp}),t?.removeEventListener("abort",d),{id:p.id,peer:o,audio:f,microphone:c,get muted(){return c.getAudioTracks().every(h=>!h.enabled)},mute(h){for(let w of c.getAudioTracks())w.enabled=!h},close:l}}catch(n){throw t?.removeEventListener("abort",d),l(),t?.aborted?t.reason:n}}function de(e,r,t){return e.iceGatheringState==="complete"?Promise.resolve():t?.aborted?Promise.reject(t.reason):new Promise((f,u)=>{let c=()=>{clearTimeout(l),e.removeEventListener("icegatheringstatechange",o),t?.removeEventListener("abort",s)},o=()=>{e.iceGatheringState==="complete"&&(c(),f())},s=()=>{c(),u(t?.reason)},l=setTimeout(()=>{c(),u(new Error(`connectVoice: the network candidates were not gathered in ${r} ms`))},r);e.addEventListener("icegatheringstatechange",o),t?.addEventListener("abort",s,{once:!0})})}function pe(e){if(typeof e=="string")try{let r=JSON.parse(e);return r.type!=="error"?void 0:typeof r.error?.message=="string"?r.error.message:typeof r.error?.code=="string"?r.error.code:"the voice failed"}catch{return}}function ye(){let e=globalThis;if(typeof e.RTCPeerConnection!="function"||typeof e.navigator?.mediaDevices?.getUserMedia!="function")throw new TypeError("connectVoice: this runtime has no WebRTC (RTCPeerConnection, navigator.mediaDevices): a chat's voice is a browser's");let r=e.navigator.mediaDevices;return{RTCPeerConnection:e.RTCPeerConnection,getUserMedia:t=>r.getUserMedia(t)}}function fe(){let e=globalThis.document;if(!e)throw new TypeError("connectVoice: give audio \u2014 the element the voice plays in \u2014 where there is no document");let r=e.createElement("audio");return r.autoplay=!0,r}var i=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0;function le(e,r,t){let f=i(i(i(e)?.components)?.schemas)??{},u=(d,n)=>{let p=new Set,h=(C,g,y)=>{let a=i(C);if(!a)return;if(typeof a.$ref=="string"){if(y.has(a.$ref)||!a.$ref.startsWith("#/components/schemas/"))return;h(f[a.$ref.slice(21)],g,new Set(y).add(a.$ref));return}if(a[E]===!0){p.add(g);return}for(let b of["anyOf","oneOf","allOf"]){let k=a[b];if(Array.isArray(k))for(let M of k)h(M,g,y)}let P=i(a.properties);if(P)for(let[b,k]of Object.entries(P))h(k,`${g}/${S(b)}`,y);i(a.items)&&h(a.items,`${g}/*`,y);for(let b of["additionalProperties","patternProperties","prefixItems"])if(a[b]!==void 0&&w(a[b],new Set(y)))throw new Error(`${t}: an encrypted field is a named property \u2014 not every key of a record, nor a tuple's place`)},w=(C,g)=>{if(Array.isArray(C))return C.some(a=>w(a,g));let y=i(C);return y?y[E]===!0?!0:typeof y.$ref=="string"&&!g.has(y.$ref)&&y.$ref.startsWith("#/components/schemas/")?(g.add(y.$ref),w(f[y.$ref.slice(21)],g)):Object.values(y).some(a=>typeof a=="object"&&a!==null&&w(a,g)):!1};return h(d,n,new Set),[...p]},c=d=>i(i(i(d)?.["application/json"])?.schema),o=[];o.push(...u(c(i(r.requestBody)?.content),"/body"));for(let d of Array.isArray(r.parameters)?r.parameters:[]){let n=i(d);if(!n)continue;let p=u(n.schema,`/query/${S(String(n.name))}`);if(p.length!==0){if(n.in!=="query")throw new Error(`${t}: ${String(n.in)} parameter ${String(n.name)} is marked encrypted \u2014 a body's or a query's field is`);if(p.some(h=>h.split("/").length!==3))throw new Error(`${t}: an encrypted query field is one of the query's own names`);o.push(...p)}}let s=i(r.responses)??{},l=Object.keys(s).filter(d=>/^2\d\d$/.test(d)).sort((d,n)=>d==="200"?-1:n==="200"?1:d.localeCompare(n)),m=l.length>0?u(c(i(s[l[0]])?.content),"/response"):[];if(o.length+m.length!==0){if(r["x-palbase-sse"]!==void 0&&m.length>0)throw new Error(`${t}: a streamed answer carries no encrypted field`);if(r["x-palbase-upload"]!==void 0)throw new Error(`${t}: an upload goes through storage, which seals nothing \u2014 it carries no encrypted field`);return{request:o,response:m}}}async function ue(e){let r=`${e.method.toUpperCase()} ${e.path}`,t=i(i(i(i(e.contract)?.paths)?.[e.path])?.[e.method.toLowerCase()]),f=t?le(e.contract,t,r):void 0;if(!f)return{body:e.body,query:e.query,open:async s=>s};let{key:u,header:c}=await A(e.key.kid,O(e.key.publicKey),x(e.projectId,e.method,e.path,e.params??[])),o=(s,l)=>s==null?s:v(s,l,f.request,(m,d)=>R(u,m,d));return{header:c,body:await o(e.body,"/body"),query:await o(e.query,"/query"),open:s=>s===void 0?Promise.resolve(s):v(s,"/response",f.response,async(l,m)=>{if(!V(m))throw new T("unopenable",`${r}: ${l} came plain where the contract says it is encrypted`);return $(u,l,m)})}}export{U as Analytics,_ as BackendError,G as Channel,F as Consent,ne as ConversationList,re as ConversationView,Z as Flags,z as GatewayError,J as InApp,B as Inbox,N as Installation,te as Messaging,W as Notify,I as PalbaseError,X as Purchases,D as RealtimeSocket,H as SESSION_START,se as ScheduledList,L as SessionChangedError,oe as ThreadView,K as WebPush,ce as connectVoice,ae as createClient,ue as encryptedCall,ee as indexedDBKeyValue,Q as isBackendError,q as localStore,j as memoryStore,Y as redemptionToken};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
2
- import{a as i}from"../chunks/E27BZ5SM.js";import{a as e,b as s,c as t,d as p,e as o,f as a,h as r,j as n,k as y,p as M,q as l,t as g}from"../chunks/R7PRW7FG.js";import"../chunks/3UVLEWTM.js";export{n as MESSAGE_COMPONENTS,a as MESSAGE_ICONS,r as MESSAGE_SCHEMA,s as assetId,y as countdownValues,e as fontFamily,o as htmlDocument,t as prepareAssets,i as presentMessage,g as renderMessage,M as resolveMessage,l as resolveMessageWithPaths,p as unzip};
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
+ import{a as i}from"../chunks/PPK2UEAY.js";import{a as e,b as s,c as t,d as p,e as o,f as a,h as r,j as n,k as y,p as M,q as l,t as g}from"../chunks/XF3JEDIQ.js";import"../chunks/T2O6XEQO.js";export{n as MESSAGE_COMPONENTS,a as MESSAGE_ICONS,r as MESSAGE_SCHEMA,s as assetId,y as countdownValues,e as fontFamily,o as htmlDocument,t as prepareAssets,i as presentMessage,g as renderMessage,M as resolveMessage,l as resolveMessageWithPaths,p as unzip};
package/dist/web/palbe.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
2
- import{c as e,d as r,i as t}from"../chunks/FWX3RGVS.js";import"../chunks/LAHIVWPV.js";import"../chunks/LR5ONXTF.js";import"../chunks/DWRLUP7O.js";import"../chunks/3Y4K6F6T.js";import"../chunks/KBDCHYSD.js";import"../chunks/3UVLEWTM.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
+ import{c as e,d as r,i as t}from"../chunks/OC32TP3L.js";import"../chunks/7R4WTDHI.js";import"../chunks/XHNZDLR4.js";import"../chunks/FT7G3QQ4.js";import"../chunks/VQXYHAU4.js";import"../chunks/6IMY2J5W.js";import"../chunks/T2O6XEQO.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
2
- import{a as f,b as d,c as m,d as u,e as A,f as c,g as R}from"../chunks/7C7HACEZ.js";import{a as e,b as a,c as t,d as l,e as r,f as o,g as p,i as y,k as s,l as P,n,o as i,s as w}from"../chunks/R7PRW7FG.js";import"../chunks/3Y4K6F6T.js";import"../chunks/KBDCHYSD.js";import"../chunks/3UVLEWTM.js";export{y as PAYWALL_COMPONENTS,o as PAYWALL_ICONS,p as PAYWALL_SCHEMA,c as Paywall,a as assetId,f as attributesHeader,s as countdownValues,R as defaultPaywall,e as fontFamily,u as formatPeriod,m as formatPrice,r as htmlDocument,A as packageValues,P as packagesOf,d as parseDuration,t as prepareAssets,w as renderPaywall,n as resolvePaywall,i as resolvePaywallWithPaths,l as unzip};
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
+ import{a as f,b as d,c as m,d as u,e as A,f as c,g as R}from"../chunks/CAZYHE64.js";import{a as e,b as a,c as t,d as l,e as r,f as o,g as p,i as y,k as s,l as P,n,o as i,s as w}from"../chunks/XF3JEDIQ.js";import"../chunks/VQXYHAU4.js";import"../chunks/6IMY2J5W.js";import"../chunks/T2O6XEQO.js";export{y as PAYWALL_COMPONENTS,o as PAYWALL_ICONS,p as PAYWALL_SCHEMA,c as Paywall,a as assetId,f as attributesHeader,s as countdownValues,R as defaultPaywall,e as fontFamily,u as formatPeriod,m as formatPrice,r as htmlDocument,A as packageValues,P as packagesOf,d as parseDuration,t as prepareAssets,w as renderPaywall,n as resolvePaywall,i as resolvePaywallWithPaths,l as unzip};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
2
  "use strict";(()=>{function g(n,s){if(n)try{let i=new URL(n,s);if(i.protocol==="https:"||i.protocol==="http:"&&(i.hostname==="localhost"||i.hostname==="127.0.0.1"))return i.href}catch{}}function p(n){let s=new URL(n.location.href).searchParams,i=s.get("url")??"",u=s.get("key")??"",a=(t,e)=>!t||!i?Promise.resolve():n.fetch(`${i.replace(/\/$/,"")}/notify/receipts`,{method:"POST",headers:{"content-type":"application/json",apikey:u},body:JSON.stringify({receipts:[{receipt:t,status:e}]}),keepalive:!0}).catch(()=>{}),l=async(t,e)=>{for(let o of await n.clients.matchAll({type:"window",includeUncontrolled:!0}))o.postMessage({type:"palbase.push",event:t,url:e.url,data:e.data})};n.addEventListener("push",(t=>{let e={};try{e=t.data?.json()??{}}catch{}let o={url:e.url,receipt:e.receipt,data:e.data},d=async()=>e.data?.type==="messaging.message"&&(await n.clients.matchAll({type:"window",includeUncontrolled:!0})).some(r=>r.focused===!0);t.waitUntil(d().then(r=>r?void 0:n.registration.showNotification(e.title??"",{body:e.body,image:e.image,tag:e.tag,data:o})).then(()=>Promise.all([a(e.receipt,"delivered"),l("received",o)])))})),n.addEventListener("notificationclick",(t=>{t.notification.close();let e=t.notification.data??{},o=g(e.url,n.location.origin),d=async()=>{if(!o)return;let c=(await n.clients.matchAll({type:"window",includeUncontrolled:!0})).find(f=>f.url===o);c?await c.focus():await n.clients.openWindow(o)};t.waitUntil(Promise.all([a(e.receipt,"opened"),d(),l("opened",e)]))})),n.addEventListener("notificationclose",(t=>{t.waitUntil(a(t.notification.data?.receipt,"dismissed"))}))}typeof self<"u"&&typeof self.registration=="object"&&!("document"in self)&&p(self);})();
package/dist/web/ssr.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
2
- import{q as f}from"../chunks/LIKE2KDM.js";import"../chunks/FWX3RGVS.js";import"../chunks/7C7HACEZ.js";import"../chunks/E27BZ5SM.js";import"../chunks/R7PRW7FG.js";import"../chunks/LAHIVWPV.js";import"../chunks/LR5ONXTF.js";import"../chunks/CYLNEHKQ.js";import"../chunks/DWRLUP7O.js";import"../chunks/3Y4K6F6T.js";import"../chunks/KBDCHYSD.js";import"../chunks/3UVLEWTM.js";var C=Object.freeze({"Cache-Control":"private, no-cache, no-store, must-revalidate, max-age=0",Expires:"0",Pragma:"no-cache"}),x={path:"/",sameSite:"lax",secure:!0,httpOnly:!1,maxAge:400*24*60*60},u=3180,k=5*6e4;function d(t){let e=/^pb_([a-z0-9]+)_c/.exec(t)?.[1];if(e===void 0)throw new TypeError("publishableKey is the project publishable key (pb_<ref>_c\u2026)");return`pb-${e}-session`}var y=t=>{let e=new TextEncoder().encode(JSON.stringify(t)),o="";for(let s of e)o+=String.fromCharCode(s);return btoa(o).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},b=t=>{try{let e=atob(t.replace(/-/g,"+").replace(/_/g,"/")),o=JSON.parse(new TextDecoder().decode(Uint8Array.from(e,s=>s.charCodeAt(0))));return typeof o.accessToken!="string"||typeof o.refreshToken!="string"||typeof o.expiresAt!="number"||typeof o.userId!="string"?null:o}catch{return null}};function m(t,e,o={},s=!1){let c={...x,...o},g=async()=>new Map((await e.getAll()).map(n=>[n.name,n.value])),S=n=>n===t||n.startsWith(`${t}.`)&&/^\d+$/.test(n.slice(t.length+1)),h=async n=>{if(!e.setAll)return;let i=n===null?[]:n.length<=u?[[t,n]]:Array.from({length:Math.ceil(n.length/u)},(r,l)=>[`${t}.${l}`,n.slice(l*u,(l+1)*u)]),p=new Set(i.map(([r])=>r)),a=i.map(([r,l])=>({name:r,value:l,options:c}));for(let r of(await g()).keys())S(r)&&!p.has(r)&&a.push({name:r,value:"",options:{...c,maxAge:0}});a.length>0&&await e.setAll(a,{...C})};return{async load(){let n=await g(),i=n.get(t);if(i===void 0){let p="";for(let a=0;n.has(`${t}.${a}`);a++)p+=n.get(`${t}.${a}`);i=p}return i?b(i):null},save:n=>h(y(n)),clear:()=>h(null),shared:s}}function A(t){let{cookies:e,cookieOptions:o,...s}=t,c=t.refresh??(e.setAll?"before":"never");return f({...s,refresh:c,storage:m(d(t.publishableKey),e,o)})}function O(){let t=()=>{let e=globalThis.document;if(!e)throw new Error("documentCookies: there is no document here \u2014 a server gives its request's cookies to createServerClient");return e};return{getAll:()=>t().cookie.split(";").map(e=>e.trim()).filter(e=>e.includes("=")).map(e=>{let o=e.indexOf("=");return{name:e.slice(0,o),value:e.slice(o+1)}}),setAll(e){for(let o of e){let s=o.options,c=[`Path=${s.path??"/"}`,s.domain?`Domain=${s.domain}`:"",s.maxAge!==void 0?`Max-Age=${s.maxAge}`:"",s.expires?`Expires=${s.expires.toUTCString()}`:"",s.sameSite?`SameSite=${s.sameSite.charAt(0).toUpperCase()}${s.sameSite.slice(1)}`:"",s.secure?"Secure":""].filter(Boolean);t().cookie=[`${o.name}=${o.value}`,...c].join("; ")}}}}function $(t){let{cookieOptions:e,...o}=t,s=globalThis.location?.protocol==="https:";return f({...o,storage:m(d(t.publishableKey),O(),{secure:s,...e},!0)})}async function v(t){let e=await t.auth.currentSession();if(!e||(e.expiresAt-Date.now()<=k&&await t.auth.refreshSession().catch(()=>{}),!await t.auth.currentSession()))return null;try{return(await t.auth.api.verifyTokenUser()).data}catch(o){if(o.status===401)return null;throw o}}export{C as NO_STORE_HEADERS,x as SESSION_COOKIE_OPTIONS,m as cookieSessionStore,$ as createBrowserClient,A as createServerClient,O as documentCookies,v as keepSession,d as sessionCookieName};
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
+ import{w as f}from"../chunks/EVBWED24.js";import"../chunks/OC32TP3L.js";import"../chunks/CAZYHE64.js";import"../chunks/PPK2UEAY.js";import"../chunks/XF3JEDIQ.js";import"../chunks/7R4WTDHI.js";import"../chunks/XHNZDLR4.js";import"../chunks/ZXV3ZKVM.js";import"../chunks/FT7G3QQ4.js";import"../chunks/VQXYHAU4.js";import"../chunks/6IMY2J5W.js";import"../chunks/T2O6XEQO.js";var C=Object.freeze({"Cache-Control":"private, no-cache, no-store, must-revalidate, max-age=0",Expires:"0",Pragma:"no-cache"}),x={path:"/",sameSite:"lax",secure:!0,httpOnly:!1,maxAge:400*24*60*60},u=3180,k=5*6e4;function d(t){let e=/^pb_([a-z0-9]+)_c/.exec(t)?.[1];if(e===void 0)throw new TypeError("publishableKey is the project publishable key (pb_<ref>_c\u2026)");return`pb-${e}-session`}var y=t=>{let e=new TextEncoder().encode(JSON.stringify(t)),o="";for(let s of e)o+=String.fromCharCode(s);return btoa(o).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},b=t=>{try{let e=atob(t.replace(/-/g,"+").replace(/_/g,"/")),o=JSON.parse(new TextDecoder().decode(Uint8Array.from(e,s=>s.charCodeAt(0))));return typeof o.accessToken!="string"||typeof o.refreshToken!="string"||typeof o.expiresAt!="number"||typeof o.userId!="string"?null:o}catch{return null}};function m(t,e,o={},s=!1){let c={...x,...o},g=async()=>new Map((await e.getAll()).map(n=>[n.name,n.value])),S=n=>n===t||n.startsWith(`${t}.`)&&/^\d+$/.test(n.slice(t.length+1)),h=async n=>{if(!e.setAll)return;let i=n===null?[]:n.length<=u?[[t,n]]:Array.from({length:Math.ceil(n.length/u)},(r,l)=>[`${t}.${l}`,n.slice(l*u,(l+1)*u)]),p=new Set(i.map(([r])=>r)),a=i.map(([r,l])=>({name:r,value:l,options:c}));for(let r of(await g()).keys())S(r)&&!p.has(r)&&a.push({name:r,value:"",options:{...c,maxAge:0}});a.length>0&&await e.setAll(a,{...C})};return{async load(){let n=await g(),i=n.get(t);if(i===void 0){let p="";for(let a=0;n.has(`${t}.${a}`);a++)p+=n.get(`${t}.${a}`);i=p}return i?b(i):null},save:n=>h(y(n)),clear:()=>h(null),shared:s}}function A(t){let{cookies:e,cookieOptions:o,...s}=t,c=t.refresh??(e.setAll?"before":"never");return f({...s,refresh:c,storage:m(d(t.publishableKey),e,o)})}function O(){let t=()=>{let e=globalThis.document;if(!e)throw new Error("documentCookies: there is no document here \u2014 a server gives its request's cookies to createServerClient");return e};return{getAll:()=>t().cookie.split(";").map(e=>e.trim()).filter(e=>e.includes("=")).map(e=>{let o=e.indexOf("=");return{name:e.slice(0,o),value:e.slice(o+1)}}),setAll(e){for(let o of e){let s=o.options,c=[`Path=${s.path??"/"}`,s.domain?`Domain=${s.domain}`:"",s.maxAge!==void 0?`Max-Age=${s.maxAge}`:"",s.expires?`Expires=${s.expires.toUTCString()}`:"",s.sameSite?`SameSite=${s.sameSite.charAt(0).toUpperCase()}${s.sameSite.slice(1)}`:"",s.secure?"Secure":""].filter(Boolean);t().cookie=[`${o.name}=${o.value}`,...c].join("; ")}}}}function $(t){let{cookieOptions:e,...o}=t,s=globalThis.location?.protocol==="https:";return f({...o,storage:m(d(t.publishableKey),O(),{secure:s,...e},!0)})}async function v(t){let e=await t.auth.currentSession();if(!e||(e.expiresAt-Date.now()<=k&&await t.auth.refreshSession().catch(()=>{}),!await t.auth.currentSession()))return null;try{return(await t.auth.api.verifyTokenUser()).data}catch(o){if(o.status===401)return null;throw o}}export{C as NO_STORE_HEADERS,x as SESSION_COOKIE_OPTIONS,m as cookieSessionStore,$ as createBrowserClient,A as createServerClient,O as documentCookies,v as keepSession,d as sessionCookieName};
package/dist/web/vite.js CHANGED
@@ -1,3 +1,3 @@
1
- /*! palbase 0.17.1 — Palbase SDK License (see LICENSE) */
2
- import"../chunks/3UVLEWTM.js";import{execFile as $}from"node:child_process";import{existsSync as y,mkdtempSync as k,readFileSync as S,rmSync as x,writeFileSync as P}from"node:fs";import{createRequire as O}from"node:module";import{tmpdir as W}from"node:os";import{dirname as g,join as o,relative as u,resolve as v,sep as d}from"node:path";var E=/\.(?:ts|js|mts|mjs)$/;function F(n){if(!/^[a-z][a-z0-9-]*$/.test(n.app))throw new TypeError(`palbase({ app }): ${JSON.stringify(n.app)} is an app's slug (palbase apps:list)`);let c=process.cwd(),p="",i="",f=()=>v(c,n.dir??"palbase"),m=()=>{let e=n.environments[p];if(!e)throw new Error(`palbase: the mode "${p}" is not built against any environment \u2014 say which in vite.config: palbase({ environments: { ${JSON.stringify(p)}: '<environment slug>' } })`);return e};return{name:"palbase",enforce:"pre",config(e,s){p=s.mode,i=s.command??"";let r=e.build?.rollupOptions?.onwarn;return{build:{rollupOptions:{onwarn(t,a){let l=String(t.exporter??t.id??"");if(t.code==="MISSING_EXPORT"&&l.includes(`${d}environments${d}`))throw new Error(`palbase: ${t.message} \u2014 ${m()}'s backend has no such route (palbase apps:sync brings what it has)`);r?r(t,a):a(t)}}}}},configResolved(e){c=e.root,p=e.mode,i=e.command??i},async buildStart(){i!=="build"||n.typecheck===!1||await j(c,m(),n.tsconfig)},resolveId(e,s){if(!s)return null;let r=f();if(e==="palbase"||e.startsWith("palbase/")){let w=u(r,s);return w.startsWith("..")||w===""?null:this.resolve(e,o(c,"index.html"),{skipSelf:!0})}if(!(e.startsWith(".")||e.startsWith("/")))return null;let t=v(g(s),e);if(E.test(t)||(t+=".ts"),g(t)!==r&&g(t)!==o(r,"palbe"))return null;let a=u(r,t),l=`${n.app}.ts`;if(a!==l&&!a.startsWith(`palbe${d}`))return null;let h=m(),b=o(r,"environments",h,a===l?l:o("palbe",a.slice(`palbe${d}`.length)));if(!y(b))throw new Error(`palbase: ${u(c,b)} is not there \u2014 palbase apps:sync writes it (is ${n.app} set in ${h}, and has ${h} that machine?)`);return b}}}async function j(n,c,p){let i=p?v(n,p):["tsconfig.app.json","tsconfig.json"].map(e=>o(n,e)).find(y);if(!i)return;if(!y(i))throw new Error(`palbase({ tsconfig }): ${u(n,i)} is not there`);let f;try{let e=O(o(n,"package.json")).resolve("typescript/package.json"),s=JSON.parse(S(e,"utf8")).bin?.tsc;if(!s)throw new Error("no tsc");f=o(g(e),s)}catch{throw new Error("palbase: the build type-checks the app against its environment with the app's TypeScript, and the app has none (npm i -D typescript) \u2014 or say palbase({ typecheck: false })")}let m=k(o(W(),"palbase-typecheck-"));try{let e=o(m,"tsconfig.json");P(e,JSON.stringify({extends:i,compilerOptions:{noEmit:!0,composite:!1,incremental:!1,moduleSuffixes:[`.${c}`,""]}}));let s=await new Promise(r=>$(process.execPath,[f,"-p",e,"--pretty","false"],{cwd:n,maxBuffer:16<<20},(t,a,l)=>r({code:t?typeof t.code=="number"?t.code:1:0,text:`${a}${l}`.trim()})));if(s.code!==0)throw new Error(`palbase: the app does not type-check against ${c}, the environment this build is made for \u2014 a route its backend does not have, or a call that does not fit it:
1
+ /*! palbase 0.18.0 — Palbase SDK License (see LICENSE) */
2
+ import"../chunks/T2O6XEQO.js";import{execFile as $}from"node:child_process";import{existsSync as y,mkdtempSync as k,readFileSync as S,rmSync as x,writeFileSync as P}from"node:fs";import{createRequire as O}from"node:module";import{tmpdir as W}from"node:os";import{dirname as g,join as o,relative as u,resolve as v,sep as d}from"node:path";var E=/\.(?:ts|js|mts|mjs)$/;function F(n){if(!/^[a-z][a-z0-9-]*$/.test(n.app))throw new TypeError(`palbase({ app }): ${JSON.stringify(n.app)} is an app's slug (palbase apps:list)`);let c=process.cwd(),p="",i="",f=()=>v(c,n.dir??"palbase"),m=()=>{let e=n.environments[p];if(!e)throw new Error(`palbase: the mode "${p}" is not built against any environment \u2014 say which in vite.config: palbase({ environments: { ${JSON.stringify(p)}: '<environment slug>' } })`);return e};return{name:"palbase",enforce:"pre",config(e,s){p=s.mode,i=s.command??"";let r=e.build?.rollupOptions?.onwarn;return{build:{rollupOptions:{onwarn(t,a){let l=String(t.exporter??t.id??"");if(t.code==="MISSING_EXPORT"&&l.includes(`${d}environments${d}`))throw new Error(`palbase: ${t.message} \u2014 ${m()}'s backend has no such route (palbase apps:sync brings what it has)`);r?r(t,a):a(t)}}}}},configResolved(e){c=e.root,p=e.mode,i=e.command??i},async buildStart(){i!=="build"||n.typecheck===!1||await j(c,m(),n.tsconfig)},resolveId(e,s){if(!s)return null;let r=f();if(e==="palbase"||e.startsWith("palbase/")){let w=u(r,s);return w.startsWith("..")||w===""?null:this.resolve(e,o(c,"index.html"),{skipSelf:!0})}if(!(e.startsWith(".")||e.startsWith("/")))return null;let t=v(g(s),e);if(E.test(t)||(t+=".ts"),g(t)!==r&&g(t)!==o(r,"palbe"))return null;let a=u(r,t),l=`${n.app}.ts`;if(a!==l&&!a.startsWith(`palbe${d}`))return null;let h=m(),b=o(r,"environments",h,a===l?l:o("palbe",a.slice(`palbe${d}`.length)));if(!y(b))throw new Error(`palbase: ${u(c,b)} is not there \u2014 palbase apps:sync writes it (is ${n.app} set in ${h}, and has ${h} that machine?)`);return b}}}async function j(n,c,p){let i=p?v(n,p):["tsconfig.app.json","tsconfig.json"].map(e=>o(n,e)).find(y);if(!i)return;if(!y(i))throw new Error(`palbase({ tsconfig }): ${u(n,i)} is not there`);let f;try{let e=O(o(n,"package.json")).resolve("typescript/package.json"),s=JSON.parse(S(e,"utf8")).bin?.tsc;if(!s)throw new Error("no tsc");f=o(g(e),s)}catch{throw new Error("palbase: the build type-checks the app against its environment with the app's TypeScript, and the app has none (npm i -D typescript) \u2014 or say palbase({ typecheck: false })")}let m=k(o(W(),"palbase-typecheck-"));try{let e=o(m,"tsconfig.json");P(e,JSON.stringify({extends:i,compilerOptions:{noEmit:!0,composite:!1,incremental:!1,moduleSuffixes:[`.${c}`,""]}}));let s=await new Promise(r=>$(process.execPath,[f,"-p",e,"--pretty","false"],{cwd:n,maxBuffer:16<<20},(t,a,l)=>r({code:t?typeof t.code=="number"?t.code:1:0,text:`${a}${l}`.trim()})));if(s.code!==0)throw new Error(`palbase: the app does not type-check against ${c}, the environment this build is made for \u2014 a route its backend does not have, or a call that does not fit it:
3
3
  ${s.text}`)}finally{x(m,{recursive:!0,force:!0})}}export{F as palbase};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "palbase",
3
- "version": "0.17.1",
3
+ "version": "0.18.0",
4
4
  "description": "Palbase for JavaScript: the web client (palbase/web), the server SDK (palbase/server), the backend framework (palbase/backend), AI (palbase/ai) and the CLI (npx palbase).",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://palbase.studio",
@@ -135,7 +135,7 @@
135
135
  "dependencies": {
136
136
  "@types/node": "26.6.4",
137
137
  "bun-types": "1.4.2",
138
- "palgres": "0.17.1",
138
+ "palgres": "0.18.0",
139
139
  "reflect-metadata": "^0.2.2",
140
140
  "typescript": "~6.0.3",
141
141
  "zod": "^4.6.5"
@@ -0,0 +1,31 @@
1
+ import type * as api from '../modules/messaging.js';
2
+ import type { Kept } from './local.js';
3
+ import { Outbox, type OutboxItem, type SendOutcome } from './outbox.js';
4
+ import { Store, type Changes, type Message, type Touched } from './store.js';
5
+ export type Entry = {
6
+ kind: 'message';
7
+ message: Message;
8
+ } | {
9
+ kind: 'pending';
10
+ item: OutboxItem;
11
+ };
12
+ export declare class Engine {
13
+ readonly store: Store;
14
+ readonly outbox: Outbox;
15
+ readonly me: string;
16
+ constructor(me: string);
17
+ apply(ch: Changes): Touched;
18
+ reset(ch: Changes): Touched;
19
+ private settled;
20
+ /** A message to send, on its way: drawn at once, sent by the next flush. */
21
+ write(conversationId: string, request: api.SendRequest, now: string): OutboxItem;
22
+ /** What the server made of a send, applied. */
23
+ sent(outcome: SendOutcome): Touched | null;
24
+ /** A conversation's timeline: its messages, the oldest first, then what is on its way to it. */
25
+ timeline(conversationId: string): Entry[];
26
+ /** A thread's answers, then what is on its way to it. */
27
+ answers(conversationId: string, rootId: string): Entry[];
28
+ private entries;
29
+ kept(): Kept;
30
+ load(k: Kept): void;
31
+ }
@@ -0,0 +1,11 @@
1
+ export declare function base64url(bytes: Uint8Array): string;
2
+ export declare function fromBase64url(s: string): Uint8Array;
3
+ /** Encrypts a file with a new key: its sealed bytes and the key, as an attachment's file_key. */
4
+ export declare function sealFile(plain: Uint8Array): Promise<{
5
+ sealed: Uint8Array;
6
+ fileKey: string;
7
+ }>;
8
+ /** sealFile with a given key and nonce: the vector's. */
9
+ export declare function sealWith(plain: Uint8Array, key: Uint8Array, nonce: Uint8Array): Promise<Uint8Array>;
10
+ /** Decrypts what sealFile sealed, with its file_key; throws when it does not open. */
11
+ export declare function openFile(sealed: Uint8Array, fileKey: string): Promise<Uint8Array>;
@@ -0,0 +1,5 @@
1
+ export * from './engine.js';
2
+ export * from './files.js';
3
+ export * from './local.js';
4
+ export * from './outbox.js';
5
+ export * from './store.js';
@@ -0,0 +1,31 @@
1
+ import type { OutboxItem } from './outbox.js';
2
+ import type { Snapshot } from './store.js';
3
+ /** Where a platform keeps it: IndexedDB in a browser, SQLite on a phone, memory in a test. */
4
+ export interface KeyValue {
5
+ get(key: string): Promise<string | null>;
6
+ set(key: string, value: string): Promise<void>;
7
+ delete(key: string): Promise<void>;
8
+ /** The keys it holds: what drops the copies of people no longer signed in. */
9
+ list(): Promise<string[]>;
10
+ }
11
+ export interface Kept {
12
+ store: Snapshot;
13
+ outbox: OutboxItem[];
14
+ }
15
+ /** The newest messages a conversation keeps on the device. */
16
+ export declare const keptPerConversation = 200;
17
+ /** The key of a person's: their project's ref and their id. */
18
+ export declare function scopeOf(ref: string, userId: string): string;
19
+ export declare class Local {
20
+ private readonly kv;
21
+ constructor(kv: KeyValue);
22
+ open(scope: string): Promise<Kept | null>;
23
+ save(scope: string, kept: Kept): Promise<void>;
24
+ drop(scope: string): Promise<void>;
25
+ /** Drops every other person's copy of the project's: the device keeps the one signed in alone. */
26
+ dropOthers(ref: string, userId: string): Promise<void>;
27
+ }
28
+ /** A KeyValue in memory: a test's, and a device's that keeps nothing. */
29
+ export declare function memoryKeyValue(): KeyValue & {
30
+ readonly keys: string[];
31
+ };
@@ -0,0 +1,53 @@
1
+ import type * as api from '../modules/messaging.js';
2
+ export type OutboxState = 'pending' | 'sending' | 'failed';
3
+ export interface OutboxItem {
4
+ clientMessageId: string;
5
+ conversationId: string;
6
+ request: api.SendRequest;
7
+ state: OutboxState;
8
+ attempts: number;
9
+ /** Why it failed: the module's code. */
10
+ error: string | null;
11
+ /** When it was written, ISO 8601: its place in its conversation. */
12
+ createdAt: string;
13
+ }
14
+ /** What the server made of a send. */
15
+ export type SendOutcome = {
16
+ kind: 'sent';
17
+ message: api.Message;
18
+ } | {
19
+ kind: 'scheduled';
20
+ scheduled: api.ScheduledMessage;
21
+ }
22
+ /** It will not take it by trying again (a refusal: 4xx but 408 and 429). */
23
+ | {
24
+ kind: 'refused';
25
+ code: string;
26
+ }
27
+ /** Not now: the network, a server that is busy or away. */
28
+ | {
29
+ kind: 'wait';
30
+ };
31
+ export declare class Outbox {
32
+ private readonly items;
33
+ add(conversationId: string, request: api.SendRequest, now: string): OutboxItem;
34
+ get(clientMessageId: string): OutboxItem | undefined;
35
+ /** The items, a conversation's in the order they were written. */
36
+ all(conversationId?: string): OutboxItem[];
37
+ /** A message of the reader's the server has (heard live, or synced): its item is done. */
38
+ settle(message: api.Message, me: string): boolean;
39
+ /** A failed item, to be tried again. */
40
+ retry(clientMessageId: string): void;
41
+ discard(clientMessageId: string): boolean;
42
+ /**
43
+ * Sends what waits, each conversation's in order, with send; done says each
44
+ * outcome (the caller applies a sent message to its store). Answers whether
45
+ * anything still waits.
46
+ */
47
+ flush(send: (item: OutboxItem) => Promise<SendOutcome>, done: (item: OutboxItem, outcome: SendOutcome) => void): Promise<boolean>;
48
+ /** What is saved with the store. */
49
+ save(): OutboxItem[];
50
+ load(items: OutboxItem[]): void;
51
+ }
52
+ /** What an answer of the server's to a send means for trying it again. */
53
+ export declare function outcomeOf(status: number, body: unknown): SendOutcome;
@@ -0,0 +1,67 @@
1
+ import type * as api from '../modules/messaging.js';
2
+ export type Conversation = api.Conversation;
3
+ export type Member = api.Member;
4
+ export type Message = api.Message;
5
+ export type ThreadState = api.ThreadState;
6
+ export type ScheduledMessage = api.ScheduledMessage;
7
+ /** What changed for the reader: a sync page's, or a live `changes` event's. */
8
+ export interface Changes {
9
+ conversations?: Conversation[];
10
+ members?: Member[];
11
+ messages?: Message[];
12
+ hidden?: api.HiddenMessage[];
13
+ threads?: ThreadState[];
14
+ scheduled?: ScheduledMessage[];
15
+ removed_conversations?: api.RemovedConversation[];
16
+ }
17
+ /** What the store keeps, as it is saved and loaded whole. */
18
+ export interface Snapshot {
19
+ cursor: string | null;
20
+ conversations: Conversation[];
21
+ members: Member[];
22
+ messages: Message[];
23
+ threads: ThreadState[];
24
+ scheduled: ScheduledMessage[];
25
+ }
26
+ /** What changed in the store by one apply: what its views read again. */
27
+ export interface Touched {
28
+ /** The list of conversations (an order, an unread count, a last message). */
29
+ list: boolean;
30
+ /** Conversations whose messages, members or details changed. */
31
+ conversations: Set<string>;
32
+ /** Threads (by their root) whose answers or place changed. */
33
+ threads: Set<string>;
34
+ scheduled: boolean;
35
+ }
36
+ export declare class Store {
37
+ cursor: string | null;
38
+ readonly conversations: Map<string, api.Conversation>;
39
+ /** By conversation, then person. */
40
+ readonly members: Map<string, Map<string, api.Member>>;
41
+ /** By conversation, then message: a conversation's timeline and its threads' answers. */
42
+ readonly messages: Map<string, Map<string, api.Message>>;
43
+ /** By the thread's root. */
44
+ readonly threads: Map<string, api.ThreadState>;
45
+ readonly scheduled: Map<string, api.ScheduledMessage>;
46
+ /** Applies what changed; answers what of the store it touched. */
47
+ apply(ch: Changes): Touched;
48
+ /** A sync that starts again (reset): what the store kept goes, then the page is applied. */
49
+ reset(ch: Changes): Touched;
50
+ private drop;
51
+ private putConversation;
52
+ private putMember;
53
+ private putMessage;
54
+ private putThread;
55
+ private putScheduled;
56
+ /** A message removed where the reader is (its timer ran out, it vanished): gone from the store at once, before the server says. */
57
+ expire(conversationId: string, messageId: string): boolean;
58
+ /** The conversations, the latest first. */
59
+ list(): Conversation[];
60
+ /** A conversation's own timeline (its messages and the answers sent to it too), the oldest first. */
61
+ timeline(conversationId: string): Message[];
62
+ /** A thread's answers, the oldest first. */
63
+ answers(conversationId: string, rootId: string): Message[];
64
+ membersOf(conversationId: string): Member[];
65
+ snapshot(): Snapshot;
66
+ load(s: Snapshot): void;
67
+ }
@@ -6042,7 +6042,7 @@ export type CustomerEvent = {
6042
6042
  */
6043
6043
  reason?: string;
6044
6044
  /**
6045
- * Who did it: `store` (the store, or the customer at it), `customer`, `project`, or the key or user that gave a grant or moved credits (`key:…`, `user:…`).
6045
+ * Who did it: `store` (the store, or the customer at it), `customer`, `project`, the developer whose Studio or CLI call it was (`developer:…`), or the key or user that gave a grant or moved credits (`key:…`, `user:…`).
6046
6046
  */
6047
6047
  actor: string;
6048
6048
  /**
@@ -6118,7 +6118,7 @@ export type GrantRecord = {
6118
6118
  */
6119
6119
  starts_at: string;
6120
6120
  /**
6121
- * Who revoked it (the API key or user); null while it is not.
6121
+ * Who revoked it (`developer:…` for Studio or the CLI, `key:…`, `user:…`); null while it is not.
6122
6122
  */
6123
6123
  revoked_by: string | null;
6124
6124
  /**
@@ -10,6 +10,7 @@ import { Notify } from './notify.js';
10
10
  import { Purchases } from './purchases.js';
11
11
  import { type ChatToolCall } from './chat.js';
12
12
  import { Flags } from './flags.js';
13
+ import { Messaging, type MessagingOptions } from './messaging.js';
13
14
  export interface ClientOptions {
14
15
  /** The project's address: https://<ref>.<domain> */
15
16
  url: string;
@@ -68,6 +69,8 @@ export interface ClientOptions {
68
69
  * pb.setLanguage changes it.
69
70
  */
70
71
  language?: string | readonly string[];
72
+ /** What the device keeps of the signed-in person's conversations (pb.messaging): dropped on sign-out unless keepOnSignOut. */
73
+ messaging?: MessagingOptions;
71
74
  }
72
75
  /**
73
76
  * The app's client. A backend's generated Palbe module (palbase apps:sync)
@@ -93,6 +96,8 @@ export interface PalbaseClient {
93
96
  notify: Notify;
94
97
  /** The project's feature flags and remote configuration, resolved for this app and its reader, kept current as they change. */
95
98
  flags: Flags;
99
+ /** The signed-in person's conversations — direct ones and groups — kept up to date, on the device and live. */
100
+ messaging: Messaging;
96
101
  /** The language every request says from now on (ClientOptions.language); null for the browser's own. */
97
102
  setLanguage(language: string | readonly string[] | null): void;
98
103
  /**
@@ -10,6 +10,7 @@ export { connectVoice, type StartedVoice, type VoiceConnection, type VoiceOption
10
10
  export { Purchases, redemptionToken, type CheckoutSource, type CustomerInfo, type CustomerInfoListener, type GrantInfo, type MergeGrant, type OfferView, type Offerings, type Redeemed, type RedemptionLink, } from './purchases.js';
11
11
  export { Notify, WebPush, type PushPermission, type PushSubscribeOptions } from './notify.js';
12
12
  export { Flags, type FlagSource, type FlagsListener } from './flags.js';
13
+ export { ConversationList, ConversationView, indexedDBKeyValue, Messaging, ScheduledList, ThreadView, type Conversation, type ConversationViewState, type ConversationListState, type Entry, type Member, type Message, type MessagingOptions, type MyProfile, type Observed, type OpenedFile, type OutboxItem, type OutgoingFile, type Profile, type ScheduledMessage, type SendOptions, type ThreadState, type ThreadViewState, } from './messaging.js';
13
14
  export { Inbox, type InboxItem, type InboxListOptions, type InboxPage, type InboxView, type InboxViewOptions } from './inbox.js';
14
15
  export { InApp, SESSION_START, type InAppOptions } from './inapp.js';
15
16
  export type { Paywall, PaywallRenderOptions } from './paywall/placement.js';