@tensorix/metahub 0.5.8 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +35 -14
  2. package/README.zh-CN.md +41 -13
  3. package/dist/cli.js +5175 -2272
  4. package/dist/cli.js.map +69 -48
  5. package/dist/core/blobs.d.ts.map +1 -1
  6. package/dist/core/blocks.d.ts +6 -2
  7. package/dist/core/blocks.d.ts.map +1 -1
  8. package/dist/core/compact.d.ts.map +1 -1
  9. package/dist/core/crdt.d.ts +5 -6
  10. package/dist/core/crdt.d.ts.map +1 -1
  11. package/dist/core/db.d.ts.map +1 -1
  12. package/dist/core/documents.d.ts +39 -0
  13. package/dist/core/documents.d.ts.map +1 -1
  14. package/dist/core/errors.d.ts +6 -1
  15. package/dist/core/errors.d.ts.map +1 -1
  16. package/dist/core/history-archive.d.ts +41 -0
  17. package/dist/core/history-archive.d.ts.map +1 -0
  18. package/dist/core/history.d.ts.map +1 -1
  19. package/dist/core/hlc.d.ts +4 -0
  20. package/dist/core/hlc.d.ts.map +1 -1
  21. package/dist/core/node.d.ts.map +1 -1
  22. package/dist/core/properties.d.ts +6 -0
  23. package/dist/core/properties.d.ts.map +1 -1
  24. package/dist/core/replica/drafts.d.ts +26 -0
  25. package/dist/core/replica/drafts.d.ts.map +1 -0
  26. package/dist/core/replica/rpc.d.ts +8 -0
  27. package/dist/core/replica/rpc.d.ts.map +1 -0
  28. package/dist/core/replica/service.d.ts +970 -0
  29. package/dist/core/replica/service.d.ts.map +1 -0
  30. package/dist/core/replica/sync.d.ts +55 -0
  31. package/dist/core/replica/sync.d.ts.map +1 -0
  32. package/dist/core/schema-init.d.ts +1 -1
  33. package/dist/core/schema-init.d.ts.map +1 -1
  34. package/dist/core/search.d.ts +34 -0
  35. package/dist/core/search.d.ts.map +1 -1
  36. package/dist/core/snapshot.d.ts.map +1 -1
  37. package/dist/core/sync/bucket-v2.d.ts +110 -0
  38. package/dist/core/sync/bucket-v2.d.ts.map +1 -0
  39. package/dist/core/sync/client.d.ts +14 -1
  40. package/dist/core/sync/client.d.ts.map +1 -1
  41. package/dist/core/sync/commit-log.d.ts +41 -0
  42. package/dist/core/sync/commit-log.d.ts.map +1 -0
  43. package/dist/core/sync/current-checkpoint.d.ts +47 -0
  44. package/dist/core/sync/current-checkpoint.d.ts.map +1 -0
  45. package/dist/core/sync/data-map-db.d.ts.map +1 -1
  46. package/dist/core/sync/data-version.d.ts +29 -0
  47. package/dist/core/sync/data-version.d.ts.map +1 -0
  48. package/dist/core/sync/drop-keys.d.ts.map +1 -1
  49. package/dist/core/sync/drop-pull.d.ts.map +1 -1
  50. package/dist/core/sync/e2ee.d.ts +5 -0
  51. package/dist/core/sync/e2ee.d.ts.map +1 -1
  52. package/dist/core/sync/enroll.d.ts +2 -0
  53. package/dist/core/sync/enroll.d.ts.map +1 -1
  54. package/dist/core/sync/history-observation.d.ts +5 -0
  55. package/dist/core/sync/history-observation.d.ts.map +1 -0
  56. package/dist/core/sync/http-status.d.ts.map +1 -1
  57. package/dist/core/sync/page-messages.d.ts +8 -0
  58. package/dist/core/sync/page-messages.d.ts.map +1 -1
  59. package/dist/core/sync/peer-v2.d.ts +9 -0
  60. package/dist/core/sync/peer-v2.d.ts.map +1 -0
  61. package/dist/core/sync/peers.d.ts +1 -0
  62. package/dist/core/sync/peers.d.ts.map +1 -1
  63. package/dist/core/sync/portable-json.d.ts +5 -0
  64. package/dist/core/sync/portable-json.d.ts.map +1 -0
  65. package/dist/core/sync/protocol.d.ts +32 -0
  66. package/dist/core/sync/protocol.d.ts.map +1 -1
  67. package/dist/core/sync/recovery-desktop.d.ts +6 -0
  68. package/dist/core/sync/recovery-desktop.d.ts.map +1 -0
  69. package/dist/core/sync/recovery-intent.d.ts +7 -0
  70. package/dist/core/sync/recovery-intent.d.ts.map +1 -0
  71. package/dist/core/sync/recovery-local.d.ts +21 -0
  72. package/dist/core/sync/recovery-local.d.ts.map +1 -0
  73. package/dist/core/sync/recovery-v2.d.ts +40 -0
  74. package/dist/core/sync/recovery-v2.d.ts.map +1 -0
  75. package/dist/core/sync/retention-executor.d.ts +77 -0
  76. package/dist/core/sync/retention-executor.d.ts.map +1 -0
  77. package/dist/core/sync/retention-protocol.d.ts +74 -0
  78. package/dist/core/sync/retention-protocol.d.ts.map +1 -0
  79. package/dist/core/sync/retention-state.d.ts +87 -0
  80. package/dist/core/sync/retention-state.d.ts.map +1 -0
  81. package/dist/core/sync/routes.d.ts +1 -1
  82. package/dist/core/sync/routes.d.ts.map +1 -1
  83. package/dist/core/sync/server.d.ts +1 -1
  84. package/dist/core/sync/server.d.ts.map +1 -1
  85. package/dist/core/sync/share-export.d.ts.map +1 -1
  86. package/dist/core/sync/share-serve.d.ts.map +1 -1
  87. package/dist/core/sync/share-tools.d.ts +10 -0
  88. package/dist/core/sync/share-tools.d.ts.map +1 -0
  89. package/dist/core/sync/storage-s3-bun.d.ts +2 -1
  90. package/dist/core/sync/storage-s3-bun.d.ts.map +1 -1
  91. package/dist/core/sync/storage-s3-fetch.d.ts +8 -0
  92. package/dist/core/sync/storage-s3-fetch.d.ts.map +1 -0
  93. package/dist/core/sync/storage-s3-sign.d.ts +3 -0
  94. package/dist/core/sync/storage-s3-sign.d.ts.map +1 -1
  95. package/dist/core/sync/storage-v2.d.ts +18 -0
  96. package/dist/core/sync/storage-v2.d.ts.map +1 -0
  97. package/dist/core/sync/storage.d.ts +47 -6
  98. package/dist/core/sync/storage.d.ts.map +1 -1
  99. package/dist/core/sync/transport.d.ts +4 -0
  100. package/dist/core/sync/transport.d.ts.map +1 -0
  101. package/dist/core/sync/v2-ingest.d.ts +10 -0
  102. package/dist/core/sync/v2-ingest.d.ts.map +1 -0
  103. package/dist/core/sync/v2-maintenance.d.ts +10 -0
  104. package/dist/core/sync/v2-maintenance.d.ts.map +1 -0
  105. package/dist/db-worker.js +212 -160
  106. package/dist/edge-worker.js +4952 -186
  107. package/dist/index.js +9243 -6455
  108. package/dist/index.js.map +67 -47
  109. package/dist/metahub-sdk.js +5 -5
  110. package/dist/mh-runtime.js +2 -2
  111. package/dist/shared/views/date.d.ts +21 -0
  112. package/dist/shared/views/date.d.ts.map +1 -0
  113. package/dist/shared/views/model.d.ts +65 -0
  114. package/dist/shared/views/model.d.ts.map +1 -0
  115. package/dist/shared/views/query.d.ts +47 -0
  116. package/dist/shared/views/query.d.ts.map +1 -0
  117. package/dist/sw.js +9 -9
  118. package/dist/webui/server/routes.d.ts.map +1 -1
  119. package/dist/webui.js +131 -131
  120. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
