@tinycloud/web-sdk 3.8.0-beta.2 → 3.8.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/replica.mjs CHANGED
@@ -1 +1 @@
1
- import*as e from"@tinycloud/web-sdk";import*as t from"@tinycloud/web-sdk/replica-gated";import{parseUcanGrant as r}from"@tinycloud/replica";var n={913(e){e.exports=import("@tinycloud/replica/kv-storage")},435(e){e.exports=import("@tinycloud/replica/profile-gate")},461(t,r,n){var i,s;t.exports=(i={__replicaActionContains:()=>e.__replicaActionContains,__replicaCanonicalizeRecapCaveats:()=>e.__replicaCanonicalizeRecapCaveats,__replicaIsCapabilitySubset:()=>e.__replicaIsCapabilitySubset,__replicaKV:()=>e.__replicaKV,__replicaParsePkhDid:()=>e.__replicaParsePkhDid,__replicaParseSpaceUri:()=>e.__replicaParseSpaceUri,__replicaPkhDid:()=>e.__replicaPkhDid,__replicaPrincipalDid:()=>e.__replicaPrincipalDid,__replicaSiweMessage:()=>e.__replicaSiweMessage},s={},n.d(s,i),s)},442(e){e.exports=t},204(e,t,n){n.d(t,{AUTHORITY_EXPIRY_MARGIN_MS:()=>O,assertRenewalParent:()=>x,assertValidReplicationConfig:()=>c,augmentSignInEntriesWithReplication:()=>f,createReplicationAuthority:()=>N,eraseReplicaLocalCopy:()=>v,establishReplicaSessionStamp:()=>b,hasUnrestrictedGetCoverage:()=>p,mintNodeReplicationGrant:()=>S,replicationScopeFromSignedSession:()=>C,reportReplicaDenial:()=>y,restoreReplicaSessionStamp:()=>R,ucanAttCovers:()=>k,ucanAttUnconstrainedFor:()=>I,verifiedOwnerConsentAnchor:()=>_}),n.r(t);var i=n(461);function s(e,t){return"/"===e||t.startsWith(e)}function a(e){const t="string"==typeof e&&e.length>0&&!e.startsWith("/")&&!e.includes("//")&&e.endsWith("/");if("/"!==e&&!t){const t="string"==typeof e?e.replace(/^\/+/,"").replace(/\/+$/,""):"",r=t.length>0&&!t.includes("//")?` Use ${JSON.stringify(`${t}/`)}.`:' Use "/" or a slash-terminated folder path such as "notes/".';throw new TypeError(`Replication prefix must be "/" or a non-empty slash-terminated folder path without empty segments.${r}`)}}var o=n(191);function c(e){if(void 0!==e?.syncScope&&"prefixes"!==e.syncScope)throw new TypeError('replication.syncScope must be "prefixes"');if(void 0===e||!e.enabled)return;if(void 0===e.storage||null===e.storage)throw new TypeError("replication.enabled requires replication.storage");if(!Array.isArray(e.prefixes)||0===e.prefixes.length)throw new TypeError("replication.prefixes must be a non-empty array");const t=e.grantTtlMs;if(void 0!==t&&(!Number.isFinite(t)||t<=0||t>6048e5))throw new TypeError("replication.grantTtlMs must be a positive number of milliseconds no greater than 604800000");for(const t of e.prefixes)try{a(t)}catch(e){throw new TypeError(e instanceof Error?e.message:String(e))}for(const[t,r]of e.prefixes.entries()){for(const n of e.prefixes.slice(t+1))if(s(r,n)||s(n,r))throw new TypeError(`replication.prefixes must not overlap: ${JSON.stringify(r)} and ${JSON.stringify(n)}`);if(("/"===r||"vault"===r.split("/",1)[0])&&!0!==e.allowSecrets)throw new TypeError(`replication prefix ${JSON.stringify(r)} overlaps the vault namespace; pass allowSecrets to opt in`)}}var l=i.__replicaKV.GET,d=i.__replicaKV.SYNC,u="tinycloud.kv";function p(e,t,r){return(0,i.__replicaIsCapabilitySubset)([{service:u,space:t,path:r,actions:[l]}],[...e]).subset}function f(e){const t=[],r=e.replication;if(void 0===r)return t;const n=[];for(const t of r.prefixes){a(t);const i="/"===t?"":t;(0,o.requiresSecretsOptIn)(e.primarySpaceId,t)&&!0!==r.allowSecrets||p(e.entries,e.primarySpaceId,i)&&n.push(i)}if("prefixes"!==r.syncScope&&n.length===r.prefixes.length&&n.length>0&&p(e.entries,e.primarySpaceId,""))return[{service:u,space:e.primarySpaceId,path:"",actions:[l,d]}];for(const r of n)t.push({service:u,space:e.primarySpaceId,path:r,actions:[l,d]});return t}var h=r;function y(e,t,r,n){if("denied"!==e.status&&"deleted"!==e.status&&"marker"!==e.status)return;const i={type:"replication.lifecycle",at:(new Date).toISOString(),reason:t,action:"denied"===e.status?"denied":"deleted"===e.status?"database_deleted":"marker_set",..."denied"===e.status?{partitions:e.intents}:{},..."marker"===e.status?{code:e.code}:{}};try{r?.(i)}catch{}const{type:s,...a}=i;try{n?.emit(s,a)}catch{}}var g=[150,450];async function v(e,t,r,n){if("indexeddb"!==e?.kind||void 0===e.eraseLocalCopy)return;let i={status:"failed",code:"STORAGE_ERROR",marker:!1};for(let t=0;t<=g.length;t++){t>0&&await new Promise(e=>setTimeout(e,g[t-1]));try{i=await e.eraseLocalCopy({signal:AbortSignal.timeout(3e3)})}catch{i={status:"failed",code:"STORAGE_ERROR",marker:!1}}if("failed"!==i.status)break}const s="marker"===r||"unguarded"===r,a="erased"===i.status?{ok:!0}:{ok:!1,retryNow:"failed"===i.status};if("erased"===i.status||"refused"===i.status&&!s)return{outcome:i,purge:a};const o="failed"===i.status&&i.marker,c={type:"replica.purge.failed",trigger:t,reason:o?"logout_pending":"gate_unavailable",code:i.code,retryNow:"failed"===i.status};for(const e of n)try{e(c)}catch(e){console.error('Error in "replica.purge.failed" handler:',e)}return o?{outcome:i,purge:a,logoutPending:o}:{outcome:i,purge:a}}var E=i.__replicaKV.GET,m=i.__replicaKV.SYNC,w="tinycloud.kv";function _(e,t,r){if("string"!=typeof e.siwe||"string"!=typeof e.signature||"string"!=typeof e.address||"number"!=typeof e.chainId)return null;try{const n=t.validatePersistedSession?.({delegationHeader:e.delegationHeader,delegationCid:e.delegationCid,spaceId:e.spaceId,jwk:e.jwk,address:e.address,chainId:e.chainId,siwe:e.siwe,signature:e.signature});if(!n||!Number.isSafeInteger(Date.parse(n.expiresAt??"")))return null;const s=new i.__replicaSiweMessage(e.siwe).issuedAt;if("string"!=typeof s)return null;const a=Date.parse(s);if(!Number.isSafeInteger(a)||a<0)return null;const o=r(n).filter(t=>t.space===e.spaceId&&"kv"===t.service).map(e=>({...e,service:"tinycloud.kv"}));return o.some(t=>(0,i.__replicaIsCapabilitySubset)([{service:"tinycloud.kv",space:e.spaceId,path:t.path,actions:[i.__replicaKV.GET,i.__replicaKV.SYNC]}],o).subset)?{at:a,source:"siwe"}:null}catch{return null}}function b(e,t,r){if("indexeddb"===e.kind&&"indexeddb"===e.lifecycle?.kind)return e.lifecycle.establishSessionStamp(t,{consentAnchor:r});if("sqlite"===e.kind&&"file"===e.lifecycle?.kind)return e.lifecycle.establishSessionStamp(t,{consentAnchor:r});throw Object.assign(new Error("Replica sign-in requires its platform lifecycle gate."),{code:"REPLICA_GATED",gate:"gate_unavailable"})}function R(e,t,r){if("indexeddb"===e.kind&&"indexeddb"===e.lifecycle?.kind)return e.lifecycle.restoreSessionStamp(t,r);if("sqlite"===e.kind&&"file"===e.lifecycle?.kind)return e.lifecycle.restoreSessionStamp(t,r);throw Object.assign(new Error("Replica restore requires its platform lifecycle gate."),{code:"REPLICA_GATED",gate:"gate_unavailable"})}function T(e,t){return[{service:w,space:e,path:"/"===t?"":t,actions:[E,m]}]}function A(e){if(null==e)return!0;if("object"==typeof e&&!Array.isArray(e)&&0===Object.keys(e).length)return!0;if(!Array.isArray(e))return!1;try{return(0,i.__replicaCanonicalizeRecapCaveats)(e)===(0,i.__replicaCanonicalizeRecapCaveats)(void 0)}catch{return!1}}function P(e,t){for(const r of[`${t}/kv`,`tinycloud://${t}/kv`])if(e===r||e===`${r}/`)return"/";for(const r of[`${t}/kv/`,`tinycloud://${t}/kv/`])if(e.startsWith(r))return e.slice(r.length)}function k(e,t,r,n,s){for(const[a,o]of Object.entries(e)){const e=P(a,t);if(void 0!==e)for(const[a,c]of Object.entries(o))if((0,i.__replicaActionContains)(a,n)&&(0,i.__replicaIsCapabilitySubset)([{service:w,space:t,path:r,actions:[n]}],[{service:w,space:t,path:e,actions:[a]}]).subset&&(!0===s?.ignoreCaveats||A(c)))return!0}return!1}function I(e,t,r){return k(e,t,r,E)&&k(e,t,r,m)}async function S(e,t,r,n,s){if(r?.renewalOnly&&!n)throw new Error("replication renewal lost its owner session");const a=r?.renewalOnly?{expiry:r.expiryMs,onPrepared:async e=>{x(e.delegationHeader.Authorization,n)}}:void 0===r?.expiryMs?void 0:{expiry:r.expiryMs},o=await s.delegateTo((0,i.__replicaPrincipalDid)(e),t,a);return{ucan:o.delegation.delegationHeader.Authorization,expiresAt:o.delegation.expiry.getTime()}}var O=6e4;function C(e){let t;try{t=h(e.delegationHeader.Authorization)}catch{return}const r=e=>e.split("#",1)[0];if(t.cid===e.delegationCid&&r(t.audience)===r(e.verificationMethod))for(const r of Object.keys(t.att)){const t=r.match(/^(?:tinycloud:\/\/)?(.+?)\/kv(?:\/|$)/)?.[1];if(t!==e.persistedSpace)continue;const n=(0,i.__replicaParseSpaceUri)(t);if(n?.owner&&n.address&&n.chainId)return{space:t,principal:n.owner}}}function x(e,t){const r=h(e);if(r.issuer!==t.verificationMethod.split("#",1)[0]||1!==r.prf.length||r.prf[0]!==t.delegationCid)throw Object.assign(new Error("replication renewal requires the bound owner session parent"),{refused:"NOT_COVERED"})}function N(e){const t=e.replicationSession();let r=null;try{const n=t&&e.verifiedConsentAnchor?.(t);n&&Number.isFinite(n.at)&&"first_install"!==n.source&&(r={at:n.at,source:n.source})}catch{}const n=()=>{const r=e.replicationSession();return void 0!==r&&r===t?r:void 0},i=(t,r)=>{const n=e.planDelegation(t,void 0===r?void 0:{expiry:r});return"refused"in n?n:{path:n.path,parentCid:n.parentCid,expiresAt:n.expiresAt}},s=e=>e.split("#",1)[0],a=e=>{const t=h(e.delegationHeader.Authorization);if(t.cid===e.delegationCid&&s(t.audience)===s(e.verificationMethod))return t},o={get sessionOnly(){const e=n();return void 0===e||void 0===e.siwe},consentAnchor:()=>n()?r:null,get canRenew(){const e=n();return"siwe"===r?.source&&void 0!==e&&void 0!==e.siwe},sessionGrant(t){const i=n();if(void 0===i)return{refused:"SESSION_EXPIRING"};if(null===r&&void 0!==i.siwe)return{refused:"NOT_COVERED"};const s=i.siwe?e.siweExpiration(i.siwe)?.getTime():void 0;if(void 0!==s&&s<=Date.now()+O)return{refused:"SESSION_EXPIRING"};let o;try{const e=a(i);if(!e)return{refused:"NOT_COVERED"};o=e}catch{return{refused:"NOT_COVERED"}}const c=null===o.expiresAt?void 0:1e3*o.expiresAt;return void 0===c||c<=Date.now()+O?{refused:"SESSION_EXPIRING"}:k(o.att,i.spaceId,t,E,{ignoreCaveats:!0})&&k(o.att,i.spaceId,t,m,{ignoreCaveats:!0})?I(o.att,i.spaceId,t)?{ucan:o.jwt,device:{did:i.verificationMethod,jwk:i.jwk}}:{refused:"CAVEATED_AUTHORITY"}:{refused:"NOT_COVERED"}},plan(e){const t=n();if(void 0===t)return{refused:"SESSION_EXPIRING"};if(null===r)return{refused:"NOT_COVERED"};const s=this.sessionGrant(e);if(!("refused"in s)){const e=a(t);return e&&null!==e.expiresAt?{path:"session",parentCid:t.delegationCid,expiresAt:1e3*e.expiresAt}:{refused:"NOT_COVERED"}}return o.sessionOnly?s:i(T(t.spaceId,e))},async mint(t,s,a,o){const c=n();if(void 0===c)throw new Error("replication mint without the bound session");if(void 0===c.siwe)throw new Error("compact delegate sessions cannot mint device grants");if("siwe"!==r?.source)throw new Error("replication mint requires verified owner consent");const l=T(c.spaceId,s),d=i(l,o?.expiryMs);if("refused"in d)throw Object.assign(new Error(`replication authority refused the mint: ${d.refused}`),{refused:d.refused});if(o?.renewalOnly&&"session"!==d.path)throw Object.assign(new Error("replication renewal requires a session parent"),{refused:"NOT_COVERED"});a.throwIfAborted();const u=await new Promise((r,n)=>{const i=()=>n(a.reason??new Error("replication mint aborted"));a.addEventListener("abort",i,{once:!0}),e.mintDelegation(t,l,o).then(e=>{a.removeEventListener("abort",i),r(e)},e=>{a.removeEventListener("abort",i),n(e instanceof Error?e:new Error(String(e)))})});return{ucan:u.ucan,parentCid:d.parentCid,expiresAt:u.expiresAt}}};return o}},230(e,t,r){r.r(t),r.d(t,{ReplicationRuntime:()=>s});var n=r(461),i={now:()=>Date.now(),setTimeout(e,t){const r=setTimeout(e,t);return r.unref?.(),()=>clearTimeout(r)}},s=class{constructor(e,t=i){this.options=e,this.clock=t,this.pending=new Map,this.attached=new Map,this.previous=Promise.resolve(),this.binding=Promise.resolve(),this.generation=0,this.bindingActive=!1,this.pendingPurgeSet=!1,this.closed=!1,this.control={status:async()=>(await this.binding,this.gatedReason?this.options.prefixes.map(e=>({prefix:e,state:"gated",gate:this.gatedReason,errorCode:"REPLICA_GATED",pending:{inFlight:0,committed:0,ambiguous:0},pinned:[],lagMs:null})):this.current?this.current.status():[]),sync:async e=>{if(await this.binding,this.gatedReason)throw Object.assign(new Error("Replica restore is gated."),{code:"REPLICA_GATED",gate:this.gatedReason});this.purgedGeneration!==this.generation&&this.current&&await this.current.sync(e)},purge:e=>{if(this.bindingActive){this.pendingPurge=e,this.pendingPurgeSet=!0;const t=this.current??this.lastController;return t&&(this.pendingPurgeResult=t.purge(e),this.purgedGeneration=this.generation),this.binding.then(()=>this.pendingPurgeResult??{purged:[],failed:[]})}const t=this.current??this.lastController;return t?(this.purgedGeneration=this.generation,t.purge(e)):Promise.resolve({purged:[],failed:[]})},clearPending:async()=>{if(await this.binding,this.current)return this.current.clearPending();const e=this.lastPending;return e?e.update(e=>{const t=e.records.length;return e.records=e.records.filter(e=>"committed"===e.state||"in_flight"===e.state&&this.clock.now()-Date.parse(e.at)<=6e5),t-e.records.length}):0},close:async()=>{this.closed=!0,this.unbind(),await this.binding.catch(()=>{}),await this.previous}}}loadServices(){return this.services??(this.services=Promise.resolve().then(r.bind(r,191)))}detachAll(){for(const e of this.attached.keys())e.setReadThrough(null);this.attached.clear()}bindGatedNetworkOnly(e,t){if(this.closed||!this.options.enabled)return Promise.resolve();const r=this.unbind(),n=this.generation;return this.purgedGeneration=void 0,this.pendingPurge=void 0,this.pendingPurgeResult=void 0,this.pending.clear(),this.lastController=void 0,this.lastPending=void 0,this.lastIdentity=void 0,this.gatedReason=e.gate,this.primarySpace=e.session.spaceId,this.binding=r.then(async()=>{let r;try{({createGatedNetworkReadThrough:r}=await t())}catch{return}if(n!==this.generation||this.closed||"function"!=typeof r)return;const i=r({space:e.session.spaceId,prefixes:this.options.prefixes,now:()=>this.clock.now(),emit:t=>{if(n!==this.generation||this.closed||this.gated!==i)return;try{this.options.onEvent?.(t)}catch{}const{type:r,...s}=t;try{e.context.emit(r,s)}catch{}}});this.gated=i;for(const t of e.primaryKV)this.attach(t.space,t.kv)}),this.binding}bind(e){if(this.closed||!this.options.enabled)return Promise.resolve();this.gated=void 0,this.gatedReason=void 0,this.bindingActive=!0;const t=++this.generation;this.purgedGeneration=void 0,this.unsubscribeConsentExpired?.(),this.unsubscribeConsentExpired=void 0;const{context:r,session:i}=e,s=e=>{try{this.options.onEvent?.(e)}catch{}const{type:t,...n}=e;r.emit(t,n)},a=this.current;this.current=void 0;for(const e of this.attached.keys())e.setReadThrough(null);this.primarySpace=i.spaceId;const o=a?a.close().catch(()=>{}):Promise.resolve();this.previous=this.previous.then(()=>o);const c=this.previous;this.binding=this.loadServices().then(a=>{if(t!==this.generation||this.closed)return;let o;try{o=a.canonicalReplicationIdentity({host:r.hosts[0],space:i.spaceId,principal:e.principal??(0,n.__replicaPkhDid)(e.address,e.chainId)})}catch{for(const e of this.options.prefixes)s({type:"replication.state",at:new Date(this.clock.now()).toISOString(),space:i.spaceId,replica:e,state:"unavailable",code:"CONFIG_INVALID"});return}const l=a.replicationIdentityKey(o);let d=this.pending.get(l);const u=e.stamp;if(!d||d.stamp?.incarnation!==u?.incarnation||d.stamp?.lifecycleEpoch!==u?.lifecycleEpoch){const e=this.options.storage.pendingWrites?.(o,{stamp:u});if(!e&&this.options.storage.lifecycle)throw Object.assign(new Error("Gated replication requires a stamped pending store"),{code:"REPLICA_GATED",gate:"gate_unavailable"});d={stamp:u,store:e??a.createMemoryPendingStore(o)},this.pending.set(l,d)}const p=d.store;this.lastPending=p;const f=a.createKVReplication({options:(h=this.options,{...h,syncIntervalMs:h.syncIntervalMs??6e4,maxStalenessMs:h.maxStalenessMs??12e4,staleSyncTimeoutMs:h.staleSyncTimeoutMs??5e3,allowSecrets:!0===h.allowSecrets,verify:!0===h.verify}),mode:this.options.mode??"background",storage:this.options.storage,identity:o,session:{id:i.delegationCid,did:i.verificationMethod,space:i.spaceId},stamp:e.stamp,authority:e.authority,pending:p,scheduler:this.clock,emit:s,fetch:r.fetch,nodeFeatures:e.nodeFeatures,previous:c});var h;this.current=f,this.unsubscribeConsentExpired=this.options.storage.lifecycle?.subscribeConsentExpired?.(e=>f.observeConsentExpired(e)),this.lastController=f,this.lastIdentity=o;for(const[e,t]of this.attached)e.setReadThrough(t===this.primarySpace?f:null);for(const t of e.primaryKV)this.attach(t.space,t.kv);this.pendingPurgeSet&&(this.pendingPurgeResult=f.purge(this.pendingPurge),this.purgedGeneration=t,this.pendingPurge=void 0,this.pendingPurgeSet=!1)}).finally(()=>{t===this.generation&&(this.bindingActive=!1)});for(const e of this.attached.keys())e.setReadThroughReady?.(this.binding);return this.binding}attach(e,t){this.attached.set(t,e),t.setReadThrough(e===this.primarySpace?this.current??this.gated??null:null);const r=this.generation;return this.binding.then(()=>{r!==this.generation||this.closed||this.attached.get(t)!==e||t.setReadThrough(e===this.primarySpace?this.current??this.gated??null:null)})}unbind(){this.generation++,this.bindingActive=!1,this.pendingPurgeSet=!1,this.unsubscribeConsentExpired?.(),this.unsubscribeConsentExpired=void 0;const e=this.current;this.current=void 0,this.gated=void 0,this.gatedReason=void 0,this.primarySpace=void 0,this.detachAll();const t=this.binding.then(()=>e?.close()).catch(()=>{});return this.previous=this.previous.then(()=>t),this.previous}get boundIdentity(){return this.lastIdentity}}},191(e,t,r){r.d(t,{CLEAR_PENDING_WARNING:()=>V,canonicalReplicationIdentity:()=>F,createKVReplication:()=>Ie,createMemoryPendingStore:()=>Ce,kvPrefixCovers:()=>K,replicationIdentityKey:()=>B,requiresSecretsOptIn:()=>z}),r.r(t);var n=[{urn:"tinycloud.kv/get",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/list",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/metadata",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/put",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/del",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/delete",service:"tinycloud.kv",status:"deprecated-alias",aliasOf:"tinycloud.kv/del"},{urn:"tinycloud.kv/sync",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/retain",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.sql/read",service:"tinycloud.sql",status:"active"},{urn:"tinycloud.sql/select",service:"tinycloud.sql",status:"deprecated-alias",aliasOf:"tinycloud.sql/read"},{urn:"tinycloud.sql/write",service:"tinycloud.sql",status:"active"},{urn:"tinycloud.sql/schema",service:"tinycloud.sql",status:"active"},{urn:"tinycloud.sql/admin",service:"tinycloud.sql",status:"active",implies:["tinycloud.sql/schema"]},{urn:"tinycloud.sql/*",service:"tinycloud.sql",status:"active",implies:["tinycloud.sql/read","tinycloud.sql/write","tinycloud.sql/schema","tinycloud.sql/admin"]},{urn:"tinycloud.duckdb/read",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/write",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/admin",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/import",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/export",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/select",service:"tinycloud.duckdb",status:"deprecated-alias",aliasOf:"tinycloud.duckdb/read"},{urn:"tinycloud.duckdb/*",service:"tinycloud.duckdb",status:"active",implies:["tinycloud.duckdb/read","tinycloud.duckdb/write","tinycloud.duckdb/admin","tinycloud.duckdb/import","tinycloud.duckdb/export"]},{urn:"tinycloud.capabilities/read",service:"tinycloud.capabilities",status:"active"},{urn:"tinycloud.delegation/status",service:"tinycloud.delegation",status:"active"},{urn:"tinycloud.delegation/list",service:"tinycloud.delegation",status:"active"},{urn:"tinycloud.hooks/subscribe",service:"tinycloud.hooks",status:"active"},{urn:"tinycloud.hooks/register",service:"tinycloud.hooks",status:"active"},{urn:"tinycloud.hooks/list",service:"tinycloud.hooks",status:"active"},{urn:"tinycloud.hooks/unregister",service:"tinycloud.hooks",status:"active"},{urn:"tinycloud.encryption/decrypt",service:"tinycloud.encryption",status:"active"},{urn:"tinycloud.encryption/network.create",service:"tinycloud.encryption",status:"active"},{urn:"tinycloud.encryption/network.revoke",service:"tinycloud.encryption",status:"active"},{urn:"tinycloud.space/host",service:"tinycloud.space",status:"active"},{urn:"tinycloud.space/create",service:"tinycloud.space",status:"active"},{urn:"tinycloud.space/list",service:"tinycloud.space",status:"active"},{urn:"tinycloud.space/info",service:"tinycloud.space",status:"active"},{urn:"tinycloud.vfs/get",service:"tinycloud.vfs",status:"reserved"},{urn:"tinycloud.vfs/list",service:"tinycloud.vfs",status:"reserved"},{urn:"tinycloud.vfs/metadata",service:"tinycloud.vfs",status:"reserved"},{urn:"tinycloud.vfs/put",service:"tinycloud.vfs",status:"reserved"},{urn:"tinycloud.vfs/delete",service:"tinycloud.vfs",status:"reserved"}];function i(e){return"*"===e?"ALL":e.toUpperCase().replace(/[^A-Z0-9]/g,"_")}function s(e){return e.slice(10,e.indexOf("/"))}function a(e){return e.slice(e.indexOf("/")+1)}function o(e){const t={};for(const r of n)s(r.urn)===e&&(t[i(a(r.urn))]=r.urn);return t}var c=o("kv"),l={...o("sql"),EXECUTE:"tinycloud.sql/execute",EXPORT:"tinycloud.sql/export"},d=(o("duckdb"),o("capabilities")),u=(o("hooks"),o("encryption")),p=o("space"),f=n,h="applications",y="account",g="applications/",v="secrets",E="default",m="public",w="agents",_="tinycloud.encryption",b=u.NETWORK_CREATE,R=[E,h,y,v,m,w],T={app_id:"xyz.tinycloud.default",name:"TinyCloud Default Space",space:E,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:E,path:"",actions:["get","put","del","list","metadata"]},{service:"tinycloud.sql",space:E,path:"",actions:["read","write"]}]},A={app_id:"xyz.tinycloud.applications",name:"TinyCloud Applications Space",space:h,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:h,path:"",actions:["get","put","del","list","metadata"]},{service:"tinycloud.sql",space:h,path:"",actions:["read","write"]}]},P={app_id:"xyz.tinycloud.account",name:"TinyCloud Account Registry",space:y,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:y,path:"applications/",actions:["get","put","list"]},{service:"tinycloud.kv",space:y,path:"spaces/",actions:["get","put","list"]},{service:"tinycloud.sql",space:y,path:"account",actions:["read","write","schema"]}]},k={app_id:"xyz.tinycloud.secrets",name:"TinyCloud Secrets",space:v,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.vault",space:v,path:"secrets/",actions:["read"],skipPrefix:!0},{service:"tinycloud.kv",space:v,path:"variables",actions:["list","metadata"],skipPrefix:!0},{service:"tinycloud.kv",space:v,path:"variables/",actions:["get","put","del","list","metadata"],skipPrefix:!0},{service:"tinycloud.sql",space:v,path:"default",actions:["read","write","schema"],skipPrefix:!0},{service:"tinycloud.capabilities",space:v,path:"",actions:["read"],skipPrefix:!0}]},I={app_id:"xyz.tinycloud.public",name:"TinyCloud Public Space",space:m,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:m,path:"",actions:["get","list","metadata"]}]},S={app_id:"xyz.tinycloud.agents",name:"TinyCloud Agents Space",space:w,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:w,path:"",actions:["get","put","del","list","metadata"]}]},O={[E]:T,[h]:A,[y]:P,[v]:k,[m]:I,[w]:S};function C(e){return{...e,permissions:e.permissions?.map(e=>({...e,actions:[...e.actions]}))}}function x(e,t,r){return!0===r||""===e||""===t?t:"/"===t?`${e}/`:`${e.endsWith("/")?e.slice(0,-1):e}/${t.startsWith("/")?t.slice(1):t}`}function N(e,t,r){if("tinycloud.vault"===e.service)return function(e){return e.actions.map(t=>{const r=t.startsWith("tinycloud.vault/")?t.slice(16):t.startsWith("tinycloud.kv/")?t.slice(13):t,n="read"===r||"get"===r?c.GET:"write"===r||"put"===r?c.PUT:"delete"===r||"del"===r?c.DEL:"list"===r?c.LIST:"metadata"===r?c.METADATA:void 0;if(void 0===n)throw new Error(`unknown vault action ${JSON.stringify(t)}`);const i=e.path.startsWith("/")?e.path.slice(1):e.path;return{...e,service:"tinycloud.kv",path:`vault/${i}`,actions:[n],skipPrefix:!0}})}(e).flatMap(e=>N(e,t,r));const n=!0===e.skipPrefix||e.service===_;return[{service:e.service,space:e.service===_?"encryption":e.space??r,path:x(t,e.path,n),actions:e.actions.map(t=>function(e,t){return t.includes("/")?t:`${e}/${t}`}(e.service,t)),...void 0!==e.description?{description:e.description}:{}}]}function D(e){const t=new Set(e.filter(e=>e.service!==_).map(e=>e.space));return function(e){const t=new Map;for(const r of e){const e=`${r.service}\0${r.space}\0${r.path}`,n=t.get(e);if(n)for(const e of r.actions)n.actions.includes(e)||n.actions.push(e);else t.set(e,{...r,actions:[...r.actions]})}return[...t.values()]}([...e,...[...t].map(e=>({service:"tinycloud.capabilities",space:e,path:"",actions:[d.READ]}))])}function M(e){return function(e,t={}){if(!Array.isArray(e)||0===e.length)throw new Error("composeManifestRequest requires at least one manifest");const r=t.includeAccountRegistryPermissions??!0,n=e.map(C),i=n.flatMap(e=>{const t=e.prefix??e.app_id,r=e.space??h;return(e.permissions??[]).flatMap(e=>N(e,t,r))});r&&i.push(...G.map(e=>({...e,actions:[...e.actions]})));const s=new Map;for(const e of n){const t=s.get(e.app_id)??[];t.push(C(e)),s.set(e.app_id,t)}return{manifests:n,resources:D(i),delegationTargets:[],registryRecords:r?[...s.entries()].map(([e,t])=>({key:`${g}${e}`,app_id:e,manifests:t})):[],expiryMs:2592e6,includePublicSpace:n.some(e=>e.includePublicSpace??!0)}}([O[e]],{includeAccountRegistryPermissions:!1})}R.map(e=>({name:e,manifest:O[e],persistedAsApplication:e===v}));var G=Object.freeze([{service:"tinycloud.kv",space:y,path:g,actions:[c.GET,c.PUT,c.LIST]},{service:"tinycloud.kv",space:y,path:"spaces/",actions:[c.GET,c.PUT,c.LIST]},{service:"tinycloud.kv",space:y,path:"system/bootstrap/complete",actions:[c.GET,c.PUT]},{service:"tinycloud.delegation",space:y,path:"",actions:["tinycloud.delegation/list"]},{service:"tinycloud.sql",space:y,path:"account",actions:[l.READ,l.WRITE,l.SCHEMA]},{service:"tinycloud.capabilities",space:y,path:"",actions:[d.READ]}]),L=M(E),U={...L,resources:[...L.resources,...G.map(e=>({...e,actions:[...e.actions]}))]},q=Object.freeze(Object.fromEntries(R.map(e=>[e,e===E?U:M(e)]))),j=Object.freeze([{service:"tinycloud.encryption",resource:"urn:tinycloud:encryption:{ownerDid}:default",actions:[b]}]);Object.freeze(R.flatMap(e=>[{kind:"session",service:"tinycloud.session",space:e,actions:["siwe"],resources:q[e].resources,...e===y?{rawAbilities:j}:{}},{kind:"space/host",service:"tinycloud.space",space:e,actions:[p.HOST]}]));var V="Clearing pending writes surrenders read-your-writes protection for the cleared keys. If a write whose record was cleared had an unknown outcome or never finished, it may commit now or later; this device can serve an older value until the next sync after that commit, as it would for a write from another device.",X=/^(tinycloud:pkh:eip155:\d+:)([^:]+)(:.+)$/,$=/^(did:pkh:eip155:\d+:)([^:]+)$/;function F(e){if(!e||"string"!=typeof e.host||"string"!=typeof e.space||"string"!=typeof e.principal)throw new TypeError("Replication identity host, space, and principal must be strings");const t=/^https?:\/\/([^/?#]*)/i.exec(e.host)?.[1];let r;try{r=new URL(e.host)}catch{throw new TypeError("Replication identity host must be an absolute HTTP(S) URL")}if(!t||t.includes("@")||e.host.includes("?")||e.host.includes("#")||r.username||r.password)throw new TypeError("Replication identity host must be HTTP(S) without credentials, query, or fragment");const n=X.exec(e.space),i=$.exec(e.principal);if(!n||!i)throw new TypeError("Replication identity requires a full TinyCloud space id and a pkh principal DID");return{host:`${r.origin}${r.pathname.replace(/\/+$/,"")}`,space:`${n[1]}${n[2].toLowerCase()}${n[3]}`,principal:`${i[1]}${i[2].toLowerCase()}`}}function B(e){const t=F(e);return`tc-replication/v1\n${t.host}\n${t.space}\n${t.principal}`}function K(e,t){return"/"===e||t.startsWith(e)}function W(e,t){return""===e||t===e||t.startsWith(e.endsWith("/")?e:`${e}/`)}function z(e,t){return"/"===t||!("secrets"!==e&&!e.endsWith(":secrets"))||"vault"===t.split("/",1)[0]}var H="NETWORK_ERROR",Y="TIMEOUT",J="ABORTED",Q="INVALID_INPUT",Z="KV_NOT_FOUND";function ee(e){return{ok:!0,data:e}}function te(e){return{ok:!1,error:e}}function re(e,t,r,n){return{code:e,message:t,service:r,cause:n?.cause,meta:n?.meta}}var ne=class extends Error{constructor(e){super(`Request timed out after ${e}ms.`),this.name="TimeoutError",this.timeoutMs=e}};function ie(e,t,r){return void 0===t?{code:Y,message:"Request timed out.",service:e,...void 0===r?{}:{cause:r}}:{code:Y,message:`Request timed out after ${t}ms.`,service:e,...void 0===r?{}:{cause:r},meta:{timeoutMs:t}}}function se(e,t,r=H){return t instanceof Error?function(e){return e instanceof ne||e instanceof Error&&"TimeoutError"===e.name&&"number"==typeof e.timeoutMs}(t)?ie(e,t.timeoutMs,t):"AbortError"===t.name?function(e){return{code:J,message:"Request was aborted.",service:e}}(e):"TimeoutError"===t.name||t.message.toLowerCase().includes("timeout")?ie(e):{code:r,message:t.message,service:e,cause:t}:{code:r,message:String(t),service:e}}new Set(f.map(({urn:e})=>e).filter(e=>!e.endsWith("/*"))),new Set(f.map(({service:e})=>e.slice(10)));var ae=new Set(["AUTH_REQUIRED",Q,"AUTH_UNAUTHORIZED","KV_PRECONDITION_FAILED","STORAGE_QUOTA_EXCEEDED","STORAGE_LIMIT_REACHED"]);function oe(e){return{v:2,identity:{...e},committedEpoch:0,seq:0,records:[]}}function ce(e,t,r,n=100){return e.records.filter(e=>K(t,e.key)&&("in_flight"===e.state||"ambiguous"===e.state)).sort((e,t)=>e.seq-t.seq).slice(0,n).map(e=>({key:e.key,state:e.state,op:e.op,since:e.at,...e.code?{code:e.code}:{},likelyOrphaned:"in_flight"===e.state&&r-Date.parse(e.at)>6e5}))}function le(e,t,r,n){if(n)return e;const i=(new TextDecoder).decode(e);if(r)return i;if(t?.includes("application/json"))return JSON.parse(i);if(t?.startsWith("text/"))return i;if(i)try{return JSON.parse(i)}catch{return i}}var de=new TextEncoder,ue=new TextDecoder("utf-8",{fatal:!0});function pe(e,t){const r=de.encode(e),n=de.encode(t);for(let e=0;e<Math.min(r.length,n.length);e++)if(r[e]!==n[e])return r[e]-n[e];return r.length-n.length}function fe(e,t,r){const n=de.encode(JSON.stringify({v:1,space:e,path:t,last:r}));let i="";for(let e=0;e<n.length;e+=32768)i+=String.fromCharCode(...n.subarray(e,e+32768));return`tcr1.${btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}`}function he(e){try{const t=e.slice(5).replace(/-/g,"+").replace(/_/g,"/"),r=atob(t+"=".repeat((4-t.length%4)%4)),n=Uint8Array.from(r,e=>e.charCodeAt(0)),i=JSON.parse(ue.decode(n));return 1===i?.v&&"string"==typeof i.space&&"string"==typeof i.path&&"string"==typeof i.last?i:null}catch{return null}}function ye(){return te(re(Q,"Local list cursor cannot be served; restart without the cursor","kv",{meta:{replication:"cursor_restart"}}))}function ge(e,t){return e.find(e=>K(e,t))}var ve=864e5,Ee=ve,me=7*ve,we=7*ve,_e=Number.NEGATIVE_INFINITY,be=({now:e,grantTtlMs:t,consentDeadline:r})=>Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(r)?Math.min(Math.min(t,me),r-e):0,Re=3e3,Te=Re,Ae=e=>new Date(e).toISOString(),Pe=e=>"object"==typeof e&&null!==e&&"code"in e&&"string"==typeof e.code?e.code:"REPLICA_UNAVAILABLE";function ke(e,t){if(t.aborted)return Promise.reject(t.reason??Object.assign(new Error("KV request was aborted"),{code:J}));let r=()=>{};const n=new Promise((e,n)=>{const i=()=>n(t.reason??Object.assign(new Error("KV request was aborted"),{code:J}));t.addEventListener("abort",i,{once:!0}),r=()=>t.removeEventListener("abort",i)});return Promise.race([e,n]).finally(r)}function Ie(e){const{options:t,mode:r,storage:n,identity:i,session:s,authority:a,pending:o,scheduler:c}=e,l=t=>function(e,t,r){try{e({...r,at:new Date(t.now()).toISOString()})}catch{}}(e.emit,c,t),d=new Map,u=new Set;let p=!1,f=!1,h=!1,y=e.previous,g=!1;const v=new Set;let E=!1,m=null;try{w=a.consentAnchor?.()??null,_=c.now(),m=null!==w&&Number.isFinite(w.at)&&Number.isFinite(_)?w.at>_?{at:_,source:w.source}:w:null,"first_install"===m?.source&&(m=null)}catch{E=!0}var w,_;const b={grantTtlMs:t.grantTtlMs??Ee,consentAnchor:m},R=void 0===t.maxBytes&&void 0===t.minFreeBytes?void 0:{maxBytes:t.maxBytes,minFreeBytes:t.minFreeBytes},T=null===m?null:(e=>Number.isFinite(e.at)?e.at+we:_e)(m);let A,P=null;function k(){if("indexeddb"!==n.kind||!e.stamp)return null;try{const t=n.lifecycle?.consentDeadline(e.stamp);return"number"==typeof t&&Number.isFinite(t)?t:null}catch{return null}}function I(){if(null===T)return null;if("indexeddb"!==n.kind)return T;const e=k();return null===e?null:Math.min(T,e)}const S=new Set;let O=!1;function C(){const t=n.lifecycle;if(!t)return"indexeddb"===n.kind||E||void 0!==e.stamp?{status:"gated",gate:"gate_unavailable"}:{status:"allow"};if(!e.stamp)return{status:"gated",gate:"not_established"};if(O)return{status:"gated",gate:"stamp_stale"};try{const r=t.checkDelivery(e.stamp);if("consent_expired"===r.status&&N(),"allow"!==r.status)return r;if("indexeddb"===n.kind){const e=k();if(null===e)return{status:"gated",gate:"gate_unavailable"};const t=c.now();if(!Number.isFinite(t))return{status:"gated",gate:"gate_unavailable"};if(t>=e)return N(),{status:"consent_expired",code:"CONSENT_EXPIRED"}}return E?{status:"gated",gate:"gate_unavailable"}:r}catch{return{status:"gated",gate:"gate_unavailable"}}}function x(){if(O||p||f)return!1;A?.(),A=void 0,O=!0;for(const e of d.values()){e.renewalTimer?.(),e.renewalTimer=void 0,e.mintAbort?.abort();const t=e.handle?.replicaId;t&&!S.has(t)&&(S.add(t),l({type:"replication.grant",replicaId:t,action:"consent_deadline_reached",code:"CONSENT_EXPIRED"}))}return!0}function N(){const e=n.lifecycle;e&&x()&&e.deny({reason:"consent_expired",principal:i.principal}).then(e=>l({type:"replication.lifecycle",action:"denied"===e.status?"denied":"stale"===e.status?"deny_stale":"deleted"===e.status?"database_deleted":"marker"===e.status?"marker_set":"unguarded",reason:"consent_expired"}),()=>l({type:"replication.lifecycle",action:"deny_failed",reason:"consent_expired"}))}function D(e){return Object.assign(new Error("consent_expired"===e.status?"Replica consent expired":"Replica session is gated"),{code:"consent_expired"===e.status?e.code:"REPLICA_GATED",..."gated"===e.status?{gate:e.gate}:{}})}function M(e){return"CONSENT_EXPIRED"===e||"GRANT_EXPIRED"===e?"grant_expired":"REPLICA_GATED"===e?"replica_gated":"replica_error"}function G(e,t,r){if(!(r?.unconstrained&&t.replicaId&&"number"==typeof r.effectiveExpiresAt&&Number.isFinite(r.effectiveExpiresAt)&&(null===r.expiresAt||r.effectiveExpiresAt<r.expiresAt)))return;const n=`${r.cid}:${r.effectiveExpiresAt}`;e.reportedCappedCid!==n&&(e.reportedCappedCid=n,l({type:"replication.grant",replicaId:t.replicaId,action:"capped",effectiveExpiresAt:Ae(r.effectiveExpiresAt)}))}const L=e=>t.prefixes.find(t=>K(t,e));function U(e,t){if("GRANT_REVOKED"!==Pe(t))return;const r=d.get(e)??{};r.authorityRevoked=!0,r.reason="grant_revoked",r.lastError="GRANT_REVOKED",d.set(e,r)}function q(e){const t=d.get(e)??{},r="REPLICATION_ROOT_UNSUPPORTED"!==t.lastError;t.reason="replica_unavailable",t.lastError="REPLICATION_ROOT_UNSUPPORTED",d.set(e,t),r&&l({type:"replication.state",space:s.space,replica:e,state:"unavailable",code:"REPLICATION_ROOT_UNSUPPORTED"})}function j(e){return q(e),Object.assign(new Error("This node doesn't support whole-space sync yet."),{code:"REPLICATION_ROOT_UNSUPPORTED"})}function V(e){try{if(!0!==a.sessionOnly)return;const t=a.sessionGrant(e);return"refused"in t?t.refused:void 0}catch{return"NOT_COVERED"}}async function X(o){const u=C();if("allow"!==u.status)throw D(u);if(p||f)throw Object.assign(new Error("Replication controller is closed"),{code:"REPLICA_CLOSED"});let h=d.get(o);if(h?.handle)return h.handle;if(h?.opening)return h.opening;if(h??(h={}),d.set(o,h),h.unsupported)throw Object.assign(new Error("Replication runtime is unsupported"),{code:"RUNTIME_UNSUPPORTED"});if(void 0!==h.retryAt&&c.now()<h.retryAt)throw Object.assign(new Error("Replica open is backing off"),{code:h.lastError??"REPLICA_UNAVAILABLE"});if(z(s.space,o)&&!t.allowSecrets){const e="SECRETS_OPT_IN_REQUIRED"!==h.lastError;throw h.reason="replica_unavailable",h.lastError="SECRETS_OPT_IN_REQUIRED",e&&l({type:"replication.state",space:s.space,replica:o,state:"unavailable",code:"SECRETS_OPT_IN_REQUIRED"}),Object.assign(new Error("Replication requires allowSecrets for this space or prefix"),{code:"SECRETS_OPT_IN_REQUIRED"})}h.opening=(async()=>{y&&(await y,y=void 0);const d=C();if("allow"!==d.status)throw D(d);const u=!0===a.sessionOnly,g=a.sessionGrant(o),v="refused"in g?void 0:g,E=u?void 0:a.plan(o);let w,_;"refused"in g&&(w=g.refused),E&&"refused"in E&&(w??(w=E.refused)),e.stamp&&null===m&&!u&&(w="REPLICA_GATED"),v&&(_=v.device,h.strategy="session");const A={identity:i,space:s.space,prefix:o,allowSecrets:t.allowSecrets,grantPolicy:b,...R?{quota:R}:{},...e.stamp?{stamp:e.stamp}:{},..._?{device:_}:{},...e.fetch?{fetch:e.fetch}:{},onPeerCommit:e=>{p||f||void 0===h.handle||l({type:"replication.sync",space:s.space,replica:o,trigger:"peer",origin:"peer",outcome:"ok",durationMs:0,lagMs:null,...void 0===e.changes?{}:{changes:e.changes},...void 0===e.coverage?{}:{coverage:e.coverage}})}};if("/"===o&&void 0!==e.nodeFeatures&&!e.nodeFeatures.includes("kv-sync-root"))throw j(o);const P=await n.open(A);h.handle=P;const S=C();if("allow"!==S.status)throw D(S);l({type:"replication.state",space:s.space,replica:o,state:"opened"});const O=u||!E||"refused"in E?void 0:E;let x,N=O||v?await P.grant():void 0;if(N&&!function(t,r){if(!t?.unconstrained)return!1;if(!e.stamp)return!0;if(!r&&null===m)return!1;const i=c.now(),s="indexeddb"===n.kind?k():T??t.consentDeadline;return"active"===t.state&&"number"==typeof t.installedAt&&Number.isFinite(t.installedAt)&&"number"==typeof t.effectiveExpiresAt&&Number.isFinite(t.effectiveExpiresAt)&&"number"==typeof t.consentDeadline&&Number.isFinite(t.consentDeadline)&&"number"==typeof s&&Number.isFinite(s)&&Number.isFinite(i)&&i>=t.installedAt&&(null===t.expiresAt||"number"==typeof t.expiresAt&&Number.isFinite(t.expiresAt)&&i<t.expiresAt)&&i<Math.min(t.effectiveExpiresAt,t.consentDeadline,s)}(N,u)&&(N.unconstrained&&(w=null!==m||u?"GRANT_EXPIRED":"REPLICA_GATED"),N=void 0),v&&null!==m){const e=C();if("allow"!==e.status)throw D(e);N=await P.installGrant(v.ucan)}else if(O){if(!N||!N.unconstrained||N.parentCid!==O.parentCid||null!==N.expiresAt&&O.expiresAt>N.expiresAt+3e5){const e=I(),t=be({now:c.now(),grantTtlMs:b.grantTtlMs,consentDeadline:e??Number.NaN});if(t>0)try{const e=new AbortController;h.mintAbort=e;const r=await a.mint(P.deviceDid,o,e.signal,{expiryMs:t}),n=C();if("allow"!==n.status)throw D(n);N=await P.installGrant(r.ucan),h.strategy="minted",x=t}catch(e){if("CONSENT_EXPIRED"===Pe(e)||"REPLICA_GATED"===Pe(e)||!N?.unconstrained)throw e}finally{h.mintAbort=void 0}}N?.unconstrained&&(h.strategy??(h.strategy="installed"),h.reason=void 0)}else(v||u)&&N?.unconstrained&&(h.strategy="installed");const M=C();if("allow"!==M.status)throw D(M);if(G(h,P,N),void 0!==x&&(h.reportedExpired=!1),void 0!==x&&P.replicaId&&l({type:"replication.grant",replicaId:P.replicaId,action:"minted",expiryMs:x}),N?.unconstrained?l({type:"replication.state",space:s.space,replica:o,state:"grant_installed",strategy:h.strategy}):(h.reason="grant_missing",h.lastError=w??"SESSION_LACKS_SYNC",l({type:"replication.state",space:s.space,replica:o,state:"grant_missing",code:h.lastError})),p||f)throw await P.close(),Object.assign(new Error("Replication controller is closed"),{code:"REPLICA_CLOSED"});return N?.unconstrained&&await F(o,P,N,O),"background"===r&&"grant_missing"!==h.reason&&(Y(o,"start").catch(()=>{}),B(o)),P})();try{return await h.opening}catch(e){const t=Pe(e);throw"CONSENT_EXPIRED"===t&&N(),U(o,e),"REPLICA_GATED"===t||"CONSENT_EXPIRED"===t?h.reason=M(t):"GRANT_REVOKED"!==t&&(h.reason="replica_unavailable"),h.lastError=t,h.failures=(h.failures??0)+1,"RUNTIME_UNSUPPORTED"===t?h.unsupported=!0:"REPLICA_CLOSED"!==t&&"REPLICATION_ROOT_UNSUPPORTED"!==t&&"REPLICA_GATED"!==t&&"CONSENT_EXPIRED"!==t&&(h.retryAt=c.now()+Math.min(3e5,5e3*2**Math.min(h.failures-1,6))),h.handle?.close().catch(()=>{}),h.handle=void 0,e}finally{h.opening=void 0}}function $(e,t,r,n){const i=d.get(e);if(i?.renewalTimer?.(),i&&(i.renewalTimer=void 0),!i||p||f||"session"!==n.path||!a.canRenew)return;const{installedAt:s,effectiveExpiresAt:o}=r,l=I();if(!("number"==typeof s&&Number.isFinite(s)&&"number"==typeof o&&Number.isFinite(o)&&o>s&&null!==l))return;const u=s+.75*(o-s),h=c.now();Number.isFinite(h)&&u<l&&!(h>u)&&(i.renewalTimer=c.setTimeout(()=>{i.renewalTimer=void 0,F(e,t).catch(()=>{})},Math.max(0,Math.floor(u)+1-h)))}async function F(e,t,r,n){const i=d.get(e);if(!i||i.handle!==t||p||f||!a.canRenew)return;if(i.renewing)return i.renewing;if("allow"!==C().status)return;const s=r??await t.grant();if(!s?.unconstrained)return;const{installedAt:o,effectiveExpiresAt:u}=s,h=I();if("number"!=typeof o||!Number.isFinite(o)||"number"!=typeof u||!Number.isFinite(u)||null===h)return;const y=c.now();if(!(({now:e,installedAt:t,effectiveExpiresAt:r,consentDeadline:n})=>!!(Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(n))&&e<n&&r-e<.25*(r-t))({now:y,installedAt:o,effectiveExpiresAt:u,consentDeadline:h}))return void(n&&$(e,t,s,n));let g=n;try{if(!g){const r=a.plan(e);if("refused"in r)return void(t.replicaId&&l({type:"replication.grant",replicaId:t.replicaId,action:"renewal_refused",code:r.refused}));g=r}}catch{return void(t.replicaId&&l({type:"replication.grant",replicaId:t.replicaId,action:"renewal_deferred"}))}if("session"!==g?.path)return void(t.replicaId&&i.reportedRenewalUnqualifiedCid!==s.cid&&(i.reportedRenewalUnqualifiedCid=s.cid,l({type:"replication.grant",replicaId:t.replicaId,action:"renewal_deferred"})));const v=be({now:y,grantTtlMs:b.grantTtlMs,consentDeadline:h});if(!(v>0))return;i.renewalTimer?.(),i.renewalTimer=void 0;const E=new AbortController;i.mintAbort=E;const m=Promise.resolve().then(async()=>{const r=await a.mint(t.deviceDid,e,E.signal,{expiryMs:v,renewalOnly:!0}),n=C();if("allow"!==n.status)throw D(n);const s=await t.installGrant(r.ucan),o=C();if("allow"!==o.status)throw D(o);G(i,t,s),i.reportedExpired=!1,"grant_expired"===i.reason&&(i.reason=void 0),"GRANT_EXPIRED"===i.lastError&&(i.lastError=void 0),t.replicaId&&l({type:"replication.grant",replicaId:t.replicaId,action:"renewed",expiryMs:v}),"number"==typeof s.effectiveExpiresAt&&s.effectiveExpiresAt>u&&$(e,t,s,g)});i.renewing=m;try{await m}catch(e){const r=Pe(e);if("CONSENT_EXPIRED"===r||"REPLICA_GATED"===r)throw e;if(!p&&t.replicaId){const n="object"==typeof e&&null!==e&&"refused"in e&&"string"==typeof e.refused?e.refused:null;l({type:"replication.grant",replicaId:t.replicaId,action:n?"renewal_refused":"renewal_deferred",code:n??r})}}finally{i.renewing=void 0,i.mintAbort===E&&(i.mintAbort=void 0)}}function B(e){const n=d.get(e);!n||"background"!==r||p||f||(n.timer=c.setTimeout(()=>{n.timer=void 0,Y(e,"interval").catch(()=>{}).finally(()=>B(e))},t.syncIntervalMs))}async function Y(t,r,n,i){if("/"===t&&void 0!==e.nodeFeatures&&!e.nodeFeatures.includes("kv-sync-root"))throw j(t);const a=V(t);if(a)throw Object.assign(new Error("Current session does not cover replica sync"),{code:a});const u=await X(t),p=d.get(t);if(p.sync)return p.sync;const f=new AbortController,h=i??{};p.syncContext=h,p.abort=f;const y=()=>{h.abortCause??(h.abortCause="caller"),f.abort(n?.reason)};n?.addEventListener("abort",y,{once:!0});const g=c.now();let E;E=(async()=>{try{const e=(await o.read()).committedEpoch,n=C();if("allow"!==n.status)throw D(n);await F(t,u);const i=C();if("allow"!==i.status)throw D(i);const a=V(t);if(a)throw Object.assign(new Error("Current session does not cover replica sync"),{code:a});const d=await u.sync({signal:f.signal,syncStartEpoch:e}),p=C();if("allow"!==p.status)throw D(p);if("busy"===d.status)return l({type:"replication.sync",space:s.space,replica:t,trigger:r,outcome:"busy",durationMs:c.now()-g,lagMs:null}),d;v.add(t);const h=await o.read(),y=C();if("allow"!==y.status)throw D(y);const E=h.records.some(r=>"committed"===r.state&&null!==r.epoch&&r.epoch<=e&&K(t,r.key))?await o.update(r=>function(e,t,r){const n=e.records.length;return e.records=e.records.filter(e=>!("committed"===e.state&&null!==e.epoch&&e.epoch<=r&&K(t,e.key))),n-e.records.length}(r,t,e)):0,m=C();if("allow"!==m.status)throw D(m);return l({type:"replication.sync",space:s.space,replica:t,trigger:r,outcome:"ok",durationMs:c.now()-g,lagMs:null,pendingCleared:E,pages:d.pages,changes:d.changes,deleted:d.deleted,fetched:d.fetched,contentMissing:d.contentMissing,coverage:d.coverage}),d}catch(e){const n=Pe(e);throw p.lastError=n,U(t,e),"CONSENT_EXPIRED"===n&&N(),l({type:"replication.sync",space:s.space,replica:t,trigger:r,outcome:f.signal.aborted?"aborted":"error",class:"CONSENT_EXPIRED"===n||"REPLICA_GATED"===n?"lifecycle":"NETWORK_ERROR"===n||"TIMEOUT"===n?"offline":"node",code:n,durationMs:c.now()-g,lagMs:null}),e}finally{n?.removeEventListener("abort",y),p.abort=void 0}})(),p.sync=E;try{return await E}finally{p.sync===E&&(p.sync=void 0,p.syncContext=void 0)}}async function J(e,t){let r=()=>{};const n=t.then(e=>({settled:!0,result:e}),e=>({settled:!0,error:e})),i=new Promise(e=>{r=c.setTimeout(()=>e({settled:!1}),Re)});try{const t=await Promise.race([n,i]);return t.settled||l({type:"replication.sync",space:s.space,replica:e,trigger:"stale_read",outcome:"aborted",code:"DRAIN_TIMEOUT",durationMs:Re,lagMs:null}),t}finally{r()}}function Q(e){if("complete"!==e.coverage)throw Object.assign(new Error("Replica coverage changed before the local read"),{code:"COVERAGE_INCOMPLETE"});if("valid"!==e.authority){const t="expired"===e.authority?"GRANT_EXPIRED":"revoked"===e.authority?"GRANT_REVOKED":"GRANT_NOT_YET_VALID";throw Object.assign(new Error("Replica authority changed before the local read"),{code:t})}}function ne(e){return"COVERAGE_INCOMPLETE"===e?"coverage_incomplete":"GRANT_EXPIRED"===e?"grant_expired":"GRANT_REVOKED"===e?"grant_revoked":"GRANT_NOT_YET_VALID"===e?"grant_not_yet_valid":"replica_error"}function ie(e,t,r){if("error"in e){const n=Pe(e.error);return"NETWORK_ERROR"===n||t&&("ABORTED"===n||"TIMEOUT"===n)?{status:r,syncedBeforeRead:!1,syncError:"NETWORK_ERROR"===n?n:"TIMEOUT"}:{status:r,syncedBeforeRead:!1,syncError:n,failure:"error"}}return"busy"===e.result.status?{status:r,syncedBeforeRead:!1,failure:"busy"}:{status:r,syncedBeforeRead:!0}}async function de(e,n,i){let s=await n.status();const a=null===s.lastSyncAt?null:Date.parse(s.lastSyncAt),l=null===a||!Number.isFinite(a)||c.now()-a>t.maxStalenessMs;let u;try{u=await o.read()}catch(e){return{status:s,syncedBeforeRead:!1,syncError:Pe(e),failure:"error"}}const p=s.syncedThroughEpoch<u.committedEpoch,f=!o.durable&&!v.has(e);if((l||p||f)&&!i.aborted){const a="foreground"===r?new AbortController:void 0,o=d.get(e),l=!o?.sync,u=o?.syncContext??{},p=()=>{l&&(u.abortCause??(u.abortCause="caller")),a?.abort(i.reason)};a&&i.addEventListener("abort",p,{once:!0});let f=()=>{};const h=new Promise(e=>{f=c.setTimeout(()=>e({timeout:!0}),t.staleSyncTimeoutMs)});let y=()=>{};const g=new Promise(e=>{if(i.aborted)e({callerAborted:!0});else{const t=()=>e({callerAborted:!0});i.addEventListener("abort",t,{once:!0}),y=()=>i.removeEventListener("abort",t)}}),v=Y(e,"stale_read",a?.signal,u),E=await Promise.race([v.then(e=>({result:e}),e=>({error:e})),h,g]);if(f(),y(),i.removeEventListener("abort",p),"callerAborted"in E)return a&&l&&(u.abortCause??(u.abortCause="caller"),a.abort(i.reason),await J(e,v)),{status:s,syncedBeforeRead:!1,syncError:Se(i)};if("timeout"in E){l&&(u.abortCause??(u.abortCause="timeout"),a?.abort(Object.assign(new Error("Stale-read sync timed out"),{code:"TIMEOUT"})));const t=a?await J(e,v):void 0;if(i.aborted)return{status:s,syncedBeforeRead:!1,syncError:Se(i)};if(t&&!t.settled)return{status:s,syncedBeforeRead:!1,syncError:"DRAIN_TIMEOUT",failure:"error"};try{s=await async function(e,t){let r=()=>{};const n=new Promise((e,t)=>{r=c.setTimeout(()=>t(Object.assign(new Error("Replica status refresh timed out"),{code:"STATUS_TIMEOUT"})),Te)});try{return await ke(Promise.race([e.status(),n]),t)}finally{r()}}(n,i)}catch(e){return i.aborted?{status:s,syncedBeforeRead:!1,syncError:Se(i),failure:"error"}:{status:s,syncedBeforeRead:!1,syncError:Pe(e),failure:"error"}}const r="timeout"===u.abortCause;return ie(t?.settled?"result"in t?{result:t.result}:{error:t.error}:{error:Object.assign(new Error("Stale-read sync timed out"),{code:"TIMEOUT"})},r||!a,s)}return"error"in E?ie({error:E.error},!1,s):"busy"===E.result.status?{status:s,syncedBeforeRead:!1,failure:"busy"}:(s=await n.status(),{status:s,syncedBeforeRead:!0})}return{status:s,syncedBeforeRead:!1}}function ue(e,t,r,n,i,a,o,u={}){null!==r&&"grant_expired"===i&&"CONSENT_EXPIRED"!==u.code&&function(e){const t=d.get(e);if(!t)return;t.reason="grant_expired",t.lastError="GRANT_EXPIRED";const r=t.handle?.replicaId;r&&!t.reportedExpired&&(t.reportedExpired=!0,l({type:"replication.grant",replicaId:r,action:"expired",code:"GRANT_EXPIRED"}))}(r),l({type:"replication.read",op:e,space:s.space,key:t,replica:r,source:n,reason:i,outcome:a,latencyMs:c.now()-o,stalenessMs:null,coverage:null,authority:null,...u})}async function ve(e,t,r,n,i,s,a={}){let o="error";try{const r=await e();return o=r.ok?"found":"get"!==t||"pending_write"!==i&&"not_covered"!==i||r.error.code!==Z?"error":"not_found",r}finally{ue(t,r,n,"network",i,o,s,a)}}async function me(){if(!g){g=!0;try{const e=ce(await o.read(),"",c.now());e.length>0&&l({type:"replication.state",space:s.space,state:"pinned",count:e.length,keys:e.map(e=>e.key)})}catch{l({type:"replication.state",space:s.space,state:"pending_store_error",code:"STORAGE_ERROR"})}}}function Ie(e){l({type:"replication.read",op:e.op,space:e.space,key:e.path,replica:null,source:"network",reason:"NETWORK_REQUESTED",outcome:e.outcome,latencyMs:e.latencyMs,stalenessMs:null,coverage:null,authority:null})}function Ce(){const e=[...u];for(const t of e)t.abort.abort(Object.assign(new Error("Replica status inspection cancelled"),{code:"ABORTED"}));return Promise.all(e.map(e=>e.settled)).then(()=>{})}function xe(e){return t.prefixes.map(t=>({prefix:t,state:"gated",reason:"replica_gated",gate:"gated"===e.status?e.gate:"stamp_stale",errorCode:"consent_expired"===e.status?e.code:"REPLICA_GATED",pending:{inFlight:0,committed:0,ambiguous:0},pinned:[],lagMs:null,redacted:!0}))}return function(){const e=k();if(null===e||O||p)return;const t=c.now();Number.isFinite(t)&&(P===e&&A||(P=e,A?.(),A=c.setTimeout(()=>{A=void 0,C()},Math.max(0,e-t))))}(),{get:async function(e){const r=c.now(),n=L(e.path);if("network"===e.options?.source){let t="error";try{const r=await e.network();return t=r.ok?"found":r.error.code===Z?"not_found":"error",r}finally{Ie({op:"get",space:e.space,path:e.path,reason:"NETWORK_REQUESTED",outcome:t,latencyMs:c.now()-r})}}let i=!1;const s=async(t,n,s={})=>{try{return await ve(e.network,"get",e.path,t,n,r,s)}catch(e){throw i=!0,e}};if(void 0===n)return ve(e.network,"get",e.path,null,"not_covered",r);const a=C();if("allow"!==a.status)return s(n,"consent_expired"===a.status?"grant_expired":"replica_gated",{code:"consent_expired"===a.status?a.code:"REPLICA_GATED"});const u=V(n);if(u)return s(n,"grant_missing",{code:u});try{await ke(me(),e.signal)}catch{if(e.signal.aborted)return Oe(e.signal)}let p,f,h;try{p=await ke(X(n),e.signal)}catch(t){if(e.signal.aborted)return Oe(e.signal);"CONSENT_EXPIRED"===Pe(t)&&N();const r=Pe(t);return s(n,"RUNTIME_UNSUPPORTED"===r?"runtime_unsupported":"CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):"replica_unavailable",{code:r})}if("grant_missing"===d.get(n)?.reason){const e=d.get(n)?.lastError;return s(n,"GRANT_EXPIRED"===e?"grant_expired":"REPLICA_GATED"===e?"replica_gated":"grant_missing",{code:e})}try{f=await de(n,p,e.signal)}catch(t){if(U(n,t),"CONSENT_EXPIRED"===Pe(t)&&N(),e.signal.aborted)return Oe(e.signal);const r=Pe(t);return s(n,"CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):"replica_error",{code:r})}if(e.signal.aborted)return Oe(e.signal);if(f.failure){const e="busy"===f.failure?"REPLICA_BUSY":f.syncError;return s(n,"GRANT_REVOKED"===e?"grant_revoked":"REPLICA_GATED"===e||"CONSENT_EXPIRED"===e||"GRANT_EXPIRED"===e?M(e):"stale",{code:e,syncedBeforeRead:f.syncedBeforeRead})}try{h=await ke(o.read(),e.signal)}catch(t){if(e.signal.aborted)return Oe(e.signal);const r=Pe(t);return s(n,"REPLICA_GATED"===r||"CONSENT_EXPIRED"===r||"GRANT_EXPIRED"===r?M(r):"replica_unavailable",{code:r})}const y=h.records.find(t=>t.key===e.path);if(y)return s(n,"pending_write",{pendingState:y.state,syncedBeforeRead:f.syncedBeforeRead});if(!o.durable&&!v.has(n))return s(n,"REPLICA_UNPROVEN_SINCE_START");if(f.status.syncedThroughEpoch<h.committedEpoch)return s(n,"REPLICA_BEHIND_OWN_WRITES");if("valid"!==f.status.authority.state)return s(n,"expired"===f.status.authority.state?"grant_expired":"revoked"===f.status.authority.state?"grant_revoked":"grant_not_yet_valid");if("complete"!==f.status.coverage)return s(n,"coverage_incomplete");try{const i=await ke(p.get(e.path),e.signal),a=C();if("allow"!==a.status)throw D(a);const o=V(n);if(o)return await s(n,"grant_missing",{code:o});try{Q(i.meta)}catch(e){const t=Pe(e);return U(n,e),await s(n,ne(t),{code:t})}if("coverage_incomplete"===i.status||"not_covered"===i.status||"content_missing"===i.status)return await s(n,"content_missing"===i.status?"content_missing":"coverage_incomplete"===i.status?"coverage_incomplete":"not_covered");if("present"===i.status&&void 0!==e.options?.maxResponseBytes&&i.value.byteLength>e.options.maxResponseBytes)return await s(n,"unsupported_option");const d=function(e,t,r){if("present"===e.status){if(void 0!==r.maxResponseBytes&&e.value.byteLength>r.maxResponseBytes)return te(re("KV_RESPONSE_TOO_LARGE",`KV value at key ${JSON.stringify(t)} exceeds the requested response limit`,"kv",{meta:{status:413}}));const n=Object.entries(e.metadata).find(([e])=>"content-type"===e.toLowerCase())?.[1],i=new Headers({etag:e.etag,"content-length":String(e.value.byteLength),"cache-control":"private, no-cache",...e.metadata,"x-tinycloud-source":"replica"});return ee({data:le(e.value,n,r.raw,r.binary),headers:{etag:e.etag,contentType:n,contentLength:e.value.byteLength,get:e=>i.get(e)}})}return"absent"===e.status||"deleted"===e.status?te(re(Z,`Key not found: ${t}`,"kv")):te(re(H,"Local value is not available","kv"))}(i,e.path,e.options??{}),u="present"===i.status?"hit":i.status,h=null===f.status.lastSyncAt?null:Date.parse(f.status.lastSyncAt),y={syncedBeforeRead:f.syncedBeforeRead,coverage:i.meta.coverage,authority:i.meta.authority,stalenessMs:null===h?null:c.now()-h,...f.syncError?{syncError:f.syncError}:{}};return t.verify?await async function(e,t,r,n,i){const s=L(e.path)??null,a=t.ok,o=!t.ok&&t.error.code===Z,c=a?"found":o?"not_found":"error";try{const d=await ke(e.network(),e.signal);if(e.signal.aborted)return ue("get",e.path,s,"none","aborted","error",n,{...i,verify:"aborted"}),Oe(e.signal);const u=C();if("allow"!==u.status)return ue("get",e.path,s,"network","consent_expired"===u.status?"grant_expired":"replica_gated",d.ok?"found":"error",n,{code:"consent_expired"===u.status?u.code:"REPLICA_GATED"}),d;const p=null===s?void 0:V(s);if(p)return ue("get",e.path,s,"network","grant_missing",d.ok?"found":"error",n,{code:p}),d;if(!d.ok&&d.error.code!==Z)return ue("get",e.path,s,"replica",r,c,n,{...i,code:d.error.code,verify:"error"}),t;const f=d.ok,h=!d.ok&&d.error.code===Z,y=t.ok?t.data.headers.etag??null:null,g=d.ok?d.data.headers.etag??null:null,v=a&&f?y===g:o&&h,E=v?"match":"diverged";return v||l({type:"replication.divergence",op:"get",space:e.space,key:e.path,replica:s??"",kind:a&&f?"value":o?"missing_local":"extra_local",localEtag:y,networkEtag:g,stalenessMs:"number"==typeof i.stalenessMs?i.stalenessMs:null}),ue("get",e.path,s,"replica",r,c,n,{...i,verify:E}),t}catch(a){if(e.signal.aborted)return ue("get",e.path,s,"none","aborted","error",n,{...i,verify:"aborted"}),Oe(e.signal);const o=C();if("allow"!==o.status)return ue("get",e.path,s,"network","consent_expired"===o.status?"grant_expired":"replica_gated","error",n,{code:"consent_expired"===o.status?o.code:"REPLICA_GATED"}),te(se("kv",a));const l=null===s?void 0:V(s);return l?(ue("get",e.path,s,"network","grant_missing","error",n,{code:l}),te(se("kv",a))):(ue("get",e.path,s,"replica",r,c,n,{...i,code:Pe(a),verify:"error"}),t)}}(e,d,u,r,y):(ue("get",e.path,n,"replica",u,d.ok?"found":d.error.code===Z?"not_found":"error",r,y),d)}catch(t){if(i)throw t;return U(n,t),"CONSENT_EXPIRED"===Pe(t)&&N(),e.signal.aborted?Oe(e.signal):s(n,M(Pe(t)),{code:Pe(t)})}},list:async function(e){const r=c.now();if("network"===e.options?.source){let t="error";try{const r=await e.network();return t=r.ok?"found":"error",r}finally{Ie({op:"list",space:e.space,path:e.listPath,reason:"NETWORK_REQUESTED",outcome:t,latencyMs:c.now()-r})}}const n=e.options?.cursor,i=n?.startsWith("tcr1.")?he(n):null;if(n&&n.startsWith("tcr1.")&&!i)return ue("list",e.listPath,null,"none","cursor_restart","error",r),ye();if(n&&!n.startsWith("tcr1."))return ve(e.network,"list",e.listPath,null,"network_cursor",r);const s=ge(t.prefixes,e.listPath);let a=!1;const u=async(t,n,i={})=>{try{return await ve(e.network,"list",e.listPath,t,n,r,i)}catch(e){throw a=!0,e}};if(void 0!==s&&!e.options?.raw){const t=C();if("allow"!==t.status)return i?(ue("list",e.listPath,s,"none","cursor_restart","error",r),ye()):u(s,"consent_expired"===t.status?"grant_expired":"replica_gated",{code:"consent_expired"===t.status?t.code:"REPLICA_GATED"})}if(void 0!==s&&!e.options?.raw){const t=V(s);if(t)return i?(ue("list",e.listPath,s,"none","cursor_restart","error",r),ye()):u(s,"grant_missing",{code:t})}try{await ke(me(),e.signal)}catch{if(e.signal.aborted)return Oe(e.signal)}const p=()=>(ue("list",e.listPath,s??null,"none","cursor_restart","error",r),ye());if(n&&i&&(i.space!==e.space||i.path!==e.listPath))return p();if(void 0===s||e.options?.raw)return n&&i?p():ve(e.network,"list",e.listPath,s??null,void 0!==s?"unsupported_option":"not_covered",r);let f,h,y;try{f=await ke(X(s),e.signal)}catch(t){if(e.signal.aborted)return Oe(e.signal);if("CONSENT_EXPIRED"===Pe(t)&&N(),n&&i)return p();const r=Pe(t);return u(s,"RUNTIME_UNSUPPORTED"===r?"runtime_unsupported":"CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):"replica_unavailable",{code:r})}if("grant_missing"===d.get(s)?.reason){if(n&&i)return p();const e=d.get(s)?.lastError;return u(s,"GRANT_EXPIRED"===e?"grant_expired":"REPLICA_GATED"===e?"replica_gated":"grant_missing",{code:e})}try{h=await de(s,f,e.signal)}catch(t){if(U(s,t),"CONSENT_EXPIRED"===Pe(t)&&N(),e.signal.aborted)return Oe(e.signal);if(n&&i)return p();const r=Pe(t);return u(s,"CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):"replica_error",{code:r})}if(e.signal.aborted)return Oe(e.signal);try{y=await ke(o.read(),e.signal)}catch(t){if(e.signal.aborted)return Oe(e.signal);if(n&&i)return p();const r=Pe(t);return u(s,"REPLICA_GATED"===r||"CONSENT_EXPIRED"===r||"GRANT_EXPIRED"===r?M(r):"replica_unavailable",{code:r})}const g=y.records.find(t=>W(e.listPath,t.key)),E=h.status.syncedThroughEpoch<y.committedEpoch;if(n&&i&&(h.failure||g||E||"complete"!==h.status.coverage||"valid"!==h.status.authority.state||!o.durable&&!v.has(s)))return p();if(E)return u(s,"REPLICA_BEHIND_OWN_WRITES");if(h.failure){const e="busy"===h.failure?"REPLICA_BUSY":h.syncError;return u(s,"GRANT_REVOKED"===e?"grant_revoked":"REPLICA_GATED"===e||"CONSENT_EXPIRED"===e||"GRANT_EXPIRED"===e?M(e):"stale",{code:e})}if(g)return u(s,"pending_write",{pendingState:g.state});if(!o.durable&&!v.has(s))return u(s,"REPLICA_UNPROVEN_SINCE_START");if("complete"!==h.status.coverage||"valid"!==h.status.authority.state)return u(s,"complete"!==h.status.coverage?"coverage_incomplete":"expired"===h.status.authority.state?"grant_expired":"revoked"===h.status.authority.state?"grant_revoked":"grant_not_yet_valid");try{const a={list:t=>ke(f.list(t),e.signal)},d=await ke(function(e,t,r,n,i,s){const a=i?he(i)?.last:void 0,o=""!==r&&!r.endsWith("/")&&(void 0===a||pe(r,a)>0)?async function(e,t,r,n){if(void 0!==r&&pe(t,r)<=0)return!1;const i=await e.list({prefix:t,limit:1});return n(i.meta),i.keys[0]===t}(e,r,a,s):Promise.resolve(!1);return o.then(async i=>{const o=""===r?"":r.endsWith("/")?r:`${r}/`,c=void 0===n?void 0:n+1-(i?1:0),l=await e.list({prefix:o,after:a,limit:c});s(l.meta);let d=(i?[r]:[]).concat(l.keys);const u=void 0!==n&&d.length>n;return u&&(d=d.slice(0,n)),{keys:d,truncated:u,...u?{nextCursor:fe(t,r,d[d.length-1])}:{}}})}(a,e.space,e.listPath,e.options?.limit,n,Q),e.signal),y=await ke(o.read(),e.signal),g=y.records.find(t=>W(e.listPath,t.key));if(n&&i&&(g||h.status.syncedThroughEpoch<y.committedEpoch))return p();if(h.status.syncedThroughEpoch<y.committedEpoch)return await u(s,"REPLICA_BEHIND_OWN_WRITES");if(g)return await u(s,"pending_write",{pendingState:g.state});const v=C();if("allow"!==v.status)throw D(v);const E=V(s);if(E)return i?p():await u(s,"grant_missing",{code:E});const m={count:d.keys.length,syncedBeforeRead:h.syncedBeforeRead,stalenessMs:null===h.status.lastSyncAt?null:c.now()-Date.parse(h.status.lastSyncAt),...h.syncError?{syncError:h.syncError}:{}};return t.verify&&!n?await async function(e,r,n,i){const s=ge(t.prefixes,e.listPath)??null;try{const t=await ke(e.network(),e.signal);if(e.signal.aborted)return ue("list",e.listPath,s,"none","aborted","error",n,{...i,verify:"aborted"}),Oe(e.signal);const a=C();if("allow"!==a.status)return ue("list",e.listPath,s,"network","consent_expired"===a.status?"grant_expired":"replica_gated",t.ok?"found":"error",n,{code:"consent_expired"===a.status?a.code:"REPLICA_GATED"}),t;const o=null===s?void 0:V(s);if(o)return ue("list",e.listPath,s,"network","grant_missing",t.ok?"found":"error",n,{code:o}),t;if(!t.ok)return ue("list",e.listPath,s,"replica","hit","found",n,{...i,code:t.error.code,verify:"error"}),ee(r);const c=new Set(r.keys),d=new Set(t.data.keys),u=r.keys.filter(e=>!d.has(e)),p=t.data.keys.filter(e=>!c.has(e)),f=0===u.length&&0===p.length,h=f&&r.keys.every((e,r)=>e===t.data.keys[r]),y=h?"match":"diverged";return f&&h||l({type:"replication.divergence",op:"list",space:e.space,key:e.listPath,replica:s??"",kind:f?"order":"keys",...f?{}:{localOnly:u,networkOnly:p},stalenessMs:"number"==typeof i.stalenessMs?i.stalenessMs:null}),ue("list",e.listPath,s,"replica","hit","found",n,{...i,verify:y}),ee(r)}catch(t){if(e.signal.aborted)return ue("list",e.listPath,s,"none","aborted","error",n,{...i,verify:"aborted"}),Oe(e.signal);const a=C();if("allow"!==a.status)return ue("list",e.listPath,s,"network","consent_expired"===a.status?"grant_expired":"replica_gated","error",n,{code:"consent_expired"===a.status?a.code:"REPLICA_GATED"}),te(se("kv",t));const o=null===s?void 0:V(s);return o?(ue("list",e.listPath,s,"network","grant_missing","error",n,{code:o}),te(se("kv",t))):(ue("list",e.listPath,s,"replica","hit","found",n,{...i,code:Pe(t),verify:"error"}),ee(r))}}(e,d,r,m):(ue("list",e.listPath,s,"replica","hit","found",r,m),ee(d))}catch(t){if(a)throw t;if(e.signal.aborted)return Oe(e.signal);const r=Pe(t);if("CONSENT_EXPIRED"===r&&N(),U(s,t),n&&i)return p();const o="CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):ne(r);return u(s,o,{code:r})}},write:async function(e){const t=e.entries.flatMap(t=>void 0!==L(t.path)?[{key:t.path,op:"delete"===e.op?"delete":"put"}]:[]);if(0===t.length)return e.network();if("allow"!==C().status)return e.network();if(await me(),"allow"!==C().status)return e.network();const r=globalThis.crypto?.randomUUID?.()??`${c.now()}-${Math.random()}`;try{await o.update(e=>function(e,t,r,n){const i=r.map(({key:r,op:i})=>({opId:t,seq:++e.seq,key:r,op:i,state:"in_flight",epoch:null,at:n,settledAt:null}));return e.records.push(...i),i}(e,r,t,Ae(c.now())))}catch(t){return"REPLICA_GATED"===Pe(t)||"CONSENT_EXPIRED"===Pe(t)||"allow"!==C().status?e.network():te(re("KV_WRITE_FAILED","Unable to persist pending KV write; request was not dispatched","kv",{cause:t instanceof Error?t:void 0,meta:{replication:"pending_store_unavailable",requestDispatched:!1}}))}const n=c.now();let i;try{i=await e.network()}catch(e){const t=se("kv",e);i=te({...t,meta:{...t.meta,requestMayHaveDispatched:!0}})}const s=function(e,t,r={}){if(t.ok)return"committed";const{code:n,meta:i}=t.error;if("delete"===e&&n===Z)return!0===r.conditional?"failed":"committed";if(!1===i?.requestMayHaveDispatched)return"failed";if(ae.has(n))return"failed";if("batch-unconfirmed"===i?.outcome)return"ambiguous";const s="number"==typeof i?.status?i.status:void 0;return void 0!==s&&s>=400&&s<500?"failed":"ambiguous"}(e.op,i,{conditional:!0===e.conditional});let a;try{await o.update(e=>function(e,t,r,n,i){if("failed"===r)return void(e.records=e.records.filter(e=>e.opId!==t));const s=e.records.filter(e=>e.opId===t&&"in_flight"===e.state);if("committed"===r&&s.length>0){const t=++e.committedEpoch;for(const e of s)e.state="committed",e.epoch=t,e.settledAt=n;return}for(const e of s)e.state="ambiguous",e.settledAt=n,i&&(e.code=i)}(e,r,s,Ae(c.now()),i.ok?void 0:i.error.code))}catch(e){a=e}l({type:"replication.write",space:e.space,op:e.op,keys:t.map(e=>e.key),outcome:s,...i.ok?{}:{code:i.error.code},latencyMs:c.now()-n});const d=await o.read().catch(()=>{}),u=d?ce(d,"",c.now()):[];return"ambiguous"===s&&l({type:"replication.state",space:e.space,state:"pinned",count:u.length,keys:u.map(e=>e.key)}),a&&l({type:"replication.state",space:e.space,state:"pending_store_error",code:"STORAGE_ERROR"}),i},observeNetworkRequested:Ie,observeConsentExpired:function(t){e.stamp&&t.incarnation===e.stamp.incarnation&&t.lifecycleEpoch===e.stamp.lifecycleEpoch&&x()&&l({type:"replication.lifecycle",action:"denied",reason:"consent_expired"})},status:async function(){const r=C();if("allow"!==r.status)return xe(r);let l;try{l=o.readExisting?await o.readExisting():await o.read()}catch(e){const t=C();if("allow"!==t.status)return xe(t);throw e}const f=C();if("allow"!==f.status)return xe(f);const y=l??oe(i),g=await Promise.all(t.prefixes.map(async r=>{"/"!==r||void 0===e.nodeFeatures||e.nodeFeatures.includes("kv-sync-root")||q(r);const o=y.records.filter(e=>K(r,e.key)),l=d.get(r);let f;if(l?.handle)try{f=await l.handle.status()}catch{}let g={missing:!1};if(f||l?.opening||l?.authorityRevoked||(g=await async function(r){if(!n.inspectStatus||p||h)return{missing:!1};const o=a.sessionGrant(r),l="refused"in o?void 0:o.device,d={identity:i,space:s.space,prefix:r,allowSecrets:t.allowSecrets,...l?{device:l}:{},...e.fetch?{fetch:e.fetch}:{}},f=new AbortController,y=Promise.resolve().then(()=>n.inspectStatus(d,{signal:f.signal})),g=y.then(()=>{},()=>{}),v={abort:f,settled:g};u.add(v),g.then(()=>u.delete(v));let E=()=>{};const m=new Promise(e=>{E=c.setTimeout(()=>{f.abort(Object.assign(new Error("Replica status inspection timed out"),{code:"STATUS_TIMEOUT"})),e({timedOut:!0})},Te)});try{const e=await Promise.race([y.then(e=>({local:e})),m]);return"timedOut"in e?{missing:!1,errorCode:"STATUS_TIMEOUT"}:{missing:void 0===e.local,...e.local?{local:e.local}:{}}}catch(e){return{missing:!1,errorCode:Pe(e)}}finally{E()}}(r)),f??(f=g.local),g.missing&&!l?.reason&&!l?.authorityRevoked&&!l?.opening&&!p)return;const v=f&&!("redacted"in f)?f:void 0,E=!0===l?.authorityRevoked||"revoked"===v?.authority.state,m=p?"closed":E?"revoked":"REPLICATION_ROOT_UNSUPPORTED"===l?.lastError||"grant_expired"===l?.reason?"unavailable":"grant_missing"===l?.reason?"grant_missing":"complete"===v?.coverage&&"valid"===v.authority.state?"ready":l?.reason||g.errorCode?"unavailable":"idle";return{prefix:r,state:m,...l?.reason?{reason:l.reason}:g.errorCode?{reason:"replica_unavailable"}:{},...g.errorCode??l?.lastError?{errorCode:g.errorCode??l?.lastError}:{},...f??{},...E?{authority:{state:"revoked",expiresAt:v?.authority.expiresAt??null}}:{},pending:{inFlight:o.filter(e=>"in_flight"===e.state).length,committed:o.filter(e=>"committed"===e.state).length,ambiguous:o.filter(e=>"ambiguous"===e.state).length},pinned:ce(y,r,c.now()),lagMs:v?.lastSyncAt?c.now()-Date.parse(v.lastSyncAt):null}})),v=C();return"allow"!==v.status?xe(v):g.filter(e=>void 0!==e)},sync:async function(e){const r=void 0!==e?.prefix?t.prefixes.filter(t=>t===e.prefix):t.prefixes;await Promise.all(r.map(t=>Y(t,"manual",e?.signal).then(()=>{})))},purge:function(e){var r;f=!0,h=!0,A?.(),A=void 0;const p=u.size>0,y=Ce();for(const e of d.values())e.timer?.(),e.timer=void 0,e.renewalTimer?.(),e.renewalTimer=void 0,e.syncContext&&((r=e.syncContext).abortCause??(r.abortCause="purge")),e.abort?.abort(),e.mintAbort?.abort();return Promise.resolve().then(async()=>{const r={purged:[],failed:[]},u=e?.timeoutMs??5e3,f=async e=>{let t=()=>{};const r=new Promise((e,r)=>{t=c.setTimeout(()=>r(Object.assign(new Error("Replication cleanup timed out"),{code:"TIMEOUT"})),u)});try{return await Promise.race([e,r])}finally{t()}},h=Promise.all([...[...d.values()].flatMap(e=>[e.opening?.catch(()=>{}),e.sync?.catch(()=>{}),e.renewing?.catch(()=>{}),e.handle?.close().catch(()=>{})]),...p?[y]:[]]);let g;try{await f(h)}catch(e){g=Pe(e)}const E=t.prefixes.map(async e=>{try{if(g)throw Object.assign(new Error("Replica cleanup did not settle before purge"),{code:g});const t=a.sessionGrant(e),c=d.get(e)?.handle?.deviceDid??("refused"in t?void 0:t.device.did);await f(n.purge({identity:i,space:s.space,prefix:e,...c?{sessionDeviceDid:c}:{}})),await o.update(t=>function(e,t){const r=e.records.length;return e.records=e.records.filter(e=>!K(t,e.key)),r-e.records.length}(t,e)),d.delete(e),v.delete(e),r.purged.push(e),l({type:"replication.state",space:s.space,replica:e,state:"purged"})}catch(t){const n=Pe(t);r.failed.push({prefix:e,code:n}),l({type:"replication.state",space:s.space,replica:e,state:"purge_failed",code:n})}});return await Promise.all(E),r}).finally(()=>{h=!1})},clearPending:async function(){const e=await o.update(e=>function(e,t){const r=e.records.length;return e.records=e.records.filter(e=>"committed"===e.state||"in_flight"===e.state&&t-Date.parse(e.at)<=6e5),r-e.records.length}(e,c.now()));return l({type:"replication.state",space:s.space,state:"pending_cleared",count:e}),e},close:async function(){var e;if(p)return;p=!0,A?.(),A=void 0;const t=u.size>0,r=Ce();for(const[t,r]of d)r.timer?.(),r.timer=void 0,r.renewalTimer?.(),r.renewalTimer=void 0,r.mintAbort?.abort(),r.syncContext&&((e=r.syncContext).abortCause??(e.abortCause="close")),r.abort?.abort(),l({type:"replication.state",space:s.space,replica:t,state:"closed"});const n=Promise.all([...[...d.values()].map(async e=>{await(e.opening?.catch(()=>{})),await(e.renewing?.catch(()=>{})),await(e.sync?.catch(()=>{})),await(e.handle?.close().catch(()=>{}))}),...t?[r]:[]]);let i=()=>{},a=!1;n.then(()=>{a=!0,i()},()=>{a=!0,i()});const o=new Promise(e=>{queueMicrotask(()=>{a||(i=c.setTimeout(e,Re))})});try{await Promise.race([n,o])}finally{i()}}}}function Se(e){return se("kv",e.reason).code===Y||"object"==typeof e.reason&&null!==e.reason&&"code"in e.reason&&e.reason.code===Y?Y:J}function Oe(e){const t=Se(e);return te(re(t,t===Y?"KV request timed out":"KV request was aborted","kv"))}function Ce(e){const t=F(e),r=B(t);let n=oe(t),i=Promise.resolve();return{identity:t,durable:!1,read:async()=>structuredClone(n),async update(e){let t,s;const a=new Promise((e,r)=>{t=e,s=r}),o=i.then(()=>{try{if(B(n.identity)!==r)throw Object.assign(new Error("Pending-store identity mismatch"),{code:"STORAGE_ERROR"});const i=structuredClone(n),s=e(i);n=i,t(s)}catch(e){s(e)}});return i=o.then(()=>{},()=>{}),a}}}}},i={};function s(e){var t=i[e];if(void 0!==t)return t.exports;var r=i[e]={exports:{}};return n[e](r,r.exports,s),r.exports}s.d=(e,t)=>{for(var r in t)s.o(t,r)&&!s.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var a={};s.d(a,{U:()=>d,r:()=>c});var o=s(461);async function c(){const{indexedDbReplicaStorage:e}=await Promise.resolve().then(s.bind(s,913));return e}const l=s(204).assertValidReplicationConfig,d=Object.freeze({validateConfig:l,loaders:Object.freeze({validateConfig:l,runtime:()=>Promise.resolve().then(s.bind(s,230)),authority:()=>Promise.resolve().then(s.bind(s,204)),gatedNetwork:()=>Promise.resolve().then(s.bind(s,442)),gate:()=>Promise.resolve().then(s.bind(s,435))}),recover:async function(e,t){const r=e.storage,n="indexeddb"===r.kind?r.lifecycle:void 0;if("indexeddb"!==n?.kind)return e;const i=(t,r)=>{try{const n={type:"replication.lifecycle",at:(new Date).toISOString(),action:"unguarded",reason:"startup",gate:"gate_unavailable",code:t};void 0!==r&&(n.remaining=r),e.onEvent?.(n)}catch{}},s=e=>null!==e&&0===e.failed.length&&0===e.remaining,a=(e,t)=>{let r;return Promise.race([e.then(()=>{},()=>{}),new Promise(e=>{r=setTimeout(()=>{t?.abort(),e()},3e3)})]).finally(()=>clearTimeout(r))};let c,l=!1,d=0,u=0,p=void 0===t?"wallet_provider_required":"gate_unavailable";const f=async e=>{const t=await n.recover(e);return l=s(t),l||(c=void 0,d++),t},h=()=>{const e=new AbortController;return a(f({signal:e.signal}),e)};let y;const g=e=>{const t=e().catch(()=>{}).finally(()=>{y===t&&(y=void 0)});return y=t,t},v=new AbortController;let E,m=!1;const w=(async()=>n.recover({signal:v.signal}))().catch(()=>null).then(e=>E=e);g(async()=>{const e=await w;m&&(s(e)?await h():i(e?.failed[0]?.code??(e?"RECOVERY_INCOMPLETE":"STORAGE_ERROR"),e?.remaining))}),await a(w,v),m=void 0===E,E&&(l=s(E)),l||i(E?.failed[0]?.code??(m?"RECOVERY_TIMEOUT":"STORAGE_ERROR"),E?.remaining);const _=()=>Object.assign(new Error("Replica wallet or startup recovery is unavailable."),{code:"REPLICA_GATED",gate:l?p:"gate_unavailable"}),b=()=>Promise.reject(_()),R=()=>{throw _()},T=async e=>{const r=(0,o.__replicaParsePkhDid)(e)?.address,n=await(t?.getConnectedAddress().catch(()=>{}));return p=void 0===t?"wallet_provider_required":n?"principal_mismatch":"gate_unavailable",void 0!==r&&void 0!==n&&r.toLowerCase()===n.toLowerCase()},A=async()=>{const e=c;if(!l||!e)throw _();if(!await T(e)||c!==e)throw c=void 0,_()},P=async(e,t)=>{const r=++d;if(c=void 0,!l&&y&&await a(y),!l&&!y&&u<2&&(u++,await g(h)),!l||!await T(e)||r!==d)throw _();const n=await t();if(r!==d)throw _();if(c=e,await A(),r!==d)throw _();return n},k=(e,t,r)=>{if(r.has(t))return r.get(t);const n=Reflect.get(e,t,e);if("function"!=typeof n)return n;const i=n.bind(e);return r.set(t,i),i},I=new Map,S=new Proxy(n,{get(e,t){if("recover"===t)return f;if("establishSessionStamp"===t)return(...t)=>P(t[0],()=>e.establishSessionStamp(...t));if("restoreSessionStamp"===t)return(...t)=>P(t[0],()=>e.restoreSessionStamp(...t));if("deny"===t)return(...t)=>(d++,c=void 0,e.deny(...t));if(!l||!c){if("activationAllowed"===t)return()=>Promise.resolve(!1);if("checkDelivery"===t)return()=>({status:"gated",gate:l?p:"gate_unavailable"});if("deliverable"===t)return()=>!1;if("consentDeadline"===t)return()=>null}return k(e,t,I)}}),O=new Map,C=new Proxy(r,{get(e,t){if("lifecycle"===t)return S;if("open"===t)return async(...t)=>{await A();const r=await e.open(...t);try{await A()}catch(e){throw await r.close().catch(()=>{}),e}const n=new Map,i=async(...e)=>{await A();const t=await r.get(...e);return await A(),t},s=async(...e)=>{await A();const t=await r.list(...e);return await A(),t};return new Proxy(r,{get:(e,t)=>"get"===t?i:"list"===t?s:k(e,t,n)})};if(!l||!c){if("inspectStatus"===t)return b;if("pendingWrites"===t)return R}return k(e,t,O)}});return{...e,storage:C}}}),u=a.U,p=a.r;export{u as browserReplicaPlugin,p as loadIndexedDbReplicaStorage};
1
+ import*as e from"@tinycloud/web-sdk";import*as t from"@tinycloud/web-sdk/replica-gated";import{parseUcanGrant as r}from"@tinycloud/replica";var n={913(e){e.exports=import("@tinycloud/replica/kv-storage")},435(e){e.exports=import("@tinycloud/replica/profile-gate")},461(t,r,n){var i,s;t.exports=(i={__replicaActionContains:()=>e.__replicaActionContains,__replicaCanonicalizeRecapCaveats:()=>e.__replicaCanonicalizeRecapCaveats,__replicaIsCapabilitySubset:()=>e.__replicaIsCapabilitySubset,__replicaKV:()=>e.__replicaKV,__replicaParsePkhDid:()=>e.__replicaParsePkhDid,__replicaParseSpaceUri:()=>e.__replicaParseSpaceUri,__replicaPkhDid:()=>e.__replicaPkhDid,__replicaPrincipalDid:()=>e.__replicaPrincipalDid,__replicaSiweMessage:()=>e.__replicaSiweMessage},s={},n.d(s,i),s)},442(e){e.exports=t},204(e,t,n){n.d(t,{AUTHORITY_EXPIRY_MARGIN_MS:()=>O,assertRenewalParent:()=>x,assertValidReplicationConfig:()=>c,augmentSignInEntriesWithReplication:()=>f,createReplicationAuthority:()=>N,eraseReplicaLocalCopy:()=>v,establishReplicaSessionStamp:()=>b,hasUnrestrictedGetCoverage:()=>p,mintNodeReplicationGrant:()=>S,replicationScopeFromSignedSession:()=>C,reportReplicaDenial:()=>y,restoreReplicaSessionStamp:()=>R,ucanAttCovers:()=>k,ucanAttUnconstrainedFor:()=>I,verifiedOwnerConsentAnchor:()=>_}),n.r(t);var i=n(461);function s(e,t){return"/"===e||t.startsWith(e)}function a(e){const t="string"==typeof e&&e.length>0&&!e.startsWith("/")&&!e.includes("//")&&e.endsWith("/");if("/"!==e&&!t){const t="string"==typeof e?e.replace(/^\/+/,"").replace(/\/+$/,""):"",r=t.length>0&&!t.includes("//")?` Use ${JSON.stringify(`${t}/`)}.`:' Use "/" or a slash-terminated folder path such as "notes/".';throw new TypeError(`Replication prefix must be "/" or a non-empty slash-terminated folder path without empty segments.${r}`)}}var o=n(191);function c(e){if(void 0!==e?.syncScope&&"prefixes"!==e.syncScope)throw new TypeError('replication.syncScope must be "prefixes"');if(void 0!==e?.contentFetch&&"eager"!==e.contentFetch&&"lazy"!==e.contentFetch)throw new TypeError('replication.contentFetch must be "eager" or "lazy"');if(void 0===e||!e.enabled)return;if(void 0===e.storage||null===e.storage)throw new TypeError("replication.enabled requires replication.storage");if(!Array.isArray(e.prefixes)||0===e.prefixes.length)throw new TypeError("replication.prefixes must be a non-empty array");const t=e.grantTtlMs;if(void 0!==t&&(!Number.isFinite(t)||t<=0||t>6048e5))throw new TypeError("replication.grantTtlMs must be a positive number of milliseconds no greater than 604800000");for(const t of e.prefixes)try{a(t)}catch(e){throw new TypeError(e instanceof Error?e.message:String(e))}for(const[t,r]of e.prefixes.entries()){for(const n of e.prefixes.slice(t+1))if(s(r,n)||s(n,r))throw new TypeError(`replication.prefixes must not overlap: ${JSON.stringify(r)} and ${JSON.stringify(n)}`);if(("/"===r||"vault"===r.split("/",1)[0])&&!0!==e.allowSecrets)throw new TypeError(`replication prefix ${JSON.stringify(r)} overlaps the vault namespace; pass allowSecrets to opt in`)}}var l=i.__replicaKV.GET,d=i.__replicaKV.SYNC,u="tinycloud.kv";function p(e,t,r){return(0,i.__replicaIsCapabilitySubset)([{service:u,space:t,path:r,actions:[l]}],[...e]).subset}function f(e){const t=[],r=e.replication;if(void 0===r)return t;const n=[];for(const t of r.prefixes){a(t);const i="/"===t?"":t;(0,o.requiresSecretsOptIn)(e.primarySpaceId,t)&&!0!==r.allowSecrets||p(e.entries,e.primarySpaceId,i)&&n.push(i)}if("prefixes"!==r.syncScope&&n.length===r.prefixes.length&&n.length>0&&p(e.entries,e.primarySpaceId,""))return[{service:u,space:e.primarySpaceId,path:"",actions:[l,d]}];for(const r of n)t.push({service:u,space:e.primarySpaceId,path:r,actions:[l,d]});return t}var h=r;function y(e,t,r,n){if("denied"!==e.status&&"deleted"!==e.status&&"marker"!==e.status)return;const i={type:"replication.lifecycle",at:(new Date).toISOString(),reason:t,action:"denied"===e.status?"denied":"deleted"===e.status?"database_deleted":"marker_set",..."denied"===e.status?{partitions:e.intents}:{},..."marker"===e.status?{code:e.code}:{}};try{r?.(i)}catch{}const{type:s,...a}=i;try{n?.emit(s,a)}catch{}}var g=[150,450];async function v(e,t,r,n){if("indexeddb"!==e?.kind||void 0===e.eraseLocalCopy)return;let i={status:"failed",code:"STORAGE_ERROR",marker:!1};for(let t=0;t<=g.length;t++){t>0&&await new Promise(e=>setTimeout(e,g[t-1]));try{i=await e.eraseLocalCopy({signal:AbortSignal.timeout(3e3)})}catch{i={status:"failed",code:"STORAGE_ERROR",marker:!1}}if("failed"!==i.status)break}const s="marker"===r||"unguarded"===r,a="erased"===i.status?{ok:!0}:{ok:!1,retryNow:"failed"===i.status};if("erased"===i.status||"refused"===i.status&&!s)return{outcome:i,purge:a};const o="failed"===i.status&&i.marker,c={type:"replica.purge.failed",trigger:t,reason:o?"logout_pending":"gate_unavailable",code:i.code,retryNow:"failed"===i.status};for(const e of n)try{e(c)}catch(e){console.error('Error in "replica.purge.failed" handler:',e)}return o?{outcome:i,purge:a,logoutPending:o}:{outcome:i,purge:a}}var E=i.__replicaKV.GET,m=i.__replicaKV.SYNC,w="tinycloud.kv";function _(e,t,r){if("string"!=typeof e.siwe||"string"!=typeof e.signature||"string"!=typeof e.address||"number"!=typeof e.chainId)return null;try{const n=t.validatePersistedSession?.({delegationHeader:e.delegationHeader,delegationCid:e.delegationCid,spaceId:e.spaceId,jwk:e.jwk,address:e.address,chainId:e.chainId,siwe:e.siwe,signature:e.signature});if(!n||!Number.isSafeInteger(Date.parse(n.expiresAt??"")))return null;const s=new i.__replicaSiweMessage(e.siwe).issuedAt;if("string"!=typeof s)return null;const a=Date.parse(s);if(!Number.isSafeInteger(a)||a<0)return null;const o=r(n).filter(t=>t.space===e.spaceId&&"kv"===t.service).map(e=>({...e,service:"tinycloud.kv"}));return o.some(t=>(0,i.__replicaIsCapabilitySubset)([{service:"tinycloud.kv",space:e.spaceId,path:t.path,actions:[i.__replicaKV.GET,i.__replicaKV.SYNC]}],o).subset)?{at:a,source:"siwe"}:null}catch{return null}}function b(e,t,r){if("indexeddb"===e.kind&&"indexeddb"===e.lifecycle?.kind)return e.lifecycle.establishSessionStamp(t,{consentAnchor:r});if("sqlite"===e.kind&&"file"===e.lifecycle?.kind)return e.lifecycle.establishSessionStamp(t,{consentAnchor:r});throw Object.assign(new Error("Replica sign-in requires its platform lifecycle gate."),{code:"REPLICA_GATED",gate:"gate_unavailable"})}function R(e,t,r){if("indexeddb"===e.kind&&"indexeddb"===e.lifecycle?.kind)return e.lifecycle.restoreSessionStamp(t,r);if("sqlite"===e.kind&&"file"===e.lifecycle?.kind)return e.lifecycle.restoreSessionStamp(t,r);throw Object.assign(new Error("Replica restore requires its platform lifecycle gate."),{code:"REPLICA_GATED",gate:"gate_unavailable"})}function T(e,t){return[{service:w,space:e,path:"/"===t?"":t,actions:[E,m]}]}function A(e){if(null==e)return!0;if("object"==typeof e&&!Array.isArray(e)&&0===Object.keys(e).length)return!0;if(!Array.isArray(e))return!1;try{return(0,i.__replicaCanonicalizeRecapCaveats)(e)===(0,i.__replicaCanonicalizeRecapCaveats)(void 0)}catch{return!1}}function P(e,t){for(const r of[`${t}/kv`,`tinycloud://${t}/kv`])if(e===r||e===`${r}/`)return"/";for(const r of[`${t}/kv/`,`tinycloud://${t}/kv/`])if(e.startsWith(r))return e.slice(r.length)}function k(e,t,r,n,s){for(const[a,o]of Object.entries(e)){const e=P(a,t);if(void 0!==e)for(const[a,c]of Object.entries(o))if((0,i.__replicaActionContains)(a,n)&&(0,i.__replicaIsCapabilitySubset)([{service:w,space:t,path:r,actions:[n]}],[{service:w,space:t,path:e,actions:[a]}]).subset&&(!0===s?.ignoreCaveats||A(c)))return!0}return!1}function I(e,t,r){return k(e,t,r,E)&&k(e,t,r,m)}async function S(e,t,r,n,s){if(r?.renewalOnly&&!n)throw new Error("replication renewal lost its owner session");const a=r?.renewalOnly?{expiry:r.expiryMs,onPrepared:async e=>{x(e.delegationHeader.Authorization,n)}}:void 0===r?.expiryMs?void 0:{expiry:r.expiryMs},o=await s.delegateTo((0,i.__replicaPrincipalDid)(e),t,a);return{ucan:o.delegation.delegationHeader.Authorization,expiresAt:o.delegation.expiry.getTime()}}var O=6e4;function C(e){let t;try{t=h(e.delegationHeader.Authorization)}catch{return}const r=e=>e.split("#",1)[0];if(t.cid===e.delegationCid&&r(t.audience)===r(e.verificationMethod))for(const r of Object.keys(t.att)){const t=r.match(/^(?:tinycloud:\/\/)?(.+?)\/kv(?:\/|$)/)?.[1];if(t!==e.persistedSpace)continue;const n=(0,i.__replicaParseSpaceUri)(t);if(n?.owner&&n.address&&n.chainId)return{space:t,principal:n.owner}}}function x(e,t){const r=h(e);if(r.issuer!==t.verificationMethod.split("#",1)[0]||1!==r.prf.length||r.prf[0]!==t.delegationCid)throw Object.assign(new Error("replication renewal requires the bound owner session parent"),{refused:"NOT_COVERED"})}function N(e){const t=e.replicationSession();let r=null;try{const n=t&&e.verifiedConsentAnchor?.(t);n&&Number.isFinite(n.at)&&"first_install"!==n.source&&(r={at:n.at,source:n.source})}catch{}const n=()=>{const r=e.replicationSession();return void 0!==r&&r===t?r:void 0},i=(t,r)=>{const n=e.planDelegation(t,void 0===r?void 0:{expiry:r});return"refused"in n?n:{path:n.path,parentCid:n.parentCid,expiresAt:n.expiresAt}},s=e=>e.split("#",1)[0],a=e=>{const t=h(e.delegationHeader.Authorization);if(t.cid===e.delegationCid&&s(t.audience)===s(e.verificationMethod))return t},o={get sessionOnly(){const e=n();return void 0===e||void 0===e.siwe},consentAnchor:()=>n()?r:null,get canRenew(){const e=n();return"siwe"===r?.source&&void 0!==e&&void 0!==e.siwe},sessionGrant(t){const i=n();if(void 0===i)return{refused:"SESSION_EXPIRING"};if(null===r&&void 0!==i.siwe)return{refused:"NOT_COVERED"};const s=i.siwe?e.siweExpiration(i.siwe)?.getTime():void 0;if(void 0!==s&&s<=Date.now()+O)return{refused:"SESSION_EXPIRING"};let o;try{const e=a(i);if(!e)return{refused:"NOT_COVERED"};o=e}catch{return{refused:"NOT_COVERED"}}const c=null===o.expiresAt?void 0:1e3*o.expiresAt;return void 0===c||c<=Date.now()+O?{refused:"SESSION_EXPIRING"}:k(o.att,i.spaceId,t,E,{ignoreCaveats:!0})&&k(o.att,i.spaceId,t,m,{ignoreCaveats:!0})?I(o.att,i.spaceId,t)?{ucan:o.jwt,device:{did:i.verificationMethod,jwk:i.jwk}}:{refused:"CAVEATED_AUTHORITY"}:{refused:"NOT_COVERED"}},plan(e){const t=n();if(void 0===t)return{refused:"SESSION_EXPIRING"};if(null===r)return{refused:"NOT_COVERED"};const s=this.sessionGrant(e);if(!("refused"in s)){const e=a(t);return e&&null!==e.expiresAt?{path:"session",parentCid:t.delegationCid,expiresAt:1e3*e.expiresAt}:{refused:"NOT_COVERED"}}return o.sessionOnly?s:i(T(t.spaceId,e))},async mint(t,s,a,o){const c=n();if(void 0===c)throw new Error("replication mint without the bound session");if(void 0===c.siwe)throw new Error("compact delegate sessions cannot mint device grants");if("siwe"!==r?.source)throw new Error("replication mint requires verified owner consent");const l=T(c.spaceId,s),d=i(l,o?.expiryMs);if("refused"in d)throw Object.assign(new Error(`replication authority refused the mint: ${d.refused}`),{refused:d.refused});if(o?.renewalOnly&&"session"!==d.path)throw Object.assign(new Error("replication renewal requires a session parent"),{refused:"NOT_COVERED"});a.throwIfAborted();const u=await new Promise((r,n)=>{const i=()=>n(a.reason??new Error("replication mint aborted"));a.addEventListener("abort",i,{once:!0}),e.mintDelegation(t,l,o).then(e=>{a.removeEventListener("abort",i),r(e)},e=>{a.removeEventListener("abort",i),n(e instanceof Error?e:new Error(String(e)))})});return{ucan:u.ucan,parentCid:d.parentCid,expiresAt:u.expiresAt}}};return o}},230(e,t,r){r.r(t),r.d(t,{ReplicationRuntime:()=>s});var n=r(461),i={now:()=>Date.now(),setTimeout(e,t){const r=setTimeout(e,t);return r.unref?.(),()=>clearTimeout(r)}},s=class{constructor(e,t=i){this.options=e,this.clock=t,this.pending=new Map,this.attached=new Map,this.previous=Promise.resolve(),this.binding=Promise.resolve(),this.generation=0,this.bindingActive=!1,this.pendingPurgeSet=!1,this.closed=!1,this.control={status:async()=>(await this.binding,this.gatedReason?this.options.prefixes.map(e=>({prefix:e,state:"gated",gate:this.gatedReason,errorCode:"REPLICA_GATED",pending:{inFlight:0,committed:0,ambiguous:0},pinned:[],lagMs:null})):this.current?this.current.status():[]),sync:async e=>{if(await this.binding,this.gatedReason)throw Object.assign(new Error("Replica restore is gated."),{code:"REPLICA_GATED",gate:this.gatedReason});this.purgedGeneration!==this.generation&&this.current&&await this.current.sync(e)},purge:e=>{if(this.bindingActive){this.pendingPurge=e,this.pendingPurgeSet=!0;const t=this.current??this.lastController;return t&&(this.pendingPurgeResult=t.purge(e),this.purgedGeneration=this.generation),this.binding.then(()=>this.pendingPurgeResult??{purged:[],failed:[]})}const t=this.current??this.lastController;return t?(this.purgedGeneration=this.generation,t.purge(e)):Promise.resolve({purged:[],failed:[]})},clearPending:async()=>{if(await this.binding,this.current)return this.current.clearPending();const e=this.lastPending;return e?e.update(e=>{const t=e.records.length;return e.records=e.records.filter(e=>"committed"===e.state||"in_flight"===e.state&&this.clock.now()-Date.parse(e.at)<=6e5),t-e.records.length}):0},close:async()=>{this.closed=!0,this.unbind(),await this.binding.catch(()=>{}),await this.previous}}}loadServices(){return this.services??(this.services=Promise.resolve().then(r.bind(r,191)))}detachAll(){for(const e of this.attached.keys())e.setReadThrough(null);this.attached.clear()}bindGatedNetworkOnly(e,t){if(this.closed||!this.options.enabled)return Promise.resolve();const r=this.unbind(),n=this.generation;return this.purgedGeneration=void 0,this.pendingPurge=void 0,this.pendingPurgeResult=void 0,this.pending.clear(),this.lastController=void 0,this.lastPending=void 0,this.lastIdentity=void 0,this.gatedReason=e.gate,this.primarySpace=e.session.spaceId,this.binding=r.then(async()=>{let r;try{({createGatedNetworkReadThrough:r}=await t())}catch{return}if(n!==this.generation||this.closed||"function"!=typeof r)return;const i=r({space:e.session.spaceId,prefixes:this.options.prefixes,now:()=>this.clock.now(),emit:t=>{if(n!==this.generation||this.closed||this.gated!==i)return;try{this.options.onEvent?.(t)}catch{}const{type:r,...s}=t;try{e.context.emit(r,s)}catch{}}});this.gated=i;for(const t of e.primaryKV)this.attach(t.space,t.kv)}),this.binding}bind(e){if(this.closed||!this.options.enabled)return Promise.resolve();this.gated=void 0,this.gatedReason=void 0,this.bindingActive=!0;const t=++this.generation;this.purgedGeneration=void 0,this.unsubscribeConsentExpired?.(),this.unsubscribeConsentExpired=void 0;const{context:r,session:i}=e,s=e=>{try{this.options.onEvent?.(e)}catch{}const{type:t,...n}=e;r.emit(t,n)},a=this.current;this.current=void 0;for(const e of this.attached.keys())e.setReadThrough(null);this.primarySpace=i.spaceId;const o=a?a.close().catch(()=>{}):Promise.resolve();this.previous=this.previous.then(()=>o);const c=this.previous;this.binding=this.loadServices().then(a=>{if(t!==this.generation||this.closed)return;let o;try{o=a.canonicalReplicationIdentity({host:r.hosts[0],space:i.spaceId,principal:e.principal??(0,n.__replicaPkhDid)(e.address,e.chainId)})}catch{for(const e of this.options.prefixes)s({type:"replication.state",at:new Date(this.clock.now()).toISOString(),space:i.spaceId,replica:e,state:"unavailable",code:"CONFIG_INVALID"});return}const l=a.replicationIdentityKey(o);let d=this.pending.get(l);const u=e.stamp;if(!d||d.stamp?.incarnation!==u?.incarnation||d.stamp?.lifecycleEpoch!==u?.lifecycleEpoch){const e=this.options.storage.pendingWrites?.(o,{stamp:u});if(!e&&this.options.storage.lifecycle)throw Object.assign(new Error("Gated replication requires a stamped pending store"),{code:"REPLICA_GATED",gate:"gate_unavailable"});d={stamp:u,store:e??a.createMemoryPendingStore(o)},this.pending.set(l,d)}const p=d.store;this.lastPending=p;const f=a.createKVReplication({options:(h=this.options,{...h,syncIntervalMs:h.syncIntervalMs??6e4,maxStalenessMs:h.maxStalenessMs??12e4,staleSyncTimeoutMs:h.staleSyncTimeoutMs??5e3,allowSecrets:!0===h.allowSecrets,contentFetch:h.contentFetch??"eager",verify:!0===h.verify}),mode:this.options.mode??"background",storage:this.options.storage,identity:o,session:{id:i.delegationCid,did:i.verificationMethod,space:i.spaceId},stamp:e.stamp,authority:e.authority,pending:p,scheduler:this.clock,emit:s,fetch:r.fetch,nodeFeatures:e.nodeFeatures,previous:c});var h;this.current=f,this.unsubscribeConsentExpired=this.options.storage.lifecycle?.subscribeConsentExpired?.(e=>f.observeConsentExpired(e)),this.lastController=f,this.lastIdentity=o;for(const[e,t]of this.attached)e.setReadThrough(t===this.primarySpace?f:null);for(const t of e.primaryKV)this.attach(t.space,t.kv);this.pendingPurgeSet&&(this.pendingPurgeResult=f.purge(this.pendingPurge),this.purgedGeneration=t,this.pendingPurge=void 0,this.pendingPurgeSet=!1)}).finally(()=>{t===this.generation&&(this.bindingActive=!1)});for(const e of this.attached.keys())e.setReadThroughReady?.(this.binding);return this.binding}attach(e,t){this.attached.set(t,e),t.setReadThrough(e===this.primarySpace?this.current??this.gated??null:null);const r=this.generation;return this.binding.then(()=>{r!==this.generation||this.closed||this.attached.get(t)!==e||t.setReadThrough(e===this.primarySpace?this.current??this.gated??null:null)})}unbind(){this.generation++,this.bindingActive=!1,this.pendingPurgeSet=!1,this.unsubscribeConsentExpired?.(),this.unsubscribeConsentExpired=void 0;const e=this.current;this.current=void 0,this.gated=void 0,this.gatedReason=void 0,this.primarySpace=void 0,this.detachAll();const t=this.binding.then(()=>e?.close()).catch(()=>{});return this.previous=this.previous.then(()=>t),this.previous}get boundIdentity(){return this.lastIdentity}}},191(e,t,r){r.d(t,{CLEAR_PENDING_WARNING:()=>j,canonicalReplicationIdentity:()=>$,createKVReplication:()=>Ie,createMemoryPendingStore:()=>Ce,kvPrefixCovers:()=>K,replicationIdentityKey:()=>B,requiresSecretsOptIn:()=>z}),r.r(t);var n=[{urn:"tinycloud.kv/get",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/list",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/metadata",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/put",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/del",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/delete",service:"tinycloud.kv",status:"deprecated-alias",aliasOf:"tinycloud.kv/del"},{urn:"tinycloud.kv/sync",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.kv/retain",service:"tinycloud.kv",status:"active"},{urn:"tinycloud.sql/read",service:"tinycloud.sql",status:"active"},{urn:"tinycloud.sql/select",service:"tinycloud.sql",status:"deprecated-alias",aliasOf:"tinycloud.sql/read"},{urn:"tinycloud.sql/write",service:"tinycloud.sql",status:"active"},{urn:"tinycloud.sql/schema",service:"tinycloud.sql",status:"active"},{urn:"tinycloud.sql/admin",service:"tinycloud.sql",status:"active",implies:["tinycloud.sql/schema"]},{urn:"tinycloud.sql/*",service:"tinycloud.sql",status:"active",implies:["tinycloud.sql/read","tinycloud.sql/write","tinycloud.sql/schema","tinycloud.sql/admin"]},{urn:"tinycloud.duckdb/read",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/write",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/admin",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/import",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/export",service:"tinycloud.duckdb",status:"active"},{urn:"tinycloud.duckdb/select",service:"tinycloud.duckdb",status:"deprecated-alias",aliasOf:"tinycloud.duckdb/read"},{urn:"tinycloud.duckdb/*",service:"tinycloud.duckdb",status:"active",implies:["tinycloud.duckdb/read","tinycloud.duckdb/write","tinycloud.duckdb/admin","tinycloud.duckdb/import","tinycloud.duckdb/export"]},{urn:"tinycloud.capabilities/read",service:"tinycloud.capabilities",status:"active"},{urn:"tinycloud.delegation/status",service:"tinycloud.delegation",status:"active"},{urn:"tinycloud.delegation/list",service:"tinycloud.delegation",status:"active"},{urn:"tinycloud.hooks/subscribe",service:"tinycloud.hooks",status:"active"},{urn:"tinycloud.hooks/register",service:"tinycloud.hooks",status:"active"},{urn:"tinycloud.hooks/list",service:"tinycloud.hooks",status:"active"},{urn:"tinycloud.hooks/unregister",service:"tinycloud.hooks",status:"active"},{urn:"tinycloud.encryption/decrypt",service:"tinycloud.encryption",status:"active"},{urn:"tinycloud.encryption/network.create",service:"tinycloud.encryption",status:"active"},{urn:"tinycloud.encryption/network.revoke",service:"tinycloud.encryption",status:"active"},{urn:"tinycloud.space/host",service:"tinycloud.space",status:"active"},{urn:"tinycloud.space/create",service:"tinycloud.space",status:"active"},{urn:"tinycloud.space/list",service:"tinycloud.space",status:"active"},{urn:"tinycloud.space/info",service:"tinycloud.space",status:"active"},{urn:"tinycloud.vfs/get",service:"tinycloud.vfs",status:"reserved"},{urn:"tinycloud.vfs/list",service:"tinycloud.vfs",status:"reserved"},{urn:"tinycloud.vfs/metadata",service:"tinycloud.vfs",status:"reserved"},{urn:"tinycloud.vfs/put",service:"tinycloud.vfs",status:"reserved"},{urn:"tinycloud.vfs/delete",service:"tinycloud.vfs",status:"reserved"}];function i(e){return"*"===e?"ALL":e.toUpperCase().replace(/[^A-Z0-9]/g,"_")}function s(e){return e.slice(10,e.indexOf("/"))}function a(e){return e.slice(e.indexOf("/")+1)}function o(e){const t={};for(const r of n)s(r.urn)===e&&(t[i(a(r.urn))]=r.urn);return t}var c=o("kv"),l={...o("sql"),EXECUTE:"tinycloud.sql/execute",EXPORT:"tinycloud.sql/export"},d=(o("duckdb"),o("capabilities")),u=(o("hooks"),o("encryption")),p=o("space"),f=n,h="applications",y="account",g="applications/",v="secrets",E="default",m="public",w="agents",_="tinycloud.encryption",b=u.NETWORK_CREATE,R=[E,h,y,v,m,w],T={app_id:"xyz.tinycloud.default",name:"TinyCloud Default Space",space:E,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:E,path:"",actions:["get","put","del","list","metadata"]},{service:"tinycloud.sql",space:E,path:"",actions:["read","write"]}]},A={app_id:"xyz.tinycloud.applications",name:"TinyCloud Applications Space",space:h,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:h,path:"",actions:["get","put","del","list","metadata"]},{service:"tinycloud.sql",space:h,path:"",actions:["read","write"]}]},P={app_id:"xyz.tinycloud.account",name:"TinyCloud Account Registry",space:y,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:y,path:"applications/",actions:["get","put","list"]},{service:"tinycloud.kv",space:y,path:"spaces/",actions:["get","put","list"]},{service:"tinycloud.sql",space:y,path:"account",actions:["read","write","schema"]}]},k={app_id:"xyz.tinycloud.secrets",name:"TinyCloud Secrets",space:v,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.vault",space:v,path:"secrets/",actions:["read"],skipPrefix:!0},{service:"tinycloud.kv",space:v,path:"variables",actions:["list","metadata"],skipPrefix:!0},{service:"tinycloud.kv",space:v,path:"variables/",actions:["get","put","del","list","metadata"],skipPrefix:!0},{service:"tinycloud.sql",space:v,path:"default",actions:["read","write","schema"],skipPrefix:!0},{service:"tinycloud.capabilities",space:v,path:"",actions:["read"],skipPrefix:!0}]},I={app_id:"xyz.tinycloud.public",name:"TinyCloud Public Space",space:m,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:m,path:"",actions:["get","list","metadata"]}]},S={app_id:"xyz.tinycloud.agents",name:"TinyCloud Agents Space",space:w,prefix:"",defaults:!1,includePublicSpace:!1,permissions:[{service:"tinycloud.kv",space:w,path:"",actions:["get","put","del","list","metadata"]}]},O={[E]:T,[h]:A,[y]:P,[v]:k,[m]:I,[w]:S};function C(e){return{...e,permissions:e.permissions?.map(e=>({...e,actions:[...e.actions]}))}}function x(e,t,r){return!0===r||""===e||""===t?t:"/"===t?`${e}/`:`${e.endsWith("/")?e.slice(0,-1):e}/${t.startsWith("/")?t.slice(1):t}`}function N(e,t,r){if("tinycloud.vault"===e.service)return function(e){return e.actions.map(t=>{const r=t.startsWith("tinycloud.vault/")?t.slice(16):t.startsWith("tinycloud.kv/")?t.slice(13):t,n="read"===r||"get"===r?c.GET:"write"===r||"put"===r?c.PUT:"delete"===r||"del"===r?c.DEL:"list"===r?c.LIST:"metadata"===r?c.METADATA:void 0;if(void 0===n)throw new Error(`unknown vault action ${JSON.stringify(t)}`);const i=e.path.startsWith("/")?e.path.slice(1):e.path;return{...e,service:"tinycloud.kv",path:`vault/${i}`,actions:[n],skipPrefix:!0}})}(e).flatMap(e=>N(e,t,r));const n=!0===e.skipPrefix||e.service===_;return[{service:e.service,space:e.service===_?"encryption":e.space??r,path:x(t,e.path,n),actions:e.actions.map(t=>function(e,t){return t.includes("/")?t:`${e}/${t}`}(e.service,t)),...void 0!==e.description?{description:e.description}:{}}]}function D(e){const t=new Set(e.filter(e=>e.service!==_).map(e=>e.space));return function(e){const t=new Map;for(const r of e){const e=`${r.service}\0${r.space}\0${r.path}`,n=t.get(e);if(n)for(const e of r.actions)n.actions.includes(e)||n.actions.push(e);else t.set(e,{...r,actions:[...r.actions]})}return[...t.values()]}([...e,...[...t].map(e=>({service:"tinycloud.capabilities",space:e,path:"",actions:[d.READ]}))])}function M(e){return function(e,t={}){if(!Array.isArray(e)||0===e.length)throw new Error("composeManifestRequest requires at least one manifest");const r=t.includeAccountRegistryPermissions??!0,n=e.map(C),i=n.flatMap(e=>{const t=e.prefix??e.app_id,r=e.space??h;return(e.permissions??[]).flatMap(e=>N(e,t,r))});r&&i.push(...G.map(e=>({...e,actions:[...e.actions]})));const s=new Map;for(const e of n){const t=s.get(e.app_id)??[];t.push(C(e)),s.set(e.app_id,t)}return{manifests:n,resources:D(i),delegationTargets:[],registryRecords:r?[...s.entries()].map(([e,t])=>({key:`${g}${e}`,app_id:e,manifests:t})):[],expiryMs:2592e6,includePublicSpace:n.some(e=>e.includePublicSpace??!0)}}([O[e]],{includeAccountRegistryPermissions:!1})}R.map(e=>({name:e,manifest:O[e],persistedAsApplication:e===v}));var G=Object.freeze([{service:"tinycloud.kv",space:y,path:g,actions:[c.GET,c.PUT,c.LIST]},{service:"tinycloud.kv",space:y,path:"spaces/",actions:[c.GET,c.PUT,c.LIST]},{service:"tinycloud.kv",space:y,path:"system/bootstrap/complete",actions:[c.GET,c.PUT]},{service:"tinycloud.delegation",space:y,path:"",actions:["tinycloud.delegation/list"]},{service:"tinycloud.sql",space:y,path:"account",actions:[l.READ,l.WRITE,l.SCHEMA]},{service:"tinycloud.capabilities",space:y,path:"",actions:[d.READ]}]),L=M(E),U={...L,resources:[...L.resources,...G.map(e=>({...e,actions:[...e.actions]}))]},q=Object.freeze(Object.fromEntries(R.map(e=>[e,e===E?U:M(e)]))),F=Object.freeze([{service:"tinycloud.encryption",resource:"urn:tinycloud:encryption:{ownerDid}:default",actions:[b]}]);Object.freeze(R.flatMap(e=>[{kind:"session",service:"tinycloud.session",space:e,actions:["siwe"],resources:q[e].resources,...e===y?{rawAbilities:F}:{}},{kind:"space/host",service:"tinycloud.space",space:e,actions:[p.HOST]}]));var j="Clearing pending writes surrenders read-your-writes protection for the cleared keys. If a write whose record was cleared had an unknown outcome or never finished, it may commit now or later; this device can serve an older value until the next sync after that commit, as it would for a write from another device.",V=/^(tinycloud:pkh:eip155:\d+:)([^:]+)(:.+)$/,X=/^(did:pkh:eip155:\d+:)([^:]+)$/;function $(e){if(!e||"string"!=typeof e.host||"string"!=typeof e.space||"string"!=typeof e.principal)throw new TypeError("Replication identity host, space, and principal must be strings");const t=/^https?:\/\/([^/?#]*)/i.exec(e.host)?.[1];let r;try{r=new URL(e.host)}catch{throw new TypeError("Replication identity host must be an absolute HTTP(S) URL")}if(!t||t.includes("@")||e.host.includes("?")||e.host.includes("#")||r.username||r.password)throw new TypeError("Replication identity host must be HTTP(S) without credentials, query, or fragment");const n=V.exec(e.space),i=X.exec(e.principal);if(!n||!i)throw new TypeError("Replication identity requires a full TinyCloud space id and a pkh principal DID");return{host:`${r.origin}${r.pathname.replace(/\/+$/,"")}`,space:`${n[1]}${n[2].toLowerCase()}${n[3]}`,principal:`${i[1]}${i[2].toLowerCase()}`}}function B(e){const t=$(e);return`tc-replication/v1\n${t.host}\n${t.space}\n${t.principal}`}function K(e,t){return"/"===e||t.startsWith(e)}function W(e,t){return""===e||t===e||t.startsWith(e.endsWith("/")?e:`${e}/`)}function z(e,t){return"/"===t||!("secrets"!==e&&!e.endsWith(":secrets"))||"vault"===t.split("/",1)[0]}var H="NETWORK_ERROR",Y="TIMEOUT",J="ABORTED",Q="INVALID_INPUT",Z="KV_NOT_FOUND";function ee(e){return{ok:!0,data:e}}function te(e){return{ok:!1,error:e}}function re(e,t,r,n){return{code:e,message:t,service:r,cause:n?.cause,meta:n?.meta}}var ne=class extends Error{constructor(e){super(`Request timed out after ${e}ms.`),this.name="TimeoutError",this.timeoutMs=e}};function ie(e,t,r){return void 0===t?{code:Y,message:"Request timed out.",service:e,...void 0===r?{}:{cause:r}}:{code:Y,message:`Request timed out after ${t}ms.`,service:e,...void 0===r?{}:{cause:r},meta:{timeoutMs:t}}}function se(e,t,r=H){return t instanceof Error?function(e){return e instanceof ne||e instanceof Error&&"TimeoutError"===e.name&&"number"==typeof e.timeoutMs}(t)?ie(e,t.timeoutMs,t):"AbortError"===t.name?function(e){return{code:J,message:"Request was aborted.",service:e}}(e):"TimeoutError"===t.name||t.message.toLowerCase().includes("timeout")?ie(e):{code:r,message:t.message,service:e,cause:t}:{code:r,message:String(t),service:e}}new Set(f.map(({urn:e})=>e).filter(e=>!e.endsWith("/*"))),new Set(f.map(({service:e})=>e.slice(10)));var ae=new Set(["AUTH_REQUIRED",Q,"AUTH_UNAUTHORIZED","KV_PRECONDITION_FAILED","STORAGE_QUOTA_EXCEEDED","STORAGE_LIMIT_REACHED"]);function oe(e){return{v:2,identity:{...e},committedEpoch:0,seq:0,records:[]}}function ce(e,t,r,n=100){return e.records.filter(e=>K(t,e.key)&&("in_flight"===e.state||"ambiguous"===e.state)).sort((e,t)=>e.seq-t.seq).slice(0,n).map(e=>({key:e.key,state:e.state,op:e.op,since:e.at,...e.code?{code:e.code}:{},likelyOrphaned:"in_flight"===e.state&&r-Date.parse(e.at)>6e5}))}function le(e,t,r,n){if(n)return e;const i=(new TextDecoder).decode(e);if(r)return i;if(t?.includes("application/json"))return JSON.parse(i);if(t?.startsWith("text/"))return i;if(i)try{return JSON.parse(i)}catch{return i}}var de=new TextEncoder,ue=new TextDecoder("utf-8",{fatal:!0});function pe(e,t){const r=de.encode(e),n=de.encode(t);for(let e=0;e<Math.min(r.length,n.length);e++)if(r[e]!==n[e])return r[e]-n[e];return r.length-n.length}function fe(e,t,r){const n=de.encode(JSON.stringify({v:1,space:e,path:t,last:r}));let i="";for(let e=0;e<n.length;e+=32768)i+=String.fromCharCode(...n.subarray(e,e+32768));return`tcr1.${btoa(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}`}function he(e){try{const t=e.slice(5).replace(/-/g,"+").replace(/_/g,"/"),r=atob(t+"=".repeat((4-t.length%4)%4)),n=Uint8Array.from(r,e=>e.charCodeAt(0)),i=JSON.parse(ue.decode(n));return 1===i?.v&&"string"==typeof i.space&&"string"==typeof i.path&&"string"==typeof i.last?i:null}catch{return null}}function ye(){return te(re(Q,"Local list cursor cannot be served; restart without the cursor","kv",{meta:{replication:"cursor_restart"}}))}function ge(e,t){return e.find(e=>K(e,t))}var ve=864e5,Ee=ve,me=7*ve,we=7*ve,_e=Number.NEGATIVE_INFINITY,be=({now:e,grantTtlMs:t,consentDeadline:r})=>Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(r)?Math.min(Math.min(t,me),r-e):0,Re=3e3,Te=Re,Ae=e=>new Date(e).toISOString(),Pe=e=>"object"==typeof e&&null!==e&&"code"in e&&"string"==typeof e.code?e.code:"REPLICA_UNAVAILABLE";function ke(e,t){if(t.aborted)return Promise.reject(t.reason??Object.assign(new Error("KV request was aborted"),{code:J}));let r=()=>{};const n=new Promise((e,n)=>{const i=()=>n(t.reason??Object.assign(new Error("KV request was aborted"),{code:J}));t.addEventListener("abort",i,{once:!0}),r=()=>t.removeEventListener("abort",i)});return Promise.race([e,n]).finally(r)}function Ie(e){const{options:t,mode:r,storage:n,identity:i,session:s,authority:a,pending:o,scheduler:c}=e,l=t=>function(e,t,r){try{e({...r,at:new Date(t.now()).toISOString()})}catch{}}(e.emit,c,t),d=new Map,u=new Set;let p=!1,f=!1,h=!1,y=e.previous,g=!1;const v=new Set;let E=!1,m=null;try{w=a.consentAnchor?.()??null,_=c.now(),m=null!==w&&Number.isFinite(w.at)&&Number.isFinite(_)?w.at>_?{at:_,source:w.source}:w:null,"first_install"===m?.source&&(m=null)}catch{E=!0}var w,_;const b={grantTtlMs:t.grantTtlMs??Ee,consentAnchor:m},R=void 0===t.maxBytes&&void 0===t.minFreeBytes?void 0:{maxBytes:t.maxBytes,minFreeBytes:t.minFreeBytes},T=null===m?null:(e=>Number.isFinite(e.at)?e.at+we:_e)(m);let A,P=null;function k(){if("indexeddb"!==n.kind||!e.stamp)return null;try{const t=n.lifecycle?.consentDeadline(e.stamp);return"number"==typeof t&&Number.isFinite(t)?t:null}catch{return null}}function I(){if(null===T)return null;if("indexeddb"!==n.kind)return T;const e=k();return null===e?null:Math.min(T,e)}const S=new Set;let O=!1;function C(){const t=n.lifecycle;if(!t)return"indexeddb"===n.kind||E||void 0!==e.stamp?{status:"gated",gate:"gate_unavailable"}:{status:"allow"};if(!e.stamp)return{status:"gated",gate:"not_established"};if(O)return{status:"gated",gate:"stamp_stale"};try{const r=t.checkDelivery(e.stamp);if("consent_expired"===r.status&&N(),"allow"!==r.status)return r;if("indexeddb"===n.kind){const e=k();if(null===e)return{status:"gated",gate:"gate_unavailable"};const t=c.now();if(!Number.isFinite(t))return{status:"gated",gate:"gate_unavailable"};if(t>=e)return N(),{status:"consent_expired",code:"CONSENT_EXPIRED"}}return E?{status:"gated",gate:"gate_unavailable"}:r}catch{return{status:"gated",gate:"gate_unavailable"}}}function x(){if(O||p||f)return!1;A?.(),A=void 0,O=!0;for(const e of d.values()){e.renewalTimer?.(),e.renewalTimer=void 0,e.mintAbort?.abort();const t=e.handle?.replicaId;t&&!S.has(t)&&(S.add(t),l({type:"replication.grant",replicaId:t,action:"consent_deadline_reached",code:"CONSENT_EXPIRED"}))}return!0}function N(){const e=n.lifecycle;e&&x()&&e.deny({reason:"consent_expired",principal:i.principal}).then(e=>l({type:"replication.lifecycle",action:"denied"===e.status?"denied":"stale"===e.status?"deny_stale":"deleted"===e.status?"database_deleted":"marker"===e.status?"marker_set":"unguarded",reason:"consent_expired"}),()=>l({type:"replication.lifecycle",action:"deny_failed",reason:"consent_expired"}))}function D(e){return Object.assign(new Error("consent_expired"===e.status?"Replica consent expired":"Replica session is gated"),{code:"consent_expired"===e.status?e.code:"REPLICA_GATED",..."gated"===e.status?{gate:e.gate}:{}})}function M(e){return"CONSENT_EXPIRED"===e||"GRANT_EXPIRED"===e?"grant_expired":"REPLICA_GATED"===e?"replica_gated":"replica_error"}function G(e,t,r){if(!(r?.unconstrained&&t.replicaId&&"number"==typeof r.effectiveExpiresAt&&Number.isFinite(r.effectiveExpiresAt)&&(null===r.expiresAt||r.effectiveExpiresAt<r.expiresAt)))return;const n=`${r.cid}:${r.effectiveExpiresAt}`;e.reportedCappedCid!==n&&(e.reportedCappedCid=n,l({type:"replication.grant",replicaId:t.replicaId,action:"capped",effectiveExpiresAt:Ae(r.effectiveExpiresAt)}))}const L=e=>t.prefixes.find(t=>K(t,e));function U(e,t){if("GRANT_REVOKED"!==Pe(t))return;const r=d.get(e)??{};r.authorityRevoked=!0,r.reason="grant_revoked",r.lastError="GRANT_REVOKED",d.set(e,r)}function q(e){const t=d.get(e)??{},r="REPLICATION_ROOT_UNSUPPORTED"!==t.lastError;t.reason="replica_unavailable",t.lastError="REPLICATION_ROOT_UNSUPPORTED",d.set(e,t),r&&l({type:"replication.state",space:s.space,replica:e,state:"unavailable",code:"REPLICATION_ROOT_UNSUPPORTED"})}function F(e){return q(e),Object.assign(new Error("This node doesn't support whole-space sync yet."),{code:"REPLICATION_ROOT_UNSUPPORTED"})}function j(e){try{if(!0!==a.sessionOnly)return;const t=a.sessionGrant(e);return"refused"in t?t.refused:void 0}catch{return"NOT_COVERED"}}async function V(o){const u=C();if("allow"!==u.status)throw D(u);if(p||f)throw Object.assign(new Error("Replication controller is closed"),{code:"REPLICA_CLOSED"});let h=d.get(o);if(h?.handle)return h.handle;if(h?.opening)return h.opening;if(h??(h={}),d.set(o,h),h.unsupported)throw Object.assign(new Error("Replication runtime is unsupported"),{code:"RUNTIME_UNSUPPORTED"});if(void 0!==h.retryAt&&c.now()<h.retryAt)throw Object.assign(new Error("Replica open is backing off"),{code:h.lastError??"REPLICA_UNAVAILABLE"});if(z(s.space,o)&&!t.allowSecrets){const e="SECRETS_OPT_IN_REQUIRED"!==h.lastError;throw h.reason="replica_unavailable",h.lastError="SECRETS_OPT_IN_REQUIRED",e&&l({type:"replication.state",space:s.space,replica:o,state:"unavailable",code:"SECRETS_OPT_IN_REQUIRED"}),Object.assign(new Error("Replication requires allowSecrets for this space or prefix"),{code:"SECRETS_OPT_IN_REQUIRED"})}h.opening=(async()=>{y&&(await y,y=void 0);const d=C();if("allow"!==d.status)throw D(d);const u=!0===a.sessionOnly,g=a.sessionGrant(o),v="refused"in g?void 0:g,E=u?void 0:a.plan(o);let w,_;"refused"in g&&(w=g.refused),E&&"refused"in E&&(w??(w=E.refused)),e.stamp&&null===m&&!u&&(w="REPLICA_GATED"),v&&(_=v.device,h.strategy="session");const A={identity:i,space:s.space,prefix:o,allowSecrets:t.allowSecrets,grantPolicy:b,...R?{quota:R}:{},...t.contentFetch?{contentFetch:t.contentFetch}:{},...e.stamp?{stamp:e.stamp}:{},..._?{device:_}:{},...e.fetch?{fetch:e.fetch}:{},onPeerCommit:e=>{p||f||void 0===h.handle||l({type:"replication.sync",space:s.space,replica:o,trigger:"peer",origin:"peer",outcome:"ok",durationMs:0,lagMs:null,...void 0===e.changes?{}:{changes:e.changes},...void 0===e.coverage?{}:{coverage:e.coverage}})}};if("/"===o&&void 0!==e.nodeFeatures&&!e.nodeFeatures.includes("kv-sync-root"))throw F(o);const P=await n.open(A);h.handle=P;const S=C();if("allow"!==S.status)throw D(S);l({type:"replication.state",space:s.space,replica:o,state:"opened"});const O=u||!E||"refused"in E?void 0:E;let x,N=O||v?await P.grant():void 0;if(N&&!function(t,r){if(!t?.unconstrained)return!1;if(!e.stamp)return!0;if(!r&&null===m)return!1;const i=c.now(),s="indexeddb"===n.kind?k():T??t.consentDeadline;return"active"===t.state&&"number"==typeof t.installedAt&&Number.isFinite(t.installedAt)&&"number"==typeof t.effectiveExpiresAt&&Number.isFinite(t.effectiveExpiresAt)&&"number"==typeof t.consentDeadline&&Number.isFinite(t.consentDeadline)&&"number"==typeof s&&Number.isFinite(s)&&Number.isFinite(i)&&i>=t.installedAt&&(null===t.expiresAt||"number"==typeof t.expiresAt&&Number.isFinite(t.expiresAt)&&i<t.expiresAt)&&i<Math.min(t.effectiveExpiresAt,t.consentDeadline,s)}(N,u)&&(N.unconstrained&&(w=null!==m||u?"GRANT_EXPIRED":"REPLICA_GATED"),N=void 0),v&&null!==m){const e=C();if("allow"!==e.status)throw D(e);N=await P.installGrant(v.ucan)}else if(O){if(!N||!N.unconstrained||N.parentCid!==O.parentCid||null!==N.expiresAt&&O.expiresAt>N.expiresAt+3e5){const e=I(),t=be({now:c.now(),grantTtlMs:b.grantTtlMs,consentDeadline:e??Number.NaN});if(t>0)try{const e=new AbortController;h.mintAbort=e;const r=await a.mint(P.deviceDid,o,e.signal,{expiryMs:t}),n=C();if("allow"!==n.status)throw D(n);N=await P.installGrant(r.ucan),h.strategy="minted",x=t}catch(e){if("CONSENT_EXPIRED"===Pe(e)||"REPLICA_GATED"===Pe(e)||!N?.unconstrained)throw e}finally{h.mintAbort=void 0}}N?.unconstrained&&(h.strategy??(h.strategy="installed"),h.reason=void 0)}else(v||u)&&N?.unconstrained&&(h.strategy="installed");const M=C();if("allow"!==M.status)throw D(M);if(G(h,P,N),void 0!==x&&(h.reportedExpired=!1),void 0!==x&&P.replicaId&&l({type:"replication.grant",replicaId:P.replicaId,action:"minted",expiryMs:x}),N?.unconstrained?l({type:"replication.state",space:s.space,replica:o,state:"grant_installed",strategy:h.strategy}):(h.reason="grant_missing",h.lastError=w??"SESSION_LACKS_SYNC",l({type:"replication.state",space:s.space,replica:o,state:"grant_missing",code:h.lastError})),p||f)throw await P.close(),Object.assign(new Error("Replication controller is closed"),{code:"REPLICA_CLOSED"});return N?.unconstrained&&await $(o,P,N,O),"background"===r&&"grant_missing"!==h.reason&&(Y(o,"start").catch(()=>{}),B(o)),P})();try{return await h.opening}catch(e){const t=Pe(e);throw"CONSENT_EXPIRED"===t&&N(),U(o,e),"REPLICA_GATED"===t||"CONSENT_EXPIRED"===t?h.reason=M(t):"GRANT_REVOKED"!==t&&(h.reason="replica_unavailable"),h.lastError=t,h.failures=(h.failures??0)+1,"RUNTIME_UNSUPPORTED"===t?h.unsupported=!0:"REPLICA_CLOSED"!==t&&"REPLICATION_ROOT_UNSUPPORTED"!==t&&"REPLICA_GATED"!==t&&"CONSENT_EXPIRED"!==t&&(h.retryAt=c.now()+Math.min(3e5,5e3*2**Math.min(h.failures-1,6))),h.handle?.close().catch(()=>{}),h.handle=void 0,e}finally{h.opening=void 0}}function X(e,t,r,n){const i=d.get(e);if(i?.renewalTimer?.(),i&&(i.renewalTimer=void 0),!i||p||f||"session"!==n.path||!a.canRenew)return;const{installedAt:s,effectiveExpiresAt:o}=r,l=I();if(!("number"==typeof s&&Number.isFinite(s)&&"number"==typeof o&&Number.isFinite(o)&&o>s&&null!==l))return;const u=s+.75*(o-s),h=c.now();Number.isFinite(h)&&u<l&&!(h>u)&&(i.renewalTimer=c.setTimeout(()=>{i.renewalTimer=void 0,$(e,t).catch(()=>{})},Math.max(0,Math.floor(u)+1-h)))}async function $(e,t,r,n){const i=d.get(e);if(!i||i.handle!==t||p||f||!a.canRenew)return;if(i.renewing)return i.renewing;if("allow"!==C().status)return;const s=r??await t.grant();if(!s?.unconstrained)return;const{installedAt:o,effectiveExpiresAt:u}=s,h=I();if("number"!=typeof o||!Number.isFinite(o)||"number"!=typeof u||!Number.isFinite(u)||null===h)return;const y=c.now();if(!(({now:e,installedAt:t,effectiveExpiresAt:r,consentDeadline:n})=>!!(Number.isFinite(e)&&Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(n))&&e<n&&r-e<.25*(r-t))({now:y,installedAt:o,effectiveExpiresAt:u,consentDeadline:h}))return void(n&&X(e,t,s,n));let g=n;try{if(!g){const r=a.plan(e);if("refused"in r)return void(t.replicaId&&l({type:"replication.grant",replicaId:t.replicaId,action:"renewal_refused",code:r.refused}));g=r}}catch{return void(t.replicaId&&l({type:"replication.grant",replicaId:t.replicaId,action:"renewal_deferred"}))}if("session"!==g?.path)return void(t.replicaId&&i.reportedRenewalUnqualifiedCid!==s.cid&&(i.reportedRenewalUnqualifiedCid=s.cid,l({type:"replication.grant",replicaId:t.replicaId,action:"renewal_deferred"})));const v=be({now:y,grantTtlMs:b.grantTtlMs,consentDeadline:h});if(!(v>0))return;i.renewalTimer?.(),i.renewalTimer=void 0;const E=new AbortController;i.mintAbort=E;const m=Promise.resolve().then(async()=>{const r=await a.mint(t.deviceDid,e,E.signal,{expiryMs:v,renewalOnly:!0}),n=C();if("allow"!==n.status)throw D(n);const s=await t.installGrant(r.ucan),o=C();if("allow"!==o.status)throw D(o);G(i,t,s),i.reportedExpired=!1,"grant_expired"===i.reason&&(i.reason=void 0),"GRANT_EXPIRED"===i.lastError&&(i.lastError=void 0),t.replicaId&&l({type:"replication.grant",replicaId:t.replicaId,action:"renewed",expiryMs:v}),"number"==typeof s.effectiveExpiresAt&&s.effectiveExpiresAt>u&&X(e,t,s,g)});i.renewing=m;try{await m}catch(e){const r=Pe(e);if("CONSENT_EXPIRED"===r||"REPLICA_GATED"===r)throw e;if(!p&&t.replicaId){const n="object"==typeof e&&null!==e&&"refused"in e&&"string"==typeof e.refused?e.refused:null;l({type:"replication.grant",replicaId:t.replicaId,action:n?"renewal_refused":"renewal_deferred",code:n??r})}}finally{i.renewing=void 0,i.mintAbort===E&&(i.mintAbort=void 0)}}function B(e){const n=d.get(e);!n||"background"!==r||p||f||(n.timer=c.setTimeout(()=>{n.timer=void 0,Y(e,"interval").catch(()=>{}).finally(()=>B(e))},t.syncIntervalMs))}async function Y(t,r,n,i){if("/"===t&&void 0!==e.nodeFeatures&&!e.nodeFeatures.includes("kv-sync-root"))throw F(t);const a=j(t);if(a)throw Object.assign(new Error("Current session does not cover replica sync"),{code:a});const u=await V(t),p=d.get(t);if(p.sync)return p.sync;const f=new AbortController,h=i??{};p.syncContext=h,p.abort=f;const y=()=>{h.abortCause??(h.abortCause="caller"),f.abort(n?.reason)};n?.addEventListener("abort",y,{once:!0});const g=c.now();let E;E=(async()=>{try{const e=(await o.read()).committedEpoch,n=C();if("allow"!==n.status)throw D(n);await $(t,u);const i=C();if("allow"!==i.status)throw D(i);const a=j(t);if(a)throw Object.assign(new Error("Current session does not cover replica sync"),{code:a});const d=await u.sync({signal:f.signal,syncStartEpoch:e}),p=C();if("allow"!==p.status)throw D(p);if("busy"===d.status)return l({type:"replication.sync",space:s.space,replica:t,trigger:r,outcome:"busy",durationMs:c.now()-g,lagMs:null}),d;v.add(t);const h=await o.read(),y=C();if("allow"!==y.status)throw D(y);const E=h.records.some(r=>"committed"===r.state&&null!==r.epoch&&r.epoch<=e&&K(t,r.key))?await o.update(r=>function(e,t,r){const n=e.records.length;return e.records=e.records.filter(e=>!("committed"===e.state&&null!==e.epoch&&e.epoch<=r&&K(t,e.key))),n-e.records.length}(r,t,e)):0,m=C();if("allow"!==m.status)throw D(m);return l({type:"replication.sync",space:s.space,replica:t,trigger:r,outcome:"ok",durationMs:c.now()-g,lagMs:null,pendingCleared:E,pages:d.pages,changes:d.changes,deleted:d.deleted,fetched:d.fetched,contentMissing:d.contentMissing,coverage:d.coverage}),d}catch(e){const n=Pe(e);throw p.lastError=n,U(t,e),"CONSENT_EXPIRED"===n&&N(),l({type:"replication.sync",space:s.space,replica:t,trigger:r,outcome:f.signal.aborted?"aborted":"error",class:"CONSENT_EXPIRED"===n||"REPLICA_GATED"===n?"lifecycle":"NETWORK_ERROR"===n||"TIMEOUT"===n?"offline":"node",code:n,durationMs:c.now()-g,lagMs:null}),e}finally{n?.removeEventListener("abort",y),p.abort=void 0}})(),p.sync=E;try{return await E}finally{p.sync===E&&(p.sync=void 0,p.syncContext=void 0)}}async function J(e,t){let r=()=>{};const n=t.then(e=>({settled:!0,result:e}),e=>({settled:!0,error:e})),i=new Promise(e=>{r=c.setTimeout(()=>e({settled:!1}),Re)});try{const t=await Promise.race([n,i]);return t.settled||l({type:"replication.sync",space:s.space,replica:e,trigger:"stale_read",outcome:"aborted",code:"DRAIN_TIMEOUT",durationMs:Re,lagMs:null}),t}finally{r()}}function Q(e){if("complete"!==e.coverage)throw Object.assign(new Error("Replica coverage changed before the local read"),{code:"COVERAGE_INCOMPLETE"});if("valid"!==e.authority){const t="expired"===e.authority?"GRANT_EXPIRED":"revoked"===e.authority?"GRANT_REVOKED":"GRANT_NOT_YET_VALID";throw Object.assign(new Error("Replica authority changed before the local read"),{code:t})}}function ne(e){return"COVERAGE_INCOMPLETE"===e?"coverage_incomplete":"GRANT_EXPIRED"===e?"grant_expired":"GRANT_REVOKED"===e?"grant_revoked":"GRANT_NOT_YET_VALID"===e?"grant_not_yet_valid":"replica_error"}function ie(e,t,r){if("error"in e){const n=Pe(e.error);return"NETWORK_ERROR"===n||t&&("ABORTED"===n||"TIMEOUT"===n)?{status:r,syncedBeforeRead:!1,syncError:"NETWORK_ERROR"===n?n:"TIMEOUT"}:{status:r,syncedBeforeRead:!1,syncError:n,failure:"error"}}return"busy"===e.result.status?{status:r,syncedBeforeRead:!1,failure:"busy"}:{status:r,syncedBeforeRead:!0}}async function de(e,n,i){let s=await n.status();const a=null===s.lastSyncAt?null:Date.parse(s.lastSyncAt),l=null===a||!Number.isFinite(a)||c.now()-a>t.maxStalenessMs;let u;try{u=await o.read()}catch(e){return{status:s,syncedBeforeRead:!1,syncError:Pe(e),failure:"error"}}const p=s.syncedThroughEpoch<u.committedEpoch,f=!o.durable&&!v.has(e);if((l||p||f)&&!i.aborted){const a="foreground"===r?new AbortController:void 0,o=d.get(e),l=!o?.sync,u=o?.syncContext??{},p=()=>{l&&(u.abortCause??(u.abortCause="caller")),a?.abort(i.reason)};a&&i.addEventListener("abort",p,{once:!0});let f=()=>{};const h=new Promise(e=>{f=c.setTimeout(()=>e({timeout:!0}),t.staleSyncTimeoutMs)});let y=()=>{};const g=new Promise(e=>{if(i.aborted)e({callerAborted:!0});else{const t=()=>e({callerAborted:!0});i.addEventListener("abort",t,{once:!0}),y=()=>i.removeEventListener("abort",t)}}),v=Y(e,"stale_read",a?.signal,u),E=await Promise.race([v.then(e=>({result:e}),e=>({error:e})),h,g]);if(f(),y(),i.removeEventListener("abort",p),"callerAborted"in E)return a&&l&&(u.abortCause??(u.abortCause="caller"),a.abort(i.reason),await J(e,v)),{status:s,syncedBeforeRead:!1,syncError:Se(i)};if("timeout"in E){l&&(u.abortCause??(u.abortCause="timeout"),a?.abort(Object.assign(new Error("Stale-read sync timed out"),{code:"TIMEOUT"})));const t=a?await J(e,v):void 0;if(i.aborted)return{status:s,syncedBeforeRead:!1,syncError:Se(i)};if(t&&!t.settled)return{status:s,syncedBeforeRead:!1,syncError:"DRAIN_TIMEOUT",failure:"error"};try{s=await async function(e,t){let r=()=>{};const n=new Promise((e,t)=>{r=c.setTimeout(()=>t(Object.assign(new Error("Replica status refresh timed out"),{code:"STATUS_TIMEOUT"})),Te)});try{return await ke(Promise.race([e.status(),n]),t)}finally{r()}}(n,i)}catch(e){return i.aborted?{status:s,syncedBeforeRead:!1,syncError:Se(i),failure:"error"}:{status:s,syncedBeforeRead:!1,syncError:Pe(e),failure:"error"}}const r="timeout"===u.abortCause;return ie(t?.settled?"result"in t?{result:t.result}:{error:t.error}:{error:Object.assign(new Error("Stale-read sync timed out"),{code:"TIMEOUT"})},r||!a,s)}return"error"in E?ie({error:E.error},!1,s):"busy"===E.result.status?{status:s,syncedBeforeRead:!1,failure:"busy"}:(s=await n.status(),{status:s,syncedBeforeRead:!0})}return{status:s,syncedBeforeRead:!1}}function ue(e,t,r,n,i,a,o,u={}){null!==r&&"grant_expired"===i&&"CONSENT_EXPIRED"!==u.code&&function(e){const t=d.get(e);if(!t)return;t.reason="grant_expired",t.lastError="GRANT_EXPIRED";const r=t.handle?.replicaId;r&&!t.reportedExpired&&(t.reportedExpired=!0,l({type:"replication.grant",replicaId:r,action:"expired",code:"GRANT_EXPIRED"}))}(r),l({type:"replication.read",op:e,space:s.space,key:t,replica:r,source:n,reason:i,outcome:a,latencyMs:c.now()-o,stalenessMs:null,coverage:null,authority:null,...u})}async function ve(e,t,r,n,i,s,a={}){let o="error";try{const r=await e();return o=r.ok?"found":"get"!==t||"pending_write"!==i&&"not_covered"!==i||r.error.code!==Z?"error":"not_found",r}finally{ue(t,r,n,"network",i,o,s,a)}}async function me(){if(!g){g=!0;try{const e=ce(await o.read(),"",c.now());e.length>0&&l({type:"replication.state",space:s.space,state:"pinned",count:e.length,keys:e.map(e=>e.key)})}catch{l({type:"replication.state",space:s.space,state:"pending_store_error",code:"STORAGE_ERROR"})}}}function Ie(e){l({type:"replication.read",op:e.op,space:e.space,key:e.path,replica:null,source:"network",reason:"NETWORK_REQUESTED",outcome:e.outcome,latencyMs:e.latencyMs,stalenessMs:null,coverage:null,authority:null})}function Ce(){const e=[...u];for(const t of e)t.abort.abort(Object.assign(new Error("Replica status inspection cancelled"),{code:"ABORTED"}));return Promise.all(e.map(e=>e.settled)).then(()=>{})}function xe(e){return t.prefixes.map(t=>({prefix:t,state:"gated",reason:"replica_gated",gate:"gated"===e.status?e.gate:"stamp_stale",errorCode:"consent_expired"===e.status?e.code:"REPLICA_GATED",pending:{inFlight:0,committed:0,ambiguous:0},pinned:[],lagMs:null,redacted:!0}))}return function(){const e=k();if(null===e||O||p)return;const t=c.now();Number.isFinite(t)&&(P===e&&A||(P=e,A?.(),A=c.setTimeout(()=>{A=void 0,C()},Math.max(0,e-t))))}(),{get:async function(e){const r=c.now(),n=L(e.path);if("network"===e.options?.source){let t="error";try{const r=await e.network();return t=r.ok?"found":r.error.code===Z?"not_found":"error",r}finally{Ie({op:"get",space:e.space,path:e.path,reason:"NETWORK_REQUESTED",outcome:t,latencyMs:c.now()-r})}}let i=!1;const s=async(t,n,s={})=>{try{return await ve(e.network,"get",e.path,t,n,r,s)}catch(e){throw i=!0,e}};if(void 0===n)return ve(e.network,"get",e.path,null,"not_covered",r);const a=C();if("allow"!==a.status)return s(n,"consent_expired"===a.status?"grant_expired":"replica_gated",{code:"consent_expired"===a.status?a.code:"REPLICA_GATED"});const u=j(n);if(u)return s(n,"grant_missing",{code:u});try{await ke(me(),e.signal)}catch{if(e.signal.aborted)return Oe(e.signal)}let p,f,h;try{p=await ke(V(n),e.signal)}catch(t){if(e.signal.aborted)return Oe(e.signal);"CONSENT_EXPIRED"===Pe(t)&&N();const r=Pe(t);return s(n,"RUNTIME_UNSUPPORTED"===r?"runtime_unsupported":"CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):"replica_unavailable",{code:r})}if("grant_missing"===d.get(n)?.reason){const e=d.get(n)?.lastError;return s(n,"GRANT_EXPIRED"===e?"grant_expired":"REPLICA_GATED"===e?"replica_gated":"grant_missing",{code:e})}try{f=await de(n,p,e.signal)}catch(t){if(U(n,t),"CONSENT_EXPIRED"===Pe(t)&&N(),e.signal.aborted)return Oe(e.signal);const r=Pe(t);return s(n,"CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):"replica_error",{code:r})}if(e.signal.aborted)return Oe(e.signal);if(f.failure){const e="busy"===f.failure?"REPLICA_BUSY":f.syncError;return s(n,"GRANT_REVOKED"===e?"grant_revoked":"REPLICA_GATED"===e||"CONSENT_EXPIRED"===e||"GRANT_EXPIRED"===e?M(e):"stale",{code:e,syncedBeforeRead:f.syncedBeforeRead})}try{h=await ke(o.read(),e.signal)}catch(t){if(e.signal.aborted)return Oe(e.signal);const r=Pe(t);return s(n,"REPLICA_GATED"===r||"CONSENT_EXPIRED"===r||"GRANT_EXPIRED"===r?M(r):"replica_unavailable",{code:r})}const y=h.records.find(t=>t.key===e.path);if(y)return s(n,"pending_write",{pendingState:y.state,syncedBeforeRead:f.syncedBeforeRead});if(!o.durable&&!v.has(n))return s(n,"REPLICA_UNPROVEN_SINCE_START");if(f.status.syncedThroughEpoch<h.committedEpoch)return s(n,"REPLICA_BEHIND_OWN_WRITES");if("valid"!==f.status.authority.state)return s(n,"expired"===f.status.authority.state?"grant_expired":"revoked"===f.status.authority.state?"grant_revoked":"grant_not_yet_valid");if("complete"!==f.status.coverage)return s(n,"coverage_incomplete");try{const i=await ke(p.get(e.path),e.signal),a=C();if("allow"!==a.status)throw D(a);const o=j(n);if(o)return await s(n,"grant_missing",{code:o});try{Q(i.meta)}catch(e){const t=Pe(e);return U(n,e),await s(n,ne(t),{code:t})}if("coverage_incomplete"===i.status||"not_covered"===i.status||"content_missing"===i.status)return await s(n,"content_missing"===i.status?"content_missing":"coverage_incomplete"===i.status?"coverage_incomplete":"not_covered");if("present"===i.status&&void 0!==e.options?.maxResponseBytes&&i.value.byteLength>e.options.maxResponseBytes)return await s(n,"unsupported_option");const d=function(e,t,r){if("present"===e.status){if(void 0!==r.maxResponseBytes&&e.value.byteLength>r.maxResponseBytes)return te(re("KV_RESPONSE_TOO_LARGE",`KV value at key ${JSON.stringify(t)} exceeds the requested response limit`,"kv",{meta:{status:413}}));const n=Object.entries(e.metadata).find(([e])=>"content-type"===e.toLowerCase())?.[1],i=new Headers({etag:e.etag,"content-length":String(e.value.byteLength),"cache-control":"private, no-cache",...e.metadata,"x-tinycloud-source":"replica"});return ee({data:le(e.value,n,r.raw,r.binary),headers:{etag:e.etag,contentType:n,contentLength:e.value.byteLength,get:e=>i.get(e)}})}return"absent"===e.status||"deleted"===e.status?te(re(Z,`Key not found: ${t}`,"kv")):te(re(H,"Local value is not available","kv"))}(i,e.path,e.options??{}),u="present"===i.status?"hit":i.status,h=null===f.status.lastSyncAt?null:Date.parse(f.status.lastSyncAt),y={syncedBeforeRead:f.syncedBeforeRead,coverage:i.meta.coverage,authority:i.meta.authority,stalenessMs:null===h?null:c.now()-h,...f.syncError?{syncError:f.syncError}:{}};return t.verify?await async function(e,t,r,n,i){const s=L(e.path)??null,a=t.ok,o=!t.ok&&t.error.code===Z,c=a?"found":o?"not_found":"error";try{const d=await ke(e.network(),e.signal);if(e.signal.aborted)return ue("get",e.path,s,"none","aborted","error",n,{...i,verify:"aborted"}),Oe(e.signal);const u=C();if("allow"!==u.status)return ue("get",e.path,s,"network","consent_expired"===u.status?"grant_expired":"replica_gated",d.ok?"found":"error",n,{code:"consent_expired"===u.status?u.code:"REPLICA_GATED"}),d;const p=null===s?void 0:j(s);if(p)return ue("get",e.path,s,"network","grant_missing",d.ok?"found":"error",n,{code:p}),d;if(!d.ok&&d.error.code!==Z)return ue("get",e.path,s,"replica",r,c,n,{...i,code:d.error.code,verify:"error"}),t;const f=d.ok,h=!d.ok&&d.error.code===Z,y=t.ok?t.data.headers.etag??null:null,g=d.ok?d.data.headers.etag??null:null,v=a&&f?y===g:o&&h,E=v?"match":"diverged";return v||l({type:"replication.divergence",op:"get",space:e.space,key:e.path,replica:s??"",kind:a&&f?"value":o?"missing_local":"extra_local",localEtag:y,networkEtag:g,stalenessMs:"number"==typeof i.stalenessMs?i.stalenessMs:null}),ue("get",e.path,s,"replica",r,c,n,{...i,verify:E}),t}catch(a){if(e.signal.aborted)return ue("get",e.path,s,"none","aborted","error",n,{...i,verify:"aborted"}),Oe(e.signal);const o=C();if("allow"!==o.status)return ue("get",e.path,s,"network","consent_expired"===o.status?"grant_expired":"replica_gated","error",n,{code:"consent_expired"===o.status?o.code:"REPLICA_GATED"}),te(se("kv",a));const l=null===s?void 0:j(s);return l?(ue("get",e.path,s,"network","grant_missing","error",n,{code:l}),te(se("kv",a))):(ue("get",e.path,s,"replica",r,c,n,{...i,code:Pe(a),verify:"error"}),t)}}(e,d,u,r,y):(ue("get",e.path,n,"replica",u,d.ok?"found":d.error.code===Z?"not_found":"error",r,y),d)}catch(t){if(i)throw t;return U(n,t),"CONSENT_EXPIRED"===Pe(t)&&N(),e.signal.aborted?Oe(e.signal):s(n,M(Pe(t)),{code:Pe(t)})}},list:async function(e){const r=c.now();if("network"===e.options?.source){let t="error";try{const r=await e.network();return t=r.ok?"found":"error",r}finally{Ie({op:"list",space:e.space,path:e.listPath,reason:"NETWORK_REQUESTED",outcome:t,latencyMs:c.now()-r})}}const n=e.options?.cursor,i=n?.startsWith("tcr1.")?he(n):null;if(n&&n.startsWith("tcr1.")&&!i)return ue("list",e.listPath,null,"none","cursor_restart","error",r),ye();if(n&&!n.startsWith("tcr1."))return ve(e.network,"list",e.listPath,null,"network_cursor",r);const s=ge(t.prefixes,e.listPath);let a=!1;const u=async(t,n,i={})=>{try{return await ve(e.network,"list",e.listPath,t,n,r,i)}catch(e){throw a=!0,e}};if(void 0!==s&&!e.options?.raw){const t=C();if("allow"!==t.status)return i?(ue("list",e.listPath,s,"none","cursor_restart","error",r),ye()):u(s,"consent_expired"===t.status?"grant_expired":"replica_gated",{code:"consent_expired"===t.status?t.code:"REPLICA_GATED"})}if(void 0!==s&&!e.options?.raw){const t=j(s);if(t)return i?(ue("list",e.listPath,s,"none","cursor_restart","error",r),ye()):u(s,"grant_missing",{code:t})}try{await ke(me(),e.signal)}catch{if(e.signal.aborted)return Oe(e.signal)}const p=()=>(ue("list",e.listPath,s??null,"none","cursor_restart","error",r),ye());if(n&&i&&(i.space!==e.space||i.path!==e.listPath))return p();if(void 0===s||e.options?.raw)return n&&i?p():ve(e.network,"list",e.listPath,s??null,void 0!==s?"unsupported_option":"not_covered",r);let f,h,y;try{f=await ke(V(s),e.signal)}catch(t){if(e.signal.aborted)return Oe(e.signal);if("CONSENT_EXPIRED"===Pe(t)&&N(),n&&i)return p();const r=Pe(t);return u(s,"RUNTIME_UNSUPPORTED"===r?"runtime_unsupported":"CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):"replica_unavailable",{code:r})}if("grant_missing"===d.get(s)?.reason){if(n&&i)return p();const e=d.get(s)?.lastError;return u(s,"GRANT_EXPIRED"===e?"grant_expired":"REPLICA_GATED"===e?"replica_gated":"grant_missing",{code:e})}try{h=await de(s,f,e.signal)}catch(t){if(U(s,t),"CONSENT_EXPIRED"===Pe(t)&&N(),e.signal.aborted)return Oe(e.signal);if(n&&i)return p();const r=Pe(t);return u(s,"CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):"replica_error",{code:r})}if(e.signal.aborted)return Oe(e.signal);try{y=await ke(o.read(),e.signal)}catch(t){if(e.signal.aborted)return Oe(e.signal);if(n&&i)return p();const r=Pe(t);return u(s,"REPLICA_GATED"===r||"CONSENT_EXPIRED"===r||"GRANT_EXPIRED"===r?M(r):"replica_unavailable",{code:r})}const g=y.records.find(t=>W(e.listPath,t.key)),E=h.status.syncedThroughEpoch<y.committedEpoch;if(n&&i&&(h.failure||g||E||"complete"!==h.status.coverage||"valid"!==h.status.authority.state||!o.durable&&!v.has(s)))return p();if(E)return u(s,"REPLICA_BEHIND_OWN_WRITES");if(h.failure){const e="busy"===h.failure?"REPLICA_BUSY":h.syncError;return u(s,"GRANT_REVOKED"===e?"grant_revoked":"REPLICA_GATED"===e||"CONSENT_EXPIRED"===e||"GRANT_EXPIRED"===e?M(e):"stale",{code:e})}if(g)return u(s,"pending_write",{pendingState:g.state});if(!o.durable&&!v.has(s))return u(s,"REPLICA_UNPROVEN_SINCE_START");if("complete"!==h.status.coverage||"valid"!==h.status.authority.state)return u(s,"complete"!==h.status.coverage?"coverage_incomplete":"expired"===h.status.authority.state?"grant_expired":"revoked"===h.status.authority.state?"grant_revoked":"grant_not_yet_valid");try{const a={list:t=>ke(f.list(t),e.signal)},d=await ke(function(e,t,r,n,i,s){const a=i?he(i)?.last:void 0,o=""!==r&&!r.endsWith("/")&&(void 0===a||pe(r,a)>0)?async function(e,t,r,n){if(void 0!==r&&pe(t,r)<=0)return!1;const i=await e.list({prefix:t,limit:1});return n(i.meta),i.keys[0]===t}(e,r,a,s):Promise.resolve(!1);return o.then(async i=>{const o=""===r?"":r.endsWith("/")?r:`${r}/`,c=void 0===n?void 0:n+1-(i?1:0),l=await e.list({prefix:o,after:a,limit:c});s(l.meta);let d=(i?[r]:[]).concat(l.keys);const u=void 0!==n&&d.length>n;return u&&(d=d.slice(0,n)),{keys:d,truncated:u,...u?{nextCursor:fe(t,r,d[d.length-1])}:{}}})}(a,e.space,e.listPath,e.options?.limit,n,Q),e.signal),y=await ke(o.read(),e.signal),g=y.records.find(t=>W(e.listPath,t.key));if(n&&i&&(g||h.status.syncedThroughEpoch<y.committedEpoch))return p();if(h.status.syncedThroughEpoch<y.committedEpoch)return await u(s,"REPLICA_BEHIND_OWN_WRITES");if(g)return await u(s,"pending_write",{pendingState:g.state});const v=C();if("allow"!==v.status)throw D(v);const E=j(s);if(E)return i?p():await u(s,"grant_missing",{code:E});const m={count:d.keys.length,syncedBeforeRead:h.syncedBeforeRead,stalenessMs:null===h.status.lastSyncAt?null:c.now()-Date.parse(h.status.lastSyncAt),...h.syncError?{syncError:h.syncError}:{}};return t.verify&&!n?await async function(e,r,n,i){const s=ge(t.prefixes,e.listPath)??null;try{const t=await ke(e.network(),e.signal);if(e.signal.aborted)return ue("list",e.listPath,s,"none","aborted","error",n,{...i,verify:"aborted"}),Oe(e.signal);const a=C();if("allow"!==a.status)return ue("list",e.listPath,s,"network","consent_expired"===a.status?"grant_expired":"replica_gated",t.ok?"found":"error",n,{code:"consent_expired"===a.status?a.code:"REPLICA_GATED"}),t;const o=null===s?void 0:j(s);if(o)return ue("list",e.listPath,s,"network","grant_missing",t.ok?"found":"error",n,{code:o}),t;if(!t.ok)return ue("list",e.listPath,s,"replica","hit","found",n,{...i,code:t.error.code,verify:"error"}),ee(r);const c=new Set(r.keys),d=new Set(t.data.keys),u=r.keys.filter(e=>!d.has(e)),p=t.data.keys.filter(e=>!c.has(e)),f=0===u.length&&0===p.length,h=f&&r.keys.every((e,r)=>e===t.data.keys[r]),y=h?"match":"diverged";return f&&h||l({type:"replication.divergence",op:"list",space:e.space,key:e.listPath,replica:s??"",kind:f?"order":"keys",...f?{}:{localOnly:u,networkOnly:p},stalenessMs:"number"==typeof i.stalenessMs?i.stalenessMs:null}),ue("list",e.listPath,s,"replica","hit","found",n,{...i,verify:y}),ee(r)}catch(t){if(e.signal.aborted)return ue("list",e.listPath,s,"none","aborted","error",n,{...i,verify:"aborted"}),Oe(e.signal);const a=C();if("allow"!==a.status)return ue("list",e.listPath,s,"network","consent_expired"===a.status?"grant_expired":"replica_gated","error",n,{code:"consent_expired"===a.status?a.code:"REPLICA_GATED"}),te(se("kv",t));const o=null===s?void 0:j(s);return o?(ue("list",e.listPath,s,"network","grant_missing","error",n,{code:o}),te(se("kv",t))):(ue("list",e.listPath,s,"replica","hit","found",n,{...i,code:Pe(t),verify:"error"}),ee(r))}}(e,d,r,m):(ue("list",e.listPath,s,"replica","hit","found",r,m),ee(d))}catch(t){if(a)throw t;if(e.signal.aborted)return Oe(e.signal);const r=Pe(t);if("CONSENT_EXPIRED"===r&&N(),U(s,t),n&&i)return p();const o="CONSENT_EXPIRED"===r||"REPLICA_GATED"===r||"GRANT_EXPIRED"===r?M(r):ne(r);return u(s,o,{code:r})}},write:async function(e){const t=e.entries.flatMap(t=>void 0!==L(t.path)?[{key:t.path,op:"delete"===e.op?"delete":"put"}]:[]);if(0===t.length)return e.network();if("allow"!==C().status)return e.network();if(await me(),"allow"!==C().status)return e.network();const r=globalThis.crypto?.randomUUID?.()??`${c.now()}-${Math.random()}`;try{await o.update(e=>function(e,t,r,n){const i=r.map(({key:r,op:i})=>({opId:t,seq:++e.seq,key:r,op:i,state:"in_flight",epoch:null,at:n,settledAt:null}));return e.records.push(...i),i}(e,r,t,Ae(c.now())))}catch(t){return"REPLICA_GATED"===Pe(t)||"CONSENT_EXPIRED"===Pe(t)||"allow"!==C().status?e.network():te(re("KV_WRITE_FAILED","Unable to persist pending KV write; request was not dispatched","kv",{cause:t instanceof Error?t:void 0,meta:{replication:"pending_store_unavailable",requestDispatched:!1}}))}const n=c.now();let i;try{i=await e.network()}catch(e){const t=se("kv",e);i=te({...t,meta:{...t.meta,requestMayHaveDispatched:!0}})}const s=function(e,t,r={}){if(t.ok)return"committed";const{code:n,meta:i}=t.error;if("delete"===e&&n===Z)return!0===r.conditional?"failed":"committed";if(!1===i?.requestMayHaveDispatched)return"failed";if(ae.has(n))return"failed";if("batch-unconfirmed"===i?.outcome)return"ambiguous";const s="number"==typeof i?.status?i.status:void 0;return void 0!==s&&s>=400&&s<500?"failed":"ambiguous"}(e.op,i,{conditional:!0===e.conditional});let a;try{await o.update(e=>function(e,t,r,n,i){if("failed"===r)return void(e.records=e.records.filter(e=>e.opId!==t));const s=e.records.filter(e=>e.opId===t&&"in_flight"===e.state);if("committed"===r&&s.length>0){const t=++e.committedEpoch;for(const e of s)e.state="committed",e.epoch=t,e.settledAt=n;return}for(const e of s)e.state="ambiguous",e.settledAt=n,i&&(e.code=i)}(e,r,s,Ae(c.now()),i.ok?void 0:i.error.code))}catch(e){a=e}l({type:"replication.write",space:e.space,op:e.op,keys:t.map(e=>e.key),outcome:s,...i.ok?{}:{code:i.error.code},latencyMs:c.now()-n});const d=await o.read().catch(()=>{}),u=d?ce(d,"",c.now()):[];return"ambiguous"===s&&l({type:"replication.state",space:e.space,state:"pinned",count:u.length,keys:u.map(e=>e.key)}),a&&l({type:"replication.state",space:e.space,state:"pending_store_error",code:"STORAGE_ERROR"}),i},observeNetworkRequested:Ie,observeConsentExpired:function(t){e.stamp&&t.incarnation===e.stamp.incarnation&&t.lifecycleEpoch===e.stamp.lifecycleEpoch&&x()&&l({type:"replication.lifecycle",action:"denied",reason:"consent_expired"})},status:async function(){const r=C();if("allow"!==r.status)return xe(r);let l;try{l=o.readExisting?await o.readExisting():await o.read()}catch(e){const t=C();if("allow"!==t.status)return xe(t);throw e}const f=C();if("allow"!==f.status)return xe(f);const y=l??oe(i),g=await Promise.all(t.prefixes.map(async r=>{"/"!==r||void 0===e.nodeFeatures||e.nodeFeatures.includes("kv-sync-root")||q(r);const o=y.records.filter(e=>K(r,e.key)),l=d.get(r);let f;if(l?.handle)try{f=await l.handle.status()}catch{}let g={missing:!1};if(f||l?.opening||l?.authorityRevoked||(g=await async function(r){if(!n.inspectStatus||p||h)return{missing:!1};const o=a.sessionGrant(r),l="refused"in o?void 0:o.device,d={identity:i,space:s.space,prefix:r,allowSecrets:t.allowSecrets,...l?{device:l}:{},...e.fetch?{fetch:e.fetch}:{}},f=new AbortController,y=Promise.resolve().then(()=>n.inspectStatus(d,{signal:f.signal})),g=y.then(()=>{},()=>{}),v={abort:f,settled:g};u.add(v),g.then(()=>u.delete(v));let E=()=>{};const m=new Promise(e=>{E=c.setTimeout(()=>{f.abort(Object.assign(new Error("Replica status inspection timed out"),{code:"STATUS_TIMEOUT"})),e({timedOut:!0})},Te)});try{const e=await Promise.race([y.then(e=>({local:e})),m]);return"timedOut"in e?{missing:!1,errorCode:"STATUS_TIMEOUT"}:{missing:void 0===e.local,...e.local?{local:e.local}:{}}}catch(e){return{missing:!1,errorCode:Pe(e)}}finally{E()}}(r)),f??(f=g.local),g.missing&&!l?.reason&&!l?.authorityRevoked&&!l?.opening&&!p)return;const v=f&&!("redacted"in f)?f:void 0,E=!0===l?.authorityRevoked||"revoked"===v?.authority.state,m=p?"closed":E?"revoked":"REPLICATION_ROOT_UNSUPPORTED"===l?.lastError||"grant_expired"===l?.reason?"unavailable":"grant_missing"===l?.reason?"grant_missing":"complete"===v?.coverage&&"valid"===v.authority.state?"ready":l?.reason||g.errorCode?"unavailable":"idle";return{prefix:r,state:m,...l?.reason?{reason:l.reason}:g.errorCode?{reason:"replica_unavailable"}:{},...g.errorCode??l?.lastError?{errorCode:g.errorCode??l?.lastError}:{},...f??{},...E?{authority:{state:"revoked",expiresAt:v?.authority.expiresAt??null}}:{},pending:{inFlight:o.filter(e=>"in_flight"===e.state).length,committed:o.filter(e=>"committed"===e.state).length,ambiguous:o.filter(e=>"ambiguous"===e.state).length},pinned:ce(y,r,c.now()),lagMs:v?.lastSyncAt?c.now()-Date.parse(v.lastSyncAt):null}})),v=C();return"allow"!==v.status?xe(v):g.filter(e=>void 0!==e)},sync:async function(e){const r=void 0!==e?.prefix?t.prefixes.filter(t=>t===e.prefix):t.prefixes;await Promise.all(r.map(t=>Y(t,"manual",e?.signal).then(()=>{})))},purge:function(e){var r;f=!0,h=!0,A?.(),A=void 0;const p=u.size>0,y=Ce();for(const e of d.values())e.timer?.(),e.timer=void 0,e.renewalTimer?.(),e.renewalTimer=void 0,e.syncContext&&((r=e.syncContext).abortCause??(r.abortCause="purge")),e.abort?.abort(),e.mintAbort?.abort();return Promise.resolve().then(async()=>{const r={purged:[],failed:[]},u=e?.timeoutMs??5e3,f=async e=>{let t=()=>{};const r=new Promise((e,r)=>{t=c.setTimeout(()=>r(Object.assign(new Error("Replication cleanup timed out"),{code:"TIMEOUT"})),u)});try{return await Promise.race([e,r])}finally{t()}},h=Promise.all([...[...d.values()].flatMap(e=>[e.opening?.catch(()=>{}),e.sync?.catch(()=>{}),e.renewing?.catch(()=>{}),e.handle?.close().catch(()=>{})]),...p?[y]:[]]);let g;try{await f(h)}catch(e){g=Pe(e)}const E=t.prefixes.map(async e=>{try{if(g)throw Object.assign(new Error("Replica cleanup did not settle before purge"),{code:g});const t=a.sessionGrant(e),c=d.get(e)?.handle?.deviceDid??("refused"in t?void 0:t.device.did);await f(n.purge({identity:i,space:s.space,prefix:e,...c?{sessionDeviceDid:c}:{}})),await o.update(t=>function(e,t){const r=e.records.length;return e.records=e.records.filter(e=>!K(t,e.key)),r-e.records.length}(t,e)),d.delete(e),v.delete(e),r.purged.push(e),l({type:"replication.state",space:s.space,replica:e,state:"purged"})}catch(t){const n=Pe(t);r.failed.push({prefix:e,code:n}),l({type:"replication.state",space:s.space,replica:e,state:"purge_failed",code:n})}});return await Promise.all(E),r}).finally(()=>{h=!1})},clearPending:async function(){const e=await o.update(e=>function(e,t){const r=e.records.length;return e.records=e.records.filter(e=>"committed"===e.state||"in_flight"===e.state&&t-Date.parse(e.at)<=6e5),r-e.records.length}(e,c.now()));return l({type:"replication.state",space:s.space,state:"pending_cleared",count:e}),e},close:async function(){var e;if(p)return;p=!0,A?.(),A=void 0;const t=u.size>0,r=Ce();for(const[t,r]of d)r.timer?.(),r.timer=void 0,r.renewalTimer?.(),r.renewalTimer=void 0,r.mintAbort?.abort(),r.syncContext&&((e=r.syncContext).abortCause??(e.abortCause="close")),r.abort?.abort(),l({type:"replication.state",space:s.space,replica:t,state:"closed"});const n=Promise.all([...[...d.values()].map(async e=>{await(e.opening?.catch(()=>{})),await(e.renewing?.catch(()=>{})),await(e.sync?.catch(()=>{})),await(e.handle?.close().catch(()=>{}))}),...t?[r]:[]]);let i=()=>{},a=!1;n.then(()=>{a=!0,i()},()=>{a=!0,i()});const o=new Promise(e=>{queueMicrotask(()=>{a||(i=c.setTimeout(e,Re))})});try{await Promise.race([n,o])}finally{i()}}}}function Se(e){return se("kv",e.reason).code===Y||"object"==typeof e.reason&&null!==e.reason&&"code"in e.reason&&e.reason.code===Y?Y:J}function Oe(e){const t=Se(e);return te(re(t,t===Y?"KV request timed out":"KV request was aborted","kv"))}function Ce(e){const t=$(e),r=B(t);let n=oe(t),i=Promise.resolve();return{identity:t,durable:!1,read:async()=>structuredClone(n),async update(e){let t,s;const a=new Promise((e,r)=>{t=e,s=r}),o=i.then(()=>{try{if(B(n.identity)!==r)throw Object.assign(new Error("Pending-store identity mismatch"),{code:"STORAGE_ERROR"});const i=structuredClone(n),s=e(i);n=i,t(s)}catch(e){s(e)}});return i=o.then(()=>{},()=>{}),a}}}}},i={};function s(e){var t=i[e];if(void 0!==t)return t.exports;var r=i[e]={exports:{}};return n[e](r,r.exports,s),r.exports}s.d=(e,t)=>{for(var r in t)s.o(t,r)&&!s.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var a={};s.d(a,{U:()=>d,r:()=>c});var o=s(461);async function c(){const{indexedDbReplicaStorage:e}=await Promise.resolve().then(s.bind(s,913));return e}const l=s(204).assertValidReplicationConfig,d=Object.freeze({validateConfig:l,loaders:Object.freeze({validateConfig:l,runtime:()=>Promise.resolve().then(s.bind(s,230)),authority:()=>Promise.resolve().then(s.bind(s,204)),gatedNetwork:()=>Promise.resolve().then(s.bind(s,442)),gate:()=>Promise.resolve().then(s.bind(s,435))}),recover:async function(e,t){const r=e.storage,n="indexeddb"===r.kind?r.lifecycle:void 0;if("indexeddb"!==n?.kind)return e;const i=(t,r)=>{try{const n={type:"replication.lifecycle",at:(new Date).toISOString(),action:"unguarded",reason:"startup",gate:"gate_unavailable",code:t};void 0!==r&&(n.remaining=r),e.onEvent?.(n)}catch{}},s=e=>null!==e&&0===e.failed.length&&0===e.remaining,a=(e,t)=>{let r;return Promise.race([e.then(()=>{},()=>{}),new Promise(e=>{r=setTimeout(()=>{t?.abort(),e()},3e3)})]).finally(()=>clearTimeout(r))};let c,l=!1,d=0,u=0,p=void 0===t?"wallet_provider_required":"gate_unavailable";const f=async e=>{const t=await n.recover(e);return l=s(t),l||(c=void 0,d++),t},h=()=>{const e=new AbortController;return a(f({signal:e.signal}),e)};let y;const g=e=>{const t=e().catch(()=>{}).finally(()=>{y===t&&(y=void 0)});return y=t,t},v=new AbortController;let E,m=!1;const w=(async()=>n.recover({signal:v.signal}))().catch(()=>null).then(e=>E=e);g(async()=>{const e=await w;m&&(s(e)?await h():i(e?.failed[0]?.code??(e?"RECOVERY_INCOMPLETE":"STORAGE_ERROR"),e?.remaining))}),await a(w,v),m=void 0===E,E&&(l=s(E)),l||i(E?.failed[0]?.code??(m?"RECOVERY_TIMEOUT":"STORAGE_ERROR"),E?.remaining);const _=()=>Object.assign(new Error("Replica wallet or startup recovery is unavailable."),{code:"REPLICA_GATED",gate:l?p:"gate_unavailable"}),b=()=>Promise.reject(_()),R=()=>{throw _()},T=async e=>{const r=(0,o.__replicaParsePkhDid)(e)?.address,n=await(t?.getConnectedAddress().catch(()=>{}));return p=void 0===t?"wallet_provider_required":n?"principal_mismatch":"gate_unavailable",void 0!==r&&void 0!==n&&r.toLowerCase()===n.toLowerCase()},A=async()=>{const e=c;if(!l||!e)throw _();if(!await T(e)||c!==e)throw c=void 0,_()},P=async(e,t)=>{const r=++d;if(c=void 0,!l&&y&&await a(y),!l&&!y&&u<2&&(u++,await g(h)),!l||!await T(e)||r!==d)throw _();const n=await t();if(r!==d)throw _();if(c=e,await A(),r!==d)throw _();return n},k=(e,t,r)=>{if(r.has(t))return r.get(t);const n=Reflect.get(e,t,e);if("function"!=typeof n)return n;const i=n.bind(e);return r.set(t,i),i},I=new Map,S=new Proxy(n,{get(e,t){if("recover"===t)return f;if("establishSessionStamp"===t)return(...t)=>P(t[0],()=>e.establishSessionStamp(...t));if("restoreSessionStamp"===t)return(...t)=>P(t[0],()=>e.restoreSessionStamp(...t));if("deny"===t)return(...t)=>(d++,c=void 0,e.deny(...t));if(!l||!c){if("activationAllowed"===t)return()=>Promise.resolve(!1);if("checkDelivery"===t)return()=>({status:"gated",gate:l?p:"gate_unavailable"});if("deliverable"===t)return()=>!1;if("consentDeadline"===t)return()=>null}return k(e,t,I)}}),O=new Map,C=new Proxy(r,{get(e,t){if("lifecycle"===t)return S;if("open"===t)return async(...t)=>{await A();const r=await e.open(...t);try{await A()}catch(e){throw await r.close().catch(()=>{}),e}const n=new Map,i=async(...e)=>{await A();const t=await r.get(...e);return await A(),t},s=async(...e)=>{await A();const t=await r.list(...e);return await A(),t};return new Proxy(r,{get:(e,t)=>"get"===t?i:"list"===t?s:k(e,t,n)})};if(!l||!c){if("inspectStatus"===t)return b;if("pendingWrites"===t)return R}return k(e,t,O)}});return{...e,storage:C}}}),u=a.U,p=a.r;export{u as browserReplicaPlugin,p as loadIndexedDbReplicaStorage};
package/dist/ui/api.d.ts CHANGED
@@ -12,6 +12,13 @@ export interface TinyCloudUI {
12
12
  /** Closes the panel only. Never changes the hidden flag. */
13
13
  close(): void;
14
14
  toggle(): void;
15
+ /**
16
+ * Shows or hides the floating button now. `true` shows it even under `ui.button: false` for this page
17
+ * session and clears the persisted hidden flag. `false` hides it without writing that flag. The SDK
18
+ * does not persist the choice: the host app calls this on load from its own setting. `open()`,
19
+ * `openPage()` and `toggle()` work whether the button is shown or not.
20
+ */
21
+ setButtonVisible(visible: boolean): void;
15
22
  readonly isOpen: boolean;
16
23
  /** False in iframes, opaque origins, SSR, no document, or when `ui: false`. */
17
24
  readonly available: boolean;
@@ -21,6 +28,7 @@ export interface UiTarget {
21
28
  openPage(section?: SectionId): void;
22
29
  close(): void;
23
30
  isOpen(): boolean;
31
+ setButtonVisible(visible: boolean): void;
24
32
  }
25
33
  /**
26
34
  * `getTarget` returns undefined when this client is not registered (ui:false,
@@ -1,5 +1,6 @@
1
- import type { IStorageService } from "@tinycloud/sdk-core";
1
+ import type { IStorageService, PermissionEntry } from "@tinycloud/sdk-core";
2
2
  import type { PanelDataFactory } from "./data";
3
+ import type { UiPlatform } from "./config";
3
4
  import type { PanelClient, PurgeLocalCopyResult, RequestLogReader, SyncFacade } from "./slots";
4
5
  /**
5
6
  * What the UI reads from a TinyCloudWeb instance. The panel never sees
@@ -17,11 +18,22 @@ export interface ClientSource {
17
18
  signOut?: (() => Promise<void>) | undefined;
18
19
  /** Removes the local copy from this browser; the panel calls it after sign-out settles. Undefined: nothing to purge. */
19
20
  purgeLocalCopy?: (() => Promise<PurgeLocalCopyResult>) | undefined;
21
+ /**
22
+ * True when this page can show the SDK's permission prompt: a page signer and a manifest exist. Absent: no.
23
+ * Read on each use, so it turns false after sign-out.
24
+ */
25
+ canRequestPermissions?(): boolean;
26
+ /** Asks the SDK for `entries` as a runtime grant. Resolves `{ approved: false }` on a decline; rejects on an error. */
27
+ requestPermissions?(entries: PermissionEntry[], options: {
28
+ expiryMs: number;
29
+ }): Promise<{
30
+ approved: boolean;
31
+ }>;
20
32
  }
21
33
  export interface PanelClientHandle {
22
34
  readonly client: PanelClient;
23
35
  /** Clears this client's per-account view state and fires onReset listeners. */
24
36
  reset(): void;
25
37
  }
26
- export declare function createPanelClient(id: number, source: ClientSource, dataFactory?: PanelDataFactory): PanelClientHandle;
38
+ export declare function createPanelClient(id: number, source: ClientSource, dataFactory?: PanelDataFactory, platform?: UiPlatform): PanelClientHandle;
27
39
  //# sourceMappingURL=client.d.ts.map
@@ -7,6 +7,12 @@ type BottomPosition = "bottom-right" | "bottom-left" | "bottom-center";
7
7
  * opens the full page directly.
8
8
  */
9
9
  export type UiMode = "sidebar" | "page" | "both";
10
+ /**
11
+ * Where the app runs. `"web"` (default) is a browser page with its own wallet signer. `"native"` is a
12
+ * desktop or mobile shell that cannot show the permission prompt in the page: the panel then explains
13
+ * that and offers no working "allow" button.
14
+ */
15
+ export type UiPlatform = "web" | "native";
10
16
  /** Config passed as `ui` on TinyCloudWeb. `ui: false` disables the UI entirely (see index.ts). */
11
17
  export interface UiConfig {
12
18
  /** Default true. false hides the button only; the panel, prompts, and open() still work. */
@@ -21,6 +27,8 @@ export interface UiConfig {
21
27
  appId?: string;
22
28
  /** Default "both". Which layouts the panel offers. */
23
29
  mode?: UiMode;
30
+ /** Default "web". Set "native" in a desktop or mobile shell, where the panel cannot ask for a permission itself. */
31
+ platform?: UiPlatform;
24
32
  }
25
33
  export interface ResolvedUiConfig {
26
34
  readonly button: boolean;
@@ -29,6 +37,7 @@ export interface ResolvedUiConfig {
29
37
  readonly position: BottomPosition;
30
38
  readonly appId: string | undefined;
31
39
  readonly mode: UiMode;
40
+ readonly platform: UiPlatform;
32
41
  }
33
42
  export declare function resolveUiConfig(ui: UiConfig | undefined): ResolvedUiConfig;
34
43
  export {};
@@ -0,0 +1,26 @@
1
+ import type { PermissionEntry } from "@tinycloud/sdk-core";
2
+ import type { PanelDataHost, PermissionAbility } from "../data";
3
+ /** The account index read: `tinycloud.sql/read` on the `account` database of the account space. */
4
+ export declare const ACCOUNT_INDEX_READ: PermissionEntry;
5
+ /** `tinycloud.space/info` on one space, given by its full space id: the storage status read. */
6
+ export declare function spaceInfoOn(spaceId: string): PermissionEntry;
7
+ /**
8
+ * True when the session holds `entry`. A host that cannot tell (`hasPermissions` absent) answers true,
9
+ * so its reads are sent as before.
10
+ */
11
+ export declare function sessionHolds(host: Pick<PanelDataHost, "hasPermissions">, entry: PermissionEntry): boolean;
12
+ /**
13
+ * The one read-only entry a tab asks for when its no-access state shows a button, keyed by the ability that state
14
+ * names. Delegations: `delegation/list` on this app's own space (`applications`), never the account space.
15
+ * A tab with no entry here has no button.
16
+ */
17
+ export declare const TAB_PERMISSION: Readonly<Partial<Record<PermissionAbility, PermissionEntry>>>;
18
+ /** Requested lifetime of a panel-requested grant: 7 days. The SDK shortens it to the session's own expiry. */
19
+ export declare const TAB_PERMISSION_EXPIRY_MS: number;
20
+ /**
21
+ * The spaces to sign the delegation query for, in the order the SDK tries them (account space, then the
22
+ * session's own space), limited to those the session holds `delegation/list` on. Empty: nothing to send.
23
+ * `undefined`: the host cannot tell, so the SDK picks its own spaces.
24
+ */
25
+ export declare function delegationQuerySpaces(host: Pick<PanelDataHost, "hasPermissions" | "accountSpaceId" | "spaceId">): readonly string[] | undefined;
26
+ //# sourceMappingURL=authority.d.ts.map
package/dist/ui/data.d.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * Panel code reads these shapes through a `PanelDataSource`. It never reads
14
14
  * TinyCloudWeb directly.
15
15
  */
16
- import type { AccountDelegationRecord, AccountService, AccountStatus, DelegationManager, IStorageService, StorageStatus, StorageUsage } from "@tinycloud/sdk-core";
16
+ import type { AccountDelegationRecord, AccountService, AccountStatus, DelegationManager, IStorageService, PermissionEntry, StorageStatus, StorageUsage } from "@tinycloud/sdk-core";
17
17
  import type { PanelClient, SyncState } from "./slots";
18
18
  export type DataSource = "real" | "stub" | "derived";
19
19
  /** Per-field source for records that mix real and stub fields. */
@@ -213,6 +213,15 @@ export interface PanelDataHost {
213
213
  readonly origin: string;
214
214
  readonly nodeDid: string;
215
215
  }>;
216
+ /**
217
+ * Whether the session or an unexpired runtime grant covers every entry (`tc.hasPermissions`). Never prompts.
218
+ * Absent on a host that cannot tell: panel reads then go out as they always did.
219
+ */
220
+ hasPermissions?(entries: PermissionEntry[]): boolean;
221
+ /** Account space id (`tc.accountSpaceId`). The delegation query signs for it first. */
222
+ readonly accountSpaceId?: string;
223
+ /** The session's own space id (`tc.spaceId`). The delegation query falls back to it. */
224
+ readonly spaceId?: string;
216
225
  }
217
226
  export interface PanelDataSource {
218
227
  /** Fires when any view's data changes (toggle, revoke, stub change). Returns unsubscribe. */
package/dist/ui/host.d.ts CHANGED
@@ -20,6 +20,8 @@ export interface HostRuntime {
20
20
  unregister(id: number): void;
21
21
  reset(id: number): void;
22
22
  open(section?: SectionId): void;
23
+ /** Absent on a runtime created by an older web-sdk bundle that shares the page. */
24
+ setButtonVisible?(visible: boolean): void;
23
25
  openPage(section?: SectionId): void;
24
26
  close(): void;
25
27
  isOpen(): boolean;