- class d extends Error{code;i18n;constructor(n,e,t){super(e);this.code=n;this.i18n=t;this.name="MhError"}}function Et(n,e){return e?n.replace(/\{(\w+)\}/g,(t,r)=>(r in e)?String(e[r]):t):n}function xe(n,e,t){return new d(n,Et(e,t),{key:e,params:t})}function L(n=6){let e=crypto.getRandomValues(new Uint8Array(n)),t="";for(let r of e)t+="0123456789abcdefghijklmnopqrstuvwxyz".charAt(r%36);return t}function de(n,e="item"){return n.normalize("NFKD").replace(/[^\x20-\x7E]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,32).replace(/-+$/g,"")||e}var Rt=new Set(["db","prop","rec","doc","blk","site","sf","chan"]);function J(n,e,t=n){return`${n}_${de(e,t)}-${L()}`}function z(n){let e=n.indexOf("_");if(e<=0)return null;let t=n.slice(0,e);return Rt.has(t)?t:null}var St=600000;function ve(n){let e=new Uint8Array(n.byteLength);return e.set(n),e.buffer}function se(n){let e="";for(let t=0;t<n.length;t++)e+=String.fromCharCode(n[t]);return btoa(e)}function ae(n){let e=atob(n),t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}async function ke(n,e){let t=await crypto.subtle.importKey("raw",ve(new TextEncoder().encode(n)),"PBKDF2",!1,["deriveBits"]),r=await crypto.subtle.deriveBits({name:"PBKDF2",salt:ve(e),iterations:St,hash:"SHA-256"},t,256);return new Uint8Array(r)}var ue=65535,Ae=300000;function Te(n,e){if(e<=ue)return{millis:n,counter:e};return{millis:n+Math.floor(e/(ue+1)),counter:e%(ue+1)}}function Pe(n){let{millis:e,counter:t}=Te(n.millis,n.counter);return`${String(e).padStart(15,"0")}-${t.toString(16).padStart(4,"0")}-${n.node}`}function Ce(n){let e=n.indexOf("-"),t=n.indexOf("-",e+1);return{millis:Number(n.slice(0,e)),counter:parseInt(n.slice(e+1,t),16),node:n.slice(t+1)}}function xt(n,e){let t=n.query("SELECT value FROM meta WHERE key = 'hlc'").get();return t?Ce(t.value):{millis:0,counter:0,node:e}}function vt(n,e){n.query("INSERT INTO meta (key, value) VALUES ('hlc', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(Pe(e))}function Oe(n,e,t=Date.now()){let r=xt(n,e);if(r.millis>t+Ae)throw xe("clock_skew","本机逻辑时钟比系统时间超前 {min} 分钟(系统时钟曾被调错,或收到过时钟错误设备的数据),运行 mh repair --clock 修复",{min:Math.ceil((r.millis-t)/60000)});let o=Math.max(r.millis,t),i=o===r.millis?r.counter+1:0,a={...Te(o,i),node:e};return vt(n,a),Pe(a)}function Ne(n,e,t,r){if(!Array.isArray(n))return n;let o=(a)=>!!a&&typeof a==="object"&&!Array.isArray(a),i=(a)=>typeof a==="string"?e.get(a)??a:a;return n.map((a)=>{if(!o(a))return a;let s={...a};for(let l of["group","dateProp","start","end"])if(l in s)s[l]=i(s[l]);if(Array.isArray(a.hidden))s.hidden=a.hidden.map(i);if(Array.isArray(a.sort))s.sort=a.sort.map((l)=>o(l)?{...l,prop:i(l.prop)}:l);if(o(a.filter)&&Array.isArray(a.filter.rules))s.filter={...a.filter,rules:a.filter.rules.map((l)=>{if(!o(l))return l;return{...l,prop:i(l.prop),...typeof l.prop==="string"&&r.has(l.prop)&&Array.isArray(l.value)?{value:l.value.map((u)=>typeof u==="string"?t.get(u)??u:u)}:{}}})};if(o(a.calc))s.calc=Object.fromEntries(Object.entries(a.calc).map(([l,u])=>[e.get(l)??l,u]));return s})}function pe(n,e){let t=n.transaction(e);return(t.immediate??t)()}function Me(n){let e=n.query("SELECT value FROM meta WHERE key = 'node_id'").get();if(e)return e.value;let t=L(8);return n.query("INSERT INTO meta (key, value) VALUES ('node_id', ?)").run(t),t}function Le(n){let e=n.filter((r)=>!!r.text&&r.text.length>0),t=[];return e.forEach((r,o)=>{t.push(...r.text.split(`
1
+ class c extends Error{code;i18n;constructor(n,e,t){super(e);this.code=n;this.i18n=t;this.name="MhError"}}class fe extends c{workspaceDataVersion;clientMaxDataVersion;constructor(n,e){super("client_update_required",`需要更新客户端:工作区数据版本为 ${n},本客户端最高支持 ${e}。`,{key:"需要更新客户端:工作区数据版本为 {workspaceDataVersion},本客户端最高支持 {clientMaxDataVersion}。",params:{workspaceDataVersion:n,clientMaxDataVersion:e}});this.workspaceDataVersion=n;this.clientMaxDataVersion=e}}function At(n,e){return e?n.replace(/\{(\w+)\}/g,(t,r)=>(r in e)?String(e[r]):t):n}function Ae(n,e,t){return new c(n,At(e,t),{key:e,params:t})}function L(n=6){let e=crypto.getRandomValues(new Uint8Array(n)),t="";for(let r of e)t+="0123456789abcdefghijklmnopqrstuvwxyz".charAt(r%36);return t}function ge(n,e="item"){return n.normalize("NFKD").replace(/[^\x20-\x7E]/g,"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,32).replace(/-+$/g,"")||e}var Tt=new Set(["db","prop","rec","doc","blk","site","sf","chan"]);function J(n,e,t=n){return`${n}_${ge(e,t)}-${L()}`}function z(n){let e=n.indexOf("_");if(e<=0)return null;let t=n.slice(0,e);return Tt.has(t)?t:null}var Ot=600000;function Te(n){let e=new Uint8Array(n.byteLength);return e.set(n),e.buffer}function ae(n){let e="";for(let t=0;t<n.length;t++)e+=String.fromCharCode(n[t]);return btoa(e)}function le(n){let e=atob(n),t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}async function Oe(n,e){let t=await crypto.subtle.importKey("raw",Te(new TextEncoder().encode(n)),"PBKDF2",!1,["deriveBits"]),r=await crypto.subtle.deriveBits({name:"PBKDF2",salt:Te(e),iterations:Ot,hash:"SHA-256"},t,256);return new Uint8Array(r)}var me=65535,Ce=300000;function Ne(n,e){if(e<=me)return{millis:n,counter:e};return{millis:n+Math.floor(e/(me+1)),counter:e%(me+1)}}function Pe(n){let{millis:e,counter:t}=Ne(n.millis,n.counter);return`${String(e).padStart(15,"0")}-${t.toString(16).padStart(4,"0")}-${n.node}`}function Le(n){let e=n.indexOf("-"),t=n.indexOf("-",e+1);return{millis:Number(n.slice(0,e)),counter:parseInt(n.slice(e+1,t),16),node:n.slice(t+1)}}function Ct(n,e){let t=n.query("SELECT value FROM meta WHERE key = 'hlc'").get();return t?Le(t.value):{millis:0,counter:0,node:e}}function Nt(n,e){n.query("INSERT INTO meta (key, value) VALUES ('hlc', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(Pe(e))}function $e(n,e,t=Date.now()){let r=Ct(n,e);if(r.millis>t+Ce)throw Ae("clock_skew","本机逻辑时钟比系统时间超前 {min} 分钟(系统时钟曾被调错,或收到过时钟错误设备的数据),运行 mh repair --clock 修复",{min:Math.ceil((r.millis-t)/60000)});let o=Math.max(r.millis,t),i=o===r.millis?r.counter+1:0,a={...Ne(o,i),node:e};return Nt(n,a),Pe(a)}function Me(n,e,t,r){if(!Array.isArray(n))return n;let o=(a)=>!!a&&typeof a==="object"&&!Array.isArray(a),i=(a)=>typeof a==="string"?e.get(a)??a:a;return n.map((a)=>{if(!o(a))return a;let s={...a};for(let l of["group","dateProp","start","end"])if(l in s)s[l]=i(s[l]);if(Array.isArray(a.hidden))s.hidden=a.hidden.map(i);if(Array.isArray(a.sort))s.sort=a.sort.map((l)=>o(l)?{...l,prop:i(l.prop)}:l);if(o(a.filter)&&Array.isArray(a.filter.rules))s.filter={...a.filter,rules:a.filter.rules.map((l)=>{if(!o(l))return l;return{...l,prop:i(l.prop),...typeof l.prop==="string"&&r.has(l.prop)&&Array.isArray(l.value)?{value:l.value.map((p)=>typeof p==="string"?t.get(p)??p:p)}:{}}})};if(o(a.calc))s.calc=Object.fromEntries(Object.entries(a.calc).map(([l,p])=>[e.get(l)??l,p]));return s})}var Pt={databases:{tier:"content",synced:!0},properties:{tier:"content",synced:!0},records:{tier:"content",synced:!0},documents:{tier:"content",synced:!0},doc_blocks:{tier:"content",synced:!0},sites:{tier:"content",synced:!0},site_files:{tier:"content",synced:!0},site_channels:{tier:"system",synced:!0},blob_policy:{tier:"system",synced:!0},nodes:{tier:"system",synced:!0},meta:{tier:"local",synced:!1},crdt_changes:{tier:"local",synced:!1},peers:{tier:"local",synced:!1},storage_cursors:{tier:"local",synced:!1},room_rows:{tier:"local",synced:!1},peer_grants:{tier:"local",synced:!1},pairing_codes:{tier:"local",synced:!1},shares:{tier:"local",synced:!1},site_channel_observations:{tier:"local",synced:!1},blob_cache:{tier:"local",synced:!1},drop_rejects:{tier:"local",synced:!1},search_fts:{tier:"local",synced:!1}},ce=(n)=>Object.entries(Pt).filter(([,e])=>n(e)).map(([e])=>e),Lt=ce((n)=>n.synced),Mn=ce((n)=>n.tier==="content"),In=ce((n)=>n.tier==="system"),Hn=ce((n)=>n.tier==="local");function ue(n,e){let t=n.transaction(e);return(t.immediate??t)()}var Ie={minSupportedDataVersion:1,maxSupportedDataVersion:2},$t="sync_workspace_data_version";function He(n){let e=n.query("SELECT value FROM meta WHERE key=?").get($t);if(!e)return null;let t=JSON.parse(e.value);if(!t||typeof t.workspaceId!=="string"||!t.workspaceId||!Number.isSafeInteger(t.dataVersion)||t.dataVersion<2)throw new c("invalid_input","Invalid saved workspace data version");return t}function Mt(n,e=Number(Ie.maxSupportedDataVersion),t=Number(Ie.minSupportedDataVersion)){if(!Number.isSafeInteger(n)||n<1)throw new c("invalid_input","Invalid workspace data version");if(!Number.isSafeInteger(e)||!Number.isSafeInteger(t)||t<1||e<t)throw new c("invalid_input","Invalid supported data version");if(n>e)throw new fe(n,e);if(n<t)throw new c("upgrade_required","Workspace data version requires migration")}function Ue(n){if(qe(n),n.query("SELECT 1 FROM meta WHERE key='sync_version_pending_join'").get())throw new c("busy","请先联网确认工作区版本")}function qe(n){let e=He(n);if(Mt(e?.dataVersion??2),e?.awaitingCompatibleClient)throw new c("busy","请先联网确认工作区版本")}function Ge(n){let e=n.query("SELECT value FROM meta WHERE key = 'node_id'").get();if(e)return e.value;let t=L(8);return n.query("INSERT INTO meta (key, value) VALUES ('node_id', ?)").run(t),t}function We(n){let e=n.filter((r)=>!!r.text&&r.text.length>0),t=[];return e.forEach((r,o)=>{t.push(...r.text.split(`
2
2
  `));let i=Math.max(0,r.blankAfter??0);if(o<e.length-1)t.push("");for(let a=0;a<i;a++)t.push("")}),t.join(`
3
- `)}var kt=new WeakMap;function fe(n,e){let t=n.docs.get(e);if(!t)return;n.docs.delete(e);for(let r of t.blockIds)if(n.blockToDoc.get(r)===e)n.blockToDoc.delete(r)}function Ie(n,e,t,r,o){let i=kt.get(n);if(!i)return;if(e==="documents"){fe(i,t);return}if(e!=="doc_blocks")return;let a=i.blockToDoc.get(t);if(a)fe(i,a);if(r==="doc_id"&&o)try{let s=JSON.parse(o);if(typeof s==="string")fe(i,s)}catch{}}var He="intent_receipts";var At=["hlc","node_id","dataset","row_id","col","value","txn"];var Wn=At.join(", "),ee=null,Ue=null;var Tt=null;function $e(n,e,t){if(ee!==null)return t();ee=(Ue?Ue+"/":"")+(e?e+":":"")+L(8);try{return pe(n,t)}finally{ee=null}}function v(n,e=null){return(t,...r)=>$e(t,e,()=>n(t,...r))}var Pt={databases:{table:"databases",cols:new Set(["name","icon","meta","created_hlc","__deleted"])},properties:{table:"properties",cols:new Set(["database_id","name","type","config","position","__deleted"])},documents:{table:"documents",cols:new Set(["title","body","database_id","parent_id","created_hlc","order_key","__deleted"])},doc_blocks:{table:"doc_blocks",cols:new Set(["doc_id","text","order_key","blank_after","__deleted"])},sites:{table:"sites",cols:new Set(["name","title","created_hlc","visibility","spa","public_grants","__deleted"])},site_channels:{table:"site_channels",cols:new Set(["site_id","audience","hosting","controller_node_id","target_ref","canonical_url","policy_json","desired_state","created_hlc","__deleted"])},site_files:{table:"site_files",cols:new Set(["site_id","path","content_type","encoding","content","created_hlc","__deleted"])},blob_policy:{table:"blob_policy",cols:new Set(["full_nodes","redundancy","__deleted"])},nodes:{table:"nodes",cols:new Set(["label","platform","form","app","first_seen","__deleted"])}},Ct=new Set(["database_id","created_hlc","order_key","__deleted"]),Ot=new Set([He]),Nt=new Set(["records:__deleted","databases:__deleted","properties:__deleted","documents:__deleted","doc_blocks:__deleted","doc_blocks:blank_after","sites:__deleted","sites:spa","site_channels:__deleted","site_files:__deleted","blob_policy:__deleted","nodes:__deleted"]);function Ge(n,e,t){if(t!==null)return JSON.parse(t);return Nt.has(`${n}:${e}`)?0:null}function qe(n){if(n===null||n===void 0)return null;if(typeof n==="boolean")return n?1:0;if(typeof n==="number")return n;if(typeof n==="string")return n;return JSON.stringify(n)}function Z(n,e,t){n.query(`INSERT OR IGNORE INTO ${e} (id) VALUES (?)`).run(t)}function Mt(n,e){return n.query("SELECT 1 AS x FROM doc_blocks WHERE doc_id = ? LIMIT 1").get(e)!=null}function $t(n,e){let t=n.query("SELECT text, blank_after FROM doc_blocks WHERE doc_id = ? AND __deleted = 0 ORDER BY order_key, id").all(e);Z(n,"documents",e),n.query("UPDATE documents SET body = ? WHERE id = ?").run(Le(t.map((r)=>({text:r.text,blankAfter:r.blank_after??0}))),e)}function Lt(n,e,t,r,o){if(Ot.has(e))return;if(e==="records"){if(Ct.has(r)){Z(n,"records",t);let s=Ge("records",r,o);n.query(`UPDATE records SET "${r}" = ? WHERE id = ?`).run(qe(s),t)}else if(Z(n,"records",t),o===null)n.query(`UPDATE records SET data = json_remove(data, '$."' || ? || '"') WHERE id = ?`).run(r,t);else n.query(`UPDATE records SET data = json_set(coalesce(data, '{}'), '$."' || ? || '"', json(?)) WHERE id = ?`).run(r,o,t);return}if(e==="databases"&&r.startsWith("meta.")){Z(n,"databases",t);let s=r.slice(5);if(o===null)n.query(`UPDATE databases SET meta = json_remove(coalesce(meta, '{}'), '$."' || ? || '"') WHERE id = ?`).run(s,t);else n.query(`UPDATE databases SET meta = json_set(coalesce(meta, '{}'), '$."' || ? || '"', json(?)) WHERE id = ?`).run(s,o,t);return}let i=Pt[e];if(!i||!i.cols.has(r))return;if(e==="documents"&&r==="body"&&Mt(n,t))return;Z(n,i.table,t);let a=Ge(e,r,o);if(n.query(`UPDATE ${i.table} SET "${r}" = ? WHERE id = ?`).run(qe(a),t),e==="doc_blocks"){let s=n.query("SELECT doc_id FROM doc_blocks WHERE id = ?").get(t);if(s?.doc_id)$t(n,s.doc_id)}}function It(n,e){let t=n.query("INSERT OR IGNORE INTO crdt_changes (hlc, node_id, dataset, row_id, col, value, txn) VALUES (?, ?, ?, ?, ?, ?, ?)").run(e.hlc,e.node_id,e.dataset,e.row_id,e.col,e.value,e.txn??null).changes>0,r=n.query("SELECT MAX(hlc) AS h FROM crdt_changes WHERE dataset = ? AND row_id = ? AND col = ?").get(e.dataset,e.row_id,e.col);if(t)Ie(n,e.dataset,e.row_id,e.col,e.value);if(r.h!==e.hlc)return{inserted:t,winner:!1};try{Lt(n,e.dataset,e.row_id,e.col,e.value)}catch(o){if(t)n.query("DELETE FROM crdt_changes WHERE dataset = ? AND row_id = ? AND col = ? AND hlc = ?").run(e.dataset,e.row_id,e.col,e.hlc);throw o}return{inserted:t,winner:!0}}function m(n,e,t,r,o){let i=()=>{let a=Tt??Me(n),s={hlc:Oe(n,a),node_id:a,dataset:e,row_id:t,col:r,value:o===void 0?null:JSON.stringify(o),txn:ee};return It(n,s),s};return ee!==null?i():pe(n,i)}function Be(n){return n.replace(/[^a-zA-Z0-9_]/g,"_")}function Ke(n){return n.replace(/'/g,"''")}function Fe(n,e){return`idx_rec_${Be(n)}_${Be(e)}`}function Ht(n,e,t){return n.query("SELECT 1 AS ok FROM sqlite_master WHERE type = 'index' AND name = ?").get(Fe(e,t))!=null}function ge(n,e,t){let r=Fe(e,t);n.exec(`CREATE INDEX IF NOT EXISTS "${r}" ON records (data ->> '${Ke(t)}', created_hlc) WHERE database_id = '${Ke(e)}' AND __deleted = 0`)}function me(n,e,t){if(Ht(n,e,t.id))return;if(t.type!=="relation"&&t.type!=="doc"){if(n.query("SELECT COUNT(*) AS c FROM records WHERE database_id = ? AND __deleted = 0").get(e).c<2000)return}ge(n,e,t.id)}var We=new Set(["text","number","checkbox","select","multi_select","date","relation","doc","url"]),Ut=["id","database_id","name","type","config","position"];var je=Ut.join(", ");function ye(n,e){if(n==="select"||n==="multi_select"){let t=e?.options;if(!Array.isArray(t)||t.length===0||!t.every((r)=>typeof r==="string"))throw new d("invalid_input",`${n} requires config.options: string[]`)}if(n==="relation"){if(typeof e?.database!=="string")throw new d("invalid_input","relation requires config.database (target database id)")}}function Gt(n,e){return(n.query("SELECT MAX(position) AS m FROM properties WHERE database_id = ? AND __deleted = 0").get(e).m??0)+1}var Ve=v(function(e,t,r){if(!M(e,t))throw new d("not_found",`no such database: ${t}`);if(!We.has(r.type))throw new d("invalid_input",`unknown property type: ${r.type}`);ye(r.type,r.config);let o=r.indexed?{...r.config??{},indexed:!0}:r.config??null,i=J("prop",r.name);if(m(e,"properties",i,"database_id",t),m(e,"properties",i,"name",r.name),m(e,"properties",i,"type",r.type),m(e,"properties",i,"config",o),m(e,"properties",i,"position",r.position??Gt(e,t)),r.type==="relation"||r.type==="doc"||r.indexed===!0)ge(e,t,i);return W(e,i)});function W(n,e){let t=n.query(`SELECT ${je} FROM properties WHERE id = ? AND __deleted = 0`).get(e);if(!t)return null;return{...t,config:t.config?JSON.parse(t.config):null}}function B(n,e){return n.query(`SELECT ${je} FROM properties WHERE database_id = ? AND __deleted = 0 ORDER BY position`).all(e).map((r)=>({...r,config:r.config?JSON.parse(r.config):null}))}var Zn=v(function(e,t,r){let o=W(e,t);if(!o)throw new d("not_found",`no such property: ${t}`);let i=r.type!==void 0&&r.type!==o.type;if(r.type!==void 0&&!We.has(r.type))throw new d("invalid_input",`unknown property type: ${r.type}`);let a=r.type??o.type,s;if(r.config!==void 0){let l={...o.config??{}};for(let[u,p]of Object.entries(r.config))if(p===null)delete l[u];else l[u]=p;s=l,ye(a,s)}else if(i)ye(r.type,o.config??void 0);if(r.name!==void 0)m(e,"properties",t,"name",r.name);if(r.type!==void 0)m(e,"properties",t,"type",r.type);if(s!==void 0)m(e,"properties",t,"config",s);if(r.position!==void 0)m(e,"properties",t,"position",r.position);if(i){let l=e.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(o.database_id,t);for(let u of l)m(e,"records",u.id,t,null)}return W(e,t)});function Ye(n,e){let t=W(n,e);if(!t)throw new d("not_found",`no such property: ${e}`);if(t.type!=="select"&&t.type!=="multi_select")throw new d("invalid_input",`${t.type} property has no options`);return{prop:t,options:t.config?.options??[]}}var er=v(function(e,t,r,o){let{prop:i,options:a}=Ye(e,t);if(o=o.trim(),!o)throw new d("invalid_input","option name must not be empty");if(!a.includes(r))throw new d("not_found",`no such option: ${r}`);if(o===r)return{property:i,renamed:0};if(a.includes(o))throw new d("conflict",`option already exists: ${o}`);m(e,"properties",t,"config",{...i.config??{},options:a.map((l)=>l===r?o:l)});let s=0;if(i.type==="select"){let l=e.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? = ?").all(i.database_id,t,r);for(let u of l)m(e,"records",u.id,t,o);s=l.length}else{let l=e.query("SELECT id, data ->> ? AS v FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(t,i.database_id,t);for(let u of l){let p=JSON.parse(u.v);if(!Array.isArray(p)||!p.includes(r))continue;m(e,"records",u.id,t,[...new Set(p.map((w)=>w===r?o:w))]),s++}}return{property:W(e,t),renamed:s}}),tr=v(function(e,t,r){let{prop:o,options:i}=Ye(e,t);if(!i.includes(r))throw new d("not_found",`no such option: ${r}`);if(i.length===1)throw new d("invalid_input","cannot remove the last option; delete the property instead");m(e,"properties",t,"config",{...o.config??{},options:i.filter((s)=>s!==r)});let a=0;if(o.type==="select"){let s=e.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? = ?").all(o.database_id,t,r);for(let l of s)m(e,"records",l.id,t,null);a=s.length}else{let s=e.query("SELECT id, data ->> ? AS v FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(t,o.database_id,t);for(let l of s){let u=JSON.parse(l.v);if(!Array.isArray(u)||!u.includes(r))continue;m(e,"records",l.id,t,u.filter((p)=>p!==r)),a++}}return{property:W(e,t),cleared:a}}),nr=v(function(e,t){let r=W(e,t);if(!r)return!1;m(e,"properties",t,"__deleted",1);let o=e.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(r.database_id,t);for(let i of o)m(e,"records",i.id,t,void 0);return!0});var qt={db:{table:"databases",nameCol:"name",scoped:!1,noun:"database"},prop:{table:"properties",nameCol:"name",scoped:!0,noun:"property"},rec:{table:"records",nameCol:null,scoped:!0,noun:"record"},doc:{table:"documents",nameCol:"title",scoped:!0,noun:"document"}},Bt=["db","prop","rec","doc"];function Kt(n){return n!==null&&n!=="blk"}var Je="{";function ze(n,e){return n.query("SELECT id FROM properties WHERE database_id = ? AND type = 'text' AND __deleted = 0 ORDER BY position LIMIT 1").get(e)?.id??null}function Ft(n,e,t,r){let o=qt[e],i=o.nameCol;if(e==="rec"&&r){let _=ze(n,r);if(_)i=`data ->> '${_.replace(/'/g,"''")}'`}let a=i??"''",s=[],l=[];s.push("(id >= ? AND id < ?)"),l.push(t,t+Je);let u=`${e}_${t}`;if(s.push("(id >= ? AND id < ?)"),l.push(u,u+Je),i)s.push(`lower(${i}) = lower(?)`),l.push(t);let p=`SELECT id, ${a} AS label FROM ${o.table} WHERE __deleted = 0 AND (${s.join(" OR ")})`;if(o.scoped&&r)p+=" AND database_id = ?",l.push(r);return n.query(p).all(...l).map((_)=>({kind:e,id:_.id,label:_.label??""}))}function we(n,e,t={}){let r=t.kind?[t.kind]:Kt(z(e))?[z(e)]:Bt,o=[],i=new Set;for(let a of r)for(let s of Ft(n,a,e,t.databaseId)){if(i.has(s.id))continue;i.add(s.id),o.push(s)}return o}function _e(n,e){if(e!==null&&n>=e)throw Error(`fracdex: ${n} >= ${e}`);if(n.endsWith("0")||e!==null&&e.endsWith("0"))throw Error(`fracdex: trailing zero in ${n}/${e}`);if(e!==null){let i=0;while((n[i]??"0")===e[i])i++;if(i>0)return e.slice(0,i)+_e(n.slice(i),e.slice(i))}let r=n===""?0:"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".indexOf(n[0]),o=e===null?62:"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".indexOf(e[0]);if(o-r>1)return"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[Math.round(0.5*(r+o))];if(e!==null&&e.length>1)return e.slice(0,1);return"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[r]+_e(n.slice(1),null)}function G(n,e){return _e(n??"",e)}function te(n,e,t){if(t<=0)return[];if(t===1)return[G(n,e)];if(e===null){let i=G(n,null),a=[i];for(let s=1;s<t;s++)i=G(i,null),a.push(i);return a}if(n===null){let i=G(null,e),a=[i];for(let s=1;s<t;s++)i=G(null,i),a.unshift(i);return a}let r=Math.floor(t/2),o=G(n,e);return[...te(n,o,r),o,...te(o,e,t-r-1)]}function Xe(n){return typeof n==="string"||typeof n==="number"||typeof n==="boolean"}function Wt(n){return typeof n==="boolean"?n?1:0:n}function jt(n,e,t){let r=e.config?.database;if(!r)return t;let o=we(n,t,{kind:"rec",databaseId:r}),i=o.find((a)=>a.id===t);if(i)return i.id;if(o.length===1)return o[0].id;if(o.length===0){if(z(t)==="rec")return t;throw new d("not_found",`${e.name}: no such record in target database: ${t}`)}throw new d("ambiguous",`${e.name}: ambiguous relation "${t}" (${o.length} matches); use a full id`)}function Vt(n,e,t){let r=we(n,t,{kind:"doc"}),o=r.find((i)=>i.id===t);if(o)return o.id;if(r.length===1)return r[0].id;if(r.length===0){if(z(t)==="doc")return t;throw new d("not_found",`${e.name}: no such document: ${t}`)}throw new d("ambiguous",`${e.name}: ambiguous document "${t}" (${r.length} matches); use a full id`)}function be(n,e,t){switch(e.type){case"text":case"url":case"date":{if(t===null)return null;if(typeof t!=="string")throw new d("invalid_input",`${e.name} expects a string`);return t}case"number":{if(t===null)return null;let r=typeof t==="number"?t:Number(t);if(!Number.isFinite(r))throw new d("invalid_input",`${e.name} expects a number`);return r}case"checkbox":{if(typeof t==="boolean")return t;if(t==="true"||t===1)return!0;if(t==="false"||t===0||t===null)return!1;throw new d("invalid_input",`${e.name} expects a boolean`)}case"select":{if(t===null)return null;let r=String(t);if(!e.config?.options?.includes(r))throw new d("invalid_input",`${e.name}: '${r}' is not an allowed option`);return r}case"multi_select":{let r=t===null?[]:Array.isArray(t)?t:[t],o=e.config?.options??[];for(let i of r)if(!o.includes(String(i)))throw new d("invalid_input",`${e.name}: '${i}' is not an allowed option`);return r.map(String)}case"relation":return(t===null?[]:Array.isArray(t)?t:[t]).map((o)=>jt(n,e,String(o)));case"doc":return(t===null?[]:Array.isArray(t)?t:[t]).map((o)=>Vt(n,e,String(o)))}}function Yt(n){let e=new Map;for(let t of n){let r=t.name.toLowerCase(),o=e.get(r);if(o)o.push(t);else e.set(r,[t])}return e}function De(n,e){let t=new Map(n.map((i)=>[i.id,i])),r=Yt(n),o=[];for(let[i,a]of Object.entries(e)){let s=t.get(i);if(!s){let l=r.get(i.toLowerCase())??[];if(l.length>1)throw new d("ambiguous",`property name "${i}" matches ${l.length} properties; use a property id`);s=l[0]}if(!s)throw new d("not_found",`unknown property: ${i}`);o.push({prop:s,value:a})}return o}function et(n,e,t){return De(B(n,e),t).map(({prop:r,value:o})=>({prop:r,value:be(n,r,o)}))}function tt(n,e){let t=JSON.parse(n.data||"{}"),r=new Map(e.map((a)=>[a.id,a])),o={},i={};for(let[a,s]of Object.entries(t)){let l=r.get(a);if(!l)continue;o[l.name]=s,i[l.id]=s}return{id:n.id,database_id:n.database_id,values:o,cells:i}}function Jt(n,e){let t=n.find((r)=>r.prop.type==="text"&&typeof r.value==="string"&&r.value);return J("rec",t?String(t.value):"",e)}function Qe(n,e){return n.query("SELECT 1 AS ok FROM sqlite_master WHERE type = 'table' AND name = ?").get(e)!=null}function zt(n){return Qe(n,"meta")&&Qe(n,"crdt_changes")}function Xt(n,e,t,r){if(r)m(n,"records",e,"order_key",t);else n.query("UPDATE records SET order_key = ? WHERE id = ?").run(t,e)}function nt(n,e){return n.query(`SELECT order_key FROM records
3
+ `)}var It=new WeakMap;function ye(n,e){let t=n.docs.get(e);if(!t)return;n.docs.delete(e);for(let r of t.blockIds)if(n.blockToDoc.get(r)===e)n.blockToDoc.delete(r)}function Be(n,e,t,r,o){let i=It.get(n);if(!i)return;if(e==="documents"){ye(i,t);return}if(e!=="doc_blocks")return;let a=i.blockToDoc.get(t);if(a)ye(i,a);if(r==="doc_id"&&o)try{let s=JSON.parse(o);if(typeof s==="string")ye(i,s)}catch{}}var Ke="intent_receipts";var Ht=["hlc","node_id","dataset","row_id","col","value","txn"];var pr=Ht.join(", "),ee=null,je=null;var Ut=null;function Fe(n,e,t){if(ee!==null)return t();ee=(je?je+"/":"")+(e?e+":":"")+L(8);try{return ue(n,t)}finally{ee=null}}function x(n,e=null){return(t,...r)=>Fe(t,e,()=>n(t,...r))}var qt={databases:{table:"databases",cols:new Set(["name","icon","meta","created_hlc","__deleted"])},properties:{table:"properties",cols:new Set(["database_id","name","type","config","position","__deleted"])},documents:{table:"documents",cols:new Set(["title","body","database_id","parent_id","created_hlc","order_key","__deleted"])},doc_blocks:{table:"doc_blocks",cols:new Set(["doc_id","text","order_key","blank_after","__deleted"])},sites:{table:"sites",cols:new Set(["name","title","created_hlc","visibility","spa","public_grants","__deleted"])},site_channels:{table:"site_channels",cols:new Set(["site_id","audience","hosting","controller_node_id","target_ref","canonical_url","policy_json","desired_state","created_hlc","__deleted"])},site_files:{table:"site_files",cols:new Set(["site_id","path","content_type","encoding","content","created_hlc","__deleted"])},blob_policy:{table:"blob_policy",cols:new Set(["full_nodes","redundancy","__deleted"])},nodes:{table:"nodes",cols:new Set(["label","platform","form","app","first_seen","__deleted"])}},Gt=new Set(["database_id","created_hlc","order_key","__deleted"]),Ft=new Set([Ke]),Wt=new Set(["records:__deleted","databases:__deleted","properties:__deleted","documents:__deleted","doc_blocks:__deleted","doc_blocks:blank_after","sites:__deleted","sites:spa","site_channels:__deleted","site_files:__deleted","blob_policy:__deleted","nodes:__deleted"]);function Ve(n,e,t){if(t!==null)return JSON.parse(t);return Wt.has(`${n}:${e}`)?0:null}function Ye(n){if(n===null||n===void 0)return null;if(typeof n==="boolean")return n?1:0;if(typeof n==="number")return n;if(typeof n==="string")return n;return JSON.stringify(n)}function Z(n,e,t){n.query(`INSERT OR IGNORE INTO ${e} (id) VALUES (?)`).run(t)}function Bt(n,e){if(n.query("SELECT 1 FROM meta WHERE key=?").get(`sync_v2_managed:${e}`))return!0;return n.query("SELECT 1 AS x FROM doc_blocks WHERE doc_id = ? LIMIT 1").get(e)!=null}function Kt(n,e){let t=n.query("SELECT text, blank_after FROM doc_blocks WHERE doc_id = ? AND __deleted = 0 ORDER BY order_key, id").all(e);Z(n,"documents",e),n.query("UPDATE documents SET body = ? WHERE id = ?").run(We(t.map((r)=>({text:r.text,blankAfter:r.blank_after??0}))),e)}function jt(n,e,t,r,o){if(Ft.has(e))return;if(e==="records"){if(Gt.has(r)){Z(n,"records",t);let s=Ve("records",r,o);n.query(`UPDATE records SET "${r}" = ? WHERE id = ?`).run(Ye(s),t)}else if(Z(n,"records",t),o===null)n.query(`UPDATE records SET data = json_remove(data, '$."' || ? || '"') WHERE id = ?`).run(r,t);else n.query(`UPDATE records SET data = json_set(coalesce(data, '{}'), '$."' || ? || '"', json(?)) WHERE id = ?`).run(r,o,t);return}if(e==="databases"&&r.startsWith("meta.")){Z(n,"databases",t);let s=r.slice(5);if(o===null)n.query(`UPDATE databases SET meta = json_remove(coalesce(meta, '{}'), '$."' || ? || '"') WHERE id = ?`).run(s,t);else n.query(`UPDATE databases SET meta = json_set(coalesce(meta, '{}'), '$."' || ? || '"', json(?)) WHERE id = ?`).run(s,o,t);return}let i=qt[e];if(!i||!i.cols.has(r))return;if(e==="documents"&&r==="body"&&Bt(n,t))return;Z(n,i.table,t);let a=Ve(e,r,o);if(n.query(`UPDATE ${i.table} SET "${r}" = ? WHERE id = ?`).run(Ye(a),t),e==="doc_blocks"){let s=n.query("SELECT doc_id FROM doc_blocks WHERE id = ?").get(t);if(s?.doc_id)Kt(n,s.doc_id)}}function Vt(n,e,t){let r=n.query("INSERT OR IGNORE INTO crdt_changes (hlc, node_id, dataset, row_id, col, value, txn) VALUES (?, ?, ?, ?, ?, ?, ?)").run(e.hlc,e.node_id,e.dataset,e.row_id,e.col,e.value,e.txn??null).changes>0;if(!r&&!t)return{inserted:!1,winner:!1};let o=n.query("SELECT MAX(hlc) AS h FROM crdt_changes WHERE dataset = ? AND row_id = ? AND col = ?").get(e.dataset,e.row_id,e.col);if(r)Be(n,e.dataset,e.row_id,e.col,e.value);if(o.h!==e.hlc)return{inserted:r,winner:!1};try{jt(n,e.dataset,e.row_id,e.col,e.value)}catch(i){if(r)n.query("DELETE FROM crdt_changes WHERE dataset = ? AND row_id = ? AND col = ? AND hlc = ?").run(e.dataset,e.row_id,e.col,e.hlc);throw i}return{inserted:r,winner:!0}}function Yt(n,e){return Vt(n,e,!0)}function y(n,e,t,r,o){Ue(n);let i=()=>{let a=Ut??Ge(n),s={hlc:$e(n,a),node_id:a,dataset:e,row_id:t,col:r,value:o===void 0?null:JSON.stringify(o),txn:ee};if(n.query("SELECT 1 FROM meta WHERE key='sync_v2_generation'").get()){let l=n.query("SELECT MAX(hlc) AS h FROM crdt_changes WHERE dataset=? AND row_id=? AND col=?").get(e,t,e==="doc_blocks"&&r==="__deleted"&&o===1?"text":r);n.query("INSERT OR REPLACE INTO meta(key,value) VALUES(?,?)").run(`sync_v2_base:${s.hlc}:${e}:${t}:${r}`,JSON.stringify(l.h))}return Yt(n,s),s};return ee!==null?i():ue(n,i)}function Je(n){return n.replace(/[^a-zA-Z0-9_]/g,"_")}function ze(n){return n.replace(/'/g,"''")}function Xe(n,e){return`idx_rec_${Je(n)}_${Je(e)}`}function Jt(n,e,t){return n.query("SELECT 1 AS ok FROM sqlite_master WHERE type = 'index' AND name = ?").get(Xe(e,t))!=null}function we(n,e,t){let r=Xe(e,t);n.exec(`CREATE INDEX IF NOT EXISTS "${r}" ON records (data ->> '${ze(t)}', created_hlc) WHERE database_id = '${ze(e)}' AND __deleted = 0`)}function _e(n,e,t){if(Jt(n,e,t.id))return;if(t.type!=="relation"&&t.type!=="doc"){if(n.query("SELECT COUNT(*) AS c FROM records WHERE database_id = ? AND __deleted = 0").get(e).c<2000)return}we(n,e,t.id)}var Qe=new Set(["text","number","checkbox","select","multi_select","date","relation","doc","url"]),zt=["id","database_id","name","type","config","position"];var Ze=zt.join(", ");function he(n,e){if(n==="select"||n==="multi_select"){let t=e?.options;if(!Array.isArray(t)||t.length===0||!t.every((r)=>typeof r==="string"))throw new c("invalid_input",`${n} requires config.options: string[]`)}if(n==="relation"){if(typeof e?.database!=="string")throw new c("invalid_input","relation requires config.database (target database id)")}}function Xt(n,e){return(n.query("SELECT MAX(position) AS m FROM properties WHERE database_id = ? AND __deleted = 0").get(e).m??0)+1}var et=x(function(e,t,r){if(!P(e,t))throw new c("not_found",`no such database: ${t}`);if(!Qe.has(r.type))throw new c("invalid_input",`unknown property type: ${r.type}`);he(r.type,r.config);let o=r.indexed?{...r.config??{},indexed:!0}:r.config??null,i=J("prop",r.name);if(y(e,"properties",i,"database_id",t),y(e,"properties",i,"name",r.name),y(e,"properties",i,"type",r.type),y(e,"properties",i,"config",o),y(e,"properties",i,"position",r.position??Xt(e,t)),r.type==="relation"||r.type==="doc"||r.indexed===!0)we(e,t,i);return M(e,i)});function M(n,e){let t=n.query(`SELECT ${Ze} FROM properties WHERE id = ? AND __deleted = 0`).get(e);if(!t)return null;return{...t,config:t.config?JSON.parse(t.config):null}}function H(n,e){return n.query(`SELECT ${Ze} FROM properties WHERE database_id = ? AND __deleted = 0 ORDER BY position, id`).all(e).map((r)=>({...r,config:r.config?JSON.parse(r.config):null}))}var br=x(function(e,t,r){let o=M(e,t);if(!o)throw new c("not_found",`no such property: ${t}`);let i=r.type!==void 0&&r.type!==o.type;if(r.type!==void 0&&!Qe.has(r.type))throw new c("invalid_input",`unknown property type: ${r.type}`);let a=r.type??o.type,s;if(r.config!==void 0){let l={...o.config??{}};for(let[p,u]of Object.entries(r.config))if(u===null)delete l[p];else l[p]=u;s=l,he(a,s)}else if(i)he(r.type,o.config??void 0);if(r.name!==void 0)y(e,"properties",t,"name",r.name);if(r.type!==void 0)y(e,"properties",t,"type",r.type);if(s!==void 0)y(e,"properties",t,"config",s);if(r.position!==void 0)y(e,"properties",t,"position",r.position);if(i){let l=e.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(o.database_id,t);for(let p of l)y(e,"records",p.id,t,null)}return M(e,t)});function be(n,e){let t=M(n,e);if(!t)throw new c("not_found",`no such property: ${e}`);if(t.type!=="select"&&t.type!=="multi_select")throw new c("invalid_input",`${t.type} property has no options`);return{prop:t,options:t.config?.options??[]}}var Er=x(function(e,t,r,o){let{prop:i,options:a}=be(e,t);if(o=o.trim(),!o)throw new c("invalid_input","option name must not be empty");if(!a.includes(r))throw new c("not_found",`no such option: ${r}`);if(o===r)return{property:i,renamed:0};if(a.includes(o))throw new c("conflict",`option already exists: ${o}`);y(e,"properties",t,"config",{...i.config??{},options:a.map((l)=>l===r?o:l)});let s=0;if(i.type==="select"){let l=e.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? = ?").all(i.database_id,t,r);for(let p of l)y(e,"records",p.id,t,o);s=l.length}else{let l=e.query("SELECT id, data ->> ? AS v FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(t,i.database_id,t);for(let p of l){let u=JSON.parse(p.v);if(!Array.isArray(u)||!u.includes(r))continue;y(e,"records",p.id,t,[...new Set(u.map((w)=>w===r?o:w))]),s++}}return{property:M(e,t),renamed:s}}),Dr=x(function(e,t,r){let{prop:o,options:i}=be(e,t);if(!i.includes(r))throw new c("not_found",`no such option: ${r}`);if(i.length===1)throw new c("invalid_input","cannot remove the last option; delete the property instead");y(e,"properties",t,"config",{...o.config??{},options:i.filter((s)=>s!==r)});let a=0;if(o.type==="select"){let s=e.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? = ?").all(o.database_id,t,r);for(let l of s)y(e,"records",l.id,t,null);a=s.length}else{let s=e.query("SELECT id, data ->> ? AS v FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(t,o.database_id,t);for(let l of s){let p=JSON.parse(l.v);if(!Array.isArray(p)||!p.includes(r))continue;y(e,"records",l.id,t,p.filter((u)=>u!==r)),a++}}return{property:M(e,t),cleared:a}}),Rr=x(function(e,t){let r=M(e,t);if(!r)return!1;y(e,"properties",t,"__deleted",1);let o=e.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(r.database_id,t);for(let i of o)y(e,"records",i.id,t,void 0);return!0}),Sr=x(function(e,t,r,o){if(o!=="before"&&o!=="after")throw new c("invalid_input","unknown move position");let i=M(e,t),a=M(e,r);if(!i)throw new c("not_found",`no such property: ${t}`);if(!a)throw new c("not_found",`no such property: ${r}`);if(i.database_id!==a.database_id)throw new c("invalid_input","cannot move a property across databases");if(t===r)return i;let s=H(e,i.database_id).filter((u)=>u.id!==t),l=()=>{let u=s.findIndex((T)=>T.id===r);if(u<0)throw new c("not_found",`no such property: ${r}`);let w=o==="before"?u:u+1,E=s[w-1]?.position,_=s[w]?.position,S=E===void 0?_-1:_===void 0?E+1:E/2+_/2;return Number.isFinite(S)&&(E===void 0||S>E)&&(_===void 0||S<_)?S:null},p=s.every((u)=>Number.isFinite(u.position))?l():null;if(p===null){for(let u=0;u<s.length;u++)y(e,"properties",s[u].id,"position",u+1);s=H(e,i.database_id).filter((u)=>u.id!==t),p=l()}if(p===null)throw new c("invalid_input","could not allocate a finite property position");if(p!==i.position)y(e,"properties",t,"position",p);return M(e,t)}),vr=x(function(e,t,r,o,i){if(i!=="before"&&i!=="after")throw new c("invalid_input","unknown move position");let{prop:a,options:s}=be(e,t);if(!s.includes(r))throw new c("not_found",`no such option: ${r}`);if(!s.includes(o))throw new c("not_found",`no such option: ${o}`);if(r===o)return a;let l=[...s];l.splice(l.indexOf(r),1);let p=l.indexOf(o)+(i==="after"?1:0);if(l.splice(p,0,r),l.some((u,w)=>u!==s[w]))y(e,"properties",t,"config",{...a.config,options:l});return M(e,t)});var Qt={db:{table:"databases",nameCol:"name",scoped:!1,noun:"database"},prop:{table:"properties",nameCol:"name",scoped:!0,noun:"property"},rec:{table:"records",nameCol:null,scoped:!0,noun:"record"},doc:{table:"documents",nameCol:"title",scoped:!0,noun:"document"}},Zt=["db","prop","rec","doc"];function en(n){return n!==null&&n!=="blk"}var tt="{";function nt(n,e){return n.query("SELECT id FROM properties WHERE database_id = ? AND type = 'text' AND __deleted = 0 ORDER BY position LIMIT 1").get(e)?.id??null}function tn(n,e,t,r){let o=Qt[e],i=o.nameCol;if(e==="rec"&&r){let E=nt(n,r);if(E)i=`data ->> '${E.replace(/'/g,"''")}'`}let a=i??"''",s=[],l=[];s.push("(id >= ? AND id < ?)"),l.push(t,t+tt);let p=`${e}_${t}`;if(s.push("(id >= ? AND id < ?)"),l.push(p,p+tt),i)s.push(`lower(${i}) = lower(?)`),l.push(t);let u=`SELECT id, ${a} AS label FROM ${o.table} WHERE __deleted = 0 AND (${s.join(" OR ")})`;if(o.scoped&&r)u+=" AND database_id = ?",l.push(r);return n.query(u).all(...l).map((E)=>({kind:e,id:E.id,label:E.label??""}))}function Ee(n,e,t={}){let r=t.kind?[t.kind]:en(z(e))?[z(e)]:Zt,o=[],i=new Set;for(let a of r)for(let s of tn(n,a,e,t.databaseId)){if(i.has(s.id))continue;i.add(s.id),o.push(s)}return o}function De(n,e){if(e!==null&&n>=e)throw Error(`fracdex: ${n} >= ${e}`);if(n.endsWith("0")||e!==null&&e.endsWith("0"))throw Error(`fracdex: trailing zero in ${n}/${e}`);if(e!==null){let i=0;while((n[i]??"0")===e[i])i++;if(i>0)return e.slice(0,i)+De(n.slice(i),e.slice(i))}let r=n===""?0:"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".indexOf(n[0]),o=e===null?62:"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".indexOf(e[0]);if(o-r>1)return"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[Math.round(0.5*(r+o))];if(e!==null&&e.length>1)return e.slice(0,1);return"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[r]+De(n.slice(1),null)}function U(n,e){return De(n??"",e)}function te(n,e,t){if(t<=0)return[];if(t===1)return[U(n,e)];if(e===null){let i=U(n,null),a=[i];for(let s=1;s<t;s++)i=U(i,null),a.push(i);return a}if(n===null){let i=U(null,e),a=[i];for(let s=1;s<t;s++)i=U(null,i),a.unshift(i);return a}let r=Math.floor(t/2),o=U(n,e);return[...te(n,o,r),o,...te(o,e,t-r-1)]}function rt(n){return typeof n==="string"||typeof n==="number"||typeof n==="boolean"}function nn(n){return typeof n==="boolean"?n?1:0:n}function rn(n,e,t){let r=e.config?.database;if(!r)return t;let o=Ee(n,t,{kind:"rec",databaseId:r}),i=o.find((a)=>a.id===t);if(i)return i.id;if(o.length===1)return o[0].id;if(o.length===0){if(z(t)==="rec")return t;throw new c("not_found",`${e.name}: no such record in target database: ${t}`)}throw new c("ambiguous",`${e.name}: ambiguous relation "${t}" (${o.length} matches); use a full id`)}function on(n,e,t){let r=Ee(n,t,{kind:"doc"}),o=r.find((i)=>i.id===t);if(o)return o.id;if(r.length===1)return r[0].id;if(r.length===0){if(z(t)==="doc")return t;throw new c("not_found",`${e.name}: no such document: ${t}`)}throw new c("ambiguous",`${e.name}: ambiguous document "${t}" (${r.length} matches); use a full id`)}function Se(n,e,t){switch(e.type){case"text":case"url":case"date":{if(t===null)return null;if(typeof t!=="string")throw new c("invalid_input",`${e.name} expects a string`);return t}case"number":{if(t===null)return null;let r=typeof t==="number"?t:Number(t);if(!Number.isFinite(r))throw new c("invalid_input",`${e.name} expects a number`);return r}case"checkbox":{if(typeof t==="boolean")return t;if(t==="true"||t===1)return!0;if(t==="false"||t===0||t===null)return!1;throw new c("invalid_input",`${e.name} expects a boolean`)}case"select":{if(t===null)return null;let r=String(t);if(!e.config?.options?.includes(r))throw new c("invalid_input",`${e.name}: '${r}' is not an allowed option`);return r}case"multi_select":{let r=t===null?[]:Array.isArray(t)?t:[t],o=e.config?.options??[];for(let i of r)if(!o.includes(String(i)))throw new c("invalid_input",`${e.name}: '${i}' is not an allowed option`);return r.map(String)}case"relation":return(t===null?[]:Array.isArray(t)?t:[t]).map((o)=>rn(n,e,String(o)));case"doc":return(t===null?[]:Array.isArray(t)?t:[t]).map((o)=>on(n,e,String(o)))}}function sn(n){let e=new Map;for(let t of n){let r=t.name.toLowerCase(),o=e.get(r);if(o)o.push(t);else e.set(r,[t])}return e}function ve(n,e){let t=new Map(n.map((i)=>[i.id,i])),r=sn(n),o=[];for(let[i,a]of Object.entries(e)){let s=t.get(i);if(!s){let l=r.get(i.toLowerCase())??[];if(l.length>1)throw new c("ambiguous",`property name "${i}" matches ${l.length} properties; use a property id`);s=l[0]}if(!s)throw new c("not_found",`unknown property: ${i}`);o.push({prop:s,value:a})}return o}function st(n,e,t){return ve(H(n,e),t).map(({prop:r,value:o})=>({prop:r,value:Se(n,r,o)}))}function at(n,e){let t=JSON.parse(n.data||"{}"),r=new Map(e.map((a)=>[a.id,a])),o={},i={};for(let[a,s]of Object.entries(t)){let l=r.get(a);if(!l)continue;o[l.name]=s,i[l.id]=s}return{id:n.id,database_id:n.database_id,values:o,cells:i}}function an(n,e){let t=n.find((r)=>r.prop.type==="text"&&typeof r.value==="string"&&r.value);return J("rec",t?String(t.value):"",e)}function ot(n,e){return n.query("SELECT 1 AS ok FROM sqlite_master WHERE type = 'table' AND name = ?").get(e)!=null}function ln(n){return ot(n,"meta")&&ot(n,"crdt_changes")}function cn(n,e,t,r){if(r)y(n,"records",e,"order_key",t);else n.query("UPDATE records SET order_key = ? WHERE id = ?").run(t,e)}function lt(n,e){return n.query(`SELECT order_key FROM records
4
4
  WHERE database_id = ? AND __deleted = 0 AND order_key IS NOT NULL
5
- ORDER BY order_key DESC, id DESC LIMIT 1`).get(e)?.order_key??null}function he(n,e){return n.query(`SELECT id, database_id, created_hlc, order_key FROM records
5
+ ORDER BY order_key DESC, id DESC LIMIT 1`).get(e)?.order_key??null}function Re(n,e){return n.query(`SELECT id, database_id, created_hlc, order_key FROM records
6
6
  WHERE database_id = ? AND __deleted = 0
7
- ORDER BY order_key IS NULL, order_key, created_hlc, id`).all(e)}function Qt(n,e){let t=he(n,e),r=te(null,null,t.length);t.forEach((o,i)=>{if(o.order_key!==r[i])m(n,"records",o.id,"order_key",r[i])})}var Zt=v(function(e,t){let r=zt(e),o=t?[{database_id:t}]:e.query(`SELECT DISTINCT database_id FROM records
7
+ ORDER BY order_key IS NULL, order_key, created_hlc, id`).all(e)}function un(n,e){let t=Re(n,e),r=te(null,null,t.length);t.forEach((o,i)=>{if(o.order_key!==r[i])y(n,"records",o.id,"order_key",r[i])})}var dn=x(function(e,t){let r=ln(e),o=t?[{database_id:t}]:e.query(`SELECT DISTINCT database_id FROM records
8
8
  WHERE database_id IS NOT NULL AND __deleted = 0 AND order_key IS NULL`).all();for(let i of o){let a=e.query(`SELECT id FROM records
9
9
  WHERE database_id = ? AND __deleted = 0 AND order_key IS NULL
10
- ORDER BY created_hlc, id`).all(i.database_id);if(!a.length)continue;let s=nt(e,i.database_id),l=te(s,null,a.length);a.forEach((u,p)=>Xt(e,u.id,l[p],r))}}),rt=v(function(e,t,r){let o=Jt(r,de(t.name,"rec")),i=G(nt(e,t.id),null),a=m(e,"records",o,"database_id",t.id);m(e,"records",o,"created_hlc",a.hlc),m(e,"records",o,"order_key",i);for(let{prop:s,value:l}of r)m(e,"records",o,s.id,l);return ne(e,o)}),ot=v(function(e,t,r){let o=M(e,t);if(!o)throw new d("not_found",`no such database: ${t}`);return rt(e,o,et(e,o.id,r))});function ne(n,e){let t=n.query("SELECT id, database_id, data FROM records WHERE id = ? AND __deleted = 0").get(e);if(!t)return null;return tt(t,B(n,t.database_id))}function Ze(n){return n.replace(/'/g,"''")}function it(n,e,t={}){let r=B(n,e),o=t.filter&&Object.keys(t.filter).length?De(r,t.filter).map(({prop:E,value:A})=>({prop:E,value:be(n,E,A)})):[],i=o.filter((E)=>Xe(E.value)),a=o.filter((E)=>!Xe(E.value)),s,l=!1;if(t.sort){let E=t.sort;if(E.startsWith("-"))l=!0,E=E.slice(1);if(E!=="created"&&E!=="created_hlc"){let A=r.find((I)=>I.id===E);if(!A){let I=r.filter((K)=>K.name.toLowerCase()===E.toLowerCase());if(I.length>1)throw new d("ambiguous",`sort field "${E}" matches ${I.length} properties; use a property id`);A=I[0]}if(!A)throw new d("not_found",`unknown sort field: ${E}`);s=A}}for(let E of i)me(n,e,E.prop);if(s)me(n,e,s);let u=["database_id = ?","__deleted = 0"],p=[e];for(let E of i)u.push(`data ->> '${Ze(E.prop.id)}' = ?`),p.push(Wt(E.value));let w=t.sort==null,_=s?`data ->> '${Ze(s.id)}'`:"created_hlc",S=`SELECT id, database_id, data FROM records WHERE ${u.join(" AND ")} `+(w?"ORDER BY order_key IS NULL, order_key, id":`ORDER BY ${_} ${l?"DESC":"ASC"}, id`);if(t.limit!=null&&a.length===0)S+=" LIMIT ?",p.push(t.limit);let T=n.query(S).all(...p).map((E)=>tt(E,r));if(a.length){if(T=T.filter((E)=>a.every((A)=>JSON.stringify(E.cells[A.prop.id]??null)===JSON.stringify(A.value))),t.limit!=null)T=T.slice(0,t.limit)}return T}var yr=v(function(e,t,r,o){if(o!=="before"&&o!=="after")throw new d("invalid_input",`unknown move position: ${o}`);let i=e.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(t);if(!i)throw new d("not_found",`no such record: ${t}`);let a=e.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(r);if(!a)throw new d("not_found",`no such record: ${r}`);if(i.database_id!==a.database_id)throw new d("invalid_input","cannot move a record across databases");if(t===r)return ne(e,t);Zt(e,i.database_id);let s=he(e,i.database_id).filter((w)=>w.id!==t),l=s.findIndex((w)=>w.id===r);if(l<0)throw new d("not_found",`no such target record: ${r}`);let u=o==="before"?s[l-1]?.order_key??null:s[l].order_key,p=o==="before"?s[l].order_key:s[l+1]?.order_key??null;if(u!==null&&p!==null&&u>=p)Qt(e,i.database_id),s=he(e,i.database_id).filter((w)=>w.id!==t),l=s.findIndex((w)=>w.id===r),u=o==="before"?s[l-1]?.order_key??null:s[l].order_key,p=o==="before"?s[l].order_key:s[l+1]?.order_key??null;return m(e,"records",t,"order_key",G(u,p)),ne(e,t)}),st=v(function(e,t,r){let o=e.query("SELECT id, database_id, data FROM records WHERE id = ? AND __deleted = 0").get(t);if(!o)throw new d("not_found",`no such record: ${t}`);let i=JSON.parse(o.data||"{}");for(let{prop:a,value:s}of r){let l=Object.hasOwn(i,a.id);if(!(s===void 0?!l:l&&JSON.stringify(s)===JSON.stringify(i[a.id])))m(e,"records",t,a.id,s)}return ne(e,t)}),at=v(function(e,t,r){let o=e.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(t);if(!o)throw new d("not_found",`no such record: ${t}`);return st(e,t,et(e,o.database_id,r))}),wr=v(function(e,t){if(!e.query("SELECT id FROM records WHERE id = ? AND __deleted = 0").get(t))return!1;return m(e,"records",t,"__deleted",1),!0});var en=["id","name","icon","meta","created_hlc"];var tn=en.join(", ");function nn(n){if(!n)return null;let e=n.meta===null?null:JSON.parse(n.meta);return{...n,meta:e&&Object.keys(e).length?e:null}}function ct(n,e,t,r){for(let[o,i]of Object.entries(r)){if(o.includes("."))throw new d("invalid_input",`meta key must not contain ".": ${o}`);let a=i===void 0?null:i,s=t&&o in t?t[o]:null;if(JSON.stringify(s??null)===JSON.stringify(a??null))continue;m(n,"databases",e,`meta.${o}`,a===null?void 0:a)}}var rn=v(function(e,t){let r=J("db",t.name),o=m(e,"databases",r,"name",t.name);if(m(e,"databases",r,"created_hlc",o.hlc),t.icon!==void 0)m(e,"databases",r,"icon",t.icon);return M(e,r)}),xr=v(function(e,t,r){if(!M(e,t))throw new d("not_found",`no such database: ${t}`);if(r.name!==void 0)m(e,"databases",t,"name",r.name);if(r.icon!==void 0)m(e,"databases",t,"icon",r.icon);if(r.meta!==void 0){if(r.meta!==null&&(typeof r.meta!=="object"||Array.isArray(r.meta)))throw new d("invalid_input","meta must be a JSON object or null");let o=M(e,t).meta,i=r.meta??Object.fromEntries(Object.keys(o??{}).map((a)=>[a,null]));ct(e,t,o,i)}return M(e,t)}),vr=v(function(e,t,r={}){let o=M(e,t);if(!o)throw new d("not_found",`no such database: ${t}`);let i=rn(e,{name:r.name??o.name,icon:r.icon??o.icon??void 0}),a=new Map,s=new Set;for(let p of B(e,t)){let w=p.type==="relation"&&p.config?.database===t,_=w?{...p.config,database:i.id}:p.config??void 0,S=Ve(e,i.id,{name:p.name,type:p.type,config:_,position:p.position});if(a.set(p.id,S.id),w)s.add(S.id)}let l=it(e,t),u=new Map;for(let p of l){let w={};for(let[_,S]of Object.entries(p.cells)){let O=a.get(_);if(!O)continue;if(s.has(O)&&Array.isArray(S)&&S.length>0)continue;w[O]=S}u.set(p.id,ot(e,i.id,w).id)}for(let p of l){let w={};for(let[_,S]of Object.entries(p.cells)){let O=a.get(_);if(O&&s.has(O)&&Array.isArray(S)&&S.length>0)w[O]=S.map((T)=>u.get(String(T))??T)}if(Object.keys(w).length)at(e,u.get(p.id),w)}if(o.meta!==null){let{collapsed:p,...w}=o.meta;if("views"in w)w.views=Ne(w.views,a,u,new Set(B(e,t).filter((_)=>_.type==="relation"&&_.config?.database===t).map((_)=>_.id)));ct(e,i.id,null,w)}return M(e,i.id)});function M(n,e){return nn(n.query(`SELECT ${tn} FROM databases WHERE id = ? AND __deleted = 0`).get(e))}var kr=v(function(e,t){if(!M(e,t))return!1;m(e,"databases",t,"__deleted",1);let r=(o)=>{for(let i of lt(e,o,"database_id",t))m(e,o,i,"__deleted",1)};r("properties"),r("records");for(let o of lt(e,"documents","database_id",t))m(e,"documents",o,"database_id",null);return e.query("DELETE FROM meta WHERE key = 'current_db' AND value = ?").run(t),!0});function lt(n,e,t,r){return n.query(`SELECT id FROM ${e} WHERE ${t} = ? AND __deleted = 0`).all(r).map((o)=>o.id)}var ut="sealed-p256";var on=12,sn="mh-drop-seal-v1",dt={name:"ECDH",namedCurve:"P-256"};function re(n){let e=new Uint8Array(n.byteLength);return e.set(n),e.buffer}function pt(...n){let e=n.reduce((o,i)=>o+i.byteLength,0),t=new Uint8Array(e),r=0;for(let o of n)t.set(o,r),r+=o.byteLength;return t}async function an(n,e,t){let r=new Uint8Array(await crypto.subtle.digest("SHA-256",re(t))),o=pt(new TextEncoder().encode(sn),e,r),i=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveKey"]);return crypto.subtle.deriveKey({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(16).buffer,info:re(o)},i,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}async function ft(n,e){let t=await crypto.subtle.importKey("raw",re(n),dt,!1,[]),r=await crypto.subtle.generateKey(dt,!0,["deriveBits"]),o=new Uint8Array(await crypto.subtle.exportKey("raw",r.publicKey)),i=await crypto.subtle.deriveBits({name:"ECDH",public:t},r.privateKey,256),a=await an(i,o,n),s=crypto.getRandomValues(new Uint8Array(on)),l=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:re(s)},a,re(e)));return pt(o,s,l)}var gt=/^g[0-9a-z]{8}$/;function ln(){return"e"+L(16)}function mt(){return"g"+L(8)}function cn(n){return new TextEncoder().encode(JSON.stringify(n))}async function yt(n){let e=await ft(n.pk,cn(n.payload));return{v:1,envelope_id:ln(),drop_id:n.dropId,enc:ut,key_id:n.keyId,sealed:se(e),created_at:n.now??Date.now()}}async function Ee(n,e){return se(await ke(n,ae(e)))}function wt(){try{if(typeof localStorage<"u"&&localStorage)return localStorage.getItem("mh_drop_probe"),{get:(e)=>localStorage.getItem(e),set:(e,t)=>localStorage.setItem(e,t)}}catch{}let n=new Map;return{get:(e)=>n.get(e)??null,set:(e,t)=>n.set(e,t)}}function dn(n){if(n===401)return"auth";if(n===404)return"not_found";if(n===429)return"rate_limited";if(n===400||n===413)return"invalid_input";return"network"}async function Re(n="mh-drop.json",e={}){let r=await(e.fetcher??fetch)(n);if(!r.ok)throw new d("not_found",`no drop config at ${n}`);let o=await r.json().catch(()=>null);if(!o||o.v!==1||!o.endpoint||!o.drop_id||!o.key_id||!o.pk)throw new d("invalid_input","malformed mh-drop.json");return un(o,r.headers.get("date"),e),le(o,e)}function un(n,e,t){if(!e)return;let r=Date.parse(e);if(!Number.isFinite(r))return;let o=t.storage??wt(),i="mh_drop_clock:"+n.endpoint.replace(/\/+$/,"");if(o.get(i))return;let a=t.now??(()=>Date.now());o.set(i,String(r-a()))}function le(n,e={}){let t=e.storage??wt(),r=e.fetcher??fetch,o=e.now??(()=>Date.now()),i=n.endpoint.replace(/\/+$/,""),a="mh_drop_guest",s=t.get("mh_drop_guest");if(!s||!gt.test(s))s=mt(),t.set("mh_drop_guest",s);let l="mh_drop_clock:"+i,u=Number(t.get(l)??"0")||0,p="mh_drop_hlc:"+s,w=/^(\d+):(\d+)$/.exec(t.get(p)??""),_=w?{millis:Number(w[1]),counter:Number(w[2])}:{millis:0,counter:0};function S(){let f=o()+u,y=Math.max(_.millis,f),b=y===_.millis?_.counter+1:0;return _={millis:y,counter:b},t.set(p,`${y}:${b}`),`${String(y).padStart(15,"0")}-${b.toString(16).padStart(4,"0")}-${s}`}let O="mh_drop_pending:"+n.drop_id;function T(){try{let f=t.get(O),y=f?JSON.parse(f):[];return Array.isArray(y)?y:[]}catch{return[]}}function E(f){t.set(O,JSON.stringify(f))}function A(f){let y=n.databases??[],b=y.find((D)=>D.id===f)??y.find((D)=>D.name.toLowerCase()===f.toLowerCase());if(!b)throw new d("not_found",`"${f}" is not a submittable table on this page`);return b}function I(f,y){let b=f.properties.find((D)=>D.id===y)??f.properties.find((D)=>D.name.toLowerCase()===y.toLowerCase());if(!b)throw new d("not_found",`unknown column: ${y}`);return b}let K=null;function c(){return K??=(async()=>{if(!e.password||!n.password_salt)return null;return Ee(e.password,n.password_salt)})(),K}async function g(f,y,b={}){let D=A(f),k="rec_"+L(10),x={},P={},N={};for(let[q,F]of Object.entries(y)){let Y=I(D,q);x[Y.id]=F,P[Y.name]=F,N[Y.id]=F??null}let oe=(n.payload_versions??[1]).includes(2),j;if(oe){let q={intentId:"int_"+L(16),action:"createRecord",table:D.id,recordId:k,payload:N,submittedAt:o()+u};j={v:2,guest_node:s,intents:[q]}}else{let q=[],F=(ce,Q,Dt)=>{q.push({hlc:Dt,node_id:s,dataset:"records",row_id:k,col:ce,value:Q===void 0||Q===null?null:JSON.stringify(Q)})},Y=S();F("database_id",D.id,Y),F("created_hlc",Y,S());for(let[ce,Q]of Object.entries(N))F(ce,Q,S());j={v:1,guest_node:s,changes:q}}let V=await yt({dropId:n.drop_id,keyId:n.key_id,pk:ae(n.pk),payload:j,now:o()}),H={"content-type":"application/json"},ie=await c();if(ie)H["x-drop-pass"]=ie;if(b.turnstileToken)H["x-turnstile-token"]=b.turnstileToken;let U;try{U=await r(`${i}/v1/inbox/${encodeURIComponent(n.drop_id)}/envelopes`,{method:"POST",headers:H,body:JSON.stringify(V)})}catch(q){throw new d("network",`drop submission failed: ${q.message}`)}let X=await U.json().catch(()=>null);if(!U.ok)throw new d(dn(U.status),X?.error??`drop submission failed (HTTP ${U.status})`);if(typeof X?.server_time==="number")u=X.server_time-o(),t.set(l,String(u));let Se={id:k,database_id:D.id,values:P,cells:x,_pending:!0,envelope_id:V.envelope_id,created_at:o()};return E([...T(),Se]),Se}function h(f){let y=T();if(!f)return y;let b=A(f).id;return y.filter((D)=>D.database_id===b)}function R(f,y){let b=new Set(f.map((N)=>N.id)),D=T(),k=D.filter((N)=>!b.has(N.id));if(k.length!==D.length)E(k);let x=y?A(y).id:null,P=k.filter((N)=>x===null||N.database_id===x);return[...f,...P]}return{config:n,guest:s,createRecord:g,pending:h,merge:R}}class C extends Error{code;status;constructor(n,e,t){super(n);this.code=e;this.status=t;this.name="MetahubError"}}var _t="mh_token",ht="/auth/token",pn=5000;function fn(n){let e=n??(typeof location<"u"&&location?location.pathname:""),t=/^\/(sites|share|r)\/[^/]+/.exec(e);return t?t[0]:""}function bt(n){let e=n;if(/^https?:\/\//i.test(n))try{e=new URL(n).pathname.replace(/\/+$/,"")}catch{return!1}return/^\/(sites|share|r)\/[^/]+$/.test(e)}function gn(n){if(!n||typeof n!=="object"||Array.isArray(n))return!1;let e=n;return typeof e.id==="string"&&e.id.length>0&&typeof e.name==="string"&&e.name.length>0&&Array.isArray(e.properties)&&e.properties.every((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return!1;let r=t;return typeof r.id==="string"&&r.id.length>0&&typeof r.name==="string"&&r.name.length>0&&typeof r.type==="string"&&r.type.length>0})}function mn(n){if(!n||typeof n!=="object"||Array.isArray(n))throw new C("malformed mh-manifest.json","invalid_input",500);let e=n;if(e.v!==1||e.mode!=="live"&&e.mode!=="static-async"||!Number.isInteger(e.policyRevision)||e.policyRevision<0||e.runtimeEndpoint!==void 0&&typeof e.runtimeEndpoint!=="string"||e.websocketEndpoint!==void 0&&typeof e.websocketEndpoint!=="string"||e.inboxEndpoint!==void 0&&typeof e.inboxEndpoint!=="string"||e.fallback!==void 0&&e.fallback!=="inbox")throw new C("malformed mh-manifest.json","invalid_input",500);if(e.drop!==void 0){let t=e.drop;if(!t||typeof t!=="object"||typeof t.drop_id!=="string"||!t.drop_id||typeof t.key_id!=="string"||!t.key_id||typeof t.pk!=="string"||!t.pk||t.payload_versions!==void 0&&(!Array.isArray(t.payload_versions)||!t.payload_versions.every((r)=>Number.isInteger(r)&&r>0))||t.databases!==void 0&&(!Array.isArray(t.databases)||!t.databases.every(gn))||t.password_salt!==void 0&&(typeof t.password_salt!=="string"||!t.password_salt)||t.turnstile_sitekey!==void 0&&(typeof t.turnstile_sitekey!=="string"||!t.turnstile_sitekey))throw new C("malformed mh-manifest.json drop config","invalid_input",500)}if((e.mode==="static-async"||e.fallback==="inbox")&&(!e.inboxEndpoint||!e.drop))throw new C("inbox deployment is missing endpoint or drop config","invalid_input",500);return e}function yn(n,e){if(!n)return e;if(/^https?:\/\//i.test(n))return n.replace(/\/+$/,"");if(/^https?:\/\//i.test(e))return new URL(n,e.endsWith("/")?e:e+"/").toString().replace(/\/+$/,"");if(n.startsWith("/"))return n.replace(/\/+$/,"");return`${e}/${n}`.replace(/\/+/g,"/").replace(/\/+$/,"")}function wn(n={}){let e=(n.baseUrl??fn()).replace(/\/$/,""),t=bt(e),r=n.manifestUrl!==void 0||n.baseUrl===void 0||t,o=n.manifestUrl??`${e}/mh-manifest.json`,i=/^https?:\/\//i.test(e)?new URL(ht,e).toString():ht,a=()=>{if(n.token)return n.token;try{return typeof localStorage<"u"?localStorage.getItem(_t):null}catch{return null}},s=(c)=>{try{localStorage.setItem(_t,c)}catch{}};async function l(c,g,h,R,f={}){let y=(x)=>{let P={...f};if(R!==void 0)P["content-type"]="application/json";if(x)P.authorization=`Bearer ${x}`;return fetch(c+h,{method:g,headers:P,body:R!==void 0?JSON.stringify(R):void 0})},b=a(),D=await y(b);if(D.status===401&&b&&!n.token){let x=await fetch(i,{headers:{authorization:`Bearer ${b}`}}).catch(()=>null),P=x?.ok?await x.json():null;if(P?.token)s(P.token),b=P.token,D=await y(b)}let k=await D.json().catch(()=>null);if(!D.ok||k&&k.error)throw new C(k?.error??`${D.status} ${D.statusText}`,k?.code,D.status);return k}let u=null,p=()=>{if(!r)return Promise.resolve(null);if(u)return u;let c=(async()=>{let g;try{g=await fetch(o,{signal:typeof AbortSignal<"u"&&typeof AbortSignal.timeout==="function"?AbortSignal.timeout(pn):void 0})}catch(h){throw new C(`deployment manifest unavailable: ${h.message}`,"network",0)}if(g.status===404)return null;if(!g.ok)throw new C(`deployment manifest failed (HTTP ${g.status})`,"network",g.status);return mn(await g.json().catch(()=>null))})();return u=c,c.catch(()=>{if(u===c)u=null}),c},w=(c)=>{if(c?.mode==="static-async")throw new C("static-async deployment has no live runtime","invalid_input",400);return yn(c?.runtimeEndpoint,e)},_=async(c,g,h,R)=>{let f=await p();return l(w(f),c,g,h,R)},S=(c)=>encodeURIComponent(c),O=()=>"int_"+Math.random().toString(36).slice(2,10)+Date.now().toString(36),T=null,E=(c)=>(T??=(c?.drop&&c.inboxEndpoint?Promise.resolve(le({...c.drop,v:1,endpoint:c.inboxEndpoint},{password:n.dropPassword})):Re(`${e}/mh-drop.json`,{password:n.dropPassword})).catch(()=>null),T),A=null,I=async(c,g)=>{let h={};if(g.turnstileToken)h["x-turnstile-token"]=g.turnstileToken;let R=c?.drop?.password_salt;if(n.dropPassword&&R)A??=Ee(n.dropPassword,R),h["x-drop-pass"]=await A;return h},K=async(c,g,h,R,f)=>{let y=w(c),b=bt(y),D=b?{$intent:{id:O(),submittedAt:Date.now()},values:R}:R,k=await I(c,f);try{return await l(y,g,h,D,k)}catch(x){if(c===null&&b&&x instanceof C&&(x.status===400||x.status===404))return l(y,g,h,R,k);throw x}};return{listDatabases:()=>_("GET","/api/databases"),createDatabase:(c)=>_("POST","/api/databases",c),listProperties:(c)=>_("GET",`/api/properties?db=${S(c)}`),listRecords:(c,g={})=>{let h=new URLSearchParams({db:c});if(g.sort)h.set("sort",g.sort);if(g.limit!=null)h.set("limit",String(g.limit));return _("GET",`/api/records?${h}`)},getRecord:(c)=>_("GET",`/api/record?id=${S(c)}`),createRecord:async(c,g,h={})=>{let R=await p();if(R?.mode==="static-async"){let f=await E(R);if(!f)throw new C("static-async inbox is unavailable","network",0);return f.createRecord(c,g,h)}try{return await K(R,"POST",`/api/records?db=${S(c)}`,g,h)}catch(f){if(!(f instanceof C?f.status===401:!0))throw f;if(R&&R.fallback!=="inbox")throw f;let b=await E(R);if(!b)throw f;return b.createRecord(c,g,h)}},updateRecord:async(c,g,h={})=>{let R=await p();if(R?.mode==="static-async")throw new C("static-async deployment does not support updateRecord","invalid_input",400);return K(R,"PATCH",`/api/record?id=${S(c)}`,g,h)},deleteRecord:async(c)=>{let g=await p();if(g?.mode==="static-async")throw new C("static-async deployment does not support deleteRecord","invalid_input",400);return l(w(g),"DELETE",`/api/record?id=${S(c)}`)},listDocuments:(c)=>_("GET",c?`/api/documents?db=${S(c)}`:"/api/documents"),getDocument:(c)=>_("GET",`/api/document?id=${S(c)}`),createDocument:(c)=>_("POST","/api/documents",c),updateDocument:(c,g)=>_("PATCH",`/api/document?id=${S(c)}`,g),deleteDocument:(c)=>_("DELETE",`/api/document?id=${S(c)}`),search:(c,g)=>{let h=new URLSearchParams({q:c});if(g!=null)h.set("limit",String(g));return _("GET",`/api/search?${h}`)},onUpdate(c,g={}){let h=!1,R=null,f=null,y=null,b=/(^|\/)r\/[^/]+$/.test(e)?e:null;if(b&&typeof WebSocket<"u"){let D=/^https?:\/\//i.test(b)?new URL(b+"/ws"):new URL(b+"/ws",typeof location<"u"?location.href:"http://localhost"),k=D.toString();D.protocol=D.protocol==="https:"?"wss:":"ws:";let x=0,P=new Set([4401,4403]),N=()=>{h=!0,c({gone:!0})},oe=()=>{if(h)return;let j=!1;R=new WebSocket(D.toString()),R.onopen=()=>{j=!0,y=setTimeout(()=>{x=0},5000)},R.onmessage=(V)=>{try{let H=JSON.parse(String(V.data));if(H?.type==="poke")c({seq:H.seq})}catch{}},R.onerror=()=>{},R.onclose=(V)=>{if(y!=null)clearTimeout(y),y=null;if(h)return;if(P.has(V.code)){N();return}let H=Math.min(30000,1000*2**x++),ie=H*0.25*Math.random(),U=()=>{f=setTimeout(oe,H+ie)};if(!j&&x>=3)fetch(k).then((X)=>{if(h)return;if(X.status===404)N();else U()}).catch(()=>{if(!h)U()});else U()}};oe()}else if(g.pollMs&&g.pollMs>0)f=setInterval(()=>c({}),g.pollMs);return()=>{if(h=!0,f!=null)clearTimeout(f),clearInterval(f);if(y!=null)clearTimeout(y);try{R?.close()}catch{}}}}}var Zr=wn();export{C as MetahubError,Zr as api,wn as createClient,le as createDrop,fn as detectBase,Re as initDrop};
10
+ ORDER BY created_hlc, id`).all(i.database_id);if(!a.length)continue;let s=lt(e,i.database_id),l=te(s,null,a.length);a.forEach((p,u)=>cn(e,p.id,l[u],r))}}),ct=x(function(e,t,r){let o=an(r,ge(t.name,"rec")),i=U(lt(e,t.id),null),a=y(e,"records",o,"database_id",t.id);y(e,"records",o,"created_hlc",a.hlc),y(e,"records",o,"order_key",i);for(let{prop:s,value:l}of r)y(e,"records",o,s.id,l);return ne(e,o)}),ut=x(function(e,t,r){let o=P(e,t);if(!o)throw new c("not_found",`no such database: ${t}`);return ct(e,o,st(e,o.id,r))});function ne(n,e){let t=n.query("SELECT id, database_id, data FROM records WHERE id = ? AND __deleted = 0").get(e);if(!t)return null;return at(t,H(n,t.database_id))}function it(n){return n.replace(/'/g,"''")}function dt(n,e,t={}){let r=H(n,e),o=t.filter&&Object.keys(t.filter).length?ve(r,t.filter).map(({prop:D,value:O})=>({prop:D,value:Se(n,D,O)})):[],i=o.filter((D)=>rt(D.value)),a=o.filter((D)=>!rt(D.value)),s,l=!1;if(t.sort){let D=t.sort;if(D.startsWith("-"))l=!0,D=D.slice(1);if(D!=="created"&&D!=="created_hlc"){let O=r.find((I)=>I.id===D);if(!O){let I=r.filter((j)=>j.name.toLowerCase()===D.toLowerCase());if(I.length>1)throw new c("ambiguous",`sort field "${D}" matches ${I.length} properties; use a property id`);O=I[0]}if(!O)throw new c("not_found",`unknown sort field: ${D}`);s=O}}for(let D of i)_e(n,e,D.prop);if(s)_e(n,e,s);let p=["database_id = ?","__deleted = 0"],u=[e];for(let D of i)p.push(`data ->> '${it(D.prop.id)}' = ?`),u.push(nn(D.value));let w=t.sort==null,E=s?`data ->> '${it(s.id)}'`:"created_hlc",_=`SELECT id, database_id, data FROM records WHERE ${p.join(" AND ")} `+(w?"ORDER BY order_key IS NULL, order_key, id":`ORDER BY ${E} ${l?"DESC":"ASC"}, id`);if(t.limit!=null&&a.length===0)_+=" LIMIT ?",u.push(t.limit);let T=n.query(_).all(...u).map((D)=>at(D,r));if(a.length){if(T=T.filter((D)=>a.every((O)=>JSON.stringify(D.cells[O.prop.id]??null)===JSON.stringify(O.value))),t.limit!=null)T=T.slice(0,t.limit)}return T}var Ur=x(function(e,t,r,o){if(o!=="before"&&o!=="after")throw new c("invalid_input",`unknown move position: ${o}`);let i=e.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(t);if(!i)throw new c("not_found",`no such record: ${t}`);let a=e.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(r);if(!a)throw new c("not_found",`no such record: ${r}`);if(i.database_id!==a.database_id)throw new c("invalid_input","cannot move a record across databases");if(t===r)return ne(e,t);dn(e,i.database_id);let s=Re(e,i.database_id).filter((w)=>w.id!==t),l=s.findIndex((w)=>w.id===r);if(l<0)throw new c("not_found",`no such target record: ${r}`);let p=o==="before"?s[l-1]?.order_key??null:s[l].order_key,u=o==="before"?s[l].order_key:s[l+1]?.order_key??null;if(p!==null&&u!==null&&p>=u)un(e,i.database_id),s=Re(e,i.database_id).filter((w)=>w.id!==t),l=s.findIndex((w)=>w.id===r),p=o==="before"?s[l-1]?.order_key??null:s[l].order_key,u=o==="before"?s[l].order_key:s[l+1]?.order_key??null;return y(e,"records",t,"order_key",U(p,u)),ne(e,t)}),pt=x(function(e,t,r){let o=e.query("SELECT id, database_id, data FROM records WHERE id = ? AND __deleted = 0").get(t);if(!o)throw new c("not_found",`no such record: ${t}`);let i=JSON.parse(o.data||"{}");for(let{prop:a,value:s}of r){let l=Object.hasOwn(i,a.id);if(!(s===void 0?!l:l&&JSON.stringify(s)===JSON.stringify(i[a.id])))y(e,"records",t,a.id,s)}return ne(e,t)}),ft=x(function(e,t,r){let o=e.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(t);if(!o)throw new c("not_found",`no such record: ${t}`);return pt(e,t,st(e,o.database_id,r))}),qr=x(function(e,t){if(!e.query("SELECT id FROM records WHERE id = ? AND __deleted = 0").get(t))return!1;return y(e,"records",t,"__deleted",1),!0});var pn=["id","name","icon","meta","created_hlc"];var fn=pn.join(", ");function gn(n){if(!n)return null;let e=n.meta===null?null:JSON.parse(n.meta);return{...n,meta:e&&Object.keys(e).length?e:null}}function mt(n,e,t,r){for(let[o,i]of Object.entries(r)){if(o.includes("."))throw new c("invalid_input",`meta key must not contain ".": ${o}`);let a=i===void 0?null:i,s=t&&o in t?t[o]:null;if(JSON.stringify(s??null)===JSON.stringify(a??null))continue;y(n,"databases",e,`meta.${o}`,a===null?void 0:a)}}var mn=x(function(e,t){let r=J("db",t.name),o=y(e,"databases",r,"name",t.name);if(y(e,"databases",r,"created_hlc",o.hlc),t.icon!==void 0)y(e,"databases",r,"icon",t.icon);return P(e,r)}),Yr=x(function(e,t,r){if(!P(e,t))throw new c("not_found",`no such database: ${t}`);if(r.name!==void 0)y(e,"databases",t,"name",r.name);if(r.icon!==void 0)y(e,"databases",t,"icon",r.icon);if(r.meta!==void 0){if(r.meta!==null&&(typeof r.meta!=="object"||Array.isArray(r.meta)))throw new c("invalid_input","meta must be a JSON object or null");let o=P(e,t).meta,i=r.meta??Object.fromEntries(Object.keys(o??{}).map((a)=>[a,null]));mt(e,t,o,i)}return P(e,t)}),Jr=x(function(e,t,r={}){let o=P(e,t);if(!o)throw new c("not_found",`no such database: ${t}`);let i=mn(e,{name:r.name??o.name,icon:r.icon??o.icon??void 0}),a=new Map,s=new Set;for(let u of H(e,t)){let w=u.type==="relation"&&u.config?.database===t,E=w?{...u.config,database:i.id}:u.config??void 0,_=et(e,i.id,{name:u.name,type:u.type,config:E,position:u.position});if(a.set(u.id,_.id),w)s.add(_.id)}let l=dt(e,t),p=new Map;for(let u of l){let w={};for(let[E,_]of Object.entries(u.cells)){let S=a.get(E);if(!S)continue;if(s.has(S)&&Array.isArray(_)&&_.length>0)continue;w[S]=_}p.set(u.id,ut(e,i.id,w).id)}for(let u of l){let w={};for(let[E,_]of Object.entries(u.cells)){let S=a.get(E);if(S&&s.has(S)&&Array.isArray(_)&&_.length>0)w[S]=_.map((T)=>p.get(String(T))??T)}if(Object.keys(w).length)ft(e,p.get(u.id),w)}if(o.meta!==null){let{collapsed:u,...w}=o.meta;if("views"in w)w.views=Me(w.views,a,p,new Set(H(e,t).filter((E)=>E.type==="relation"&&E.config?.database===t).map((E)=>E.id)));mt(e,i.id,null,w)}return P(e,i.id)});function P(n,e){return gn(n.query(`SELECT ${fn} FROM databases WHERE id = ? AND __deleted = 0`).get(e))}var zr=x(function(e,t){if(!P(e,t))return!1;y(e,"databases",t,"__deleted",1);let r=(o)=>{for(let i of gt(e,o,"database_id",t))y(e,o,i,"__deleted",1)};r("properties"),r("records");for(let o of gt(e,"documents","database_id",t))y(e,"documents",o,"database_id",null);return e.query("DELETE FROM meta WHERE key = 'current_db' AND value = ?").run(t),!0});function gt(n,e,t,r){return n.query(`SELECT id FROM ${e} WHERE ${t} = ? AND __deleted = 0`).all(r).map((o)=>o.id)}var wt="sealed-p256";var yn=12,wn="mh-drop-seal-v1",yt={name:"ECDH",namedCurve:"P-256"};function re(n){let e=new Uint8Array(n.byteLength);return e.set(n),e.buffer}function _t(...n){let e=n.reduce((o,i)=>o+i.byteLength,0),t=new Uint8Array(e),r=0;for(let o of n)t.set(o,r),r+=o.byteLength;return t}async function _n(n,e,t){let r=new Uint8Array(await crypto.subtle.digest("SHA-256",re(t))),o=_t(new TextEncoder().encode(wn),e,r),i=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveKey"]);return crypto.subtle.deriveKey({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(16).buffer,info:re(o)},i,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}async function ht(n,e){let t=await crypto.subtle.importKey("raw",re(n),yt,!1,[]),r=await crypto.subtle.generateKey(yt,!0,["deriveBits"]),o=new Uint8Array(await crypto.subtle.exportKey("raw",r.publicKey)),i=await crypto.subtle.deriveBits({name:"ECDH",public:t},r.privateKey,256),a=await _n(i,o,n),s=crypto.getRandomValues(new Uint8Array(yn)),l=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:re(s)},a,re(e)));return _t(o,s,l)}var bt=/^g[0-9a-z]{8}$/;function hn(){return"e"+L(16)}function Et(){return"g"+L(8)}function bn(n){return new TextEncoder().encode(JSON.stringify(n))}async function Dt(n){let e=await ht(n.pk,bn(n.payload));return{v:1,envelope_id:hn(),drop_id:n.dropId,enc:wt,key_id:n.keyId,sealed:ae(e),created_at:n.now??Date.now()}}async function xe(n,e){return ae(await Oe(n,le(e)))}function Rt(){try{if(typeof localStorage<"u"&&localStorage)return localStorage.getItem("mh_drop_probe"),{get:(e)=>localStorage.getItem(e),set:(e,t)=>localStorage.setItem(e,t)}}catch{}let n=new Map;return{get:(e)=>n.get(e)??null,set:(e,t)=>n.set(e,t)}}function En(n){if(n===401)return"auth";if(n===404)return"not_found";if(n===429)return"rate_limited";if(n===400||n===413)return"invalid_input";return"network"}async function ke(n="mh-drop.json",e={}){let r=await(e.fetcher??fetch)(n);if(!r.ok)throw new c("not_found",`no drop config at ${n}`);let o=await r.json().catch(()=>null);if(!o||o.v!==1||!o.endpoint||!o.drop_id||!o.key_id||!o.pk)throw new c("invalid_input","malformed mh-drop.json");return Dn(o,r.headers.get("date"),e),de(o,e)}function Dn(n,e,t){if(!e)return;let r=Date.parse(e);if(!Number.isFinite(r))return;let o=t.storage??Rt(),i="mh_drop_clock:"+n.endpoint.replace(/\/+$/,"");if(o.get(i))return;let a=t.now??(()=>Date.now());o.set(i,String(r-a()))}function de(n,e={}){let t=e.storage??Rt(),r=e.fetcher??fetch,o=e.now??(()=>Date.now()),i=n.endpoint.replace(/\/+$/,""),a="mh_drop_guest",s=t.get("mh_drop_guest");if(!s||!bt.test(s))s=Et(),t.set("mh_drop_guest",s);let l="mh_drop_clock:"+i,p=Number(t.get(l)??"0")||0,u="mh_drop_hlc:"+s,w=/^(\d+):(\d+)$/.exec(t.get(u)??""),E=w?{millis:Number(w[1]),counter:Number(w[2])}:{millis:0,counter:0};function _(){let f=o()+p,g=Math.max(E.millis,f),R=g===E.millis?E.counter+1:0;return E={millis:g,counter:R},t.set(u,`${g}:${R}`),`${String(g).padStart(15,"0")}-${R.toString(16).padStart(4,"0")}-${s}`}let S="mh_drop_pending:"+n.drop_id;function T(){try{let f=t.get(S),g=f?JSON.parse(f):[];return Array.isArray(g)?g:[]}catch{return[]}}function D(f){t.set(S,JSON.stringify(f))}function O(f){let g=n.databases??[],R=g.find((b)=>b.id===f)??g.find((b)=>b.name.toLowerCase()===f.toLowerCase());if(!R)throw new c("not_found",`"${f}" is not a submittable table on this page`);return R}function I(f,g){let R=f.properties.find((b)=>b.id===g)??f.properties.find((b)=>b.name.toLowerCase()===g.toLowerCase());if(!R)throw new c("not_found",`unknown column: ${g}`);return R}let j=null;function oe(){return j??=(async()=>{if(!e.password||!n.password_salt)return null;return xe(e.password,n.password_salt)})(),j}async function d(f,g,R={}){let b=O(f),v="rec_"+L(10),C={},k={},A={};for(let[G,K]of Object.entries(g)){let Y=I(b,G);C[Y.id]=K,k[Y.name]=K,A[Y.id]=K??null}let ie=(n.payload_versions??[1]).includes(2),V;if(ie){let G={intentId:"int_"+L(16),action:"createRecord",table:b.id,recordId:v,payload:A,submittedAt:o()+p};V={v:2,guest_node:s,intents:[G]}}else{let G=[],K=(pe,Q,kt)=>{G.push({hlc:kt,node_id:s,dataset:"records",row_id:v,col:pe,value:Q===void 0||Q===null?null:JSON.stringify(Q)})},Y=_();K("database_id",b.id,Y),K("created_hlc",Y,_());for(let[pe,Q]of Object.entries(A))K(pe,Q,_());V={v:1,guest_node:s,changes:G}}let X=await Dt({dropId:n.drop_id,keyId:n.key_id,pk:le(n.pk),payload:V,now:o()}),F={"content-type":"application/json"},q=await oe();if(q)F["x-drop-pass"]=q;if(R.turnstileToken)F["x-turnstile-token"]=R.turnstileToken;let W;try{W=await r(`${i}/v1/inbox/${encodeURIComponent(n.drop_id)}/envelopes`,{method:"POST",headers:F,body:JSON.stringify(X)})}catch(G){throw new c("network",`drop submission failed: ${G.message}`)}let B=await W.json().catch(()=>null);if(!W.ok)throw new c(En(W.status),B?.error??`drop submission failed (HTTP ${W.status})`);if(typeof B?.server_time==="number")p=B.server_time-o(),t.set(l,String(p));let se={id:v,database_id:b.id,values:k,cells:C,_pending:!0,envelope_id:X.envelope_id,created_at:o()};return D([...T(),se]),se}function m(f){let g=T();if(!f)return g;let R=O(f).id;return g.filter((b)=>b.database_id===R)}function h(f,g){let R=new Set(f.map((A)=>A.id)),b=T(),v=b.filter((A)=>!R.has(A.id));if(v.length!==b.length)D(v);let C=g?O(g).id:null,k=v.filter((A)=>C===null||A.database_id===C);return[...f,...k]}return{config:n,guest:s,createRecord:d,pending:m,merge:h}}class N extends Error{code;status;constructor(n,e,t){super(n);this.code=e;this.status=t;this.name="MetahubError"}}var St="mh_token",vt="/auth/token",Rn=5000;function Sn(n){let e=n??(typeof location<"u"&&location?location.pathname:""),t=/^\/(sites|share|r)\/[^/]+/.exec(e);return t?t[0]:""}function xt(n){let e=n;if(/^https?:\/\//i.test(n))try{e=new URL(n).pathname.replace(/\/+$/,"")}catch{return!1}return/^\/(sites|share|r)\/[^/]+$/.test(e)}function vn(n){if(!n||typeof n!=="object"||Array.isArray(n))return!1;let e=n;return typeof e.id==="string"&&e.id.length>0&&typeof e.name==="string"&&e.name.length>0&&Array.isArray(e.properties)&&e.properties.every((t)=>{if(!t||typeof t!=="object"||Array.isArray(t))return!1;let r=t;return typeof r.id==="string"&&r.id.length>0&&typeof r.name==="string"&&r.name.length>0&&typeof r.type==="string"&&r.type.length>0})}function xn(n){if(!n||typeof n!=="object"||Array.isArray(n))throw new N("malformed mh-manifest.json","invalid_input",500);let e=n;if(e.v!==1||e.mode!=="live"&&e.mode!=="static-async"||!Number.isInteger(e.policyRevision)||e.policyRevision<0||e.runtimeEndpoint!==void 0&&typeof e.runtimeEndpoint!=="string"||e.websocketEndpoint!==void 0&&typeof e.websocketEndpoint!=="string"||e.inboxEndpoint!==void 0&&typeof e.inboxEndpoint!=="string"||e.fallback!==void 0&&e.fallback!=="inbox")throw new N("malformed mh-manifest.json","invalid_input",500);if(e.drop!==void 0){let t=e.drop;if(!t||typeof t!=="object"||typeof t.drop_id!=="string"||!t.drop_id||typeof t.key_id!=="string"||!t.key_id||typeof t.pk!=="string"||!t.pk||t.payload_versions!==void 0&&(!Array.isArray(t.payload_versions)||!t.payload_versions.every((r)=>Number.isInteger(r)&&r>0))||t.databases!==void 0&&(!Array.isArray(t.databases)||!t.databases.every(vn))||t.password_salt!==void 0&&(typeof t.password_salt!=="string"||!t.password_salt)||t.turnstile_sitekey!==void 0&&(typeof t.turnstile_sitekey!=="string"||!t.turnstile_sitekey))throw new N("malformed mh-manifest.json drop config","invalid_input",500)}if((e.mode==="static-async"||e.fallback==="inbox")&&(!e.inboxEndpoint||!e.drop))throw new N("inbox deployment is missing endpoint or drop config","invalid_input",500);return e}function kn(n,e){if(!n)return e;if(/^https?:\/\//i.test(n))return n.replace(/\/+$/,"");if(/^https?:\/\//i.test(e))return new URL(n,e.endsWith("/")?e:e+"/").toString().replace(/\/+$/,"");if(n.startsWith("/"))return n.replace(/\/+$/,"");return`${e}/${n}`.replace(/\/+/g,"/").replace(/\/+$/,"")}function An(n={}){let e=n.fetch??((d,m)=>fetch(d,m)),t=(n.baseUrl??Sn()).replace(/\/$/,""),r=xt(t),o=n.manifestUrl!==void 0||n.baseUrl===void 0||r,i=n.manifestUrl??`${t}/mh-manifest.json`,a=/^https?:\/\//i.test(t)?new URL(vt,t).toString():vt,s=()=>{if(n.token)return n.token;try{return typeof localStorage<"u"?localStorage.getItem(St):null}catch{return null}},l=(d)=>{try{localStorage.setItem(St,d)}catch{}};async function p(d,m,h,f,g={}){let R=(k)=>{let A={...g};if(f!==void 0)A["content-type"]="application/json";if(k)A.authorization=`Bearer ${k}`;return e(d+h,{method:m,headers:A,body:f!==void 0?JSON.stringify(f):void 0})},b=s(),v=await R(b);if(v.status===401&&b&&!n.token){let k=await e(a,{headers:{authorization:`Bearer ${b}`}}).catch(()=>null),A=k?.ok?await k.json():null;if(A?.token)l(A.token),b=A.token,v=await R(b)}let C=await v.json().catch(()=>null);if(!v.ok||C&&C.error)throw new N(C?.error??`${v.status} ${v.statusText}`,C?.code,v.status);return C}let u=null,w=()=>{if(!o)return Promise.resolve(null);if(u)return u;let d=(async()=>{let m;try{m=await e(i,{signal:typeof AbortSignal<"u"&&typeof AbortSignal.timeout==="function"?AbortSignal.timeout(Rn):void 0})}catch(h){throw new N(`deployment manifest unavailable: ${h.message}`,"network",0)}if(m.status===404)return null;if(!m.ok)throw new N(`deployment manifest failed (HTTP ${m.status})`,"network",m.status);return xn(await m.json().catch(()=>null))})();return u=d,d.catch(()=>{if(u===d)u=null}),d},E=(d)=>{if(d?.mode==="static-async")throw new N("static-async deployment has no live runtime","invalid_input",400);return kn(d?.runtimeEndpoint,t)},_=async(d,m,h,f)=>{let g=await w();return p(E(g),d,m,h,f)},S=(d)=>encodeURIComponent(d),T=()=>"int_"+Math.random().toString(36).slice(2,10)+Date.now().toString(36),D=null,O=(d)=>(D??=(d?.drop&&d.inboxEndpoint?Promise.resolve(de({...d.drop,v:1,endpoint:d.inboxEndpoint},{password:n.dropPassword})):ke(`${t}/mh-drop.json`,{password:n.dropPassword})).catch(()=>null),D),I=null,j=async(d,m)=>{let h={};if(m.turnstileToken)h["x-turnstile-token"]=m.turnstileToken;let f=d?.drop?.password_salt;if(n.dropPassword&&f){I??=xe(n.dropPassword,f);let g=await I;if(g)h["x-drop-pass"]=g}return h},oe=async(d,m,h,f,g)=>{let R=E(d),b=xt(R),v=b?{$intent:{id:T(),submittedAt:Date.now()},values:f}:f,C=await j(d,g);try{return await p(R,m,h,v,C)}catch(k){if(d===null&&b&&k instanceof N&&(k.status===400||k.status===404))return p(R,m,h,f,C);throw k}};return{listDatabases:()=>_("GET","/api/databases"),createDatabase:(d)=>_("POST","/api/databases",d),listProperties:(d)=>_("GET",`/api/properties?db=${S(d)}`),listRecords:(d,m={})=>{let h=new URLSearchParams({db:d});if(m.sort)h.set("sort",m.sort);if(m.limit!=null)h.set("limit",String(m.limit));return _("GET",`/api/records?${h}`)},getRecord:(d)=>_("GET",`/api/record?id=${S(d)}`),createRecord:async(d,m,h={})=>{let f=await w();if(f?.mode==="static-async"){let g=await O(f);if(!g)throw new N("static-async inbox is unavailable","network",0);return g.createRecord(d,m,h)}try{return await oe(f,"POST",`/api/records?db=${S(d)}`,m,h)}catch(g){if(!(g instanceof N?g.status===401:!0))throw g;if(f&&f.fallback!=="inbox")throw g;let b=await O(f);if(!b)throw g;return b.createRecord(d,m,h)}},updateRecord:async(d,m,h={})=>{let f=await w();if(f?.mode==="static-async")throw new N("static-async deployment does not support updateRecord","invalid_input",400);return oe(f,"PATCH",`/api/record?id=${S(d)}`,m,h)},deleteRecord:async(d)=>{let m=await w();if(m?.mode==="static-async")throw new N("static-async deployment does not support deleteRecord","invalid_input",400);return p(E(m),"DELETE",`/api/record?id=${S(d)}`)},listDocuments:(d)=>_("GET",d?`/api/documents?db=${S(d)}`:"/api/documents"),getDocument:(d)=>_("GET",`/api/document?id=${S(d)}`),createDocument:(d)=>_("POST","/api/documents",d),updateDocument:(d,m)=>_("PATCH",`/api/document?id=${S(d)}`,m),deleteDocument:(d)=>_("DELETE",`/api/document?id=${S(d)}`),search:(d,m)=>{let h=new URLSearchParams({q:d});if(m!=null)h.set("limit",String(m));return _("GET",`/api/search?${h}`)},onUpdate(d,m={}){let h=!1,f=null,g=null,R=null,b=/(^|\/)r\/[^/]+$/.test(t)?t:null;if(b&&typeof WebSocket<"u"){let v=/^https?:\/\//i.test(b)?new URL(b+"/ws"):new URL(b+"/ws",typeof location<"u"?location.href:"http://localhost"),C=v.toString();v.protocol=v.protocol==="https:"?"wss:":"ws:";let k=0,A=new Set([4401,4403]),ie=()=>{h=!0,d({gone:!0})},V=()=>{if(h)return;let X=!1;f=new WebSocket(v.toString()),f.onopen=()=>{X=!0,R=setTimeout(()=>{k=0},5000)},f.onmessage=(F)=>{try{let q=JSON.parse(String(F.data));if(q?.type==="poke")d({seq:q.seq})}catch{}},f.onerror=()=>{},f.onclose=(F)=>{if(R!=null)clearTimeout(R),R=null;if(h)return;if(A.has(F.code)){ie();return}let q=Math.min(30000,1000*2**k++),W=q*0.25*Math.random(),B=()=>{g=setTimeout(V,q+W)};if(!X&&k>=3)e(C).then((se)=>{if(h)return;if(se.status===404)ie();else B()}).catch(()=>{if(!h)B()});else B()}};V()}else if(m.pollMs&&m.pollMs>0)g=setInterval(()=>d({}),m.pollMs);return()=>{if(h=!0,g!=null)clearTimeout(g),clearInterval(g);if(R!=null)clearTimeout(R);try{f?.close()}catch{}}}}}var Ro=An();export{N as MetahubError,Ro as api,An as createClient,de as createDrop,Sn as detectBase,ke as initDrop};