@vibecontrols/agent 2026.602.2 → 2026.602.4

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 (116) hide show
  1. package/dist/{agent-config-85pskv43.js → agent-config-4ppenhqp.js} +1 -1
  2. package/dist/{agent-ready-tracker-zp6p8e6f.js → agent-ready-tracker-kgs7td6t.js} +1 -1
  3. package/dist/app-8qe1gw9z.js +2 -0
  4. package/dist/bootstrap-workspace-qgs6d5f0.js +2 -0
  5. package/dist/bootstrap.service-vg72w8pa.js +2 -0
  6. package/dist/{bridge-client-341r9rry.js → bridge-client-1fxza4p7.js} +1 -1
  7. package/dist/cli.js +1 -1
  8. package/dist/daemon-profile-gwdcqx0q.js +2 -0
  9. package/dist/esm-6f3dfn6v.js +2 -0
  10. package/dist/{finalize-retry-handle-registry-vv241fsq.js → finalize-retry-handle-registry-xnm9kxry.js} +1 -1
  11. package/dist/{finalize-retry-worker-xp1nhv3c.js → finalize-retry-worker-dvykrzed.js} +1 -1
  12. package/dist/gateway-client-9kwnmk89.js +2 -0
  13. package/dist/{getMachineId-bsd-a56s0v8c.js → getMachineId-bsd-753751sw.js} +1 -1
  14. package/dist/{getMachineId-darwin-w9k0yw9r.js → getMachineId-darwin-na1pranq.js} +1 -1
  15. package/dist/{getMachineId-linux-anh31jbf.js → getMachineId-linux-dmn0ncdm.js} +1 -1
  16. package/dist/{getMachineId-unsupported-5hv3pwca.js → getMachineId-unsupported-yv77j894.js} +1 -1
  17. package/dist/{getMachineId-win-njb8tery.js → getMachineId-win-9hmyqmm0.js} +1 -1
  18. package/dist/highlights-00fcgwwq.js +2 -0
  19. package/dist/highlights-23bc8zge.js +2 -0
  20. package/dist/highlights-4mhb2pb0.js +2 -0
  21. package/dist/highlights-q7w64nwb.js +2 -0
  22. package/dist/highlights-xwdw5xay.js +2 -0
  23. package/dist/{index-678rwfc0.js → index-0924jp9m.js} +1 -1
  24. package/dist/{index-z5a4yxzz.js → index-1mppacnx.js} +3 -3
  25. package/dist/{index-g8zv1gta.js → index-1zf3r23y.js} +1 -1
  26. package/dist/{index-jw1k4vbk.js → index-4qq083yd.js} +1 -1
  27. package/dist/index-5amvpjqx.js +11 -0
  28. package/dist/{index-d5ysy1yn.js → index-5dysvvjv.js} +1 -1
  29. package/dist/{index-n7qyrdr1.js → index-5wpck4aw.js} +1 -1
  30. package/dist/{index-5mw3eshk.js → index-8nqp3a4d.js} +1 -1
  31. package/dist/{index-2xs9cvjn.js → index-8sdrhr3q.js} +2 -2
  32. package/dist/{index-6mprnf7p.js → index-97mq40rr.js} +1 -1
  33. package/dist/{index-0cn9bv8z.js → index-a4854mwz.js} +1 -1
  34. package/dist/{index-tp4y9jde.js → index-a9ejdv22.js} +1 -1
  35. package/dist/{index-fzzwprvk.js → index-aq81xmn0.js} +5 -5
  36. package/dist/{index-xjzmb1pn.js → index-b6x6a4xp.js} +2 -2
  37. package/dist/{index-yy1mm8zs.js → index-c7554sg7.js} +1 -1
  38. package/dist/{index-mtm8cfyt.js → index-ca5c245v.js} +2 -2
  39. package/dist/{index-2gsarrbn.js → index-d1xjj001.js} +1 -1
  40. package/dist/{index-h8a8s8sn.js → index-ebwwtwwc.js} +1 -1
  41. package/dist/{index-8sm0nkh8.js → index-ep3zb271.js} +1 -1
  42. package/dist/{index-g2raeeh4.js → index-h74va4wd.js} +2 -2
  43. package/dist/{index-v9fx5wab.js → index-hvjqgb97.js} +1 -1
  44. package/dist/{index-9bqd8veb.js → index-js1xn4sq.js} +3 -3
  45. package/dist/{index-x1h8r7pr.js → index-kt5zxp42.js} +1 -1
  46. package/dist/{index-ssjmzqcz.js → index-nmk7cbj5.js} +1 -1
  47. package/dist/{index-rdp5xq4r.js → index-nrsqzcfc.js} +1 -1
  48. package/dist/index-p23tet7a.js +2 -0
  49. package/dist/{index-04n4qgvd.js → index-pgew6sge.js} +3 -3
  50. package/dist/{index-1zw3kea7.js → index-qwtspxw8.js} +1 -1
  51. package/dist/index-qzwphe3q.js +26 -0
  52. package/dist/index-rqq0k5fc.js +16 -0
  53. package/dist/{index-6jq17k9s.js → index-rv6h14n8.js} +1 -1
  54. package/dist/{index-qfz9fy56.js → index-rw9x93zb.js} +1 -1
  55. package/dist/{index-dm6yjmgq.js → index-rzpaqrhx.js} +2 -2
  56. package/dist/{index-g3ap3xpr.js → index-s2xpdnsj.js} +4 -4
  57. package/dist/{index-vdahdt49.js → index-tgrt61qr.js} +1 -1
  58. package/dist/{index-ef95xr4z.js → index-thammzct.js} +2 -2
  59. package/dist/{index-scsjyj4m.js → index-x649afed.js} +2 -2
  60. package/dist/{index-8kvc8ttn.js → index-xrs52f2c.js} +1 -1
  61. package/dist/{index-yrgm89r8.js → index-ydc0tk17.js} +1 -1
  62. package/dist/{index-1hnw0rhc.js → index-ytgmhxsj.js} +31 -31
  63. package/dist/{index-0248afsn.js → index-z5s398n0.js} +1 -1
  64. package/dist/index.js +2 -2
  65. package/dist/injections-x3xya90r.js +2 -0
  66. package/dist/interactive-qc1j66mq.js +2 -0
  67. package/dist/key.cmd-972133dv.js +2 -0
  68. package/dist/log-shipper-hjnn1d5p.js +2 -0
  69. package/dist/{path-utils-35re7qf9.js → path-utils-hxdyv2zn.js} +1 -1
  70. package/dist/{plugin-system-c916v9an.js → plugin-system-cwznxqx5.js} +1 -1
  71. package/dist/prereqs-runner-27x3j1md.js +2 -0
  72. package/dist/profile-mount-8dc9jwt5.js +2 -0
  73. package/dist/prune-stale-shims-23y0stm8.js +2 -0
  74. package/dist/register-core-0d4adnqp.js +2 -0
  75. package/dist/secondary-profile-attach-qk5tde9n.js +2 -0
  76. package/dist/subprocess-1nna3d3x.js +2 -0
  77. package/dist/telemetry-8jfdyt51.js +2 -0
  78. package/dist/tree-sitter-javascript-q22gvtms.js +2 -0
  79. package/dist/tree-sitter-markdown-pntsjzm3.js +2 -0
  80. package/dist/tree-sitter-markdown_inline-g1wzqf7k.js +2 -0
  81. package/dist/tree-sitter-typescript-m9yfes10.js +2 -0
  82. package/dist/tree-sitter-zig-jmh62j90.js +2 -0
  83. package/dist/tunnel-bootstrap-5wgt9a1h.js +2 -0
  84. package/package.json +1 -1
  85. package/dist/app-y4yzq7yw.js +0 -2
  86. package/dist/bootstrap-workspace-zpm20zez.js +0 -2
  87. package/dist/bootstrap.service-pjmnpxha.js +0 -2
  88. package/dist/daemon-profile-vas1vf2t.js +0 -2
  89. package/dist/esm-9fpye77x.js +0 -2
  90. package/dist/gateway-client-43gzvj5s.js +0 -2
  91. package/dist/highlights-8d9mgr01.js +0 -2
  92. package/dist/highlights-jwvdxm9x.js +0 -2
  93. package/dist/highlights-qbx2vnme.js +0 -2
  94. package/dist/highlights-r3m83kn9.js +0 -2
  95. package/dist/highlights-s7mqapt6.js +0 -2
  96. package/dist/index-01qzsnwd.js +0 -16
  97. package/dist/index-hrdamx5j.js +0 -2
  98. package/dist/index-tmrbs96r.js +0 -11
  99. package/dist/index-z2yjbq9a.js +0 -26
  100. package/dist/injections-srewsjcz.js +0 -2
  101. package/dist/interactive-22ta89hc.js +0 -2
  102. package/dist/key.cmd-wgcq6kt8.js +0 -2
  103. package/dist/log-shipper-k24m8yw5.js +0 -2
  104. package/dist/prereqs-runner-ca4kt803.js +0 -2
  105. package/dist/profile-mount-npcknw6v.js +0 -2
  106. package/dist/prune-stale-shims-nkx9vq5m.js +0 -2
  107. package/dist/register-core-xhrk6ay5.js +0 -2
  108. package/dist/secondary-profile-attach-db5cr3e1.js +0 -2
  109. package/dist/subprocess-g9sk1ep9.js +0 -2
  110. package/dist/telemetry-tnq47dcs.js +0 -2
  111. package/dist/tree-sitter-javascript-3h25c6bs.js +0 -2
  112. package/dist/tree-sitter-markdown-3nemcjhe.js +0 -2
  113. package/dist/tree-sitter-markdown_inline-16ftwa53.js +0 -2
  114. package/dist/tree-sitter-typescript-f6mq6ze6.js +0 -2
  115. package/dist/tree-sitter-zig-s2trkm2d.js +0 -2
  116. package/dist/tunnel-bootstrap-2kg79ng8.js +0 -2
@@ -1,18 +1,18 @@
1
1
  // @bun
2
- import{wa as Ma,za as qa}from"./index-tp4y9jde.js";import{Aa as ja}from"./index-4wgjx8bf.js";import{Da as Ra,Wa as Ka}from"./index-g3ap3xpr.js";import{Xa as ka}from"./index-0ckffygp.js";import{nb as Pa}from"./index-v9fx5wab.js";import{Jb as La}from"./index-01qzsnwd.js";import{pd as ba,rd as yt}from"./index-g2raeeh4.js";import{Bd as os,Dd as Ca,Hd as v,Ld as Ta,Nd as g,Od as Oa,zd as Gt}from"./index-9bqd8veb.js";import{Yd as Xt,be as Ia}from"./index-0cn9bv8z.js";import{he as Ae}from"./index-yy1mm8zs.js";var Qt=[0,5000,15000,30000,60000],Fa=2000,Ua=5000,za=120000,cs=10,Ba=1048576;class Zt extends Error{resetAt;resource;constructor(e,t,i){super(e);this.name="RateLimitError",this.resource=t,this.resetAt=i}}function ei(e,t){if(!e?.length)return null;let i=e.find((r)=>r.extensions?.code==="RATE_LIMITED");if(!i)return null;let s=i.extensions?.resetAt,n=null;if(s){let r=new Date(s);if(!Number.isNaN(r.getTime()))n=r}return new Zt(`${t} rate limited${n?` until ${n.toISOString()}`:""}`,t,n)}function Xa(e){if(!e.resetAt)return 60000;let t=e.resetAt.getTime()-Date.now()+Fa;return Math.min(Math.max(t,Ua),za)}async function Ha(e,t){let i=e.headers.get("content-length");if(i){let o=Number.parseInt(i,10);if(Number.isInteger(o)&&o>t)throw Error(`Gateway response is too large (${o} bytes)`)}if(!e.body)return"";let s=e.body.getReader(),n=[],r=0;try{while(!0){let{done:o,value:c}=await s.read();if(o)break;if(!c)continue;if(r+=c.byteLength,r>t)throw await s.cancel().catch(()=>{return}),Error(`Gateway response exceeds ${t} bytes`);n.push(c)}}finally{s.releaseLock()}let a=new Uint8Array(r),l=0;for(let o of n)a.set(o,l),l+=o.byteLength;return new TextDecoder().decode(a)}async function ti(e,t){let i=await Ha(e,Ba),s;try{s=i?JSON.parse(i):{}}catch(n){let r=i.slice(0,240).replace(/\s+/g," ");throw Error(`${t} returned non-JSON response (${e.status} ${e.statusText})${r?`: ${r}`:""}`,{cause:n})}if(!e.ok){let n=i.slice(0,240).replace(/\s+/g," ");throw Error(`${t} failed (${e.status} ${e.statusText})${n?`: ${n}`:""}`)}return s}function ii(e){return e.endsWith("/graphql")?e:`${e}/graphql`}function Va(e){let t;try{t=new URL(e).hostname.toLowerCase().replace(/^\[|\]$/g,"")}catch{return!1}if(t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="0.0.0.0"||t==="host.docker.internal")return!0;return t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".local.burdenoff.com")}function si(e){if(!(process.env.VIBE_DEV_INSECURE_TLS==="1"||process.env.NODE_TLS_REJECT_UNAUTHORIZED==="0")&&!Va(e))return{};return{tls:{rejectUnauthorized:!1}}}async function Ja(e,t,i){let s=await fetch(ii(e),{method:"POST",...si(e),headers:{"Content-Type":"application/json"},body:JSON.stringify({query:`mutation AuthenticateApp($input: AuthenticateAppInput!) {
2
+ import{wa as qa,za as Fa}from"./index-a9ejdv22.js";import{Aa as Ka}from"./index-4wgjx8bf.js";import{Da as ka,Wa as Ua}from"./index-s2xpdnsj.js";import{Xa as Pa}from"./index-0ckffygp.js";import{nb as ja}from"./index-hvjqgb97.js";import{Jb as Ma}from"./index-rqq0k5fc.js";import{qd as ba,sd as yt}from"./index-h74va4wd.js";import{Ad as Gt,Cd as os,Ed as Ra,Id as v,Md as Ta,Od as g,Pd as Oa}from"./index-js1xn4sq.js";import{Zd as Xt,ce as Ia}from"./index-a4854mwz.js";import{ie as Ae}from"./index-c7554sg7.js";var Qt=[0,5000,15000,30000,60000],za=2000,Ba=5000,Xa=120000,cs=10,Ha=1048576;class Zt extends Error{resetAt;resource;constructor(e,t,i){super(e);this.name="RateLimitError",this.resource=t,this.resetAt=i}}function ei(e,t){if(!e?.length)return null;let i=e.find((r)=>r.extensions?.code==="RATE_LIMITED");if(!i)return null;let s=i.extensions?.resetAt,n=null;if(s){let r=new Date(s);if(!Number.isNaN(r.getTime()))n=r}return new Zt(`${t} rate limited${n?` until ${n.toISOString()}`:""}`,t,n)}function Va(e){if(!e.resetAt)return 60000;let t=e.resetAt.getTime()-Date.now()+za;return Math.min(Math.max(t,Ba),Xa)}async function Ja(e,t){let i=e.headers.get("content-length");if(i){let o=Number.parseInt(i,10);if(Number.isInteger(o)&&o>t)throw Error(`Gateway response is too large (${o} bytes)`)}if(!e.body)return"";let s=e.body.getReader(),n=[],r=0;try{while(!0){let{done:o,value:c}=await s.read();if(o)break;if(!c)continue;if(r+=c.byteLength,r>t)throw await s.cancel().catch(()=>{return}),Error(`Gateway response exceeds ${t} bytes`);n.push(c)}}finally{s.releaseLock()}let a=new Uint8Array(r),l=0;for(let o of n)a.set(o,l),l+=o.byteLength;return new TextDecoder().decode(a)}async function ti(e,t){let i=await Ja(e,Ha),s;try{s=i?JSON.parse(i):{}}catch(n){let r=i.slice(0,240).replace(/\s+/g," ");throw Error(`${t} returned non-JSON response (${e.status} ${e.statusText})${r?`: ${r}`:""}`,{cause:n})}if(!e.ok){let n=i.slice(0,240).replace(/\s+/g," ");throw Error(`${t} failed (${e.status} ${e.statusText})${n?`: ${n}`:""}`)}return s}function ii(e){return e.endsWith("/graphql")?e:`${e}/graphql`}function Ya(e){let t;try{t=new URL(e).hostname.toLowerCase().replace(/^\[|\]$/g,"")}catch{return!1}if(t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="0.0.0.0"||t==="host.docker.internal")return!0;return t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".local.burdenoff.com")}function si(e){if(!(process.env.VIBE_DEV_INSECURE_TLS==="1"||process.env.NODE_TLS_REJECT_UNAUTHORIZED==="0")&&!Ya(e))return{};return{tls:{rejectUnauthorized:!1}}}async function Wa(e,t,i){let s=await fetch(ii(e),{method:"POST",...si(e),headers:{"Content-Type":"application/json"},body:JSON.stringify({query:`mutation AuthenticateApp($input: AuthenticateAppInput!) {
3
3
  authenticateApp(input: $input) { accessToken expiresIn }
4
- }`,variables:{input:{clientId:t,clientSecret:i,scopes:[]}}}),signal:AbortSignal.timeout(15000)}),n=await ti(s,"authenticateApp"),r=ei(n.errors,"authenticateApp");if(r)throw r;if(n.errors?.length){let l=n.errors.map((o)=>o.extensions?.code??"UNKNOWN").join(",");throw Error(`authenticateApp errors [${l}]: ${n.errors.map((o)=>o.message).join("; ")}`)}let a=n.data?.authenticateApp?.accessToken;if(!a)throw Error("authenticateApp returned no token");return a}async function Ya(e,t,i,s){let n=await fetch(ii(e),{method:"POST",...si(e),headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({query:`mutation IssueAgentWorkspaceToken($input: IssueWorkspaceTokenInput!) {
4
+ }`,variables:{input:{clientId:t,clientSecret:i,scopes:[]}}}),signal:AbortSignal.timeout(15000)}),n=await ti(s,"authenticateApp"),r=ei(n.errors,"authenticateApp");if(r)throw r;if(n.errors?.length){let l=n.errors.map((o)=>o.extensions?.code??"UNKNOWN").join(",");throw Error(`authenticateApp errors [${l}]: ${n.errors.map((o)=>o.message).join("; ")}`)}let a=n.data?.authenticateApp?.accessToken;if(!a)throw Error("authenticateApp returned no token");return a}async function Qa(e,t,i,s){let n=await fetch(ii(e),{method:"POST",...si(e),headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({query:`mutation IssueAgentWorkspaceToken($input: IssueWorkspaceTokenInput!) {
5
5
  issueWorkspaceToken(input: $input) {
6
6
  success
7
7
  token
8
8
  expiresAt
9
9
  error { code message }
10
10
  }
11
- }`,variables:{input:{organizationId:s||i,workspaceId:i}}}),signal:AbortSignal.timeout(15000)}),r=await ti(n,"issueWorkspaceToken"),a=ei(r.errors,"issueWorkspaceToken");if(a)throw a;if(r.errors?.length)throw Error(`issueWorkspaceToken errors: ${r.errors.map((o)=>o.message).join("; ")}`);let l=r.data?.issueWorkspaceToken;if(!l?.success||!l.token){let o=l?.error?.code??"UNKNOWN",c=l?.error?.message??"no workspace token returned";throw Error(`issueWorkspaceToken failed [${o}]: ${c}`)}return l.token}async function Wa(e){let t=await Ja(e.globalGatewayUrl,e.clientId,e.clientSecret),i=await Ya(e.workspaceGatewayUrl,t,e.workspaceId,e.organizationId),s=await fetch(ii(e.workspaceGatewayUrl),{method:"POST",...si(e.workspaceGatewayUrl),headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`,"X-Workspace-Authorization":`Bearer ${i}`},body:JSON.stringify({query:`query FetchAgentEncryptionKey($workspaceId: ID!) {
11
+ }`,variables:{input:{organizationId:s||i,workspaceId:i}}}),signal:AbortSignal.timeout(15000)}),r=await ti(n,"issueWorkspaceToken"),a=ei(r.errors,"issueWorkspaceToken");if(a)throw a;if(r.errors?.length)throw Error(`issueWorkspaceToken errors: ${r.errors.map((o)=>o.message).join("; ")}`);let l=r.data?.issueWorkspaceToken;if(!l?.success||!l.token){let o=l?.error?.code??"UNKNOWN",c=l?.error?.message??"no workspace token returned";throw Error(`issueWorkspaceToken failed [${o}]: ${c}`)}return l.token}async function Ga(e){let t=await Wa(e.globalGatewayUrl,e.clientId,e.clientSecret),i=await Qa(e.workspaceGatewayUrl,t,e.workspaceId,e.organizationId),s=await fetch(ii(e.workspaceGatewayUrl),{method:"POST",...si(e.workspaceGatewayUrl),headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`,"X-Workspace-Authorization":`Bearer ${i}`},body:JSON.stringify({query:`query FetchAgentEncryptionKey($workspaceId: ID!) {
12
12
  vibecontrolsAgentEncryptionKey(workspaceId: $workspaceId)
13
- }`,variables:{workspaceId:e.workspaceId}}),signal:AbortSignal.timeout(15000)}),n=await ti(s,"vibecontrolsAgentEncryptionKey"),r=ei(n.errors,"vibecontrolsAgentEncryptionKey");if(r)throw r;if(n.errors?.length)throw Error(`vibecontrolsAgentEncryptionKey errors: ${n.errors.map((l)=>l.message).join("; ")}`);let a=n.data?.vibecontrolsAgentEncryptionKey;if(!a)throw Error("vibecontrolsAgentEncryptionKey returned empty");return a}async function hs(e,t=Qt.length,i={}){let s={...e,globalGatewayUrl:Gt(e.globalGatewayUrl,"globalGatewayUrl"),workspaceGatewayUrl:Gt(e.workspaceGatewayUrl,"workspaceGatewayUrl")},n=i.signal,r=()=>{if(n?.aborted)throw n.reason instanceof Error?n.reason:Error("encryption key fetch aborted")},a=(h)=>new Promise((u,d)=>{let _=setTimeout(()=>{if(n)n.removeEventListener("abort",f);u()},h),f=()=>{clearTimeout(_),d(n?.reason instanceof Error?n.reason:Error("encryption key fetch aborted"))};n?.addEventListener("abort",f,{once:!0})}),l,o=0,c=0;while(o<t){r();try{let h=await Wa(s);return g().logger.info("finalizer","Storage encryption key fetched from backend",{attempt:o+1,rateLimitRetries:c}),h}catch(h){if(l=h,r(),h instanceof Zt){if(c>=cs){g().logger.error("finalizer","Rate-limit retries exhausted; giving up",{resource:h.resource,resetAt:h.resetAt?.toISOString()??null,rateLimitRetries:c});break}let _=Xa(h);c+=1,g().logger.warn("finalizer",`Rate limited by ${h.resource}; waiting ${Math.round(_/1000)}s for window to clear (retry ${c}/${cs})`,{resource:h.resource,resetAt:h.resetAt?.toISOString()??null,waitMs:_}),await a(_);continue}if(o+=1,o>=t){g().logger.error("finalizer","Failed to fetch storage encryption key from backend (final attempt)",{error:String(h),attempts:t});break}let d=Qt[o]??Qt.at(-1)??0;if(g().logger.warn("finalizer",`Storage key fetch attempt ${o}/${t} failed; retrying in ${Math.round(d/1000)}s`,{error:String(h)}),d>0)await a(d)}}throw l instanceof Error?l:Error(String(l??"encryption key fetch failed"))}import{existsSync as Qa,readFileSync as Ga}from"fs";import{dirname as ni,join as Za}from"path";import{fileURLToPath as eo}from"url";import{closeSync as to,existsSync as io,mkdirSync as so,openSync as no,readFileSync as ro,unlinkSync as ds,writeFileSync as ao}from"fs";import{join as oo}from"path";import lo from"crypto";import ze from"path";import j from"fs";import ri from"zlib";import co from"http";import{closeSync as ho,existsSync as uo,mkdirSync as _o,openSync as fo,readFileSync as po,unlinkSync as us,writeFileSync as mo}from"fs";import{join as go}from"path";import yo from"crypto";import Be from"path";import q from"fs";import ai from"zlib";import wo from"http";import{closeSync as Ao,existsSync as xo,mkdirSync as vo,openSync as Eo,readFileSync as So,unlinkSync as _s,writeFileSync as Io}from"fs";import{join as bo}from"path";import To from"crypto";import Xe from"path";import K from"fs";import oi from"zlib";import Oo from"http";import{closeSync as No,existsSync as $o,mkdirSync as Do,openSync as Co,readFileSync as Ro,unlinkSync as fs,writeFileSync as ko}from"fs";import{join as Lo}from"path";import Po from"crypto";import He from"path";import F from"fs";import li from"zlib";import Mo from"http";function jo(){let e=Date.now().toString(16),t;try{t=lo.randomBytes(8).toString("hex")}catch{let i=new Uint8Array(8);crypto.getRandomValues(i),t=Array.from(i).map((s)=>s.toString(16).padStart(2,"0")).join("")}return`${e}${t}`}function ps(e,t){let i=e instanceof Error?e.message:e;if(t==="error")console.error(i);else console.log(i)}var ms=new Set(["__proto__","constructor","prototype"]);function Pt(e,t){if(!t.includes(".")){if(ms.has(t))return;return e[t]}let i=e;for(let s of t.split(".")){if(ms.has(s))return;if(i==null)return;i=i[s]}return i}class Me extends Error{constructor(e,t,i={}){super(t);this.name=this.constructor.name,this.code=e,this.details=i}}class N extends Me{}class xe extends Me{}class me extends Me{}class Re extends Me{}class ue extends Me{}class Qe extends Me{}function gi(e,t){if(e===t)return!0;if(e==null||t==null)return!1;if(typeof e!==typeof t)return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.source===t.source&&e.flags===t.flags;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!gi(e[i],t[i]))return!1;return!0}if(typeof e==="object"){if(Array.isArray(t))return!1;let i=Object.keys(e);if(i.length!==Object.keys(t).length)return!1;for(let s of i){if(!Object.prototype.hasOwnProperty.call(t,s))return!1;if(!gi(e[s],t[s]))return!1}return!0}return!1}function H(e,t){if(typeof t==="function")return t(e);if(t==null)return!0;if(typeof t==="object"&&Object.keys(t).length===0)return!0;if("$or"in t){let i=t.$or;if(!Array.isArray(i))throw new Qe("ERR_SKALEX_QUERY_INVALID_OPERATOR","$or must be an array of filters",{operator:"$or"});if(!i.some((s)=>H(e,s)))return!1}if("$and"in t){let i=t.$and;if(!Array.isArray(i))throw new Qe("ERR_SKALEX_QUERY_INVALID_OPERATOR","$and must be an array of filters",{operator:"$and"});if(!i.every((s)=>H(e,s)))return!1}if("$not"in t){if(H(e,t.$not))return!1}for(let i in t){if(i==="$or"||i==="$and"||i==="$not")continue;let s=t[i],n;try{n=Pt(e,i)}catch{return!1}if(s instanceof RegExp){if(!s.test(String(n)))return!1}else if(typeof s==="object"&&s!==null){if(Object.keys(s).some((r)=>r.startsWith("$"))){if("$eq"in s&&n!==s.$eq)return!1;if("$ne"in s&&n===s.$ne)return!1;if("$gt"in s&&!(n>s.$gt))return!1;if("$lt"in s&&!(n<s.$lt))return!1;if("$gte"in s&&!(n>=s.$gte))return!1;if("$lte"in s&&!(n<=s.$lte))return!1;if("$in"in s&&!s.$in.includes(n))return!1;if("$nin"in s&&s.$nin.includes(n))return!1;if("$regex"in s){if(!(s.$regex instanceof RegExp?s.$regex:new RegExp(s.$regex)).test(String(n)))return!1}if("$fn"in s&&!s.$fn(n))return!1}else if(!gi(n,s))return!1}else if(n!==s)return!1}return!0}function qo(e,t=new Set){if(typeof e!=="object"||e===null||typeof e==="function")return e;let i=[],s=[],n=[],r=[],a=[];for(let o in e){if(o==="$or"||o==="$and"||o==="$not"){a.push(o);continue}let c=e[o];if(t.has(o))i.push(o);else if(c instanceof RegExp||typeof c==="object"&&c!==null&&(("$regex"in c)||("$fn"in c))||typeof c==="function")r.push(o);else if(typeof c==="object"&&c!==null&&(("$gt"in c)||("$lt"in c)||("$gte"in c)||("$lte"in c)||("$ne"in c)||("$in"in c)||("$nin"in c)))n.push(o);else s.push(o)}let l={};for(let o of[...i,...s,...n,...r,...a])l[o]=e[o];return l}var yi=new Set(["string","number","boolean","object","array","date","any"]);function Ii(e){if(Array.isArray(e))return"array";if(e instanceof Date)return"date";return typeof e}function pn(e){let t=new Map,i=[];for(let[s,n]of Object.entries(e)){let r;if(typeof n==="string"){if(!yi.has(n))throw new N("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${n}" for field "${s}"`,{field:s,type:n});r={type:n,required:!1,unique:!1}}else if(typeof n==="object"&&n!==null){let{type:a="any",required:l=!1,unique:o=!1,enum:c}=n;if(!yi.has(a))throw new N("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${a}" for field "${s}"`,{field:s,type:a});if(r={type:a,required:l,unique:o,enum:c},o)i.push(s)}else throw new N("ERR_SKALEX_VALIDATION_INVALID_SCHEMA",`Invalid schema definition for field "${s}"`,{field:s});t.set(s,r)}return{fields:t,uniqueFields:i}}function gs(e,t,i=!1){let s=[];for(let[n,r]of t){let a=e[n],l=a===void 0||a===null;if(r.required&&l){s.push(`Field "${n}" is required`);continue}if(l)continue;if(r.type!=="any"){let o=Ii(a);if(o!==r.type)s.push(`Field "${n}" must be of type "${r.type}", got "${o}"`)}if(r.enum&&!r.enum.includes(a))s.push(`Field "${n}" must be one of [${r.enum.map((o)=>JSON.stringify(o)).join(", ")}], got ${JSON.stringify(a)}`)}if(i){for(let n of Object.keys(e))if(!n.startsWith("_")&&!t.has(n))s.push(`Unknown field "${n}" (strict mode)`)}return s}function ys(e,t){let i={};for(let[s,n]of Object.entries(e)){if(s.startsWith("_")){i[s]=n;continue}if(!t.has(s))continue;let r=t.get(s);if(r.type!=="any"){if(Ii(n)!==r.type)continue}if(r.enum&&!r.enum.includes(n))continue;i[s]=n}return i}function Ko(e){let t={};for(let[i,s]of Object.entries(e)){if(i.startsWith("_"))continue;let n=Ii(s);t[i]=yi.has(n)?n:"any"}return t}function Fo(e){if(typeof e==="number"){if(e<=0)throw new N("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got ${e}`,{ttl:e});return e*1000}if(typeof e!=="string")throw new N("ERR_SKALEX_VALIDATION_TTL",`Invalid TTL value: ${e}`,{ttl:e});let t=e.match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/);if(!t)throw new N("ERR_SKALEX_VALIDATION_TTL_FORMAT",`Invalid TTL format: "${e}". Use e.g. 300 (seconds), "30m", "24h", "7d"`,{ttl:e});let i=parseFloat(t[1]);if(i<=0)throw new N("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got "${e}"`,{ttl:e});let s=t[2],n=i*{ms:1,s:1000,m:60000,h:3600000,d:86400000}[s];if(!isFinite(n))throw new N("ERR_SKALEX_VALIDATION_TTL",`TTL value "${e}" is too large`,{ttl:e});return n}function Uo(e){return new Date(Date.now()+Fo(e))}function zo(e,t,i=null){let s=Date.now(),n=0,r=e.length;while(r--){let a=e[r];if(a._expiresAt&&new Date(a._expiresAt).getTime()<=s){if(e.splice(r,1),t.delete(a._id),i)i(a);n++}}return n}function ws(e,t){if(e.length!==t.length)throw new Qe("ERR_SKALEX_QUERY_VECTOR_MISMATCH",`Vector dimension mismatch: ${e.length} vs ${t.length}`,{expected:e.length,got:t.length});let i=0,s=0,n=0;for(let a=0;a<e.length;a++)i+=e[a]*t[a],s+=e[a]*e[a],n+=t[a]*t[a];let r=Math.sqrt(s*n);return r===0?0:i/r}function U(e){if(!("_vector"in e))return{...e};let{_vector:t,...i}=e;return i}function Bo(e){return e.length}function Xo(e,t){let i=0;for(let s of e){let n=Pt(s,t);if(typeof n==="number"&&!isNaN(n))i+=n}return i}function Ho(e,t){let i=0,s=0;for(let n of e){let r=Pt(n,t);if(typeof r==="number"&&!isNaN(r))i+=r,s++}return s===0?null:i/s}function Vo(e,t){let i=Object.create(null);for(let s of e){let n=String(Pt(s,t)??"__null__");if(!i[n])i[n]=[];i[n].push(s)}return i}class mn{constructor(e){this._col=e}get _ctx(){return this._col._ctx}async execute({op:e,beforeHook:t,afterHook:i,hookPayload:s,mutate:n,afterHookPayload:r,save:a,session:l}){let o=this._ctx;await o.ensureConnected(),this._col._txSnapshotIfNeeded();let c=o.txManager,h=c.active&&this._col._activeTxId===c.context?.id,u=h?c.context.id:null,d=this._col._createdInTxId,_=()=>{if(u!==null&&c._abortedIds.has(u))throw new me("ERR_SKALEX_TX_ABORTED",`Transaction ${u} was aborted. No further mutations allowed.`);if(d!==null&&c._abortedIds.has(d))throw new me("ERR_SKALEX_TX_ABORTED",`Transaction ${d} was aborted. Collection obtained inside that transaction cannot be used for further mutations.`)};if(h||d!==null)_();if(t)await o.plugins.run(t,s);let{docs:f,prevDocs:p=[]}=await n(_);if(o.persistence.markDirty(o.collections,this._col.name),await this._col._saveIfNeeded(a),this._col._changelogEnabled)for(let m=0;m<f.length;m++)await o.logChange(e,this._col.name,f[m],p[m]??null,l||null);if(!h||!c.defer(()=>o.sessionStats.recordWrite(l)))o.sessionStats.recordWrite(l);for(let m of f)o.emitEvent(this._col.name,{op:e,collection:this._col.name,doc:U(m)});if(i)if(r)await o.runAfterHook(i,r(f));else for(let m of f)await o.runAfterHook(i,{collection:this._col.name,doc:U(m)});return{docs:f,prevDocs:p}}}function Jo(e){let t={};for(let i in e){if(i.startsWith("$"))continue;let s=e[i];if(s&&typeof s==="object"&&!Array.isArray(s)){let n=Object.keys(s);if(n.length===1&&n[0]==="$eq")t[i]=s.$eq}else t[i]=s}return t}var gn=new Set(["__proto__","constructor","prototype"]);function yn(e){if(typeof e!=="object"||e===null||Array.isArray(e))return e;let t={};for(let i of Object.keys(e)){if(gn.has(i))continue;t[i]=yn(e[i])}return t}class wn{constructor(e,t){this.name=e.collectionName,this.database=t,this._ctx=t._buildCollectionContext(),this._store=e,this._pipeline=new mn(this),this._createdInTxId=t._txManager.context?.id??null,this._activeTxId=null}get _data(){return this._store.data}set _data(e){this._store.data=e}get _index(){return this._store.index}get _fieldIndex(){return this._store.fieldIndex||null}get _schema(){return this._store.schema?this._store.schema.fields:null}get _changelogEnabled(){return this._store.changelog===!0}get _softDelete(){return this._store.softDelete===!0}get _versioning(){return this._store.versioning===!0}get _strict(){return this._store.strict===!0}get _onSchemaError(){return this._store.onSchemaError??"throw"}get _defaultTtl(){return this._store.defaultTtl||null}get _defaultEmbed(){return this._store.defaultEmbed||null}get _maxDocs(){return this._store.maxDocs||null}async insertOne(e,t={}){let{save:i,ifNotExists:s,ttl:n,embed:r,session:a}=t;if(s){await this._ctx.ensureConnected();let o=this._findRaw(e);if(o)return U({...o})}let{docs:l}=await this._insertCore([e],{ttl:n,embed:r,session:a,save:i});return U(l[0])}async insertMany(e,t={}){let{save:i,ttl:s,embed:n,session:r}=t,{docs:a}=await this._insertCore(e,{ttl:s,embed:n,session:r,save:i});return a.map(U)}async _insertCore(e,{ttl:t,embed:i,session:s,save:n}){return this._pipeline.execute({op:"insert",beforeHook:null,afterHook:"afterInsert",hookPayload:null,save:n,session:s,mutate:async(r)=>{let a=[],l=new Set;for(let o of e){let c=this._applyValidation(o);await this._ctx.plugins.run("beforeInsert",{collection:this.name,doc:c});let h=await this._buildDoc(c,{ttl:t,embed:i});if(this._index.has(h._id)||l.has(h._id))throw new xe("ERR_SKALEX_UNIQUE_DUPLICATE_ID",`Duplicate _id "${h._id}" in collection "${this.name}"`,{id:h._id,collection:this.name});l.add(h._id),a.push(h)}if(r(),this._fieldIndex)this._fieldIndex.assertUniqueBatch(a);for(let o of a)this._addToIndex(o);this._data.push(...a);for(let o of a)this._index.set(o._id,o);return this._enforceCapAfterInsert(),{docs:a}}})}async updateOne(e,t,i={}){await this._ctx.ensureConnected();let s=this._findRaw(e);if(!s)return null;let{save:n,session:r}=i,{docs:a}=await this._updateCore([s],e,t,{save:n,session:r});return U(a[0])}async updateMany(e,t,i={}){await this._ctx.ensureConnected();let s=this._findAllRaw(e);if(s.length===0)return[];let{save:n,session:r}=i,{docs:a}=await this._updateCore(s,e,t,{save:n,session:r});return a.map(U)}async _updateCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"update",beforeHook:"beforeUpdate",afterHook:"afterUpdate",hookPayload:{collection:this.name,filter:t,update:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:t,update:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{let a=this._changelogEnabled?e.map((h)=>structuredClone(h)):e.map(()=>null),l=e.map((h)=>this._prepareUpdatedDoc(h,i));this._assertUniqueCandidates(e,l),r();let o=new Set(e),c=new Map;for(let h=0;h<this._data.length;h++)if(o.has(this._data[h]))c.set(this._data[h],h);for(let h=0;h<e.length;h++)this._commitUpdatedDoc(e[h],l[h],c);return{docs:l,prevDocs:a}}})}applyUpdate(e,t){for(let i in t){if(gn.has(i))continue;if(i==="_id"||i==="createdAt")continue;let s=t[i];if(Array.isArray(s))e[i]=s;else if(typeof s==="object"&&s!==null){let n=Object.keys(s);if(n.some((r)=>r.startsWith("$"))){for(let r of n)if(r==="$inc"&&typeof e[i]==="number")e[i]+=s[r];else if(r==="$push"){if(!Array.isArray(e[i]))e[i]=[];e[i].push(s[r])}}else e[i]=yn(s)}else e[i]=s}if(e.updatedAt=new Date,this._versioning)e._version=(e._version??0)+1;return e}_prepareUpdatedDoc(e,t){let i=structuredClone(e),s=structuredClone(e);if(this.applyUpdate(s,t),!this._schema)return s;let n=gs(s,this._schema,this._strict);if(!n.length)return s;switch(this._onSchemaError){case"throw":throw new N("ERR_SKALEX_VALIDATION_UPDATE",`Update validation failed on doc "${e._id}": ${n.join("; ")}`,{id:e._id,errors:n});case"strip":return this._stripCandidateToValid(s,i);default:return this._ctx.logger(`[${this.name}] Update validation warning: ${n.join("; ")}`,"warn"),s}}_stripCandidateToValid(e,t){let i=ys(e,this._schema),s=structuredClone(t);for(let[n,r]of Object.entries(i)){if(n.startsWith("_"))continue;s[n]=r}if(s.updatedAt=e.updatedAt,this._versioning)s._version=e._version;return s}_commitUpdatedDoc(e,t,i){let s=i?i.get(e):this._data.indexOf(e);if(s===void 0||s===-1)throw new Re("ERR_SKALEX_PERSISTENCE_DOC_MISSING",`Document "${e._id}" no longer exists in collection "${this.name}"`,{id:e._id,collection:this.name});this._data[s]=t,this._index.set(t._id,t),this._updateInIndex(e,t)}_assertUniqueCandidates(e,t){this._fieldIndex?.assertUniqueCandidates(e,t)}async upsert(e,t,i={}){if(await this._ctx.ensureConnected(),this._findRaw(e))return this.updateOne(e,t,i);return this.insertOne({...Jo(e),...t},i)}async upsertMany(e,t,i={}){await this._ctx.ensureConnected();let{save:s,...n}=i,r=[];for(let a of e)r.push(await this.upsert({[t]:a[t]},a,{...n,save:!1}));return await this._saveIfNeeded(s),r}async restore(e,t={}){if(!this._softDelete)throw new Qe("ERR_SKALEX_QUERY_SOFT_DELETE_REQUIRED",`restore() requires softDelete on "${this.name}"`,{collection:this.name});await this._ctx.ensureConnected();let{save:i,session:s}=t,n=this._findRaw(e,{includeDeleted:!0});if(!n||!n._deletedAt)return null;let{docs:r}=await this._pipeline.execute({op:"restore",beforeHook:null,afterHook:null,hookPayload:null,save:i,session:s,mutate:async(a)=>{return a(),delete n._deletedAt,n.updatedAt=new Date,this._index.set(n._id,n),{docs:[n]}}});return U(r[0])}watch(e,t){if(typeof e==="function")t=e,e=null;if(t)return this._ctx.eventBus.on(this.name,(i)=>{if(!e||H(i.doc,e))t(i)});return this._watchIterator(e)}_watchIterator(e){let t=[],i=null,s=!1,n=this._ctx.eventBus.on(this.name,(r)=>{if(e&&!H(r.doc,e))return;if(i){let a=i;i=null,a({value:r,done:!1})}else t.push(r)});return{[Symbol.asyncIterator](){return this},next(){if(t.length>0)return Promise.resolve({value:t.shift(),done:!1});if(s)return Promise.resolve({value:void 0,done:!0});return new Promise((r)=>{i=r})},return(){if(s=!0,n(),i){let r=i;i=null,r({value:void 0,done:!0})}return Promise.resolve({value:void 0,done:!0})}}}async count(e={}){return await this._ctx.ensureConnected(),Bo(this._findAllRaw(e))}async sum(e,t={}){return await this._ctx.ensureConnected(),Xo(this._findAllRaw(t),e)}async avg(e,t={}){return await this._ctx.ensureConnected(),Ho(this._findAllRaw(t),e)}async groupBy(e,t={}){return await this._ctx.ensureConnected(),Vo(this._findAllRaw(t),e)}async findOne(e,t={}){await this._ctx.ensureConnected();let{populate:i,select:s,includeDeleted:n=!1}=t,r=this._findRaw(e,{includeDeleted:n});if(!r)return null;let a=this._projectDoc(r,s);if(i)await this._populateDoc(a,r,i);return a}async find(e,t={}){await this._ctx.ensureConnected();let i=Date.now(),{populate:s,select:n,sort:r,page:a=1,limit:l,session:o,includeDeleted:c=!1}=t;await this._ctx.plugins.run("beforeFind",{collection:this.name,filter:e,options:t});let h=this._getCandidates(e),u=qo(e,this._fieldIndex?this._fieldIndex.indexedFields:new Set),d=[];for(let f of h){if(this._softDelete&&f._deletedAt&&!c)continue;if(!H(f,u))continue;let p=this._projectDoc(f,n);if(s)await this._populateDoc(p,f,s);d.push(p)}if(r){let f=Object.keys(r);d.sort((p,m)=>{for(let w of f){let x=r[w];if(p[w]<m[w])return-x;if(p[w]>m[w])return x}return 0})}let _;if(l){let f=d.length,p=Math.ceil(f/l),m=(a-1)*l;d=d.slice(m,m+l),_={page:a,totalDocs:f,totalPages:p}}return this._ctx.queryLog?.record({collection:this.name,op:"find",filter:e,duration:Date.now()-i,resultCount:d.length}),this._ctx.sessionStats.recordRead(o),await this._ctx.plugins.run("afterFind",{collection:this.name,filter:e,options:t,docs:d}),_?{docs:d,..._}:{docs:d}}async search(e,{filter:t,limit:i=10,minScore:s=0,session:n}={}){await this._ctx.ensureConnected();let r=Date.now();await this._ctx.plugins.run("beforeSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s}});let a=await this._ctx.embed(e),l=t?this._findAllRaw(t):this._data,o=[];for(let d of l){if(!d._vector)continue;let _=ws(a,d._vector);if(_>=s)o.push({doc:d,score:_})}o.sort((d,_)=>_.score-d.score);let c=o.slice(0,i);this._ctx.queryLog?.record({collection:this.name,op:"search",query:e,duration:Date.now()-r,resultCount:c.length}),this._ctx.sessionStats.recordRead(n);let h=c.map((d)=>U(d.doc)),u=c.map((d)=>d.score);return await this._ctx.plugins.run("afterSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s},docs:h,scores:u}),{docs:h,scores:u}}async similar(e,{limit:t=10,minScore:i=0}={}){await this._ctx.ensureConnected();let s=this._index.get(e);if(!s||!s._vector)return{docs:[],scores:[]};let n=[];for(let a of this._data){if(a._id===e||!a._vector)continue;let l=ws(s._vector,a._vector);if(l>=i)n.push({doc:a,score:l})}n.sort((a,l)=>l.score-a.score);let r=n.slice(0,t);return{docs:r.map((a)=>U(a.doc)),scores:r.map((a)=>a.score)}}async deleteOne(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findRaw(e);if(!r)return null;let{docs:a}=await this._deleteCore("soft",[r],e,{save:i,session:s});return U(a[0])}let{docs:n}=await this._deleteCore("hard",null,e,{save:i,session:s});if(n.length===0)return null;return U(n[0])}async deleteMany(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findAllRaw(e);if(r.length===0)return[];let{docs:a}=await this._deleteCore("soft",r,e,{save:i,session:s});return a.map(U)}let{docs:n}=await this._deleteCore("hardMany",null,e,{save:i,session:s});return n.map(U)}async _deleteCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"delete",beforeHook:"beforeDelete",afterHook:"afterDelete",hookPayload:{collection:this.name,filter:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{if(r(),e==="soft"){let o=new Date;for(let c of t)c._deletedAt=o,c.updatedAt=o,this._index.set(c._id,c);return{docs:t}}if(e==="hard"){let o=this._findIndex(i);if(o===-1)return{docs:[]};let c=this._data.splice(o,1)[0];return this._index.delete(c._id),this._removeFromIndex(c),{docs:[c]}}let a=[],l=[];for(let o of this._data)if(H(o,i))a.push(o),this._index.delete(o._id),this._removeFromIndex(o);else l.push(o);return this._data=l,{docs:a}}})}async export(e={},t={}){let{dir:i,name:s,format:n="json"}=t;try{let r=this._data.filter((h)=>H(h,e));if(r.length===0)throw new Qe("ERR_SKALEX_QUERY_EXPORT_EMPTY",`export(): no documents matched the filter in "${this.name}"`,{collection:this.name});let a;if(n==="json")a=JSON.stringify(r,null,2);else{let h=(_)=>{if(_==null)return"";let f=typeof _==="object"?JSON.stringify(_):String(_);return f.includes(",")||f.includes('"')||f.includes(`
13
+ }`,variables:{workspaceId:e.workspaceId}}),signal:AbortSignal.timeout(15000)}),n=await ti(s,"vibecontrolsAgentEncryptionKey"),r=ei(n.errors,"vibecontrolsAgentEncryptionKey");if(r)throw r;if(n.errors?.length)throw Error(`vibecontrolsAgentEncryptionKey errors: ${n.errors.map((l)=>l.message).join("; ")}`);let a=n.data?.vibecontrolsAgentEncryptionKey;if(!a)throw Error("vibecontrolsAgentEncryptionKey returned empty");return a}async function hs(e,t=Qt.length,i={}){let s={...e,globalGatewayUrl:Gt(e.globalGatewayUrl,"globalGatewayUrl"),workspaceGatewayUrl:Gt(e.workspaceGatewayUrl,"workspaceGatewayUrl")},n=i.signal,r=()=>{if(n?.aborted)throw n.reason instanceof Error?n.reason:Error("encryption key fetch aborted")},a=(h)=>new Promise((u,d)=>{let _=setTimeout(()=>{if(n)n.removeEventListener("abort",f);u()},h),f=()=>{clearTimeout(_),d(n?.reason instanceof Error?n.reason:Error("encryption key fetch aborted"))};n?.addEventListener("abort",f,{once:!0})}),l,o=0,c=0;while(o<t){r();try{let h=await Ga(s);return g().logger.info("finalizer","Storage encryption key fetched from backend",{attempt:o+1,rateLimitRetries:c}),h}catch(h){if(l=h,r(),h instanceof Zt){if(c>=cs){g().logger.error("finalizer","Rate-limit retries exhausted; giving up",{resource:h.resource,resetAt:h.resetAt?.toISOString()??null,rateLimitRetries:c});break}let _=Va(h);c+=1,g().logger.warn("finalizer",`Rate limited by ${h.resource}; waiting ${Math.round(_/1000)}s for window to clear (retry ${c}/${cs})`,{resource:h.resource,resetAt:h.resetAt?.toISOString()??null,waitMs:_}),await a(_);continue}if(o+=1,o>=t){g().logger.error("finalizer","Failed to fetch storage encryption key from backend (final attempt)",{error:String(h),attempts:t});break}let d=Qt[o]??Qt.at(-1)??0;if(g().logger.warn("finalizer",`Storage key fetch attempt ${o}/${t} failed; retrying in ${Math.round(d/1000)}s`,{error:String(h)}),d>0)await a(d)}}throw l instanceof Error?l:Error(String(l??"encryption key fetch failed"))}import{existsSync as Za,readFileSync as eo}from"fs";import{dirname as ni,join as to}from"path";import{fileURLToPath as io}from"url";import{closeSync as so,existsSync as no,mkdirSync as ro,openSync as ao,readFileSync as oo,unlinkSync as ds,writeFileSync as lo}from"fs";import{join as co}from"path";import ho from"crypto";import ze from"path";import j from"fs";import ri from"zlib";import uo from"http";import{closeSync as _o,existsSync as fo,mkdirSync as po,openSync as mo,readFileSync as go,unlinkSync as us,writeFileSync as yo}from"fs";import{join as wo}from"path";import Ao from"crypto";import Be from"path";import q from"fs";import ai from"zlib";import xo from"http";import{closeSync as vo,existsSync as Eo,mkdirSync as So,openSync as Io,readFileSync as bo,unlinkSync as _s,writeFileSync as To}from"fs";import{join as Oo}from"path";import No from"crypto";import Xe from"path";import K from"fs";import oi from"zlib";import $o from"http";import{closeSync as Do,existsSync as Co,mkdirSync as Ro,openSync as ko,readFileSync as Lo,unlinkSync as fs,writeFileSync as Po}from"fs";import{join as Mo}from"path";import jo from"crypto";import He from"path";import F from"fs";import li from"zlib";import qo from"http";function Ko(){let e=Date.now().toString(16),t;try{t=ho.randomBytes(8).toString("hex")}catch{let i=new Uint8Array(8);crypto.getRandomValues(i),t=Array.from(i).map((s)=>s.toString(16).padStart(2,"0")).join("")}return`${e}${t}`}function ps(e,t){let i=e instanceof Error?e.message:e;if(t==="error")console.error(i);else console.log(i)}var ms=new Set(["__proto__","constructor","prototype"]);function Pt(e,t){if(!t.includes(".")){if(ms.has(t))return;return e[t]}let i=e;for(let s of t.split(".")){if(ms.has(s))return;if(i==null)return;i=i[s]}return i}class Me extends Error{constructor(e,t,i={}){super(t);this.name=this.constructor.name,this.code=e,this.details=i}}class N extends Me{}class xe extends Me{}class me extends Me{}class Re extends Me{}class ue extends Me{}class Qe extends Me{}function gi(e,t){if(e===t)return!0;if(e==null||t==null)return!1;if(typeof e!==typeof t)return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.source===t.source&&e.flags===t.flags;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!gi(e[i],t[i]))return!1;return!0}if(typeof e==="object"){if(Array.isArray(t))return!1;let i=Object.keys(e);if(i.length!==Object.keys(t).length)return!1;for(let s of i){if(!Object.prototype.hasOwnProperty.call(t,s))return!1;if(!gi(e[s],t[s]))return!1}return!0}return!1}function H(e,t){if(typeof t==="function")return t(e);if(t==null)return!0;if(typeof t==="object"&&Object.keys(t).length===0)return!0;if("$or"in t){let i=t.$or;if(!Array.isArray(i))throw new Qe("ERR_SKALEX_QUERY_INVALID_OPERATOR","$or must be an array of filters",{operator:"$or"});if(!i.some((s)=>H(e,s)))return!1}if("$and"in t){let i=t.$and;if(!Array.isArray(i))throw new Qe("ERR_SKALEX_QUERY_INVALID_OPERATOR","$and must be an array of filters",{operator:"$and"});if(!i.every((s)=>H(e,s)))return!1}if("$not"in t){if(H(e,t.$not))return!1}for(let i in t){if(i==="$or"||i==="$and"||i==="$not")continue;let s=t[i],n;try{n=Pt(e,i)}catch{return!1}if(s instanceof RegExp){if(!s.test(String(n)))return!1}else if(typeof s==="object"&&s!==null){if(Object.keys(s).some((r)=>r.startsWith("$"))){if("$eq"in s&&n!==s.$eq)return!1;if("$ne"in s&&n===s.$ne)return!1;if("$gt"in s&&!(n>s.$gt))return!1;if("$lt"in s&&!(n<s.$lt))return!1;if("$gte"in s&&!(n>=s.$gte))return!1;if("$lte"in s&&!(n<=s.$lte))return!1;if("$in"in s&&!s.$in.includes(n))return!1;if("$nin"in s&&s.$nin.includes(n))return!1;if("$regex"in s){if(!(s.$regex instanceof RegExp?s.$regex:new RegExp(s.$regex)).test(String(n)))return!1}if("$fn"in s&&!s.$fn(n))return!1}else if(!gi(n,s))return!1}else if(n!==s)return!1}return!0}function Fo(e,t=new Set){if(typeof e!=="object"||e===null||typeof e==="function")return e;let i=[],s=[],n=[],r=[],a=[];for(let o in e){if(o==="$or"||o==="$and"||o==="$not"){a.push(o);continue}let c=e[o];if(t.has(o))i.push(o);else if(c instanceof RegExp||typeof c==="object"&&c!==null&&(("$regex"in c)||("$fn"in c))||typeof c==="function")r.push(o);else if(typeof c==="object"&&c!==null&&(("$gt"in c)||("$lt"in c)||("$gte"in c)||("$lte"in c)||("$ne"in c)||("$in"in c)||("$nin"in c)))n.push(o);else s.push(o)}let l={};for(let o of[...i,...s,...n,...r,...a])l[o]=e[o];return l}var yi=new Set(["string","number","boolean","object","array","date","any"]);function Ii(e){if(Array.isArray(e))return"array";if(e instanceof Date)return"date";return typeof e}function pn(e){let t=new Map,i=[];for(let[s,n]of Object.entries(e)){let r;if(typeof n==="string"){if(!yi.has(n))throw new N("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${n}" for field "${s}"`,{field:s,type:n});r={type:n,required:!1,unique:!1}}else if(typeof n==="object"&&n!==null){let{type:a="any",required:l=!1,unique:o=!1,enum:c}=n;if(!yi.has(a))throw new N("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${a}" for field "${s}"`,{field:s,type:a});if(r={type:a,required:l,unique:o,enum:c},o)i.push(s)}else throw new N("ERR_SKALEX_VALIDATION_INVALID_SCHEMA",`Invalid schema definition for field "${s}"`,{field:s});t.set(s,r)}return{fields:t,uniqueFields:i}}function gs(e,t,i=!1){let s=[];for(let[n,r]of t){let a=e[n],l=a===void 0||a===null;if(r.required&&l){s.push(`Field "${n}" is required`);continue}if(l)continue;if(r.type!=="any"){let o=Ii(a);if(o!==r.type)s.push(`Field "${n}" must be of type "${r.type}", got "${o}"`)}if(r.enum&&!r.enum.includes(a))s.push(`Field "${n}" must be one of [${r.enum.map((o)=>JSON.stringify(o)).join(", ")}], got ${JSON.stringify(a)}`)}if(i){for(let n of Object.keys(e))if(!n.startsWith("_")&&!t.has(n))s.push(`Unknown field "${n}" (strict mode)`)}return s}function ys(e,t){let i={};for(let[s,n]of Object.entries(e)){if(s.startsWith("_")){i[s]=n;continue}if(!t.has(s))continue;let r=t.get(s);if(r.type!=="any"){if(Ii(n)!==r.type)continue}if(r.enum&&!r.enum.includes(n))continue;i[s]=n}return i}function Uo(e){let t={};for(let[i,s]of Object.entries(e)){if(i.startsWith("_"))continue;let n=Ii(s);t[i]=yi.has(n)?n:"any"}return t}function zo(e){if(typeof e==="number"){if(e<=0)throw new N("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got ${e}`,{ttl:e});return e*1000}if(typeof e!=="string")throw new N("ERR_SKALEX_VALIDATION_TTL",`Invalid TTL value: ${e}`,{ttl:e});let t=e.match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/);if(!t)throw new N("ERR_SKALEX_VALIDATION_TTL_FORMAT",`Invalid TTL format: "${e}". Use e.g. 300 (seconds), "30m", "24h", "7d"`,{ttl:e});let i=parseFloat(t[1]);if(i<=0)throw new N("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got "${e}"`,{ttl:e});let s=t[2],n=i*{ms:1,s:1000,m:60000,h:3600000,d:86400000}[s];if(!isFinite(n))throw new N("ERR_SKALEX_VALIDATION_TTL",`TTL value "${e}" is too large`,{ttl:e});return n}function Bo(e){return new Date(Date.now()+zo(e))}function Xo(e,t,i=null){let s=Date.now(),n=0,r=e.length;while(r--){let a=e[r];if(a._expiresAt&&new Date(a._expiresAt).getTime()<=s){if(e.splice(r,1),t.delete(a._id),i)i(a);n++}}return n}function ws(e,t){if(e.length!==t.length)throw new Qe("ERR_SKALEX_QUERY_VECTOR_MISMATCH",`Vector dimension mismatch: ${e.length} vs ${t.length}`,{expected:e.length,got:t.length});let i=0,s=0,n=0;for(let a=0;a<e.length;a++)i+=e[a]*t[a],s+=e[a]*e[a],n+=t[a]*t[a];let r=Math.sqrt(s*n);return r===0?0:i/r}function U(e){if(!("_vector"in e))return{...e};let{_vector:t,...i}=e;return i}function Ho(e){return e.length}function Vo(e,t){let i=0;for(let s of e){let n=Pt(s,t);if(typeof n==="number"&&!isNaN(n))i+=n}return i}function Jo(e,t){let i=0,s=0;for(let n of e){let r=Pt(n,t);if(typeof r==="number"&&!isNaN(r))i+=r,s++}return s===0?null:i/s}function Yo(e,t){let i=Object.create(null);for(let s of e){let n=String(Pt(s,t)??"__null__");if(!i[n])i[n]=[];i[n].push(s)}return i}class mn{constructor(e){this._col=e}get _ctx(){return this._col._ctx}async execute({op:e,beforeHook:t,afterHook:i,hookPayload:s,mutate:n,afterHookPayload:r,save:a,session:l}){let o=this._ctx;await o.ensureConnected(),this._col._txSnapshotIfNeeded();let c=o.txManager,h=c.active&&this._col._activeTxId===c.context?.id,u=h?c.context.id:null,d=this._col._createdInTxId,_=()=>{if(u!==null&&c._abortedIds.has(u))throw new me("ERR_SKALEX_TX_ABORTED",`Transaction ${u} was aborted. No further mutations allowed.`);if(d!==null&&c._abortedIds.has(d))throw new me("ERR_SKALEX_TX_ABORTED",`Transaction ${d} was aborted. Collection obtained inside that transaction cannot be used for further mutations.`)};if(h||d!==null)_();if(t)await o.plugins.run(t,s);let{docs:f,prevDocs:p=[]}=await n(_);if(o.persistence.markDirty(o.collections,this._col.name),await this._col._saveIfNeeded(a),this._col._changelogEnabled)for(let m=0;m<f.length;m++)await o.logChange(e,this._col.name,f[m],p[m]??null,l||null);if(!h||!c.defer(()=>o.sessionStats.recordWrite(l)))o.sessionStats.recordWrite(l);for(let m of f)o.emitEvent(this._col.name,{op:e,collection:this._col.name,doc:U(m)});if(i)if(r)await o.runAfterHook(i,r(f));else for(let m of f)await o.runAfterHook(i,{collection:this._col.name,doc:U(m)});return{docs:f,prevDocs:p}}}function Wo(e){let t={};for(let i in e){if(i.startsWith("$"))continue;let s=e[i];if(s&&typeof s==="object"&&!Array.isArray(s)){let n=Object.keys(s);if(n.length===1&&n[0]==="$eq")t[i]=s.$eq}else t[i]=s}return t}var gn=new Set(["__proto__","constructor","prototype"]);function yn(e){if(typeof e!=="object"||e===null||Array.isArray(e))return e;let t={};for(let i of Object.keys(e)){if(gn.has(i))continue;t[i]=yn(e[i])}return t}class wn{constructor(e,t){this.name=e.collectionName,this.database=t,this._ctx=t._buildCollectionContext(),this._store=e,this._pipeline=new mn(this),this._createdInTxId=t._txManager.context?.id??null,this._activeTxId=null}get _data(){return this._store.data}set _data(e){this._store.data=e}get _index(){return this._store.index}get _fieldIndex(){return this._store.fieldIndex||null}get _schema(){return this._store.schema?this._store.schema.fields:null}get _changelogEnabled(){return this._store.changelog===!0}get _softDelete(){return this._store.softDelete===!0}get _versioning(){return this._store.versioning===!0}get _strict(){return this._store.strict===!0}get _onSchemaError(){return this._store.onSchemaError??"throw"}get _defaultTtl(){return this._store.defaultTtl||null}get _defaultEmbed(){return this._store.defaultEmbed||null}get _maxDocs(){return this._store.maxDocs||null}async insertOne(e,t={}){let{save:i,ifNotExists:s,ttl:n,embed:r,session:a}=t;if(s){await this._ctx.ensureConnected();let o=this._findRaw(e);if(o)return U({...o})}let{docs:l}=await this._insertCore([e],{ttl:n,embed:r,session:a,save:i});return U(l[0])}async insertMany(e,t={}){let{save:i,ttl:s,embed:n,session:r}=t,{docs:a}=await this._insertCore(e,{ttl:s,embed:n,session:r,save:i});return a.map(U)}async _insertCore(e,{ttl:t,embed:i,session:s,save:n}){return this._pipeline.execute({op:"insert",beforeHook:null,afterHook:"afterInsert",hookPayload:null,save:n,session:s,mutate:async(r)=>{let a=[],l=new Set;for(let o of e){let c=this._applyValidation(o);await this._ctx.plugins.run("beforeInsert",{collection:this.name,doc:c});let h=await this._buildDoc(c,{ttl:t,embed:i});if(this._index.has(h._id)||l.has(h._id))throw new xe("ERR_SKALEX_UNIQUE_DUPLICATE_ID",`Duplicate _id "${h._id}" in collection "${this.name}"`,{id:h._id,collection:this.name});l.add(h._id),a.push(h)}if(r(),this._fieldIndex)this._fieldIndex.assertUniqueBatch(a);for(let o of a)this._addToIndex(o);this._data.push(...a);for(let o of a)this._index.set(o._id,o);return this._enforceCapAfterInsert(),{docs:a}}})}async updateOne(e,t,i={}){await this._ctx.ensureConnected();let s=this._findRaw(e);if(!s)return null;let{save:n,session:r}=i,{docs:a}=await this._updateCore([s],e,t,{save:n,session:r});return U(a[0])}async updateMany(e,t,i={}){await this._ctx.ensureConnected();let s=this._findAllRaw(e);if(s.length===0)return[];let{save:n,session:r}=i,{docs:a}=await this._updateCore(s,e,t,{save:n,session:r});return a.map(U)}async _updateCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"update",beforeHook:"beforeUpdate",afterHook:"afterUpdate",hookPayload:{collection:this.name,filter:t,update:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:t,update:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{let a=this._changelogEnabled?e.map((h)=>structuredClone(h)):e.map(()=>null),l=e.map((h)=>this._prepareUpdatedDoc(h,i));this._assertUniqueCandidates(e,l),r();let o=new Set(e),c=new Map;for(let h=0;h<this._data.length;h++)if(o.has(this._data[h]))c.set(this._data[h],h);for(let h=0;h<e.length;h++)this._commitUpdatedDoc(e[h],l[h],c);return{docs:l,prevDocs:a}}})}applyUpdate(e,t){for(let i in t){if(gn.has(i))continue;if(i==="_id"||i==="createdAt")continue;let s=t[i];if(Array.isArray(s))e[i]=s;else if(typeof s==="object"&&s!==null){let n=Object.keys(s);if(n.some((r)=>r.startsWith("$"))){for(let r of n)if(r==="$inc"&&typeof e[i]==="number")e[i]+=s[r];else if(r==="$push"){if(!Array.isArray(e[i]))e[i]=[];e[i].push(s[r])}}else e[i]=yn(s)}else e[i]=s}if(e.updatedAt=new Date,this._versioning)e._version=(e._version??0)+1;return e}_prepareUpdatedDoc(e,t){let i=structuredClone(e),s=structuredClone(e);if(this.applyUpdate(s,t),!this._schema)return s;let n=gs(s,this._schema,this._strict);if(!n.length)return s;switch(this._onSchemaError){case"throw":throw new N("ERR_SKALEX_VALIDATION_UPDATE",`Update validation failed on doc "${e._id}": ${n.join("; ")}`,{id:e._id,errors:n});case"strip":return this._stripCandidateToValid(s,i);default:return this._ctx.logger(`[${this.name}] Update validation warning: ${n.join("; ")}`,"warn"),s}}_stripCandidateToValid(e,t){let i=ys(e,this._schema),s=structuredClone(t);for(let[n,r]of Object.entries(i)){if(n.startsWith("_"))continue;s[n]=r}if(s.updatedAt=e.updatedAt,this._versioning)s._version=e._version;return s}_commitUpdatedDoc(e,t,i){let s=i?i.get(e):this._data.indexOf(e);if(s===void 0||s===-1)throw new Re("ERR_SKALEX_PERSISTENCE_DOC_MISSING",`Document "${e._id}" no longer exists in collection "${this.name}"`,{id:e._id,collection:this.name});this._data[s]=t,this._index.set(t._id,t),this._updateInIndex(e,t)}_assertUniqueCandidates(e,t){this._fieldIndex?.assertUniqueCandidates(e,t)}async upsert(e,t,i={}){if(await this._ctx.ensureConnected(),this._findRaw(e))return this.updateOne(e,t,i);return this.insertOne({...Wo(e),...t},i)}async upsertMany(e,t,i={}){await this._ctx.ensureConnected();let{save:s,...n}=i,r=[];for(let a of e)r.push(await this.upsert({[t]:a[t]},a,{...n,save:!1}));return await this._saveIfNeeded(s),r}async restore(e,t={}){if(!this._softDelete)throw new Qe("ERR_SKALEX_QUERY_SOFT_DELETE_REQUIRED",`restore() requires softDelete on "${this.name}"`,{collection:this.name});await this._ctx.ensureConnected();let{save:i,session:s}=t,n=this._findRaw(e,{includeDeleted:!0});if(!n||!n._deletedAt)return null;let{docs:r}=await this._pipeline.execute({op:"restore",beforeHook:null,afterHook:null,hookPayload:null,save:i,session:s,mutate:async(a)=>{return a(),delete n._deletedAt,n.updatedAt=new Date,this._index.set(n._id,n),{docs:[n]}}});return U(r[0])}watch(e,t){if(typeof e==="function")t=e,e=null;if(t)return this._ctx.eventBus.on(this.name,(i)=>{if(!e||H(i.doc,e))t(i)});return this._watchIterator(e)}_watchIterator(e){let t=[],i=null,s=!1,n=this._ctx.eventBus.on(this.name,(r)=>{if(e&&!H(r.doc,e))return;if(i){let a=i;i=null,a({value:r,done:!1})}else t.push(r)});return{[Symbol.asyncIterator](){return this},next(){if(t.length>0)return Promise.resolve({value:t.shift(),done:!1});if(s)return Promise.resolve({value:void 0,done:!0});return new Promise((r)=>{i=r})},return(){if(s=!0,n(),i){let r=i;i=null,r({value:void 0,done:!0})}return Promise.resolve({value:void 0,done:!0})}}}async count(e={}){return await this._ctx.ensureConnected(),Ho(this._findAllRaw(e))}async sum(e,t={}){return await this._ctx.ensureConnected(),Vo(this._findAllRaw(t),e)}async avg(e,t={}){return await this._ctx.ensureConnected(),Jo(this._findAllRaw(t),e)}async groupBy(e,t={}){return await this._ctx.ensureConnected(),Yo(this._findAllRaw(t),e)}async findOne(e,t={}){await this._ctx.ensureConnected();let{populate:i,select:s,includeDeleted:n=!1}=t,r=this._findRaw(e,{includeDeleted:n});if(!r)return null;let a=this._projectDoc(r,s);if(i)await this._populateDoc(a,r,i);return a}async find(e,t={}){await this._ctx.ensureConnected();let i=Date.now(),{populate:s,select:n,sort:r,page:a=1,limit:l,session:o,includeDeleted:c=!1}=t;await this._ctx.plugins.run("beforeFind",{collection:this.name,filter:e,options:t});let h=this._getCandidates(e),u=Fo(e,this._fieldIndex?this._fieldIndex.indexedFields:new Set),d=[];for(let f of h){if(this._softDelete&&f._deletedAt&&!c)continue;if(!H(f,u))continue;let p=this._projectDoc(f,n);if(s)await this._populateDoc(p,f,s);d.push(p)}if(r){let f=Object.keys(r);d.sort((p,m)=>{for(let w of f){let x=r[w];if(p[w]<m[w])return-x;if(p[w]>m[w])return x}return 0})}let _;if(l){let f=d.length,p=Math.ceil(f/l),m=(a-1)*l;d=d.slice(m,m+l),_={page:a,totalDocs:f,totalPages:p}}return this._ctx.queryLog?.record({collection:this.name,op:"find",filter:e,duration:Date.now()-i,resultCount:d.length}),this._ctx.sessionStats.recordRead(o),await this._ctx.plugins.run("afterFind",{collection:this.name,filter:e,options:t,docs:d}),_?{docs:d,..._}:{docs:d}}async search(e,{filter:t,limit:i=10,minScore:s=0,session:n}={}){await this._ctx.ensureConnected();let r=Date.now();await this._ctx.plugins.run("beforeSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s}});let a=await this._ctx.embed(e),l=t?this._findAllRaw(t):this._data,o=[];for(let d of l){if(!d._vector)continue;let _=ws(a,d._vector);if(_>=s)o.push({doc:d,score:_})}o.sort((d,_)=>_.score-d.score);let c=o.slice(0,i);this._ctx.queryLog?.record({collection:this.name,op:"search",query:e,duration:Date.now()-r,resultCount:c.length}),this._ctx.sessionStats.recordRead(n);let h=c.map((d)=>U(d.doc)),u=c.map((d)=>d.score);return await this._ctx.plugins.run("afterSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s},docs:h,scores:u}),{docs:h,scores:u}}async similar(e,{limit:t=10,minScore:i=0}={}){await this._ctx.ensureConnected();let s=this._index.get(e);if(!s||!s._vector)return{docs:[],scores:[]};let n=[];for(let a of this._data){if(a._id===e||!a._vector)continue;let l=ws(s._vector,a._vector);if(l>=i)n.push({doc:a,score:l})}n.sort((a,l)=>l.score-a.score);let r=n.slice(0,t);return{docs:r.map((a)=>U(a.doc)),scores:r.map((a)=>a.score)}}async deleteOne(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findRaw(e);if(!r)return null;let{docs:a}=await this._deleteCore("soft",[r],e,{save:i,session:s});return U(a[0])}let{docs:n}=await this._deleteCore("hard",null,e,{save:i,session:s});if(n.length===0)return null;return U(n[0])}async deleteMany(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findAllRaw(e);if(r.length===0)return[];let{docs:a}=await this._deleteCore("soft",r,e,{save:i,session:s});return a.map(U)}let{docs:n}=await this._deleteCore("hardMany",null,e,{save:i,session:s});return n.map(U)}async _deleteCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"delete",beforeHook:"beforeDelete",afterHook:"afterDelete",hookPayload:{collection:this.name,filter:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{if(r(),e==="soft"){let o=new Date;for(let c of t)c._deletedAt=o,c.updatedAt=o,this._index.set(c._id,c);return{docs:t}}if(e==="hard"){let o=this._findIndex(i);if(o===-1)return{docs:[]};let c=this._data.splice(o,1)[0];return this._index.delete(c._id),this._removeFromIndex(c),{docs:[c]}}let a=[],l=[];for(let o of this._data)if(H(o,i))a.push(o),this._index.delete(o._id),this._removeFromIndex(o);else l.push(o);return this._data=l,{docs:a}}})}async export(e={},t={}){let{dir:i,name:s,format:n="json"}=t;try{let r=this._data.filter((h)=>H(h,e));if(r.length===0)throw new Qe("ERR_SKALEX_QUERY_EXPORT_EMPTY",`export(): no documents matched the filter in "${this.name}"`,{collection:this.name});let a;if(n==="json")a=JSON.stringify(r,null,2);else{let h=(_)=>{if(_==null)return"";let f=typeof _==="object"?JSON.stringify(_):String(_);return f.includes(",")||f.includes('"')||f.includes(`
14
14
  `)||f.includes("\r")?`"${f.replace(/"/g,'""')}"`:f},u=Object.keys(r[0]).map(h).join(","),d=r.map((_)=>Object.values(_).map(h).join(","));a=[u,...d].join(`
15
- `)}if(typeof this._ctx.fs.writeRaw!=="function")throw new ue("ERR_SKALEX_ADAPTER_NO_RAW_WRITE","export() requires a file-system adapter (FsAdapter). The current adapter does not support raw file writes.");let l=i||`${this._ctx.dataDirectory}/exports`,o=`${s||this.name}.${n}`,c=this._ctx.fs.join(l,o);this._ctx.fs.ensureDir(l),await this._ctx.fs.writeRaw(c,a)}catch(r){throw this._ctx.logger(`Error exporting "${this.name}": ${r.message}`,"error"),r}}_txSnapshotIfNeeded(){let e=this._ctx.txManager;if(!e.active)return;if(this._activeTxId!==e.context?.id)return;e.snapshotIfNeeded(this.name,this._store,(t)=>this._ctx.snapshotCollection(t))}async _saveIfNeeded(e){let t=this._ctx.txManager;if(t.active&&this._activeTxId===t.context?.id)return;if(e??this._ctx.autoSave)await this._ctx.saveCollection(this.name)}_applyValidation(e){if(!this._schema)return e;let t=gs(e,this._schema,this._strict);if(!t.length)return e;switch(this._onSchemaError){case"warn":return this._ctx.logger(`[${this.name}] Validation warning: ${t.join("; ")}`,"warn"),e;case"strip":return ys(e,this._schema);default:throw new N("ERR_SKALEX_VALIDATION_FAILED",`Validation failed: ${t.join("; ")}`,{errors:t})}}_enforceCapAfterInsert(){let e=this._maxDocs;if(!e||this._data.length<=e)return;let t=this._data.splice(0,this._data.length-e);for(let i of t)this._index.delete(i._id),this._removeFromIndex(i)}_findRaw(e,{includeDeleted:t=!1}={}){if(typeof e==="function"){for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(e(i))return i}return null}if(e._id){let i=this._index.get(e._id)||null;if(!i)return null;if(this._softDelete&&i._deletedAt&&!t)return null;if(Object.keys(e).length>1)return H(i,e)?i:null;return i}if(this._fieldIndex)for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null){let n=this._fieldIndex._lookupIterable(i,s);if(n!==null){for(let r of n){if(this._softDelete&&r._deletedAt&&!t)continue;if(H(r,e))return r}return null}}}for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(H(i,e))return i}return null}_findAllRaw(e,{includeDeleted:t=!1}={}){if(e&&typeof e!=="function"&&e._id){let s=this._index.get(e._id);if(!s)return[];if(this._softDelete&&s._deletedAt&&!t)return[];return H(s,e)?[s]:[]}let i=[];for(let s of this._getCandidates(e)){if(this._softDelete&&s._deletedAt&&!t)continue;if(H(s,e))i.push(s)}return i}_getCandidates(e){if(!this._fieldIndex)return this._data;if(this._fieldIndex._compoundIndexes.size>0){let t={};for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null)t[i]=s}if(Object.keys(t).length>=2){let i=this._fieldIndex.lookupCompound(t);if(i!==null)return i}}for(let t in e){if(t==="$or"||t==="$and"||t==="$not")continue;let i=e[t];if(typeof i!=="object"||i===null){let s=this._fieldIndex._lookupIterable(t,i);if(s!==null)return s}}return this._data}_findIndex(e){for(let t=0;t<this._data.length;t++)if(H(this._data[t],e))return t;return-1}_addToIndex(e){if(this._fieldIndex)this._fieldIndex.add(e)}_removeFromIndex(e){if(this._fieldIndex)this._fieldIndex.remove(e)}_updateInIndex(e,t){if(this._fieldIndex)this._fieldIndex.update(e,t)}async _buildDoc(e,{ttl:t,embed:i}={}){let s={...e,_id:e._id??(this._ctx.idGenerator??jo)(),createdAt:new Date,updatedAt:new Date},n=t??this._defaultTtl;if(n)s._expiresAt=Uo(n);let r=i??this._defaultEmbed;if(r){let a=typeof r==="function"?r(s):s[r];s._vector=await this._ctx.embed(String(a))}if(this._versioning)s._version=1;return s}_projectDoc(e,t){if(t){let s={};for(let n of t){if(n==="_vector")continue;s[n]=e[n]}return s}let i={...e};return delete i._vector,i}async _populateDoc(e,t,i){for(let s of i){let n=await this._ctx.getCollection(s).findOne({_id:t[s]});if(n)e[s]=n}}}class bi{async read(e){throw Error("StorageAdapter.read() not implemented")}async write(e,t){throw Error("StorageAdapter.write() not implemented")}async delete(e){throw Error("StorageAdapter.delete() not implemented")}async list(){throw Error("StorageAdapter.list() not implemented")}async writeAll(e){for(let{name:t,data:i}of e)await this.write(t,i)}}class An extends bi{constructor({dir:e,format:t="gz"}){super();this.dir=ze.resolve(e),this.format=t,this._ensureDir(this.dir)}_ensureDir(e){if(!j.existsSync(e))j.mkdirSync(e,{recursive:!0})}_filePath(e){return ze.join(this.dir,`${e}.${this.format}`)}async read(e){let t=this._filePath(e);try{let i=await j.promises.readFile(t);if(this.format==="gz")i=ri.inflateSync(i);return i.toString("utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async write(e,t){let i=this._filePath(e),s=ze.join(this.dir,`${e}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let n=ri.deflateSync(t);await j.promises.writeFile(s,n)}else await j.promises.writeFile(s,t,"utf8");await j.promises.rename(s,i)}async writeAll(e){let t=[];try{for(let{name:i,data:s}of e){let n=this._filePath(i),r=ze.join(this.dir,`${i}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let a=ri.deflateSync(s);await j.promises.writeFile(r,a)}else await j.promises.writeFile(r,s,"utf8");t.push({tmp:r,fp:n})}for(let{tmp:i,fp:s}of t)await j.promises.rename(i,s)}catch(i){for(let{tmp:s}of t)try{await j.promises.unlink(s)}catch{}throw i}}async delete(e){let t=this._filePath(e);try{await j.promises.unlink(t)}catch(i){if(i.code!=="ENOENT")throw i}}async list(){try{let e=await j.promises.readdir(this.dir),t=`.${this.format}`;return e.filter((i)=>i.endsWith(t)&&!i.includes(".tmp.")).map((i)=>i.slice(0,-t.length))}catch(e){if(e.code==="ENOENT")return[];throw e}}join(...e){return ze.join(...e)}ensureDir(e){this._ensureDir(e)}async writeRaw(e,t){this._ensureDir(ze.dirname(e)),await j.promises.writeFile(e,t,"utf8")}async readRaw(e){return j.promises.readFile(ze.resolve(e),"utf8")}}class xn{constructor(){this._migrations=[]}add(e){let{version:t,up:i}=e;if(typeof t!=="number"||t<1)throw new N("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version must be a positive integer, got ${t}`,{version:t});if(typeof i!=="function")throw new N("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version ${t} must have an "up" function`,{version:t});if(this._migrations.some((s)=>s.version===t))throw new N("ERR_SKALEX_VALIDATION_MIGRATION_DUPLICATE",`Migration version ${t} is already registered`,{version:t});this._migrations.push({...e}),this._migrations.sort((s,n)=>s.version-n.version)}async run(e,t=[]){let i=new Set(t),s=this._migrations.filter((n)=>!i.has(n.version));for(let n of s){let r=e(n.version);await n.up(r),i.add(n.version)}return[...i].sort((n,r)=>n-r)}status(e=[]){let t=new Set(e),i=this._migrations.map((s)=>s.version).filter((s)=>!t.has(s));return{current:e.length?Math.max(...e):0,applied:[...t].sort((s,n)=>s-n),pending:i}}}var As={[Symbol.iterator](){return{next(){return{done:!0}}}},size:0};function xs(e){return{[Symbol.iterator](){return e[Symbol.iterator]()},get size(){return e.size}}}function ci(e){return e.map((t)=>{if(t===null||t===void 0)return"\x00";if(typeof t==="boolean")return t?"\x01T":"\x01F";if(typeof t==="number")return`\x02${t}`;return`\x03${String(t)}`}).join("\x1F")}class Ct{constructor(e=[],t=[]){this._fields=new Set,this._compoundFields=[];for(let i of e)if(Array.isArray(i)){for(let s of i)this._validateFieldName(s);this._compoundFields.push(i)}else this._validateFieldName(i),this._fields.add(i);for(let i of t)this._validateFieldName(i);this._uniqueFields=new Set(t),this._indexedFields=new Set([...this._fields,...this._uniqueFields]),this._fieldIndexes=new Map,this._uniqueIndexes=new Map;for(let i of this._fields)this._fieldIndexes.set(i,new Map);for(let i of this._uniqueFields)if(this._uniqueIndexes.set(i,new Map),!this._fieldIndexes.has(i))this._fieldIndexes.set(i,new Map);this._compoundIndexes=new Map;for(let i of this._compoundFields)this._compoundIndexes.set(i.join("\x00"),{fields:i,map:new Map})}get indexedFields(){return this._indexedFields}buildFromData(e){for(let[,t]of this._fieldIndexes)t.clear();for(let[,t]of this._uniqueIndexes)t.clear();for(let[,t]of this._compoundIndexes)t.map.clear();for(let t of e)this._indexDoc(t)}add(e){this._checkUnique(e,null),this._indexDoc(e)}remove(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){let n=i.get(s);if(n){if(n.delete(e),n.size===0)i.delete(s)}}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.delete(s)}for(let[,t]of this._compoundIndexes){let i=ci(t.fields.map((n)=>e[n])),s=t.map.get(i);if(s){if(s.delete(e),s.size===0)t.map.delete(i)}}}update(e,t){this._checkUnique(t,e),this.remove(e);try{this._indexDoc(t)}catch(i){try{this._indexDoc(e)}catch{}throw i}}lookup(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?[...s]:[]}_lookupIterable(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?xs(s):As}lookupCompound(e){let t=Object.keys(e).sort();for(let[,i]of this._compoundIndexes){let s=[...i.fields].sort();if(s.length!==t.length)continue;if(s.every((n,r)=>n===t[r])){let n=ci(i.fields.map((a)=>e[a])),r=i.map.get(n);return r?xs(r):As}}return null}isUniqueTaken(e,t){let i=this._uniqueIndexes.get(e);if(!i)return!1;return i.has(t)}assertUniqueCandidates(e,t){if(this._uniqueFields.size===0)return;let i=new Set(e.map((s)=>s._id));for(let s of this._uniqueFields){let n=new Set,r=this._uniqueIndexes.get(s);if(r){for(let[l,o]of r.entries())if(!i.has(o._id))n.add(l)}let a=new Map;for(let l=0;l<t.length;l++){let o=t[l][s];if(o===void 0)continue;if(n.has(o))throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});let c=a.get(o);if(c&&c!==e[l]._id)throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});a.set(o,e[l]._id)}}}assertUniqueBatch(e){if(this._uniqueFields.size===0)return;for(let t of this._uniqueFields){let i=this._uniqueIndexes.get(t),s=new Set;for(let n of e){let r=n[t];if(r===void 0)continue;if(i&&i.has(r))throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${t}" value "${r}" already exists`,{field:t,value:r});if(s.has(r))throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: duplicate "${t}" value "${r}" within batch`,{field:t,value:r});s.add(r)}}}_validateFieldName(e){if(e.includes("."))throw new N("ERR_SKALEX_VALIDATION_INDEX_DOT_PATH",`Index fields cannot use dot-notation: "${e}". Use a flat field name.`,{field:e})}_indexDoc(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){if(!i.has(s))i.set(s,new Set);i.get(s).add(e)}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.set(s,e)}for(let[,t]of this._compoundIndexes){for(let s of t.fields){let n=e[s];if(n!==void 0&&n!==null&&typeof n==="object")throw new N("ERR_SKALEX_VALIDATION_COMPOUND_INDEX",`Compound index field "${s}" must be a scalar value (string, number, or boolean), got ${Array.isArray(n)?"array":typeof n}`,{field:s})}let i=ci(t.fields.map((s)=>e[s]));if(!t.map.has(i))t.map.set(i,new Set);t.map.get(i).add(e)}}_checkUnique(e,t){for(let i of this._uniqueFields){let s=e[i];if(s===void 0)continue;let n=this._uniqueIndexes.get(i);if(!n)continue;let r=n.get(s);if(r&&r._id!==t?._id)throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${i}" value "${s}" already exists`,{field:i,value:s})}}}var At="_flush",xt="migrations";class vn{constructor({adapter:e,serializer:t,deserializer:i,logger:s,debug:n=!1,lenientLoad:r=!1}){this._adapter=e,this._serializer=t,this._deserializer=i,this._logger=s,this._debug=n,this._lenientLoad=r,this._saveLock=Promise.resolve()}_withSaveLock(e){let t=this._saveLock.then(e);return this._saveLock=t.catch(()=>{}),t}async loadAll(e,{parseSchema:t,buildIndex:i,IndexEngine:s}){try{let n=await this._adapter.list();await Promise.all(n.map(async(r)=>{try{let a=await this._adapter.read(r);if(!a)return;let l=this._deserializer(a),{collectionName:o,data:c}=l;if(!o)return;let h=e[o],u=h?.rawSchema??l.rawSchema??null,d=h?.schema??(u?t(u):null),_=h?.changelog??l.changelog??!1,f=h?.softDelete??l.softDelete??!1,p=h?.versioning??l.versioning??!1,m=h?.strict??l.strict??!1,w=h?.onSchemaError??l.onSchemaError??"throw",x=h?.defaultTtl??l.defaultTtl??null,R=h?.defaultEmbed??l.defaultEmbed??null,E=h?.maxDocs??l.maxDocs??null,A=h?h.fieldIndex:null;if(!A&&d?.uniqueFields?.length)A=new s([],d.uniqueFields);let Ue=i(c,"_id");if(A)A.buildFromData(c);e[o]={collectionName:o,data:c,index:Ue,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:d,rawSchema:u,fieldIndex:A,changelog:_,softDelete:f,versioning:p,strict:m,onSchemaError:w,defaultTtl:x,defaultEmbed:R,maxDocs:E}}catch(a){if(a.code==="ENOENT")return;if(this._lenientLoad){this._logger(`WARNING: Could not load collection "${r}": ${a.message}. Collection will be empty.`,"error");return}throw new Re("ERR_SKALEX_PERSISTENCE_CORRUPT",`Failed to load collection "${r}": ${a.message}`,{collection:r})}})),this._detectIncompleteFlush(e),await this._cleanOrphanTempFiles()}catch(n){if(n.code!=="ENOENT")throw this._logger(`Error loading data: ${n}`,"error"),n}}async save(e,t){if(t)await this._saveOne(e,t);else await Promise.all(Object.keys(e).map((i)=>this._saveOne(e,i)))}async saveDirty(e){let t=Object.keys(e).filter((i)=>e[i]._dirty);if(t.length===0)return;await Promise.all(t.map((i)=>this._saveOne(e,i)))}saveAtomic(e,t){return this._withSaveLock(async()=>{if(t.length===0)return;this._writeFlushSentinel(e,t);let i=new Set(t);i.add("_meta");let s=[...i].filter((n)=>e[n]).map((n)=>({name:n,data:this._serializeCollection(e[n])}));try{await this._adapter.writeAll(s)}catch(n){throw new Re("ERR_SKALEX_PERSISTENCE_FLUSH_FAILED",`Batch save failed during writeAll: ${n.message}`,{collections:t})}for(let n of t)if(e[n])e[n]._dirty=!1;try{this._clearFlushSentinel(e),await this._adapter.write("_meta",this._serializeCollection(e._meta))}catch(n){this._logger(`WARNING: Batch data committed but sentinel clear failed: ${n.message}. Next load will report an incomplete flush (false positive).`,"error")}})}markDirty(e,t){let i=e[t];if(i)i._dirty=!0}_serializeCollection(e){let t={collectionName:e.collectionName,data:e.data};if(e.rawSchema)t.rawSchema=e.rawSchema;if(e.changelog)t.changelog=e.changelog;if(e.softDelete)t.softDelete=e.softDelete;if(e.versioning)t.versioning=e.versioning;if(e.strict)t.strict=e.strict;if(e.onSchemaError!=="throw")t.onSchemaError=e.onSchemaError;if(e.defaultTtl)t.defaultTtl=e.defaultTtl;if(e.defaultEmbed)t.defaultEmbed=e.defaultEmbed;if(e.maxDocs)t.maxDocs=e.maxDocs;return this._serializer(t)}async _saveOne(e,t){let i=e[t];if(!i)return;if(i.isSaving)return i._pendingSave=!0,new Promise((s,n)=>{(i._saveWaiters??=[]).push({resolve:s,reject:n})});i.isSaving=!0,i._pendingSave=!1;try{await this._writeCollection(t,i);while(i._pendingSave)i._pendingSave=!1,await this._writeCollection(t,i);this._resolveSaveWaiters(i)}catch(s){throw this._rejectSaveWaiters(i,s),s}finally{i.isSaving=!1}}async _writeCollection(e,t){try{await this._adapter.write(e,this._serializeCollection(t)),t._dirty=!1}catch(i){throw this._logger(`Error saving "${e}": ${i.message}`,"error"),i}}_resolveSaveWaiters(e){let t=e._saveWaiters?.splice(0)??[];for(let i of t)i.resolve()}_rejectSaveWaiters(e,t){let i=e._saveWaiters?.splice(0)??[];for(let s of i)s.reject(t)}_writeFlushSentinel(e,t){let i=this._getOrCreateMeta(e);i[At]={startedAt:new Date().toISOString(),collections:t,completedAt:null}}_clearFlushSentinel(e){let t=this._getOrCreateMeta(e);if(t[At])t[At].completedAt=new Date().toISOString()}_detectIncompleteFlush(e){let t=e._meta;if(!t)return;let i=t.index.get(xt);if(!i)return;let s=i[At];if(!s)return;if(s.startedAt&&!s.completedAt)this._logger(`WARNING: Incomplete flush detected (started ${s.startedAt}, collections: ${s.collections?.join(", ")}). Data may be inconsistent.`,"error")}async _cleanOrphanTempFiles(){if(typeof this._adapter.join!=="function")return;if(typeof this._adapter.list!=="function")return;try{let e=await import("fs"),t=await import("path"),i=this._adapter.dir;if(!i)return;let s=(await e.default.promises.readdir(i)).filter((n)=>n.includes(".tmp."));for(let n of s){let r=t.default.join(i,n);try{await e.default.promises.unlink(r),this._log(`Cleaned orphan temp file: ${n}`)}catch{}}}catch{}}_getOrCreateMeta(e){if(!e._meta)e._meta={collectionName:"_meta",data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:null,rawSchema:null,fieldIndex:null,changelog:!1,softDelete:!1,versioning:!1,strict:!1,onSchemaError:"throw",defaultTtl:null,defaultEmbed:null,maxDocs:null};let t=e._meta,i=t.index.get(xt);if(!i)i={_id:xt},t.data.push(i),t.index.set(xt,i);return i}_log(e){if(this._debug)this._logger(e,"info")}}var Yo=0;class En{constructor(){this._txLock=Promise.resolve(),this._ctx=null,this._abortedIds=new Set}get active(){return this._ctx!==null&&!this._ctx.aborted}get context(){return this._ctx}async run(e,t,{timeout:i=0}={}){let s=async()=>{await t._ensureConnected();let r=new Set(Object.keys(t.collections)),a={id:++Yo,startedAt:Date.now(),aborted:!1,preExisting:r,touchedCollections:new Set,snapshots:new Map,deferredEffects:[],timeout:i};this._ctx=a;let l=null,o=i>0?new Promise((u,d)=>{l=setTimeout(()=>{a.aborted=!0,d(new me("ERR_SKALEX_TX_TIMEOUT",`Transaction ${a.id} timed out after ${i}ms`))},i)}):null,c=this,h=new Proxy(t,{get(u,d){if(d==="_txId")return a.id;if(a!==c._ctx)throw new me("ERR_SKALEX_TX_STALE_PROXY",`Transaction ${a.id} has ended. This proxy is no longer usable.`);if(d==="collections")throw new me("ERR_SKALEX_TX_DIRECT_ACCESS","Direct access to db.collections inside transaction() is not covered by rollback. Use the collection API (db.useCollection) instead.");if(d==="useCollection")return(f)=>{let p=u.useCollection(f);return p._activeTxId=a.id,p};let _=Reflect.get(u,d);return typeof _==="function"?_.bind(u):_}});try{let u=e(h),d=o?await Promise.race([u,o]):await u;if(a.aborted)throw new me("ERR_SKALEX_TX_ABORTED",`Transaction ${a.id} was aborted`);let _=[...a.touchedCollections];if(_.length>0)await t._persistence.saveAtomic(t.collections,_);for(let f of a.deferredEffects)await f();return d}catch(u){for(let[d,_]of a.snapshots)if(a.preExisting.has(d)){if(t._applySnapshot(d,_),t.collections[d])t.collections[d]._dirty=_._dirty}for(let d in t.collections)if(!a.preExisting.has(d))delete t.collections[d],delete t._collectionInstances[d];throw u}finally{if(l)clearTimeout(l);if(a.aborted)this._abortedIds.add(a.id);this._ctx=null;for(let u in t._collectionInstances){let d=t._collectionInstances[u];if(d._createdInTxId===a.id)d._createdInTxId=null;if(d._activeTxId===a.id)d._activeTxId=null}}},n=this._txLock.then(s);return this._txLock=n.catch(()=>{}),n}snapshotIfNeeded(e,t,i){let s=this._ctx;if(!s)return;if(this._assertCtxNotAborted(s),!s.snapshots.has(e)){let n=i(t);n._dirty=t._dirty??!1,s.snapshots.set(e,n)}s.touchedCollections.add(e)}assertNotAborted(){let e=this._ctx;if(e)this._assertCtxNotAborted(e)}_assertCtxNotAborted(e){if(e.aborted)throw new me("ERR_SKALEX_TX_ABORTED",`Transaction ${e.id} was aborted. No further mutations allowed.`)}defer(e){if(this._ctx)return this._ctx.deferredEffects.push(e),!0;return!1}}class Sn{constructor(e){this._CollectionClass=e,this.stores={},this._instances={}}get(e,t){if(this._instances[e])return this._instances[e];if(!this.stores[e])this.createStore(e);let i=new this._CollectionClass(this.stores[e],t);return this._instances[e]=i,i}create(e,t={},i){this.createStore(e,t);let s=new this._CollectionClass(this.stores[e],i);return this._instances[e]=s,s}createStore(e,{schema:t,indexes:i=[],changelog:s=!1,softDelete:n=!1,versioning:r=!1,strict:a=!1,onSchemaError:l="throw",defaultTtl:o=null,defaultEmbed:c=null,maxDocs:h=null}={}){let u=null,d=null;if(t){u=pn(t);let _=u.uniqueFields;if(i.length||_.length)d=new Ct(i,_)}else if(i.length)d=new Ct(i,[]);this.stores[e]={collectionName:e,data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:u,rawSchema:t||null,fieldIndex:d,changelog:s,softDelete:n,versioning:r,strict:a,onSchemaError:l,defaultTtl:o,defaultEmbed:c,maxDocs:h}}rename(e,t){if(!this.stores[e])throw new Re("ERR_SKALEX_PERSISTENCE_COLLECTION_NOT_FOUND",`Collection "${e}" not found`,{collection:e});if(this.stores[t])throw new Re("ERR_SKALEX_PERSISTENCE_COLLECTION_EXISTS",`Collection "${t}" already exists`,{collection:t});let i=this.stores[e];if(i.collectionName=t,this.stores[t]=i,delete this.stores[e],this._instances[e]){let s=this._instances[e];s.name=t,this._instances[t]=s,delete this._instances[e]}}buildIndex(e,t){let i=new Map;for(let s of e)i.set(s[t],s);return i}inspect(e){if(e){let i=this.stores[e];if(!i)return null;return{name:e,count:i.data.length,schema:i.schema?Object.fromEntries(i.schema.fields):null,indexes:i.fieldIndex?[...i.fieldIndex.indexedFields]:[],softDelete:i.softDelete??!1,versioning:i.versioning??!1,strict:i.strict??!1,onSchemaError:i.onSchemaError??"throw",maxDocs:i.maxDocs??null}}let t={};for(let i in this.stores)t[i]=this.inspect(i);return t}dump(){let e={};for(let t in this.stores)if(!t.startsWith("_"))e[t]=structuredClone(this.stores[t].data);return e}schema(e){let t=this.stores[e];if(!t)return null;if(t.schema)return Object.fromEntries([...t.schema.fields.entries()].map(([i,s])=>[i,s.type]));if(t.data.length>0)return Ko(t.data[0]);return null}stats(e){let t=(i)=>{let s=this.stores[i];if(!s)return null;let n=s.data.length,r=0;for(let a of s.data)try{r+=JSON.stringify(a).length}catch(l){}return{collection:i,count:n,estimatedSize:r,avgDocSize:n>0?Math.round(r/n):0}};if(e)return t(e);return Object.keys(this.stores).map(t)}clear(){this.stores={},this._instances={}}}class Ti{async embed(e){throw Error("EmbeddingAdapter.embed() not implemented")}}var le=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class In extends Ti{constructor({apiKey:e=le("OPENAI_API_KEY"),model:t=le("OPENAI_EMBED_MODEL")??"text-embedding-3-small",baseUrl:i=le("OPENAI_EMBED_BASE_URL")??"https://api.openai.com/v1/embeddings",dimensions:s=le("OPENAI_EMBED_DIMENSIONS")!=null?Number(le("OPENAI_EMBED_DIMENSIONS")):void 0,organization:n=le("OPENAI_ORGANIZATION")??void 0,timeout:r=le("OPENAI_EMBED_TIMEOUT")!=null?Number(le("OPENAI_EMBED_TIMEOUT")):void 0,retries:a=Number(le("OPENAI_EMBED_RETRIES")??0),retryDelay:l=Number(le("OPENAI_EMBED_RETRY_DELAY")??1000),headers:o={},fetch:c=globalThis.fetch}={}){super();if(!e)throw Error("OpenAIEmbeddingAdapter requires an apiKey");this.apiKey=e,this.model=t,this.baseUrl=i,this.dimensions=s,this.organization=n,this.timeout=r,this.retries=a,this.retryDelay=l,this.headers=o,this._fetch=c}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(this.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...this.organization&&{"OpenAI-Organization":this.organization},...this.headers},body:JSON.stringify({input:e,model:this.model,...this.dimensions!==void 0&&{dimensions:this.dimensions}}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`OpenAI embedding API error ${r.status}: ${a}`)}return(await r.json()).data[0].embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}var tt=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class bn extends Ti{constructor({model:e=tt("OLLAMA_EMBED_MODEL")??"nomic-embed-text",host:t=tt("OLLAMA_HOST")??"http://localhost:11434",timeout:i=tt("OLLAMA_EMBED_TIMEOUT")!=null?Number(tt("OLLAMA_EMBED_TIMEOUT")):void 0,retries:s=Number(tt("OLLAMA_EMBED_RETRIES")??0),retryDelay:n=Number(tt("OLLAMA_EMBED_RETRY_DELAY")??1000),headers:r={},fetch:a=globalThis.fetch}={}){super();this.model=e,this.host=t,this.timeout=i,this.retries=s,this.retryDelay=n,this.headers=r,this._fetch=a}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({model:this.model,prompt:e}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama embedding API error ${r.status}: ${a}`)}return(await r.json()).embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}class Mt{async generate(e,t){throw Error("LLMAdapter.generate() not implemented")}async summarize(e){throw Error("LLMAdapter.summarize() not implemented")}}var Oi=`You are a database query assistant. Convert the user's natural language request into a JSON filter object for a document database.
15
+ `)}if(typeof this._ctx.fs.writeRaw!=="function")throw new ue("ERR_SKALEX_ADAPTER_NO_RAW_WRITE","export() requires a file-system adapter (FsAdapter). The current adapter does not support raw file writes.");let l=i||`${this._ctx.dataDirectory}/exports`,o=`${s||this.name}.${n}`,c=this._ctx.fs.join(l,o);this._ctx.fs.ensureDir(l),await this._ctx.fs.writeRaw(c,a)}catch(r){throw this._ctx.logger(`Error exporting "${this.name}": ${r.message}`,"error"),r}}_txSnapshotIfNeeded(){let e=this._ctx.txManager;if(!e.active)return;if(this._activeTxId!==e.context?.id)return;e.snapshotIfNeeded(this.name,this._store,(t)=>this._ctx.snapshotCollection(t))}async _saveIfNeeded(e){let t=this._ctx.txManager;if(t.active&&this._activeTxId===t.context?.id)return;if(e??this._ctx.autoSave)await this._ctx.saveCollection(this.name)}_applyValidation(e){if(!this._schema)return e;let t=gs(e,this._schema,this._strict);if(!t.length)return e;switch(this._onSchemaError){case"warn":return this._ctx.logger(`[${this.name}] Validation warning: ${t.join("; ")}`,"warn"),e;case"strip":return ys(e,this._schema);default:throw new N("ERR_SKALEX_VALIDATION_FAILED",`Validation failed: ${t.join("; ")}`,{errors:t})}}_enforceCapAfterInsert(){let e=this._maxDocs;if(!e||this._data.length<=e)return;let t=this._data.splice(0,this._data.length-e);for(let i of t)this._index.delete(i._id),this._removeFromIndex(i)}_findRaw(e,{includeDeleted:t=!1}={}){if(typeof e==="function"){for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(e(i))return i}return null}if(e._id){let i=this._index.get(e._id)||null;if(!i)return null;if(this._softDelete&&i._deletedAt&&!t)return null;if(Object.keys(e).length>1)return H(i,e)?i:null;return i}if(this._fieldIndex)for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null){let n=this._fieldIndex._lookupIterable(i,s);if(n!==null){for(let r of n){if(this._softDelete&&r._deletedAt&&!t)continue;if(H(r,e))return r}return null}}}for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(H(i,e))return i}return null}_findAllRaw(e,{includeDeleted:t=!1}={}){if(e&&typeof e!=="function"&&e._id){let s=this._index.get(e._id);if(!s)return[];if(this._softDelete&&s._deletedAt&&!t)return[];return H(s,e)?[s]:[]}let i=[];for(let s of this._getCandidates(e)){if(this._softDelete&&s._deletedAt&&!t)continue;if(H(s,e))i.push(s)}return i}_getCandidates(e){if(!this._fieldIndex)return this._data;if(this._fieldIndex._compoundIndexes.size>0){let t={};for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null)t[i]=s}if(Object.keys(t).length>=2){let i=this._fieldIndex.lookupCompound(t);if(i!==null)return i}}for(let t in e){if(t==="$or"||t==="$and"||t==="$not")continue;let i=e[t];if(typeof i!=="object"||i===null){let s=this._fieldIndex._lookupIterable(t,i);if(s!==null)return s}}return this._data}_findIndex(e){for(let t=0;t<this._data.length;t++)if(H(this._data[t],e))return t;return-1}_addToIndex(e){if(this._fieldIndex)this._fieldIndex.add(e)}_removeFromIndex(e){if(this._fieldIndex)this._fieldIndex.remove(e)}_updateInIndex(e,t){if(this._fieldIndex)this._fieldIndex.update(e,t)}async _buildDoc(e,{ttl:t,embed:i}={}){let s={...e,_id:e._id??(this._ctx.idGenerator??Ko)(),createdAt:new Date,updatedAt:new Date},n=t??this._defaultTtl;if(n)s._expiresAt=Bo(n);let r=i??this._defaultEmbed;if(r){let a=typeof r==="function"?r(s):s[r];s._vector=await this._ctx.embed(String(a))}if(this._versioning)s._version=1;return s}_projectDoc(e,t){if(t){let s={};for(let n of t){if(n==="_vector")continue;s[n]=e[n]}return s}let i={...e};return delete i._vector,i}async _populateDoc(e,t,i){for(let s of i){let n=await this._ctx.getCollection(s).findOne({_id:t[s]});if(n)e[s]=n}}}class bi{async read(e){throw Error("StorageAdapter.read() not implemented")}async write(e,t){throw Error("StorageAdapter.write() not implemented")}async delete(e){throw Error("StorageAdapter.delete() not implemented")}async list(){throw Error("StorageAdapter.list() not implemented")}async writeAll(e){for(let{name:t,data:i}of e)await this.write(t,i)}}class An extends bi{constructor({dir:e,format:t="gz"}){super();this.dir=ze.resolve(e),this.format=t,this._ensureDir(this.dir)}_ensureDir(e){if(!j.existsSync(e))j.mkdirSync(e,{recursive:!0})}_filePath(e){return ze.join(this.dir,`${e}.${this.format}`)}async read(e){let t=this._filePath(e);try{let i=await j.promises.readFile(t);if(this.format==="gz")i=ri.inflateSync(i);return i.toString("utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async write(e,t){let i=this._filePath(e),s=ze.join(this.dir,`${e}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let n=ri.deflateSync(t);await j.promises.writeFile(s,n)}else await j.promises.writeFile(s,t,"utf8");await j.promises.rename(s,i)}async writeAll(e){let t=[];try{for(let{name:i,data:s}of e){let n=this._filePath(i),r=ze.join(this.dir,`${i}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let a=ri.deflateSync(s);await j.promises.writeFile(r,a)}else await j.promises.writeFile(r,s,"utf8");t.push({tmp:r,fp:n})}for(let{tmp:i,fp:s}of t)await j.promises.rename(i,s)}catch(i){for(let{tmp:s}of t)try{await j.promises.unlink(s)}catch{}throw i}}async delete(e){let t=this._filePath(e);try{await j.promises.unlink(t)}catch(i){if(i.code!=="ENOENT")throw i}}async list(){try{let e=await j.promises.readdir(this.dir),t=`.${this.format}`;return e.filter((i)=>i.endsWith(t)&&!i.includes(".tmp.")).map((i)=>i.slice(0,-t.length))}catch(e){if(e.code==="ENOENT")return[];throw e}}join(...e){return ze.join(...e)}ensureDir(e){this._ensureDir(e)}async writeRaw(e,t){this._ensureDir(ze.dirname(e)),await j.promises.writeFile(e,t,"utf8")}async readRaw(e){return j.promises.readFile(ze.resolve(e),"utf8")}}class xn{constructor(){this._migrations=[]}add(e){let{version:t,up:i}=e;if(typeof t!=="number"||t<1)throw new N("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version must be a positive integer, got ${t}`,{version:t});if(typeof i!=="function")throw new N("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version ${t} must have an "up" function`,{version:t});if(this._migrations.some((s)=>s.version===t))throw new N("ERR_SKALEX_VALIDATION_MIGRATION_DUPLICATE",`Migration version ${t} is already registered`,{version:t});this._migrations.push({...e}),this._migrations.sort((s,n)=>s.version-n.version)}async run(e,t=[]){let i=new Set(t),s=this._migrations.filter((n)=>!i.has(n.version));for(let n of s){let r=e(n.version);await n.up(r),i.add(n.version)}return[...i].sort((n,r)=>n-r)}status(e=[]){let t=new Set(e),i=this._migrations.map((s)=>s.version).filter((s)=>!t.has(s));return{current:e.length?Math.max(...e):0,applied:[...t].sort((s,n)=>s-n),pending:i}}}var As={[Symbol.iterator](){return{next(){return{done:!0}}}},size:0};function xs(e){return{[Symbol.iterator](){return e[Symbol.iterator]()},get size(){return e.size}}}function ci(e){return e.map((t)=>{if(t===null||t===void 0)return"\x00";if(typeof t==="boolean")return t?"\x01T":"\x01F";if(typeof t==="number")return`\x02${t}`;return`\x03${String(t)}`}).join("\x1F")}class Ct{constructor(e=[],t=[]){this._fields=new Set,this._compoundFields=[];for(let i of e)if(Array.isArray(i)){for(let s of i)this._validateFieldName(s);this._compoundFields.push(i)}else this._validateFieldName(i),this._fields.add(i);for(let i of t)this._validateFieldName(i);this._uniqueFields=new Set(t),this._indexedFields=new Set([...this._fields,...this._uniqueFields]),this._fieldIndexes=new Map,this._uniqueIndexes=new Map;for(let i of this._fields)this._fieldIndexes.set(i,new Map);for(let i of this._uniqueFields)if(this._uniqueIndexes.set(i,new Map),!this._fieldIndexes.has(i))this._fieldIndexes.set(i,new Map);this._compoundIndexes=new Map;for(let i of this._compoundFields)this._compoundIndexes.set(i.join("\x00"),{fields:i,map:new Map})}get indexedFields(){return this._indexedFields}buildFromData(e){for(let[,t]of this._fieldIndexes)t.clear();for(let[,t]of this._uniqueIndexes)t.clear();for(let[,t]of this._compoundIndexes)t.map.clear();for(let t of e)this._indexDoc(t)}add(e){this._checkUnique(e,null),this._indexDoc(e)}remove(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){let n=i.get(s);if(n){if(n.delete(e),n.size===0)i.delete(s)}}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.delete(s)}for(let[,t]of this._compoundIndexes){let i=ci(t.fields.map((n)=>e[n])),s=t.map.get(i);if(s){if(s.delete(e),s.size===0)t.map.delete(i)}}}update(e,t){this._checkUnique(t,e),this.remove(e);try{this._indexDoc(t)}catch(i){try{this._indexDoc(e)}catch{}throw i}}lookup(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?[...s]:[]}_lookupIterable(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?xs(s):As}lookupCompound(e){let t=Object.keys(e).sort();for(let[,i]of this._compoundIndexes){let s=[...i.fields].sort();if(s.length!==t.length)continue;if(s.every((n,r)=>n===t[r])){let n=ci(i.fields.map((a)=>e[a])),r=i.map.get(n);return r?xs(r):As}}return null}isUniqueTaken(e,t){let i=this._uniqueIndexes.get(e);if(!i)return!1;return i.has(t)}assertUniqueCandidates(e,t){if(this._uniqueFields.size===0)return;let i=new Set(e.map((s)=>s._id));for(let s of this._uniqueFields){let n=new Set,r=this._uniqueIndexes.get(s);if(r){for(let[l,o]of r.entries())if(!i.has(o._id))n.add(l)}let a=new Map;for(let l=0;l<t.length;l++){let o=t[l][s];if(o===void 0)continue;if(n.has(o))throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});let c=a.get(o);if(c&&c!==e[l]._id)throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});a.set(o,e[l]._id)}}}assertUniqueBatch(e){if(this._uniqueFields.size===0)return;for(let t of this._uniqueFields){let i=this._uniqueIndexes.get(t),s=new Set;for(let n of e){let r=n[t];if(r===void 0)continue;if(i&&i.has(r))throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${t}" value "${r}" already exists`,{field:t,value:r});if(s.has(r))throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: duplicate "${t}" value "${r}" within batch`,{field:t,value:r});s.add(r)}}}_validateFieldName(e){if(e.includes("."))throw new N("ERR_SKALEX_VALIDATION_INDEX_DOT_PATH",`Index fields cannot use dot-notation: "${e}". Use a flat field name.`,{field:e})}_indexDoc(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){if(!i.has(s))i.set(s,new Set);i.get(s).add(e)}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.set(s,e)}for(let[,t]of this._compoundIndexes){for(let s of t.fields){let n=e[s];if(n!==void 0&&n!==null&&typeof n==="object")throw new N("ERR_SKALEX_VALIDATION_COMPOUND_INDEX",`Compound index field "${s}" must be a scalar value (string, number, or boolean), got ${Array.isArray(n)?"array":typeof n}`,{field:s})}let i=ci(t.fields.map((s)=>e[s]));if(!t.map.has(i))t.map.set(i,new Set);t.map.get(i).add(e)}}_checkUnique(e,t){for(let i of this._uniqueFields){let s=e[i];if(s===void 0)continue;let n=this._uniqueIndexes.get(i);if(!n)continue;let r=n.get(s);if(r&&r._id!==t?._id)throw new xe("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${i}" value "${s}" already exists`,{field:i,value:s})}}}var At="_flush",xt="migrations";class vn{constructor({adapter:e,serializer:t,deserializer:i,logger:s,debug:n=!1,lenientLoad:r=!1}){this._adapter=e,this._serializer=t,this._deserializer=i,this._logger=s,this._debug=n,this._lenientLoad=r,this._saveLock=Promise.resolve()}_withSaveLock(e){let t=this._saveLock.then(e);return this._saveLock=t.catch(()=>{}),t}async loadAll(e,{parseSchema:t,buildIndex:i,IndexEngine:s}){try{let n=await this._adapter.list();await Promise.all(n.map(async(r)=>{try{let a=await this._adapter.read(r);if(!a)return;let l=this._deserializer(a),{collectionName:o,data:c}=l;if(!o)return;let h=e[o],u=h?.rawSchema??l.rawSchema??null,d=h?.schema??(u?t(u):null),_=h?.changelog??l.changelog??!1,f=h?.softDelete??l.softDelete??!1,p=h?.versioning??l.versioning??!1,m=h?.strict??l.strict??!1,w=h?.onSchemaError??l.onSchemaError??"throw",x=h?.defaultTtl??l.defaultTtl??null,R=h?.defaultEmbed??l.defaultEmbed??null,E=h?.maxDocs??l.maxDocs??null,A=h?h.fieldIndex:null;if(!A&&d?.uniqueFields?.length)A=new s([],d.uniqueFields);let Ue=i(c,"_id");if(A)A.buildFromData(c);e[o]={collectionName:o,data:c,index:Ue,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:d,rawSchema:u,fieldIndex:A,changelog:_,softDelete:f,versioning:p,strict:m,onSchemaError:w,defaultTtl:x,defaultEmbed:R,maxDocs:E}}catch(a){if(a.code==="ENOENT")return;if(this._lenientLoad){this._logger(`WARNING: Could not load collection "${r}": ${a.message}. Collection will be empty.`,"error");return}throw new Re("ERR_SKALEX_PERSISTENCE_CORRUPT",`Failed to load collection "${r}": ${a.message}`,{collection:r})}})),this._detectIncompleteFlush(e),await this._cleanOrphanTempFiles()}catch(n){if(n.code!=="ENOENT")throw this._logger(`Error loading data: ${n}`,"error"),n}}async save(e,t){if(t)await this._saveOne(e,t);else await Promise.all(Object.keys(e).map((i)=>this._saveOne(e,i)))}async saveDirty(e){let t=Object.keys(e).filter((i)=>e[i]._dirty);if(t.length===0)return;await Promise.all(t.map((i)=>this._saveOne(e,i)))}saveAtomic(e,t){return this._withSaveLock(async()=>{if(t.length===0)return;this._writeFlushSentinel(e,t);let i=new Set(t);i.add("_meta");let s=[...i].filter((n)=>e[n]).map((n)=>({name:n,data:this._serializeCollection(e[n])}));try{await this._adapter.writeAll(s)}catch(n){throw new Re("ERR_SKALEX_PERSISTENCE_FLUSH_FAILED",`Batch save failed during writeAll: ${n.message}`,{collections:t})}for(let n of t)if(e[n])e[n]._dirty=!1;try{this._clearFlushSentinel(e),await this._adapter.write("_meta",this._serializeCollection(e._meta))}catch(n){this._logger(`WARNING: Batch data committed but sentinel clear failed: ${n.message}. Next load will report an incomplete flush (false positive).`,"error")}})}markDirty(e,t){let i=e[t];if(i)i._dirty=!0}_serializeCollection(e){let t={collectionName:e.collectionName,data:e.data};if(e.rawSchema)t.rawSchema=e.rawSchema;if(e.changelog)t.changelog=e.changelog;if(e.softDelete)t.softDelete=e.softDelete;if(e.versioning)t.versioning=e.versioning;if(e.strict)t.strict=e.strict;if(e.onSchemaError!=="throw")t.onSchemaError=e.onSchemaError;if(e.defaultTtl)t.defaultTtl=e.defaultTtl;if(e.defaultEmbed)t.defaultEmbed=e.defaultEmbed;if(e.maxDocs)t.maxDocs=e.maxDocs;return this._serializer(t)}async _saveOne(e,t){let i=e[t];if(!i)return;if(i.isSaving)return i._pendingSave=!0,new Promise((s,n)=>{(i._saveWaiters??=[]).push({resolve:s,reject:n})});i.isSaving=!0,i._pendingSave=!1;try{await this._writeCollection(t,i);while(i._pendingSave)i._pendingSave=!1,await this._writeCollection(t,i);this._resolveSaveWaiters(i)}catch(s){throw this._rejectSaveWaiters(i,s),s}finally{i.isSaving=!1}}async _writeCollection(e,t){try{await this._adapter.write(e,this._serializeCollection(t)),t._dirty=!1}catch(i){throw this._logger(`Error saving "${e}": ${i.message}`,"error"),i}}_resolveSaveWaiters(e){let t=e._saveWaiters?.splice(0)??[];for(let i of t)i.resolve()}_rejectSaveWaiters(e,t){let i=e._saveWaiters?.splice(0)??[];for(let s of i)s.reject(t)}_writeFlushSentinel(e,t){let i=this._getOrCreateMeta(e);i[At]={startedAt:new Date().toISOString(),collections:t,completedAt:null}}_clearFlushSentinel(e){let t=this._getOrCreateMeta(e);if(t[At])t[At].completedAt=new Date().toISOString()}_detectIncompleteFlush(e){let t=e._meta;if(!t)return;let i=t.index.get(xt);if(!i)return;let s=i[At];if(!s)return;if(s.startedAt&&!s.completedAt)this._logger(`WARNING: Incomplete flush detected (started ${s.startedAt}, collections: ${s.collections?.join(", ")}). Data may be inconsistent.`,"error")}async _cleanOrphanTempFiles(){if(typeof this._adapter.join!=="function")return;if(typeof this._adapter.list!=="function")return;try{let e=await import("fs"),t=await import("path"),i=this._adapter.dir;if(!i)return;let s=(await e.default.promises.readdir(i)).filter((n)=>n.includes(".tmp."));for(let n of s){let r=t.default.join(i,n);try{await e.default.promises.unlink(r),this._log(`Cleaned orphan temp file: ${n}`)}catch{}}}catch{}}_getOrCreateMeta(e){if(!e._meta)e._meta={collectionName:"_meta",data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:null,rawSchema:null,fieldIndex:null,changelog:!1,softDelete:!1,versioning:!1,strict:!1,onSchemaError:"throw",defaultTtl:null,defaultEmbed:null,maxDocs:null};let t=e._meta,i=t.index.get(xt);if(!i)i={_id:xt},t.data.push(i),t.index.set(xt,i);return i}_log(e){if(this._debug)this._logger(e,"info")}}var Qo=0;class En{constructor(){this._txLock=Promise.resolve(),this._ctx=null,this._abortedIds=new Set}get active(){return this._ctx!==null&&!this._ctx.aborted}get context(){return this._ctx}async run(e,t,{timeout:i=0}={}){let s=async()=>{await t._ensureConnected();let r=new Set(Object.keys(t.collections)),a={id:++Qo,startedAt:Date.now(),aborted:!1,preExisting:r,touchedCollections:new Set,snapshots:new Map,deferredEffects:[],timeout:i};this._ctx=a;let l=null,o=i>0?new Promise((u,d)=>{l=setTimeout(()=>{a.aborted=!0,d(new me("ERR_SKALEX_TX_TIMEOUT",`Transaction ${a.id} timed out after ${i}ms`))},i)}):null,c=this,h=new Proxy(t,{get(u,d){if(d==="_txId")return a.id;if(a!==c._ctx)throw new me("ERR_SKALEX_TX_STALE_PROXY",`Transaction ${a.id} has ended. This proxy is no longer usable.`);if(d==="collections")throw new me("ERR_SKALEX_TX_DIRECT_ACCESS","Direct access to db.collections inside transaction() is not covered by rollback. Use the collection API (db.useCollection) instead.");if(d==="useCollection")return(f)=>{let p=u.useCollection(f);return p._activeTxId=a.id,p};let _=Reflect.get(u,d);return typeof _==="function"?_.bind(u):_}});try{let u=e(h),d=o?await Promise.race([u,o]):await u;if(a.aborted)throw new me("ERR_SKALEX_TX_ABORTED",`Transaction ${a.id} was aborted`);let _=[...a.touchedCollections];if(_.length>0)await t._persistence.saveAtomic(t.collections,_);for(let f of a.deferredEffects)await f();return d}catch(u){for(let[d,_]of a.snapshots)if(a.preExisting.has(d)){if(t._applySnapshot(d,_),t.collections[d])t.collections[d]._dirty=_._dirty}for(let d in t.collections)if(!a.preExisting.has(d))delete t.collections[d],delete t._collectionInstances[d];throw u}finally{if(l)clearTimeout(l);if(a.aborted)this._abortedIds.add(a.id);this._ctx=null;for(let u in t._collectionInstances){let d=t._collectionInstances[u];if(d._createdInTxId===a.id)d._createdInTxId=null;if(d._activeTxId===a.id)d._activeTxId=null}}},n=this._txLock.then(s);return this._txLock=n.catch(()=>{}),n}snapshotIfNeeded(e,t,i){let s=this._ctx;if(!s)return;if(this._assertCtxNotAborted(s),!s.snapshots.has(e)){let n=i(t);n._dirty=t._dirty??!1,s.snapshots.set(e,n)}s.touchedCollections.add(e)}assertNotAborted(){let e=this._ctx;if(e)this._assertCtxNotAborted(e)}_assertCtxNotAborted(e){if(e.aborted)throw new me("ERR_SKALEX_TX_ABORTED",`Transaction ${e.id} was aborted. No further mutations allowed.`)}defer(e){if(this._ctx)return this._ctx.deferredEffects.push(e),!0;return!1}}class Sn{constructor(e){this._CollectionClass=e,this.stores={},this._instances={}}get(e,t){if(this._instances[e])return this._instances[e];if(!this.stores[e])this.createStore(e);let i=new this._CollectionClass(this.stores[e],t);return this._instances[e]=i,i}create(e,t={},i){this.createStore(e,t);let s=new this._CollectionClass(this.stores[e],i);return this._instances[e]=s,s}createStore(e,{schema:t,indexes:i=[],changelog:s=!1,softDelete:n=!1,versioning:r=!1,strict:a=!1,onSchemaError:l="throw",defaultTtl:o=null,defaultEmbed:c=null,maxDocs:h=null}={}){let u=null,d=null;if(t){u=pn(t);let _=u.uniqueFields;if(i.length||_.length)d=new Ct(i,_)}else if(i.length)d=new Ct(i,[]);this.stores[e]={collectionName:e,data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:u,rawSchema:t||null,fieldIndex:d,changelog:s,softDelete:n,versioning:r,strict:a,onSchemaError:l,defaultTtl:o,defaultEmbed:c,maxDocs:h}}rename(e,t){if(!this.stores[e])throw new Re("ERR_SKALEX_PERSISTENCE_COLLECTION_NOT_FOUND",`Collection "${e}" not found`,{collection:e});if(this.stores[t])throw new Re("ERR_SKALEX_PERSISTENCE_COLLECTION_EXISTS",`Collection "${t}" already exists`,{collection:t});let i=this.stores[e];if(i.collectionName=t,this.stores[t]=i,delete this.stores[e],this._instances[e]){let s=this._instances[e];s.name=t,this._instances[t]=s,delete this._instances[e]}}buildIndex(e,t){let i=new Map;for(let s of e)i.set(s[t],s);return i}inspect(e){if(e){let i=this.stores[e];if(!i)return null;return{name:e,count:i.data.length,schema:i.schema?Object.fromEntries(i.schema.fields):null,indexes:i.fieldIndex?[...i.fieldIndex.indexedFields]:[],softDelete:i.softDelete??!1,versioning:i.versioning??!1,strict:i.strict??!1,onSchemaError:i.onSchemaError??"throw",maxDocs:i.maxDocs??null}}let t={};for(let i in this.stores)t[i]=this.inspect(i);return t}dump(){let e={};for(let t in this.stores)if(!t.startsWith("_"))e[t]=structuredClone(this.stores[t].data);return e}schema(e){let t=this.stores[e];if(!t)return null;if(t.schema)return Object.fromEntries([...t.schema.fields.entries()].map(([i,s])=>[i,s.type]));if(t.data.length>0)return Uo(t.data[0]);return null}stats(e){let t=(i)=>{let s=this.stores[i];if(!s)return null;let n=s.data.length,r=0;for(let a of s.data)try{r+=JSON.stringify(a).length}catch(l){}return{collection:i,count:n,estimatedSize:r,avgDocSize:n>0?Math.round(r/n):0}};if(e)return t(e);return Object.keys(this.stores).map(t)}clear(){this.stores={},this._instances={}}}class Ti{async embed(e){throw Error("EmbeddingAdapter.embed() not implemented")}}var le=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class In extends Ti{constructor({apiKey:e=le("OPENAI_API_KEY"),model:t=le("OPENAI_EMBED_MODEL")??"text-embedding-3-small",baseUrl:i=le("OPENAI_EMBED_BASE_URL")??"https://api.openai.com/v1/embeddings",dimensions:s=le("OPENAI_EMBED_DIMENSIONS")!=null?Number(le("OPENAI_EMBED_DIMENSIONS")):void 0,organization:n=le("OPENAI_ORGANIZATION")??void 0,timeout:r=le("OPENAI_EMBED_TIMEOUT")!=null?Number(le("OPENAI_EMBED_TIMEOUT")):void 0,retries:a=Number(le("OPENAI_EMBED_RETRIES")??0),retryDelay:l=Number(le("OPENAI_EMBED_RETRY_DELAY")??1000),headers:o={},fetch:c=globalThis.fetch}={}){super();if(!e)throw Error("OpenAIEmbeddingAdapter requires an apiKey");this.apiKey=e,this.model=t,this.baseUrl=i,this.dimensions=s,this.organization=n,this.timeout=r,this.retries=a,this.retryDelay=l,this.headers=o,this._fetch=c}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(this.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...this.organization&&{"OpenAI-Organization":this.organization},...this.headers},body:JSON.stringify({input:e,model:this.model,...this.dimensions!==void 0&&{dimensions:this.dimensions}}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`OpenAI embedding API error ${r.status}: ${a}`)}return(await r.json()).data[0].embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}var tt=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class bn extends Ti{constructor({model:e=tt("OLLAMA_EMBED_MODEL")??"nomic-embed-text",host:t=tt("OLLAMA_HOST")??"http://localhost:11434",timeout:i=tt("OLLAMA_EMBED_TIMEOUT")!=null?Number(tt("OLLAMA_EMBED_TIMEOUT")):void 0,retries:s=Number(tt("OLLAMA_EMBED_RETRIES")??0),retryDelay:n=Number(tt("OLLAMA_EMBED_RETRY_DELAY")??1000),headers:r={},fetch:a=globalThis.fetch}={}){super();this.model=e,this.host=t,this.timeout=i,this.retries=s,this.retryDelay=n,this.headers=r,this._fetch=a}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({model:this.model,prompt:e}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama embedding API error ${r.status}: ${a}`)}return(await r.json()).embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}class Mt{async generate(e,t){throw Error("LLMAdapter.generate() not implemented")}async summarize(e){throw Error("LLMAdapter.summarize() not implemented")}}var Oi=`You are a database query assistant. Convert the user's natural language request into a JSON filter object for a document database.
16
16
 
17
17
  Rules:
18
18
  - Return ONLY a valid JSON object, nothing else
@@ -27,18 +27,18 @@ Schema: ${JSON.stringify(e)}`,messages:[{role:"user",content:t}]})).content[0].t
27
27
  Schema: ${JSON.stringify(e)}
28
28
  Query: ${t}`,s=await this._post({model:this.model,prompt:i,format:"json",options:{temperature:0},stream:!1});return JSON.parse(s.response)}async summarize(e){return(await this._post({model:this.model,prompt:`${this.summarizePrompt}
29
29
 
30
- ${e}`,options:{temperature:this.temperature,...this.topP!==void 0&&{top_p:this.topP},...this.topK!==void 0&&{top_k:this.topK}},stream:!1})).response.trim()}async _post(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify(e),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama API error ${r.status}: ${a}`)}return r.json()}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}function Wo({provider:e,apiKey:t,embedModel:i,model:s,host:n,embedBaseUrl:r,dimensions:a,organization:l,embedTimeout:o,embedRetries:c,embedRetryDelay:h}){let u=i||s;switch(e){case"openai":return new In({apiKey:t,model:u,baseUrl:r,...a!==void 0&&{dimensions:a},...l!==void 0&&{organization:l},...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});case"ollama":return new bn({model:u,host:n,...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});default:throw new ue("ERR_SKALEX_ADAPTER_UNKNOWN_PROVIDER",`Unknown AI provider: "${e}". Supported: "openai", "ollama".`,{provider:e})}}function Qo({provider:e,apiKey:t,model:i,host:s,baseUrl:n,apiVersion:r,temperature:a,maxTokens:l,topP:o,topK:c,organization:h,timeout:u,retries:d,retryDelay:_,seed:f,generatePrompt:p,summarizePrompt:m}){if(!i)return null;switch(e){case"openai":return new Tn({apiKey:t,model:i,baseUrl:n,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...h!==void 0&&{organization:h},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...f!==void 0&&{seed:f},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"anthropic":return new On({apiKey:t,model:i,baseUrl:n,apiVersion:r,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"ollama":return new Nn({model:i,host:s,...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});default:return null}}var hi="AES-GCM",ft=12,ve=32,Go=new TextEncoder,Zo=new TextDecoder;class $n extends bi{constructor(e,t){super();if(this._adapter=e,this._rawKey=typeof t==="string"?el(t):Uint8Array.from(t),this._rawKey.length!==ve)throw new ue("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: key must be ${ve} bytes (${ve*2} hex chars), got ${this._rawKey.length}`);this._cryptoKey=null}async read(e){let t=await this._adapter.read(e);if(!t)return null;return this._decrypt(t)}async write(e,t){return this._adapter.write(e,await this._encrypt(t))}async delete(e){return this._adapter.delete(e)}async list(){return this._adapter.list()}async writeAll(e){let t=[];for(let{name:i,data:s}of e)t.push({name:i,data:await this._encrypt(s)});return this._adapter.writeAll(t)}join(...e){return this._adapter.join?.(...e)}ensureDir(e){return this._adapter.ensureDir?.(e)}async writeRaw(e,t){return this._adapter.writeRaw?.(e,await this._encrypt(t))}async readRaw(e){let t=await this._adapter.readRaw?.(e);if(!t)return null;return this._decrypt(t)}async _getKey(){if(!this._cryptoKey)this._cryptoKey=await globalThis.crypto.subtle.importKey("raw",this._rawKey,{name:hi},!1,["encrypt","decrypt"]);return this._cryptoKey}async _encrypt(e){let t=await this._getKey(),i=globalThis.crypto.getRandomValues(new Uint8Array(ft)),s=Go.encode(e),n=await globalThis.crypto.subtle.encrypt({name:hi,iv:i,tagLength:128},t,s),r=new Uint8Array(ft+n.byteLength);return r.set(i,0),r.set(new Uint8Array(n),ft),tl(r)}async _decrypt(e){let t=await this._getKey(),i=il(e),s=i.slice(0,ft),n=i.slice(ft),r=await globalThis.crypto.subtle.decrypt({name:hi,iv:s,tagLength:128},t,n);return Zo.decode(r)}}function el(e){if(e.length!==ve*2)throw new ue("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: hex key must be ${ve*2} characters (${ve} bytes)`);if(!/^[0-9a-fA-F]+$/.test(e))throw new ue("ERR_SKALEX_ADAPTER_INVALID_KEY","EncryptedAdapter: hex key contains invalid characters");let t=new Uint8Array(ve);for(let i=0;i<ve;i++)t[i]=parseInt(e.slice(i*2,i*2+2),16);return t}function tl(e){let t="";for(let i=0;i<e.length;i++)t+=String.fromCharCode(e[i]);return globalThis.btoa(t)}function il(e){let t=globalThis.atob(e),i=new Uint8Array(t.length);for(let s=0;s<t.length;s++)i[s]=t.charCodeAt(s);return i}var sl=4;class Dn{constructor(e,t){this.sessionId=e,this._db=t,this._col=t.useCollection(`_memory_${e}`)}async remember(e){let t=await this._col.insertOne({text:e,sessionId:this.sessionId},{embed:"text"}),i=this._db._memoryConfig?.maxEntries;if(i&&this._col._data.length>i)await this.compress({threshold:0});return t}async recall(e,{limit:t=10,minScore:i=0}={}){return this._col.search(e,{limit:t,minScore:i})}async history({since:e,limit:t}={}){let i=e?{createdAt:{$gte:new Date(e)}}:{},s={sort:{createdAt:1}};if(t)s.limit=t;let{docs:n}=await this._col.find(i,s);return n}async forget(e){return this._col.deleteOne({_id:e})}tokenCount(){let e=this._col._data;return{tokens:e.reduce((t,i)=>t+this._docTokens(i),0),count:e.length}}context({tokens:e=this._db._memoryConfig?.contextTokens??4000}={}){let t=this._sortedData("desc"),i=[],s=0;for(let n of t){let r=this._docTokens(n);if(s+r>e)break;i.push(n.text),s+=r}return i.reverse().join(`
30
+ ${e}`,options:{temperature:this.temperature,...this.topP!==void 0&&{top_p:this.topP},...this.topK!==void 0&&{top_k:this.topK}},stream:!1})).response.trim()}async _post(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify(e),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama API error ${r.status}: ${a}`)}return r.json()}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}function Go({provider:e,apiKey:t,embedModel:i,model:s,host:n,embedBaseUrl:r,dimensions:a,organization:l,embedTimeout:o,embedRetries:c,embedRetryDelay:h}){let u=i||s;switch(e){case"openai":return new In({apiKey:t,model:u,baseUrl:r,...a!==void 0&&{dimensions:a},...l!==void 0&&{organization:l},...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});case"ollama":return new bn({model:u,host:n,...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});default:throw new ue("ERR_SKALEX_ADAPTER_UNKNOWN_PROVIDER",`Unknown AI provider: "${e}". Supported: "openai", "ollama".`,{provider:e})}}function Zo({provider:e,apiKey:t,model:i,host:s,baseUrl:n,apiVersion:r,temperature:a,maxTokens:l,topP:o,topK:c,organization:h,timeout:u,retries:d,retryDelay:_,seed:f,generatePrompt:p,summarizePrompt:m}){if(!i)return null;switch(e){case"openai":return new Tn({apiKey:t,model:i,baseUrl:n,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...h!==void 0&&{organization:h},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...f!==void 0&&{seed:f},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"anthropic":return new On({apiKey:t,model:i,baseUrl:n,apiVersion:r,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"ollama":return new Nn({model:i,host:s,...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});default:return null}}var hi="AES-GCM",ft=12,ve=32,el=new TextEncoder,tl=new TextDecoder;class $n extends bi{constructor(e,t){super();if(this._adapter=e,this._rawKey=typeof t==="string"?il(t):Uint8Array.from(t),this._rawKey.length!==ve)throw new ue("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: key must be ${ve} bytes (${ve*2} hex chars), got ${this._rawKey.length}`);this._cryptoKey=null}async read(e){let t=await this._adapter.read(e);if(!t)return null;return this._decrypt(t)}async write(e,t){return this._adapter.write(e,await this._encrypt(t))}async delete(e){return this._adapter.delete(e)}async list(){return this._adapter.list()}async writeAll(e){let t=[];for(let{name:i,data:s}of e)t.push({name:i,data:await this._encrypt(s)});return this._adapter.writeAll(t)}join(...e){return this._adapter.join?.(...e)}ensureDir(e){return this._adapter.ensureDir?.(e)}async writeRaw(e,t){return this._adapter.writeRaw?.(e,await this._encrypt(t))}async readRaw(e){let t=await this._adapter.readRaw?.(e);if(!t)return null;return this._decrypt(t)}async _getKey(){if(!this._cryptoKey)this._cryptoKey=await globalThis.crypto.subtle.importKey("raw",this._rawKey,{name:hi},!1,["encrypt","decrypt"]);return this._cryptoKey}async _encrypt(e){let t=await this._getKey(),i=globalThis.crypto.getRandomValues(new Uint8Array(ft)),s=el.encode(e),n=await globalThis.crypto.subtle.encrypt({name:hi,iv:i,tagLength:128},t,s),r=new Uint8Array(ft+n.byteLength);return r.set(i,0),r.set(new Uint8Array(n),ft),sl(r)}async _decrypt(e){let t=await this._getKey(),i=nl(e),s=i.slice(0,ft),n=i.slice(ft),r=await globalThis.crypto.subtle.decrypt({name:hi,iv:s,tagLength:128},t,n);return tl.decode(r)}}function il(e){if(e.length!==ve*2)throw new ue("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: hex key must be ${ve*2} characters (${ve} bytes)`);if(!/^[0-9a-fA-F]+$/.test(e))throw new ue("ERR_SKALEX_ADAPTER_INVALID_KEY","EncryptedAdapter: hex key contains invalid characters");let t=new Uint8Array(ve);for(let i=0;i<ve;i++)t[i]=parseInt(e.slice(i*2,i*2+2),16);return t}function sl(e){let t="";for(let i=0;i<e.length;i++)t+=String.fromCharCode(e[i]);return globalThis.btoa(t)}function nl(e){let t=globalThis.atob(e),i=new Uint8Array(t.length);for(let s=0;s<t.length;s++)i[s]=t.charCodeAt(s);return i}var rl=4;class Dn{constructor(e,t){this.sessionId=e,this._db=t,this._col=t.useCollection(`_memory_${e}`)}async remember(e){let t=await this._col.insertOne({text:e,sessionId:this.sessionId},{embed:"text"}),i=this._db._memoryConfig?.maxEntries;if(i&&this._col._data.length>i)await this.compress({threshold:0});return t}async recall(e,{limit:t=10,minScore:i=0}={}){return this._col.search(e,{limit:t,minScore:i})}async history({since:e,limit:t}={}){let i=e?{createdAt:{$gte:new Date(e)}}:{},s={sort:{createdAt:1}};if(t)s.limit=t;let{docs:n}=await this._col.find(i,s);return n}async forget(e){return this._col.deleteOne({_id:e})}tokenCount(){let e=this._col._data;return{tokens:e.reduce((t,i)=>t+this._docTokens(i),0),count:e.length}}context({tokens:e=this._db._memoryConfig?.contextTokens??4000}={}){let t=this._sortedData("desc"),i=[],s=0;for(let n of t){let r=this._docTokens(n);if(s+r>e)break;i.push(n.text),s+=r}return i.reverse().join(`
31
31
  `)}async compress({threshold:e=this._db._memoryConfig?.compressionThreshold??8000,keepRecent:t=this._db._memoryConfig?.keepRecent??10}={}){let{tokens:i}=this.tokenCount();if(i<=e)return;if(!this._db._aiAdapter)throw Error('memory.compress() requires a language model adapter. Configure { ai: { model: "..." } }.');let s=this._sortedData("asc"),n=Math.max(0,s.length-t),r=s.slice(0,n);if(r.length===0)return;let a=r.map((o)=>o.text).join(`
32
- `),l=await this._db._aiAdapter.summarize(a);await this._col.deleteMany({_id:{$in:r.map((o)=>o._id)}}),await this._col.insertOne({text:l,sessionId:this.sessionId,compressed:!0})}_docTokens(e){return Math.ceil((e.text||"").length/sl)}_sortedData(e){return[...this._col._data].sort(e==="asc"?(t,i)=>new Date(t.createdAt)-new Date(i.createdAt):(t,i)=>new Date(i.createdAt)-new Date(t.createdAt))}}class Cn{constructor(e){this._db=e,this._restoring=!1}get _col(){return this._db.useCollection("_changelog")}async log(e,t,i,s=null,n=null){if(this._restoring)return;let r={op:e,collection:t,docId:i._id,doc:{...i},timestamp:new Date};if(s)r.prev={...s};if(n)r.session=n;await this._col.insertOne(r)}async query(e,{since:t,limit:i,session:s}={}){let n={collection:e};if(t)n.timestamp={$gte:new Date(t)};if(s)n.session=s;let r={sort:{timestamp:1}};if(i)r.limit=i;let{docs:a}=await this._col.find(n,r);return a}async restore(e,t,{_id:i}={}){let s=new Date(t),n=this._db.useCollection(e),r=(await this.query(e,{})).filter((l)=>new Date(l.timestamp)<=s);if(i){let l=r.filter((c)=>c.docId===i);if(l.length===0)return;let o=l[l.length-1];this._restoring=!0;try{if(o.op==="delete"){if(await n.findOne({_id:i}))await n.deleteOne({_id:i});return}if(await n.findOne({_id:i})){let{_id:c,createdAt:h,updatedAt:u,...d}=o.doc;await n.updateOne({_id:i},d)}else await n.insertOne({...o.doc})}finally{this._restoring=!1}await this._db.saveData(e);return}let a=new Map;for(let l of r)if(l.op==="insert"||l.op==="update")a.set(l.docId,{doc:l.doc,deleted:!1});else if(l.op==="delete")a.set(l.docId,{doc:null,deleted:!0});this._restoring=!0;try{await n.deleteMany({});for(let[,{doc:l,deleted:o}]of a)if(!o&&l)await n.insertOne({...l})}finally{this._restoring=!1}await this._db.saveData(e)}}function nl(e){let t=5381;for(let i=0;i<e.length;i++)t=(t<<5)+t+e.charCodeAt(i)|0;return(t>>>0).toString(16).padStart(8,"0")}class Rn{constructor({maxSize:e=500,ttl:t=0}={}){this._cache=new Map,this._maxSize=e,this._ttl=t}_key(e,t,i){return nl(JSON.stringify({collectionName:e,schema:t,query:i}))}get(e,t,i){let s=this._key(e,t,i),n=this._cache.get(s);if(!n)return;if(this._ttl>0&&Date.now()-n.ts>this._ttl){this._cache.delete(s);return}return n.filter}set(e,t,i,s){let n=this._key(e,t,i);if(this._cache.size>=this._maxSize&&!this._cache.has(n))this._cache.delete(this._cache.keys().next().value);this._cache.set(n,{filter:s,ts:Date.now()})}toJSON(){return Object.fromEntries([...this._cache.entries()].map(([e,t])=>[e,t]))}fromJSON(e){if(!e||typeof e!=="object")return;for(let[t,i]of Object.entries(e))this._cache.set(t,i)}get size(){return this._cache.size}}function rl(e,{regexMaxLength:t=500}={}){if(typeof e!=="object"||e===null)return e;let i={};for(let s of Object.keys(e)){let n=e[s];if(n&&typeof n==="object"&&!Array.isArray(n)){let r={};for(let a of Object.keys(n))if(a==="$regex"&&typeof n.$regex==="string"){if(n.$regex.length>t)throw Error(`$regex pattern too long (max ${t} characters)`);if(/\([^)]*[+*][^)]*\)[+*{]/.test(n.$regex))throw Error("$regex pattern rejected: nested quantifiers risk ReDoS");try{r.$regex=new RegExp(n.$regex)}catch{throw Error(`invalid $regex pattern: "${n.$regex}"`)}}else if(["$gt","$gte","$lt","$lte"].includes(a)&&al(n[a]))r[a]=new Date(n[a]);else r[a]=n[a];i[s]=r}else i[s]=n}return i}function al(e){if(typeof e!=="string")return!1;return/\d{4}-\d{2}-\d{2}/.test(e)&&!isNaN(Date.parse(e))}function ol(e,t){let i=[];if(!t||typeof e!=="object"||e===null)return i;for(let s of Object.keys(e)){if(s.startsWith("$"))continue;if(!(s.split(".")[0]in t))i.push(`Unknown field referenced in generated filter: "${s}"`)}return i}class kn{constructor(){this._listeners=new Map}on(e,t){if(!this._listeners.has(e))this._listeners.set(e,new Set);return this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}emit(e,t){for(let i of[e,"*"]){let s=this._listeners.get(i);if(!s)continue;for(let n of s)try{n(t)}catch(r){}}}removeAll(e){if(e)this._listeners.delete(e);else this._listeners.clear()}listenerCount(e){return this._listeners.get(e)?.size??0}}class Ln{constructor({threshold:e=100,maxEntries:t=500}={}){this._threshold=e,this._maxEntries=t,this._entries=[]}record({collection:e,op:t,filter:i,query:s,duration:n,resultCount:r}){if(n<this._threshold)return;let a={collection:e,op:t,duration:n,resultCount:r,timestamp:new Date};if(i!==void 0)a.filter=i;if(s!==void 0)a.query=s;if(this._entries.push(a),this._entries.length>this._maxEntries)this._entries.shift()}entries({limit:e,minDuration:t,collection:i}={}){let s=this._entries;if(i)s=s.filter((n)=>n.collection===i);if(t)s=s.filter((n)=>n.duration>=t);if(e)s=s.slice(-e);return s}get size(){return this._entries.length}clear(){this._entries=[]}}class Pn{constructor(){this._sessions=new Map}_ensure(e){if(!this._sessions.has(e))this._sessions.set(e,{reads:0,writes:0,lastActive:null});return this._sessions.get(e)}recordRead(e){if(!e)return;let t=this._ensure(e);t.reads++,t.lastActive=new Date}recordWrite(e){if(!e)return;let t=this._ensure(e);t.writes++,t.lastActive=new Date}get(e){let t=this._sessions.get(e);if(!t)return null;return{sessionId:e,...t}}all(){return[...this._sessions.entries()].map(([e,t])=>({sessionId:e,...t}))}clear(e){if(e)this._sessions.delete(e);else this._sessions.clear()}}class Mn{constructor(){this._plugins=[]}register(e){if(typeof e!=="object"||e===null)throw TypeError("Plugin must be a non-null object.");this._plugins.push(e)}async run(e,t){for(let i of this._plugins)if(typeof i[e]==="function")await i[e](t)}get size(){return this._plugins.length}}function Ve(e){if(typeof e!=="string"||!e.trim())throw Error("collection name must be a non-empty string");if(/[/\\]/.test(e)||e.includes("..")||e.includes("\x00"))throw Error(`invalid collection name: "${e}"`);if(e.trim().startsWith("_"))throw Error(`access to system collection "${e}" is not permitted`);return e.trim()}var vs=[{name:"skalex_collections",description:"List all collection names in the database.",inputSchema:{type:"object",properties:{}},scope:"read"},{name:"skalex_schema",description:"Return the schema for a collection as a { field: type } map. Returns null if the collection is empty.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."}},required:["collection"]},scope:"read"},{name:"skalex_find",description:"Find documents in a collection that match a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter (MongoDB-style operators supported)."},limit:{type:"number",description:"Maximum number of results. Default: 20."},sort:{type:"object",description:"Sort descriptor: { field: 1 } for ascending, { field: -1 } for descending."}},required:["collection"]},scope:"read"},{name:"skalex_insert",description:"Insert a single document into a collection.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},doc:{type:"object",description:"Document to insert."}},required:["collection","doc"]},scope:"write"},{name:"skalex_update",description:"Update the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},update:{type:"object",description:"Fields to update (direct assignment, $inc, $push supported)."},many:{type:"boolean",description:"If true, update all matching documents. Default: false."}},required:["collection","filter","update"]},scope:"write"},{name:"skalex_delete",description:"Delete the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},many:{type:"boolean",description:"If true, delete all matching documents. Default: false."}},required:["collection","filter"]},scope:"write"},{name:"skalex_search",description:"Semantic similarity search. Requires an embedding adapter to be configured.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},query:{type:"string",description:"Natural-language query string to embed and compare."},limit:{type:"number",description:"Maximum number of results. Default: 10."},minScore:{type:"number",description:"Minimum cosine similarity score [0, 1]. Default: 0."},filter:{type:"object",description:"Optional structured pre-filter (hybrid search)."}},required:["collection","query"]},scope:"read"},{name:"skalex_ask",description:"Translate a natural-language question into a filter and query a collection. Requires a language model adapter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},question:{type:"string",description:"Natural-language question about the data."},limit:{type:"number",description:"Maximum number of results. Default: 20."}},required:["collection","question"]},scope:"read"}];async function ll(e,t,i){switch(e){case"skalex_collections":return Object.keys(i.collections).filter((s)=>!s.startsWith("_"));case"skalex_schema":return i.schema(Ve(t.collection))??null;case"skalex_find":{let s=i.useCollection(Ve(t.collection)),n={};if(t.limit)n.limit=t.limit;if(t.sort)n.sort=t.sort;return s.find(t.filter||{},n)}case"skalex_insert":return i.useCollection(Ve(t.collection)).insertOne(t.doc||{});case"skalex_update":{let s=i.useCollection(Ve(t.collection));if(t.many)return s.updateMany(t.filter||{},t.update||{});return s.updateOne(t.filter||{},t.update||{})}case"skalex_delete":{let s=i.useCollection(Ve(t.collection));if(t.many)return s.deleteMany(t.filter||{});return s.deleteOne(t.filter||{})}case"skalex_search":return i.useCollection(Ve(t.collection)).search(t.query,{limit:t.limit??10,minScore:t.minScore??0,filter:t.filter});case"skalex_ask":return i.ask(Ve(t.collection),t.question,{limit:t.limit??20});default:throw Object.assign(Error(`Unknown tool: ${e}`),{code:"NOT_FOUND"})}}var $i="2.0",Di=-32700,cl=-32600,Es=-32601,hl=-32602,dl=-32603;function it(e,t){return{jsonrpc:$i,id:e,result:t}}function Ne(e,t,i,s){return{jsonrpc:$i,id:e,error:{code:t,message:i}}}function ul(e){try{let t=JSON.parse(e);if(typeof t!=="object"||t===null||t.jsonrpc!==$i)return{parseError:Ne(null,cl,"Invalid JSON-RPC request")};return{msg:t}}catch(t){return{parseError:Ne(null,Di,"Parse error")}}}function _l(e){return{content:[{type:"text",text:e}]}}function Ss(e){return{content:[{type:"text",text:e}],isError:!0}}class jn{constructor({port:e=3000,host:t="127.0.0.1",allowedOrigin:i=null,maxBodySize:s=1048576}={}){this._port=e,this._host=t,this._allowedOrigin=i,this._maxBodySize=s,this._clients=new Set,this._onMessage=null,this._server=null}onMessage(e){this._onMessage=e}send(e){let t=`data: ${JSON.stringify(e)}
32
+ `),l=await this._db._aiAdapter.summarize(a);await this._col.deleteMany({_id:{$in:r.map((o)=>o._id)}}),await this._col.insertOne({text:l,sessionId:this.sessionId,compressed:!0})}_docTokens(e){return Math.ceil((e.text||"").length/rl)}_sortedData(e){return[...this._col._data].sort(e==="asc"?(t,i)=>new Date(t.createdAt)-new Date(i.createdAt):(t,i)=>new Date(i.createdAt)-new Date(t.createdAt))}}class Cn{constructor(e){this._db=e,this._restoring=!1}get _col(){return this._db.useCollection("_changelog")}async log(e,t,i,s=null,n=null){if(this._restoring)return;let r={op:e,collection:t,docId:i._id,doc:{...i},timestamp:new Date};if(s)r.prev={...s};if(n)r.session=n;await this._col.insertOne(r)}async query(e,{since:t,limit:i,session:s}={}){let n={collection:e};if(t)n.timestamp={$gte:new Date(t)};if(s)n.session=s;let r={sort:{timestamp:1}};if(i)r.limit=i;let{docs:a}=await this._col.find(n,r);return a}async restore(e,t,{_id:i}={}){let s=new Date(t),n=this._db.useCollection(e),r=(await this.query(e,{})).filter((l)=>new Date(l.timestamp)<=s);if(i){let l=r.filter((c)=>c.docId===i);if(l.length===0)return;let o=l[l.length-1];this._restoring=!0;try{if(o.op==="delete"){if(await n.findOne({_id:i}))await n.deleteOne({_id:i});return}if(await n.findOne({_id:i})){let{_id:c,createdAt:h,updatedAt:u,...d}=o.doc;await n.updateOne({_id:i},d)}else await n.insertOne({...o.doc})}finally{this._restoring=!1}await this._db.saveData(e);return}let a=new Map;for(let l of r)if(l.op==="insert"||l.op==="update")a.set(l.docId,{doc:l.doc,deleted:!1});else if(l.op==="delete")a.set(l.docId,{doc:null,deleted:!0});this._restoring=!0;try{await n.deleteMany({});for(let[,{doc:l,deleted:o}]of a)if(!o&&l)await n.insertOne({...l})}finally{this._restoring=!1}await this._db.saveData(e)}}function al(e){let t=5381;for(let i=0;i<e.length;i++)t=(t<<5)+t+e.charCodeAt(i)|0;return(t>>>0).toString(16).padStart(8,"0")}class Rn{constructor({maxSize:e=500,ttl:t=0}={}){this._cache=new Map,this._maxSize=e,this._ttl=t}_key(e,t,i){return al(JSON.stringify({collectionName:e,schema:t,query:i}))}get(e,t,i){let s=this._key(e,t,i),n=this._cache.get(s);if(!n)return;if(this._ttl>0&&Date.now()-n.ts>this._ttl){this._cache.delete(s);return}return n.filter}set(e,t,i,s){let n=this._key(e,t,i);if(this._cache.size>=this._maxSize&&!this._cache.has(n))this._cache.delete(this._cache.keys().next().value);this._cache.set(n,{filter:s,ts:Date.now()})}toJSON(){return Object.fromEntries([...this._cache.entries()].map(([e,t])=>[e,t]))}fromJSON(e){if(!e||typeof e!=="object")return;for(let[t,i]of Object.entries(e))this._cache.set(t,i)}get size(){return this._cache.size}}function ol(e,{regexMaxLength:t=500}={}){if(typeof e!=="object"||e===null)return e;let i={};for(let s of Object.keys(e)){let n=e[s];if(n&&typeof n==="object"&&!Array.isArray(n)){let r={};for(let a of Object.keys(n))if(a==="$regex"&&typeof n.$regex==="string"){if(n.$regex.length>t)throw Error(`$regex pattern too long (max ${t} characters)`);if(/\([^)]*[+*][^)]*\)[+*{]/.test(n.$regex))throw Error("$regex pattern rejected: nested quantifiers risk ReDoS");try{r.$regex=new RegExp(n.$regex)}catch{throw Error(`invalid $regex pattern: "${n.$regex}"`)}}else if(["$gt","$gte","$lt","$lte"].includes(a)&&ll(n[a]))r[a]=new Date(n[a]);else r[a]=n[a];i[s]=r}else i[s]=n}return i}function ll(e){if(typeof e!=="string")return!1;return/\d{4}-\d{2}-\d{2}/.test(e)&&!isNaN(Date.parse(e))}function cl(e,t){let i=[];if(!t||typeof e!=="object"||e===null)return i;for(let s of Object.keys(e)){if(s.startsWith("$"))continue;if(!(s.split(".")[0]in t))i.push(`Unknown field referenced in generated filter: "${s}"`)}return i}class kn{constructor(){this._listeners=new Map}on(e,t){if(!this._listeners.has(e))this._listeners.set(e,new Set);return this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}emit(e,t){for(let i of[e,"*"]){let s=this._listeners.get(i);if(!s)continue;for(let n of s)try{n(t)}catch(r){}}}removeAll(e){if(e)this._listeners.delete(e);else this._listeners.clear()}listenerCount(e){return this._listeners.get(e)?.size??0}}class Ln{constructor({threshold:e=100,maxEntries:t=500}={}){this._threshold=e,this._maxEntries=t,this._entries=[]}record({collection:e,op:t,filter:i,query:s,duration:n,resultCount:r}){if(n<this._threshold)return;let a={collection:e,op:t,duration:n,resultCount:r,timestamp:new Date};if(i!==void 0)a.filter=i;if(s!==void 0)a.query=s;if(this._entries.push(a),this._entries.length>this._maxEntries)this._entries.shift()}entries({limit:e,minDuration:t,collection:i}={}){let s=this._entries;if(i)s=s.filter((n)=>n.collection===i);if(t)s=s.filter((n)=>n.duration>=t);if(e)s=s.slice(-e);return s}get size(){return this._entries.length}clear(){this._entries=[]}}class Pn{constructor(){this._sessions=new Map}_ensure(e){if(!this._sessions.has(e))this._sessions.set(e,{reads:0,writes:0,lastActive:null});return this._sessions.get(e)}recordRead(e){if(!e)return;let t=this._ensure(e);t.reads++,t.lastActive=new Date}recordWrite(e){if(!e)return;let t=this._ensure(e);t.writes++,t.lastActive=new Date}get(e){let t=this._sessions.get(e);if(!t)return null;return{sessionId:e,...t}}all(){return[...this._sessions.entries()].map(([e,t])=>({sessionId:e,...t}))}clear(e){if(e)this._sessions.delete(e);else this._sessions.clear()}}class Mn{constructor(){this._plugins=[]}register(e){if(typeof e!=="object"||e===null)throw TypeError("Plugin must be a non-null object.");this._plugins.push(e)}async run(e,t){for(let i of this._plugins)if(typeof i[e]==="function")await i[e](t)}get size(){return this._plugins.length}}function Ve(e){if(typeof e!=="string"||!e.trim())throw Error("collection name must be a non-empty string");if(/[/\\]/.test(e)||e.includes("..")||e.includes("\x00"))throw Error(`invalid collection name: "${e}"`);if(e.trim().startsWith("_"))throw Error(`access to system collection "${e}" is not permitted`);return e.trim()}var vs=[{name:"skalex_collections",description:"List all collection names in the database.",inputSchema:{type:"object",properties:{}},scope:"read"},{name:"skalex_schema",description:"Return the schema for a collection as a { field: type } map. Returns null if the collection is empty.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."}},required:["collection"]},scope:"read"},{name:"skalex_find",description:"Find documents in a collection that match a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter (MongoDB-style operators supported)."},limit:{type:"number",description:"Maximum number of results. Default: 20."},sort:{type:"object",description:"Sort descriptor: { field: 1 } for ascending, { field: -1 } for descending."}},required:["collection"]},scope:"read"},{name:"skalex_insert",description:"Insert a single document into a collection.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},doc:{type:"object",description:"Document to insert."}},required:["collection","doc"]},scope:"write"},{name:"skalex_update",description:"Update the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},update:{type:"object",description:"Fields to update (direct assignment, $inc, $push supported)."},many:{type:"boolean",description:"If true, update all matching documents. Default: false."}},required:["collection","filter","update"]},scope:"write"},{name:"skalex_delete",description:"Delete the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},many:{type:"boolean",description:"If true, delete all matching documents. Default: false."}},required:["collection","filter"]},scope:"write"},{name:"skalex_search",description:"Semantic similarity search. Requires an embedding adapter to be configured.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},query:{type:"string",description:"Natural-language query string to embed and compare."},limit:{type:"number",description:"Maximum number of results. Default: 10."},minScore:{type:"number",description:"Minimum cosine similarity score [0, 1]. Default: 0."},filter:{type:"object",description:"Optional structured pre-filter (hybrid search)."}},required:["collection","query"]},scope:"read"},{name:"skalex_ask",description:"Translate a natural-language question into a filter and query a collection. Requires a language model adapter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},question:{type:"string",description:"Natural-language question about the data."},limit:{type:"number",description:"Maximum number of results. Default: 20."}},required:["collection","question"]},scope:"read"}];async function hl(e,t,i){switch(e){case"skalex_collections":return Object.keys(i.collections).filter((s)=>!s.startsWith("_"));case"skalex_schema":return i.schema(Ve(t.collection))??null;case"skalex_find":{let s=i.useCollection(Ve(t.collection)),n={};if(t.limit)n.limit=t.limit;if(t.sort)n.sort=t.sort;return s.find(t.filter||{},n)}case"skalex_insert":return i.useCollection(Ve(t.collection)).insertOne(t.doc||{});case"skalex_update":{let s=i.useCollection(Ve(t.collection));if(t.many)return s.updateMany(t.filter||{},t.update||{});return s.updateOne(t.filter||{},t.update||{})}case"skalex_delete":{let s=i.useCollection(Ve(t.collection));if(t.many)return s.deleteMany(t.filter||{});return s.deleteOne(t.filter||{})}case"skalex_search":return i.useCollection(Ve(t.collection)).search(t.query,{limit:t.limit??10,minScore:t.minScore??0,filter:t.filter});case"skalex_ask":return i.ask(Ve(t.collection),t.question,{limit:t.limit??20});default:throw Object.assign(Error(`Unknown tool: ${e}`),{code:"NOT_FOUND"})}}var $i="2.0",Di=-32700,dl=-32600,Es=-32601,ul=-32602,_l=-32603;function it(e,t){return{jsonrpc:$i,id:e,result:t}}function Ne(e,t,i,s){return{jsonrpc:$i,id:e,error:{code:t,message:i}}}function fl(e){try{let t=JSON.parse(e);if(typeof t!=="object"||t===null||t.jsonrpc!==$i)return{parseError:Ne(null,dl,"Invalid JSON-RPC request")};return{msg:t}}catch(t){return{parseError:Ne(null,Di,"Parse error")}}}function pl(e){return{content:[{type:"text",text:e}]}}function Ss(e){return{content:[{type:"text",text:e}],isError:!0}}class jn{constructor({port:e=3000,host:t="127.0.0.1",allowedOrigin:i=null,maxBodySize:s=1048576}={}){this._port=e,this._host=t,this._allowedOrigin=i,this._maxBodySize=s,this._clients=new Set,this._onMessage=null,this._server=null}onMessage(e){this._onMessage=e}send(e){let t=`data: ${JSON.stringify(e)}
33
33
 
34
- `;for(let i of this._clients)try{i.write(t)}catch(s){this._clients.delete(i)}}start(){return new Promise((e,t)=>{this._server=co.createServer((i,s)=>{if(this._allowedOrigin)s.setHeader("Access-Control-Allow-Origin",this._allowedOrigin),s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type");if(i.method==="OPTIONS"){s.writeHead(204),s.end();return}if(i.method==="GET"&&i.url==="/sse")this._handleSSE(i,s);else if(i.method==="POST"&&i.url==="/message")this._handleMessage(i,s);else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not Found")}),this._server.on("error",t),this._server.listen(this._port,this._host,()=>e())})}stop(){return new Promise((e)=>{if(!this._server){e();return}for(let t of this._clients)try{t.end()}catch(i){}this._clients.clear(),this._server.close(()=>e()),this._server=null})}_handleSSE(e,t){t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),t.write(`event: endpoint
34
+ `;for(let i of this._clients)try{i.write(t)}catch(s){this._clients.delete(i)}}start(){return new Promise((e,t)=>{this._server=uo.createServer((i,s)=>{if(this._allowedOrigin)s.setHeader("Access-Control-Allow-Origin",this._allowedOrigin),s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type");if(i.method==="OPTIONS"){s.writeHead(204),s.end();return}if(i.method==="GET"&&i.url==="/sse")this._handleSSE(i,s);else if(i.method==="POST"&&i.url==="/message")this._handleMessage(i,s);else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not Found")}),this._server.on("error",t),this._server.listen(this._port,this._host,()=>e())})}stop(){return new Promise((e)=>{if(!this._server){e();return}for(let t of this._clients)try{t.end()}catch(i){}this._clients.clear(),this._server.close(()=>e()),this._server=null})}_handleSSE(e,t){t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),t.write(`event: endpoint
35
35
  data: /message
36
36
 
37
37
  `),this._clients.add(t),e.on("close",()=>{this._clients.delete(t)})}async _handleMessage(e,t){let i="";e.setEncoding("utf8"),e.on("data",(s)=>{if(i+=s,i.length>this._maxBodySize)e.destroy(),t.writeHead(413,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"Request body too large"}))}),e.on("end",async()=>{t.writeHead(202,{"Content-Type":"application/json"}),t.end("{}");let s;try{s=JSON.parse(i)}catch(n){this.send(Ne(null,Di,"Parse error"));return}if(this._onMessage)await this._onMessage(s).catch(()=>{})})}get port(){return this._port}get host(){return this._host}get url(){return`http://${this._host}:${this._port}`}get sseUrl(){return`${this.url}/sse`}}class qn{constructor(){this._onMessage=null,this._buffer="",this._started=!1}onMessage(e){this._onMessage=e}send(e){process.stdout.write(JSON.stringify(e)+`
38
38
  `)}start(){if(this._started)return;this._started=!0,process.stdin.setEncoding("utf8"),process.stdin.on("data",(e)=>{this._buffer+=e;let t;while((t=this._buffer.indexOf(`
39
- `))!==-1){let i=this._buffer.slice(0,t).trim();if(this._buffer=this._buffer.slice(t+1),i&&this._onMessage){let s;try{s=JSON.parse(i)}catch(n){this.send(Ne(null,Di,"Parse error"));continue}this._onMessage(s).catch(()=>{})}}}),process.stdin.on("end",()=>{process.exit(0)})}stop(){process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),this._started=!1}}var fl={name:"skalex",version:"4.0.0-alpha"},pl="2024-11-05";class Kn{constructor(e,t={}){this._db=e,this._transport=t.transport||"stdio",this._port=t.port||3000,this._host=t.host||"127.0.0.1",this._allowedOrigin=t.allowedOrigin??null,this._maxBodySize=t.maxBodySize??1048576,this._scopes=t.scopes||{"*":["read"]},this._t=null}async listen(){if(this._transport==="http")this._t=new jn({port:this._port,host:this._host,allowedOrigin:this._allowedOrigin,maxBodySize:this._maxBodySize});else this._t=new qn;this._t.onMessage((e)=>this._handleMessage(e)),await this._t.start()}async connect(e){if(this._t=e,this._t.onMessage((t)=>this._handleMessage(t)),typeof this._t.start==="function")await this._t.start()}async close(){if(this._t&&typeof this._t.stop==="function")await this._t.stop();this._t=null}get transport(){return this._transport}get url(){return this._t?.url}async _handleMessage(e){let{msg:t,parseError:i}=typeof e==="string"?ul(e):{msg:e};if(i){this._send(i);return}let{id:s,method:n,params:r}=t;if(s===void 0){if(n==="notifications/initialized")return;return}try{switch(n){case"initialize":this._send(it(s,{protocolVersion:pl,capabilities:{tools:{}},serverInfo:fl}));break;case"tools/list":this._send(it(s,{tools:this._visibleTools()}));break;case"tools/call":await this._handleToolCall(s,r);break;case"ping":this._send(it(s,{}));break;default:this._send(Ne(s,Es,`Method not found: ${n}`))}}catch(a){this._send(Ne(s,dl,a.message||"Internal error"))}}async _handleToolCall(e,t){let i=t?.name,s=t?.arguments??{};if(!i){this._send(Ne(e,hl,"tools/call requires params.name"));return}let n=vs.find((a)=>a.name===i);if(!n){this._send(Ne(e,Es,`Unknown tool: ${i}`));return}let r=s.collection||s.collection_name||null;if(!this._hasScope(r,n.scope)){this._send(it(e,Ss(`Access denied: "${i}" requires "${n.scope}" scope on collection "${r}".`)));return}try{let a=await ll(i,s,this._db);this._send(it(e,_l(JSON.stringify(a,null,2))))}catch(a){this._send(it(e,Ss(a.message||String(a))))}}_visibleTools(){return vs.filter((e)=>{let t=this._scopes["*"];if(t&&(t.includes(e.scope)||t.includes("admin")))return!0;for(let[,i]of Object.entries(this._scopes))if(i.includes(e.scope)||i.includes("admin"))return!0;return!1})}_hasScope(e,t){let i=(s)=>s.includes("admin")||s.includes(t);if(e&&this._scopes[e])return i(this._scopes[e]);if(this._scopes["*"])return i(this._scopes["*"]);return!1}_send(e){this._t?.send(e)}}var vt="migrations",Is=(e)=>JSON.stringify(e,function(t,i){let s=this[t];if(s instanceof Date)return{__skalex_date__:s.toISOString()};if(typeof i==="bigint")return{__skalex_bigint__:i.toString()};return i}),bs=(e)=>JSON.parse(e,(t,i)=>{if(i&&typeof i==="object"){if("__skalex_bigint__"in i)return BigInt(i.__skalex_bigint__);if("__skalex_date__"in i)return new Date(i.__skalex_date__)}return i});class ee{constructor({path:e="./.db",format:t="gz",debug:i=!1,adapter:s,ai:n,encrypt:r,slowQueryLog:a,queryCache:l,memory:o,logger:c,plugins:h,llmAdapter:u,embeddingAdapter:d,regexMaxLength:_,idGenerator:f,serializer:p,deserializer:m,autoSave:w,ttlSweepInterval:x,lenientLoad:R}={}){if(this.dataDirectory=e,this.dataFormat=t,this.debug=i,!ee._errorsAttached)ee.SkalexError=Me,ee.ValidationError=N,ee.UniqueConstraintError=xe,ee.TransactionError=me,ee.PersistenceError=Re,ee.AdapterError=ue,ee.QueryError=Qe,ee._errorsAttached=!0;this._adapterConfig=s??null;let E=s||new An({dir:e,format:t});if(r)E=new $n(E,r.key);if(this.fs=E,this._registry=new Sn(wn),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._migrations=new xn,this._connectPromise=null,this.isConnected=!1,this._aiConfig=n||null,this._encryptConfig=r||null,this._pluginsConfig=Array.isArray(h)?h:null,this._memoryConfig=o||null,this._regexMaxLength=_??500,this._idGenerator=f??null,this._serializer=p??Is,this._deserializer=m??bs,this._autoSave=w??!1,this._txManager=new En,this._ttlSweepInterval=x??0,this._ttlTimer=null,this._logger=c??ps,this._embeddingAdapter=d??(n?Wo(n):null),this._aiAdapter=u??(n?Qo(n):null),this._persistence=new vn({adapter:this.fs,serializer:this._serializer,deserializer:this._deserializer,logger:this._logger,debug:this.debug,lenientLoad:R??!1}),this._changeLog=new Cn(this),this._queryCache=new Rn(l||{}),this._eventBus=new kn,this._queryLog=a?new Ln(a):null,this._sessionStats=new Pn,this._plugins=new Mn,Array.isArray(h))for(let A of h)this._plugins.register(A)}async connect(){if(this._connectPromise)return this._connectPromise;return this._connectPromise=this._doConnect(),this._connectPromise}async _doConnect(){try{await this.loadData();let e=this._getMeta();if(e.queryCache)this._queryCache.fromJSON(e.queryCache);if(this._migrations._migrations.length>0){let t=e.appliedVersions||[],i=await this._migrations.run((s)=>this.useCollection(`_migration_${s}`),t);this._saveMeta({appliedVersions:i})}if(this._sweepTtl(),this._ttlSweepInterval>0){if(this._ttlTimer=setInterval(()=>this._sweepTtl(),this._ttlSweepInterval),this._ttlTimer?.unref)this._ttlTimer.unref()}this.isConnected=!0,this._log("> - Connected to the database (\u221A)")}catch(e){throw this._logger(`Error connecting to the database: ${e}`,"error"),e}}async disconnect(){try{if(this._ttlTimer)clearInterval(this._ttlTimer),this._ttlTimer=null;await this.saveData(),this._registry.clear(),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._connectPromise=null,this.isConnected=!1,this._log("> - Disconnected from the database (\u221A)")}catch(e){throw this._logger(`Error disconnecting from the database: ${e}`,"error"),e}}async _ensureConnected(){if(this.isConnected)return;return this.connect()}useCollection(e){return this._registry.get(e,this)}createCollection(e,t={}){return this._registry.create(e,t,this)}_createCollectionStore(e,t={}){this._registry.createStore(e,t)}async renameCollection(e,t){this._registry.rename(e,t),await this.saveData(t),await this.fs.delete(e)}async loadData(){await this._persistence.loadAll(this.collections,{parseSchema:pn,buildIndex:this._registry.buildIndex,IndexEngine:Ct});for(let e in this._collectionInstances){let t=this.collections[e];if(t&&this._collectionInstances[e]._store!==t)this._collectionInstances[e]._store=t}}async saveData(e){await this._persistence.save(this.collections,e)}buildIndex(e,t){return this._registry.buildIndex(e,t)}addMigration(e){this._migrations.add(e)}migrationStatus(){let e=this._getMeta();return this._migrations.status(e.appliedVersions||[])}namespace(e){if(this._adapterConfig)throw new ue("ERR_SKALEX_ADAPTER_NAMESPACE_REQUIRES_FS","namespace() requires the default FsAdapter. When a custom storage adapter is configured, create a separate Skalex instance with your adapter instead.");let t=String(e).replace(/[^a-zA-Z0-9_-]/g,"_");if(!t)throw new N("ERR_SKALEX_VALIDATION_NAMESPACE_ID","namespace: id must contain at least one alphanumeric character",{id:e});return new ee({path:`${this.dataDirectory}/${t}`,format:this.dataFormat,debug:this.debug,ai:this._aiConfig||void 0,encrypt:this._encryptConfig||void 0,slowQueryLog:this._queryLog?{threshold:this._queryLog._threshold,maxEntries:this._queryLog._maxEntries}:void 0,queryCache:this._queryCache?{maxSize:this._queryCache._maxSize,ttl:this._queryCache._ttl}:void 0,plugins:this._pluginsConfig||void 0,memory:this._memoryConfig||void 0,logger:this._logger!==ps?this._logger:void 0,llmAdapter:this._aiAdapter&&!this._aiConfig?this._aiAdapter:void 0,embeddingAdapter:this._embeddingAdapter&&!this._aiConfig?this._embeddingAdapter:void 0,regexMaxLength:this._regexMaxLength!==500?this._regexMaxLength:void 0,idGenerator:this._idGenerator||void 0,serializer:this._serializer!==Is?this._serializer:void 0,deserializer:this._deserializer!==bs?this._deserializer:void 0,autoSave:this._autoSave||void 0,ttlSweepInterval:this._ttlSweepInterval||void 0})}use(e){this._plugins.register(e)}watch(e){return this._eventBus.on("*",e)}sessionStats(e){if(e!==void 0)return this._sessionStats.get(e);return this._sessionStats.all()}get _inTransaction(){return this._txManager.active}_emitEvent(e,t){if(!this._txManager.defer(()=>this._eventBus.emit(e,t)))this._eventBus.emit(e,t)}async _runAfterHook(e,t){if(!this._txManager.defer(()=>this._plugins.run(e,t)))await this._plugins.run(e,t)}async _logChange(e,t,i,s,n){if(!this._txManager.defer(()=>this._changeLog.log(e,t,i,s,n)))await this._changeLog.log(e,t,i,s,n)}async transaction(e,t={}){return this._txManager.run(e,this,t)}async seed(e,{reset:t=!1}={}){for(let[i,s]of Object.entries(e)){if(t&&this.collections[i])this._applySnapshot(i,{data:[],index:new Map}),delete this._collectionInstances[i];await this.useCollection(i).insertMany(s)}await this.saveData()}dump(){return this._registry.dump()}inspect(e){return this._registry.inspect(e)}async import(e){let t=await this.fs.readRaw(e),i;try{i=JSON.parse(t)}catch{throw new Re("ERR_SKALEX_PERSISTENCE_INVALID_JSON",`import: invalid JSON in file "${e}"`,{filePath:e})}let s=e.split("/").pop().replace(/\.[^.]+$/,"");return this.useCollection(s).insertMany(Array.isArray(i)?i:[i],{save:!0})}async embed(e){if(!this._embeddingAdapter)throw new ue("ERR_SKALEX_ADAPTER_EMBEDDING_REQUIRED","db.embed() requires an AI adapter. Pass { ai: { provider, apiKey } } to the Skalex constructor.");return this._embeddingAdapter.embed(e)}async ask(e,t,{limit:i=20}={}){if(!this._aiAdapter)throw new ue("ERR_SKALEX_ADAPTER_LLM_REQUIRED",'db.ask() requires a language model adapter. Configure { ai: { provider, model: "..." } }.');let s=this.useCollection(e),n=this.schema(e),r=this._queryCache.get(e,n,t);if(!r){r=await this._aiAdapter.generate(n,t);let a=ol(r,n);if(a.length)a.forEach((l)=>this._log(`[ask] ${l}`));this._queryCache.set(e,n,t,r),this._saveMeta({queryCache:this._queryCache.toJSON()})}return s.find(rl(r,{regexMaxLength:this._regexMaxLength}),{limit:i})}schema(e){return this._registry.schema(e)}useMemory(e){return new Dn(e,this)}changelog(){return this._changeLog}async restore(e,t,i={}){return this._changeLog.restore(e,t,i)}stats(e){return this._registry.stats(e)}slowQueries(e={}){if(!this._queryLog)return[];return this._queryLog.entries(e)}slowQueryCount(){return this._queryLog?this._queryLog.size:0}clearSlowQueries(){this._queryLog?.clear()}mcp(e={}){return new Kn(this,e)}_getMeta(){let e=this.collections._meta;if(!e)return{};return e.index.get(vt)||{}}_saveMeta(e){if(!this.collections._meta)this._createCollectionStore("_meta");let t=this.collections._meta,i=t.index.get(vt);if(i)Object.assign(i,e);else{let s={_id:vt,...e};t.data.push(s),t.index.set(vt,s)}this._persistence.markDirty(this.collections,"_meta")}_sweepTtl(){for(let e in this.collections){let t=this.collections[e],i=zo(t.data,t.index,t.fieldIndex?(s)=>t.fieldIndex.remove(s):null);if(i>0)this._persistence.markDirty(this.collections,e),this._log(`TTL sweep: removed ${i} expired docs from "${e}"`)}}_buildCollectionContext(){let e=this;return{ensureConnected:()=>e._ensureConnected(),get txManager(){return e._txManager},get plugins(){return e._plugins},get eventBus(){return e._eventBus},get sessionStats(){return e._sessionStats},get queryLog(){return e._queryLog},get logger(){return e._logger},get persistence(){return e._persistence},get collections(){return e.collections},embed:(t)=>e.embed(t),get idGenerator(){return e._idGenerator},get autoSave(){return e._autoSave},saveCollection:(t)=>e.saveData(t),snapshotCollection:(t)=>e._snapshotCollection(t),getCollection:(t)=>e.useCollection(t),emitEvent:(t,i)=>e._emitEvent(t,i),runAfterHook:(t,i)=>e._runAfterHook(t,i),logChange:(t,i,s,n,r)=>e._logChange(t,i,s,n,r),get fs(){return e.fs},get dataDirectory(){return e.dataDirectory}}}_log(e){if(this.debug)this._logger(e,"info")}_snapshotCollection(e){return{data:structuredClone(e.data)}}_applySnapshot(e,t){let i=this.collections[e];if(!i)return;if(i.data=t.data,i.index=this.buildIndex(t.data,"_id"),i.fieldIndex)i.fieldIndex.buildFromData(t.data)}}function ml(){let e=Date.now().toString(16),t;try{t=yo.randomBytes(8).toString("hex")}catch{let i=new Uint8Array(8);crypto.getRandomValues(i),t=Array.from(i).map((s)=>s.toString(16).padStart(2,"0")).join("")}return`${e}${t}`}function Ts(e,t){let i=e instanceof Error?e.message:e;if(t==="error")console.error(i);else console.log(i)}var Os=new Set(["__proto__","constructor","prototype"]);function jt(e,t){if(!t.includes(".")){if(Os.has(t))return;return e[t]}let i=e;for(let s of t.split(".")){if(Os.has(s))return;if(i==null)return;i=i[s]}return i}class je extends Error{constructor(e,t,i={}){super(t);this.name=this.constructor.name,this.code=e,this.details=i}}class $ extends je{}class Ee extends je{}class ge extends je{}class ke extends je{}class _e extends je{}class Ge extends je{}function wi(e,t){if(e===t)return!0;if(e==null||t==null)return!1;if(typeof e!==typeof t)return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.source===t.source&&e.flags===t.flags;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!wi(e[i],t[i]))return!1;return!0}if(typeof e==="object"){if(Array.isArray(t))return!1;let i=Object.keys(e);if(i.length!==Object.keys(t).length)return!1;for(let s of i){if(!Object.prototype.hasOwnProperty.call(t,s))return!1;if(!wi(e[s],t[s]))return!1}return!0}return!1}function V(e,t){if(typeof t==="function")return t(e);if(t==null)return!0;if(typeof t==="object"&&Object.keys(t).length===0)return!0;if("$or"in t){let i=t.$or;if(!Array.isArray(i))throw new Ge("ERR_SKALEX_QUERY_INVALID_OPERATOR","$or must be an array of filters",{operator:"$or"});if(!i.some((s)=>V(e,s)))return!1}if("$and"in t){let i=t.$and;if(!Array.isArray(i))throw new Ge("ERR_SKALEX_QUERY_INVALID_OPERATOR","$and must be an array of filters",{operator:"$and"});if(!i.every((s)=>V(e,s)))return!1}if("$not"in t){if(V(e,t.$not))return!1}for(let i in t){if(i==="$or"||i==="$and"||i==="$not")continue;let s=t[i],n;try{n=jt(e,i)}catch{return!1}if(s instanceof RegExp){if(!s.test(String(n)))return!1}else if(typeof s==="object"&&s!==null){if(Object.keys(s).some((r)=>r.startsWith("$"))){if("$eq"in s&&n!==s.$eq)return!1;if("$ne"in s&&n===s.$ne)return!1;if("$gt"in s&&!(n>s.$gt))return!1;if("$lt"in s&&!(n<s.$lt))return!1;if("$gte"in s&&!(n>=s.$gte))return!1;if("$lte"in s&&!(n<=s.$lte))return!1;if("$in"in s&&!s.$in.includes(n))return!1;if("$nin"in s&&s.$nin.includes(n))return!1;if("$regex"in s){if(!(s.$regex instanceof RegExp?s.$regex:new RegExp(s.$regex)).test(String(n)))return!1}if("$fn"in s&&!s.$fn(n))return!1}else if(!wi(n,s))return!1}else if(n!==s)return!1}return!0}function gl(e,t=new Set){if(typeof e!=="object"||e===null||typeof e==="function")return e;let i=[],s=[],n=[],r=[],a=[];for(let o in e){if(o==="$or"||o==="$and"||o==="$not"){a.push(o);continue}let c=e[o];if(t.has(o))i.push(o);else if(c instanceof RegExp||typeof c==="object"&&c!==null&&(("$regex"in c)||("$fn"in c))||typeof c==="function")r.push(o);else if(typeof c==="object"&&c!==null&&(("$gt"in c)||("$lt"in c)||("$gte"in c)||("$lte"in c)||("$ne"in c)||("$in"in c)||("$nin"in c)))n.push(o);else s.push(o)}let l={};for(let o of[...i,...s,...n,...r,...a])l[o]=e[o];return l}var Ai=new Set(["string","number","boolean","object","array","date","any"]);function Ci(e){if(Array.isArray(e))return"array";if(e instanceof Date)return"date";return typeof e}function Fn(e){let t=new Map,i=[];for(let[s,n]of Object.entries(e)){let r;if(typeof n==="string"){if(!Ai.has(n))throw new $("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${n}" for field "${s}"`,{field:s,type:n});r={type:n,required:!1,unique:!1}}else if(typeof n==="object"&&n!==null){let{type:a="any",required:l=!1,unique:o=!1,enum:c}=n;if(!Ai.has(a))throw new $("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${a}" for field "${s}"`,{field:s,type:a});if(r={type:a,required:l,unique:o,enum:c},o)i.push(s)}else throw new $("ERR_SKALEX_VALIDATION_INVALID_SCHEMA",`Invalid schema definition for field "${s}"`,{field:s});t.set(s,r)}return{fields:t,uniqueFields:i}}function Ns(e,t,i=!1){let s=[];for(let[n,r]of t){let a=e[n],l=a===void 0||a===null;if(r.required&&l){s.push(`Field "${n}" is required`);continue}if(l)continue;if(r.type!=="any"){let o=Ci(a);if(o!==r.type)s.push(`Field "${n}" must be of type "${r.type}", got "${o}"`)}if(r.enum&&!r.enum.includes(a))s.push(`Field "${n}" must be one of [${r.enum.map((o)=>JSON.stringify(o)).join(", ")}], got ${JSON.stringify(a)}`)}if(i){for(let n of Object.keys(e))if(!n.startsWith("_")&&!t.has(n))s.push(`Unknown field "${n}" (strict mode)`)}return s}function $s(e,t){let i={};for(let[s,n]of Object.entries(e)){if(s.startsWith("_")){i[s]=n;continue}if(!t.has(s))continue;let r=t.get(s);if(r.type!=="any"){if(Ci(n)!==r.type)continue}if(r.enum&&!r.enum.includes(n))continue;i[s]=n}return i}function yl(e){let t={};for(let[i,s]of Object.entries(e)){if(i.startsWith("_"))continue;let n=Ci(s);t[i]=Ai.has(n)?n:"any"}return t}function wl(e){if(typeof e==="number"){if(e<=0)throw new $("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got ${e}`,{ttl:e});return e*1000}if(typeof e!=="string")throw new $("ERR_SKALEX_VALIDATION_TTL",`Invalid TTL value: ${e}`,{ttl:e});let t=e.match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/);if(!t)throw new $("ERR_SKALEX_VALIDATION_TTL_FORMAT",`Invalid TTL format: "${e}". Use e.g. 300 (seconds), "30m", "24h", "7d"`,{ttl:e});let i=parseFloat(t[1]);if(i<=0)throw new $("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got "${e}"`,{ttl:e});let s=t[2],n=i*{ms:1,s:1000,m:60000,h:3600000,d:86400000}[s];if(!isFinite(n))throw new $("ERR_SKALEX_VALIDATION_TTL",`TTL value "${e}" is too large`,{ttl:e});return n}function Al(e){return new Date(Date.now()+wl(e))}function xl(e,t,i=null){let s=Date.now(),n=0,r=e.length;while(r--){let a=e[r];if(a._expiresAt&&new Date(a._expiresAt).getTime()<=s){if(e.splice(r,1),t.delete(a._id),i)i(a);n++}}return n}function Ds(e,t){if(e.length!==t.length)throw new Ge("ERR_SKALEX_QUERY_VECTOR_MISMATCH",`Vector dimension mismatch: ${e.length} vs ${t.length}`,{expected:e.length,got:t.length});let i=0,s=0,n=0;for(let a=0;a<e.length;a++)i+=e[a]*t[a],s+=e[a]*e[a],n+=t[a]*t[a];let r=Math.sqrt(s*n);return r===0?0:i/r}function z(e){if(!("_vector"in e))return{...e};let{_vector:t,...i}=e;return i}function vl(e){return e.length}function El(e,t){let i=0;for(let s of e){let n=jt(s,t);if(typeof n==="number"&&!isNaN(n))i+=n}return i}function Sl(e,t){let i=0,s=0;for(let n of e){let r=jt(n,t);if(typeof r==="number"&&!isNaN(r))i+=r,s++}return s===0?null:i/s}function Il(e,t){let i=Object.create(null);for(let s of e){let n=String(jt(s,t)??"__null__");if(!i[n])i[n]=[];i[n].push(s)}return i}class Un{constructor(e){this._col=e}get _ctx(){return this._col._ctx}async execute({op:e,beforeHook:t,afterHook:i,hookPayload:s,mutate:n,afterHookPayload:r,save:a,session:l}){let o=this._ctx;await o.ensureConnected(),this._col._txSnapshotIfNeeded();let c=o.txManager,h=c.active&&this._col._activeTxId===c.context?.id,u=h?c.context.id:null,d=this._col._createdInTxId,_=()=>{if(u!==null&&c._abortedIds.has(u))throw new ge("ERR_SKALEX_TX_ABORTED",`Transaction ${u} was aborted. No further mutations allowed.`);if(d!==null&&c._abortedIds.has(d))throw new ge("ERR_SKALEX_TX_ABORTED",`Transaction ${d} was aborted. Collection obtained inside that transaction cannot be used for further mutations.`)};if(h||d!==null)_();if(t)await o.plugins.run(t,s);let{docs:f,prevDocs:p=[]}=await n(_);if(o.persistence.markDirty(o.collections,this._col.name),await this._col._saveIfNeeded(a),this._col._changelogEnabled)for(let m=0;m<f.length;m++)await o.logChange(e,this._col.name,f[m],p[m]??null,l||null);if(!h||!c.defer(()=>o.sessionStats.recordWrite(l)))o.sessionStats.recordWrite(l);for(let m of f)o.emitEvent(this._col.name,{op:e,collection:this._col.name,doc:z(m)});if(i)if(r)await o.runAfterHook(i,r(f));else for(let m of f)await o.runAfterHook(i,{collection:this._col.name,doc:z(m)});return{docs:f,prevDocs:p}}}function bl(e){let t={};for(let i in e){if(i.startsWith("$"))continue;let s=e[i];if(s&&typeof s==="object"&&!Array.isArray(s)){let n=Object.keys(s);if(n.length===1&&n[0]==="$eq")t[i]=s.$eq}else t[i]=s}return t}var zn=new Set(["__proto__","constructor","prototype"]);function Bn(e){if(typeof e!=="object"||e===null||Array.isArray(e))return e;let t={};for(let i of Object.keys(e)){if(zn.has(i))continue;t[i]=Bn(e[i])}return t}class Xn{constructor(e,t){this.name=e.collectionName,this.database=t,this._ctx=t._buildCollectionContext(),this._store=e,this._pipeline=new Un(this),this._createdInTxId=t._txManager.context?.id??null,this._activeTxId=null}get _data(){return this._store.data}set _data(e){this._store.data=e}get _index(){return this._store.index}get _fieldIndex(){return this._store.fieldIndex||null}get _schema(){return this._store.schema?this._store.schema.fields:null}get _changelogEnabled(){return this._store.changelog===!0}get _softDelete(){return this._store.softDelete===!0}get _versioning(){return this._store.versioning===!0}get _strict(){return this._store.strict===!0}get _onSchemaError(){return this._store.onSchemaError??"throw"}get _defaultTtl(){return this._store.defaultTtl||null}get _defaultEmbed(){return this._store.defaultEmbed||null}get _maxDocs(){return this._store.maxDocs||null}async insertOne(e,t={}){let{save:i,ifNotExists:s,ttl:n,embed:r,session:a}=t;if(s){await this._ctx.ensureConnected();let o=this._findRaw(e);if(o)return z({...o})}let{docs:l}=await this._insertCore([e],{ttl:n,embed:r,session:a,save:i});return z(l[0])}async insertMany(e,t={}){let{save:i,ttl:s,embed:n,session:r}=t,{docs:a}=await this._insertCore(e,{ttl:s,embed:n,session:r,save:i});return a.map(z)}async _insertCore(e,{ttl:t,embed:i,session:s,save:n}){return this._pipeline.execute({op:"insert",beforeHook:null,afterHook:"afterInsert",hookPayload:null,save:n,session:s,mutate:async(r)=>{let a=[],l=new Set;for(let o of e){let c=this._applyValidation(o);await this._ctx.plugins.run("beforeInsert",{collection:this.name,doc:c});let h=await this._buildDoc(c,{ttl:t,embed:i});if(this._index.has(h._id)||l.has(h._id))throw new Ee("ERR_SKALEX_UNIQUE_DUPLICATE_ID",`Duplicate _id "${h._id}" in collection "${this.name}"`,{id:h._id,collection:this.name});l.add(h._id),a.push(h)}if(r(),this._fieldIndex)this._fieldIndex.assertUniqueBatch(a);for(let o of a)this._addToIndex(o);this._data.push(...a);for(let o of a)this._index.set(o._id,o);return this._enforceCapAfterInsert(),{docs:a}}})}async updateOne(e,t,i={}){await this._ctx.ensureConnected();let s=this._findRaw(e);if(!s)return null;let{save:n,session:r}=i,{docs:a}=await this._updateCore([s],e,t,{save:n,session:r});return z(a[0])}async updateMany(e,t,i={}){await this._ctx.ensureConnected();let s=this._findAllRaw(e);if(s.length===0)return[];let{save:n,session:r}=i,{docs:a}=await this._updateCore(s,e,t,{save:n,session:r});return a.map(z)}async _updateCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"update",beforeHook:"beforeUpdate",afterHook:"afterUpdate",hookPayload:{collection:this.name,filter:t,update:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:t,update:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{let a=this._changelogEnabled?e.map((h)=>structuredClone(h)):e.map(()=>null),l=e.map((h)=>this._prepareUpdatedDoc(h,i));this._assertUniqueCandidates(e,l),r();let o=new Set(e),c=new Map;for(let h=0;h<this._data.length;h++)if(o.has(this._data[h]))c.set(this._data[h],h);for(let h=0;h<e.length;h++)this._commitUpdatedDoc(e[h],l[h],c);return{docs:l,prevDocs:a}}})}applyUpdate(e,t){for(let i in t){if(zn.has(i))continue;if(i==="_id"||i==="createdAt")continue;let s=t[i];if(Array.isArray(s))e[i]=s;else if(typeof s==="object"&&s!==null){let n=Object.keys(s);if(n.some((r)=>r.startsWith("$"))){for(let r of n)if(r==="$inc"&&typeof e[i]==="number")e[i]+=s[r];else if(r==="$push"){if(!Array.isArray(e[i]))e[i]=[];e[i].push(s[r])}}else e[i]=Bn(s)}else e[i]=s}if(e.updatedAt=new Date,this._versioning)e._version=(e._version??0)+1;return e}_prepareUpdatedDoc(e,t){let i=structuredClone(e),s=structuredClone(e);if(this.applyUpdate(s,t),!this._schema)return s;let n=Ns(s,this._schema,this._strict);if(!n.length)return s;switch(this._onSchemaError){case"throw":throw new $("ERR_SKALEX_VALIDATION_UPDATE",`Update validation failed on doc "${e._id}": ${n.join("; ")}`,{id:e._id,errors:n});case"strip":return this._stripCandidateToValid(s,i);default:return this._ctx.logger(`[${this.name}] Update validation warning: ${n.join("; ")}`,"warn"),s}}_stripCandidateToValid(e,t){let i=$s(e,this._schema),s=structuredClone(t);for(let[n,r]of Object.entries(i)){if(n.startsWith("_"))continue;s[n]=r}if(s.updatedAt=e.updatedAt,this._versioning)s._version=e._version;return s}_commitUpdatedDoc(e,t,i){let s=i?i.get(e):this._data.indexOf(e);if(s===void 0||s===-1)throw new ke("ERR_SKALEX_PERSISTENCE_DOC_MISSING",`Document "${e._id}" no longer exists in collection "${this.name}"`,{id:e._id,collection:this.name});this._data[s]=t,this._index.set(t._id,t),this._updateInIndex(e,t)}_assertUniqueCandidates(e,t){this._fieldIndex?.assertUniqueCandidates(e,t)}async upsert(e,t,i={}){if(await this._ctx.ensureConnected(),this._findRaw(e))return this.updateOne(e,t,i);return this.insertOne({...bl(e),...t},i)}async upsertMany(e,t,i={}){await this._ctx.ensureConnected();let{save:s,...n}=i,r=[];for(let a of e)r.push(await this.upsert({[t]:a[t]},a,{...n,save:!1}));return await this._saveIfNeeded(s),r}async restore(e,t={}){if(!this._softDelete)throw new Ge("ERR_SKALEX_QUERY_SOFT_DELETE_REQUIRED",`restore() requires softDelete on "${this.name}"`,{collection:this.name});await this._ctx.ensureConnected();let{save:i,session:s}=t,n=this._findRaw(e,{includeDeleted:!0});if(!n||!n._deletedAt)return null;let{docs:r}=await this._pipeline.execute({op:"restore",beforeHook:null,afterHook:null,hookPayload:null,save:i,session:s,mutate:async(a)=>{return a(),delete n._deletedAt,n.updatedAt=new Date,this._index.set(n._id,n),{docs:[n]}}});return z(r[0])}watch(e,t){if(typeof e==="function")t=e,e=null;if(t)return this._ctx.eventBus.on(this.name,(i)=>{if(!e||V(i.doc,e))t(i)});return this._watchIterator(e)}_watchIterator(e){let t=[],i=null,s=!1,n=this._ctx.eventBus.on(this.name,(r)=>{if(e&&!V(r.doc,e))return;if(i){let a=i;i=null,a({value:r,done:!1})}else t.push(r)});return{[Symbol.asyncIterator](){return this},next(){if(t.length>0)return Promise.resolve({value:t.shift(),done:!1});if(s)return Promise.resolve({value:void 0,done:!0});return new Promise((r)=>{i=r})},return(){if(s=!0,n(),i){let r=i;i=null,r({value:void 0,done:!0})}return Promise.resolve({value:void 0,done:!0})}}}async count(e={}){return await this._ctx.ensureConnected(),vl(this._findAllRaw(e))}async sum(e,t={}){return await this._ctx.ensureConnected(),El(this._findAllRaw(t),e)}async avg(e,t={}){return await this._ctx.ensureConnected(),Sl(this._findAllRaw(t),e)}async groupBy(e,t={}){return await this._ctx.ensureConnected(),Il(this._findAllRaw(t),e)}async findOne(e,t={}){await this._ctx.ensureConnected();let{populate:i,select:s,includeDeleted:n=!1}=t,r=this._findRaw(e,{includeDeleted:n});if(!r)return null;let a=this._projectDoc(r,s);if(i)await this._populateDoc(a,r,i);return a}async find(e,t={}){await this._ctx.ensureConnected();let i=Date.now(),{populate:s,select:n,sort:r,page:a=1,limit:l,session:o,includeDeleted:c=!1}=t;await this._ctx.plugins.run("beforeFind",{collection:this.name,filter:e,options:t});let h=this._getCandidates(e),u=gl(e,this._fieldIndex?this._fieldIndex.indexedFields:new Set),d=[];for(let f of h){if(this._softDelete&&f._deletedAt&&!c)continue;if(!V(f,u))continue;let p=this._projectDoc(f,n);if(s)await this._populateDoc(p,f,s);d.push(p)}if(r){let f=Object.keys(r);d.sort((p,m)=>{for(let w of f){let x=r[w];if(p[w]<m[w])return-x;if(p[w]>m[w])return x}return 0})}let _;if(l){let f=d.length,p=Math.ceil(f/l),m=(a-1)*l;d=d.slice(m,m+l),_={page:a,totalDocs:f,totalPages:p}}return this._ctx.queryLog?.record({collection:this.name,op:"find",filter:e,duration:Date.now()-i,resultCount:d.length}),this._ctx.sessionStats.recordRead(o),await this._ctx.plugins.run("afterFind",{collection:this.name,filter:e,options:t,docs:d}),_?{docs:d,..._}:{docs:d}}async search(e,{filter:t,limit:i=10,minScore:s=0,session:n}={}){await this._ctx.ensureConnected();let r=Date.now();await this._ctx.plugins.run("beforeSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s}});let a=await this._ctx.embed(e),l=t?this._findAllRaw(t):this._data,o=[];for(let d of l){if(!d._vector)continue;let _=Ds(a,d._vector);if(_>=s)o.push({doc:d,score:_})}o.sort((d,_)=>_.score-d.score);let c=o.slice(0,i);this._ctx.queryLog?.record({collection:this.name,op:"search",query:e,duration:Date.now()-r,resultCount:c.length}),this._ctx.sessionStats.recordRead(n);let h=c.map((d)=>z(d.doc)),u=c.map((d)=>d.score);return await this._ctx.plugins.run("afterSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s},docs:h,scores:u}),{docs:h,scores:u}}async similar(e,{limit:t=10,minScore:i=0}={}){await this._ctx.ensureConnected();let s=this._index.get(e);if(!s||!s._vector)return{docs:[],scores:[]};let n=[];for(let a of this._data){if(a._id===e||!a._vector)continue;let l=Ds(s._vector,a._vector);if(l>=i)n.push({doc:a,score:l})}n.sort((a,l)=>l.score-a.score);let r=n.slice(0,t);return{docs:r.map((a)=>z(a.doc)),scores:r.map((a)=>a.score)}}async deleteOne(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findRaw(e);if(!r)return null;let{docs:a}=await this._deleteCore("soft",[r],e,{save:i,session:s});return z(a[0])}let{docs:n}=await this._deleteCore("hard",null,e,{save:i,session:s});if(n.length===0)return null;return z(n[0])}async deleteMany(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findAllRaw(e);if(r.length===0)return[];let{docs:a}=await this._deleteCore("soft",r,e,{save:i,session:s});return a.map(z)}let{docs:n}=await this._deleteCore("hardMany",null,e,{save:i,session:s});return n.map(z)}async _deleteCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"delete",beforeHook:"beforeDelete",afterHook:"afterDelete",hookPayload:{collection:this.name,filter:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{if(r(),e==="soft"){let o=new Date;for(let c of t)c._deletedAt=o,c.updatedAt=o,this._index.set(c._id,c);return{docs:t}}if(e==="hard"){let o=this._findIndex(i);if(o===-1)return{docs:[]};let c=this._data.splice(o,1)[0];return this._index.delete(c._id),this._removeFromIndex(c),{docs:[c]}}let a=[],l=[];for(let o of this._data)if(V(o,i))a.push(o),this._index.delete(o._id),this._removeFromIndex(o);else l.push(o);return this._data=l,{docs:a}}})}async export(e={},t={}){let{dir:i,name:s,format:n="json"}=t;try{let r=this._data.filter((h)=>V(h,e));if(r.length===0)throw new Ge("ERR_SKALEX_QUERY_EXPORT_EMPTY",`export(): no documents matched the filter in "${this.name}"`,{collection:this.name});let a;if(n==="json")a=JSON.stringify(r,null,2);else{let h=(_)=>{if(_==null)return"";let f=typeof _==="object"?JSON.stringify(_):String(_);return f.includes(",")||f.includes('"')||f.includes(`
39
+ `))!==-1){let i=this._buffer.slice(0,t).trim();if(this._buffer=this._buffer.slice(t+1),i&&this._onMessage){let s;try{s=JSON.parse(i)}catch(n){this.send(Ne(null,Di,"Parse error"));continue}this._onMessage(s).catch(()=>{})}}}),process.stdin.on("end",()=>{process.exit(0)})}stop(){process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),this._started=!1}}var ml={name:"skalex",version:"4.0.0-alpha"},gl="2024-11-05";class Kn{constructor(e,t={}){this._db=e,this._transport=t.transport||"stdio",this._port=t.port||3000,this._host=t.host||"127.0.0.1",this._allowedOrigin=t.allowedOrigin??null,this._maxBodySize=t.maxBodySize??1048576,this._scopes=t.scopes||{"*":["read"]},this._t=null}async listen(){if(this._transport==="http")this._t=new jn({port:this._port,host:this._host,allowedOrigin:this._allowedOrigin,maxBodySize:this._maxBodySize});else this._t=new qn;this._t.onMessage((e)=>this._handleMessage(e)),await this._t.start()}async connect(e){if(this._t=e,this._t.onMessage((t)=>this._handleMessage(t)),typeof this._t.start==="function")await this._t.start()}async close(){if(this._t&&typeof this._t.stop==="function")await this._t.stop();this._t=null}get transport(){return this._transport}get url(){return this._t?.url}async _handleMessage(e){let{msg:t,parseError:i}=typeof e==="string"?fl(e):{msg:e};if(i){this._send(i);return}let{id:s,method:n,params:r}=t;if(s===void 0){if(n==="notifications/initialized")return;return}try{switch(n){case"initialize":this._send(it(s,{protocolVersion:gl,capabilities:{tools:{}},serverInfo:ml}));break;case"tools/list":this._send(it(s,{tools:this._visibleTools()}));break;case"tools/call":await this._handleToolCall(s,r);break;case"ping":this._send(it(s,{}));break;default:this._send(Ne(s,Es,`Method not found: ${n}`))}}catch(a){this._send(Ne(s,_l,a.message||"Internal error"))}}async _handleToolCall(e,t){let i=t?.name,s=t?.arguments??{};if(!i){this._send(Ne(e,ul,"tools/call requires params.name"));return}let n=vs.find((a)=>a.name===i);if(!n){this._send(Ne(e,Es,`Unknown tool: ${i}`));return}let r=s.collection||s.collection_name||null;if(!this._hasScope(r,n.scope)){this._send(it(e,Ss(`Access denied: "${i}" requires "${n.scope}" scope on collection "${r}".`)));return}try{let a=await hl(i,s,this._db);this._send(it(e,pl(JSON.stringify(a,null,2))))}catch(a){this._send(it(e,Ss(a.message||String(a))))}}_visibleTools(){return vs.filter((e)=>{let t=this._scopes["*"];if(t&&(t.includes(e.scope)||t.includes("admin")))return!0;for(let[,i]of Object.entries(this._scopes))if(i.includes(e.scope)||i.includes("admin"))return!0;return!1})}_hasScope(e,t){let i=(s)=>s.includes("admin")||s.includes(t);if(e&&this._scopes[e])return i(this._scopes[e]);if(this._scopes["*"])return i(this._scopes["*"]);return!1}_send(e){this._t?.send(e)}}var vt="migrations",Is=(e)=>JSON.stringify(e,function(t,i){let s=this[t];if(s instanceof Date)return{__skalex_date__:s.toISOString()};if(typeof i==="bigint")return{__skalex_bigint__:i.toString()};return i}),bs=(e)=>JSON.parse(e,(t,i)=>{if(i&&typeof i==="object"){if("__skalex_bigint__"in i)return BigInt(i.__skalex_bigint__);if("__skalex_date__"in i)return new Date(i.__skalex_date__)}return i});class ee{constructor({path:e="./.db",format:t="gz",debug:i=!1,adapter:s,ai:n,encrypt:r,slowQueryLog:a,queryCache:l,memory:o,logger:c,plugins:h,llmAdapter:u,embeddingAdapter:d,regexMaxLength:_,idGenerator:f,serializer:p,deserializer:m,autoSave:w,ttlSweepInterval:x,lenientLoad:R}={}){if(this.dataDirectory=e,this.dataFormat=t,this.debug=i,!ee._errorsAttached)ee.SkalexError=Me,ee.ValidationError=N,ee.UniqueConstraintError=xe,ee.TransactionError=me,ee.PersistenceError=Re,ee.AdapterError=ue,ee.QueryError=Qe,ee._errorsAttached=!0;this._adapterConfig=s??null;let E=s||new An({dir:e,format:t});if(r)E=new $n(E,r.key);if(this.fs=E,this._registry=new Sn(wn),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._migrations=new xn,this._connectPromise=null,this.isConnected=!1,this._aiConfig=n||null,this._encryptConfig=r||null,this._pluginsConfig=Array.isArray(h)?h:null,this._memoryConfig=o||null,this._regexMaxLength=_??500,this._idGenerator=f??null,this._serializer=p??Is,this._deserializer=m??bs,this._autoSave=w??!1,this._txManager=new En,this._ttlSweepInterval=x??0,this._ttlTimer=null,this._logger=c??ps,this._embeddingAdapter=d??(n?Go(n):null),this._aiAdapter=u??(n?Zo(n):null),this._persistence=new vn({adapter:this.fs,serializer:this._serializer,deserializer:this._deserializer,logger:this._logger,debug:this.debug,lenientLoad:R??!1}),this._changeLog=new Cn(this),this._queryCache=new Rn(l||{}),this._eventBus=new kn,this._queryLog=a?new Ln(a):null,this._sessionStats=new Pn,this._plugins=new Mn,Array.isArray(h))for(let A of h)this._plugins.register(A)}async connect(){if(this._connectPromise)return this._connectPromise;return this._connectPromise=this._doConnect(),this._connectPromise}async _doConnect(){try{await this.loadData();let e=this._getMeta();if(e.queryCache)this._queryCache.fromJSON(e.queryCache);if(this._migrations._migrations.length>0){let t=e.appliedVersions||[],i=await this._migrations.run((s)=>this.useCollection(`_migration_${s}`),t);this._saveMeta({appliedVersions:i})}if(this._sweepTtl(),this._ttlSweepInterval>0){if(this._ttlTimer=setInterval(()=>this._sweepTtl(),this._ttlSweepInterval),this._ttlTimer?.unref)this._ttlTimer.unref()}this.isConnected=!0,this._log("> - Connected to the database (\u221A)")}catch(e){throw this._logger(`Error connecting to the database: ${e}`,"error"),e}}async disconnect(){try{if(this._ttlTimer)clearInterval(this._ttlTimer),this._ttlTimer=null;await this.saveData(),this._registry.clear(),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._connectPromise=null,this.isConnected=!1,this._log("> - Disconnected from the database (\u221A)")}catch(e){throw this._logger(`Error disconnecting from the database: ${e}`,"error"),e}}async _ensureConnected(){if(this.isConnected)return;return this.connect()}useCollection(e){return this._registry.get(e,this)}createCollection(e,t={}){return this._registry.create(e,t,this)}_createCollectionStore(e,t={}){this._registry.createStore(e,t)}async renameCollection(e,t){this._registry.rename(e,t),await this.saveData(t),await this.fs.delete(e)}async loadData(){await this._persistence.loadAll(this.collections,{parseSchema:pn,buildIndex:this._registry.buildIndex,IndexEngine:Ct});for(let e in this._collectionInstances){let t=this.collections[e];if(t&&this._collectionInstances[e]._store!==t)this._collectionInstances[e]._store=t}}async saveData(e){await this._persistence.save(this.collections,e)}buildIndex(e,t){return this._registry.buildIndex(e,t)}addMigration(e){this._migrations.add(e)}migrationStatus(){let e=this._getMeta();return this._migrations.status(e.appliedVersions||[])}namespace(e){if(this._adapterConfig)throw new ue("ERR_SKALEX_ADAPTER_NAMESPACE_REQUIRES_FS","namespace() requires the default FsAdapter. When a custom storage adapter is configured, create a separate Skalex instance with your adapter instead.");let t=String(e).replace(/[^a-zA-Z0-9_-]/g,"_");if(!t)throw new N("ERR_SKALEX_VALIDATION_NAMESPACE_ID","namespace: id must contain at least one alphanumeric character",{id:e});return new ee({path:`${this.dataDirectory}/${t}`,format:this.dataFormat,debug:this.debug,ai:this._aiConfig||void 0,encrypt:this._encryptConfig||void 0,slowQueryLog:this._queryLog?{threshold:this._queryLog._threshold,maxEntries:this._queryLog._maxEntries}:void 0,queryCache:this._queryCache?{maxSize:this._queryCache._maxSize,ttl:this._queryCache._ttl}:void 0,plugins:this._pluginsConfig||void 0,memory:this._memoryConfig||void 0,logger:this._logger!==ps?this._logger:void 0,llmAdapter:this._aiAdapter&&!this._aiConfig?this._aiAdapter:void 0,embeddingAdapter:this._embeddingAdapter&&!this._aiConfig?this._embeddingAdapter:void 0,regexMaxLength:this._regexMaxLength!==500?this._regexMaxLength:void 0,idGenerator:this._idGenerator||void 0,serializer:this._serializer!==Is?this._serializer:void 0,deserializer:this._deserializer!==bs?this._deserializer:void 0,autoSave:this._autoSave||void 0,ttlSweepInterval:this._ttlSweepInterval||void 0})}use(e){this._plugins.register(e)}watch(e){return this._eventBus.on("*",e)}sessionStats(e){if(e!==void 0)return this._sessionStats.get(e);return this._sessionStats.all()}get _inTransaction(){return this._txManager.active}_emitEvent(e,t){if(!this._txManager.defer(()=>this._eventBus.emit(e,t)))this._eventBus.emit(e,t)}async _runAfterHook(e,t){if(!this._txManager.defer(()=>this._plugins.run(e,t)))await this._plugins.run(e,t)}async _logChange(e,t,i,s,n){if(!this._txManager.defer(()=>this._changeLog.log(e,t,i,s,n)))await this._changeLog.log(e,t,i,s,n)}async transaction(e,t={}){return this._txManager.run(e,this,t)}async seed(e,{reset:t=!1}={}){for(let[i,s]of Object.entries(e)){if(t&&this.collections[i])this._applySnapshot(i,{data:[],index:new Map}),delete this._collectionInstances[i];await this.useCollection(i).insertMany(s)}await this.saveData()}dump(){return this._registry.dump()}inspect(e){return this._registry.inspect(e)}async import(e){let t=await this.fs.readRaw(e),i;try{i=JSON.parse(t)}catch{throw new Re("ERR_SKALEX_PERSISTENCE_INVALID_JSON",`import: invalid JSON in file "${e}"`,{filePath:e})}let s=e.split("/").pop().replace(/\.[^.]+$/,"");return this.useCollection(s).insertMany(Array.isArray(i)?i:[i],{save:!0})}async embed(e){if(!this._embeddingAdapter)throw new ue("ERR_SKALEX_ADAPTER_EMBEDDING_REQUIRED","db.embed() requires an AI adapter. Pass { ai: { provider, apiKey } } to the Skalex constructor.");return this._embeddingAdapter.embed(e)}async ask(e,t,{limit:i=20}={}){if(!this._aiAdapter)throw new ue("ERR_SKALEX_ADAPTER_LLM_REQUIRED",'db.ask() requires a language model adapter. Configure { ai: { provider, model: "..." } }.');let s=this.useCollection(e),n=this.schema(e),r=this._queryCache.get(e,n,t);if(!r){r=await this._aiAdapter.generate(n,t);let a=cl(r,n);if(a.length)a.forEach((l)=>this._log(`[ask] ${l}`));this._queryCache.set(e,n,t,r),this._saveMeta({queryCache:this._queryCache.toJSON()})}return s.find(ol(r,{regexMaxLength:this._regexMaxLength}),{limit:i})}schema(e){return this._registry.schema(e)}useMemory(e){return new Dn(e,this)}changelog(){return this._changeLog}async restore(e,t,i={}){return this._changeLog.restore(e,t,i)}stats(e){return this._registry.stats(e)}slowQueries(e={}){if(!this._queryLog)return[];return this._queryLog.entries(e)}slowQueryCount(){return this._queryLog?this._queryLog.size:0}clearSlowQueries(){this._queryLog?.clear()}mcp(e={}){return new Kn(this,e)}_getMeta(){let e=this.collections._meta;if(!e)return{};return e.index.get(vt)||{}}_saveMeta(e){if(!this.collections._meta)this._createCollectionStore("_meta");let t=this.collections._meta,i=t.index.get(vt);if(i)Object.assign(i,e);else{let s={_id:vt,...e};t.data.push(s),t.index.set(vt,s)}this._persistence.markDirty(this.collections,"_meta")}_sweepTtl(){for(let e in this.collections){let t=this.collections[e],i=Xo(t.data,t.index,t.fieldIndex?(s)=>t.fieldIndex.remove(s):null);if(i>0)this._persistence.markDirty(this.collections,e),this._log(`TTL sweep: removed ${i} expired docs from "${e}"`)}}_buildCollectionContext(){let e=this;return{ensureConnected:()=>e._ensureConnected(),get txManager(){return e._txManager},get plugins(){return e._plugins},get eventBus(){return e._eventBus},get sessionStats(){return e._sessionStats},get queryLog(){return e._queryLog},get logger(){return e._logger},get persistence(){return e._persistence},get collections(){return e.collections},embed:(t)=>e.embed(t),get idGenerator(){return e._idGenerator},get autoSave(){return e._autoSave},saveCollection:(t)=>e.saveData(t),snapshotCollection:(t)=>e._snapshotCollection(t),getCollection:(t)=>e.useCollection(t),emitEvent:(t,i)=>e._emitEvent(t,i),runAfterHook:(t,i)=>e._runAfterHook(t,i),logChange:(t,i,s,n,r)=>e._logChange(t,i,s,n,r),get fs(){return e.fs},get dataDirectory(){return e.dataDirectory}}}_log(e){if(this.debug)this._logger(e,"info")}_snapshotCollection(e){return{data:structuredClone(e.data)}}_applySnapshot(e,t){let i=this.collections[e];if(!i)return;if(i.data=t.data,i.index=this.buildIndex(t.data,"_id"),i.fieldIndex)i.fieldIndex.buildFromData(t.data)}}function yl(){let e=Date.now().toString(16),t;try{t=Ao.randomBytes(8).toString("hex")}catch{let i=new Uint8Array(8);crypto.getRandomValues(i),t=Array.from(i).map((s)=>s.toString(16).padStart(2,"0")).join("")}return`${e}${t}`}function Ts(e,t){let i=e instanceof Error?e.message:e;if(t==="error")console.error(i);else console.log(i)}var Os=new Set(["__proto__","constructor","prototype"]);function jt(e,t){if(!t.includes(".")){if(Os.has(t))return;return e[t]}let i=e;for(let s of t.split(".")){if(Os.has(s))return;if(i==null)return;i=i[s]}return i}class je extends Error{constructor(e,t,i={}){super(t);this.name=this.constructor.name,this.code=e,this.details=i}}class $ extends je{}class Ee extends je{}class ge extends je{}class ke extends je{}class _e extends je{}class Ge extends je{}function wi(e,t){if(e===t)return!0;if(e==null||t==null)return!1;if(typeof e!==typeof t)return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.source===t.source&&e.flags===t.flags;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!wi(e[i],t[i]))return!1;return!0}if(typeof e==="object"){if(Array.isArray(t))return!1;let i=Object.keys(e);if(i.length!==Object.keys(t).length)return!1;for(let s of i){if(!Object.prototype.hasOwnProperty.call(t,s))return!1;if(!wi(e[s],t[s]))return!1}return!0}return!1}function V(e,t){if(typeof t==="function")return t(e);if(t==null)return!0;if(typeof t==="object"&&Object.keys(t).length===0)return!0;if("$or"in t){let i=t.$or;if(!Array.isArray(i))throw new Ge("ERR_SKALEX_QUERY_INVALID_OPERATOR","$or must be an array of filters",{operator:"$or"});if(!i.some((s)=>V(e,s)))return!1}if("$and"in t){let i=t.$and;if(!Array.isArray(i))throw new Ge("ERR_SKALEX_QUERY_INVALID_OPERATOR","$and must be an array of filters",{operator:"$and"});if(!i.every((s)=>V(e,s)))return!1}if("$not"in t){if(V(e,t.$not))return!1}for(let i in t){if(i==="$or"||i==="$and"||i==="$not")continue;let s=t[i],n;try{n=jt(e,i)}catch{return!1}if(s instanceof RegExp){if(!s.test(String(n)))return!1}else if(typeof s==="object"&&s!==null){if(Object.keys(s).some((r)=>r.startsWith("$"))){if("$eq"in s&&n!==s.$eq)return!1;if("$ne"in s&&n===s.$ne)return!1;if("$gt"in s&&!(n>s.$gt))return!1;if("$lt"in s&&!(n<s.$lt))return!1;if("$gte"in s&&!(n>=s.$gte))return!1;if("$lte"in s&&!(n<=s.$lte))return!1;if("$in"in s&&!s.$in.includes(n))return!1;if("$nin"in s&&s.$nin.includes(n))return!1;if("$regex"in s){if(!(s.$regex instanceof RegExp?s.$regex:new RegExp(s.$regex)).test(String(n)))return!1}if("$fn"in s&&!s.$fn(n))return!1}else if(!wi(n,s))return!1}else if(n!==s)return!1}return!0}function wl(e,t=new Set){if(typeof e!=="object"||e===null||typeof e==="function")return e;let i=[],s=[],n=[],r=[],a=[];for(let o in e){if(o==="$or"||o==="$and"||o==="$not"){a.push(o);continue}let c=e[o];if(t.has(o))i.push(o);else if(c instanceof RegExp||typeof c==="object"&&c!==null&&(("$regex"in c)||("$fn"in c))||typeof c==="function")r.push(o);else if(typeof c==="object"&&c!==null&&(("$gt"in c)||("$lt"in c)||("$gte"in c)||("$lte"in c)||("$ne"in c)||("$in"in c)||("$nin"in c)))n.push(o);else s.push(o)}let l={};for(let o of[...i,...s,...n,...r,...a])l[o]=e[o];return l}var Ai=new Set(["string","number","boolean","object","array","date","any"]);function Ci(e){if(Array.isArray(e))return"array";if(e instanceof Date)return"date";return typeof e}function Fn(e){let t=new Map,i=[];for(let[s,n]of Object.entries(e)){let r;if(typeof n==="string"){if(!Ai.has(n))throw new $("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${n}" for field "${s}"`,{field:s,type:n});r={type:n,required:!1,unique:!1}}else if(typeof n==="object"&&n!==null){let{type:a="any",required:l=!1,unique:o=!1,enum:c}=n;if(!Ai.has(a))throw new $("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${a}" for field "${s}"`,{field:s,type:a});if(r={type:a,required:l,unique:o,enum:c},o)i.push(s)}else throw new $("ERR_SKALEX_VALIDATION_INVALID_SCHEMA",`Invalid schema definition for field "${s}"`,{field:s});t.set(s,r)}return{fields:t,uniqueFields:i}}function Ns(e,t,i=!1){let s=[];for(let[n,r]of t){let a=e[n],l=a===void 0||a===null;if(r.required&&l){s.push(`Field "${n}" is required`);continue}if(l)continue;if(r.type!=="any"){let o=Ci(a);if(o!==r.type)s.push(`Field "${n}" must be of type "${r.type}", got "${o}"`)}if(r.enum&&!r.enum.includes(a))s.push(`Field "${n}" must be one of [${r.enum.map((o)=>JSON.stringify(o)).join(", ")}], got ${JSON.stringify(a)}`)}if(i){for(let n of Object.keys(e))if(!n.startsWith("_")&&!t.has(n))s.push(`Unknown field "${n}" (strict mode)`)}return s}function $s(e,t){let i={};for(let[s,n]of Object.entries(e)){if(s.startsWith("_")){i[s]=n;continue}if(!t.has(s))continue;let r=t.get(s);if(r.type!=="any"){if(Ci(n)!==r.type)continue}if(r.enum&&!r.enum.includes(n))continue;i[s]=n}return i}function Al(e){let t={};for(let[i,s]of Object.entries(e)){if(i.startsWith("_"))continue;let n=Ci(s);t[i]=Ai.has(n)?n:"any"}return t}function xl(e){if(typeof e==="number"){if(e<=0)throw new $("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got ${e}`,{ttl:e});return e*1000}if(typeof e!=="string")throw new $("ERR_SKALEX_VALIDATION_TTL",`Invalid TTL value: ${e}`,{ttl:e});let t=e.match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/);if(!t)throw new $("ERR_SKALEX_VALIDATION_TTL_FORMAT",`Invalid TTL format: "${e}". Use e.g. 300 (seconds), "30m", "24h", "7d"`,{ttl:e});let i=parseFloat(t[1]);if(i<=0)throw new $("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got "${e}"`,{ttl:e});let s=t[2],n=i*{ms:1,s:1000,m:60000,h:3600000,d:86400000}[s];if(!isFinite(n))throw new $("ERR_SKALEX_VALIDATION_TTL",`TTL value "${e}" is too large`,{ttl:e});return n}function vl(e){return new Date(Date.now()+xl(e))}function El(e,t,i=null){let s=Date.now(),n=0,r=e.length;while(r--){let a=e[r];if(a._expiresAt&&new Date(a._expiresAt).getTime()<=s){if(e.splice(r,1),t.delete(a._id),i)i(a);n++}}return n}function Ds(e,t){if(e.length!==t.length)throw new Ge("ERR_SKALEX_QUERY_VECTOR_MISMATCH",`Vector dimension mismatch: ${e.length} vs ${t.length}`,{expected:e.length,got:t.length});let i=0,s=0,n=0;for(let a=0;a<e.length;a++)i+=e[a]*t[a],s+=e[a]*e[a],n+=t[a]*t[a];let r=Math.sqrt(s*n);return r===0?0:i/r}function z(e){if(!("_vector"in e))return{...e};let{_vector:t,...i}=e;return i}function Sl(e){return e.length}function Il(e,t){let i=0;for(let s of e){let n=jt(s,t);if(typeof n==="number"&&!isNaN(n))i+=n}return i}function bl(e,t){let i=0,s=0;for(let n of e){let r=jt(n,t);if(typeof r==="number"&&!isNaN(r))i+=r,s++}return s===0?null:i/s}function Tl(e,t){let i=Object.create(null);for(let s of e){let n=String(jt(s,t)??"__null__");if(!i[n])i[n]=[];i[n].push(s)}return i}class Un{constructor(e){this._col=e}get _ctx(){return this._col._ctx}async execute({op:e,beforeHook:t,afterHook:i,hookPayload:s,mutate:n,afterHookPayload:r,save:a,session:l}){let o=this._ctx;await o.ensureConnected(),this._col._txSnapshotIfNeeded();let c=o.txManager,h=c.active&&this._col._activeTxId===c.context?.id,u=h?c.context.id:null,d=this._col._createdInTxId,_=()=>{if(u!==null&&c._abortedIds.has(u))throw new ge("ERR_SKALEX_TX_ABORTED",`Transaction ${u} was aborted. No further mutations allowed.`);if(d!==null&&c._abortedIds.has(d))throw new ge("ERR_SKALEX_TX_ABORTED",`Transaction ${d} was aborted. Collection obtained inside that transaction cannot be used for further mutations.`)};if(h||d!==null)_();if(t)await o.plugins.run(t,s);let{docs:f,prevDocs:p=[]}=await n(_);if(o.persistence.markDirty(o.collections,this._col.name),await this._col._saveIfNeeded(a),this._col._changelogEnabled)for(let m=0;m<f.length;m++)await o.logChange(e,this._col.name,f[m],p[m]??null,l||null);if(!h||!c.defer(()=>o.sessionStats.recordWrite(l)))o.sessionStats.recordWrite(l);for(let m of f)o.emitEvent(this._col.name,{op:e,collection:this._col.name,doc:z(m)});if(i)if(r)await o.runAfterHook(i,r(f));else for(let m of f)await o.runAfterHook(i,{collection:this._col.name,doc:z(m)});return{docs:f,prevDocs:p}}}function Ol(e){let t={};for(let i in e){if(i.startsWith("$"))continue;let s=e[i];if(s&&typeof s==="object"&&!Array.isArray(s)){let n=Object.keys(s);if(n.length===1&&n[0]==="$eq")t[i]=s.$eq}else t[i]=s}return t}var zn=new Set(["__proto__","constructor","prototype"]);function Bn(e){if(typeof e!=="object"||e===null||Array.isArray(e))return e;let t={};for(let i of Object.keys(e)){if(zn.has(i))continue;t[i]=Bn(e[i])}return t}class Xn{constructor(e,t){this.name=e.collectionName,this.database=t,this._ctx=t._buildCollectionContext(),this._store=e,this._pipeline=new Un(this),this._createdInTxId=t._txManager.context?.id??null,this._activeTxId=null}get _data(){return this._store.data}set _data(e){this._store.data=e}get _index(){return this._store.index}get _fieldIndex(){return this._store.fieldIndex||null}get _schema(){return this._store.schema?this._store.schema.fields:null}get _changelogEnabled(){return this._store.changelog===!0}get _softDelete(){return this._store.softDelete===!0}get _versioning(){return this._store.versioning===!0}get _strict(){return this._store.strict===!0}get _onSchemaError(){return this._store.onSchemaError??"throw"}get _defaultTtl(){return this._store.defaultTtl||null}get _defaultEmbed(){return this._store.defaultEmbed||null}get _maxDocs(){return this._store.maxDocs||null}async insertOne(e,t={}){let{save:i,ifNotExists:s,ttl:n,embed:r,session:a}=t;if(s){await this._ctx.ensureConnected();let o=this._findRaw(e);if(o)return z({...o})}let{docs:l}=await this._insertCore([e],{ttl:n,embed:r,session:a,save:i});return z(l[0])}async insertMany(e,t={}){let{save:i,ttl:s,embed:n,session:r}=t,{docs:a}=await this._insertCore(e,{ttl:s,embed:n,session:r,save:i});return a.map(z)}async _insertCore(e,{ttl:t,embed:i,session:s,save:n}){return this._pipeline.execute({op:"insert",beforeHook:null,afterHook:"afterInsert",hookPayload:null,save:n,session:s,mutate:async(r)=>{let a=[],l=new Set;for(let o of e){let c=this._applyValidation(o);await this._ctx.plugins.run("beforeInsert",{collection:this.name,doc:c});let h=await this._buildDoc(c,{ttl:t,embed:i});if(this._index.has(h._id)||l.has(h._id))throw new Ee("ERR_SKALEX_UNIQUE_DUPLICATE_ID",`Duplicate _id "${h._id}" in collection "${this.name}"`,{id:h._id,collection:this.name});l.add(h._id),a.push(h)}if(r(),this._fieldIndex)this._fieldIndex.assertUniqueBatch(a);for(let o of a)this._addToIndex(o);this._data.push(...a);for(let o of a)this._index.set(o._id,o);return this._enforceCapAfterInsert(),{docs:a}}})}async updateOne(e,t,i={}){await this._ctx.ensureConnected();let s=this._findRaw(e);if(!s)return null;let{save:n,session:r}=i,{docs:a}=await this._updateCore([s],e,t,{save:n,session:r});return z(a[0])}async updateMany(e,t,i={}){await this._ctx.ensureConnected();let s=this._findAllRaw(e);if(s.length===0)return[];let{save:n,session:r}=i,{docs:a}=await this._updateCore(s,e,t,{save:n,session:r});return a.map(z)}async _updateCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"update",beforeHook:"beforeUpdate",afterHook:"afterUpdate",hookPayload:{collection:this.name,filter:t,update:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:t,update:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{let a=this._changelogEnabled?e.map((h)=>structuredClone(h)):e.map(()=>null),l=e.map((h)=>this._prepareUpdatedDoc(h,i));this._assertUniqueCandidates(e,l),r();let o=new Set(e),c=new Map;for(let h=0;h<this._data.length;h++)if(o.has(this._data[h]))c.set(this._data[h],h);for(let h=0;h<e.length;h++)this._commitUpdatedDoc(e[h],l[h],c);return{docs:l,prevDocs:a}}})}applyUpdate(e,t){for(let i in t){if(zn.has(i))continue;if(i==="_id"||i==="createdAt")continue;let s=t[i];if(Array.isArray(s))e[i]=s;else if(typeof s==="object"&&s!==null){let n=Object.keys(s);if(n.some((r)=>r.startsWith("$"))){for(let r of n)if(r==="$inc"&&typeof e[i]==="number")e[i]+=s[r];else if(r==="$push"){if(!Array.isArray(e[i]))e[i]=[];e[i].push(s[r])}}else e[i]=Bn(s)}else e[i]=s}if(e.updatedAt=new Date,this._versioning)e._version=(e._version??0)+1;return e}_prepareUpdatedDoc(e,t){let i=structuredClone(e),s=structuredClone(e);if(this.applyUpdate(s,t),!this._schema)return s;let n=Ns(s,this._schema,this._strict);if(!n.length)return s;switch(this._onSchemaError){case"throw":throw new $("ERR_SKALEX_VALIDATION_UPDATE",`Update validation failed on doc "${e._id}": ${n.join("; ")}`,{id:e._id,errors:n});case"strip":return this._stripCandidateToValid(s,i);default:return this._ctx.logger(`[${this.name}] Update validation warning: ${n.join("; ")}`,"warn"),s}}_stripCandidateToValid(e,t){let i=$s(e,this._schema),s=structuredClone(t);for(let[n,r]of Object.entries(i)){if(n.startsWith("_"))continue;s[n]=r}if(s.updatedAt=e.updatedAt,this._versioning)s._version=e._version;return s}_commitUpdatedDoc(e,t,i){let s=i?i.get(e):this._data.indexOf(e);if(s===void 0||s===-1)throw new ke("ERR_SKALEX_PERSISTENCE_DOC_MISSING",`Document "${e._id}" no longer exists in collection "${this.name}"`,{id:e._id,collection:this.name});this._data[s]=t,this._index.set(t._id,t),this._updateInIndex(e,t)}_assertUniqueCandidates(e,t){this._fieldIndex?.assertUniqueCandidates(e,t)}async upsert(e,t,i={}){if(await this._ctx.ensureConnected(),this._findRaw(e))return this.updateOne(e,t,i);return this.insertOne({...Ol(e),...t},i)}async upsertMany(e,t,i={}){await this._ctx.ensureConnected();let{save:s,...n}=i,r=[];for(let a of e)r.push(await this.upsert({[t]:a[t]},a,{...n,save:!1}));return await this._saveIfNeeded(s),r}async restore(e,t={}){if(!this._softDelete)throw new Ge("ERR_SKALEX_QUERY_SOFT_DELETE_REQUIRED",`restore() requires softDelete on "${this.name}"`,{collection:this.name});await this._ctx.ensureConnected();let{save:i,session:s}=t,n=this._findRaw(e,{includeDeleted:!0});if(!n||!n._deletedAt)return null;let{docs:r}=await this._pipeline.execute({op:"restore",beforeHook:null,afterHook:null,hookPayload:null,save:i,session:s,mutate:async(a)=>{return a(),delete n._deletedAt,n.updatedAt=new Date,this._index.set(n._id,n),{docs:[n]}}});return z(r[0])}watch(e,t){if(typeof e==="function")t=e,e=null;if(t)return this._ctx.eventBus.on(this.name,(i)=>{if(!e||V(i.doc,e))t(i)});return this._watchIterator(e)}_watchIterator(e){let t=[],i=null,s=!1,n=this._ctx.eventBus.on(this.name,(r)=>{if(e&&!V(r.doc,e))return;if(i){let a=i;i=null,a({value:r,done:!1})}else t.push(r)});return{[Symbol.asyncIterator](){return this},next(){if(t.length>0)return Promise.resolve({value:t.shift(),done:!1});if(s)return Promise.resolve({value:void 0,done:!0});return new Promise((r)=>{i=r})},return(){if(s=!0,n(),i){let r=i;i=null,r({value:void 0,done:!0})}return Promise.resolve({value:void 0,done:!0})}}}async count(e={}){return await this._ctx.ensureConnected(),Sl(this._findAllRaw(e))}async sum(e,t={}){return await this._ctx.ensureConnected(),Il(this._findAllRaw(t),e)}async avg(e,t={}){return await this._ctx.ensureConnected(),bl(this._findAllRaw(t),e)}async groupBy(e,t={}){return await this._ctx.ensureConnected(),Tl(this._findAllRaw(t),e)}async findOne(e,t={}){await this._ctx.ensureConnected();let{populate:i,select:s,includeDeleted:n=!1}=t,r=this._findRaw(e,{includeDeleted:n});if(!r)return null;let a=this._projectDoc(r,s);if(i)await this._populateDoc(a,r,i);return a}async find(e,t={}){await this._ctx.ensureConnected();let i=Date.now(),{populate:s,select:n,sort:r,page:a=1,limit:l,session:o,includeDeleted:c=!1}=t;await this._ctx.plugins.run("beforeFind",{collection:this.name,filter:e,options:t});let h=this._getCandidates(e),u=wl(e,this._fieldIndex?this._fieldIndex.indexedFields:new Set),d=[];for(let f of h){if(this._softDelete&&f._deletedAt&&!c)continue;if(!V(f,u))continue;let p=this._projectDoc(f,n);if(s)await this._populateDoc(p,f,s);d.push(p)}if(r){let f=Object.keys(r);d.sort((p,m)=>{for(let w of f){let x=r[w];if(p[w]<m[w])return-x;if(p[w]>m[w])return x}return 0})}let _;if(l){let f=d.length,p=Math.ceil(f/l),m=(a-1)*l;d=d.slice(m,m+l),_={page:a,totalDocs:f,totalPages:p}}return this._ctx.queryLog?.record({collection:this.name,op:"find",filter:e,duration:Date.now()-i,resultCount:d.length}),this._ctx.sessionStats.recordRead(o),await this._ctx.plugins.run("afterFind",{collection:this.name,filter:e,options:t,docs:d}),_?{docs:d,..._}:{docs:d}}async search(e,{filter:t,limit:i=10,minScore:s=0,session:n}={}){await this._ctx.ensureConnected();let r=Date.now();await this._ctx.plugins.run("beforeSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s}});let a=await this._ctx.embed(e),l=t?this._findAllRaw(t):this._data,o=[];for(let d of l){if(!d._vector)continue;let _=Ds(a,d._vector);if(_>=s)o.push({doc:d,score:_})}o.sort((d,_)=>_.score-d.score);let c=o.slice(0,i);this._ctx.queryLog?.record({collection:this.name,op:"search",query:e,duration:Date.now()-r,resultCount:c.length}),this._ctx.sessionStats.recordRead(n);let h=c.map((d)=>z(d.doc)),u=c.map((d)=>d.score);return await this._ctx.plugins.run("afterSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s},docs:h,scores:u}),{docs:h,scores:u}}async similar(e,{limit:t=10,minScore:i=0}={}){await this._ctx.ensureConnected();let s=this._index.get(e);if(!s||!s._vector)return{docs:[],scores:[]};let n=[];for(let a of this._data){if(a._id===e||!a._vector)continue;let l=Ds(s._vector,a._vector);if(l>=i)n.push({doc:a,score:l})}n.sort((a,l)=>l.score-a.score);let r=n.slice(0,t);return{docs:r.map((a)=>z(a.doc)),scores:r.map((a)=>a.score)}}async deleteOne(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findRaw(e);if(!r)return null;let{docs:a}=await this._deleteCore("soft",[r],e,{save:i,session:s});return z(a[0])}let{docs:n}=await this._deleteCore("hard",null,e,{save:i,session:s});if(n.length===0)return null;return z(n[0])}async deleteMany(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findAllRaw(e);if(r.length===0)return[];let{docs:a}=await this._deleteCore("soft",r,e,{save:i,session:s});return a.map(z)}let{docs:n}=await this._deleteCore("hardMany",null,e,{save:i,session:s});return n.map(z)}async _deleteCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"delete",beforeHook:"beforeDelete",afterHook:"afterDelete",hookPayload:{collection:this.name,filter:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{if(r(),e==="soft"){let o=new Date;for(let c of t)c._deletedAt=o,c.updatedAt=o,this._index.set(c._id,c);return{docs:t}}if(e==="hard"){let o=this._findIndex(i);if(o===-1)return{docs:[]};let c=this._data.splice(o,1)[0];return this._index.delete(c._id),this._removeFromIndex(c),{docs:[c]}}let a=[],l=[];for(let o of this._data)if(V(o,i))a.push(o),this._index.delete(o._id),this._removeFromIndex(o);else l.push(o);return this._data=l,{docs:a}}})}async export(e={},t={}){let{dir:i,name:s,format:n="json"}=t;try{let r=this._data.filter((h)=>V(h,e));if(r.length===0)throw new Ge("ERR_SKALEX_QUERY_EXPORT_EMPTY",`export(): no documents matched the filter in "${this.name}"`,{collection:this.name});let a;if(n==="json")a=JSON.stringify(r,null,2);else{let h=(_)=>{if(_==null)return"";let f=typeof _==="object"?JSON.stringify(_):String(_);return f.includes(",")||f.includes('"')||f.includes(`
40
40
  `)||f.includes("\r")?`"${f.replace(/"/g,'""')}"`:f},u=Object.keys(r[0]).map(h).join(","),d=r.map((_)=>Object.values(_).map(h).join(","));a=[u,...d].join(`
41
- `)}if(typeof this._ctx.fs.writeRaw!=="function")throw new _e("ERR_SKALEX_ADAPTER_NO_RAW_WRITE","export() requires a file-system adapter (FsAdapter). The current adapter does not support raw file writes.");let l=i||`${this._ctx.dataDirectory}/exports`,o=`${s||this.name}.${n}`,c=this._ctx.fs.join(l,o);this._ctx.fs.ensureDir(l),await this._ctx.fs.writeRaw(c,a)}catch(r){throw this._ctx.logger(`Error exporting "${this.name}": ${r.message}`,"error"),r}}_txSnapshotIfNeeded(){let e=this._ctx.txManager;if(!e.active)return;if(this._activeTxId!==e.context?.id)return;e.snapshotIfNeeded(this.name,this._store,(t)=>this._ctx.snapshotCollection(t))}async _saveIfNeeded(e){let t=this._ctx.txManager;if(t.active&&this._activeTxId===t.context?.id)return;if(e??this._ctx.autoSave)await this._ctx.saveCollection(this.name)}_applyValidation(e){if(!this._schema)return e;let t=Ns(e,this._schema,this._strict);if(!t.length)return e;switch(this._onSchemaError){case"warn":return this._ctx.logger(`[${this.name}] Validation warning: ${t.join("; ")}`,"warn"),e;case"strip":return $s(e,this._schema);default:throw new $("ERR_SKALEX_VALIDATION_FAILED",`Validation failed: ${t.join("; ")}`,{errors:t})}}_enforceCapAfterInsert(){let e=this._maxDocs;if(!e||this._data.length<=e)return;let t=this._data.splice(0,this._data.length-e);for(let i of t)this._index.delete(i._id),this._removeFromIndex(i)}_findRaw(e,{includeDeleted:t=!1}={}){if(typeof e==="function"){for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(e(i))return i}return null}if(e._id){let i=this._index.get(e._id)||null;if(!i)return null;if(this._softDelete&&i._deletedAt&&!t)return null;if(Object.keys(e).length>1)return V(i,e)?i:null;return i}if(this._fieldIndex)for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null){let n=this._fieldIndex._lookupIterable(i,s);if(n!==null){for(let r of n){if(this._softDelete&&r._deletedAt&&!t)continue;if(V(r,e))return r}return null}}}for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(V(i,e))return i}return null}_findAllRaw(e,{includeDeleted:t=!1}={}){if(e&&typeof e!=="function"&&e._id){let s=this._index.get(e._id);if(!s)return[];if(this._softDelete&&s._deletedAt&&!t)return[];return V(s,e)?[s]:[]}let i=[];for(let s of this._getCandidates(e)){if(this._softDelete&&s._deletedAt&&!t)continue;if(V(s,e))i.push(s)}return i}_getCandidates(e){if(!this._fieldIndex)return this._data;if(this._fieldIndex._compoundIndexes.size>0){let t={};for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null)t[i]=s}if(Object.keys(t).length>=2){let i=this._fieldIndex.lookupCompound(t);if(i!==null)return i}}for(let t in e){if(t==="$or"||t==="$and"||t==="$not")continue;let i=e[t];if(typeof i!=="object"||i===null){let s=this._fieldIndex._lookupIterable(t,i);if(s!==null)return s}}return this._data}_findIndex(e){for(let t=0;t<this._data.length;t++)if(V(this._data[t],e))return t;return-1}_addToIndex(e){if(this._fieldIndex)this._fieldIndex.add(e)}_removeFromIndex(e){if(this._fieldIndex)this._fieldIndex.remove(e)}_updateInIndex(e,t){if(this._fieldIndex)this._fieldIndex.update(e,t)}async _buildDoc(e,{ttl:t,embed:i}={}){let s={...e,_id:e._id??(this._ctx.idGenerator??ml)(),createdAt:new Date,updatedAt:new Date},n=t??this._defaultTtl;if(n)s._expiresAt=Al(n);let r=i??this._defaultEmbed;if(r){let a=typeof r==="function"?r(s):s[r];s._vector=await this._ctx.embed(String(a))}if(this._versioning)s._version=1;return s}_projectDoc(e,t){if(t){let s={};for(let n of t){if(n==="_vector")continue;s[n]=e[n]}return s}let i={...e};return delete i._vector,i}async _populateDoc(e,t,i){for(let s of i){let n=await this._ctx.getCollection(s).findOne({_id:t[s]});if(n)e[s]=n}}}class Ri{async read(e){throw Error("StorageAdapter.read() not implemented")}async write(e,t){throw Error("StorageAdapter.write() not implemented")}async delete(e){throw Error("StorageAdapter.delete() not implemented")}async list(){throw Error("StorageAdapter.list() not implemented")}async writeAll(e){for(let{name:t,data:i}of e)await this.write(t,i)}}class Hn extends Ri{constructor({dir:e,format:t="gz"}){super();this.dir=Be.resolve(e),this.format=t,this._ensureDir(this.dir)}_ensureDir(e){if(!q.existsSync(e))q.mkdirSync(e,{recursive:!0})}_filePath(e){return Be.join(this.dir,`${e}.${this.format}`)}async read(e){let t=this._filePath(e);try{let i=await q.promises.readFile(t);if(this.format==="gz")i=ai.inflateSync(i);return i.toString("utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async write(e,t){let i=this._filePath(e),s=Be.join(this.dir,`${e}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let n=ai.deflateSync(t);await q.promises.writeFile(s,n)}else await q.promises.writeFile(s,t,"utf8");await q.promises.rename(s,i)}async writeAll(e){let t=[];try{for(let{name:i,data:s}of e){let n=this._filePath(i),r=Be.join(this.dir,`${i}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let a=ai.deflateSync(s);await q.promises.writeFile(r,a)}else await q.promises.writeFile(r,s,"utf8");t.push({tmp:r,fp:n})}for(let{tmp:i,fp:s}of t)await q.promises.rename(i,s)}catch(i){for(let{tmp:s}of t)try{await q.promises.unlink(s)}catch{}throw i}}async delete(e){let t=this._filePath(e);try{await q.promises.unlink(t)}catch(i){if(i.code!=="ENOENT")throw i}}async list(){try{let e=await q.promises.readdir(this.dir),t=`.${this.format}`;return e.filter((i)=>i.endsWith(t)&&!i.includes(".tmp.")).map((i)=>i.slice(0,-t.length))}catch(e){if(e.code==="ENOENT")return[];throw e}}join(...e){return Be.join(...e)}ensureDir(e){this._ensureDir(e)}async writeRaw(e,t){this._ensureDir(Be.dirname(e)),await q.promises.writeFile(e,t,"utf8")}async readRaw(e){return q.promises.readFile(Be.resolve(e),"utf8")}}class Vn{constructor(){this._migrations=[]}add(e){let{version:t,up:i}=e;if(typeof t!=="number"||t<1)throw new $("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version must be a positive integer, got ${t}`,{version:t});if(typeof i!=="function")throw new $("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version ${t} must have an "up" function`,{version:t});if(this._migrations.some((s)=>s.version===t))throw new $("ERR_SKALEX_VALIDATION_MIGRATION_DUPLICATE",`Migration version ${t} is already registered`,{version:t});this._migrations.push({...e}),this._migrations.sort((s,n)=>s.version-n.version)}async run(e,t=[]){let i=new Set(t),s=this._migrations.filter((n)=>!i.has(n.version));for(let n of s){let r=e(n.version);await n.up(r),i.add(n.version)}return[...i].sort((n,r)=>n-r)}status(e=[]){let t=new Set(e),i=this._migrations.map((s)=>s.version).filter((s)=>!t.has(s));return{current:e.length?Math.max(...e):0,applied:[...t].sort((s,n)=>s-n),pending:i}}}var Cs={[Symbol.iterator](){return{next(){return{done:!0}}}},size:0};function Rs(e){return{[Symbol.iterator](){return e[Symbol.iterator]()},get size(){return e.size}}}function di(e){return e.map((t)=>{if(t===null||t===void 0)return"\x00";if(typeof t==="boolean")return t?"\x01T":"\x01F";if(typeof t==="number")return`\x02${t}`;return`\x03${String(t)}`}).join("\x1F")}class Rt{constructor(e=[],t=[]){this._fields=new Set,this._compoundFields=[];for(let i of e)if(Array.isArray(i)){for(let s of i)this._validateFieldName(s);this._compoundFields.push(i)}else this._validateFieldName(i),this._fields.add(i);for(let i of t)this._validateFieldName(i);this._uniqueFields=new Set(t),this._indexedFields=new Set([...this._fields,...this._uniqueFields]),this._fieldIndexes=new Map,this._uniqueIndexes=new Map;for(let i of this._fields)this._fieldIndexes.set(i,new Map);for(let i of this._uniqueFields)if(this._uniqueIndexes.set(i,new Map),!this._fieldIndexes.has(i))this._fieldIndexes.set(i,new Map);this._compoundIndexes=new Map;for(let i of this._compoundFields)this._compoundIndexes.set(i.join("\x00"),{fields:i,map:new Map})}get indexedFields(){return this._indexedFields}buildFromData(e){for(let[,t]of this._fieldIndexes)t.clear();for(let[,t]of this._uniqueIndexes)t.clear();for(let[,t]of this._compoundIndexes)t.map.clear();for(let t of e)this._indexDoc(t)}add(e){this._checkUnique(e,null),this._indexDoc(e)}remove(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){let n=i.get(s);if(n){if(n.delete(e),n.size===0)i.delete(s)}}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.delete(s)}for(let[,t]of this._compoundIndexes){let i=di(t.fields.map((n)=>e[n])),s=t.map.get(i);if(s){if(s.delete(e),s.size===0)t.map.delete(i)}}}update(e,t){this._checkUnique(t,e),this.remove(e);try{this._indexDoc(t)}catch(i){try{this._indexDoc(e)}catch{}throw i}}lookup(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?[...s]:[]}_lookupIterable(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?Rs(s):Cs}lookupCompound(e){let t=Object.keys(e).sort();for(let[,i]of this._compoundIndexes){let s=[...i.fields].sort();if(s.length!==t.length)continue;if(s.every((n,r)=>n===t[r])){let n=di(i.fields.map((a)=>e[a])),r=i.map.get(n);return r?Rs(r):Cs}}return null}isUniqueTaken(e,t){let i=this._uniqueIndexes.get(e);if(!i)return!1;return i.has(t)}assertUniqueCandidates(e,t){if(this._uniqueFields.size===0)return;let i=new Set(e.map((s)=>s._id));for(let s of this._uniqueFields){let n=new Set,r=this._uniqueIndexes.get(s);if(r){for(let[l,o]of r.entries())if(!i.has(o._id))n.add(l)}let a=new Map;for(let l=0;l<t.length;l++){let o=t[l][s];if(o===void 0)continue;if(n.has(o))throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});let c=a.get(o);if(c&&c!==e[l]._id)throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});a.set(o,e[l]._id)}}}assertUniqueBatch(e){if(this._uniqueFields.size===0)return;for(let t of this._uniqueFields){let i=this._uniqueIndexes.get(t),s=new Set;for(let n of e){let r=n[t];if(r===void 0)continue;if(i&&i.has(r))throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${t}" value "${r}" already exists`,{field:t,value:r});if(s.has(r))throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: duplicate "${t}" value "${r}" within batch`,{field:t,value:r});s.add(r)}}}_validateFieldName(e){if(e.includes("."))throw new $("ERR_SKALEX_VALIDATION_INDEX_DOT_PATH",`Index fields cannot use dot-notation: "${e}". Use a flat field name.`,{field:e})}_indexDoc(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){if(!i.has(s))i.set(s,new Set);i.get(s).add(e)}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.set(s,e)}for(let[,t]of this._compoundIndexes){for(let s of t.fields){let n=e[s];if(n!==void 0&&n!==null&&typeof n==="object")throw new $("ERR_SKALEX_VALIDATION_COMPOUND_INDEX",`Compound index field "${s}" must be a scalar value (string, number, or boolean), got ${Array.isArray(n)?"array":typeof n}`,{field:s})}let i=di(t.fields.map((s)=>e[s]));if(!t.map.has(i))t.map.set(i,new Set);t.map.get(i).add(e)}}_checkUnique(e,t){for(let i of this._uniqueFields){let s=e[i];if(s===void 0)continue;let n=this._uniqueIndexes.get(i);if(!n)continue;let r=n.get(s);if(r&&r._id!==t?._id)throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${i}" value "${s}" already exists`,{field:i,value:s})}}}var Et="_flush",St="migrations";class Jn{constructor({adapter:e,serializer:t,deserializer:i,logger:s,debug:n=!1,lenientLoad:r=!1}){this._adapter=e,this._serializer=t,this._deserializer=i,this._logger=s,this._debug=n,this._lenientLoad=r,this._saveLock=Promise.resolve()}_withSaveLock(e){let t=this._saveLock.then(e);return this._saveLock=t.catch(()=>{}),t}async loadAll(e,{parseSchema:t,buildIndex:i,IndexEngine:s}){try{let n=await this._adapter.list();await Promise.all(n.map(async(r)=>{try{let a=await this._adapter.read(r);if(!a)return;let l=this._deserializer(a),{collectionName:o,data:c}=l;if(!o)return;let h=e[o],u=h?.rawSchema??l.rawSchema??null,d=h?.schema??(u?t(u):null),_=h?.changelog??l.changelog??!1,f=h?.softDelete??l.softDelete??!1,p=h?.versioning??l.versioning??!1,m=h?.strict??l.strict??!1,w=h?.onSchemaError??l.onSchemaError??"throw",x=h?.defaultTtl??l.defaultTtl??null,R=h?.defaultEmbed??l.defaultEmbed??null,E=h?.maxDocs??l.maxDocs??null,A=h?h.fieldIndex:null;if(!A&&d?.uniqueFields?.length)A=new s([],d.uniqueFields);let Ue=i(c,"_id");if(A)A.buildFromData(c);e[o]={collectionName:o,data:c,index:Ue,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:d,rawSchema:u,fieldIndex:A,changelog:_,softDelete:f,versioning:p,strict:m,onSchemaError:w,defaultTtl:x,defaultEmbed:R,maxDocs:E}}catch(a){if(a.code==="ENOENT")return;if(this._lenientLoad){this._logger(`WARNING: Could not load collection "${r}": ${a.message}. Collection will be empty.`,"error");return}throw new ke("ERR_SKALEX_PERSISTENCE_CORRUPT",`Failed to load collection "${r}": ${a.message}`,{collection:r})}})),this._detectIncompleteFlush(e),await this._cleanOrphanTempFiles()}catch(n){if(n.code!=="ENOENT")throw this._logger(`Error loading data: ${n}`,"error"),n}}async save(e,t){if(t)await this._saveOne(e,t);else await Promise.all(Object.keys(e).map((i)=>this._saveOne(e,i)))}async saveDirty(e){let t=Object.keys(e).filter((i)=>e[i]._dirty);if(t.length===0)return;await Promise.all(t.map((i)=>this._saveOne(e,i)))}saveAtomic(e,t){return this._withSaveLock(async()=>{if(t.length===0)return;this._writeFlushSentinel(e,t);let i=new Set(t);i.add("_meta");let s=[...i].filter((n)=>e[n]).map((n)=>({name:n,data:this._serializeCollection(e[n])}));try{await this._adapter.writeAll(s)}catch(n){throw new ke("ERR_SKALEX_PERSISTENCE_FLUSH_FAILED",`Batch save failed during writeAll: ${n.message}`,{collections:t})}for(let n of t)if(e[n])e[n]._dirty=!1;try{this._clearFlushSentinel(e),await this._adapter.write("_meta",this._serializeCollection(e._meta))}catch(n){this._logger(`WARNING: Batch data committed but sentinel clear failed: ${n.message}. Next load will report an incomplete flush (false positive).`,"error")}})}markDirty(e,t){let i=e[t];if(i)i._dirty=!0}_serializeCollection(e){let t={collectionName:e.collectionName,data:e.data};if(e.rawSchema)t.rawSchema=e.rawSchema;if(e.changelog)t.changelog=e.changelog;if(e.softDelete)t.softDelete=e.softDelete;if(e.versioning)t.versioning=e.versioning;if(e.strict)t.strict=e.strict;if(e.onSchemaError!=="throw")t.onSchemaError=e.onSchemaError;if(e.defaultTtl)t.defaultTtl=e.defaultTtl;if(e.defaultEmbed)t.defaultEmbed=e.defaultEmbed;if(e.maxDocs)t.maxDocs=e.maxDocs;return this._serializer(t)}async _saveOne(e,t){let i=e[t];if(!i)return;if(i.isSaving)return i._pendingSave=!0,new Promise((s,n)=>{(i._saveWaiters??=[]).push({resolve:s,reject:n})});i.isSaving=!0,i._pendingSave=!1;try{await this._writeCollection(t,i);while(i._pendingSave)i._pendingSave=!1,await this._writeCollection(t,i);this._resolveSaveWaiters(i)}catch(s){throw this._rejectSaveWaiters(i,s),s}finally{i.isSaving=!1}}async _writeCollection(e,t){try{await this._adapter.write(e,this._serializeCollection(t)),t._dirty=!1}catch(i){throw this._logger(`Error saving "${e}": ${i.message}`,"error"),i}}_resolveSaveWaiters(e){let t=e._saveWaiters?.splice(0)??[];for(let i of t)i.resolve()}_rejectSaveWaiters(e,t){let i=e._saveWaiters?.splice(0)??[];for(let s of i)s.reject(t)}_writeFlushSentinel(e,t){let i=this._getOrCreateMeta(e);i[Et]={startedAt:new Date().toISOString(),collections:t,completedAt:null}}_clearFlushSentinel(e){let t=this._getOrCreateMeta(e);if(t[Et])t[Et].completedAt=new Date().toISOString()}_detectIncompleteFlush(e){let t=e._meta;if(!t)return;let i=t.index.get(St);if(!i)return;let s=i[Et];if(!s)return;if(s.startedAt&&!s.completedAt)this._logger(`WARNING: Incomplete flush detected (started ${s.startedAt}, collections: ${s.collections?.join(", ")}). Data may be inconsistent.`,"error")}async _cleanOrphanTempFiles(){if(typeof this._adapter.join!=="function")return;if(typeof this._adapter.list!=="function")return;try{let e=await import("fs"),t=await import("path"),i=this._adapter.dir;if(!i)return;let s=(await e.default.promises.readdir(i)).filter((n)=>n.includes(".tmp."));for(let n of s){let r=t.default.join(i,n);try{await e.default.promises.unlink(r),this._log(`Cleaned orphan temp file: ${n}`)}catch{}}}catch{}}_getOrCreateMeta(e){if(!e._meta)e._meta={collectionName:"_meta",data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:null,rawSchema:null,fieldIndex:null,changelog:!1,softDelete:!1,versioning:!1,strict:!1,onSchemaError:"throw",defaultTtl:null,defaultEmbed:null,maxDocs:null};let t=e._meta,i=t.index.get(St);if(!i)i={_id:St},t.data.push(i),t.index.set(St,i);return i}_log(e){if(this._debug)this._logger(e,"info")}}var Tl=0;class Yn{constructor(){this._txLock=Promise.resolve(),this._ctx=null,this._abortedIds=new Set}get active(){return this._ctx!==null&&!this._ctx.aborted}get context(){return this._ctx}async run(e,t,{timeout:i=0}={}){let s=async()=>{await t._ensureConnected();let r=new Set(Object.keys(t.collections)),a={id:++Tl,startedAt:Date.now(),aborted:!1,preExisting:r,touchedCollections:new Set,snapshots:new Map,deferredEffects:[],timeout:i};this._ctx=a;let l=null,o=i>0?new Promise((u,d)=>{l=setTimeout(()=>{a.aborted=!0,d(new ge("ERR_SKALEX_TX_TIMEOUT",`Transaction ${a.id} timed out after ${i}ms`))},i)}):null,c=this,h=new Proxy(t,{get(u,d){if(d==="_txId")return a.id;if(a!==c._ctx)throw new ge("ERR_SKALEX_TX_STALE_PROXY",`Transaction ${a.id} has ended. This proxy is no longer usable.`);if(d==="collections")throw new ge("ERR_SKALEX_TX_DIRECT_ACCESS","Direct access to db.collections inside transaction() is not covered by rollback. Use the collection API (db.useCollection) instead.");if(d==="useCollection")return(f)=>{let p=u.useCollection(f);return p._activeTxId=a.id,p};let _=Reflect.get(u,d);return typeof _==="function"?_.bind(u):_}});try{let u=e(h),d=o?await Promise.race([u,o]):await u;if(a.aborted)throw new ge("ERR_SKALEX_TX_ABORTED",`Transaction ${a.id} was aborted`);let _=[...a.touchedCollections];if(_.length>0)await t._persistence.saveAtomic(t.collections,_);for(let f of a.deferredEffects)await f();return d}catch(u){for(let[d,_]of a.snapshots)if(a.preExisting.has(d)){if(t._applySnapshot(d,_),t.collections[d])t.collections[d]._dirty=_._dirty}for(let d in t.collections)if(!a.preExisting.has(d))delete t.collections[d],delete t._collectionInstances[d];throw u}finally{if(l)clearTimeout(l);if(a.aborted)this._abortedIds.add(a.id);this._ctx=null;for(let u in t._collectionInstances){let d=t._collectionInstances[u];if(d._createdInTxId===a.id)d._createdInTxId=null;if(d._activeTxId===a.id)d._activeTxId=null}}},n=this._txLock.then(s);return this._txLock=n.catch(()=>{}),n}snapshotIfNeeded(e,t,i){let s=this._ctx;if(!s)return;if(this._assertCtxNotAborted(s),!s.snapshots.has(e)){let n=i(t);n._dirty=t._dirty??!1,s.snapshots.set(e,n)}s.touchedCollections.add(e)}assertNotAborted(){let e=this._ctx;if(e)this._assertCtxNotAborted(e)}_assertCtxNotAborted(e){if(e.aborted)throw new ge("ERR_SKALEX_TX_ABORTED",`Transaction ${e.id} was aborted. No further mutations allowed.`)}defer(e){if(this._ctx)return this._ctx.deferredEffects.push(e),!0;return!1}}class Wn{constructor(e){this._CollectionClass=e,this.stores={},this._instances={}}get(e,t){if(this._instances[e])return this._instances[e];if(!this.stores[e])this.createStore(e);let i=new this._CollectionClass(this.stores[e],t);return this._instances[e]=i,i}create(e,t={},i){this.createStore(e,t);let s=new this._CollectionClass(this.stores[e],i);return this._instances[e]=s,s}createStore(e,{schema:t,indexes:i=[],changelog:s=!1,softDelete:n=!1,versioning:r=!1,strict:a=!1,onSchemaError:l="throw",defaultTtl:o=null,defaultEmbed:c=null,maxDocs:h=null}={}){let u=null,d=null;if(t){u=Fn(t);let _=u.uniqueFields;if(i.length||_.length)d=new Rt(i,_)}else if(i.length)d=new Rt(i,[]);this.stores[e]={collectionName:e,data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:u,rawSchema:t||null,fieldIndex:d,changelog:s,softDelete:n,versioning:r,strict:a,onSchemaError:l,defaultTtl:o,defaultEmbed:c,maxDocs:h}}rename(e,t){if(!this.stores[e])throw new ke("ERR_SKALEX_PERSISTENCE_COLLECTION_NOT_FOUND",`Collection "${e}" not found`,{collection:e});if(this.stores[t])throw new ke("ERR_SKALEX_PERSISTENCE_COLLECTION_EXISTS",`Collection "${t}" already exists`,{collection:t});let i=this.stores[e];if(i.collectionName=t,this.stores[t]=i,delete this.stores[e],this._instances[e]){let s=this._instances[e];s.name=t,this._instances[t]=s,delete this._instances[e]}}buildIndex(e,t){let i=new Map;for(let s of e)i.set(s[t],s);return i}inspect(e){if(e){let i=this.stores[e];if(!i)return null;return{name:e,count:i.data.length,schema:i.schema?Object.fromEntries(i.schema.fields):null,indexes:i.fieldIndex?[...i.fieldIndex.indexedFields]:[],softDelete:i.softDelete??!1,versioning:i.versioning??!1,strict:i.strict??!1,onSchemaError:i.onSchemaError??"throw",maxDocs:i.maxDocs??null}}let t={};for(let i in this.stores)t[i]=this.inspect(i);return t}dump(){let e={};for(let t in this.stores)if(!t.startsWith("_"))e[t]=structuredClone(this.stores[t].data);return e}schema(e){let t=this.stores[e];if(!t)return null;if(t.schema)return Object.fromEntries([...t.schema.fields.entries()].map(([i,s])=>[i,s.type]));if(t.data.length>0)return yl(t.data[0]);return null}stats(e){let t=(i)=>{let s=this.stores[i];if(!s)return null;let n=s.data.length,r=0;for(let a of s.data)try{r+=JSON.stringify(a).length}catch(l){}return{collection:i,count:n,estimatedSize:r,avgDocSize:n>0?Math.round(r/n):0}};if(e)return t(e);return Object.keys(this.stores).map(t)}clear(){this.stores={},this._instances={}}}class ki{async embed(e){throw Error("EmbeddingAdapter.embed() not implemented")}}var ce=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Qn extends ki{constructor({apiKey:e=ce("OPENAI_API_KEY"),model:t=ce("OPENAI_EMBED_MODEL")??"text-embedding-3-small",baseUrl:i=ce("OPENAI_EMBED_BASE_URL")??"https://api.openai.com/v1/embeddings",dimensions:s=ce("OPENAI_EMBED_DIMENSIONS")!=null?Number(ce("OPENAI_EMBED_DIMENSIONS")):void 0,organization:n=ce("OPENAI_ORGANIZATION")??void 0,timeout:r=ce("OPENAI_EMBED_TIMEOUT")!=null?Number(ce("OPENAI_EMBED_TIMEOUT")):void 0,retries:a=Number(ce("OPENAI_EMBED_RETRIES")??0),retryDelay:l=Number(ce("OPENAI_EMBED_RETRY_DELAY")??1000),headers:o={},fetch:c=globalThis.fetch}={}){super();if(!e)throw Error("OpenAIEmbeddingAdapter requires an apiKey");this.apiKey=e,this.model=t,this.baseUrl=i,this.dimensions=s,this.organization=n,this.timeout=r,this.retries=a,this.retryDelay=l,this.headers=o,this._fetch=c}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(this.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...this.organization&&{"OpenAI-Organization":this.organization},...this.headers},body:JSON.stringify({input:e,model:this.model,...this.dimensions!==void 0&&{dimensions:this.dimensions}}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`OpenAI embedding API error ${r.status}: ${a}`)}return(await r.json()).data[0].embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}var st=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Gn extends ki{constructor({model:e=st("OLLAMA_EMBED_MODEL")??"nomic-embed-text",host:t=st("OLLAMA_HOST")??"http://localhost:11434",timeout:i=st("OLLAMA_EMBED_TIMEOUT")!=null?Number(st("OLLAMA_EMBED_TIMEOUT")):void 0,retries:s=Number(st("OLLAMA_EMBED_RETRIES")??0),retryDelay:n=Number(st("OLLAMA_EMBED_RETRY_DELAY")??1000),headers:r={},fetch:a=globalThis.fetch}={}){super();this.model=e,this.host=t,this.timeout=i,this.retries=s,this.retryDelay=n,this.headers=r,this._fetch=a}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({model:this.model,prompt:e}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama embedding API error ${r.status}: ${a}`)}return(await r.json()).embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}class qt{async generate(e,t){throw Error("LLMAdapter.generate() not implemented")}async summarize(e){throw Error("LLMAdapter.summarize() not implemented")}}var Li=`You are a database query assistant. Convert the user's natural language request into a JSON filter object for a document database.
41
+ `)}if(typeof this._ctx.fs.writeRaw!=="function")throw new _e("ERR_SKALEX_ADAPTER_NO_RAW_WRITE","export() requires a file-system adapter (FsAdapter). The current adapter does not support raw file writes.");let l=i||`${this._ctx.dataDirectory}/exports`,o=`${s||this.name}.${n}`,c=this._ctx.fs.join(l,o);this._ctx.fs.ensureDir(l),await this._ctx.fs.writeRaw(c,a)}catch(r){throw this._ctx.logger(`Error exporting "${this.name}": ${r.message}`,"error"),r}}_txSnapshotIfNeeded(){let e=this._ctx.txManager;if(!e.active)return;if(this._activeTxId!==e.context?.id)return;e.snapshotIfNeeded(this.name,this._store,(t)=>this._ctx.snapshotCollection(t))}async _saveIfNeeded(e){let t=this._ctx.txManager;if(t.active&&this._activeTxId===t.context?.id)return;if(e??this._ctx.autoSave)await this._ctx.saveCollection(this.name)}_applyValidation(e){if(!this._schema)return e;let t=Ns(e,this._schema,this._strict);if(!t.length)return e;switch(this._onSchemaError){case"warn":return this._ctx.logger(`[${this.name}] Validation warning: ${t.join("; ")}`,"warn"),e;case"strip":return $s(e,this._schema);default:throw new $("ERR_SKALEX_VALIDATION_FAILED",`Validation failed: ${t.join("; ")}`,{errors:t})}}_enforceCapAfterInsert(){let e=this._maxDocs;if(!e||this._data.length<=e)return;let t=this._data.splice(0,this._data.length-e);for(let i of t)this._index.delete(i._id),this._removeFromIndex(i)}_findRaw(e,{includeDeleted:t=!1}={}){if(typeof e==="function"){for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(e(i))return i}return null}if(e._id){let i=this._index.get(e._id)||null;if(!i)return null;if(this._softDelete&&i._deletedAt&&!t)return null;if(Object.keys(e).length>1)return V(i,e)?i:null;return i}if(this._fieldIndex)for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null){let n=this._fieldIndex._lookupIterable(i,s);if(n!==null){for(let r of n){if(this._softDelete&&r._deletedAt&&!t)continue;if(V(r,e))return r}return null}}}for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(V(i,e))return i}return null}_findAllRaw(e,{includeDeleted:t=!1}={}){if(e&&typeof e!=="function"&&e._id){let s=this._index.get(e._id);if(!s)return[];if(this._softDelete&&s._deletedAt&&!t)return[];return V(s,e)?[s]:[]}let i=[];for(let s of this._getCandidates(e)){if(this._softDelete&&s._deletedAt&&!t)continue;if(V(s,e))i.push(s)}return i}_getCandidates(e){if(!this._fieldIndex)return this._data;if(this._fieldIndex._compoundIndexes.size>0){let t={};for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null)t[i]=s}if(Object.keys(t).length>=2){let i=this._fieldIndex.lookupCompound(t);if(i!==null)return i}}for(let t in e){if(t==="$or"||t==="$and"||t==="$not")continue;let i=e[t];if(typeof i!=="object"||i===null){let s=this._fieldIndex._lookupIterable(t,i);if(s!==null)return s}}return this._data}_findIndex(e){for(let t=0;t<this._data.length;t++)if(V(this._data[t],e))return t;return-1}_addToIndex(e){if(this._fieldIndex)this._fieldIndex.add(e)}_removeFromIndex(e){if(this._fieldIndex)this._fieldIndex.remove(e)}_updateInIndex(e,t){if(this._fieldIndex)this._fieldIndex.update(e,t)}async _buildDoc(e,{ttl:t,embed:i}={}){let s={...e,_id:e._id??(this._ctx.idGenerator??yl)(),createdAt:new Date,updatedAt:new Date},n=t??this._defaultTtl;if(n)s._expiresAt=vl(n);let r=i??this._defaultEmbed;if(r){let a=typeof r==="function"?r(s):s[r];s._vector=await this._ctx.embed(String(a))}if(this._versioning)s._version=1;return s}_projectDoc(e,t){if(t){let s={};for(let n of t){if(n==="_vector")continue;s[n]=e[n]}return s}let i={...e};return delete i._vector,i}async _populateDoc(e,t,i){for(let s of i){let n=await this._ctx.getCollection(s).findOne({_id:t[s]});if(n)e[s]=n}}}class Ri{async read(e){throw Error("StorageAdapter.read() not implemented")}async write(e,t){throw Error("StorageAdapter.write() not implemented")}async delete(e){throw Error("StorageAdapter.delete() not implemented")}async list(){throw Error("StorageAdapter.list() not implemented")}async writeAll(e){for(let{name:t,data:i}of e)await this.write(t,i)}}class Hn extends Ri{constructor({dir:e,format:t="gz"}){super();this.dir=Be.resolve(e),this.format=t,this._ensureDir(this.dir)}_ensureDir(e){if(!q.existsSync(e))q.mkdirSync(e,{recursive:!0})}_filePath(e){return Be.join(this.dir,`${e}.${this.format}`)}async read(e){let t=this._filePath(e);try{let i=await q.promises.readFile(t);if(this.format==="gz")i=ai.inflateSync(i);return i.toString("utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async write(e,t){let i=this._filePath(e),s=Be.join(this.dir,`${e}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let n=ai.deflateSync(t);await q.promises.writeFile(s,n)}else await q.promises.writeFile(s,t,"utf8");await q.promises.rename(s,i)}async writeAll(e){let t=[];try{for(let{name:i,data:s}of e){let n=this._filePath(i),r=Be.join(this.dir,`${i}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let a=ai.deflateSync(s);await q.promises.writeFile(r,a)}else await q.promises.writeFile(r,s,"utf8");t.push({tmp:r,fp:n})}for(let{tmp:i,fp:s}of t)await q.promises.rename(i,s)}catch(i){for(let{tmp:s}of t)try{await q.promises.unlink(s)}catch{}throw i}}async delete(e){let t=this._filePath(e);try{await q.promises.unlink(t)}catch(i){if(i.code!=="ENOENT")throw i}}async list(){try{let e=await q.promises.readdir(this.dir),t=`.${this.format}`;return e.filter((i)=>i.endsWith(t)&&!i.includes(".tmp.")).map((i)=>i.slice(0,-t.length))}catch(e){if(e.code==="ENOENT")return[];throw e}}join(...e){return Be.join(...e)}ensureDir(e){this._ensureDir(e)}async writeRaw(e,t){this._ensureDir(Be.dirname(e)),await q.promises.writeFile(e,t,"utf8")}async readRaw(e){return q.promises.readFile(Be.resolve(e),"utf8")}}class Vn{constructor(){this._migrations=[]}add(e){let{version:t,up:i}=e;if(typeof t!=="number"||t<1)throw new $("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version must be a positive integer, got ${t}`,{version:t});if(typeof i!=="function")throw new $("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version ${t} must have an "up" function`,{version:t});if(this._migrations.some((s)=>s.version===t))throw new $("ERR_SKALEX_VALIDATION_MIGRATION_DUPLICATE",`Migration version ${t} is already registered`,{version:t});this._migrations.push({...e}),this._migrations.sort((s,n)=>s.version-n.version)}async run(e,t=[]){let i=new Set(t),s=this._migrations.filter((n)=>!i.has(n.version));for(let n of s){let r=e(n.version);await n.up(r),i.add(n.version)}return[...i].sort((n,r)=>n-r)}status(e=[]){let t=new Set(e),i=this._migrations.map((s)=>s.version).filter((s)=>!t.has(s));return{current:e.length?Math.max(...e):0,applied:[...t].sort((s,n)=>s-n),pending:i}}}var Cs={[Symbol.iterator](){return{next(){return{done:!0}}}},size:0};function Rs(e){return{[Symbol.iterator](){return e[Symbol.iterator]()},get size(){return e.size}}}function di(e){return e.map((t)=>{if(t===null||t===void 0)return"\x00";if(typeof t==="boolean")return t?"\x01T":"\x01F";if(typeof t==="number")return`\x02${t}`;return`\x03${String(t)}`}).join("\x1F")}class Rt{constructor(e=[],t=[]){this._fields=new Set,this._compoundFields=[];for(let i of e)if(Array.isArray(i)){for(let s of i)this._validateFieldName(s);this._compoundFields.push(i)}else this._validateFieldName(i),this._fields.add(i);for(let i of t)this._validateFieldName(i);this._uniqueFields=new Set(t),this._indexedFields=new Set([...this._fields,...this._uniqueFields]),this._fieldIndexes=new Map,this._uniqueIndexes=new Map;for(let i of this._fields)this._fieldIndexes.set(i,new Map);for(let i of this._uniqueFields)if(this._uniqueIndexes.set(i,new Map),!this._fieldIndexes.has(i))this._fieldIndexes.set(i,new Map);this._compoundIndexes=new Map;for(let i of this._compoundFields)this._compoundIndexes.set(i.join("\x00"),{fields:i,map:new Map})}get indexedFields(){return this._indexedFields}buildFromData(e){for(let[,t]of this._fieldIndexes)t.clear();for(let[,t]of this._uniqueIndexes)t.clear();for(let[,t]of this._compoundIndexes)t.map.clear();for(let t of e)this._indexDoc(t)}add(e){this._checkUnique(e,null),this._indexDoc(e)}remove(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){let n=i.get(s);if(n){if(n.delete(e),n.size===0)i.delete(s)}}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.delete(s)}for(let[,t]of this._compoundIndexes){let i=di(t.fields.map((n)=>e[n])),s=t.map.get(i);if(s){if(s.delete(e),s.size===0)t.map.delete(i)}}}update(e,t){this._checkUnique(t,e),this.remove(e);try{this._indexDoc(t)}catch(i){try{this._indexDoc(e)}catch{}throw i}}lookup(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?[...s]:[]}_lookupIterable(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?Rs(s):Cs}lookupCompound(e){let t=Object.keys(e).sort();for(let[,i]of this._compoundIndexes){let s=[...i.fields].sort();if(s.length!==t.length)continue;if(s.every((n,r)=>n===t[r])){let n=di(i.fields.map((a)=>e[a])),r=i.map.get(n);return r?Rs(r):Cs}}return null}isUniqueTaken(e,t){let i=this._uniqueIndexes.get(e);if(!i)return!1;return i.has(t)}assertUniqueCandidates(e,t){if(this._uniqueFields.size===0)return;let i=new Set(e.map((s)=>s._id));for(let s of this._uniqueFields){let n=new Set,r=this._uniqueIndexes.get(s);if(r){for(let[l,o]of r.entries())if(!i.has(o._id))n.add(l)}let a=new Map;for(let l=0;l<t.length;l++){let o=t[l][s];if(o===void 0)continue;if(n.has(o))throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});let c=a.get(o);if(c&&c!==e[l]._id)throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});a.set(o,e[l]._id)}}}assertUniqueBatch(e){if(this._uniqueFields.size===0)return;for(let t of this._uniqueFields){let i=this._uniqueIndexes.get(t),s=new Set;for(let n of e){let r=n[t];if(r===void 0)continue;if(i&&i.has(r))throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${t}" value "${r}" already exists`,{field:t,value:r});if(s.has(r))throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: duplicate "${t}" value "${r}" within batch`,{field:t,value:r});s.add(r)}}}_validateFieldName(e){if(e.includes("."))throw new $("ERR_SKALEX_VALIDATION_INDEX_DOT_PATH",`Index fields cannot use dot-notation: "${e}". Use a flat field name.`,{field:e})}_indexDoc(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){if(!i.has(s))i.set(s,new Set);i.get(s).add(e)}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.set(s,e)}for(let[,t]of this._compoundIndexes){for(let s of t.fields){let n=e[s];if(n!==void 0&&n!==null&&typeof n==="object")throw new $("ERR_SKALEX_VALIDATION_COMPOUND_INDEX",`Compound index field "${s}" must be a scalar value (string, number, or boolean), got ${Array.isArray(n)?"array":typeof n}`,{field:s})}let i=di(t.fields.map((s)=>e[s]));if(!t.map.has(i))t.map.set(i,new Set);t.map.get(i).add(e)}}_checkUnique(e,t){for(let i of this._uniqueFields){let s=e[i];if(s===void 0)continue;let n=this._uniqueIndexes.get(i);if(!n)continue;let r=n.get(s);if(r&&r._id!==t?._id)throw new Ee("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${i}" value "${s}" already exists`,{field:i,value:s})}}}var Et="_flush",St="migrations";class Jn{constructor({adapter:e,serializer:t,deserializer:i,logger:s,debug:n=!1,lenientLoad:r=!1}){this._adapter=e,this._serializer=t,this._deserializer=i,this._logger=s,this._debug=n,this._lenientLoad=r,this._saveLock=Promise.resolve()}_withSaveLock(e){let t=this._saveLock.then(e);return this._saveLock=t.catch(()=>{}),t}async loadAll(e,{parseSchema:t,buildIndex:i,IndexEngine:s}){try{let n=await this._adapter.list();await Promise.all(n.map(async(r)=>{try{let a=await this._adapter.read(r);if(!a)return;let l=this._deserializer(a),{collectionName:o,data:c}=l;if(!o)return;let h=e[o],u=h?.rawSchema??l.rawSchema??null,d=h?.schema??(u?t(u):null),_=h?.changelog??l.changelog??!1,f=h?.softDelete??l.softDelete??!1,p=h?.versioning??l.versioning??!1,m=h?.strict??l.strict??!1,w=h?.onSchemaError??l.onSchemaError??"throw",x=h?.defaultTtl??l.defaultTtl??null,R=h?.defaultEmbed??l.defaultEmbed??null,E=h?.maxDocs??l.maxDocs??null,A=h?h.fieldIndex:null;if(!A&&d?.uniqueFields?.length)A=new s([],d.uniqueFields);let Ue=i(c,"_id");if(A)A.buildFromData(c);e[o]={collectionName:o,data:c,index:Ue,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:d,rawSchema:u,fieldIndex:A,changelog:_,softDelete:f,versioning:p,strict:m,onSchemaError:w,defaultTtl:x,defaultEmbed:R,maxDocs:E}}catch(a){if(a.code==="ENOENT")return;if(this._lenientLoad){this._logger(`WARNING: Could not load collection "${r}": ${a.message}. Collection will be empty.`,"error");return}throw new ke("ERR_SKALEX_PERSISTENCE_CORRUPT",`Failed to load collection "${r}": ${a.message}`,{collection:r})}})),this._detectIncompleteFlush(e),await this._cleanOrphanTempFiles()}catch(n){if(n.code!=="ENOENT")throw this._logger(`Error loading data: ${n}`,"error"),n}}async save(e,t){if(t)await this._saveOne(e,t);else await Promise.all(Object.keys(e).map((i)=>this._saveOne(e,i)))}async saveDirty(e){let t=Object.keys(e).filter((i)=>e[i]._dirty);if(t.length===0)return;await Promise.all(t.map((i)=>this._saveOne(e,i)))}saveAtomic(e,t){return this._withSaveLock(async()=>{if(t.length===0)return;this._writeFlushSentinel(e,t);let i=new Set(t);i.add("_meta");let s=[...i].filter((n)=>e[n]).map((n)=>({name:n,data:this._serializeCollection(e[n])}));try{await this._adapter.writeAll(s)}catch(n){throw new ke("ERR_SKALEX_PERSISTENCE_FLUSH_FAILED",`Batch save failed during writeAll: ${n.message}`,{collections:t})}for(let n of t)if(e[n])e[n]._dirty=!1;try{this._clearFlushSentinel(e),await this._adapter.write("_meta",this._serializeCollection(e._meta))}catch(n){this._logger(`WARNING: Batch data committed but sentinel clear failed: ${n.message}. Next load will report an incomplete flush (false positive).`,"error")}})}markDirty(e,t){let i=e[t];if(i)i._dirty=!0}_serializeCollection(e){let t={collectionName:e.collectionName,data:e.data};if(e.rawSchema)t.rawSchema=e.rawSchema;if(e.changelog)t.changelog=e.changelog;if(e.softDelete)t.softDelete=e.softDelete;if(e.versioning)t.versioning=e.versioning;if(e.strict)t.strict=e.strict;if(e.onSchemaError!=="throw")t.onSchemaError=e.onSchemaError;if(e.defaultTtl)t.defaultTtl=e.defaultTtl;if(e.defaultEmbed)t.defaultEmbed=e.defaultEmbed;if(e.maxDocs)t.maxDocs=e.maxDocs;return this._serializer(t)}async _saveOne(e,t){let i=e[t];if(!i)return;if(i.isSaving)return i._pendingSave=!0,new Promise((s,n)=>{(i._saveWaiters??=[]).push({resolve:s,reject:n})});i.isSaving=!0,i._pendingSave=!1;try{await this._writeCollection(t,i);while(i._pendingSave)i._pendingSave=!1,await this._writeCollection(t,i);this._resolveSaveWaiters(i)}catch(s){throw this._rejectSaveWaiters(i,s),s}finally{i.isSaving=!1}}async _writeCollection(e,t){try{await this._adapter.write(e,this._serializeCollection(t)),t._dirty=!1}catch(i){throw this._logger(`Error saving "${e}": ${i.message}`,"error"),i}}_resolveSaveWaiters(e){let t=e._saveWaiters?.splice(0)??[];for(let i of t)i.resolve()}_rejectSaveWaiters(e,t){let i=e._saveWaiters?.splice(0)??[];for(let s of i)s.reject(t)}_writeFlushSentinel(e,t){let i=this._getOrCreateMeta(e);i[Et]={startedAt:new Date().toISOString(),collections:t,completedAt:null}}_clearFlushSentinel(e){let t=this._getOrCreateMeta(e);if(t[Et])t[Et].completedAt=new Date().toISOString()}_detectIncompleteFlush(e){let t=e._meta;if(!t)return;let i=t.index.get(St);if(!i)return;let s=i[Et];if(!s)return;if(s.startedAt&&!s.completedAt)this._logger(`WARNING: Incomplete flush detected (started ${s.startedAt}, collections: ${s.collections?.join(", ")}). Data may be inconsistent.`,"error")}async _cleanOrphanTempFiles(){if(typeof this._adapter.join!=="function")return;if(typeof this._adapter.list!=="function")return;try{let e=await import("fs"),t=await import("path"),i=this._adapter.dir;if(!i)return;let s=(await e.default.promises.readdir(i)).filter((n)=>n.includes(".tmp."));for(let n of s){let r=t.default.join(i,n);try{await e.default.promises.unlink(r),this._log(`Cleaned orphan temp file: ${n}`)}catch{}}}catch{}}_getOrCreateMeta(e){if(!e._meta)e._meta={collectionName:"_meta",data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:null,rawSchema:null,fieldIndex:null,changelog:!1,softDelete:!1,versioning:!1,strict:!1,onSchemaError:"throw",defaultTtl:null,defaultEmbed:null,maxDocs:null};let t=e._meta,i=t.index.get(St);if(!i)i={_id:St},t.data.push(i),t.index.set(St,i);return i}_log(e){if(this._debug)this._logger(e,"info")}}var Nl=0;class Yn{constructor(){this._txLock=Promise.resolve(),this._ctx=null,this._abortedIds=new Set}get active(){return this._ctx!==null&&!this._ctx.aborted}get context(){return this._ctx}async run(e,t,{timeout:i=0}={}){let s=async()=>{await t._ensureConnected();let r=new Set(Object.keys(t.collections)),a={id:++Nl,startedAt:Date.now(),aborted:!1,preExisting:r,touchedCollections:new Set,snapshots:new Map,deferredEffects:[],timeout:i};this._ctx=a;let l=null,o=i>0?new Promise((u,d)=>{l=setTimeout(()=>{a.aborted=!0,d(new ge("ERR_SKALEX_TX_TIMEOUT",`Transaction ${a.id} timed out after ${i}ms`))},i)}):null,c=this,h=new Proxy(t,{get(u,d){if(d==="_txId")return a.id;if(a!==c._ctx)throw new ge("ERR_SKALEX_TX_STALE_PROXY",`Transaction ${a.id} has ended. This proxy is no longer usable.`);if(d==="collections")throw new ge("ERR_SKALEX_TX_DIRECT_ACCESS","Direct access to db.collections inside transaction() is not covered by rollback. Use the collection API (db.useCollection) instead.");if(d==="useCollection")return(f)=>{let p=u.useCollection(f);return p._activeTxId=a.id,p};let _=Reflect.get(u,d);return typeof _==="function"?_.bind(u):_}});try{let u=e(h),d=o?await Promise.race([u,o]):await u;if(a.aborted)throw new ge("ERR_SKALEX_TX_ABORTED",`Transaction ${a.id} was aborted`);let _=[...a.touchedCollections];if(_.length>0)await t._persistence.saveAtomic(t.collections,_);for(let f of a.deferredEffects)await f();return d}catch(u){for(let[d,_]of a.snapshots)if(a.preExisting.has(d)){if(t._applySnapshot(d,_),t.collections[d])t.collections[d]._dirty=_._dirty}for(let d in t.collections)if(!a.preExisting.has(d))delete t.collections[d],delete t._collectionInstances[d];throw u}finally{if(l)clearTimeout(l);if(a.aborted)this._abortedIds.add(a.id);this._ctx=null;for(let u in t._collectionInstances){let d=t._collectionInstances[u];if(d._createdInTxId===a.id)d._createdInTxId=null;if(d._activeTxId===a.id)d._activeTxId=null}}},n=this._txLock.then(s);return this._txLock=n.catch(()=>{}),n}snapshotIfNeeded(e,t,i){let s=this._ctx;if(!s)return;if(this._assertCtxNotAborted(s),!s.snapshots.has(e)){let n=i(t);n._dirty=t._dirty??!1,s.snapshots.set(e,n)}s.touchedCollections.add(e)}assertNotAborted(){let e=this._ctx;if(e)this._assertCtxNotAborted(e)}_assertCtxNotAborted(e){if(e.aborted)throw new ge("ERR_SKALEX_TX_ABORTED",`Transaction ${e.id} was aborted. No further mutations allowed.`)}defer(e){if(this._ctx)return this._ctx.deferredEffects.push(e),!0;return!1}}class Wn{constructor(e){this._CollectionClass=e,this.stores={},this._instances={}}get(e,t){if(this._instances[e])return this._instances[e];if(!this.stores[e])this.createStore(e);let i=new this._CollectionClass(this.stores[e],t);return this._instances[e]=i,i}create(e,t={},i){this.createStore(e,t);let s=new this._CollectionClass(this.stores[e],i);return this._instances[e]=s,s}createStore(e,{schema:t,indexes:i=[],changelog:s=!1,softDelete:n=!1,versioning:r=!1,strict:a=!1,onSchemaError:l="throw",defaultTtl:o=null,defaultEmbed:c=null,maxDocs:h=null}={}){let u=null,d=null;if(t){u=Fn(t);let _=u.uniqueFields;if(i.length||_.length)d=new Rt(i,_)}else if(i.length)d=new Rt(i,[]);this.stores[e]={collectionName:e,data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:u,rawSchema:t||null,fieldIndex:d,changelog:s,softDelete:n,versioning:r,strict:a,onSchemaError:l,defaultTtl:o,defaultEmbed:c,maxDocs:h}}rename(e,t){if(!this.stores[e])throw new ke("ERR_SKALEX_PERSISTENCE_COLLECTION_NOT_FOUND",`Collection "${e}" not found`,{collection:e});if(this.stores[t])throw new ke("ERR_SKALEX_PERSISTENCE_COLLECTION_EXISTS",`Collection "${t}" already exists`,{collection:t});let i=this.stores[e];if(i.collectionName=t,this.stores[t]=i,delete this.stores[e],this._instances[e]){let s=this._instances[e];s.name=t,this._instances[t]=s,delete this._instances[e]}}buildIndex(e,t){let i=new Map;for(let s of e)i.set(s[t],s);return i}inspect(e){if(e){let i=this.stores[e];if(!i)return null;return{name:e,count:i.data.length,schema:i.schema?Object.fromEntries(i.schema.fields):null,indexes:i.fieldIndex?[...i.fieldIndex.indexedFields]:[],softDelete:i.softDelete??!1,versioning:i.versioning??!1,strict:i.strict??!1,onSchemaError:i.onSchemaError??"throw",maxDocs:i.maxDocs??null}}let t={};for(let i in this.stores)t[i]=this.inspect(i);return t}dump(){let e={};for(let t in this.stores)if(!t.startsWith("_"))e[t]=structuredClone(this.stores[t].data);return e}schema(e){let t=this.stores[e];if(!t)return null;if(t.schema)return Object.fromEntries([...t.schema.fields.entries()].map(([i,s])=>[i,s.type]));if(t.data.length>0)return Al(t.data[0]);return null}stats(e){let t=(i)=>{let s=this.stores[i];if(!s)return null;let n=s.data.length,r=0;for(let a of s.data)try{r+=JSON.stringify(a).length}catch(l){}return{collection:i,count:n,estimatedSize:r,avgDocSize:n>0?Math.round(r/n):0}};if(e)return t(e);return Object.keys(this.stores).map(t)}clear(){this.stores={},this._instances={}}}class ki{async embed(e){throw Error("EmbeddingAdapter.embed() not implemented")}}var ce=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Qn extends ki{constructor({apiKey:e=ce("OPENAI_API_KEY"),model:t=ce("OPENAI_EMBED_MODEL")??"text-embedding-3-small",baseUrl:i=ce("OPENAI_EMBED_BASE_URL")??"https://api.openai.com/v1/embeddings",dimensions:s=ce("OPENAI_EMBED_DIMENSIONS")!=null?Number(ce("OPENAI_EMBED_DIMENSIONS")):void 0,organization:n=ce("OPENAI_ORGANIZATION")??void 0,timeout:r=ce("OPENAI_EMBED_TIMEOUT")!=null?Number(ce("OPENAI_EMBED_TIMEOUT")):void 0,retries:a=Number(ce("OPENAI_EMBED_RETRIES")??0),retryDelay:l=Number(ce("OPENAI_EMBED_RETRY_DELAY")??1000),headers:o={},fetch:c=globalThis.fetch}={}){super();if(!e)throw Error("OpenAIEmbeddingAdapter requires an apiKey");this.apiKey=e,this.model=t,this.baseUrl=i,this.dimensions=s,this.organization=n,this.timeout=r,this.retries=a,this.retryDelay=l,this.headers=o,this._fetch=c}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(this.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...this.organization&&{"OpenAI-Organization":this.organization},...this.headers},body:JSON.stringify({input:e,model:this.model,...this.dimensions!==void 0&&{dimensions:this.dimensions}}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`OpenAI embedding API error ${r.status}: ${a}`)}return(await r.json()).data[0].embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}var st=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Gn extends ki{constructor({model:e=st("OLLAMA_EMBED_MODEL")??"nomic-embed-text",host:t=st("OLLAMA_HOST")??"http://localhost:11434",timeout:i=st("OLLAMA_EMBED_TIMEOUT")!=null?Number(st("OLLAMA_EMBED_TIMEOUT")):void 0,retries:s=Number(st("OLLAMA_EMBED_RETRIES")??0),retryDelay:n=Number(st("OLLAMA_EMBED_RETRY_DELAY")??1000),headers:r={},fetch:a=globalThis.fetch}={}){super();this.model=e,this.host=t,this.timeout=i,this.retries=s,this.retryDelay=n,this.headers=r,this._fetch=a}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({model:this.model,prompt:e}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama embedding API error ${r.status}: ${a}`)}return(await r.json()).embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}class qt{async generate(e,t){throw Error("LLMAdapter.generate() not implemented")}async summarize(e){throw Error("LLMAdapter.summarize() not implemented")}}var Li=`You are a database query assistant. Convert the user's natural language request into a JSON filter object for a document database.
42
42
 
43
43
  Rules:
44
44
  - Return ONLY a valid JSON object, nothing else
@@ -53,18 +53,18 @@ Schema: ${JSON.stringify(e)}`,messages:[{role:"user",content:t}]})).content[0].t
53
53
  Schema: ${JSON.stringify(e)}
54
54
  Query: ${t}`,s=await this._post({model:this.model,prompt:i,format:"json",options:{temperature:0},stream:!1});return JSON.parse(s.response)}async summarize(e){return(await this._post({model:this.model,prompt:`${this.summarizePrompt}
55
55
 
56
- ${e}`,options:{temperature:this.temperature,...this.topP!==void 0&&{top_p:this.topP},...this.topK!==void 0&&{top_k:this.topK}},stream:!1})).response.trim()}async _post(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify(e),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama API error ${r.status}: ${a}`)}return r.json()}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}function Ol({provider:e,apiKey:t,embedModel:i,model:s,host:n,embedBaseUrl:r,dimensions:a,organization:l,embedTimeout:o,embedRetries:c,embedRetryDelay:h}){let u=i||s;switch(e){case"openai":return new Qn({apiKey:t,model:u,baseUrl:r,...a!==void 0&&{dimensions:a},...l!==void 0&&{organization:l},...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});case"ollama":return new Gn({model:u,host:n,...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});default:throw new _e("ERR_SKALEX_ADAPTER_UNKNOWN_PROVIDER",`Unknown AI provider: "${e}". Supported: "openai", "ollama".`,{provider:e})}}function Nl({provider:e,apiKey:t,model:i,host:s,baseUrl:n,apiVersion:r,temperature:a,maxTokens:l,topP:o,topK:c,organization:h,timeout:u,retries:d,retryDelay:_,seed:f,generatePrompt:p,summarizePrompt:m}){if(!i)return null;switch(e){case"openai":return new Zn({apiKey:t,model:i,baseUrl:n,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...h!==void 0&&{organization:h},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...f!==void 0&&{seed:f},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"anthropic":return new er({apiKey:t,model:i,baseUrl:n,apiVersion:r,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"ollama":return new tr({model:i,host:s,...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});default:return null}}var ui="AES-GCM",pt=12,Se=32,$l=new TextEncoder,Dl=new TextDecoder;class ir extends Ri{constructor(e,t){super();if(this._adapter=e,this._rawKey=typeof t==="string"?Cl(t):Uint8Array.from(t),this._rawKey.length!==Se)throw new _e("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: key must be ${Se} bytes (${Se*2} hex chars), got ${this._rawKey.length}`);this._cryptoKey=null}async read(e){let t=await this._adapter.read(e);if(!t)return null;return this._decrypt(t)}async write(e,t){return this._adapter.write(e,await this._encrypt(t))}async delete(e){return this._adapter.delete(e)}async list(){return this._adapter.list()}async writeAll(e){let t=[];for(let{name:i,data:s}of e)t.push({name:i,data:await this._encrypt(s)});return this._adapter.writeAll(t)}join(...e){return this._adapter.join?.(...e)}ensureDir(e){return this._adapter.ensureDir?.(e)}async writeRaw(e,t){return this._adapter.writeRaw?.(e,await this._encrypt(t))}async readRaw(e){let t=await this._adapter.readRaw?.(e);if(!t)return null;return this._decrypt(t)}async _getKey(){if(!this._cryptoKey)this._cryptoKey=await globalThis.crypto.subtle.importKey("raw",this._rawKey,{name:ui},!1,["encrypt","decrypt"]);return this._cryptoKey}async _encrypt(e){let t=await this._getKey(),i=globalThis.crypto.getRandomValues(new Uint8Array(pt)),s=$l.encode(e),n=await globalThis.crypto.subtle.encrypt({name:ui,iv:i,tagLength:128},t,s),r=new Uint8Array(pt+n.byteLength);return r.set(i,0),r.set(new Uint8Array(n),pt),Rl(r)}async _decrypt(e){let t=await this._getKey(),i=kl(e),s=i.slice(0,pt),n=i.slice(pt),r=await globalThis.crypto.subtle.decrypt({name:ui,iv:s,tagLength:128},t,n);return Dl.decode(r)}}function Cl(e){if(e.length!==Se*2)throw new _e("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: hex key must be ${Se*2} characters (${Se} bytes)`);if(!/^[0-9a-fA-F]+$/.test(e))throw new _e("ERR_SKALEX_ADAPTER_INVALID_KEY","EncryptedAdapter: hex key contains invalid characters");let t=new Uint8Array(Se);for(let i=0;i<Se;i++)t[i]=parseInt(e.slice(i*2,i*2+2),16);return t}function Rl(e){let t="";for(let i=0;i<e.length;i++)t+=String.fromCharCode(e[i]);return globalThis.btoa(t)}function kl(e){let t=globalThis.atob(e),i=new Uint8Array(t.length);for(let s=0;s<t.length;s++)i[s]=t.charCodeAt(s);return i}var Ll=4;class sr{constructor(e,t){this.sessionId=e,this._db=t,this._col=t.useCollection(`_memory_${e}`)}async remember(e){let t=await this._col.insertOne({text:e,sessionId:this.sessionId},{embed:"text"}),i=this._db._memoryConfig?.maxEntries;if(i&&this._col._data.length>i)await this.compress({threshold:0});return t}async recall(e,{limit:t=10,minScore:i=0}={}){return this._col.search(e,{limit:t,minScore:i})}async history({since:e,limit:t}={}){let i=e?{createdAt:{$gte:new Date(e)}}:{},s={sort:{createdAt:1}};if(t)s.limit=t;let{docs:n}=await this._col.find(i,s);return n}async forget(e){return this._col.deleteOne({_id:e})}tokenCount(){let e=this._col._data;return{tokens:e.reduce((t,i)=>t+this._docTokens(i),0),count:e.length}}context({tokens:e=this._db._memoryConfig?.contextTokens??4000}={}){let t=this._sortedData("desc"),i=[],s=0;for(let n of t){let r=this._docTokens(n);if(s+r>e)break;i.push(n.text),s+=r}return i.reverse().join(`
56
+ ${e}`,options:{temperature:this.temperature,...this.topP!==void 0&&{top_p:this.topP},...this.topK!==void 0&&{top_k:this.topK}},stream:!1})).response.trim()}async _post(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify(e),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama API error ${r.status}: ${a}`)}return r.json()}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}function $l({provider:e,apiKey:t,embedModel:i,model:s,host:n,embedBaseUrl:r,dimensions:a,organization:l,embedTimeout:o,embedRetries:c,embedRetryDelay:h}){let u=i||s;switch(e){case"openai":return new Qn({apiKey:t,model:u,baseUrl:r,...a!==void 0&&{dimensions:a},...l!==void 0&&{organization:l},...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});case"ollama":return new Gn({model:u,host:n,...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});default:throw new _e("ERR_SKALEX_ADAPTER_UNKNOWN_PROVIDER",`Unknown AI provider: "${e}". Supported: "openai", "ollama".`,{provider:e})}}function Dl({provider:e,apiKey:t,model:i,host:s,baseUrl:n,apiVersion:r,temperature:a,maxTokens:l,topP:o,topK:c,organization:h,timeout:u,retries:d,retryDelay:_,seed:f,generatePrompt:p,summarizePrompt:m}){if(!i)return null;switch(e){case"openai":return new Zn({apiKey:t,model:i,baseUrl:n,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...h!==void 0&&{organization:h},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...f!==void 0&&{seed:f},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"anthropic":return new er({apiKey:t,model:i,baseUrl:n,apiVersion:r,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"ollama":return new tr({model:i,host:s,...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});default:return null}}var ui="AES-GCM",pt=12,Se=32,Cl=new TextEncoder,Rl=new TextDecoder;class ir extends Ri{constructor(e,t){super();if(this._adapter=e,this._rawKey=typeof t==="string"?kl(t):Uint8Array.from(t),this._rawKey.length!==Se)throw new _e("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: key must be ${Se} bytes (${Se*2} hex chars), got ${this._rawKey.length}`);this._cryptoKey=null}async read(e){let t=await this._adapter.read(e);if(!t)return null;return this._decrypt(t)}async write(e,t){return this._adapter.write(e,await this._encrypt(t))}async delete(e){return this._adapter.delete(e)}async list(){return this._adapter.list()}async writeAll(e){let t=[];for(let{name:i,data:s}of e)t.push({name:i,data:await this._encrypt(s)});return this._adapter.writeAll(t)}join(...e){return this._adapter.join?.(...e)}ensureDir(e){return this._adapter.ensureDir?.(e)}async writeRaw(e,t){return this._adapter.writeRaw?.(e,await this._encrypt(t))}async readRaw(e){let t=await this._adapter.readRaw?.(e);if(!t)return null;return this._decrypt(t)}async _getKey(){if(!this._cryptoKey)this._cryptoKey=await globalThis.crypto.subtle.importKey("raw",this._rawKey,{name:ui},!1,["encrypt","decrypt"]);return this._cryptoKey}async _encrypt(e){let t=await this._getKey(),i=globalThis.crypto.getRandomValues(new Uint8Array(pt)),s=Cl.encode(e),n=await globalThis.crypto.subtle.encrypt({name:ui,iv:i,tagLength:128},t,s),r=new Uint8Array(pt+n.byteLength);return r.set(i,0),r.set(new Uint8Array(n),pt),Ll(r)}async _decrypt(e){let t=await this._getKey(),i=Pl(e),s=i.slice(0,pt),n=i.slice(pt),r=await globalThis.crypto.subtle.decrypt({name:ui,iv:s,tagLength:128},t,n);return Rl.decode(r)}}function kl(e){if(e.length!==Se*2)throw new _e("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: hex key must be ${Se*2} characters (${Se} bytes)`);if(!/^[0-9a-fA-F]+$/.test(e))throw new _e("ERR_SKALEX_ADAPTER_INVALID_KEY","EncryptedAdapter: hex key contains invalid characters");let t=new Uint8Array(Se);for(let i=0;i<Se;i++)t[i]=parseInt(e.slice(i*2,i*2+2),16);return t}function Ll(e){let t="";for(let i=0;i<e.length;i++)t+=String.fromCharCode(e[i]);return globalThis.btoa(t)}function Pl(e){let t=globalThis.atob(e),i=new Uint8Array(t.length);for(let s=0;s<t.length;s++)i[s]=t.charCodeAt(s);return i}var Ml=4;class sr{constructor(e,t){this.sessionId=e,this._db=t,this._col=t.useCollection(`_memory_${e}`)}async remember(e){let t=await this._col.insertOne({text:e,sessionId:this.sessionId},{embed:"text"}),i=this._db._memoryConfig?.maxEntries;if(i&&this._col._data.length>i)await this.compress({threshold:0});return t}async recall(e,{limit:t=10,minScore:i=0}={}){return this._col.search(e,{limit:t,minScore:i})}async history({since:e,limit:t}={}){let i=e?{createdAt:{$gte:new Date(e)}}:{},s={sort:{createdAt:1}};if(t)s.limit=t;let{docs:n}=await this._col.find(i,s);return n}async forget(e){return this._col.deleteOne({_id:e})}tokenCount(){let e=this._col._data;return{tokens:e.reduce((t,i)=>t+this._docTokens(i),0),count:e.length}}context({tokens:e=this._db._memoryConfig?.contextTokens??4000}={}){let t=this._sortedData("desc"),i=[],s=0;for(let n of t){let r=this._docTokens(n);if(s+r>e)break;i.push(n.text),s+=r}return i.reverse().join(`
57
57
  `)}async compress({threshold:e=this._db._memoryConfig?.compressionThreshold??8000,keepRecent:t=this._db._memoryConfig?.keepRecent??10}={}){let{tokens:i}=this.tokenCount();if(i<=e)return;if(!this._db._aiAdapter)throw Error('memory.compress() requires a language model adapter. Configure { ai: { model: "..." } }.');let s=this._sortedData("asc"),n=Math.max(0,s.length-t),r=s.slice(0,n);if(r.length===0)return;let a=r.map((o)=>o.text).join(`
58
- `),l=await this._db._aiAdapter.summarize(a);await this._col.deleteMany({_id:{$in:r.map((o)=>o._id)}}),await this._col.insertOne({text:l,sessionId:this.sessionId,compressed:!0})}_docTokens(e){return Math.ceil((e.text||"").length/Ll)}_sortedData(e){return[...this._col._data].sort(e==="asc"?(t,i)=>new Date(t.createdAt)-new Date(i.createdAt):(t,i)=>new Date(i.createdAt)-new Date(t.createdAt))}}class nr{constructor(e){this._db=e,this._restoring=!1}get _col(){return this._db.useCollection("_changelog")}async log(e,t,i,s=null,n=null){if(this._restoring)return;let r={op:e,collection:t,docId:i._id,doc:{...i},timestamp:new Date};if(s)r.prev={...s};if(n)r.session=n;await this._col.insertOne(r)}async query(e,{since:t,limit:i,session:s}={}){let n={collection:e};if(t)n.timestamp={$gte:new Date(t)};if(s)n.session=s;let r={sort:{timestamp:1}};if(i)r.limit=i;let{docs:a}=await this._col.find(n,r);return a}async restore(e,t,{_id:i}={}){let s=new Date(t),n=this._db.useCollection(e),r=(await this.query(e,{})).filter((l)=>new Date(l.timestamp)<=s);if(i){let l=r.filter((c)=>c.docId===i);if(l.length===0)return;let o=l[l.length-1];this._restoring=!0;try{if(o.op==="delete"){if(await n.findOne({_id:i}))await n.deleteOne({_id:i});return}if(await n.findOne({_id:i})){let{_id:c,createdAt:h,updatedAt:u,...d}=o.doc;await n.updateOne({_id:i},d)}else await n.insertOne({...o.doc})}finally{this._restoring=!1}await this._db.saveData(e);return}let a=new Map;for(let l of r)if(l.op==="insert"||l.op==="update")a.set(l.docId,{doc:l.doc,deleted:!1});else if(l.op==="delete")a.set(l.docId,{doc:null,deleted:!0});this._restoring=!0;try{await n.deleteMany({});for(let[,{doc:l,deleted:o}]of a)if(!o&&l)await n.insertOne({...l})}finally{this._restoring=!1}await this._db.saveData(e)}}function Pl(e){let t=5381;for(let i=0;i<e.length;i++)t=(t<<5)+t+e.charCodeAt(i)|0;return(t>>>0).toString(16).padStart(8,"0")}class rr{constructor({maxSize:e=500,ttl:t=0}={}){this._cache=new Map,this._maxSize=e,this._ttl=t}_key(e,t,i){return Pl(JSON.stringify({collectionName:e,schema:t,query:i}))}get(e,t,i){let s=this._key(e,t,i),n=this._cache.get(s);if(!n)return;if(this._ttl>0&&Date.now()-n.ts>this._ttl){this._cache.delete(s);return}return n.filter}set(e,t,i,s){let n=this._key(e,t,i);if(this._cache.size>=this._maxSize&&!this._cache.has(n))this._cache.delete(this._cache.keys().next().value);this._cache.set(n,{filter:s,ts:Date.now()})}toJSON(){return Object.fromEntries([...this._cache.entries()].map(([e,t])=>[e,t]))}fromJSON(e){if(!e||typeof e!=="object")return;for(let[t,i]of Object.entries(e))this._cache.set(t,i)}get size(){return this._cache.size}}function Ml(e,{regexMaxLength:t=500}={}){if(typeof e!=="object"||e===null)return e;let i={};for(let s of Object.keys(e)){let n=e[s];if(n&&typeof n==="object"&&!Array.isArray(n)){let r={};for(let a of Object.keys(n))if(a==="$regex"&&typeof n.$regex==="string"){if(n.$regex.length>t)throw Error(`$regex pattern too long (max ${t} characters)`);if(/\([^)]*[+*][^)]*\)[+*{]/.test(n.$regex))throw Error("$regex pattern rejected: nested quantifiers risk ReDoS");try{r.$regex=new RegExp(n.$regex)}catch{throw Error(`invalid $regex pattern: "${n.$regex}"`)}}else if(["$gt","$gte","$lt","$lte"].includes(a)&&jl(n[a]))r[a]=new Date(n[a]);else r[a]=n[a];i[s]=r}else i[s]=n}return i}function jl(e){if(typeof e!=="string")return!1;return/\d{4}-\d{2}-\d{2}/.test(e)&&!isNaN(Date.parse(e))}function ql(e,t){let i=[];if(!t||typeof e!=="object"||e===null)return i;for(let s of Object.keys(e)){if(s.startsWith("$"))continue;if(!(s.split(".")[0]in t))i.push(`Unknown field referenced in generated filter: "${s}"`)}return i}class ar{constructor(){this._listeners=new Map}on(e,t){if(!this._listeners.has(e))this._listeners.set(e,new Set);return this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}emit(e,t){for(let i of[e,"*"]){let s=this._listeners.get(i);if(!s)continue;for(let n of s)try{n(t)}catch(r){}}}removeAll(e){if(e)this._listeners.delete(e);else this._listeners.clear()}listenerCount(e){return this._listeners.get(e)?.size??0}}class or{constructor({threshold:e=100,maxEntries:t=500}={}){this._threshold=e,this._maxEntries=t,this._entries=[]}record({collection:e,op:t,filter:i,query:s,duration:n,resultCount:r}){if(n<this._threshold)return;let a={collection:e,op:t,duration:n,resultCount:r,timestamp:new Date};if(i!==void 0)a.filter=i;if(s!==void 0)a.query=s;if(this._entries.push(a),this._entries.length>this._maxEntries)this._entries.shift()}entries({limit:e,minDuration:t,collection:i}={}){let s=this._entries;if(i)s=s.filter((n)=>n.collection===i);if(t)s=s.filter((n)=>n.duration>=t);if(e)s=s.slice(-e);return s}get size(){return this._entries.length}clear(){this._entries=[]}}class lr{constructor(){this._sessions=new Map}_ensure(e){if(!this._sessions.has(e))this._sessions.set(e,{reads:0,writes:0,lastActive:null});return this._sessions.get(e)}recordRead(e){if(!e)return;let t=this._ensure(e);t.reads++,t.lastActive=new Date}recordWrite(e){if(!e)return;let t=this._ensure(e);t.writes++,t.lastActive=new Date}get(e){let t=this._sessions.get(e);if(!t)return null;return{sessionId:e,...t}}all(){return[...this._sessions.entries()].map(([e,t])=>({sessionId:e,...t}))}clear(e){if(e)this._sessions.delete(e);else this._sessions.clear()}}class cr{constructor(){this._plugins=[]}register(e){if(typeof e!=="object"||e===null)throw TypeError("Plugin must be a non-null object.");this._plugins.push(e)}async run(e,t){for(let i of this._plugins)if(typeof i[e]==="function")await i[e](t)}get size(){return this._plugins.length}}function Je(e){if(typeof e!=="string"||!e.trim())throw Error("collection name must be a non-empty string");if(/[/\\]/.test(e)||e.includes("..")||e.includes("\x00"))throw Error(`invalid collection name: "${e}"`);if(e.trim().startsWith("_"))throw Error(`access to system collection "${e}" is not permitted`);return e.trim()}var ks=[{name:"skalex_collections",description:"List all collection names in the database.",inputSchema:{type:"object",properties:{}},scope:"read"},{name:"skalex_schema",description:"Return the schema for a collection as a { field: type } map. Returns null if the collection is empty.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."}},required:["collection"]},scope:"read"},{name:"skalex_find",description:"Find documents in a collection that match a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter (MongoDB-style operators supported)."},limit:{type:"number",description:"Maximum number of results. Default: 20."},sort:{type:"object",description:"Sort descriptor: { field: 1 } for ascending, { field: -1 } for descending."}},required:["collection"]},scope:"read"},{name:"skalex_insert",description:"Insert a single document into a collection.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},doc:{type:"object",description:"Document to insert."}},required:["collection","doc"]},scope:"write"},{name:"skalex_update",description:"Update the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},update:{type:"object",description:"Fields to update (direct assignment, $inc, $push supported)."},many:{type:"boolean",description:"If true, update all matching documents. Default: false."}},required:["collection","filter","update"]},scope:"write"},{name:"skalex_delete",description:"Delete the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},many:{type:"boolean",description:"If true, delete all matching documents. Default: false."}},required:["collection","filter"]},scope:"write"},{name:"skalex_search",description:"Semantic similarity search. Requires an embedding adapter to be configured.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},query:{type:"string",description:"Natural-language query string to embed and compare."},limit:{type:"number",description:"Maximum number of results. Default: 10."},minScore:{type:"number",description:"Minimum cosine similarity score [0, 1]. Default: 0."},filter:{type:"object",description:"Optional structured pre-filter (hybrid search)."}},required:["collection","query"]},scope:"read"},{name:"skalex_ask",description:"Translate a natural-language question into a filter and query a collection. Requires a language model adapter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},question:{type:"string",description:"Natural-language question about the data."},limit:{type:"number",description:"Maximum number of results. Default: 20."}},required:["collection","question"]},scope:"read"}];async function Kl(e,t,i){switch(e){case"skalex_collections":return Object.keys(i.collections).filter((s)=>!s.startsWith("_"));case"skalex_schema":return i.schema(Je(t.collection))??null;case"skalex_find":{let s=i.useCollection(Je(t.collection)),n={};if(t.limit)n.limit=t.limit;if(t.sort)n.sort=t.sort;return s.find(t.filter||{},n)}case"skalex_insert":return i.useCollection(Je(t.collection)).insertOne(t.doc||{});case"skalex_update":{let s=i.useCollection(Je(t.collection));if(t.many)return s.updateMany(t.filter||{},t.update||{});return s.updateOne(t.filter||{},t.update||{})}case"skalex_delete":{let s=i.useCollection(Je(t.collection));if(t.many)return s.deleteMany(t.filter||{});return s.deleteOne(t.filter||{})}case"skalex_search":return i.useCollection(Je(t.collection)).search(t.query,{limit:t.limit??10,minScore:t.minScore??0,filter:t.filter});case"skalex_ask":return i.ask(Je(t.collection),t.question,{limit:t.limit??20});default:throw Object.assign(Error(`Unknown tool: ${e}`),{code:"NOT_FOUND"})}}var Mi="2.0",ji=-32700,Fl=-32600,Ls=-32601,Ul=-32602,zl=-32603;function nt(e,t){return{jsonrpc:Mi,id:e,result:t}}function $e(e,t,i,s){return{jsonrpc:Mi,id:e,error:{code:t,message:i}}}function Bl(e){try{let t=JSON.parse(e);if(typeof t!=="object"||t===null||t.jsonrpc!==Mi)return{parseError:$e(null,Fl,"Invalid JSON-RPC request")};return{msg:t}}catch(t){return{parseError:$e(null,ji,"Parse error")}}}function Xl(e){return{content:[{type:"text",text:e}]}}function Ps(e){return{content:[{type:"text",text:e}],isError:!0}}class hr{constructor({port:e=3000,host:t="127.0.0.1",allowedOrigin:i=null,maxBodySize:s=1048576}={}){this._port=e,this._host=t,this._allowedOrigin=i,this._maxBodySize=s,this._clients=new Set,this._onMessage=null,this._server=null}onMessage(e){this._onMessage=e}send(e){let t=`data: ${JSON.stringify(e)}
58
+ `),l=await this._db._aiAdapter.summarize(a);await this._col.deleteMany({_id:{$in:r.map((o)=>o._id)}}),await this._col.insertOne({text:l,sessionId:this.sessionId,compressed:!0})}_docTokens(e){return Math.ceil((e.text||"").length/Ml)}_sortedData(e){return[...this._col._data].sort(e==="asc"?(t,i)=>new Date(t.createdAt)-new Date(i.createdAt):(t,i)=>new Date(i.createdAt)-new Date(t.createdAt))}}class nr{constructor(e){this._db=e,this._restoring=!1}get _col(){return this._db.useCollection("_changelog")}async log(e,t,i,s=null,n=null){if(this._restoring)return;let r={op:e,collection:t,docId:i._id,doc:{...i},timestamp:new Date};if(s)r.prev={...s};if(n)r.session=n;await this._col.insertOne(r)}async query(e,{since:t,limit:i,session:s}={}){let n={collection:e};if(t)n.timestamp={$gte:new Date(t)};if(s)n.session=s;let r={sort:{timestamp:1}};if(i)r.limit=i;let{docs:a}=await this._col.find(n,r);return a}async restore(e,t,{_id:i}={}){let s=new Date(t),n=this._db.useCollection(e),r=(await this.query(e,{})).filter((l)=>new Date(l.timestamp)<=s);if(i){let l=r.filter((c)=>c.docId===i);if(l.length===0)return;let o=l[l.length-1];this._restoring=!0;try{if(o.op==="delete"){if(await n.findOne({_id:i}))await n.deleteOne({_id:i});return}if(await n.findOne({_id:i})){let{_id:c,createdAt:h,updatedAt:u,...d}=o.doc;await n.updateOne({_id:i},d)}else await n.insertOne({...o.doc})}finally{this._restoring=!1}await this._db.saveData(e);return}let a=new Map;for(let l of r)if(l.op==="insert"||l.op==="update")a.set(l.docId,{doc:l.doc,deleted:!1});else if(l.op==="delete")a.set(l.docId,{doc:null,deleted:!0});this._restoring=!0;try{await n.deleteMany({});for(let[,{doc:l,deleted:o}]of a)if(!o&&l)await n.insertOne({...l})}finally{this._restoring=!1}await this._db.saveData(e)}}function jl(e){let t=5381;for(let i=0;i<e.length;i++)t=(t<<5)+t+e.charCodeAt(i)|0;return(t>>>0).toString(16).padStart(8,"0")}class rr{constructor({maxSize:e=500,ttl:t=0}={}){this._cache=new Map,this._maxSize=e,this._ttl=t}_key(e,t,i){return jl(JSON.stringify({collectionName:e,schema:t,query:i}))}get(e,t,i){let s=this._key(e,t,i),n=this._cache.get(s);if(!n)return;if(this._ttl>0&&Date.now()-n.ts>this._ttl){this._cache.delete(s);return}return n.filter}set(e,t,i,s){let n=this._key(e,t,i);if(this._cache.size>=this._maxSize&&!this._cache.has(n))this._cache.delete(this._cache.keys().next().value);this._cache.set(n,{filter:s,ts:Date.now()})}toJSON(){return Object.fromEntries([...this._cache.entries()].map(([e,t])=>[e,t]))}fromJSON(e){if(!e||typeof e!=="object")return;for(let[t,i]of Object.entries(e))this._cache.set(t,i)}get size(){return this._cache.size}}function ql(e,{regexMaxLength:t=500}={}){if(typeof e!=="object"||e===null)return e;let i={};for(let s of Object.keys(e)){let n=e[s];if(n&&typeof n==="object"&&!Array.isArray(n)){let r={};for(let a of Object.keys(n))if(a==="$regex"&&typeof n.$regex==="string"){if(n.$regex.length>t)throw Error(`$regex pattern too long (max ${t} characters)`);if(/\([^)]*[+*][^)]*\)[+*{]/.test(n.$regex))throw Error("$regex pattern rejected: nested quantifiers risk ReDoS");try{r.$regex=new RegExp(n.$regex)}catch{throw Error(`invalid $regex pattern: "${n.$regex}"`)}}else if(["$gt","$gte","$lt","$lte"].includes(a)&&Kl(n[a]))r[a]=new Date(n[a]);else r[a]=n[a];i[s]=r}else i[s]=n}return i}function Kl(e){if(typeof e!=="string")return!1;return/\d{4}-\d{2}-\d{2}/.test(e)&&!isNaN(Date.parse(e))}function Fl(e,t){let i=[];if(!t||typeof e!=="object"||e===null)return i;for(let s of Object.keys(e)){if(s.startsWith("$"))continue;if(!(s.split(".")[0]in t))i.push(`Unknown field referenced in generated filter: "${s}"`)}return i}class ar{constructor(){this._listeners=new Map}on(e,t){if(!this._listeners.has(e))this._listeners.set(e,new Set);return this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}emit(e,t){for(let i of[e,"*"]){let s=this._listeners.get(i);if(!s)continue;for(let n of s)try{n(t)}catch(r){}}}removeAll(e){if(e)this._listeners.delete(e);else this._listeners.clear()}listenerCount(e){return this._listeners.get(e)?.size??0}}class or{constructor({threshold:e=100,maxEntries:t=500}={}){this._threshold=e,this._maxEntries=t,this._entries=[]}record({collection:e,op:t,filter:i,query:s,duration:n,resultCount:r}){if(n<this._threshold)return;let a={collection:e,op:t,duration:n,resultCount:r,timestamp:new Date};if(i!==void 0)a.filter=i;if(s!==void 0)a.query=s;if(this._entries.push(a),this._entries.length>this._maxEntries)this._entries.shift()}entries({limit:e,minDuration:t,collection:i}={}){let s=this._entries;if(i)s=s.filter((n)=>n.collection===i);if(t)s=s.filter((n)=>n.duration>=t);if(e)s=s.slice(-e);return s}get size(){return this._entries.length}clear(){this._entries=[]}}class lr{constructor(){this._sessions=new Map}_ensure(e){if(!this._sessions.has(e))this._sessions.set(e,{reads:0,writes:0,lastActive:null});return this._sessions.get(e)}recordRead(e){if(!e)return;let t=this._ensure(e);t.reads++,t.lastActive=new Date}recordWrite(e){if(!e)return;let t=this._ensure(e);t.writes++,t.lastActive=new Date}get(e){let t=this._sessions.get(e);if(!t)return null;return{sessionId:e,...t}}all(){return[...this._sessions.entries()].map(([e,t])=>({sessionId:e,...t}))}clear(e){if(e)this._sessions.delete(e);else this._sessions.clear()}}class cr{constructor(){this._plugins=[]}register(e){if(typeof e!=="object"||e===null)throw TypeError("Plugin must be a non-null object.");this._plugins.push(e)}async run(e,t){for(let i of this._plugins)if(typeof i[e]==="function")await i[e](t)}get size(){return this._plugins.length}}function Je(e){if(typeof e!=="string"||!e.trim())throw Error("collection name must be a non-empty string");if(/[/\\]/.test(e)||e.includes("..")||e.includes("\x00"))throw Error(`invalid collection name: "${e}"`);if(e.trim().startsWith("_"))throw Error(`access to system collection "${e}" is not permitted`);return e.trim()}var ks=[{name:"skalex_collections",description:"List all collection names in the database.",inputSchema:{type:"object",properties:{}},scope:"read"},{name:"skalex_schema",description:"Return the schema for a collection as a { field: type } map. Returns null if the collection is empty.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."}},required:["collection"]},scope:"read"},{name:"skalex_find",description:"Find documents in a collection that match a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter (MongoDB-style operators supported)."},limit:{type:"number",description:"Maximum number of results. Default: 20."},sort:{type:"object",description:"Sort descriptor: { field: 1 } for ascending, { field: -1 } for descending."}},required:["collection"]},scope:"read"},{name:"skalex_insert",description:"Insert a single document into a collection.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},doc:{type:"object",description:"Document to insert."}},required:["collection","doc"]},scope:"write"},{name:"skalex_update",description:"Update the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},update:{type:"object",description:"Fields to update (direct assignment, $inc, $push supported)."},many:{type:"boolean",description:"If true, update all matching documents. Default: false."}},required:["collection","filter","update"]},scope:"write"},{name:"skalex_delete",description:"Delete the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},many:{type:"boolean",description:"If true, delete all matching documents. Default: false."}},required:["collection","filter"]},scope:"write"},{name:"skalex_search",description:"Semantic similarity search. Requires an embedding adapter to be configured.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},query:{type:"string",description:"Natural-language query string to embed and compare."},limit:{type:"number",description:"Maximum number of results. Default: 10."},minScore:{type:"number",description:"Minimum cosine similarity score [0, 1]. Default: 0."},filter:{type:"object",description:"Optional structured pre-filter (hybrid search)."}},required:["collection","query"]},scope:"read"},{name:"skalex_ask",description:"Translate a natural-language question into a filter and query a collection. Requires a language model adapter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},question:{type:"string",description:"Natural-language question about the data."},limit:{type:"number",description:"Maximum number of results. Default: 20."}},required:["collection","question"]},scope:"read"}];async function Ul(e,t,i){switch(e){case"skalex_collections":return Object.keys(i.collections).filter((s)=>!s.startsWith("_"));case"skalex_schema":return i.schema(Je(t.collection))??null;case"skalex_find":{let s=i.useCollection(Je(t.collection)),n={};if(t.limit)n.limit=t.limit;if(t.sort)n.sort=t.sort;return s.find(t.filter||{},n)}case"skalex_insert":return i.useCollection(Je(t.collection)).insertOne(t.doc||{});case"skalex_update":{let s=i.useCollection(Je(t.collection));if(t.many)return s.updateMany(t.filter||{},t.update||{});return s.updateOne(t.filter||{},t.update||{})}case"skalex_delete":{let s=i.useCollection(Je(t.collection));if(t.many)return s.deleteMany(t.filter||{});return s.deleteOne(t.filter||{})}case"skalex_search":return i.useCollection(Je(t.collection)).search(t.query,{limit:t.limit??10,minScore:t.minScore??0,filter:t.filter});case"skalex_ask":return i.ask(Je(t.collection),t.question,{limit:t.limit??20});default:throw Object.assign(Error(`Unknown tool: ${e}`),{code:"NOT_FOUND"})}}var Mi="2.0",ji=-32700,zl=-32600,Ls=-32601,Bl=-32602,Xl=-32603;function nt(e,t){return{jsonrpc:Mi,id:e,result:t}}function $e(e,t,i,s){return{jsonrpc:Mi,id:e,error:{code:t,message:i}}}function Hl(e){try{let t=JSON.parse(e);if(typeof t!=="object"||t===null||t.jsonrpc!==Mi)return{parseError:$e(null,zl,"Invalid JSON-RPC request")};return{msg:t}}catch(t){return{parseError:$e(null,ji,"Parse error")}}}function Vl(e){return{content:[{type:"text",text:e}]}}function Ps(e){return{content:[{type:"text",text:e}],isError:!0}}class hr{constructor({port:e=3000,host:t="127.0.0.1",allowedOrigin:i=null,maxBodySize:s=1048576}={}){this._port=e,this._host=t,this._allowedOrigin=i,this._maxBodySize=s,this._clients=new Set,this._onMessage=null,this._server=null}onMessage(e){this._onMessage=e}send(e){let t=`data: ${JSON.stringify(e)}
59
59
 
60
- `;for(let i of this._clients)try{i.write(t)}catch(s){this._clients.delete(i)}}start(){return new Promise((e,t)=>{this._server=wo.createServer((i,s)=>{if(this._allowedOrigin)s.setHeader("Access-Control-Allow-Origin",this._allowedOrigin),s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type");if(i.method==="OPTIONS"){s.writeHead(204),s.end();return}if(i.method==="GET"&&i.url==="/sse")this._handleSSE(i,s);else if(i.method==="POST"&&i.url==="/message")this._handleMessage(i,s);else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not Found")}),this._server.on("error",t),this._server.listen(this._port,this._host,()=>e())})}stop(){return new Promise((e)=>{if(!this._server){e();return}for(let t of this._clients)try{t.end()}catch(i){}this._clients.clear(),this._server.close(()=>e()),this._server=null})}_handleSSE(e,t){t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),t.write(`event: endpoint
60
+ `;for(let i of this._clients)try{i.write(t)}catch(s){this._clients.delete(i)}}start(){return new Promise((e,t)=>{this._server=xo.createServer((i,s)=>{if(this._allowedOrigin)s.setHeader("Access-Control-Allow-Origin",this._allowedOrigin),s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type");if(i.method==="OPTIONS"){s.writeHead(204),s.end();return}if(i.method==="GET"&&i.url==="/sse")this._handleSSE(i,s);else if(i.method==="POST"&&i.url==="/message")this._handleMessage(i,s);else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not Found")}),this._server.on("error",t),this._server.listen(this._port,this._host,()=>e())})}stop(){return new Promise((e)=>{if(!this._server){e();return}for(let t of this._clients)try{t.end()}catch(i){}this._clients.clear(),this._server.close(()=>e()),this._server=null})}_handleSSE(e,t){t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),t.write(`event: endpoint
61
61
  data: /message
62
62
 
63
63
  `),this._clients.add(t),e.on("close",()=>{this._clients.delete(t)})}async _handleMessage(e,t){let i="";e.setEncoding("utf8"),e.on("data",(s)=>{if(i+=s,i.length>this._maxBodySize)e.destroy(),t.writeHead(413,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"Request body too large"}))}),e.on("end",async()=>{t.writeHead(202,{"Content-Type":"application/json"}),t.end("{}");let s;try{s=JSON.parse(i)}catch(n){this.send($e(null,ji,"Parse error"));return}if(this._onMessage)await this._onMessage(s).catch(()=>{})})}get port(){return this._port}get host(){return this._host}get url(){return`http://${this._host}:${this._port}`}get sseUrl(){return`${this.url}/sse`}}class dr{constructor(){this._onMessage=null,this._buffer="",this._started=!1}onMessage(e){this._onMessage=e}send(e){process.stdout.write(JSON.stringify(e)+`
64
64
  `)}start(){if(this._started)return;this._started=!0,process.stdin.setEncoding("utf8"),process.stdin.on("data",(e)=>{this._buffer+=e;let t;while((t=this._buffer.indexOf(`
65
- `))!==-1){let i=this._buffer.slice(0,t).trim();if(this._buffer=this._buffer.slice(t+1),i&&this._onMessage){let s;try{s=JSON.parse(i)}catch(n){this.send($e(null,ji,"Parse error"));continue}this._onMessage(s).catch(()=>{})}}}),process.stdin.on("end",()=>{process.exit(0)})}stop(){process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),this._started=!1}}var Hl={name:"skalex",version:"4.0.0-alpha"},Vl="2024-11-05";class ur{constructor(e,t={}){this._db=e,this._transport=t.transport||"stdio",this._port=t.port||3000,this._host=t.host||"127.0.0.1",this._allowedOrigin=t.allowedOrigin??null,this._maxBodySize=t.maxBodySize??1048576,this._scopes=t.scopes||{"*":["read"]},this._t=null}async listen(){if(this._transport==="http")this._t=new hr({port:this._port,host:this._host,allowedOrigin:this._allowedOrigin,maxBodySize:this._maxBodySize});else this._t=new dr;this._t.onMessage((e)=>this._handleMessage(e)),await this._t.start()}async connect(e){if(this._t=e,this._t.onMessage((t)=>this._handleMessage(t)),typeof this._t.start==="function")await this._t.start()}async close(){if(this._t&&typeof this._t.stop==="function")await this._t.stop();this._t=null}get transport(){return this._transport}get url(){return this._t?.url}async _handleMessage(e){let{msg:t,parseError:i}=typeof e==="string"?Bl(e):{msg:e};if(i){this._send(i);return}let{id:s,method:n,params:r}=t;if(s===void 0){if(n==="notifications/initialized")return;return}try{switch(n){case"initialize":this._send(nt(s,{protocolVersion:Vl,capabilities:{tools:{}},serverInfo:Hl}));break;case"tools/list":this._send(nt(s,{tools:this._visibleTools()}));break;case"tools/call":await this._handleToolCall(s,r);break;case"ping":this._send(nt(s,{}));break;default:this._send($e(s,Ls,`Method not found: ${n}`))}}catch(a){this._send($e(s,zl,a.message||"Internal error"))}}async _handleToolCall(e,t){let i=t?.name,s=t?.arguments??{};if(!i){this._send($e(e,Ul,"tools/call requires params.name"));return}let n=ks.find((a)=>a.name===i);if(!n){this._send($e(e,Ls,`Unknown tool: ${i}`));return}let r=s.collection||s.collection_name||null;if(!this._hasScope(r,n.scope)){this._send(nt(e,Ps(`Access denied: "${i}" requires "${n.scope}" scope on collection "${r}".`)));return}try{let a=await Kl(i,s,this._db);this._send(nt(e,Xl(JSON.stringify(a,null,2))))}catch(a){this._send(nt(e,Ps(a.message||String(a))))}}_visibleTools(){return ks.filter((e)=>{let t=this._scopes["*"];if(t&&(t.includes(e.scope)||t.includes("admin")))return!0;for(let[,i]of Object.entries(this._scopes))if(i.includes(e.scope)||i.includes("admin"))return!0;return!1})}_hasScope(e,t){let i=(s)=>s.includes("admin")||s.includes(t);if(e&&this._scopes[e])return i(this._scopes[e]);if(this._scopes["*"])return i(this._scopes["*"]);return!1}_send(e){this._t?.send(e)}}var It="migrations",Ms=(e)=>JSON.stringify(e,function(t,i){let s=this[t];if(s instanceof Date)return{__skalex_date__:s.toISOString()};if(typeof i==="bigint")return{__skalex_bigint__:i.toString()};return i}),js=(e)=>JSON.parse(e,(t,i)=>{if(i&&typeof i==="object"){if("__skalex_bigint__"in i)return BigInt(i.__skalex_bigint__);if("__skalex_date__"in i)return new Date(i.__skalex_date__)}return i});class te{constructor({path:e="./.db",format:t="gz",debug:i=!1,adapter:s,ai:n,encrypt:r,slowQueryLog:a,queryCache:l,memory:o,logger:c,plugins:h,llmAdapter:u,embeddingAdapter:d,regexMaxLength:_,idGenerator:f,serializer:p,deserializer:m,autoSave:w,ttlSweepInterval:x,lenientLoad:R}={}){if(this.dataDirectory=e,this.dataFormat=t,this.debug=i,!te._errorsAttached)te.SkalexError=je,te.ValidationError=$,te.UniqueConstraintError=Ee,te.TransactionError=ge,te.PersistenceError=ke,te.AdapterError=_e,te.QueryError=Ge,te._errorsAttached=!0;this._adapterConfig=s??null;let E=s||new Hn({dir:e,format:t});if(r)E=new ir(E,r.key);if(this.fs=E,this._registry=new Wn(Xn),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._migrations=new Vn,this._connectPromise=null,this.isConnected=!1,this._aiConfig=n||null,this._encryptConfig=r||null,this._pluginsConfig=Array.isArray(h)?h:null,this._memoryConfig=o||null,this._regexMaxLength=_??500,this._idGenerator=f??null,this._serializer=p??Ms,this._deserializer=m??js,this._autoSave=w??!1,this._txManager=new Yn,this._ttlSweepInterval=x??0,this._ttlTimer=null,this._logger=c??Ts,this._embeddingAdapter=d??(n?Ol(n):null),this._aiAdapter=u??(n?Nl(n):null),this._persistence=new Jn({adapter:this.fs,serializer:this._serializer,deserializer:this._deserializer,logger:this._logger,debug:this.debug,lenientLoad:R??!1}),this._changeLog=new nr(this),this._queryCache=new rr(l||{}),this._eventBus=new ar,this._queryLog=a?new or(a):null,this._sessionStats=new lr,this._plugins=new cr,Array.isArray(h))for(let A of h)this._plugins.register(A)}async connect(){if(this._connectPromise)return this._connectPromise;return this._connectPromise=this._doConnect(),this._connectPromise}async _doConnect(){try{await this.loadData();let e=this._getMeta();if(e.queryCache)this._queryCache.fromJSON(e.queryCache);if(this._migrations._migrations.length>0){let t=e.appliedVersions||[],i=await this._migrations.run((s)=>this.useCollection(`_migration_${s}`),t);this._saveMeta({appliedVersions:i})}if(this._sweepTtl(),this._ttlSweepInterval>0){if(this._ttlTimer=setInterval(()=>this._sweepTtl(),this._ttlSweepInterval),this._ttlTimer?.unref)this._ttlTimer.unref()}this.isConnected=!0,this._log("> - Connected to the database (\u221A)")}catch(e){throw this._logger(`Error connecting to the database: ${e}`,"error"),e}}async disconnect(){try{if(this._ttlTimer)clearInterval(this._ttlTimer),this._ttlTimer=null;await this.saveData(),this._registry.clear(),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._connectPromise=null,this.isConnected=!1,this._log("> - Disconnected from the database (\u221A)")}catch(e){throw this._logger(`Error disconnecting from the database: ${e}`,"error"),e}}async _ensureConnected(){if(this.isConnected)return;return this.connect()}useCollection(e){return this._registry.get(e,this)}createCollection(e,t={}){return this._registry.create(e,t,this)}_createCollectionStore(e,t={}){this._registry.createStore(e,t)}async renameCollection(e,t){this._registry.rename(e,t),await this.saveData(t),await this.fs.delete(e)}async loadData(){await this._persistence.loadAll(this.collections,{parseSchema:Fn,buildIndex:this._registry.buildIndex,IndexEngine:Rt});for(let e in this._collectionInstances){let t=this.collections[e];if(t&&this._collectionInstances[e]._store!==t)this._collectionInstances[e]._store=t}}async saveData(e){await this._persistence.save(this.collections,e)}buildIndex(e,t){return this._registry.buildIndex(e,t)}addMigration(e){this._migrations.add(e)}migrationStatus(){let e=this._getMeta();return this._migrations.status(e.appliedVersions||[])}namespace(e){if(this._adapterConfig)throw new _e("ERR_SKALEX_ADAPTER_NAMESPACE_REQUIRES_FS","namespace() requires the default FsAdapter. When a custom storage adapter is configured, create a separate Skalex instance with your adapter instead.");let t=String(e).replace(/[^a-zA-Z0-9_-]/g,"_");if(!t)throw new $("ERR_SKALEX_VALIDATION_NAMESPACE_ID","namespace: id must contain at least one alphanumeric character",{id:e});return new te({path:`${this.dataDirectory}/${t}`,format:this.dataFormat,debug:this.debug,ai:this._aiConfig||void 0,encrypt:this._encryptConfig||void 0,slowQueryLog:this._queryLog?{threshold:this._queryLog._threshold,maxEntries:this._queryLog._maxEntries}:void 0,queryCache:this._queryCache?{maxSize:this._queryCache._maxSize,ttl:this._queryCache._ttl}:void 0,plugins:this._pluginsConfig||void 0,memory:this._memoryConfig||void 0,logger:this._logger!==Ts?this._logger:void 0,llmAdapter:this._aiAdapter&&!this._aiConfig?this._aiAdapter:void 0,embeddingAdapter:this._embeddingAdapter&&!this._aiConfig?this._embeddingAdapter:void 0,regexMaxLength:this._regexMaxLength!==500?this._regexMaxLength:void 0,idGenerator:this._idGenerator||void 0,serializer:this._serializer!==Ms?this._serializer:void 0,deserializer:this._deserializer!==js?this._deserializer:void 0,autoSave:this._autoSave||void 0,ttlSweepInterval:this._ttlSweepInterval||void 0})}use(e){this._plugins.register(e)}watch(e){return this._eventBus.on("*",e)}sessionStats(e){if(e!==void 0)return this._sessionStats.get(e);return this._sessionStats.all()}get _inTransaction(){return this._txManager.active}_emitEvent(e,t){if(!this._txManager.defer(()=>this._eventBus.emit(e,t)))this._eventBus.emit(e,t)}async _runAfterHook(e,t){if(!this._txManager.defer(()=>this._plugins.run(e,t)))await this._plugins.run(e,t)}async _logChange(e,t,i,s,n){if(!this._txManager.defer(()=>this._changeLog.log(e,t,i,s,n)))await this._changeLog.log(e,t,i,s,n)}async transaction(e,t={}){return this._txManager.run(e,this,t)}async seed(e,{reset:t=!1}={}){for(let[i,s]of Object.entries(e)){if(t&&this.collections[i])this._applySnapshot(i,{data:[],index:new Map}),delete this._collectionInstances[i];await this.useCollection(i).insertMany(s)}await this.saveData()}dump(){return this._registry.dump()}inspect(e){return this._registry.inspect(e)}async import(e){let t=await this.fs.readRaw(e),i;try{i=JSON.parse(t)}catch{throw new ke("ERR_SKALEX_PERSISTENCE_INVALID_JSON",`import: invalid JSON in file "${e}"`,{filePath:e})}let s=e.split("/").pop().replace(/\.[^.]+$/,"");return this.useCollection(s).insertMany(Array.isArray(i)?i:[i],{save:!0})}async embed(e){if(!this._embeddingAdapter)throw new _e("ERR_SKALEX_ADAPTER_EMBEDDING_REQUIRED","db.embed() requires an AI adapter. Pass { ai: { provider, apiKey } } to the Skalex constructor.");return this._embeddingAdapter.embed(e)}async ask(e,t,{limit:i=20}={}){if(!this._aiAdapter)throw new _e("ERR_SKALEX_ADAPTER_LLM_REQUIRED",'db.ask() requires a language model adapter. Configure { ai: { provider, model: "..." } }.');let s=this.useCollection(e),n=this.schema(e),r=this._queryCache.get(e,n,t);if(!r){r=await this._aiAdapter.generate(n,t);let a=ql(r,n);if(a.length)a.forEach((l)=>this._log(`[ask] ${l}`));this._queryCache.set(e,n,t,r),this._saveMeta({queryCache:this._queryCache.toJSON()})}return s.find(Ml(r,{regexMaxLength:this._regexMaxLength}),{limit:i})}schema(e){return this._registry.schema(e)}useMemory(e){return new sr(e,this)}changelog(){return this._changeLog}async restore(e,t,i={}){return this._changeLog.restore(e,t,i)}stats(e){return this._registry.stats(e)}slowQueries(e={}){if(!this._queryLog)return[];return this._queryLog.entries(e)}slowQueryCount(){return this._queryLog?this._queryLog.size:0}clearSlowQueries(){this._queryLog?.clear()}mcp(e={}){return new ur(this,e)}_getMeta(){let e=this.collections._meta;if(!e)return{};return e.index.get(It)||{}}_saveMeta(e){if(!this.collections._meta)this._createCollectionStore("_meta");let t=this.collections._meta,i=t.index.get(It);if(i)Object.assign(i,e);else{let s={_id:It,...e};t.data.push(s),t.index.set(It,s)}this._persistence.markDirty(this.collections,"_meta")}_sweepTtl(){for(let e in this.collections){let t=this.collections[e],i=xl(t.data,t.index,t.fieldIndex?(s)=>t.fieldIndex.remove(s):null);if(i>0)this._persistence.markDirty(this.collections,e),this._log(`TTL sweep: removed ${i} expired docs from "${e}"`)}}_buildCollectionContext(){let e=this;return{ensureConnected:()=>e._ensureConnected(),get txManager(){return e._txManager},get plugins(){return e._plugins},get eventBus(){return e._eventBus},get sessionStats(){return e._sessionStats},get queryLog(){return e._queryLog},get logger(){return e._logger},get persistence(){return e._persistence},get collections(){return e.collections},embed:(t)=>e.embed(t),get idGenerator(){return e._idGenerator},get autoSave(){return e._autoSave},saveCollection:(t)=>e.saveData(t),snapshotCollection:(t)=>e._snapshotCollection(t),getCollection:(t)=>e.useCollection(t),emitEvent:(t,i)=>e._emitEvent(t,i),runAfterHook:(t,i)=>e._runAfterHook(t,i),logChange:(t,i,s,n,r)=>e._logChange(t,i,s,n,r),get fs(){return e.fs},get dataDirectory(){return e.dataDirectory}}}_log(e){if(this.debug)this._logger(e,"info")}_snapshotCollection(e){return{data:structuredClone(e.data)}}_applySnapshot(e,t){let i=this.collections[e];if(!i)return;if(i.data=t.data,i.index=this.buildIndex(t.data,"_id"),i.fieldIndex)i.fieldIndex.buildFromData(t.data)}}function Jl(){let e=Date.now().toString(16),t;try{t=To.randomBytes(8).toString("hex")}catch{let i=new Uint8Array(8);crypto.getRandomValues(i),t=Array.from(i).map((s)=>s.toString(16).padStart(2,"0")).join("")}return`${e}${t}`}function qs(e,t){let i=e instanceof Error?e.message:e;if(t==="error")console.error(i);else console.log(i)}var Ks=new Set(["__proto__","constructor","prototype"]);function Kt(e,t){if(!t.includes(".")){if(Ks.has(t))return;return e[t]}let i=e;for(let s of t.split(".")){if(Ks.has(s))return;if(i==null)return;i=i[s]}return i}class qe extends Error{constructor(e,t,i={}){super(t);this.name=this.constructor.name,this.code=e,this.details=i}}class D extends qe{}class Ie extends qe{}class ye extends qe{}class Le extends qe{}class fe extends qe{}class Ze extends qe{}function xi(e,t){if(e===t)return!0;if(e==null||t==null)return!1;if(typeof e!==typeof t)return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.source===t.source&&e.flags===t.flags;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!xi(e[i],t[i]))return!1;return!0}if(typeof e==="object"){if(Array.isArray(t))return!1;let i=Object.keys(e);if(i.length!==Object.keys(t).length)return!1;for(let s of i){if(!Object.prototype.hasOwnProperty.call(t,s))return!1;if(!xi(e[s],t[s]))return!1}return!0}return!1}function J(e,t){if(typeof t==="function")return t(e);if(t==null)return!0;if(typeof t==="object"&&Object.keys(t).length===0)return!0;if("$or"in t){let i=t.$or;if(!Array.isArray(i))throw new Ze("ERR_SKALEX_QUERY_INVALID_OPERATOR","$or must be an array of filters",{operator:"$or"});if(!i.some((s)=>J(e,s)))return!1}if("$and"in t){let i=t.$and;if(!Array.isArray(i))throw new Ze("ERR_SKALEX_QUERY_INVALID_OPERATOR","$and must be an array of filters",{operator:"$and"});if(!i.every((s)=>J(e,s)))return!1}if("$not"in t){if(J(e,t.$not))return!1}for(let i in t){if(i==="$or"||i==="$and"||i==="$not")continue;let s=t[i],n;try{n=Kt(e,i)}catch{return!1}if(s instanceof RegExp){if(!s.test(String(n)))return!1}else if(typeof s==="object"&&s!==null){if(Object.keys(s).some((r)=>r.startsWith("$"))){if("$eq"in s&&n!==s.$eq)return!1;if("$ne"in s&&n===s.$ne)return!1;if("$gt"in s&&!(n>s.$gt))return!1;if("$lt"in s&&!(n<s.$lt))return!1;if("$gte"in s&&!(n>=s.$gte))return!1;if("$lte"in s&&!(n<=s.$lte))return!1;if("$in"in s&&!s.$in.includes(n))return!1;if("$nin"in s&&s.$nin.includes(n))return!1;if("$regex"in s){if(!(s.$regex instanceof RegExp?s.$regex:new RegExp(s.$regex)).test(String(n)))return!1}if("$fn"in s&&!s.$fn(n))return!1}else if(!xi(n,s))return!1}else if(n!==s)return!1}return!0}function Yl(e,t=new Set){if(typeof e!=="object"||e===null||typeof e==="function")return e;let i=[],s=[],n=[],r=[],a=[];for(let o in e){if(o==="$or"||o==="$and"||o==="$not"){a.push(o);continue}let c=e[o];if(t.has(o))i.push(o);else if(c instanceof RegExp||typeof c==="object"&&c!==null&&(("$regex"in c)||("$fn"in c))||typeof c==="function")r.push(o);else if(typeof c==="object"&&c!==null&&(("$gt"in c)||("$lt"in c)||("$gte"in c)||("$lte"in c)||("$ne"in c)||("$in"in c)||("$nin"in c)))n.push(o);else s.push(o)}let l={};for(let o of[...i,...s,...n,...r,...a])l[o]=e[o];return l}var vi=new Set(["string","number","boolean","object","array","date","any"]);function qi(e){if(Array.isArray(e))return"array";if(e instanceof Date)return"date";return typeof e}function _r(e){let t=new Map,i=[];for(let[s,n]of Object.entries(e)){let r;if(typeof n==="string"){if(!vi.has(n))throw new D("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${n}" for field "${s}"`,{field:s,type:n});r={type:n,required:!1,unique:!1}}else if(typeof n==="object"&&n!==null){let{type:a="any",required:l=!1,unique:o=!1,enum:c}=n;if(!vi.has(a))throw new D("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${a}" for field "${s}"`,{field:s,type:a});if(r={type:a,required:l,unique:o,enum:c},o)i.push(s)}else throw new D("ERR_SKALEX_VALIDATION_INVALID_SCHEMA",`Invalid schema definition for field "${s}"`,{field:s});t.set(s,r)}return{fields:t,uniqueFields:i}}function Fs(e,t,i=!1){let s=[];for(let[n,r]of t){let a=e[n],l=a===void 0||a===null;if(r.required&&l){s.push(`Field "${n}" is required`);continue}if(l)continue;if(r.type!=="any"){let o=qi(a);if(o!==r.type)s.push(`Field "${n}" must be of type "${r.type}", got "${o}"`)}if(r.enum&&!r.enum.includes(a))s.push(`Field "${n}" must be one of [${r.enum.map((o)=>JSON.stringify(o)).join(", ")}], got ${JSON.stringify(a)}`)}if(i){for(let n of Object.keys(e))if(!n.startsWith("_")&&!t.has(n))s.push(`Unknown field "${n}" (strict mode)`)}return s}function Us(e,t){let i={};for(let[s,n]of Object.entries(e)){if(s.startsWith("_")){i[s]=n;continue}if(!t.has(s))continue;let r=t.get(s);if(r.type!=="any"){if(qi(n)!==r.type)continue}if(r.enum&&!r.enum.includes(n))continue;i[s]=n}return i}function Wl(e){let t={};for(let[i,s]of Object.entries(e)){if(i.startsWith("_"))continue;let n=qi(s);t[i]=vi.has(n)?n:"any"}return t}function Ql(e){if(typeof e==="number"){if(e<=0)throw new D("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got ${e}`,{ttl:e});return e*1000}if(typeof e!=="string")throw new D("ERR_SKALEX_VALIDATION_TTL",`Invalid TTL value: ${e}`,{ttl:e});let t=e.match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/);if(!t)throw new D("ERR_SKALEX_VALIDATION_TTL_FORMAT",`Invalid TTL format: "${e}". Use e.g. 300 (seconds), "30m", "24h", "7d"`,{ttl:e});let i=parseFloat(t[1]);if(i<=0)throw new D("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got "${e}"`,{ttl:e});let s=t[2],n=i*{ms:1,s:1000,m:60000,h:3600000,d:86400000}[s];if(!isFinite(n))throw new D("ERR_SKALEX_VALIDATION_TTL",`TTL value "${e}" is too large`,{ttl:e});return n}function Gl(e){return new Date(Date.now()+Ql(e))}function Zl(e,t,i=null){let s=Date.now(),n=0,r=e.length;while(r--){let a=e[r];if(a._expiresAt&&new Date(a._expiresAt).getTime()<=s){if(e.splice(r,1),t.delete(a._id),i)i(a);n++}}return n}function zs(e,t){if(e.length!==t.length)throw new Ze("ERR_SKALEX_QUERY_VECTOR_MISMATCH",`Vector dimension mismatch: ${e.length} vs ${t.length}`,{expected:e.length,got:t.length});let i=0,s=0,n=0;for(let a=0;a<e.length;a++)i+=e[a]*t[a],s+=e[a]*e[a],n+=t[a]*t[a];let r=Math.sqrt(s*n);return r===0?0:i/r}function B(e){if(!("_vector"in e))return{...e};let{_vector:t,...i}=e;return i}function ec(e){return e.length}function tc(e,t){let i=0;for(let s of e){let n=Kt(s,t);if(typeof n==="number"&&!isNaN(n))i+=n}return i}function ic(e,t){let i=0,s=0;for(let n of e){let r=Kt(n,t);if(typeof r==="number"&&!isNaN(r))i+=r,s++}return s===0?null:i/s}function sc(e,t){let i=Object.create(null);for(let s of e){let n=String(Kt(s,t)??"__null__");if(!i[n])i[n]=[];i[n].push(s)}return i}class fr{constructor(e){this._col=e}get _ctx(){return this._col._ctx}async execute({op:e,beforeHook:t,afterHook:i,hookPayload:s,mutate:n,afterHookPayload:r,save:a,session:l}){let o=this._ctx;await o.ensureConnected(),this._col._txSnapshotIfNeeded();let c=o.txManager,h=c.active&&this._col._activeTxId===c.context?.id,u=h?c.context.id:null,d=this._col._createdInTxId,_=()=>{if(u!==null&&c._abortedIds.has(u))throw new ye("ERR_SKALEX_TX_ABORTED",`Transaction ${u} was aborted. No further mutations allowed.`);if(d!==null&&c._abortedIds.has(d))throw new ye("ERR_SKALEX_TX_ABORTED",`Transaction ${d} was aborted. Collection obtained inside that transaction cannot be used for further mutations.`)};if(h||d!==null)_();if(t)await o.plugins.run(t,s);let{docs:f,prevDocs:p=[]}=await n(_);if(o.persistence.markDirty(o.collections,this._col.name),await this._col._saveIfNeeded(a),this._col._changelogEnabled)for(let m=0;m<f.length;m++)await o.logChange(e,this._col.name,f[m],p[m]??null,l||null);if(!h||!c.defer(()=>o.sessionStats.recordWrite(l)))o.sessionStats.recordWrite(l);for(let m of f)o.emitEvent(this._col.name,{op:e,collection:this._col.name,doc:B(m)});if(i)if(r)await o.runAfterHook(i,r(f));else for(let m of f)await o.runAfterHook(i,{collection:this._col.name,doc:B(m)});return{docs:f,prevDocs:p}}}function nc(e){let t={};for(let i in e){if(i.startsWith("$"))continue;let s=e[i];if(s&&typeof s==="object"&&!Array.isArray(s)){let n=Object.keys(s);if(n.length===1&&n[0]==="$eq")t[i]=s.$eq}else t[i]=s}return t}var pr=new Set(["__proto__","constructor","prototype"]);function mr(e){if(typeof e!=="object"||e===null||Array.isArray(e))return e;let t={};for(let i of Object.keys(e)){if(pr.has(i))continue;t[i]=mr(e[i])}return t}class gr{constructor(e,t){this.name=e.collectionName,this.database=t,this._ctx=t._buildCollectionContext(),this._store=e,this._pipeline=new fr(this),this._createdInTxId=t._txManager.context?.id??null,this._activeTxId=null}get _data(){return this._store.data}set _data(e){this._store.data=e}get _index(){return this._store.index}get _fieldIndex(){return this._store.fieldIndex||null}get _schema(){return this._store.schema?this._store.schema.fields:null}get _changelogEnabled(){return this._store.changelog===!0}get _softDelete(){return this._store.softDelete===!0}get _versioning(){return this._store.versioning===!0}get _strict(){return this._store.strict===!0}get _onSchemaError(){return this._store.onSchemaError??"throw"}get _defaultTtl(){return this._store.defaultTtl||null}get _defaultEmbed(){return this._store.defaultEmbed||null}get _maxDocs(){return this._store.maxDocs||null}async insertOne(e,t={}){let{save:i,ifNotExists:s,ttl:n,embed:r,session:a}=t;if(s){await this._ctx.ensureConnected();let o=this._findRaw(e);if(o)return B({...o})}let{docs:l}=await this._insertCore([e],{ttl:n,embed:r,session:a,save:i});return B(l[0])}async insertMany(e,t={}){let{save:i,ttl:s,embed:n,session:r}=t,{docs:a}=await this._insertCore(e,{ttl:s,embed:n,session:r,save:i});return a.map(B)}async _insertCore(e,{ttl:t,embed:i,session:s,save:n}){return this._pipeline.execute({op:"insert",beforeHook:null,afterHook:"afterInsert",hookPayload:null,save:n,session:s,mutate:async(r)=>{let a=[],l=new Set;for(let o of e){let c=this._applyValidation(o);await this._ctx.plugins.run("beforeInsert",{collection:this.name,doc:c});let h=await this._buildDoc(c,{ttl:t,embed:i});if(this._index.has(h._id)||l.has(h._id))throw new Ie("ERR_SKALEX_UNIQUE_DUPLICATE_ID",`Duplicate _id "${h._id}" in collection "${this.name}"`,{id:h._id,collection:this.name});l.add(h._id),a.push(h)}if(r(),this._fieldIndex)this._fieldIndex.assertUniqueBatch(a);for(let o of a)this._addToIndex(o);this._data.push(...a);for(let o of a)this._index.set(o._id,o);return this._enforceCapAfterInsert(),{docs:a}}})}async updateOne(e,t,i={}){await this._ctx.ensureConnected();let s=this._findRaw(e);if(!s)return null;let{save:n,session:r}=i,{docs:a}=await this._updateCore([s],e,t,{save:n,session:r});return B(a[0])}async updateMany(e,t,i={}){await this._ctx.ensureConnected();let s=this._findAllRaw(e);if(s.length===0)return[];let{save:n,session:r}=i,{docs:a}=await this._updateCore(s,e,t,{save:n,session:r});return a.map(B)}async _updateCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"update",beforeHook:"beforeUpdate",afterHook:"afterUpdate",hookPayload:{collection:this.name,filter:t,update:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:t,update:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{let a=this._changelogEnabled?e.map((h)=>structuredClone(h)):e.map(()=>null),l=e.map((h)=>this._prepareUpdatedDoc(h,i));this._assertUniqueCandidates(e,l),r();let o=new Set(e),c=new Map;for(let h=0;h<this._data.length;h++)if(o.has(this._data[h]))c.set(this._data[h],h);for(let h=0;h<e.length;h++)this._commitUpdatedDoc(e[h],l[h],c);return{docs:l,prevDocs:a}}})}applyUpdate(e,t){for(let i in t){if(pr.has(i))continue;if(i==="_id"||i==="createdAt")continue;let s=t[i];if(Array.isArray(s))e[i]=s;else if(typeof s==="object"&&s!==null){let n=Object.keys(s);if(n.some((r)=>r.startsWith("$"))){for(let r of n)if(r==="$inc"&&typeof e[i]==="number")e[i]+=s[r];else if(r==="$push"){if(!Array.isArray(e[i]))e[i]=[];e[i].push(s[r])}}else e[i]=mr(s)}else e[i]=s}if(e.updatedAt=new Date,this._versioning)e._version=(e._version??0)+1;return e}_prepareUpdatedDoc(e,t){let i=structuredClone(e),s=structuredClone(e);if(this.applyUpdate(s,t),!this._schema)return s;let n=Fs(s,this._schema,this._strict);if(!n.length)return s;switch(this._onSchemaError){case"throw":throw new D("ERR_SKALEX_VALIDATION_UPDATE",`Update validation failed on doc "${e._id}": ${n.join("; ")}`,{id:e._id,errors:n});case"strip":return this._stripCandidateToValid(s,i);default:return this._ctx.logger(`[${this.name}] Update validation warning: ${n.join("; ")}`,"warn"),s}}_stripCandidateToValid(e,t){let i=Us(e,this._schema),s=structuredClone(t);for(let[n,r]of Object.entries(i)){if(n.startsWith("_"))continue;s[n]=r}if(s.updatedAt=e.updatedAt,this._versioning)s._version=e._version;return s}_commitUpdatedDoc(e,t,i){let s=i?i.get(e):this._data.indexOf(e);if(s===void 0||s===-1)throw new Le("ERR_SKALEX_PERSISTENCE_DOC_MISSING",`Document "${e._id}" no longer exists in collection "${this.name}"`,{id:e._id,collection:this.name});this._data[s]=t,this._index.set(t._id,t),this._updateInIndex(e,t)}_assertUniqueCandidates(e,t){this._fieldIndex?.assertUniqueCandidates(e,t)}async upsert(e,t,i={}){if(await this._ctx.ensureConnected(),this._findRaw(e))return this.updateOne(e,t,i);return this.insertOne({...nc(e),...t},i)}async upsertMany(e,t,i={}){await this._ctx.ensureConnected();let{save:s,...n}=i,r=[];for(let a of e)r.push(await this.upsert({[t]:a[t]},a,{...n,save:!1}));return await this._saveIfNeeded(s),r}async restore(e,t={}){if(!this._softDelete)throw new Ze("ERR_SKALEX_QUERY_SOFT_DELETE_REQUIRED",`restore() requires softDelete on "${this.name}"`,{collection:this.name});await this._ctx.ensureConnected();let{save:i,session:s}=t,n=this._findRaw(e,{includeDeleted:!0});if(!n||!n._deletedAt)return null;let{docs:r}=await this._pipeline.execute({op:"restore",beforeHook:null,afterHook:null,hookPayload:null,save:i,session:s,mutate:async(a)=>{return a(),delete n._deletedAt,n.updatedAt=new Date,this._index.set(n._id,n),{docs:[n]}}});return B(r[0])}watch(e,t){if(typeof e==="function")t=e,e=null;if(t)return this._ctx.eventBus.on(this.name,(i)=>{if(!e||J(i.doc,e))t(i)});return this._watchIterator(e)}_watchIterator(e){let t=[],i=null,s=!1,n=this._ctx.eventBus.on(this.name,(r)=>{if(e&&!J(r.doc,e))return;if(i){let a=i;i=null,a({value:r,done:!1})}else t.push(r)});return{[Symbol.asyncIterator](){return this},next(){if(t.length>0)return Promise.resolve({value:t.shift(),done:!1});if(s)return Promise.resolve({value:void 0,done:!0});return new Promise((r)=>{i=r})},return(){if(s=!0,n(),i){let r=i;i=null,r({value:void 0,done:!0})}return Promise.resolve({value:void 0,done:!0})}}}async count(e={}){return await this._ctx.ensureConnected(),ec(this._findAllRaw(e))}async sum(e,t={}){return await this._ctx.ensureConnected(),tc(this._findAllRaw(t),e)}async avg(e,t={}){return await this._ctx.ensureConnected(),ic(this._findAllRaw(t),e)}async groupBy(e,t={}){return await this._ctx.ensureConnected(),sc(this._findAllRaw(t),e)}async findOne(e,t={}){await this._ctx.ensureConnected();let{populate:i,select:s,includeDeleted:n=!1}=t,r=this._findRaw(e,{includeDeleted:n});if(!r)return null;let a=this._projectDoc(r,s);if(i)await this._populateDoc(a,r,i);return a}async find(e,t={}){await this._ctx.ensureConnected();let i=Date.now(),{populate:s,select:n,sort:r,page:a=1,limit:l,session:o,includeDeleted:c=!1}=t;await this._ctx.plugins.run("beforeFind",{collection:this.name,filter:e,options:t});let h=this._getCandidates(e),u=Yl(e,this._fieldIndex?this._fieldIndex.indexedFields:new Set),d=[];for(let f of h){if(this._softDelete&&f._deletedAt&&!c)continue;if(!J(f,u))continue;let p=this._projectDoc(f,n);if(s)await this._populateDoc(p,f,s);d.push(p)}if(r){let f=Object.keys(r);d.sort((p,m)=>{for(let w of f){let x=r[w];if(p[w]<m[w])return-x;if(p[w]>m[w])return x}return 0})}let _;if(l){let f=d.length,p=Math.ceil(f/l),m=(a-1)*l;d=d.slice(m,m+l),_={page:a,totalDocs:f,totalPages:p}}return this._ctx.queryLog?.record({collection:this.name,op:"find",filter:e,duration:Date.now()-i,resultCount:d.length}),this._ctx.sessionStats.recordRead(o),await this._ctx.plugins.run("afterFind",{collection:this.name,filter:e,options:t,docs:d}),_?{docs:d,..._}:{docs:d}}async search(e,{filter:t,limit:i=10,minScore:s=0,session:n}={}){await this._ctx.ensureConnected();let r=Date.now();await this._ctx.plugins.run("beforeSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s}});let a=await this._ctx.embed(e),l=t?this._findAllRaw(t):this._data,o=[];for(let d of l){if(!d._vector)continue;let _=zs(a,d._vector);if(_>=s)o.push({doc:d,score:_})}o.sort((d,_)=>_.score-d.score);let c=o.slice(0,i);this._ctx.queryLog?.record({collection:this.name,op:"search",query:e,duration:Date.now()-r,resultCount:c.length}),this._ctx.sessionStats.recordRead(n);let h=c.map((d)=>B(d.doc)),u=c.map((d)=>d.score);return await this._ctx.plugins.run("afterSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s},docs:h,scores:u}),{docs:h,scores:u}}async similar(e,{limit:t=10,minScore:i=0}={}){await this._ctx.ensureConnected();let s=this._index.get(e);if(!s||!s._vector)return{docs:[],scores:[]};let n=[];for(let a of this._data){if(a._id===e||!a._vector)continue;let l=zs(s._vector,a._vector);if(l>=i)n.push({doc:a,score:l})}n.sort((a,l)=>l.score-a.score);let r=n.slice(0,t);return{docs:r.map((a)=>B(a.doc)),scores:r.map((a)=>a.score)}}async deleteOne(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findRaw(e);if(!r)return null;let{docs:a}=await this._deleteCore("soft",[r],e,{save:i,session:s});return B(a[0])}let{docs:n}=await this._deleteCore("hard",null,e,{save:i,session:s});if(n.length===0)return null;return B(n[0])}async deleteMany(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findAllRaw(e);if(r.length===0)return[];let{docs:a}=await this._deleteCore("soft",r,e,{save:i,session:s});return a.map(B)}let{docs:n}=await this._deleteCore("hardMany",null,e,{save:i,session:s});return n.map(B)}async _deleteCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"delete",beforeHook:"beforeDelete",afterHook:"afterDelete",hookPayload:{collection:this.name,filter:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{if(r(),e==="soft"){let o=new Date;for(let c of t)c._deletedAt=o,c.updatedAt=o,this._index.set(c._id,c);return{docs:t}}if(e==="hard"){let o=this._findIndex(i);if(o===-1)return{docs:[]};let c=this._data.splice(o,1)[0];return this._index.delete(c._id),this._removeFromIndex(c),{docs:[c]}}let a=[],l=[];for(let o of this._data)if(J(o,i))a.push(o),this._index.delete(o._id),this._removeFromIndex(o);else l.push(o);return this._data=l,{docs:a}}})}async export(e={},t={}){let{dir:i,name:s,format:n="json"}=t;try{let r=this._data.filter((h)=>J(h,e));if(r.length===0)throw new Ze("ERR_SKALEX_QUERY_EXPORT_EMPTY",`export(): no documents matched the filter in "${this.name}"`,{collection:this.name});let a;if(n==="json")a=JSON.stringify(r,null,2);else{let h=(_)=>{if(_==null)return"";let f=typeof _==="object"?JSON.stringify(_):String(_);return f.includes(",")||f.includes('"')||f.includes(`
65
+ `))!==-1){let i=this._buffer.slice(0,t).trim();if(this._buffer=this._buffer.slice(t+1),i&&this._onMessage){let s;try{s=JSON.parse(i)}catch(n){this.send($e(null,ji,"Parse error"));continue}this._onMessage(s).catch(()=>{})}}}),process.stdin.on("end",()=>{process.exit(0)})}stop(){process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),this._started=!1}}var Jl={name:"skalex",version:"4.0.0-alpha"},Yl="2024-11-05";class ur{constructor(e,t={}){this._db=e,this._transport=t.transport||"stdio",this._port=t.port||3000,this._host=t.host||"127.0.0.1",this._allowedOrigin=t.allowedOrigin??null,this._maxBodySize=t.maxBodySize??1048576,this._scopes=t.scopes||{"*":["read"]},this._t=null}async listen(){if(this._transport==="http")this._t=new hr({port:this._port,host:this._host,allowedOrigin:this._allowedOrigin,maxBodySize:this._maxBodySize});else this._t=new dr;this._t.onMessage((e)=>this._handleMessage(e)),await this._t.start()}async connect(e){if(this._t=e,this._t.onMessage((t)=>this._handleMessage(t)),typeof this._t.start==="function")await this._t.start()}async close(){if(this._t&&typeof this._t.stop==="function")await this._t.stop();this._t=null}get transport(){return this._transport}get url(){return this._t?.url}async _handleMessage(e){let{msg:t,parseError:i}=typeof e==="string"?Hl(e):{msg:e};if(i){this._send(i);return}let{id:s,method:n,params:r}=t;if(s===void 0){if(n==="notifications/initialized")return;return}try{switch(n){case"initialize":this._send(nt(s,{protocolVersion:Yl,capabilities:{tools:{}},serverInfo:Jl}));break;case"tools/list":this._send(nt(s,{tools:this._visibleTools()}));break;case"tools/call":await this._handleToolCall(s,r);break;case"ping":this._send(nt(s,{}));break;default:this._send($e(s,Ls,`Method not found: ${n}`))}}catch(a){this._send($e(s,Xl,a.message||"Internal error"))}}async _handleToolCall(e,t){let i=t?.name,s=t?.arguments??{};if(!i){this._send($e(e,Bl,"tools/call requires params.name"));return}let n=ks.find((a)=>a.name===i);if(!n){this._send($e(e,Ls,`Unknown tool: ${i}`));return}let r=s.collection||s.collection_name||null;if(!this._hasScope(r,n.scope)){this._send(nt(e,Ps(`Access denied: "${i}" requires "${n.scope}" scope on collection "${r}".`)));return}try{let a=await Ul(i,s,this._db);this._send(nt(e,Vl(JSON.stringify(a,null,2))))}catch(a){this._send(nt(e,Ps(a.message||String(a))))}}_visibleTools(){return ks.filter((e)=>{let t=this._scopes["*"];if(t&&(t.includes(e.scope)||t.includes("admin")))return!0;for(let[,i]of Object.entries(this._scopes))if(i.includes(e.scope)||i.includes("admin"))return!0;return!1})}_hasScope(e,t){let i=(s)=>s.includes("admin")||s.includes(t);if(e&&this._scopes[e])return i(this._scopes[e]);if(this._scopes["*"])return i(this._scopes["*"]);return!1}_send(e){this._t?.send(e)}}var It="migrations",Ms=(e)=>JSON.stringify(e,function(t,i){let s=this[t];if(s instanceof Date)return{__skalex_date__:s.toISOString()};if(typeof i==="bigint")return{__skalex_bigint__:i.toString()};return i}),js=(e)=>JSON.parse(e,(t,i)=>{if(i&&typeof i==="object"){if("__skalex_bigint__"in i)return BigInt(i.__skalex_bigint__);if("__skalex_date__"in i)return new Date(i.__skalex_date__)}return i});class te{constructor({path:e="./.db",format:t="gz",debug:i=!1,adapter:s,ai:n,encrypt:r,slowQueryLog:a,queryCache:l,memory:o,logger:c,plugins:h,llmAdapter:u,embeddingAdapter:d,regexMaxLength:_,idGenerator:f,serializer:p,deserializer:m,autoSave:w,ttlSweepInterval:x,lenientLoad:R}={}){if(this.dataDirectory=e,this.dataFormat=t,this.debug=i,!te._errorsAttached)te.SkalexError=je,te.ValidationError=$,te.UniqueConstraintError=Ee,te.TransactionError=ge,te.PersistenceError=ke,te.AdapterError=_e,te.QueryError=Ge,te._errorsAttached=!0;this._adapterConfig=s??null;let E=s||new Hn({dir:e,format:t});if(r)E=new ir(E,r.key);if(this.fs=E,this._registry=new Wn(Xn),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._migrations=new Vn,this._connectPromise=null,this.isConnected=!1,this._aiConfig=n||null,this._encryptConfig=r||null,this._pluginsConfig=Array.isArray(h)?h:null,this._memoryConfig=o||null,this._regexMaxLength=_??500,this._idGenerator=f??null,this._serializer=p??Ms,this._deserializer=m??js,this._autoSave=w??!1,this._txManager=new Yn,this._ttlSweepInterval=x??0,this._ttlTimer=null,this._logger=c??Ts,this._embeddingAdapter=d??(n?$l(n):null),this._aiAdapter=u??(n?Dl(n):null),this._persistence=new Jn({adapter:this.fs,serializer:this._serializer,deserializer:this._deserializer,logger:this._logger,debug:this.debug,lenientLoad:R??!1}),this._changeLog=new nr(this),this._queryCache=new rr(l||{}),this._eventBus=new ar,this._queryLog=a?new or(a):null,this._sessionStats=new lr,this._plugins=new cr,Array.isArray(h))for(let A of h)this._plugins.register(A)}async connect(){if(this._connectPromise)return this._connectPromise;return this._connectPromise=this._doConnect(),this._connectPromise}async _doConnect(){try{await this.loadData();let e=this._getMeta();if(e.queryCache)this._queryCache.fromJSON(e.queryCache);if(this._migrations._migrations.length>0){let t=e.appliedVersions||[],i=await this._migrations.run((s)=>this.useCollection(`_migration_${s}`),t);this._saveMeta({appliedVersions:i})}if(this._sweepTtl(),this._ttlSweepInterval>0){if(this._ttlTimer=setInterval(()=>this._sweepTtl(),this._ttlSweepInterval),this._ttlTimer?.unref)this._ttlTimer.unref()}this.isConnected=!0,this._log("> - Connected to the database (\u221A)")}catch(e){throw this._logger(`Error connecting to the database: ${e}`,"error"),e}}async disconnect(){try{if(this._ttlTimer)clearInterval(this._ttlTimer),this._ttlTimer=null;await this.saveData(),this._registry.clear(),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._connectPromise=null,this.isConnected=!1,this._log("> - Disconnected from the database (\u221A)")}catch(e){throw this._logger(`Error disconnecting from the database: ${e}`,"error"),e}}async _ensureConnected(){if(this.isConnected)return;return this.connect()}useCollection(e){return this._registry.get(e,this)}createCollection(e,t={}){return this._registry.create(e,t,this)}_createCollectionStore(e,t={}){this._registry.createStore(e,t)}async renameCollection(e,t){this._registry.rename(e,t),await this.saveData(t),await this.fs.delete(e)}async loadData(){await this._persistence.loadAll(this.collections,{parseSchema:Fn,buildIndex:this._registry.buildIndex,IndexEngine:Rt});for(let e in this._collectionInstances){let t=this.collections[e];if(t&&this._collectionInstances[e]._store!==t)this._collectionInstances[e]._store=t}}async saveData(e){await this._persistence.save(this.collections,e)}buildIndex(e,t){return this._registry.buildIndex(e,t)}addMigration(e){this._migrations.add(e)}migrationStatus(){let e=this._getMeta();return this._migrations.status(e.appliedVersions||[])}namespace(e){if(this._adapterConfig)throw new _e("ERR_SKALEX_ADAPTER_NAMESPACE_REQUIRES_FS","namespace() requires the default FsAdapter. When a custom storage adapter is configured, create a separate Skalex instance with your adapter instead.");let t=String(e).replace(/[^a-zA-Z0-9_-]/g,"_");if(!t)throw new $("ERR_SKALEX_VALIDATION_NAMESPACE_ID","namespace: id must contain at least one alphanumeric character",{id:e});return new te({path:`${this.dataDirectory}/${t}`,format:this.dataFormat,debug:this.debug,ai:this._aiConfig||void 0,encrypt:this._encryptConfig||void 0,slowQueryLog:this._queryLog?{threshold:this._queryLog._threshold,maxEntries:this._queryLog._maxEntries}:void 0,queryCache:this._queryCache?{maxSize:this._queryCache._maxSize,ttl:this._queryCache._ttl}:void 0,plugins:this._pluginsConfig||void 0,memory:this._memoryConfig||void 0,logger:this._logger!==Ts?this._logger:void 0,llmAdapter:this._aiAdapter&&!this._aiConfig?this._aiAdapter:void 0,embeddingAdapter:this._embeddingAdapter&&!this._aiConfig?this._embeddingAdapter:void 0,regexMaxLength:this._regexMaxLength!==500?this._regexMaxLength:void 0,idGenerator:this._idGenerator||void 0,serializer:this._serializer!==Ms?this._serializer:void 0,deserializer:this._deserializer!==js?this._deserializer:void 0,autoSave:this._autoSave||void 0,ttlSweepInterval:this._ttlSweepInterval||void 0})}use(e){this._plugins.register(e)}watch(e){return this._eventBus.on("*",e)}sessionStats(e){if(e!==void 0)return this._sessionStats.get(e);return this._sessionStats.all()}get _inTransaction(){return this._txManager.active}_emitEvent(e,t){if(!this._txManager.defer(()=>this._eventBus.emit(e,t)))this._eventBus.emit(e,t)}async _runAfterHook(e,t){if(!this._txManager.defer(()=>this._plugins.run(e,t)))await this._plugins.run(e,t)}async _logChange(e,t,i,s,n){if(!this._txManager.defer(()=>this._changeLog.log(e,t,i,s,n)))await this._changeLog.log(e,t,i,s,n)}async transaction(e,t={}){return this._txManager.run(e,this,t)}async seed(e,{reset:t=!1}={}){for(let[i,s]of Object.entries(e)){if(t&&this.collections[i])this._applySnapshot(i,{data:[],index:new Map}),delete this._collectionInstances[i];await this.useCollection(i).insertMany(s)}await this.saveData()}dump(){return this._registry.dump()}inspect(e){return this._registry.inspect(e)}async import(e){let t=await this.fs.readRaw(e),i;try{i=JSON.parse(t)}catch{throw new ke("ERR_SKALEX_PERSISTENCE_INVALID_JSON",`import: invalid JSON in file "${e}"`,{filePath:e})}let s=e.split("/").pop().replace(/\.[^.]+$/,"");return this.useCollection(s).insertMany(Array.isArray(i)?i:[i],{save:!0})}async embed(e){if(!this._embeddingAdapter)throw new _e("ERR_SKALEX_ADAPTER_EMBEDDING_REQUIRED","db.embed() requires an AI adapter. Pass { ai: { provider, apiKey } } to the Skalex constructor.");return this._embeddingAdapter.embed(e)}async ask(e,t,{limit:i=20}={}){if(!this._aiAdapter)throw new _e("ERR_SKALEX_ADAPTER_LLM_REQUIRED",'db.ask() requires a language model adapter. Configure { ai: { provider, model: "..." } }.');let s=this.useCollection(e),n=this.schema(e),r=this._queryCache.get(e,n,t);if(!r){r=await this._aiAdapter.generate(n,t);let a=Fl(r,n);if(a.length)a.forEach((l)=>this._log(`[ask] ${l}`));this._queryCache.set(e,n,t,r),this._saveMeta({queryCache:this._queryCache.toJSON()})}return s.find(ql(r,{regexMaxLength:this._regexMaxLength}),{limit:i})}schema(e){return this._registry.schema(e)}useMemory(e){return new sr(e,this)}changelog(){return this._changeLog}async restore(e,t,i={}){return this._changeLog.restore(e,t,i)}stats(e){return this._registry.stats(e)}slowQueries(e={}){if(!this._queryLog)return[];return this._queryLog.entries(e)}slowQueryCount(){return this._queryLog?this._queryLog.size:0}clearSlowQueries(){this._queryLog?.clear()}mcp(e={}){return new ur(this,e)}_getMeta(){let e=this.collections._meta;if(!e)return{};return e.index.get(It)||{}}_saveMeta(e){if(!this.collections._meta)this._createCollectionStore("_meta");let t=this.collections._meta,i=t.index.get(It);if(i)Object.assign(i,e);else{let s={_id:It,...e};t.data.push(s),t.index.set(It,s)}this._persistence.markDirty(this.collections,"_meta")}_sweepTtl(){for(let e in this.collections){let t=this.collections[e],i=El(t.data,t.index,t.fieldIndex?(s)=>t.fieldIndex.remove(s):null);if(i>0)this._persistence.markDirty(this.collections,e),this._log(`TTL sweep: removed ${i} expired docs from "${e}"`)}}_buildCollectionContext(){let e=this;return{ensureConnected:()=>e._ensureConnected(),get txManager(){return e._txManager},get plugins(){return e._plugins},get eventBus(){return e._eventBus},get sessionStats(){return e._sessionStats},get queryLog(){return e._queryLog},get logger(){return e._logger},get persistence(){return e._persistence},get collections(){return e.collections},embed:(t)=>e.embed(t),get idGenerator(){return e._idGenerator},get autoSave(){return e._autoSave},saveCollection:(t)=>e.saveData(t),snapshotCollection:(t)=>e._snapshotCollection(t),getCollection:(t)=>e.useCollection(t),emitEvent:(t,i)=>e._emitEvent(t,i),runAfterHook:(t,i)=>e._runAfterHook(t,i),logChange:(t,i,s,n,r)=>e._logChange(t,i,s,n,r),get fs(){return e.fs},get dataDirectory(){return e.dataDirectory}}}_log(e){if(this.debug)this._logger(e,"info")}_snapshotCollection(e){return{data:structuredClone(e.data)}}_applySnapshot(e,t){let i=this.collections[e];if(!i)return;if(i.data=t.data,i.index=this.buildIndex(t.data,"_id"),i.fieldIndex)i.fieldIndex.buildFromData(t.data)}}function Wl(){let e=Date.now().toString(16),t;try{t=No.randomBytes(8).toString("hex")}catch{let i=new Uint8Array(8);crypto.getRandomValues(i),t=Array.from(i).map((s)=>s.toString(16).padStart(2,"0")).join("")}return`${e}${t}`}function qs(e,t){let i=e instanceof Error?e.message:e;if(t==="error")console.error(i);else console.log(i)}var Ks=new Set(["__proto__","constructor","prototype"]);function Kt(e,t){if(!t.includes(".")){if(Ks.has(t))return;return e[t]}let i=e;for(let s of t.split(".")){if(Ks.has(s))return;if(i==null)return;i=i[s]}return i}class qe extends Error{constructor(e,t,i={}){super(t);this.name=this.constructor.name,this.code=e,this.details=i}}class D extends qe{}class Ie extends qe{}class ye extends qe{}class Le extends qe{}class fe extends qe{}class Ze extends qe{}function xi(e,t){if(e===t)return!0;if(e==null||t==null)return!1;if(typeof e!==typeof t)return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.source===t.source&&e.flags===t.flags;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!xi(e[i],t[i]))return!1;return!0}if(typeof e==="object"){if(Array.isArray(t))return!1;let i=Object.keys(e);if(i.length!==Object.keys(t).length)return!1;for(let s of i){if(!Object.prototype.hasOwnProperty.call(t,s))return!1;if(!xi(e[s],t[s]))return!1}return!0}return!1}function J(e,t){if(typeof t==="function")return t(e);if(t==null)return!0;if(typeof t==="object"&&Object.keys(t).length===0)return!0;if("$or"in t){let i=t.$or;if(!Array.isArray(i))throw new Ze("ERR_SKALEX_QUERY_INVALID_OPERATOR","$or must be an array of filters",{operator:"$or"});if(!i.some((s)=>J(e,s)))return!1}if("$and"in t){let i=t.$and;if(!Array.isArray(i))throw new Ze("ERR_SKALEX_QUERY_INVALID_OPERATOR","$and must be an array of filters",{operator:"$and"});if(!i.every((s)=>J(e,s)))return!1}if("$not"in t){if(J(e,t.$not))return!1}for(let i in t){if(i==="$or"||i==="$and"||i==="$not")continue;let s=t[i],n;try{n=Kt(e,i)}catch{return!1}if(s instanceof RegExp){if(!s.test(String(n)))return!1}else if(typeof s==="object"&&s!==null){if(Object.keys(s).some((r)=>r.startsWith("$"))){if("$eq"in s&&n!==s.$eq)return!1;if("$ne"in s&&n===s.$ne)return!1;if("$gt"in s&&!(n>s.$gt))return!1;if("$lt"in s&&!(n<s.$lt))return!1;if("$gte"in s&&!(n>=s.$gte))return!1;if("$lte"in s&&!(n<=s.$lte))return!1;if("$in"in s&&!s.$in.includes(n))return!1;if("$nin"in s&&s.$nin.includes(n))return!1;if("$regex"in s){if(!(s.$regex instanceof RegExp?s.$regex:new RegExp(s.$regex)).test(String(n)))return!1}if("$fn"in s&&!s.$fn(n))return!1}else if(!xi(n,s))return!1}else if(n!==s)return!1}return!0}function Ql(e,t=new Set){if(typeof e!=="object"||e===null||typeof e==="function")return e;let i=[],s=[],n=[],r=[],a=[];for(let o in e){if(o==="$or"||o==="$and"||o==="$not"){a.push(o);continue}let c=e[o];if(t.has(o))i.push(o);else if(c instanceof RegExp||typeof c==="object"&&c!==null&&(("$regex"in c)||("$fn"in c))||typeof c==="function")r.push(o);else if(typeof c==="object"&&c!==null&&(("$gt"in c)||("$lt"in c)||("$gte"in c)||("$lte"in c)||("$ne"in c)||("$in"in c)||("$nin"in c)))n.push(o);else s.push(o)}let l={};for(let o of[...i,...s,...n,...r,...a])l[o]=e[o];return l}var vi=new Set(["string","number","boolean","object","array","date","any"]);function qi(e){if(Array.isArray(e))return"array";if(e instanceof Date)return"date";return typeof e}function _r(e){let t=new Map,i=[];for(let[s,n]of Object.entries(e)){let r;if(typeof n==="string"){if(!vi.has(n))throw new D("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${n}" for field "${s}"`,{field:s,type:n});r={type:n,required:!1,unique:!1}}else if(typeof n==="object"&&n!==null){let{type:a="any",required:l=!1,unique:o=!1,enum:c}=n;if(!vi.has(a))throw new D("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${a}" for field "${s}"`,{field:s,type:a});if(r={type:a,required:l,unique:o,enum:c},o)i.push(s)}else throw new D("ERR_SKALEX_VALIDATION_INVALID_SCHEMA",`Invalid schema definition for field "${s}"`,{field:s});t.set(s,r)}return{fields:t,uniqueFields:i}}function Fs(e,t,i=!1){let s=[];for(let[n,r]of t){let a=e[n],l=a===void 0||a===null;if(r.required&&l){s.push(`Field "${n}" is required`);continue}if(l)continue;if(r.type!=="any"){let o=qi(a);if(o!==r.type)s.push(`Field "${n}" must be of type "${r.type}", got "${o}"`)}if(r.enum&&!r.enum.includes(a))s.push(`Field "${n}" must be one of [${r.enum.map((o)=>JSON.stringify(o)).join(", ")}], got ${JSON.stringify(a)}`)}if(i){for(let n of Object.keys(e))if(!n.startsWith("_")&&!t.has(n))s.push(`Unknown field "${n}" (strict mode)`)}return s}function Us(e,t){let i={};for(let[s,n]of Object.entries(e)){if(s.startsWith("_")){i[s]=n;continue}if(!t.has(s))continue;let r=t.get(s);if(r.type!=="any"){if(qi(n)!==r.type)continue}if(r.enum&&!r.enum.includes(n))continue;i[s]=n}return i}function Gl(e){let t={};for(let[i,s]of Object.entries(e)){if(i.startsWith("_"))continue;let n=qi(s);t[i]=vi.has(n)?n:"any"}return t}function Zl(e){if(typeof e==="number"){if(e<=0)throw new D("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got ${e}`,{ttl:e});return e*1000}if(typeof e!=="string")throw new D("ERR_SKALEX_VALIDATION_TTL",`Invalid TTL value: ${e}`,{ttl:e});let t=e.match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/);if(!t)throw new D("ERR_SKALEX_VALIDATION_TTL_FORMAT",`Invalid TTL format: "${e}". Use e.g. 300 (seconds), "30m", "24h", "7d"`,{ttl:e});let i=parseFloat(t[1]);if(i<=0)throw new D("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got "${e}"`,{ttl:e});let s=t[2],n=i*{ms:1,s:1000,m:60000,h:3600000,d:86400000}[s];if(!isFinite(n))throw new D("ERR_SKALEX_VALIDATION_TTL",`TTL value "${e}" is too large`,{ttl:e});return n}function ec(e){return new Date(Date.now()+Zl(e))}function tc(e,t,i=null){let s=Date.now(),n=0,r=e.length;while(r--){let a=e[r];if(a._expiresAt&&new Date(a._expiresAt).getTime()<=s){if(e.splice(r,1),t.delete(a._id),i)i(a);n++}}return n}function zs(e,t){if(e.length!==t.length)throw new Ze("ERR_SKALEX_QUERY_VECTOR_MISMATCH",`Vector dimension mismatch: ${e.length} vs ${t.length}`,{expected:e.length,got:t.length});let i=0,s=0,n=0;for(let a=0;a<e.length;a++)i+=e[a]*t[a],s+=e[a]*e[a],n+=t[a]*t[a];let r=Math.sqrt(s*n);return r===0?0:i/r}function B(e){if(!("_vector"in e))return{...e};let{_vector:t,...i}=e;return i}function ic(e){return e.length}function sc(e,t){let i=0;for(let s of e){let n=Kt(s,t);if(typeof n==="number"&&!isNaN(n))i+=n}return i}function nc(e,t){let i=0,s=0;for(let n of e){let r=Kt(n,t);if(typeof r==="number"&&!isNaN(r))i+=r,s++}return s===0?null:i/s}function rc(e,t){let i=Object.create(null);for(let s of e){let n=String(Kt(s,t)??"__null__");if(!i[n])i[n]=[];i[n].push(s)}return i}class fr{constructor(e){this._col=e}get _ctx(){return this._col._ctx}async execute({op:e,beforeHook:t,afterHook:i,hookPayload:s,mutate:n,afterHookPayload:r,save:a,session:l}){let o=this._ctx;await o.ensureConnected(),this._col._txSnapshotIfNeeded();let c=o.txManager,h=c.active&&this._col._activeTxId===c.context?.id,u=h?c.context.id:null,d=this._col._createdInTxId,_=()=>{if(u!==null&&c._abortedIds.has(u))throw new ye("ERR_SKALEX_TX_ABORTED",`Transaction ${u} was aborted. No further mutations allowed.`);if(d!==null&&c._abortedIds.has(d))throw new ye("ERR_SKALEX_TX_ABORTED",`Transaction ${d} was aborted. Collection obtained inside that transaction cannot be used for further mutations.`)};if(h||d!==null)_();if(t)await o.plugins.run(t,s);let{docs:f,prevDocs:p=[]}=await n(_);if(o.persistence.markDirty(o.collections,this._col.name),await this._col._saveIfNeeded(a),this._col._changelogEnabled)for(let m=0;m<f.length;m++)await o.logChange(e,this._col.name,f[m],p[m]??null,l||null);if(!h||!c.defer(()=>o.sessionStats.recordWrite(l)))o.sessionStats.recordWrite(l);for(let m of f)o.emitEvent(this._col.name,{op:e,collection:this._col.name,doc:B(m)});if(i)if(r)await o.runAfterHook(i,r(f));else for(let m of f)await o.runAfterHook(i,{collection:this._col.name,doc:B(m)});return{docs:f,prevDocs:p}}}function ac(e){let t={};for(let i in e){if(i.startsWith("$"))continue;let s=e[i];if(s&&typeof s==="object"&&!Array.isArray(s)){let n=Object.keys(s);if(n.length===1&&n[0]==="$eq")t[i]=s.$eq}else t[i]=s}return t}var pr=new Set(["__proto__","constructor","prototype"]);function mr(e){if(typeof e!=="object"||e===null||Array.isArray(e))return e;let t={};for(let i of Object.keys(e)){if(pr.has(i))continue;t[i]=mr(e[i])}return t}class gr{constructor(e,t){this.name=e.collectionName,this.database=t,this._ctx=t._buildCollectionContext(),this._store=e,this._pipeline=new fr(this),this._createdInTxId=t._txManager.context?.id??null,this._activeTxId=null}get _data(){return this._store.data}set _data(e){this._store.data=e}get _index(){return this._store.index}get _fieldIndex(){return this._store.fieldIndex||null}get _schema(){return this._store.schema?this._store.schema.fields:null}get _changelogEnabled(){return this._store.changelog===!0}get _softDelete(){return this._store.softDelete===!0}get _versioning(){return this._store.versioning===!0}get _strict(){return this._store.strict===!0}get _onSchemaError(){return this._store.onSchemaError??"throw"}get _defaultTtl(){return this._store.defaultTtl||null}get _defaultEmbed(){return this._store.defaultEmbed||null}get _maxDocs(){return this._store.maxDocs||null}async insertOne(e,t={}){let{save:i,ifNotExists:s,ttl:n,embed:r,session:a}=t;if(s){await this._ctx.ensureConnected();let o=this._findRaw(e);if(o)return B({...o})}let{docs:l}=await this._insertCore([e],{ttl:n,embed:r,session:a,save:i});return B(l[0])}async insertMany(e,t={}){let{save:i,ttl:s,embed:n,session:r}=t,{docs:a}=await this._insertCore(e,{ttl:s,embed:n,session:r,save:i});return a.map(B)}async _insertCore(e,{ttl:t,embed:i,session:s,save:n}){return this._pipeline.execute({op:"insert",beforeHook:null,afterHook:"afterInsert",hookPayload:null,save:n,session:s,mutate:async(r)=>{let a=[],l=new Set;for(let o of e){let c=this._applyValidation(o);await this._ctx.plugins.run("beforeInsert",{collection:this.name,doc:c});let h=await this._buildDoc(c,{ttl:t,embed:i});if(this._index.has(h._id)||l.has(h._id))throw new Ie("ERR_SKALEX_UNIQUE_DUPLICATE_ID",`Duplicate _id "${h._id}" in collection "${this.name}"`,{id:h._id,collection:this.name});l.add(h._id),a.push(h)}if(r(),this._fieldIndex)this._fieldIndex.assertUniqueBatch(a);for(let o of a)this._addToIndex(o);this._data.push(...a);for(let o of a)this._index.set(o._id,o);return this._enforceCapAfterInsert(),{docs:a}}})}async updateOne(e,t,i={}){await this._ctx.ensureConnected();let s=this._findRaw(e);if(!s)return null;let{save:n,session:r}=i,{docs:a}=await this._updateCore([s],e,t,{save:n,session:r});return B(a[0])}async updateMany(e,t,i={}){await this._ctx.ensureConnected();let s=this._findAllRaw(e);if(s.length===0)return[];let{save:n,session:r}=i,{docs:a}=await this._updateCore(s,e,t,{save:n,session:r});return a.map(B)}async _updateCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"update",beforeHook:"beforeUpdate",afterHook:"afterUpdate",hookPayload:{collection:this.name,filter:t,update:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:t,update:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{let a=this._changelogEnabled?e.map((h)=>structuredClone(h)):e.map(()=>null),l=e.map((h)=>this._prepareUpdatedDoc(h,i));this._assertUniqueCandidates(e,l),r();let o=new Set(e),c=new Map;for(let h=0;h<this._data.length;h++)if(o.has(this._data[h]))c.set(this._data[h],h);for(let h=0;h<e.length;h++)this._commitUpdatedDoc(e[h],l[h],c);return{docs:l,prevDocs:a}}})}applyUpdate(e,t){for(let i in t){if(pr.has(i))continue;if(i==="_id"||i==="createdAt")continue;let s=t[i];if(Array.isArray(s))e[i]=s;else if(typeof s==="object"&&s!==null){let n=Object.keys(s);if(n.some((r)=>r.startsWith("$"))){for(let r of n)if(r==="$inc"&&typeof e[i]==="number")e[i]+=s[r];else if(r==="$push"){if(!Array.isArray(e[i]))e[i]=[];e[i].push(s[r])}}else e[i]=mr(s)}else e[i]=s}if(e.updatedAt=new Date,this._versioning)e._version=(e._version??0)+1;return e}_prepareUpdatedDoc(e,t){let i=structuredClone(e),s=structuredClone(e);if(this.applyUpdate(s,t),!this._schema)return s;let n=Fs(s,this._schema,this._strict);if(!n.length)return s;switch(this._onSchemaError){case"throw":throw new D("ERR_SKALEX_VALIDATION_UPDATE",`Update validation failed on doc "${e._id}": ${n.join("; ")}`,{id:e._id,errors:n});case"strip":return this._stripCandidateToValid(s,i);default:return this._ctx.logger(`[${this.name}] Update validation warning: ${n.join("; ")}`,"warn"),s}}_stripCandidateToValid(e,t){let i=Us(e,this._schema),s=structuredClone(t);for(let[n,r]of Object.entries(i)){if(n.startsWith("_"))continue;s[n]=r}if(s.updatedAt=e.updatedAt,this._versioning)s._version=e._version;return s}_commitUpdatedDoc(e,t,i){let s=i?i.get(e):this._data.indexOf(e);if(s===void 0||s===-1)throw new Le("ERR_SKALEX_PERSISTENCE_DOC_MISSING",`Document "${e._id}" no longer exists in collection "${this.name}"`,{id:e._id,collection:this.name});this._data[s]=t,this._index.set(t._id,t),this._updateInIndex(e,t)}_assertUniqueCandidates(e,t){this._fieldIndex?.assertUniqueCandidates(e,t)}async upsert(e,t,i={}){if(await this._ctx.ensureConnected(),this._findRaw(e))return this.updateOne(e,t,i);return this.insertOne({...ac(e),...t},i)}async upsertMany(e,t,i={}){await this._ctx.ensureConnected();let{save:s,...n}=i,r=[];for(let a of e)r.push(await this.upsert({[t]:a[t]},a,{...n,save:!1}));return await this._saveIfNeeded(s),r}async restore(e,t={}){if(!this._softDelete)throw new Ze("ERR_SKALEX_QUERY_SOFT_DELETE_REQUIRED",`restore() requires softDelete on "${this.name}"`,{collection:this.name});await this._ctx.ensureConnected();let{save:i,session:s}=t,n=this._findRaw(e,{includeDeleted:!0});if(!n||!n._deletedAt)return null;let{docs:r}=await this._pipeline.execute({op:"restore",beforeHook:null,afterHook:null,hookPayload:null,save:i,session:s,mutate:async(a)=>{return a(),delete n._deletedAt,n.updatedAt=new Date,this._index.set(n._id,n),{docs:[n]}}});return B(r[0])}watch(e,t){if(typeof e==="function")t=e,e=null;if(t)return this._ctx.eventBus.on(this.name,(i)=>{if(!e||J(i.doc,e))t(i)});return this._watchIterator(e)}_watchIterator(e){let t=[],i=null,s=!1,n=this._ctx.eventBus.on(this.name,(r)=>{if(e&&!J(r.doc,e))return;if(i){let a=i;i=null,a({value:r,done:!1})}else t.push(r)});return{[Symbol.asyncIterator](){return this},next(){if(t.length>0)return Promise.resolve({value:t.shift(),done:!1});if(s)return Promise.resolve({value:void 0,done:!0});return new Promise((r)=>{i=r})},return(){if(s=!0,n(),i){let r=i;i=null,r({value:void 0,done:!0})}return Promise.resolve({value:void 0,done:!0})}}}async count(e={}){return await this._ctx.ensureConnected(),ic(this._findAllRaw(e))}async sum(e,t={}){return await this._ctx.ensureConnected(),sc(this._findAllRaw(t),e)}async avg(e,t={}){return await this._ctx.ensureConnected(),nc(this._findAllRaw(t),e)}async groupBy(e,t={}){return await this._ctx.ensureConnected(),rc(this._findAllRaw(t),e)}async findOne(e,t={}){await this._ctx.ensureConnected();let{populate:i,select:s,includeDeleted:n=!1}=t,r=this._findRaw(e,{includeDeleted:n});if(!r)return null;let a=this._projectDoc(r,s);if(i)await this._populateDoc(a,r,i);return a}async find(e,t={}){await this._ctx.ensureConnected();let i=Date.now(),{populate:s,select:n,sort:r,page:a=1,limit:l,session:o,includeDeleted:c=!1}=t;await this._ctx.plugins.run("beforeFind",{collection:this.name,filter:e,options:t});let h=this._getCandidates(e),u=Ql(e,this._fieldIndex?this._fieldIndex.indexedFields:new Set),d=[];for(let f of h){if(this._softDelete&&f._deletedAt&&!c)continue;if(!J(f,u))continue;let p=this._projectDoc(f,n);if(s)await this._populateDoc(p,f,s);d.push(p)}if(r){let f=Object.keys(r);d.sort((p,m)=>{for(let w of f){let x=r[w];if(p[w]<m[w])return-x;if(p[w]>m[w])return x}return 0})}let _;if(l){let f=d.length,p=Math.ceil(f/l),m=(a-1)*l;d=d.slice(m,m+l),_={page:a,totalDocs:f,totalPages:p}}return this._ctx.queryLog?.record({collection:this.name,op:"find",filter:e,duration:Date.now()-i,resultCount:d.length}),this._ctx.sessionStats.recordRead(o),await this._ctx.plugins.run("afterFind",{collection:this.name,filter:e,options:t,docs:d}),_?{docs:d,..._}:{docs:d}}async search(e,{filter:t,limit:i=10,minScore:s=0,session:n}={}){await this._ctx.ensureConnected();let r=Date.now();await this._ctx.plugins.run("beforeSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s}});let a=await this._ctx.embed(e),l=t?this._findAllRaw(t):this._data,o=[];for(let d of l){if(!d._vector)continue;let _=zs(a,d._vector);if(_>=s)o.push({doc:d,score:_})}o.sort((d,_)=>_.score-d.score);let c=o.slice(0,i);this._ctx.queryLog?.record({collection:this.name,op:"search",query:e,duration:Date.now()-r,resultCount:c.length}),this._ctx.sessionStats.recordRead(n);let h=c.map((d)=>B(d.doc)),u=c.map((d)=>d.score);return await this._ctx.plugins.run("afterSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s},docs:h,scores:u}),{docs:h,scores:u}}async similar(e,{limit:t=10,minScore:i=0}={}){await this._ctx.ensureConnected();let s=this._index.get(e);if(!s||!s._vector)return{docs:[],scores:[]};let n=[];for(let a of this._data){if(a._id===e||!a._vector)continue;let l=zs(s._vector,a._vector);if(l>=i)n.push({doc:a,score:l})}n.sort((a,l)=>l.score-a.score);let r=n.slice(0,t);return{docs:r.map((a)=>B(a.doc)),scores:r.map((a)=>a.score)}}async deleteOne(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findRaw(e);if(!r)return null;let{docs:a}=await this._deleteCore("soft",[r],e,{save:i,session:s});return B(a[0])}let{docs:n}=await this._deleteCore("hard",null,e,{save:i,session:s});if(n.length===0)return null;return B(n[0])}async deleteMany(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findAllRaw(e);if(r.length===0)return[];let{docs:a}=await this._deleteCore("soft",r,e,{save:i,session:s});return a.map(B)}let{docs:n}=await this._deleteCore("hardMany",null,e,{save:i,session:s});return n.map(B)}async _deleteCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"delete",beforeHook:"beforeDelete",afterHook:"afterDelete",hookPayload:{collection:this.name,filter:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{if(r(),e==="soft"){let o=new Date;for(let c of t)c._deletedAt=o,c.updatedAt=o,this._index.set(c._id,c);return{docs:t}}if(e==="hard"){let o=this._findIndex(i);if(o===-1)return{docs:[]};let c=this._data.splice(o,1)[0];return this._index.delete(c._id),this._removeFromIndex(c),{docs:[c]}}let a=[],l=[];for(let o of this._data)if(J(o,i))a.push(o),this._index.delete(o._id),this._removeFromIndex(o);else l.push(o);return this._data=l,{docs:a}}})}async export(e={},t={}){let{dir:i,name:s,format:n="json"}=t;try{let r=this._data.filter((h)=>J(h,e));if(r.length===0)throw new Ze("ERR_SKALEX_QUERY_EXPORT_EMPTY",`export(): no documents matched the filter in "${this.name}"`,{collection:this.name});let a;if(n==="json")a=JSON.stringify(r,null,2);else{let h=(_)=>{if(_==null)return"";let f=typeof _==="object"?JSON.stringify(_):String(_);return f.includes(",")||f.includes('"')||f.includes(`
66
66
  `)||f.includes("\r")?`"${f.replace(/"/g,'""')}"`:f},u=Object.keys(r[0]).map(h).join(","),d=r.map((_)=>Object.values(_).map(h).join(","));a=[u,...d].join(`
67
- `)}if(typeof this._ctx.fs.writeRaw!=="function")throw new fe("ERR_SKALEX_ADAPTER_NO_RAW_WRITE","export() requires a file-system adapter (FsAdapter). The current adapter does not support raw file writes.");let l=i||`${this._ctx.dataDirectory}/exports`,o=`${s||this.name}.${n}`,c=this._ctx.fs.join(l,o);this._ctx.fs.ensureDir(l),await this._ctx.fs.writeRaw(c,a)}catch(r){throw this._ctx.logger(`Error exporting "${this.name}": ${r.message}`,"error"),r}}_txSnapshotIfNeeded(){let e=this._ctx.txManager;if(!e.active)return;if(this._activeTxId!==e.context?.id)return;e.snapshotIfNeeded(this.name,this._store,(t)=>this._ctx.snapshotCollection(t))}async _saveIfNeeded(e){let t=this._ctx.txManager;if(t.active&&this._activeTxId===t.context?.id)return;if(e??this._ctx.autoSave)await this._ctx.saveCollection(this.name)}_applyValidation(e){if(!this._schema)return e;let t=Fs(e,this._schema,this._strict);if(!t.length)return e;switch(this._onSchemaError){case"warn":return this._ctx.logger(`[${this.name}] Validation warning: ${t.join("; ")}`,"warn"),e;case"strip":return Us(e,this._schema);default:throw new D("ERR_SKALEX_VALIDATION_FAILED",`Validation failed: ${t.join("; ")}`,{errors:t})}}_enforceCapAfterInsert(){let e=this._maxDocs;if(!e||this._data.length<=e)return;let t=this._data.splice(0,this._data.length-e);for(let i of t)this._index.delete(i._id),this._removeFromIndex(i)}_findRaw(e,{includeDeleted:t=!1}={}){if(typeof e==="function"){for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(e(i))return i}return null}if(e._id){let i=this._index.get(e._id)||null;if(!i)return null;if(this._softDelete&&i._deletedAt&&!t)return null;if(Object.keys(e).length>1)return J(i,e)?i:null;return i}if(this._fieldIndex)for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null){let n=this._fieldIndex._lookupIterable(i,s);if(n!==null){for(let r of n){if(this._softDelete&&r._deletedAt&&!t)continue;if(J(r,e))return r}return null}}}for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(J(i,e))return i}return null}_findAllRaw(e,{includeDeleted:t=!1}={}){if(e&&typeof e!=="function"&&e._id){let s=this._index.get(e._id);if(!s)return[];if(this._softDelete&&s._deletedAt&&!t)return[];return J(s,e)?[s]:[]}let i=[];for(let s of this._getCandidates(e)){if(this._softDelete&&s._deletedAt&&!t)continue;if(J(s,e))i.push(s)}return i}_getCandidates(e){if(!this._fieldIndex)return this._data;if(this._fieldIndex._compoundIndexes.size>0){let t={};for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null)t[i]=s}if(Object.keys(t).length>=2){let i=this._fieldIndex.lookupCompound(t);if(i!==null)return i}}for(let t in e){if(t==="$or"||t==="$and"||t==="$not")continue;let i=e[t];if(typeof i!=="object"||i===null){let s=this._fieldIndex._lookupIterable(t,i);if(s!==null)return s}}return this._data}_findIndex(e){for(let t=0;t<this._data.length;t++)if(J(this._data[t],e))return t;return-1}_addToIndex(e){if(this._fieldIndex)this._fieldIndex.add(e)}_removeFromIndex(e){if(this._fieldIndex)this._fieldIndex.remove(e)}_updateInIndex(e,t){if(this._fieldIndex)this._fieldIndex.update(e,t)}async _buildDoc(e,{ttl:t,embed:i}={}){let s={...e,_id:e._id??(this._ctx.idGenerator??Jl)(),createdAt:new Date,updatedAt:new Date},n=t??this._defaultTtl;if(n)s._expiresAt=Gl(n);let r=i??this._defaultEmbed;if(r){let a=typeof r==="function"?r(s):s[r];s._vector=await this._ctx.embed(String(a))}if(this._versioning)s._version=1;return s}_projectDoc(e,t){if(t){let s={};for(let n of t){if(n==="_vector")continue;s[n]=e[n]}return s}let i={...e};return delete i._vector,i}async _populateDoc(e,t,i){for(let s of i){let n=await this._ctx.getCollection(s).findOne({_id:t[s]});if(n)e[s]=n}}}class Ki{async read(e){throw Error("StorageAdapter.read() not implemented")}async write(e,t){throw Error("StorageAdapter.write() not implemented")}async delete(e){throw Error("StorageAdapter.delete() not implemented")}async list(){throw Error("StorageAdapter.list() not implemented")}async writeAll(e){for(let{name:t,data:i}of e)await this.write(t,i)}}class yr extends Ki{constructor({dir:e,format:t="gz"}){super();this.dir=Xe.resolve(e),this.format=t,this._ensureDir(this.dir)}_ensureDir(e){if(!K.existsSync(e))K.mkdirSync(e,{recursive:!0})}_filePath(e){return Xe.join(this.dir,`${e}.${this.format}`)}async read(e){let t=this._filePath(e);try{let i=await K.promises.readFile(t);if(this.format==="gz")i=oi.inflateSync(i);return i.toString("utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async write(e,t){let i=this._filePath(e),s=Xe.join(this.dir,`${e}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let n=oi.deflateSync(t);await K.promises.writeFile(s,n)}else await K.promises.writeFile(s,t,"utf8");await K.promises.rename(s,i)}async writeAll(e){let t=[];try{for(let{name:i,data:s}of e){let n=this._filePath(i),r=Xe.join(this.dir,`${i}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let a=oi.deflateSync(s);await K.promises.writeFile(r,a)}else await K.promises.writeFile(r,s,"utf8");t.push({tmp:r,fp:n})}for(let{tmp:i,fp:s}of t)await K.promises.rename(i,s)}catch(i){for(let{tmp:s}of t)try{await K.promises.unlink(s)}catch{}throw i}}async delete(e){let t=this._filePath(e);try{await K.promises.unlink(t)}catch(i){if(i.code!=="ENOENT")throw i}}async list(){try{let e=await K.promises.readdir(this.dir),t=`.${this.format}`;return e.filter((i)=>i.endsWith(t)&&!i.includes(".tmp.")).map((i)=>i.slice(0,-t.length))}catch(e){if(e.code==="ENOENT")return[];throw e}}join(...e){return Xe.join(...e)}ensureDir(e){this._ensureDir(e)}async writeRaw(e,t){this._ensureDir(Xe.dirname(e)),await K.promises.writeFile(e,t,"utf8")}async readRaw(e){return K.promises.readFile(Xe.resolve(e),"utf8")}}class wr{constructor(){this._migrations=[]}add(e){let{version:t,up:i}=e;if(typeof t!=="number"||t<1)throw new D("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version must be a positive integer, got ${t}`,{version:t});if(typeof i!=="function")throw new D("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version ${t} must have an "up" function`,{version:t});if(this._migrations.some((s)=>s.version===t))throw new D("ERR_SKALEX_VALIDATION_MIGRATION_DUPLICATE",`Migration version ${t} is already registered`,{version:t});this._migrations.push({...e}),this._migrations.sort((s,n)=>s.version-n.version)}async run(e,t=[]){let i=new Set(t),s=this._migrations.filter((n)=>!i.has(n.version));for(let n of s){let r=e(n.version);await n.up(r),i.add(n.version)}return[...i].sort((n,r)=>n-r)}status(e=[]){let t=new Set(e),i=this._migrations.map((s)=>s.version).filter((s)=>!t.has(s));return{current:e.length?Math.max(...e):0,applied:[...t].sort((s,n)=>s-n),pending:i}}}var Bs={[Symbol.iterator](){return{next(){return{done:!0}}}},size:0};function Xs(e){return{[Symbol.iterator](){return e[Symbol.iterator]()},get size(){return e.size}}}function _i(e){return e.map((t)=>{if(t===null||t===void 0)return"\x00";if(typeof t==="boolean")return t?"\x01T":"\x01F";if(typeof t==="number")return`\x02${t}`;return`\x03${String(t)}`}).join("\x1F")}class kt{constructor(e=[],t=[]){this._fields=new Set,this._compoundFields=[];for(let i of e)if(Array.isArray(i)){for(let s of i)this._validateFieldName(s);this._compoundFields.push(i)}else this._validateFieldName(i),this._fields.add(i);for(let i of t)this._validateFieldName(i);this._uniqueFields=new Set(t),this._indexedFields=new Set([...this._fields,...this._uniqueFields]),this._fieldIndexes=new Map,this._uniqueIndexes=new Map;for(let i of this._fields)this._fieldIndexes.set(i,new Map);for(let i of this._uniqueFields)if(this._uniqueIndexes.set(i,new Map),!this._fieldIndexes.has(i))this._fieldIndexes.set(i,new Map);this._compoundIndexes=new Map;for(let i of this._compoundFields)this._compoundIndexes.set(i.join("\x00"),{fields:i,map:new Map})}get indexedFields(){return this._indexedFields}buildFromData(e){for(let[,t]of this._fieldIndexes)t.clear();for(let[,t]of this._uniqueIndexes)t.clear();for(let[,t]of this._compoundIndexes)t.map.clear();for(let t of e)this._indexDoc(t)}add(e){this._checkUnique(e,null),this._indexDoc(e)}remove(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){let n=i.get(s);if(n){if(n.delete(e),n.size===0)i.delete(s)}}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.delete(s)}for(let[,t]of this._compoundIndexes){let i=_i(t.fields.map((n)=>e[n])),s=t.map.get(i);if(s){if(s.delete(e),s.size===0)t.map.delete(i)}}}update(e,t){this._checkUnique(t,e),this.remove(e);try{this._indexDoc(t)}catch(i){try{this._indexDoc(e)}catch{}throw i}}lookup(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?[...s]:[]}_lookupIterable(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?Xs(s):Bs}lookupCompound(e){let t=Object.keys(e).sort();for(let[,i]of this._compoundIndexes){let s=[...i.fields].sort();if(s.length!==t.length)continue;if(s.every((n,r)=>n===t[r])){let n=_i(i.fields.map((a)=>e[a])),r=i.map.get(n);return r?Xs(r):Bs}}return null}isUniqueTaken(e,t){let i=this._uniqueIndexes.get(e);if(!i)return!1;return i.has(t)}assertUniqueCandidates(e,t){if(this._uniqueFields.size===0)return;let i=new Set(e.map((s)=>s._id));for(let s of this._uniqueFields){let n=new Set,r=this._uniqueIndexes.get(s);if(r){for(let[l,o]of r.entries())if(!i.has(o._id))n.add(l)}let a=new Map;for(let l=0;l<t.length;l++){let o=t[l][s];if(o===void 0)continue;if(n.has(o))throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});let c=a.get(o);if(c&&c!==e[l]._id)throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});a.set(o,e[l]._id)}}}assertUniqueBatch(e){if(this._uniqueFields.size===0)return;for(let t of this._uniqueFields){let i=this._uniqueIndexes.get(t),s=new Set;for(let n of e){let r=n[t];if(r===void 0)continue;if(i&&i.has(r))throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${t}" value "${r}" already exists`,{field:t,value:r});if(s.has(r))throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: duplicate "${t}" value "${r}" within batch`,{field:t,value:r});s.add(r)}}}_validateFieldName(e){if(e.includes("."))throw new D("ERR_SKALEX_VALIDATION_INDEX_DOT_PATH",`Index fields cannot use dot-notation: "${e}". Use a flat field name.`,{field:e})}_indexDoc(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){if(!i.has(s))i.set(s,new Set);i.get(s).add(e)}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.set(s,e)}for(let[,t]of this._compoundIndexes){for(let s of t.fields){let n=e[s];if(n!==void 0&&n!==null&&typeof n==="object")throw new D("ERR_SKALEX_VALIDATION_COMPOUND_INDEX",`Compound index field "${s}" must be a scalar value (string, number, or boolean), got ${Array.isArray(n)?"array":typeof n}`,{field:s})}let i=_i(t.fields.map((s)=>e[s]));if(!t.map.has(i))t.map.set(i,new Set);t.map.get(i).add(e)}}_checkUnique(e,t){for(let i of this._uniqueFields){let s=e[i];if(s===void 0)continue;let n=this._uniqueIndexes.get(i);if(!n)continue;let r=n.get(s);if(r&&r._id!==t?._id)throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${i}" value "${s}" already exists`,{field:i,value:s})}}}var bt="_flush",Tt="migrations";class Ar{constructor({adapter:e,serializer:t,deserializer:i,logger:s,debug:n=!1,lenientLoad:r=!1}){this._adapter=e,this._serializer=t,this._deserializer=i,this._logger=s,this._debug=n,this._lenientLoad=r,this._saveLock=Promise.resolve()}_withSaveLock(e){let t=this._saveLock.then(e);return this._saveLock=t.catch(()=>{}),t}async loadAll(e,{parseSchema:t,buildIndex:i,IndexEngine:s}){try{let n=await this._adapter.list();await Promise.all(n.map(async(r)=>{try{let a=await this._adapter.read(r);if(!a)return;let l=this._deserializer(a),{collectionName:o,data:c}=l;if(!o)return;let h=e[o],u=h?.rawSchema??l.rawSchema??null,d=h?.schema??(u?t(u):null),_=h?.changelog??l.changelog??!1,f=h?.softDelete??l.softDelete??!1,p=h?.versioning??l.versioning??!1,m=h?.strict??l.strict??!1,w=h?.onSchemaError??l.onSchemaError??"throw",x=h?.defaultTtl??l.defaultTtl??null,R=h?.defaultEmbed??l.defaultEmbed??null,E=h?.maxDocs??l.maxDocs??null,A=h?h.fieldIndex:null;if(!A&&d?.uniqueFields?.length)A=new s([],d.uniqueFields);let Ue=i(c,"_id");if(A)A.buildFromData(c);e[o]={collectionName:o,data:c,index:Ue,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:d,rawSchema:u,fieldIndex:A,changelog:_,softDelete:f,versioning:p,strict:m,onSchemaError:w,defaultTtl:x,defaultEmbed:R,maxDocs:E}}catch(a){if(a.code==="ENOENT")return;if(this._lenientLoad){this._logger(`WARNING: Could not load collection "${r}": ${a.message}. Collection will be empty.`,"error");return}throw new Le("ERR_SKALEX_PERSISTENCE_CORRUPT",`Failed to load collection "${r}": ${a.message}`,{collection:r})}})),this._detectIncompleteFlush(e),await this._cleanOrphanTempFiles()}catch(n){if(n.code!=="ENOENT")throw this._logger(`Error loading data: ${n}`,"error"),n}}async save(e,t){if(t)await this._saveOne(e,t);else await Promise.all(Object.keys(e).map((i)=>this._saveOne(e,i)))}async saveDirty(e){let t=Object.keys(e).filter((i)=>e[i]._dirty);if(t.length===0)return;await Promise.all(t.map((i)=>this._saveOne(e,i)))}saveAtomic(e,t){return this._withSaveLock(async()=>{if(t.length===0)return;this._writeFlushSentinel(e,t);let i=new Set(t);i.add("_meta");let s=[...i].filter((n)=>e[n]).map((n)=>({name:n,data:this._serializeCollection(e[n])}));try{await this._adapter.writeAll(s)}catch(n){throw new Le("ERR_SKALEX_PERSISTENCE_FLUSH_FAILED",`Batch save failed during writeAll: ${n.message}`,{collections:t})}for(let n of t)if(e[n])e[n]._dirty=!1;try{this._clearFlushSentinel(e),await this._adapter.write("_meta",this._serializeCollection(e._meta))}catch(n){this._logger(`WARNING: Batch data committed but sentinel clear failed: ${n.message}. Next load will report an incomplete flush (false positive).`,"error")}})}markDirty(e,t){let i=e[t];if(i)i._dirty=!0}_serializeCollection(e){let t={collectionName:e.collectionName,data:e.data};if(e.rawSchema)t.rawSchema=e.rawSchema;if(e.changelog)t.changelog=e.changelog;if(e.softDelete)t.softDelete=e.softDelete;if(e.versioning)t.versioning=e.versioning;if(e.strict)t.strict=e.strict;if(e.onSchemaError!=="throw")t.onSchemaError=e.onSchemaError;if(e.defaultTtl)t.defaultTtl=e.defaultTtl;if(e.defaultEmbed)t.defaultEmbed=e.defaultEmbed;if(e.maxDocs)t.maxDocs=e.maxDocs;return this._serializer(t)}async _saveOne(e,t){let i=e[t];if(!i)return;if(i.isSaving)return i._pendingSave=!0,new Promise((s,n)=>{(i._saveWaiters??=[]).push({resolve:s,reject:n})});i.isSaving=!0,i._pendingSave=!1;try{await this._writeCollection(t,i);while(i._pendingSave)i._pendingSave=!1,await this._writeCollection(t,i);this._resolveSaveWaiters(i)}catch(s){throw this._rejectSaveWaiters(i,s),s}finally{i.isSaving=!1}}async _writeCollection(e,t){try{await this._adapter.write(e,this._serializeCollection(t)),t._dirty=!1}catch(i){throw this._logger(`Error saving "${e}": ${i.message}`,"error"),i}}_resolveSaveWaiters(e){let t=e._saveWaiters?.splice(0)??[];for(let i of t)i.resolve()}_rejectSaveWaiters(e,t){let i=e._saveWaiters?.splice(0)??[];for(let s of i)s.reject(t)}_writeFlushSentinel(e,t){let i=this._getOrCreateMeta(e);i[bt]={startedAt:new Date().toISOString(),collections:t,completedAt:null}}_clearFlushSentinel(e){let t=this._getOrCreateMeta(e);if(t[bt])t[bt].completedAt=new Date().toISOString()}_detectIncompleteFlush(e){let t=e._meta;if(!t)return;let i=t.index.get(Tt);if(!i)return;let s=i[bt];if(!s)return;if(s.startedAt&&!s.completedAt)this._logger(`WARNING: Incomplete flush detected (started ${s.startedAt}, collections: ${s.collections?.join(", ")}). Data may be inconsistent.`,"error")}async _cleanOrphanTempFiles(){if(typeof this._adapter.join!=="function")return;if(typeof this._adapter.list!=="function")return;try{let e=await import("fs"),t=await import("path"),i=this._adapter.dir;if(!i)return;let s=(await e.default.promises.readdir(i)).filter((n)=>n.includes(".tmp."));for(let n of s){let r=t.default.join(i,n);try{await e.default.promises.unlink(r),this._log(`Cleaned orphan temp file: ${n}`)}catch{}}}catch{}}_getOrCreateMeta(e){if(!e._meta)e._meta={collectionName:"_meta",data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:null,rawSchema:null,fieldIndex:null,changelog:!1,softDelete:!1,versioning:!1,strict:!1,onSchemaError:"throw",defaultTtl:null,defaultEmbed:null,maxDocs:null};let t=e._meta,i=t.index.get(Tt);if(!i)i={_id:Tt},t.data.push(i),t.index.set(Tt,i);return i}_log(e){if(this._debug)this._logger(e,"info")}}var rc=0;class xr{constructor(){this._txLock=Promise.resolve(),this._ctx=null,this._abortedIds=new Set}get active(){return this._ctx!==null&&!this._ctx.aborted}get context(){return this._ctx}async run(e,t,{timeout:i=0}={}){let s=async()=>{await t._ensureConnected();let r=new Set(Object.keys(t.collections)),a={id:++rc,startedAt:Date.now(),aborted:!1,preExisting:r,touchedCollections:new Set,snapshots:new Map,deferredEffects:[],timeout:i};this._ctx=a;let l=null,o=i>0?new Promise((u,d)=>{l=setTimeout(()=>{a.aborted=!0,d(new ye("ERR_SKALEX_TX_TIMEOUT",`Transaction ${a.id} timed out after ${i}ms`))},i)}):null,c=this,h=new Proxy(t,{get(u,d){if(d==="_txId")return a.id;if(a!==c._ctx)throw new ye("ERR_SKALEX_TX_STALE_PROXY",`Transaction ${a.id} has ended. This proxy is no longer usable.`);if(d==="collections")throw new ye("ERR_SKALEX_TX_DIRECT_ACCESS","Direct access to db.collections inside transaction() is not covered by rollback. Use the collection API (db.useCollection) instead.");if(d==="useCollection")return(f)=>{let p=u.useCollection(f);return p._activeTxId=a.id,p};let _=Reflect.get(u,d);return typeof _==="function"?_.bind(u):_}});try{let u=e(h),d=o?await Promise.race([u,o]):await u;if(a.aborted)throw new ye("ERR_SKALEX_TX_ABORTED",`Transaction ${a.id} was aborted`);let _=[...a.touchedCollections];if(_.length>0)await t._persistence.saveAtomic(t.collections,_);for(let f of a.deferredEffects)await f();return d}catch(u){for(let[d,_]of a.snapshots)if(a.preExisting.has(d)){if(t._applySnapshot(d,_),t.collections[d])t.collections[d]._dirty=_._dirty}for(let d in t.collections)if(!a.preExisting.has(d))delete t.collections[d],delete t._collectionInstances[d];throw u}finally{if(l)clearTimeout(l);if(a.aborted)this._abortedIds.add(a.id);this._ctx=null;for(let u in t._collectionInstances){let d=t._collectionInstances[u];if(d._createdInTxId===a.id)d._createdInTxId=null;if(d._activeTxId===a.id)d._activeTxId=null}}},n=this._txLock.then(s);return this._txLock=n.catch(()=>{}),n}snapshotIfNeeded(e,t,i){let s=this._ctx;if(!s)return;if(this._assertCtxNotAborted(s),!s.snapshots.has(e)){let n=i(t);n._dirty=t._dirty??!1,s.snapshots.set(e,n)}s.touchedCollections.add(e)}assertNotAborted(){let e=this._ctx;if(e)this._assertCtxNotAborted(e)}_assertCtxNotAborted(e){if(e.aborted)throw new ye("ERR_SKALEX_TX_ABORTED",`Transaction ${e.id} was aborted. No further mutations allowed.`)}defer(e){if(this._ctx)return this._ctx.deferredEffects.push(e),!0;return!1}}class vr{constructor(e){this._CollectionClass=e,this.stores={},this._instances={}}get(e,t){if(this._instances[e])return this._instances[e];if(!this.stores[e])this.createStore(e);let i=new this._CollectionClass(this.stores[e],t);return this._instances[e]=i,i}create(e,t={},i){this.createStore(e,t);let s=new this._CollectionClass(this.stores[e],i);return this._instances[e]=s,s}createStore(e,{schema:t,indexes:i=[],changelog:s=!1,softDelete:n=!1,versioning:r=!1,strict:a=!1,onSchemaError:l="throw",defaultTtl:o=null,defaultEmbed:c=null,maxDocs:h=null}={}){let u=null,d=null;if(t){u=_r(t);let _=u.uniqueFields;if(i.length||_.length)d=new kt(i,_)}else if(i.length)d=new kt(i,[]);this.stores[e]={collectionName:e,data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:u,rawSchema:t||null,fieldIndex:d,changelog:s,softDelete:n,versioning:r,strict:a,onSchemaError:l,defaultTtl:o,defaultEmbed:c,maxDocs:h}}rename(e,t){if(!this.stores[e])throw new Le("ERR_SKALEX_PERSISTENCE_COLLECTION_NOT_FOUND",`Collection "${e}" not found`,{collection:e});if(this.stores[t])throw new Le("ERR_SKALEX_PERSISTENCE_COLLECTION_EXISTS",`Collection "${t}" already exists`,{collection:t});let i=this.stores[e];if(i.collectionName=t,this.stores[t]=i,delete this.stores[e],this._instances[e]){let s=this._instances[e];s.name=t,this._instances[t]=s,delete this._instances[e]}}buildIndex(e,t){let i=new Map;for(let s of e)i.set(s[t],s);return i}inspect(e){if(e){let i=this.stores[e];if(!i)return null;return{name:e,count:i.data.length,schema:i.schema?Object.fromEntries(i.schema.fields):null,indexes:i.fieldIndex?[...i.fieldIndex.indexedFields]:[],softDelete:i.softDelete??!1,versioning:i.versioning??!1,strict:i.strict??!1,onSchemaError:i.onSchemaError??"throw",maxDocs:i.maxDocs??null}}let t={};for(let i in this.stores)t[i]=this.inspect(i);return t}dump(){let e={};for(let t in this.stores)if(!t.startsWith("_"))e[t]=structuredClone(this.stores[t].data);return e}schema(e){let t=this.stores[e];if(!t)return null;if(t.schema)return Object.fromEntries([...t.schema.fields.entries()].map(([i,s])=>[i,s.type]));if(t.data.length>0)return Wl(t.data[0]);return null}stats(e){let t=(i)=>{let s=this.stores[i];if(!s)return null;let n=s.data.length,r=0;for(let a of s.data)try{r+=JSON.stringify(a).length}catch(l){}return{collection:i,count:n,estimatedSize:r,avgDocSize:n>0?Math.round(r/n):0}};if(e)return t(e);return Object.keys(this.stores).map(t)}clear(){this.stores={},this._instances={}}}class Fi{async embed(e){throw Error("EmbeddingAdapter.embed() not implemented")}}var he=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Er extends Fi{constructor({apiKey:e=he("OPENAI_API_KEY"),model:t=he("OPENAI_EMBED_MODEL")??"text-embedding-3-small",baseUrl:i=he("OPENAI_EMBED_BASE_URL")??"https://api.openai.com/v1/embeddings",dimensions:s=he("OPENAI_EMBED_DIMENSIONS")!=null?Number(he("OPENAI_EMBED_DIMENSIONS")):void 0,organization:n=he("OPENAI_ORGANIZATION")??void 0,timeout:r=he("OPENAI_EMBED_TIMEOUT")!=null?Number(he("OPENAI_EMBED_TIMEOUT")):void 0,retries:a=Number(he("OPENAI_EMBED_RETRIES")??0),retryDelay:l=Number(he("OPENAI_EMBED_RETRY_DELAY")??1000),headers:o={},fetch:c=globalThis.fetch}={}){super();if(!e)throw Error("OpenAIEmbeddingAdapter requires an apiKey");this.apiKey=e,this.model=t,this.baseUrl=i,this.dimensions=s,this.organization=n,this.timeout=r,this.retries=a,this.retryDelay=l,this.headers=o,this._fetch=c}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(this.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...this.organization&&{"OpenAI-Organization":this.organization},...this.headers},body:JSON.stringify({input:e,model:this.model,...this.dimensions!==void 0&&{dimensions:this.dimensions}}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`OpenAI embedding API error ${r.status}: ${a}`)}return(await r.json()).data[0].embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}var rt=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Sr extends Fi{constructor({model:e=rt("OLLAMA_EMBED_MODEL")??"nomic-embed-text",host:t=rt("OLLAMA_HOST")??"http://localhost:11434",timeout:i=rt("OLLAMA_EMBED_TIMEOUT")!=null?Number(rt("OLLAMA_EMBED_TIMEOUT")):void 0,retries:s=Number(rt("OLLAMA_EMBED_RETRIES")??0),retryDelay:n=Number(rt("OLLAMA_EMBED_RETRY_DELAY")??1000),headers:r={},fetch:a=globalThis.fetch}={}){super();this.model=e,this.host=t,this.timeout=i,this.retries=s,this.retryDelay=n,this.headers=r,this._fetch=a}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({model:this.model,prompt:e}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama embedding API error ${r.status}: ${a}`)}return(await r.json()).embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}class Ft{async generate(e,t){throw Error("LLMAdapter.generate() not implemented")}async summarize(e){throw Error("LLMAdapter.summarize() not implemented")}}var Ui=`You are a database query assistant. Convert the user's natural language request into a JSON filter object for a document database.
67
+ `)}if(typeof this._ctx.fs.writeRaw!=="function")throw new fe("ERR_SKALEX_ADAPTER_NO_RAW_WRITE","export() requires a file-system adapter (FsAdapter). The current adapter does not support raw file writes.");let l=i||`${this._ctx.dataDirectory}/exports`,o=`${s||this.name}.${n}`,c=this._ctx.fs.join(l,o);this._ctx.fs.ensureDir(l),await this._ctx.fs.writeRaw(c,a)}catch(r){throw this._ctx.logger(`Error exporting "${this.name}": ${r.message}`,"error"),r}}_txSnapshotIfNeeded(){let e=this._ctx.txManager;if(!e.active)return;if(this._activeTxId!==e.context?.id)return;e.snapshotIfNeeded(this.name,this._store,(t)=>this._ctx.snapshotCollection(t))}async _saveIfNeeded(e){let t=this._ctx.txManager;if(t.active&&this._activeTxId===t.context?.id)return;if(e??this._ctx.autoSave)await this._ctx.saveCollection(this.name)}_applyValidation(e){if(!this._schema)return e;let t=Fs(e,this._schema,this._strict);if(!t.length)return e;switch(this._onSchemaError){case"warn":return this._ctx.logger(`[${this.name}] Validation warning: ${t.join("; ")}`,"warn"),e;case"strip":return Us(e,this._schema);default:throw new D("ERR_SKALEX_VALIDATION_FAILED",`Validation failed: ${t.join("; ")}`,{errors:t})}}_enforceCapAfterInsert(){let e=this._maxDocs;if(!e||this._data.length<=e)return;let t=this._data.splice(0,this._data.length-e);for(let i of t)this._index.delete(i._id),this._removeFromIndex(i)}_findRaw(e,{includeDeleted:t=!1}={}){if(typeof e==="function"){for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(e(i))return i}return null}if(e._id){let i=this._index.get(e._id)||null;if(!i)return null;if(this._softDelete&&i._deletedAt&&!t)return null;if(Object.keys(e).length>1)return J(i,e)?i:null;return i}if(this._fieldIndex)for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null){let n=this._fieldIndex._lookupIterable(i,s);if(n!==null){for(let r of n){if(this._softDelete&&r._deletedAt&&!t)continue;if(J(r,e))return r}return null}}}for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(J(i,e))return i}return null}_findAllRaw(e,{includeDeleted:t=!1}={}){if(e&&typeof e!=="function"&&e._id){let s=this._index.get(e._id);if(!s)return[];if(this._softDelete&&s._deletedAt&&!t)return[];return J(s,e)?[s]:[]}let i=[];for(let s of this._getCandidates(e)){if(this._softDelete&&s._deletedAt&&!t)continue;if(J(s,e))i.push(s)}return i}_getCandidates(e){if(!this._fieldIndex)return this._data;if(this._fieldIndex._compoundIndexes.size>0){let t={};for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null)t[i]=s}if(Object.keys(t).length>=2){let i=this._fieldIndex.lookupCompound(t);if(i!==null)return i}}for(let t in e){if(t==="$or"||t==="$and"||t==="$not")continue;let i=e[t];if(typeof i!=="object"||i===null){let s=this._fieldIndex._lookupIterable(t,i);if(s!==null)return s}}return this._data}_findIndex(e){for(let t=0;t<this._data.length;t++)if(J(this._data[t],e))return t;return-1}_addToIndex(e){if(this._fieldIndex)this._fieldIndex.add(e)}_removeFromIndex(e){if(this._fieldIndex)this._fieldIndex.remove(e)}_updateInIndex(e,t){if(this._fieldIndex)this._fieldIndex.update(e,t)}async _buildDoc(e,{ttl:t,embed:i}={}){let s={...e,_id:e._id??(this._ctx.idGenerator??Wl)(),createdAt:new Date,updatedAt:new Date},n=t??this._defaultTtl;if(n)s._expiresAt=ec(n);let r=i??this._defaultEmbed;if(r){let a=typeof r==="function"?r(s):s[r];s._vector=await this._ctx.embed(String(a))}if(this._versioning)s._version=1;return s}_projectDoc(e,t){if(t){let s={};for(let n of t){if(n==="_vector")continue;s[n]=e[n]}return s}let i={...e};return delete i._vector,i}async _populateDoc(e,t,i){for(let s of i){let n=await this._ctx.getCollection(s).findOne({_id:t[s]});if(n)e[s]=n}}}class Ki{async read(e){throw Error("StorageAdapter.read() not implemented")}async write(e,t){throw Error("StorageAdapter.write() not implemented")}async delete(e){throw Error("StorageAdapter.delete() not implemented")}async list(){throw Error("StorageAdapter.list() not implemented")}async writeAll(e){for(let{name:t,data:i}of e)await this.write(t,i)}}class yr extends Ki{constructor({dir:e,format:t="gz"}){super();this.dir=Xe.resolve(e),this.format=t,this._ensureDir(this.dir)}_ensureDir(e){if(!K.existsSync(e))K.mkdirSync(e,{recursive:!0})}_filePath(e){return Xe.join(this.dir,`${e}.${this.format}`)}async read(e){let t=this._filePath(e);try{let i=await K.promises.readFile(t);if(this.format==="gz")i=oi.inflateSync(i);return i.toString("utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async write(e,t){let i=this._filePath(e),s=Xe.join(this.dir,`${e}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let n=oi.deflateSync(t);await K.promises.writeFile(s,n)}else await K.promises.writeFile(s,t,"utf8");await K.promises.rename(s,i)}async writeAll(e){let t=[];try{for(let{name:i,data:s}of e){let n=this._filePath(i),r=Xe.join(this.dir,`${i}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let a=oi.deflateSync(s);await K.promises.writeFile(r,a)}else await K.promises.writeFile(r,s,"utf8");t.push({tmp:r,fp:n})}for(let{tmp:i,fp:s}of t)await K.promises.rename(i,s)}catch(i){for(let{tmp:s}of t)try{await K.promises.unlink(s)}catch{}throw i}}async delete(e){let t=this._filePath(e);try{await K.promises.unlink(t)}catch(i){if(i.code!=="ENOENT")throw i}}async list(){try{let e=await K.promises.readdir(this.dir),t=`.${this.format}`;return e.filter((i)=>i.endsWith(t)&&!i.includes(".tmp.")).map((i)=>i.slice(0,-t.length))}catch(e){if(e.code==="ENOENT")return[];throw e}}join(...e){return Xe.join(...e)}ensureDir(e){this._ensureDir(e)}async writeRaw(e,t){this._ensureDir(Xe.dirname(e)),await K.promises.writeFile(e,t,"utf8")}async readRaw(e){return K.promises.readFile(Xe.resolve(e),"utf8")}}class wr{constructor(){this._migrations=[]}add(e){let{version:t,up:i}=e;if(typeof t!=="number"||t<1)throw new D("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version must be a positive integer, got ${t}`,{version:t});if(typeof i!=="function")throw new D("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version ${t} must have an "up" function`,{version:t});if(this._migrations.some((s)=>s.version===t))throw new D("ERR_SKALEX_VALIDATION_MIGRATION_DUPLICATE",`Migration version ${t} is already registered`,{version:t});this._migrations.push({...e}),this._migrations.sort((s,n)=>s.version-n.version)}async run(e,t=[]){let i=new Set(t),s=this._migrations.filter((n)=>!i.has(n.version));for(let n of s){let r=e(n.version);await n.up(r),i.add(n.version)}return[...i].sort((n,r)=>n-r)}status(e=[]){let t=new Set(e),i=this._migrations.map((s)=>s.version).filter((s)=>!t.has(s));return{current:e.length?Math.max(...e):0,applied:[...t].sort((s,n)=>s-n),pending:i}}}var Bs={[Symbol.iterator](){return{next(){return{done:!0}}}},size:0};function Xs(e){return{[Symbol.iterator](){return e[Symbol.iterator]()},get size(){return e.size}}}function _i(e){return e.map((t)=>{if(t===null||t===void 0)return"\x00";if(typeof t==="boolean")return t?"\x01T":"\x01F";if(typeof t==="number")return`\x02${t}`;return`\x03${String(t)}`}).join("\x1F")}class kt{constructor(e=[],t=[]){this._fields=new Set,this._compoundFields=[];for(let i of e)if(Array.isArray(i)){for(let s of i)this._validateFieldName(s);this._compoundFields.push(i)}else this._validateFieldName(i),this._fields.add(i);for(let i of t)this._validateFieldName(i);this._uniqueFields=new Set(t),this._indexedFields=new Set([...this._fields,...this._uniqueFields]),this._fieldIndexes=new Map,this._uniqueIndexes=new Map;for(let i of this._fields)this._fieldIndexes.set(i,new Map);for(let i of this._uniqueFields)if(this._uniqueIndexes.set(i,new Map),!this._fieldIndexes.has(i))this._fieldIndexes.set(i,new Map);this._compoundIndexes=new Map;for(let i of this._compoundFields)this._compoundIndexes.set(i.join("\x00"),{fields:i,map:new Map})}get indexedFields(){return this._indexedFields}buildFromData(e){for(let[,t]of this._fieldIndexes)t.clear();for(let[,t]of this._uniqueIndexes)t.clear();for(let[,t]of this._compoundIndexes)t.map.clear();for(let t of e)this._indexDoc(t)}add(e){this._checkUnique(e,null),this._indexDoc(e)}remove(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){let n=i.get(s);if(n){if(n.delete(e),n.size===0)i.delete(s)}}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.delete(s)}for(let[,t]of this._compoundIndexes){let i=_i(t.fields.map((n)=>e[n])),s=t.map.get(i);if(s){if(s.delete(e),s.size===0)t.map.delete(i)}}}update(e,t){this._checkUnique(t,e),this.remove(e);try{this._indexDoc(t)}catch(i){try{this._indexDoc(e)}catch{}throw i}}lookup(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?[...s]:[]}_lookupIterable(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?Xs(s):Bs}lookupCompound(e){let t=Object.keys(e).sort();for(let[,i]of this._compoundIndexes){let s=[...i.fields].sort();if(s.length!==t.length)continue;if(s.every((n,r)=>n===t[r])){let n=_i(i.fields.map((a)=>e[a])),r=i.map.get(n);return r?Xs(r):Bs}}return null}isUniqueTaken(e,t){let i=this._uniqueIndexes.get(e);if(!i)return!1;return i.has(t)}assertUniqueCandidates(e,t){if(this._uniqueFields.size===0)return;let i=new Set(e.map((s)=>s._id));for(let s of this._uniqueFields){let n=new Set,r=this._uniqueIndexes.get(s);if(r){for(let[l,o]of r.entries())if(!i.has(o._id))n.add(l)}let a=new Map;for(let l=0;l<t.length;l++){let o=t[l][s];if(o===void 0)continue;if(n.has(o))throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});let c=a.get(o);if(c&&c!==e[l]._id)throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});a.set(o,e[l]._id)}}}assertUniqueBatch(e){if(this._uniqueFields.size===0)return;for(let t of this._uniqueFields){let i=this._uniqueIndexes.get(t),s=new Set;for(let n of e){let r=n[t];if(r===void 0)continue;if(i&&i.has(r))throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${t}" value "${r}" already exists`,{field:t,value:r});if(s.has(r))throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: duplicate "${t}" value "${r}" within batch`,{field:t,value:r});s.add(r)}}}_validateFieldName(e){if(e.includes("."))throw new D("ERR_SKALEX_VALIDATION_INDEX_DOT_PATH",`Index fields cannot use dot-notation: "${e}". Use a flat field name.`,{field:e})}_indexDoc(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){if(!i.has(s))i.set(s,new Set);i.get(s).add(e)}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.set(s,e)}for(let[,t]of this._compoundIndexes){for(let s of t.fields){let n=e[s];if(n!==void 0&&n!==null&&typeof n==="object")throw new D("ERR_SKALEX_VALIDATION_COMPOUND_INDEX",`Compound index field "${s}" must be a scalar value (string, number, or boolean), got ${Array.isArray(n)?"array":typeof n}`,{field:s})}let i=_i(t.fields.map((s)=>e[s]));if(!t.map.has(i))t.map.set(i,new Set);t.map.get(i).add(e)}}_checkUnique(e,t){for(let i of this._uniqueFields){let s=e[i];if(s===void 0)continue;let n=this._uniqueIndexes.get(i);if(!n)continue;let r=n.get(s);if(r&&r._id!==t?._id)throw new Ie("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${i}" value "${s}" already exists`,{field:i,value:s})}}}var bt="_flush",Tt="migrations";class Ar{constructor({adapter:e,serializer:t,deserializer:i,logger:s,debug:n=!1,lenientLoad:r=!1}){this._adapter=e,this._serializer=t,this._deserializer=i,this._logger=s,this._debug=n,this._lenientLoad=r,this._saveLock=Promise.resolve()}_withSaveLock(e){let t=this._saveLock.then(e);return this._saveLock=t.catch(()=>{}),t}async loadAll(e,{parseSchema:t,buildIndex:i,IndexEngine:s}){try{let n=await this._adapter.list();await Promise.all(n.map(async(r)=>{try{let a=await this._adapter.read(r);if(!a)return;let l=this._deserializer(a),{collectionName:o,data:c}=l;if(!o)return;let h=e[o],u=h?.rawSchema??l.rawSchema??null,d=h?.schema??(u?t(u):null),_=h?.changelog??l.changelog??!1,f=h?.softDelete??l.softDelete??!1,p=h?.versioning??l.versioning??!1,m=h?.strict??l.strict??!1,w=h?.onSchemaError??l.onSchemaError??"throw",x=h?.defaultTtl??l.defaultTtl??null,R=h?.defaultEmbed??l.defaultEmbed??null,E=h?.maxDocs??l.maxDocs??null,A=h?h.fieldIndex:null;if(!A&&d?.uniqueFields?.length)A=new s([],d.uniqueFields);let Ue=i(c,"_id");if(A)A.buildFromData(c);e[o]={collectionName:o,data:c,index:Ue,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:d,rawSchema:u,fieldIndex:A,changelog:_,softDelete:f,versioning:p,strict:m,onSchemaError:w,defaultTtl:x,defaultEmbed:R,maxDocs:E}}catch(a){if(a.code==="ENOENT")return;if(this._lenientLoad){this._logger(`WARNING: Could not load collection "${r}": ${a.message}. Collection will be empty.`,"error");return}throw new Le("ERR_SKALEX_PERSISTENCE_CORRUPT",`Failed to load collection "${r}": ${a.message}`,{collection:r})}})),this._detectIncompleteFlush(e),await this._cleanOrphanTempFiles()}catch(n){if(n.code!=="ENOENT")throw this._logger(`Error loading data: ${n}`,"error"),n}}async save(e,t){if(t)await this._saveOne(e,t);else await Promise.all(Object.keys(e).map((i)=>this._saveOne(e,i)))}async saveDirty(e){let t=Object.keys(e).filter((i)=>e[i]._dirty);if(t.length===0)return;await Promise.all(t.map((i)=>this._saveOne(e,i)))}saveAtomic(e,t){return this._withSaveLock(async()=>{if(t.length===0)return;this._writeFlushSentinel(e,t);let i=new Set(t);i.add("_meta");let s=[...i].filter((n)=>e[n]).map((n)=>({name:n,data:this._serializeCollection(e[n])}));try{await this._adapter.writeAll(s)}catch(n){throw new Le("ERR_SKALEX_PERSISTENCE_FLUSH_FAILED",`Batch save failed during writeAll: ${n.message}`,{collections:t})}for(let n of t)if(e[n])e[n]._dirty=!1;try{this._clearFlushSentinel(e),await this._adapter.write("_meta",this._serializeCollection(e._meta))}catch(n){this._logger(`WARNING: Batch data committed but sentinel clear failed: ${n.message}. Next load will report an incomplete flush (false positive).`,"error")}})}markDirty(e,t){let i=e[t];if(i)i._dirty=!0}_serializeCollection(e){let t={collectionName:e.collectionName,data:e.data};if(e.rawSchema)t.rawSchema=e.rawSchema;if(e.changelog)t.changelog=e.changelog;if(e.softDelete)t.softDelete=e.softDelete;if(e.versioning)t.versioning=e.versioning;if(e.strict)t.strict=e.strict;if(e.onSchemaError!=="throw")t.onSchemaError=e.onSchemaError;if(e.defaultTtl)t.defaultTtl=e.defaultTtl;if(e.defaultEmbed)t.defaultEmbed=e.defaultEmbed;if(e.maxDocs)t.maxDocs=e.maxDocs;return this._serializer(t)}async _saveOne(e,t){let i=e[t];if(!i)return;if(i.isSaving)return i._pendingSave=!0,new Promise((s,n)=>{(i._saveWaiters??=[]).push({resolve:s,reject:n})});i.isSaving=!0,i._pendingSave=!1;try{await this._writeCollection(t,i);while(i._pendingSave)i._pendingSave=!1,await this._writeCollection(t,i);this._resolveSaveWaiters(i)}catch(s){throw this._rejectSaveWaiters(i,s),s}finally{i.isSaving=!1}}async _writeCollection(e,t){try{await this._adapter.write(e,this._serializeCollection(t)),t._dirty=!1}catch(i){throw this._logger(`Error saving "${e}": ${i.message}`,"error"),i}}_resolveSaveWaiters(e){let t=e._saveWaiters?.splice(0)??[];for(let i of t)i.resolve()}_rejectSaveWaiters(e,t){let i=e._saveWaiters?.splice(0)??[];for(let s of i)s.reject(t)}_writeFlushSentinel(e,t){let i=this._getOrCreateMeta(e);i[bt]={startedAt:new Date().toISOString(),collections:t,completedAt:null}}_clearFlushSentinel(e){let t=this._getOrCreateMeta(e);if(t[bt])t[bt].completedAt=new Date().toISOString()}_detectIncompleteFlush(e){let t=e._meta;if(!t)return;let i=t.index.get(Tt);if(!i)return;let s=i[bt];if(!s)return;if(s.startedAt&&!s.completedAt)this._logger(`WARNING: Incomplete flush detected (started ${s.startedAt}, collections: ${s.collections?.join(", ")}). Data may be inconsistent.`,"error")}async _cleanOrphanTempFiles(){if(typeof this._adapter.join!=="function")return;if(typeof this._adapter.list!=="function")return;try{let e=await import("fs"),t=await import("path"),i=this._adapter.dir;if(!i)return;let s=(await e.default.promises.readdir(i)).filter((n)=>n.includes(".tmp."));for(let n of s){let r=t.default.join(i,n);try{await e.default.promises.unlink(r),this._log(`Cleaned orphan temp file: ${n}`)}catch{}}}catch{}}_getOrCreateMeta(e){if(!e._meta)e._meta={collectionName:"_meta",data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:null,rawSchema:null,fieldIndex:null,changelog:!1,softDelete:!1,versioning:!1,strict:!1,onSchemaError:"throw",defaultTtl:null,defaultEmbed:null,maxDocs:null};let t=e._meta,i=t.index.get(Tt);if(!i)i={_id:Tt},t.data.push(i),t.index.set(Tt,i);return i}_log(e){if(this._debug)this._logger(e,"info")}}var oc=0;class xr{constructor(){this._txLock=Promise.resolve(),this._ctx=null,this._abortedIds=new Set}get active(){return this._ctx!==null&&!this._ctx.aborted}get context(){return this._ctx}async run(e,t,{timeout:i=0}={}){let s=async()=>{await t._ensureConnected();let r=new Set(Object.keys(t.collections)),a={id:++oc,startedAt:Date.now(),aborted:!1,preExisting:r,touchedCollections:new Set,snapshots:new Map,deferredEffects:[],timeout:i};this._ctx=a;let l=null,o=i>0?new Promise((u,d)=>{l=setTimeout(()=>{a.aborted=!0,d(new ye("ERR_SKALEX_TX_TIMEOUT",`Transaction ${a.id} timed out after ${i}ms`))},i)}):null,c=this,h=new Proxy(t,{get(u,d){if(d==="_txId")return a.id;if(a!==c._ctx)throw new ye("ERR_SKALEX_TX_STALE_PROXY",`Transaction ${a.id} has ended. This proxy is no longer usable.`);if(d==="collections")throw new ye("ERR_SKALEX_TX_DIRECT_ACCESS","Direct access to db.collections inside transaction() is not covered by rollback. Use the collection API (db.useCollection) instead.");if(d==="useCollection")return(f)=>{let p=u.useCollection(f);return p._activeTxId=a.id,p};let _=Reflect.get(u,d);return typeof _==="function"?_.bind(u):_}});try{let u=e(h),d=o?await Promise.race([u,o]):await u;if(a.aborted)throw new ye("ERR_SKALEX_TX_ABORTED",`Transaction ${a.id} was aborted`);let _=[...a.touchedCollections];if(_.length>0)await t._persistence.saveAtomic(t.collections,_);for(let f of a.deferredEffects)await f();return d}catch(u){for(let[d,_]of a.snapshots)if(a.preExisting.has(d)){if(t._applySnapshot(d,_),t.collections[d])t.collections[d]._dirty=_._dirty}for(let d in t.collections)if(!a.preExisting.has(d))delete t.collections[d],delete t._collectionInstances[d];throw u}finally{if(l)clearTimeout(l);if(a.aborted)this._abortedIds.add(a.id);this._ctx=null;for(let u in t._collectionInstances){let d=t._collectionInstances[u];if(d._createdInTxId===a.id)d._createdInTxId=null;if(d._activeTxId===a.id)d._activeTxId=null}}},n=this._txLock.then(s);return this._txLock=n.catch(()=>{}),n}snapshotIfNeeded(e,t,i){let s=this._ctx;if(!s)return;if(this._assertCtxNotAborted(s),!s.snapshots.has(e)){let n=i(t);n._dirty=t._dirty??!1,s.snapshots.set(e,n)}s.touchedCollections.add(e)}assertNotAborted(){let e=this._ctx;if(e)this._assertCtxNotAborted(e)}_assertCtxNotAborted(e){if(e.aborted)throw new ye("ERR_SKALEX_TX_ABORTED",`Transaction ${e.id} was aborted. No further mutations allowed.`)}defer(e){if(this._ctx)return this._ctx.deferredEffects.push(e),!0;return!1}}class vr{constructor(e){this._CollectionClass=e,this.stores={},this._instances={}}get(e,t){if(this._instances[e])return this._instances[e];if(!this.stores[e])this.createStore(e);let i=new this._CollectionClass(this.stores[e],t);return this._instances[e]=i,i}create(e,t={},i){this.createStore(e,t);let s=new this._CollectionClass(this.stores[e],i);return this._instances[e]=s,s}createStore(e,{schema:t,indexes:i=[],changelog:s=!1,softDelete:n=!1,versioning:r=!1,strict:a=!1,onSchemaError:l="throw",defaultTtl:o=null,defaultEmbed:c=null,maxDocs:h=null}={}){let u=null,d=null;if(t){u=_r(t);let _=u.uniqueFields;if(i.length||_.length)d=new kt(i,_)}else if(i.length)d=new kt(i,[]);this.stores[e]={collectionName:e,data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:u,rawSchema:t||null,fieldIndex:d,changelog:s,softDelete:n,versioning:r,strict:a,onSchemaError:l,defaultTtl:o,defaultEmbed:c,maxDocs:h}}rename(e,t){if(!this.stores[e])throw new Le("ERR_SKALEX_PERSISTENCE_COLLECTION_NOT_FOUND",`Collection "${e}" not found`,{collection:e});if(this.stores[t])throw new Le("ERR_SKALEX_PERSISTENCE_COLLECTION_EXISTS",`Collection "${t}" already exists`,{collection:t});let i=this.stores[e];if(i.collectionName=t,this.stores[t]=i,delete this.stores[e],this._instances[e]){let s=this._instances[e];s.name=t,this._instances[t]=s,delete this._instances[e]}}buildIndex(e,t){let i=new Map;for(let s of e)i.set(s[t],s);return i}inspect(e){if(e){let i=this.stores[e];if(!i)return null;return{name:e,count:i.data.length,schema:i.schema?Object.fromEntries(i.schema.fields):null,indexes:i.fieldIndex?[...i.fieldIndex.indexedFields]:[],softDelete:i.softDelete??!1,versioning:i.versioning??!1,strict:i.strict??!1,onSchemaError:i.onSchemaError??"throw",maxDocs:i.maxDocs??null}}let t={};for(let i in this.stores)t[i]=this.inspect(i);return t}dump(){let e={};for(let t in this.stores)if(!t.startsWith("_"))e[t]=structuredClone(this.stores[t].data);return e}schema(e){let t=this.stores[e];if(!t)return null;if(t.schema)return Object.fromEntries([...t.schema.fields.entries()].map(([i,s])=>[i,s.type]));if(t.data.length>0)return Gl(t.data[0]);return null}stats(e){let t=(i)=>{let s=this.stores[i];if(!s)return null;let n=s.data.length,r=0;for(let a of s.data)try{r+=JSON.stringify(a).length}catch(l){}return{collection:i,count:n,estimatedSize:r,avgDocSize:n>0?Math.round(r/n):0}};if(e)return t(e);return Object.keys(this.stores).map(t)}clear(){this.stores={},this._instances={}}}class Fi{async embed(e){throw Error("EmbeddingAdapter.embed() not implemented")}}var he=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Er extends Fi{constructor({apiKey:e=he("OPENAI_API_KEY"),model:t=he("OPENAI_EMBED_MODEL")??"text-embedding-3-small",baseUrl:i=he("OPENAI_EMBED_BASE_URL")??"https://api.openai.com/v1/embeddings",dimensions:s=he("OPENAI_EMBED_DIMENSIONS")!=null?Number(he("OPENAI_EMBED_DIMENSIONS")):void 0,organization:n=he("OPENAI_ORGANIZATION")??void 0,timeout:r=he("OPENAI_EMBED_TIMEOUT")!=null?Number(he("OPENAI_EMBED_TIMEOUT")):void 0,retries:a=Number(he("OPENAI_EMBED_RETRIES")??0),retryDelay:l=Number(he("OPENAI_EMBED_RETRY_DELAY")??1000),headers:o={},fetch:c=globalThis.fetch}={}){super();if(!e)throw Error("OpenAIEmbeddingAdapter requires an apiKey");this.apiKey=e,this.model=t,this.baseUrl=i,this.dimensions=s,this.organization=n,this.timeout=r,this.retries=a,this.retryDelay=l,this.headers=o,this._fetch=c}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(this.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...this.organization&&{"OpenAI-Organization":this.organization},...this.headers},body:JSON.stringify({input:e,model:this.model,...this.dimensions!==void 0&&{dimensions:this.dimensions}}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`OpenAI embedding API error ${r.status}: ${a}`)}return(await r.json()).data[0].embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}var rt=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Sr extends Fi{constructor({model:e=rt("OLLAMA_EMBED_MODEL")??"nomic-embed-text",host:t=rt("OLLAMA_HOST")??"http://localhost:11434",timeout:i=rt("OLLAMA_EMBED_TIMEOUT")!=null?Number(rt("OLLAMA_EMBED_TIMEOUT")):void 0,retries:s=Number(rt("OLLAMA_EMBED_RETRIES")??0),retryDelay:n=Number(rt("OLLAMA_EMBED_RETRY_DELAY")??1000),headers:r={},fetch:a=globalThis.fetch}={}){super();this.model=e,this.host=t,this.timeout=i,this.retries=s,this.retryDelay=n,this.headers=r,this._fetch=a}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({model:this.model,prompt:e}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama embedding API error ${r.status}: ${a}`)}return(await r.json()).embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}class Ft{async generate(e,t){throw Error("LLMAdapter.generate() not implemented")}async summarize(e){throw Error("LLMAdapter.summarize() not implemented")}}var Ui=`You are a database query assistant. Convert the user's natural language request into a JSON filter object for a document database.
68
68
 
69
69
  Rules:
70
70
  - Return ONLY a valid JSON object, nothing else
@@ -79,18 +79,18 @@ Schema: ${JSON.stringify(e)}`,messages:[{role:"user",content:t}]})).content[0].t
79
79
  Schema: ${JSON.stringify(e)}
80
80
  Query: ${t}`,s=await this._post({model:this.model,prompt:i,format:"json",options:{temperature:0},stream:!1});return JSON.parse(s.response)}async summarize(e){return(await this._post({model:this.model,prompt:`${this.summarizePrompt}
81
81
 
82
- ${e}`,options:{temperature:this.temperature,...this.topP!==void 0&&{top_p:this.topP},...this.topK!==void 0&&{top_k:this.topK}},stream:!1})).response.trim()}async _post(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify(e),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama API error ${r.status}: ${a}`)}return r.json()}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}function ac({provider:e,apiKey:t,embedModel:i,model:s,host:n,embedBaseUrl:r,dimensions:a,organization:l,embedTimeout:o,embedRetries:c,embedRetryDelay:h}){let u=i||s;switch(e){case"openai":return new Er({apiKey:t,model:u,baseUrl:r,...a!==void 0&&{dimensions:a},...l!==void 0&&{organization:l},...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});case"ollama":return new Sr({model:u,host:n,...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});default:throw new fe("ERR_SKALEX_ADAPTER_UNKNOWN_PROVIDER",`Unknown AI provider: "${e}". Supported: "openai", "ollama".`,{provider:e})}}function oc({provider:e,apiKey:t,model:i,host:s,baseUrl:n,apiVersion:r,temperature:a,maxTokens:l,topP:o,topK:c,organization:h,timeout:u,retries:d,retryDelay:_,seed:f,generatePrompt:p,summarizePrompt:m}){if(!i)return null;switch(e){case"openai":return new Ir({apiKey:t,model:i,baseUrl:n,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...h!==void 0&&{organization:h},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...f!==void 0&&{seed:f},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"anthropic":return new br({apiKey:t,model:i,baseUrl:n,apiVersion:r,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"ollama":return new Tr({model:i,host:s,...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});default:return null}}var fi="AES-GCM",mt=12,be=32,lc=new TextEncoder,cc=new TextDecoder;class Or extends Ki{constructor(e,t){super();if(this._adapter=e,this._rawKey=typeof t==="string"?hc(t):Uint8Array.from(t),this._rawKey.length!==be)throw new fe("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: key must be ${be} bytes (${be*2} hex chars), got ${this._rawKey.length}`);this._cryptoKey=null}async read(e){let t=await this._adapter.read(e);if(!t)return null;return this._decrypt(t)}async write(e,t){return this._adapter.write(e,await this._encrypt(t))}async delete(e){return this._adapter.delete(e)}async list(){return this._adapter.list()}async writeAll(e){let t=[];for(let{name:i,data:s}of e)t.push({name:i,data:await this._encrypt(s)});return this._adapter.writeAll(t)}join(...e){return this._adapter.join?.(...e)}ensureDir(e){return this._adapter.ensureDir?.(e)}async writeRaw(e,t){return this._adapter.writeRaw?.(e,await this._encrypt(t))}async readRaw(e){let t=await this._adapter.readRaw?.(e);if(!t)return null;return this._decrypt(t)}async _getKey(){if(!this._cryptoKey)this._cryptoKey=await globalThis.crypto.subtle.importKey("raw",this._rawKey,{name:fi},!1,["encrypt","decrypt"]);return this._cryptoKey}async _encrypt(e){let t=await this._getKey(),i=globalThis.crypto.getRandomValues(new Uint8Array(mt)),s=lc.encode(e),n=await globalThis.crypto.subtle.encrypt({name:fi,iv:i,tagLength:128},t,s),r=new Uint8Array(mt+n.byteLength);return r.set(i,0),r.set(new Uint8Array(n),mt),dc(r)}async _decrypt(e){let t=await this._getKey(),i=uc(e),s=i.slice(0,mt),n=i.slice(mt),r=await globalThis.crypto.subtle.decrypt({name:fi,iv:s,tagLength:128},t,n);return cc.decode(r)}}function hc(e){if(e.length!==be*2)throw new fe("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: hex key must be ${be*2} characters (${be} bytes)`);if(!/^[0-9a-fA-F]+$/.test(e))throw new fe("ERR_SKALEX_ADAPTER_INVALID_KEY","EncryptedAdapter: hex key contains invalid characters");let t=new Uint8Array(be);for(let i=0;i<be;i++)t[i]=parseInt(e.slice(i*2,i*2+2),16);return t}function dc(e){let t="";for(let i=0;i<e.length;i++)t+=String.fromCharCode(e[i]);return globalThis.btoa(t)}function uc(e){let t=globalThis.atob(e),i=new Uint8Array(t.length);for(let s=0;s<t.length;s++)i[s]=t.charCodeAt(s);return i}var _c=4;class Nr{constructor(e,t){this.sessionId=e,this._db=t,this._col=t.useCollection(`_memory_${e}`)}async remember(e){let t=await this._col.insertOne({text:e,sessionId:this.sessionId},{embed:"text"}),i=this._db._memoryConfig?.maxEntries;if(i&&this._col._data.length>i)await this.compress({threshold:0});return t}async recall(e,{limit:t=10,minScore:i=0}={}){return this._col.search(e,{limit:t,minScore:i})}async history({since:e,limit:t}={}){let i=e?{createdAt:{$gte:new Date(e)}}:{},s={sort:{createdAt:1}};if(t)s.limit=t;let{docs:n}=await this._col.find(i,s);return n}async forget(e){return this._col.deleteOne({_id:e})}tokenCount(){let e=this._col._data;return{tokens:e.reduce((t,i)=>t+this._docTokens(i),0),count:e.length}}context({tokens:e=this._db._memoryConfig?.contextTokens??4000}={}){let t=this._sortedData("desc"),i=[],s=0;for(let n of t){let r=this._docTokens(n);if(s+r>e)break;i.push(n.text),s+=r}return i.reverse().join(`
82
+ ${e}`,options:{temperature:this.temperature,...this.topP!==void 0&&{top_p:this.topP},...this.topK!==void 0&&{top_k:this.topK}},stream:!1})).response.trim()}async _post(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify(e),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama API error ${r.status}: ${a}`)}return r.json()}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}function lc({provider:e,apiKey:t,embedModel:i,model:s,host:n,embedBaseUrl:r,dimensions:a,organization:l,embedTimeout:o,embedRetries:c,embedRetryDelay:h}){let u=i||s;switch(e){case"openai":return new Er({apiKey:t,model:u,baseUrl:r,...a!==void 0&&{dimensions:a},...l!==void 0&&{organization:l},...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});case"ollama":return new Sr({model:u,host:n,...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});default:throw new fe("ERR_SKALEX_ADAPTER_UNKNOWN_PROVIDER",`Unknown AI provider: "${e}". Supported: "openai", "ollama".`,{provider:e})}}function cc({provider:e,apiKey:t,model:i,host:s,baseUrl:n,apiVersion:r,temperature:a,maxTokens:l,topP:o,topK:c,organization:h,timeout:u,retries:d,retryDelay:_,seed:f,generatePrompt:p,summarizePrompt:m}){if(!i)return null;switch(e){case"openai":return new Ir({apiKey:t,model:i,baseUrl:n,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...h!==void 0&&{organization:h},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...f!==void 0&&{seed:f},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"anthropic":return new br({apiKey:t,model:i,baseUrl:n,apiVersion:r,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"ollama":return new Tr({model:i,host:s,...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});default:return null}}var fi="AES-GCM",mt=12,be=32,hc=new TextEncoder,dc=new TextDecoder;class Or extends Ki{constructor(e,t){super();if(this._adapter=e,this._rawKey=typeof t==="string"?uc(t):Uint8Array.from(t),this._rawKey.length!==be)throw new fe("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: key must be ${be} bytes (${be*2} hex chars), got ${this._rawKey.length}`);this._cryptoKey=null}async read(e){let t=await this._adapter.read(e);if(!t)return null;return this._decrypt(t)}async write(e,t){return this._adapter.write(e,await this._encrypt(t))}async delete(e){return this._adapter.delete(e)}async list(){return this._adapter.list()}async writeAll(e){let t=[];for(let{name:i,data:s}of e)t.push({name:i,data:await this._encrypt(s)});return this._adapter.writeAll(t)}join(...e){return this._adapter.join?.(...e)}ensureDir(e){return this._adapter.ensureDir?.(e)}async writeRaw(e,t){return this._adapter.writeRaw?.(e,await this._encrypt(t))}async readRaw(e){let t=await this._adapter.readRaw?.(e);if(!t)return null;return this._decrypt(t)}async _getKey(){if(!this._cryptoKey)this._cryptoKey=await globalThis.crypto.subtle.importKey("raw",this._rawKey,{name:fi},!1,["encrypt","decrypt"]);return this._cryptoKey}async _encrypt(e){let t=await this._getKey(),i=globalThis.crypto.getRandomValues(new Uint8Array(mt)),s=hc.encode(e),n=await globalThis.crypto.subtle.encrypt({name:fi,iv:i,tagLength:128},t,s),r=new Uint8Array(mt+n.byteLength);return r.set(i,0),r.set(new Uint8Array(n),mt),_c(r)}async _decrypt(e){let t=await this._getKey(),i=fc(e),s=i.slice(0,mt),n=i.slice(mt),r=await globalThis.crypto.subtle.decrypt({name:fi,iv:s,tagLength:128},t,n);return dc.decode(r)}}function uc(e){if(e.length!==be*2)throw new fe("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: hex key must be ${be*2} characters (${be} bytes)`);if(!/^[0-9a-fA-F]+$/.test(e))throw new fe("ERR_SKALEX_ADAPTER_INVALID_KEY","EncryptedAdapter: hex key contains invalid characters");let t=new Uint8Array(be);for(let i=0;i<be;i++)t[i]=parseInt(e.slice(i*2,i*2+2),16);return t}function _c(e){let t="";for(let i=0;i<e.length;i++)t+=String.fromCharCode(e[i]);return globalThis.btoa(t)}function fc(e){let t=globalThis.atob(e),i=new Uint8Array(t.length);for(let s=0;s<t.length;s++)i[s]=t.charCodeAt(s);return i}var pc=4;class Nr{constructor(e,t){this.sessionId=e,this._db=t,this._col=t.useCollection(`_memory_${e}`)}async remember(e){let t=await this._col.insertOne({text:e,sessionId:this.sessionId},{embed:"text"}),i=this._db._memoryConfig?.maxEntries;if(i&&this._col._data.length>i)await this.compress({threshold:0});return t}async recall(e,{limit:t=10,minScore:i=0}={}){return this._col.search(e,{limit:t,minScore:i})}async history({since:e,limit:t}={}){let i=e?{createdAt:{$gte:new Date(e)}}:{},s={sort:{createdAt:1}};if(t)s.limit=t;let{docs:n}=await this._col.find(i,s);return n}async forget(e){return this._col.deleteOne({_id:e})}tokenCount(){let e=this._col._data;return{tokens:e.reduce((t,i)=>t+this._docTokens(i),0),count:e.length}}context({tokens:e=this._db._memoryConfig?.contextTokens??4000}={}){let t=this._sortedData("desc"),i=[],s=0;for(let n of t){let r=this._docTokens(n);if(s+r>e)break;i.push(n.text),s+=r}return i.reverse().join(`
83
83
  `)}async compress({threshold:e=this._db._memoryConfig?.compressionThreshold??8000,keepRecent:t=this._db._memoryConfig?.keepRecent??10}={}){let{tokens:i}=this.tokenCount();if(i<=e)return;if(!this._db._aiAdapter)throw Error('memory.compress() requires a language model adapter. Configure { ai: { model: "..." } }.');let s=this._sortedData("asc"),n=Math.max(0,s.length-t),r=s.slice(0,n);if(r.length===0)return;let a=r.map((o)=>o.text).join(`
84
- `),l=await this._db._aiAdapter.summarize(a);await this._col.deleteMany({_id:{$in:r.map((o)=>o._id)}}),await this._col.insertOne({text:l,sessionId:this.sessionId,compressed:!0})}_docTokens(e){return Math.ceil((e.text||"").length/_c)}_sortedData(e){return[...this._col._data].sort(e==="asc"?(t,i)=>new Date(t.createdAt)-new Date(i.createdAt):(t,i)=>new Date(i.createdAt)-new Date(t.createdAt))}}class $r{constructor(e){this._db=e,this._restoring=!1}get _col(){return this._db.useCollection("_changelog")}async log(e,t,i,s=null,n=null){if(this._restoring)return;let r={op:e,collection:t,docId:i._id,doc:{...i},timestamp:new Date};if(s)r.prev={...s};if(n)r.session=n;await this._col.insertOne(r)}async query(e,{since:t,limit:i,session:s}={}){let n={collection:e};if(t)n.timestamp={$gte:new Date(t)};if(s)n.session=s;let r={sort:{timestamp:1}};if(i)r.limit=i;let{docs:a}=await this._col.find(n,r);return a}async restore(e,t,{_id:i}={}){let s=new Date(t),n=this._db.useCollection(e),r=(await this.query(e,{})).filter((l)=>new Date(l.timestamp)<=s);if(i){let l=r.filter((c)=>c.docId===i);if(l.length===0)return;let o=l[l.length-1];this._restoring=!0;try{if(o.op==="delete"){if(await n.findOne({_id:i}))await n.deleteOne({_id:i});return}if(await n.findOne({_id:i})){let{_id:c,createdAt:h,updatedAt:u,...d}=o.doc;await n.updateOne({_id:i},d)}else await n.insertOne({...o.doc})}finally{this._restoring=!1}await this._db.saveData(e);return}let a=new Map;for(let l of r)if(l.op==="insert"||l.op==="update")a.set(l.docId,{doc:l.doc,deleted:!1});else if(l.op==="delete")a.set(l.docId,{doc:null,deleted:!0});this._restoring=!0;try{await n.deleteMany({});for(let[,{doc:l,deleted:o}]of a)if(!o&&l)await n.insertOne({...l})}finally{this._restoring=!1}await this._db.saveData(e)}}function fc(e){let t=5381;for(let i=0;i<e.length;i++)t=(t<<5)+t+e.charCodeAt(i)|0;return(t>>>0).toString(16).padStart(8,"0")}class Dr{constructor({maxSize:e=500,ttl:t=0}={}){this._cache=new Map,this._maxSize=e,this._ttl=t}_key(e,t,i){return fc(JSON.stringify({collectionName:e,schema:t,query:i}))}get(e,t,i){let s=this._key(e,t,i),n=this._cache.get(s);if(!n)return;if(this._ttl>0&&Date.now()-n.ts>this._ttl){this._cache.delete(s);return}return n.filter}set(e,t,i,s){let n=this._key(e,t,i);if(this._cache.size>=this._maxSize&&!this._cache.has(n))this._cache.delete(this._cache.keys().next().value);this._cache.set(n,{filter:s,ts:Date.now()})}toJSON(){return Object.fromEntries([...this._cache.entries()].map(([e,t])=>[e,t]))}fromJSON(e){if(!e||typeof e!=="object")return;for(let[t,i]of Object.entries(e))this._cache.set(t,i)}get size(){return this._cache.size}}function pc(e,{regexMaxLength:t=500}={}){if(typeof e!=="object"||e===null)return e;let i={};for(let s of Object.keys(e)){let n=e[s];if(n&&typeof n==="object"&&!Array.isArray(n)){let r={};for(let a of Object.keys(n))if(a==="$regex"&&typeof n.$regex==="string"){if(n.$regex.length>t)throw Error(`$regex pattern too long (max ${t} characters)`);if(/\([^)]*[+*][^)]*\)[+*{]/.test(n.$regex))throw Error("$regex pattern rejected: nested quantifiers risk ReDoS");try{r.$regex=new RegExp(n.$regex)}catch{throw Error(`invalid $regex pattern: "${n.$regex}"`)}}else if(["$gt","$gte","$lt","$lte"].includes(a)&&mc(n[a]))r[a]=new Date(n[a]);else r[a]=n[a];i[s]=r}else i[s]=n}return i}function mc(e){if(typeof e!=="string")return!1;return/\d{4}-\d{2}-\d{2}/.test(e)&&!isNaN(Date.parse(e))}function gc(e,t){let i=[];if(!t||typeof e!=="object"||e===null)return i;for(let s of Object.keys(e)){if(s.startsWith("$"))continue;if(!(s.split(".")[0]in t))i.push(`Unknown field referenced in generated filter: "${s}"`)}return i}class Cr{constructor(){this._listeners=new Map}on(e,t){if(!this._listeners.has(e))this._listeners.set(e,new Set);return this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}emit(e,t){for(let i of[e,"*"]){let s=this._listeners.get(i);if(!s)continue;for(let n of s)try{n(t)}catch(r){}}}removeAll(e){if(e)this._listeners.delete(e);else this._listeners.clear()}listenerCount(e){return this._listeners.get(e)?.size??0}}class Rr{constructor({threshold:e=100,maxEntries:t=500}={}){this._threshold=e,this._maxEntries=t,this._entries=[]}record({collection:e,op:t,filter:i,query:s,duration:n,resultCount:r}){if(n<this._threshold)return;let a={collection:e,op:t,duration:n,resultCount:r,timestamp:new Date};if(i!==void 0)a.filter=i;if(s!==void 0)a.query=s;if(this._entries.push(a),this._entries.length>this._maxEntries)this._entries.shift()}entries({limit:e,minDuration:t,collection:i}={}){let s=this._entries;if(i)s=s.filter((n)=>n.collection===i);if(t)s=s.filter((n)=>n.duration>=t);if(e)s=s.slice(-e);return s}get size(){return this._entries.length}clear(){this._entries=[]}}class kr{constructor(){this._sessions=new Map}_ensure(e){if(!this._sessions.has(e))this._sessions.set(e,{reads:0,writes:0,lastActive:null});return this._sessions.get(e)}recordRead(e){if(!e)return;let t=this._ensure(e);t.reads++,t.lastActive=new Date}recordWrite(e){if(!e)return;let t=this._ensure(e);t.writes++,t.lastActive=new Date}get(e){let t=this._sessions.get(e);if(!t)return null;return{sessionId:e,...t}}all(){return[...this._sessions.entries()].map(([e,t])=>({sessionId:e,...t}))}clear(e){if(e)this._sessions.delete(e);else this._sessions.clear()}}class Lr{constructor(){this._plugins=[]}register(e){if(typeof e!=="object"||e===null)throw TypeError("Plugin must be a non-null object.");this._plugins.push(e)}async run(e,t){for(let i of this._plugins)if(typeof i[e]==="function")await i[e](t)}get size(){return this._plugins.length}}function Ye(e){if(typeof e!=="string"||!e.trim())throw Error("collection name must be a non-empty string");if(/[/\\]/.test(e)||e.includes("..")||e.includes("\x00"))throw Error(`invalid collection name: "${e}"`);if(e.trim().startsWith("_"))throw Error(`access to system collection "${e}" is not permitted`);return e.trim()}var Hs=[{name:"skalex_collections",description:"List all collection names in the database.",inputSchema:{type:"object",properties:{}},scope:"read"},{name:"skalex_schema",description:"Return the schema for a collection as a { field: type } map. Returns null if the collection is empty.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."}},required:["collection"]},scope:"read"},{name:"skalex_find",description:"Find documents in a collection that match a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter (MongoDB-style operators supported)."},limit:{type:"number",description:"Maximum number of results. Default: 20."},sort:{type:"object",description:"Sort descriptor: { field: 1 } for ascending, { field: -1 } for descending."}},required:["collection"]},scope:"read"},{name:"skalex_insert",description:"Insert a single document into a collection.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},doc:{type:"object",description:"Document to insert."}},required:["collection","doc"]},scope:"write"},{name:"skalex_update",description:"Update the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},update:{type:"object",description:"Fields to update (direct assignment, $inc, $push supported)."},many:{type:"boolean",description:"If true, update all matching documents. Default: false."}},required:["collection","filter","update"]},scope:"write"},{name:"skalex_delete",description:"Delete the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},many:{type:"boolean",description:"If true, delete all matching documents. Default: false."}},required:["collection","filter"]},scope:"write"},{name:"skalex_search",description:"Semantic similarity search. Requires an embedding adapter to be configured.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},query:{type:"string",description:"Natural-language query string to embed and compare."},limit:{type:"number",description:"Maximum number of results. Default: 10."},minScore:{type:"number",description:"Minimum cosine similarity score [0, 1]. Default: 0."},filter:{type:"object",description:"Optional structured pre-filter (hybrid search)."}},required:["collection","query"]},scope:"read"},{name:"skalex_ask",description:"Translate a natural-language question into a filter and query a collection. Requires a language model adapter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},question:{type:"string",description:"Natural-language question about the data."},limit:{type:"number",description:"Maximum number of results. Default: 20."}},required:["collection","question"]},scope:"read"}];async function yc(e,t,i){switch(e){case"skalex_collections":return Object.keys(i.collections).filter((s)=>!s.startsWith("_"));case"skalex_schema":return i.schema(Ye(t.collection))??null;case"skalex_find":{let s=i.useCollection(Ye(t.collection)),n={};if(t.limit)n.limit=t.limit;if(t.sort)n.sort=t.sort;return s.find(t.filter||{},n)}case"skalex_insert":return i.useCollection(Ye(t.collection)).insertOne(t.doc||{});case"skalex_update":{let s=i.useCollection(Ye(t.collection));if(t.many)return s.updateMany(t.filter||{},t.update||{});return s.updateOne(t.filter||{},t.update||{})}case"skalex_delete":{let s=i.useCollection(Ye(t.collection));if(t.many)return s.deleteMany(t.filter||{});return s.deleteOne(t.filter||{})}case"skalex_search":return i.useCollection(Ye(t.collection)).search(t.query,{limit:t.limit??10,minScore:t.minScore??0,filter:t.filter});case"skalex_ask":return i.ask(Ye(t.collection),t.question,{limit:t.limit??20});default:throw Object.assign(Error(`Unknown tool: ${e}`),{code:"NOT_FOUND"})}}var Bi="2.0",Xi=-32700,wc=-32600,Vs=-32601,Ac=-32602,xc=-32603;function at(e,t){return{jsonrpc:Bi,id:e,result:t}}function De(e,t,i,s){return{jsonrpc:Bi,id:e,error:{code:t,message:i}}}function vc(e){try{let t=JSON.parse(e);if(typeof t!=="object"||t===null||t.jsonrpc!==Bi)return{parseError:De(null,wc,"Invalid JSON-RPC request")};return{msg:t}}catch(t){return{parseError:De(null,Xi,"Parse error")}}}function Ec(e){return{content:[{type:"text",text:e}]}}function Js(e){return{content:[{type:"text",text:e}],isError:!0}}class Pr{constructor({port:e=3000,host:t="127.0.0.1",allowedOrigin:i=null,maxBodySize:s=1048576}={}){this._port=e,this._host=t,this._allowedOrigin=i,this._maxBodySize=s,this._clients=new Set,this._onMessage=null,this._server=null}onMessage(e){this._onMessage=e}send(e){let t=`data: ${JSON.stringify(e)}
84
+ `),l=await this._db._aiAdapter.summarize(a);await this._col.deleteMany({_id:{$in:r.map((o)=>o._id)}}),await this._col.insertOne({text:l,sessionId:this.sessionId,compressed:!0})}_docTokens(e){return Math.ceil((e.text||"").length/pc)}_sortedData(e){return[...this._col._data].sort(e==="asc"?(t,i)=>new Date(t.createdAt)-new Date(i.createdAt):(t,i)=>new Date(i.createdAt)-new Date(t.createdAt))}}class $r{constructor(e){this._db=e,this._restoring=!1}get _col(){return this._db.useCollection("_changelog")}async log(e,t,i,s=null,n=null){if(this._restoring)return;let r={op:e,collection:t,docId:i._id,doc:{...i},timestamp:new Date};if(s)r.prev={...s};if(n)r.session=n;await this._col.insertOne(r)}async query(e,{since:t,limit:i,session:s}={}){let n={collection:e};if(t)n.timestamp={$gte:new Date(t)};if(s)n.session=s;let r={sort:{timestamp:1}};if(i)r.limit=i;let{docs:a}=await this._col.find(n,r);return a}async restore(e,t,{_id:i}={}){let s=new Date(t),n=this._db.useCollection(e),r=(await this.query(e,{})).filter((l)=>new Date(l.timestamp)<=s);if(i){let l=r.filter((c)=>c.docId===i);if(l.length===0)return;let o=l[l.length-1];this._restoring=!0;try{if(o.op==="delete"){if(await n.findOne({_id:i}))await n.deleteOne({_id:i});return}if(await n.findOne({_id:i})){let{_id:c,createdAt:h,updatedAt:u,...d}=o.doc;await n.updateOne({_id:i},d)}else await n.insertOne({...o.doc})}finally{this._restoring=!1}await this._db.saveData(e);return}let a=new Map;for(let l of r)if(l.op==="insert"||l.op==="update")a.set(l.docId,{doc:l.doc,deleted:!1});else if(l.op==="delete")a.set(l.docId,{doc:null,deleted:!0});this._restoring=!0;try{await n.deleteMany({});for(let[,{doc:l,deleted:o}]of a)if(!o&&l)await n.insertOne({...l})}finally{this._restoring=!1}await this._db.saveData(e)}}function mc(e){let t=5381;for(let i=0;i<e.length;i++)t=(t<<5)+t+e.charCodeAt(i)|0;return(t>>>0).toString(16).padStart(8,"0")}class Dr{constructor({maxSize:e=500,ttl:t=0}={}){this._cache=new Map,this._maxSize=e,this._ttl=t}_key(e,t,i){return mc(JSON.stringify({collectionName:e,schema:t,query:i}))}get(e,t,i){let s=this._key(e,t,i),n=this._cache.get(s);if(!n)return;if(this._ttl>0&&Date.now()-n.ts>this._ttl){this._cache.delete(s);return}return n.filter}set(e,t,i,s){let n=this._key(e,t,i);if(this._cache.size>=this._maxSize&&!this._cache.has(n))this._cache.delete(this._cache.keys().next().value);this._cache.set(n,{filter:s,ts:Date.now()})}toJSON(){return Object.fromEntries([...this._cache.entries()].map(([e,t])=>[e,t]))}fromJSON(e){if(!e||typeof e!=="object")return;for(let[t,i]of Object.entries(e))this._cache.set(t,i)}get size(){return this._cache.size}}function gc(e,{regexMaxLength:t=500}={}){if(typeof e!=="object"||e===null)return e;let i={};for(let s of Object.keys(e)){let n=e[s];if(n&&typeof n==="object"&&!Array.isArray(n)){let r={};for(let a of Object.keys(n))if(a==="$regex"&&typeof n.$regex==="string"){if(n.$regex.length>t)throw Error(`$regex pattern too long (max ${t} characters)`);if(/\([^)]*[+*][^)]*\)[+*{]/.test(n.$regex))throw Error("$regex pattern rejected: nested quantifiers risk ReDoS");try{r.$regex=new RegExp(n.$regex)}catch{throw Error(`invalid $regex pattern: "${n.$regex}"`)}}else if(["$gt","$gte","$lt","$lte"].includes(a)&&yc(n[a]))r[a]=new Date(n[a]);else r[a]=n[a];i[s]=r}else i[s]=n}return i}function yc(e){if(typeof e!=="string")return!1;return/\d{4}-\d{2}-\d{2}/.test(e)&&!isNaN(Date.parse(e))}function wc(e,t){let i=[];if(!t||typeof e!=="object"||e===null)return i;for(let s of Object.keys(e)){if(s.startsWith("$"))continue;if(!(s.split(".")[0]in t))i.push(`Unknown field referenced in generated filter: "${s}"`)}return i}class Cr{constructor(){this._listeners=new Map}on(e,t){if(!this._listeners.has(e))this._listeners.set(e,new Set);return this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}emit(e,t){for(let i of[e,"*"]){let s=this._listeners.get(i);if(!s)continue;for(let n of s)try{n(t)}catch(r){}}}removeAll(e){if(e)this._listeners.delete(e);else this._listeners.clear()}listenerCount(e){return this._listeners.get(e)?.size??0}}class Rr{constructor({threshold:e=100,maxEntries:t=500}={}){this._threshold=e,this._maxEntries=t,this._entries=[]}record({collection:e,op:t,filter:i,query:s,duration:n,resultCount:r}){if(n<this._threshold)return;let a={collection:e,op:t,duration:n,resultCount:r,timestamp:new Date};if(i!==void 0)a.filter=i;if(s!==void 0)a.query=s;if(this._entries.push(a),this._entries.length>this._maxEntries)this._entries.shift()}entries({limit:e,minDuration:t,collection:i}={}){let s=this._entries;if(i)s=s.filter((n)=>n.collection===i);if(t)s=s.filter((n)=>n.duration>=t);if(e)s=s.slice(-e);return s}get size(){return this._entries.length}clear(){this._entries=[]}}class kr{constructor(){this._sessions=new Map}_ensure(e){if(!this._sessions.has(e))this._sessions.set(e,{reads:0,writes:0,lastActive:null});return this._sessions.get(e)}recordRead(e){if(!e)return;let t=this._ensure(e);t.reads++,t.lastActive=new Date}recordWrite(e){if(!e)return;let t=this._ensure(e);t.writes++,t.lastActive=new Date}get(e){let t=this._sessions.get(e);if(!t)return null;return{sessionId:e,...t}}all(){return[...this._sessions.entries()].map(([e,t])=>({sessionId:e,...t}))}clear(e){if(e)this._sessions.delete(e);else this._sessions.clear()}}class Lr{constructor(){this._plugins=[]}register(e){if(typeof e!=="object"||e===null)throw TypeError("Plugin must be a non-null object.");this._plugins.push(e)}async run(e,t){for(let i of this._plugins)if(typeof i[e]==="function")await i[e](t)}get size(){return this._plugins.length}}function Ye(e){if(typeof e!=="string"||!e.trim())throw Error("collection name must be a non-empty string");if(/[/\\]/.test(e)||e.includes("..")||e.includes("\x00"))throw Error(`invalid collection name: "${e}"`);if(e.trim().startsWith("_"))throw Error(`access to system collection "${e}" is not permitted`);return e.trim()}var Hs=[{name:"skalex_collections",description:"List all collection names in the database.",inputSchema:{type:"object",properties:{}},scope:"read"},{name:"skalex_schema",description:"Return the schema for a collection as a { field: type } map. Returns null if the collection is empty.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."}},required:["collection"]},scope:"read"},{name:"skalex_find",description:"Find documents in a collection that match a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter (MongoDB-style operators supported)."},limit:{type:"number",description:"Maximum number of results. Default: 20."},sort:{type:"object",description:"Sort descriptor: { field: 1 } for ascending, { field: -1 } for descending."}},required:["collection"]},scope:"read"},{name:"skalex_insert",description:"Insert a single document into a collection.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},doc:{type:"object",description:"Document to insert."}},required:["collection","doc"]},scope:"write"},{name:"skalex_update",description:"Update the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},update:{type:"object",description:"Fields to update (direct assignment, $inc, $push supported)."},many:{type:"boolean",description:"If true, update all matching documents. Default: false."}},required:["collection","filter","update"]},scope:"write"},{name:"skalex_delete",description:"Delete the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},many:{type:"boolean",description:"If true, delete all matching documents. Default: false."}},required:["collection","filter"]},scope:"write"},{name:"skalex_search",description:"Semantic similarity search. Requires an embedding adapter to be configured.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},query:{type:"string",description:"Natural-language query string to embed and compare."},limit:{type:"number",description:"Maximum number of results. Default: 10."},minScore:{type:"number",description:"Minimum cosine similarity score [0, 1]. Default: 0."},filter:{type:"object",description:"Optional structured pre-filter (hybrid search)."}},required:["collection","query"]},scope:"read"},{name:"skalex_ask",description:"Translate a natural-language question into a filter and query a collection. Requires a language model adapter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},question:{type:"string",description:"Natural-language question about the data."},limit:{type:"number",description:"Maximum number of results. Default: 20."}},required:["collection","question"]},scope:"read"}];async function Ac(e,t,i){switch(e){case"skalex_collections":return Object.keys(i.collections).filter((s)=>!s.startsWith("_"));case"skalex_schema":return i.schema(Ye(t.collection))??null;case"skalex_find":{let s=i.useCollection(Ye(t.collection)),n={};if(t.limit)n.limit=t.limit;if(t.sort)n.sort=t.sort;return s.find(t.filter||{},n)}case"skalex_insert":return i.useCollection(Ye(t.collection)).insertOne(t.doc||{});case"skalex_update":{let s=i.useCollection(Ye(t.collection));if(t.many)return s.updateMany(t.filter||{},t.update||{});return s.updateOne(t.filter||{},t.update||{})}case"skalex_delete":{let s=i.useCollection(Ye(t.collection));if(t.many)return s.deleteMany(t.filter||{});return s.deleteOne(t.filter||{})}case"skalex_search":return i.useCollection(Ye(t.collection)).search(t.query,{limit:t.limit??10,minScore:t.minScore??0,filter:t.filter});case"skalex_ask":return i.ask(Ye(t.collection),t.question,{limit:t.limit??20});default:throw Object.assign(Error(`Unknown tool: ${e}`),{code:"NOT_FOUND"})}}var Bi="2.0",Xi=-32700,xc=-32600,Vs=-32601,vc=-32602,Ec=-32603;function at(e,t){return{jsonrpc:Bi,id:e,result:t}}function De(e,t,i,s){return{jsonrpc:Bi,id:e,error:{code:t,message:i}}}function Sc(e){try{let t=JSON.parse(e);if(typeof t!=="object"||t===null||t.jsonrpc!==Bi)return{parseError:De(null,xc,"Invalid JSON-RPC request")};return{msg:t}}catch(t){return{parseError:De(null,Xi,"Parse error")}}}function Ic(e){return{content:[{type:"text",text:e}]}}function Js(e){return{content:[{type:"text",text:e}],isError:!0}}class Pr{constructor({port:e=3000,host:t="127.0.0.1",allowedOrigin:i=null,maxBodySize:s=1048576}={}){this._port=e,this._host=t,this._allowedOrigin=i,this._maxBodySize=s,this._clients=new Set,this._onMessage=null,this._server=null}onMessage(e){this._onMessage=e}send(e){let t=`data: ${JSON.stringify(e)}
85
85
 
86
- `;for(let i of this._clients)try{i.write(t)}catch(s){this._clients.delete(i)}}start(){return new Promise((e,t)=>{this._server=Oo.createServer((i,s)=>{if(this._allowedOrigin)s.setHeader("Access-Control-Allow-Origin",this._allowedOrigin),s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type");if(i.method==="OPTIONS"){s.writeHead(204),s.end();return}if(i.method==="GET"&&i.url==="/sse")this._handleSSE(i,s);else if(i.method==="POST"&&i.url==="/message")this._handleMessage(i,s);else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not Found")}),this._server.on("error",t),this._server.listen(this._port,this._host,()=>e())})}stop(){return new Promise((e)=>{if(!this._server){e();return}for(let t of this._clients)try{t.end()}catch(i){}this._clients.clear(),this._server.close(()=>e()),this._server=null})}_handleSSE(e,t){t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),t.write(`event: endpoint
86
+ `;for(let i of this._clients)try{i.write(t)}catch(s){this._clients.delete(i)}}start(){return new Promise((e,t)=>{this._server=$o.createServer((i,s)=>{if(this._allowedOrigin)s.setHeader("Access-Control-Allow-Origin",this._allowedOrigin),s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type");if(i.method==="OPTIONS"){s.writeHead(204),s.end();return}if(i.method==="GET"&&i.url==="/sse")this._handleSSE(i,s);else if(i.method==="POST"&&i.url==="/message")this._handleMessage(i,s);else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not Found")}),this._server.on("error",t),this._server.listen(this._port,this._host,()=>e())})}stop(){return new Promise((e)=>{if(!this._server){e();return}for(let t of this._clients)try{t.end()}catch(i){}this._clients.clear(),this._server.close(()=>e()),this._server=null})}_handleSSE(e,t){t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),t.write(`event: endpoint
87
87
  data: /message
88
88
 
89
89
  `),this._clients.add(t),e.on("close",()=>{this._clients.delete(t)})}async _handleMessage(e,t){let i="";e.setEncoding("utf8"),e.on("data",(s)=>{if(i+=s,i.length>this._maxBodySize)e.destroy(),t.writeHead(413,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"Request body too large"}))}),e.on("end",async()=>{t.writeHead(202,{"Content-Type":"application/json"}),t.end("{}");let s;try{s=JSON.parse(i)}catch(n){this.send(De(null,Xi,"Parse error"));return}if(this._onMessage)await this._onMessage(s).catch(()=>{})})}get port(){return this._port}get host(){return this._host}get url(){return`http://${this._host}:${this._port}`}get sseUrl(){return`${this.url}/sse`}}class Mr{constructor(){this._onMessage=null,this._buffer="",this._started=!1}onMessage(e){this._onMessage=e}send(e){process.stdout.write(JSON.stringify(e)+`
90
90
  `)}start(){if(this._started)return;this._started=!0,process.stdin.setEncoding("utf8"),process.stdin.on("data",(e)=>{this._buffer+=e;let t;while((t=this._buffer.indexOf(`
91
- `))!==-1){let i=this._buffer.slice(0,t).trim();if(this._buffer=this._buffer.slice(t+1),i&&this._onMessage){let s;try{s=JSON.parse(i)}catch(n){this.send(De(null,Xi,"Parse error"));continue}this._onMessage(s).catch(()=>{})}}}),process.stdin.on("end",()=>{process.exit(0)})}stop(){process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),this._started=!1}}var Sc={name:"skalex",version:"4.0.0-alpha"},Ic="2024-11-05";class jr{constructor(e,t={}){this._db=e,this._transport=t.transport||"stdio",this._port=t.port||3000,this._host=t.host||"127.0.0.1",this._allowedOrigin=t.allowedOrigin??null,this._maxBodySize=t.maxBodySize??1048576,this._scopes=t.scopes||{"*":["read"]},this._t=null}async listen(){if(this._transport==="http")this._t=new Pr({port:this._port,host:this._host,allowedOrigin:this._allowedOrigin,maxBodySize:this._maxBodySize});else this._t=new Mr;this._t.onMessage((e)=>this._handleMessage(e)),await this._t.start()}async connect(e){if(this._t=e,this._t.onMessage((t)=>this._handleMessage(t)),typeof this._t.start==="function")await this._t.start()}async close(){if(this._t&&typeof this._t.stop==="function")await this._t.stop();this._t=null}get transport(){return this._transport}get url(){return this._t?.url}async _handleMessage(e){let{msg:t,parseError:i}=typeof e==="string"?vc(e):{msg:e};if(i){this._send(i);return}let{id:s,method:n,params:r}=t;if(s===void 0){if(n==="notifications/initialized")return;return}try{switch(n){case"initialize":this._send(at(s,{protocolVersion:Ic,capabilities:{tools:{}},serverInfo:Sc}));break;case"tools/list":this._send(at(s,{tools:this._visibleTools()}));break;case"tools/call":await this._handleToolCall(s,r);break;case"ping":this._send(at(s,{}));break;default:this._send(De(s,Vs,`Method not found: ${n}`))}}catch(a){this._send(De(s,xc,a.message||"Internal error"))}}async _handleToolCall(e,t){let i=t?.name,s=t?.arguments??{};if(!i){this._send(De(e,Ac,"tools/call requires params.name"));return}let n=Hs.find((a)=>a.name===i);if(!n){this._send(De(e,Vs,`Unknown tool: ${i}`));return}let r=s.collection||s.collection_name||null;if(!this._hasScope(r,n.scope)){this._send(at(e,Js(`Access denied: "${i}" requires "${n.scope}" scope on collection "${r}".`)));return}try{let a=await yc(i,s,this._db);this._send(at(e,Ec(JSON.stringify(a,null,2))))}catch(a){this._send(at(e,Js(a.message||String(a))))}}_visibleTools(){return Hs.filter((e)=>{let t=this._scopes["*"];if(t&&(t.includes(e.scope)||t.includes("admin")))return!0;for(let[,i]of Object.entries(this._scopes))if(i.includes(e.scope)||i.includes("admin"))return!0;return!1})}_hasScope(e,t){let i=(s)=>s.includes("admin")||s.includes(t);if(e&&this._scopes[e])return i(this._scopes[e]);if(this._scopes["*"])return i(this._scopes["*"]);return!1}_send(e){this._t?.send(e)}}var Ot="migrations",Ys=(e)=>JSON.stringify(e,function(t,i){let s=this[t];if(s instanceof Date)return{__skalex_date__:s.toISOString()};if(typeof i==="bigint")return{__skalex_bigint__:i.toString()};return i}),Ws=(e)=>JSON.parse(e,(t,i)=>{if(i&&typeof i==="object"){if("__skalex_bigint__"in i)return BigInt(i.__skalex_bigint__);if("__skalex_date__"in i)return new Date(i.__skalex_date__)}return i});class ie{constructor({path:e="./.db",format:t="gz",debug:i=!1,adapter:s,ai:n,encrypt:r,slowQueryLog:a,queryCache:l,memory:o,logger:c,plugins:h,llmAdapter:u,embeddingAdapter:d,regexMaxLength:_,idGenerator:f,serializer:p,deserializer:m,autoSave:w,ttlSweepInterval:x,lenientLoad:R}={}){if(this.dataDirectory=e,this.dataFormat=t,this.debug=i,!ie._errorsAttached)ie.SkalexError=qe,ie.ValidationError=D,ie.UniqueConstraintError=Ie,ie.TransactionError=ye,ie.PersistenceError=Le,ie.AdapterError=fe,ie.QueryError=Ze,ie._errorsAttached=!0;this._adapterConfig=s??null;let E=s||new yr({dir:e,format:t});if(r)E=new Or(E,r.key);if(this.fs=E,this._registry=new vr(gr),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._migrations=new wr,this._connectPromise=null,this.isConnected=!1,this._aiConfig=n||null,this._encryptConfig=r||null,this._pluginsConfig=Array.isArray(h)?h:null,this._memoryConfig=o||null,this._regexMaxLength=_??500,this._idGenerator=f??null,this._serializer=p??Ys,this._deserializer=m??Ws,this._autoSave=w??!1,this._txManager=new xr,this._ttlSweepInterval=x??0,this._ttlTimer=null,this._logger=c??qs,this._embeddingAdapter=d??(n?ac(n):null),this._aiAdapter=u??(n?oc(n):null),this._persistence=new Ar({adapter:this.fs,serializer:this._serializer,deserializer:this._deserializer,logger:this._logger,debug:this.debug,lenientLoad:R??!1}),this._changeLog=new $r(this),this._queryCache=new Dr(l||{}),this._eventBus=new Cr,this._queryLog=a?new Rr(a):null,this._sessionStats=new kr,this._plugins=new Lr,Array.isArray(h))for(let A of h)this._plugins.register(A)}async connect(){if(this._connectPromise)return this._connectPromise;return this._connectPromise=this._doConnect(),this._connectPromise}async _doConnect(){try{await this.loadData();let e=this._getMeta();if(e.queryCache)this._queryCache.fromJSON(e.queryCache);if(this._migrations._migrations.length>0){let t=e.appliedVersions||[],i=await this._migrations.run((s)=>this.useCollection(`_migration_${s}`),t);this._saveMeta({appliedVersions:i})}if(this._sweepTtl(),this._ttlSweepInterval>0){if(this._ttlTimer=setInterval(()=>this._sweepTtl(),this._ttlSweepInterval),this._ttlTimer?.unref)this._ttlTimer.unref()}this.isConnected=!0,this._log("> - Connected to the database (\u221A)")}catch(e){throw this._logger(`Error connecting to the database: ${e}`,"error"),e}}async disconnect(){try{if(this._ttlTimer)clearInterval(this._ttlTimer),this._ttlTimer=null;await this.saveData(),this._registry.clear(),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._connectPromise=null,this.isConnected=!1,this._log("> - Disconnected from the database (\u221A)")}catch(e){throw this._logger(`Error disconnecting from the database: ${e}`,"error"),e}}async _ensureConnected(){if(this.isConnected)return;return this.connect()}useCollection(e){return this._registry.get(e,this)}createCollection(e,t={}){return this._registry.create(e,t,this)}_createCollectionStore(e,t={}){this._registry.createStore(e,t)}async renameCollection(e,t){this._registry.rename(e,t),await this.saveData(t),await this.fs.delete(e)}async loadData(){await this._persistence.loadAll(this.collections,{parseSchema:_r,buildIndex:this._registry.buildIndex,IndexEngine:kt});for(let e in this._collectionInstances){let t=this.collections[e];if(t&&this._collectionInstances[e]._store!==t)this._collectionInstances[e]._store=t}}async saveData(e){await this._persistence.save(this.collections,e)}buildIndex(e,t){return this._registry.buildIndex(e,t)}addMigration(e){this._migrations.add(e)}migrationStatus(){let e=this._getMeta();return this._migrations.status(e.appliedVersions||[])}namespace(e){if(this._adapterConfig)throw new fe("ERR_SKALEX_ADAPTER_NAMESPACE_REQUIRES_FS","namespace() requires the default FsAdapter. When a custom storage adapter is configured, create a separate Skalex instance with your adapter instead.");let t=String(e).replace(/[^a-zA-Z0-9_-]/g,"_");if(!t)throw new D("ERR_SKALEX_VALIDATION_NAMESPACE_ID","namespace: id must contain at least one alphanumeric character",{id:e});return new ie({path:`${this.dataDirectory}/${t}`,format:this.dataFormat,debug:this.debug,ai:this._aiConfig||void 0,encrypt:this._encryptConfig||void 0,slowQueryLog:this._queryLog?{threshold:this._queryLog._threshold,maxEntries:this._queryLog._maxEntries}:void 0,queryCache:this._queryCache?{maxSize:this._queryCache._maxSize,ttl:this._queryCache._ttl}:void 0,plugins:this._pluginsConfig||void 0,memory:this._memoryConfig||void 0,logger:this._logger!==qs?this._logger:void 0,llmAdapter:this._aiAdapter&&!this._aiConfig?this._aiAdapter:void 0,embeddingAdapter:this._embeddingAdapter&&!this._aiConfig?this._embeddingAdapter:void 0,regexMaxLength:this._regexMaxLength!==500?this._regexMaxLength:void 0,idGenerator:this._idGenerator||void 0,serializer:this._serializer!==Ys?this._serializer:void 0,deserializer:this._deserializer!==Ws?this._deserializer:void 0,autoSave:this._autoSave||void 0,ttlSweepInterval:this._ttlSweepInterval||void 0})}use(e){this._plugins.register(e)}watch(e){return this._eventBus.on("*",e)}sessionStats(e){if(e!==void 0)return this._sessionStats.get(e);return this._sessionStats.all()}get _inTransaction(){return this._txManager.active}_emitEvent(e,t){if(!this._txManager.defer(()=>this._eventBus.emit(e,t)))this._eventBus.emit(e,t)}async _runAfterHook(e,t){if(!this._txManager.defer(()=>this._plugins.run(e,t)))await this._plugins.run(e,t)}async _logChange(e,t,i,s,n){if(!this._txManager.defer(()=>this._changeLog.log(e,t,i,s,n)))await this._changeLog.log(e,t,i,s,n)}async transaction(e,t={}){return this._txManager.run(e,this,t)}async seed(e,{reset:t=!1}={}){for(let[i,s]of Object.entries(e)){if(t&&this.collections[i])this._applySnapshot(i,{data:[],index:new Map}),delete this._collectionInstances[i];await this.useCollection(i).insertMany(s)}await this.saveData()}dump(){return this._registry.dump()}inspect(e){return this._registry.inspect(e)}async import(e){let t=await this.fs.readRaw(e),i;try{i=JSON.parse(t)}catch{throw new Le("ERR_SKALEX_PERSISTENCE_INVALID_JSON",`import: invalid JSON in file "${e}"`,{filePath:e})}let s=e.split("/").pop().replace(/\.[^.]+$/,"");return this.useCollection(s).insertMany(Array.isArray(i)?i:[i],{save:!0})}async embed(e){if(!this._embeddingAdapter)throw new fe("ERR_SKALEX_ADAPTER_EMBEDDING_REQUIRED","db.embed() requires an AI adapter. Pass { ai: { provider, apiKey } } to the Skalex constructor.");return this._embeddingAdapter.embed(e)}async ask(e,t,{limit:i=20}={}){if(!this._aiAdapter)throw new fe("ERR_SKALEX_ADAPTER_LLM_REQUIRED",'db.ask() requires a language model adapter. Configure { ai: { provider, model: "..." } }.');let s=this.useCollection(e),n=this.schema(e),r=this._queryCache.get(e,n,t);if(!r){r=await this._aiAdapter.generate(n,t);let a=gc(r,n);if(a.length)a.forEach((l)=>this._log(`[ask] ${l}`));this._queryCache.set(e,n,t,r),this._saveMeta({queryCache:this._queryCache.toJSON()})}return s.find(pc(r,{regexMaxLength:this._regexMaxLength}),{limit:i})}schema(e){return this._registry.schema(e)}useMemory(e){return new Nr(e,this)}changelog(){return this._changeLog}async restore(e,t,i={}){return this._changeLog.restore(e,t,i)}stats(e){return this._registry.stats(e)}slowQueries(e={}){if(!this._queryLog)return[];return this._queryLog.entries(e)}slowQueryCount(){return this._queryLog?this._queryLog.size:0}clearSlowQueries(){this._queryLog?.clear()}mcp(e={}){return new jr(this,e)}_getMeta(){let e=this.collections._meta;if(!e)return{};return e.index.get(Ot)||{}}_saveMeta(e){if(!this.collections._meta)this._createCollectionStore("_meta");let t=this.collections._meta,i=t.index.get(Ot);if(i)Object.assign(i,e);else{let s={_id:Ot,...e};t.data.push(s),t.index.set(Ot,s)}this._persistence.markDirty(this.collections,"_meta")}_sweepTtl(){for(let e in this.collections){let t=this.collections[e],i=Zl(t.data,t.index,t.fieldIndex?(s)=>t.fieldIndex.remove(s):null);if(i>0)this._persistence.markDirty(this.collections,e),this._log(`TTL sweep: removed ${i} expired docs from "${e}"`)}}_buildCollectionContext(){let e=this;return{ensureConnected:()=>e._ensureConnected(),get txManager(){return e._txManager},get plugins(){return e._plugins},get eventBus(){return e._eventBus},get sessionStats(){return e._sessionStats},get queryLog(){return e._queryLog},get logger(){return e._logger},get persistence(){return e._persistence},get collections(){return e.collections},embed:(t)=>e.embed(t),get idGenerator(){return e._idGenerator},get autoSave(){return e._autoSave},saveCollection:(t)=>e.saveData(t),snapshotCollection:(t)=>e._snapshotCollection(t),getCollection:(t)=>e.useCollection(t),emitEvent:(t,i)=>e._emitEvent(t,i),runAfterHook:(t,i)=>e._runAfterHook(t,i),logChange:(t,i,s,n,r)=>e._logChange(t,i,s,n,r),get fs(){return e.fs},get dataDirectory(){return e.dataDirectory}}}_log(e){if(this.debug)this._logger(e,"info")}_snapshotCollection(e){return{data:structuredClone(e.data)}}_applySnapshot(e,t){let i=this.collections[e];if(!i)return;if(i.data=t.data,i.index=this.buildIndex(t.data,"_id"),i.fieldIndex)i.fieldIndex.buildFromData(t.data)}}function bc(){let e=Date.now().toString(16),t;try{t=Po.randomBytes(8).toString("hex")}catch{let i=new Uint8Array(8);crypto.getRandomValues(i),t=Array.from(i).map((s)=>s.toString(16).padStart(2,"0")).join("")}return`${e}${t}`}function Qs(e,t){let i=e instanceof Error?e.message:e;if(t==="error")console.error(i);else console.log(i)}var Gs=new Set(["__proto__","constructor","prototype"]);function Ut(e,t){if(!t.includes(".")){if(Gs.has(t))return;return e[t]}let i=e;for(let s of t.split(".")){if(Gs.has(s))return;if(i==null)return;i=i[s]}return i}class Ke extends Error{constructor(e,t,i={}){super(t);this.name=this.constructor.name,this.code=e,this.details=i}}class C extends Ke{}class Te extends Ke{}class we extends Ke{}class Pe extends Ke{}class pe extends Ke{}class et extends Ke{}function Ei(e,t){if(e===t)return!0;if(e==null||t==null)return!1;if(typeof e!==typeof t)return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.source===t.source&&e.flags===t.flags;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!Ei(e[i],t[i]))return!1;return!0}if(typeof e==="object"){if(Array.isArray(t))return!1;let i=Object.keys(e);if(i.length!==Object.keys(t).length)return!1;for(let s of i){if(!Object.prototype.hasOwnProperty.call(t,s))return!1;if(!Ei(e[s],t[s]))return!1}return!0}return!1}function Y(e,t){if(typeof t==="function")return t(e);if(t==null)return!0;if(typeof t==="object"&&Object.keys(t).length===0)return!0;if("$or"in t){let i=t.$or;if(!Array.isArray(i))throw new et("ERR_SKALEX_QUERY_INVALID_OPERATOR","$or must be an array of filters",{operator:"$or"});if(!i.some((s)=>Y(e,s)))return!1}if("$and"in t){let i=t.$and;if(!Array.isArray(i))throw new et("ERR_SKALEX_QUERY_INVALID_OPERATOR","$and must be an array of filters",{operator:"$and"});if(!i.every((s)=>Y(e,s)))return!1}if("$not"in t){if(Y(e,t.$not))return!1}for(let i in t){if(i==="$or"||i==="$and"||i==="$not")continue;let s=t[i],n;try{n=Ut(e,i)}catch{return!1}if(s instanceof RegExp){if(!s.test(String(n)))return!1}else if(typeof s==="object"&&s!==null){if(Object.keys(s).some((r)=>r.startsWith("$"))){if("$eq"in s&&n!==s.$eq)return!1;if("$ne"in s&&n===s.$ne)return!1;if("$gt"in s&&!(n>s.$gt))return!1;if("$lt"in s&&!(n<s.$lt))return!1;if("$gte"in s&&!(n>=s.$gte))return!1;if("$lte"in s&&!(n<=s.$lte))return!1;if("$in"in s&&!s.$in.includes(n))return!1;if("$nin"in s&&s.$nin.includes(n))return!1;if("$regex"in s){if(!(s.$regex instanceof RegExp?s.$regex:new RegExp(s.$regex)).test(String(n)))return!1}if("$fn"in s&&!s.$fn(n))return!1}else if(!Ei(n,s))return!1}else if(n!==s)return!1}return!0}function Tc(e,t=new Set){if(typeof e!=="object"||e===null||typeof e==="function")return e;let i=[],s=[],n=[],r=[],a=[];for(let o in e){if(o==="$or"||o==="$and"||o==="$not"){a.push(o);continue}let c=e[o];if(t.has(o))i.push(o);else if(c instanceof RegExp||typeof c==="object"&&c!==null&&(("$regex"in c)||("$fn"in c))||typeof c==="function")r.push(o);else if(typeof c==="object"&&c!==null&&(("$gt"in c)||("$lt"in c)||("$gte"in c)||("$lte"in c)||("$ne"in c)||("$in"in c)||("$nin"in c)))n.push(o);else s.push(o)}let l={};for(let o of[...i,...s,...n,...r,...a])l[o]=e[o];return l}var Si=new Set(["string","number","boolean","object","array","date","any"]);function Hi(e){if(Array.isArray(e))return"array";if(e instanceof Date)return"date";return typeof e}function qr(e){let t=new Map,i=[];for(let[s,n]of Object.entries(e)){let r;if(typeof n==="string"){if(!Si.has(n))throw new C("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${n}" for field "${s}"`,{field:s,type:n});r={type:n,required:!1,unique:!1}}else if(typeof n==="object"&&n!==null){let{type:a="any",required:l=!1,unique:o=!1,enum:c}=n;if(!Si.has(a))throw new C("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${a}" for field "${s}"`,{field:s,type:a});if(r={type:a,required:l,unique:o,enum:c},o)i.push(s)}else throw new C("ERR_SKALEX_VALIDATION_INVALID_SCHEMA",`Invalid schema definition for field "${s}"`,{field:s});t.set(s,r)}return{fields:t,uniqueFields:i}}function Zs(e,t,i=!1){let s=[];for(let[n,r]of t){let a=e[n],l=a===void 0||a===null;if(r.required&&l){s.push(`Field "${n}" is required`);continue}if(l)continue;if(r.type!=="any"){let o=Hi(a);if(o!==r.type)s.push(`Field "${n}" must be of type "${r.type}", got "${o}"`)}if(r.enum&&!r.enum.includes(a))s.push(`Field "${n}" must be one of [${r.enum.map((o)=>JSON.stringify(o)).join(", ")}], got ${JSON.stringify(a)}`)}if(i){for(let n of Object.keys(e))if(!n.startsWith("_")&&!t.has(n))s.push(`Unknown field "${n}" (strict mode)`)}return s}function en(e,t){let i={};for(let[s,n]of Object.entries(e)){if(s.startsWith("_")){i[s]=n;continue}if(!t.has(s))continue;let r=t.get(s);if(r.type!=="any"){if(Hi(n)!==r.type)continue}if(r.enum&&!r.enum.includes(n))continue;i[s]=n}return i}function Oc(e){let t={};for(let[i,s]of Object.entries(e)){if(i.startsWith("_"))continue;let n=Hi(s);t[i]=Si.has(n)?n:"any"}return t}function Nc(e){if(typeof e==="number"){if(e<=0)throw new C("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got ${e}`,{ttl:e});return e*1000}if(typeof e!=="string")throw new C("ERR_SKALEX_VALIDATION_TTL",`Invalid TTL value: ${e}`,{ttl:e});let t=e.match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/);if(!t)throw new C("ERR_SKALEX_VALIDATION_TTL_FORMAT",`Invalid TTL format: "${e}". Use e.g. 300 (seconds), "30m", "24h", "7d"`,{ttl:e});let i=parseFloat(t[1]);if(i<=0)throw new C("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got "${e}"`,{ttl:e});let s=t[2],n=i*{ms:1,s:1000,m:60000,h:3600000,d:86400000}[s];if(!isFinite(n))throw new C("ERR_SKALEX_VALIDATION_TTL",`TTL value "${e}" is too large`,{ttl:e});return n}function $c(e){return new Date(Date.now()+Nc(e))}function Dc(e,t,i=null){let s=Date.now(),n=0,r=e.length;while(r--){let a=e[r];if(a._expiresAt&&new Date(a._expiresAt).getTime()<=s){if(e.splice(r,1),t.delete(a._id),i)i(a);n++}}return n}function tn(e,t){if(e.length!==t.length)throw new et("ERR_SKALEX_QUERY_VECTOR_MISMATCH",`Vector dimension mismatch: ${e.length} vs ${t.length}`,{expected:e.length,got:t.length});let i=0,s=0,n=0;for(let a=0;a<e.length;a++)i+=e[a]*t[a],s+=e[a]*e[a],n+=t[a]*t[a];let r=Math.sqrt(s*n);return r===0?0:i/r}function X(e){if(!("_vector"in e))return{...e};let{_vector:t,...i}=e;return i}function Cc(e){return e.length}function Rc(e,t){let i=0;for(let s of e){let n=Ut(s,t);if(typeof n==="number"&&!isNaN(n))i+=n}return i}function kc(e,t){let i=0,s=0;for(let n of e){let r=Ut(n,t);if(typeof r==="number"&&!isNaN(r))i+=r,s++}return s===0?null:i/s}function Lc(e,t){let i=Object.create(null);for(let s of e){let n=String(Ut(s,t)??"__null__");if(!i[n])i[n]=[];i[n].push(s)}return i}class Kr{constructor(e){this._col=e}get _ctx(){return this._col._ctx}async execute({op:e,beforeHook:t,afterHook:i,hookPayload:s,mutate:n,afterHookPayload:r,save:a,session:l}){let o=this._ctx;await o.ensureConnected(),this._col._txSnapshotIfNeeded();let c=o.txManager,h=c.active&&this._col._activeTxId===c.context?.id,u=h?c.context.id:null,d=this._col._createdInTxId,_=()=>{if(u!==null&&c._abortedIds.has(u))throw new we("ERR_SKALEX_TX_ABORTED",`Transaction ${u} was aborted. No further mutations allowed.`);if(d!==null&&c._abortedIds.has(d))throw new we("ERR_SKALEX_TX_ABORTED",`Transaction ${d} was aborted. Collection obtained inside that transaction cannot be used for further mutations.`)};if(h||d!==null)_();if(t)await o.plugins.run(t,s);let{docs:f,prevDocs:p=[]}=await n(_);if(o.persistence.markDirty(o.collections,this._col.name),await this._col._saveIfNeeded(a),this._col._changelogEnabled)for(let m=0;m<f.length;m++)await o.logChange(e,this._col.name,f[m],p[m]??null,l||null);if(!h||!c.defer(()=>o.sessionStats.recordWrite(l)))o.sessionStats.recordWrite(l);for(let m of f)o.emitEvent(this._col.name,{op:e,collection:this._col.name,doc:X(m)});if(i)if(r)await o.runAfterHook(i,r(f));else for(let m of f)await o.runAfterHook(i,{collection:this._col.name,doc:X(m)});return{docs:f,prevDocs:p}}}function Pc(e){let t={};for(let i in e){if(i.startsWith("$"))continue;let s=e[i];if(s&&typeof s==="object"&&!Array.isArray(s)){let n=Object.keys(s);if(n.length===1&&n[0]==="$eq")t[i]=s.$eq}else t[i]=s}return t}var Fr=new Set(["__proto__","constructor","prototype"]);function Ur(e){if(typeof e!=="object"||e===null||Array.isArray(e))return e;let t={};for(let i of Object.keys(e)){if(Fr.has(i))continue;t[i]=Ur(e[i])}return t}class zr{constructor(e,t){this.name=e.collectionName,this.database=t,this._ctx=t._buildCollectionContext(),this._store=e,this._pipeline=new Kr(this),this._createdInTxId=t._txManager.context?.id??null,this._activeTxId=null}get _data(){return this._store.data}set _data(e){this._store.data=e}get _index(){return this._store.index}get _fieldIndex(){return this._store.fieldIndex||null}get _schema(){return this._store.schema?this._store.schema.fields:null}get _changelogEnabled(){return this._store.changelog===!0}get _softDelete(){return this._store.softDelete===!0}get _versioning(){return this._store.versioning===!0}get _strict(){return this._store.strict===!0}get _onSchemaError(){return this._store.onSchemaError??"throw"}get _defaultTtl(){return this._store.defaultTtl||null}get _defaultEmbed(){return this._store.defaultEmbed||null}get _maxDocs(){return this._store.maxDocs||null}async insertOne(e,t={}){let{save:i,ifNotExists:s,ttl:n,embed:r,session:a}=t;if(s){await this._ctx.ensureConnected();let o=this._findRaw(e);if(o)return X({...o})}let{docs:l}=await this._insertCore([e],{ttl:n,embed:r,session:a,save:i});return X(l[0])}async insertMany(e,t={}){let{save:i,ttl:s,embed:n,session:r}=t,{docs:a}=await this._insertCore(e,{ttl:s,embed:n,session:r,save:i});return a.map(X)}async _insertCore(e,{ttl:t,embed:i,session:s,save:n}){return this._pipeline.execute({op:"insert",beforeHook:null,afterHook:"afterInsert",hookPayload:null,save:n,session:s,mutate:async(r)=>{let a=[],l=new Set;for(let o of e){let c=this._applyValidation(o);await this._ctx.plugins.run("beforeInsert",{collection:this.name,doc:c});let h=await this._buildDoc(c,{ttl:t,embed:i});if(this._index.has(h._id)||l.has(h._id))throw new Te("ERR_SKALEX_UNIQUE_DUPLICATE_ID",`Duplicate _id "${h._id}" in collection "${this.name}"`,{id:h._id,collection:this.name});l.add(h._id),a.push(h)}if(r(),this._fieldIndex)this._fieldIndex.assertUniqueBatch(a);for(let o of a)this._addToIndex(o);this._data.push(...a);for(let o of a)this._index.set(o._id,o);return this._enforceCapAfterInsert(),{docs:a}}})}async updateOne(e,t,i={}){await this._ctx.ensureConnected();let s=this._findRaw(e);if(!s)return null;let{save:n,session:r}=i,{docs:a}=await this._updateCore([s],e,t,{save:n,session:r});return X(a[0])}async updateMany(e,t,i={}){await this._ctx.ensureConnected();let s=this._findAllRaw(e);if(s.length===0)return[];let{save:n,session:r}=i,{docs:a}=await this._updateCore(s,e,t,{save:n,session:r});return a.map(X)}async _updateCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"update",beforeHook:"beforeUpdate",afterHook:"afterUpdate",hookPayload:{collection:this.name,filter:t,update:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:t,update:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{let a=this._changelogEnabled?e.map((h)=>structuredClone(h)):e.map(()=>null),l=e.map((h)=>this._prepareUpdatedDoc(h,i));this._assertUniqueCandidates(e,l),r();let o=new Set(e),c=new Map;for(let h=0;h<this._data.length;h++)if(o.has(this._data[h]))c.set(this._data[h],h);for(let h=0;h<e.length;h++)this._commitUpdatedDoc(e[h],l[h],c);return{docs:l,prevDocs:a}}})}applyUpdate(e,t){for(let i in t){if(Fr.has(i))continue;if(i==="_id"||i==="createdAt")continue;let s=t[i];if(Array.isArray(s))e[i]=s;else if(typeof s==="object"&&s!==null){let n=Object.keys(s);if(n.some((r)=>r.startsWith("$"))){for(let r of n)if(r==="$inc"&&typeof e[i]==="number")e[i]+=s[r];else if(r==="$push"){if(!Array.isArray(e[i]))e[i]=[];e[i].push(s[r])}}else e[i]=Ur(s)}else e[i]=s}if(e.updatedAt=new Date,this._versioning)e._version=(e._version??0)+1;return e}_prepareUpdatedDoc(e,t){let i=structuredClone(e),s=structuredClone(e);if(this.applyUpdate(s,t),!this._schema)return s;let n=Zs(s,this._schema,this._strict);if(!n.length)return s;switch(this._onSchemaError){case"throw":throw new C("ERR_SKALEX_VALIDATION_UPDATE",`Update validation failed on doc "${e._id}": ${n.join("; ")}`,{id:e._id,errors:n});case"strip":return this._stripCandidateToValid(s,i);default:return this._ctx.logger(`[${this.name}] Update validation warning: ${n.join("; ")}`,"warn"),s}}_stripCandidateToValid(e,t){let i=en(e,this._schema),s=structuredClone(t);for(let[n,r]of Object.entries(i)){if(n.startsWith("_"))continue;s[n]=r}if(s.updatedAt=e.updatedAt,this._versioning)s._version=e._version;return s}_commitUpdatedDoc(e,t,i){let s=i?i.get(e):this._data.indexOf(e);if(s===void 0||s===-1)throw new Pe("ERR_SKALEX_PERSISTENCE_DOC_MISSING",`Document "${e._id}" no longer exists in collection "${this.name}"`,{id:e._id,collection:this.name});this._data[s]=t,this._index.set(t._id,t),this._updateInIndex(e,t)}_assertUniqueCandidates(e,t){this._fieldIndex?.assertUniqueCandidates(e,t)}async upsert(e,t,i={}){if(await this._ctx.ensureConnected(),this._findRaw(e))return this.updateOne(e,t,i);return this.insertOne({...Pc(e),...t},i)}async upsertMany(e,t,i={}){await this._ctx.ensureConnected();let{save:s,...n}=i,r=[];for(let a of e)r.push(await this.upsert({[t]:a[t]},a,{...n,save:!1}));return await this._saveIfNeeded(s),r}async restore(e,t={}){if(!this._softDelete)throw new et("ERR_SKALEX_QUERY_SOFT_DELETE_REQUIRED",`restore() requires softDelete on "${this.name}"`,{collection:this.name});await this._ctx.ensureConnected();let{save:i,session:s}=t,n=this._findRaw(e,{includeDeleted:!0});if(!n||!n._deletedAt)return null;let{docs:r}=await this._pipeline.execute({op:"restore",beforeHook:null,afterHook:null,hookPayload:null,save:i,session:s,mutate:async(a)=>{return a(),delete n._deletedAt,n.updatedAt=new Date,this._index.set(n._id,n),{docs:[n]}}});return X(r[0])}watch(e,t){if(typeof e==="function")t=e,e=null;if(t)return this._ctx.eventBus.on(this.name,(i)=>{if(!e||Y(i.doc,e))t(i)});return this._watchIterator(e)}_watchIterator(e){let t=[],i=null,s=!1,n=this._ctx.eventBus.on(this.name,(r)=>{if(e&&!Y(r.doc,e))return;if(i){let a=i;i=null,a({value:r,done:!1})}else t.push(r)});return{[Symbol.asyncIterator](){return this},next(){if(t.length>0)return Promise.resolve({value:t.shift(),done:!1});if(s)return Promise.resolve({value:void 0,done:!0});return new Promise((r)=>{i=r})},return(){if(s=!0,n(),i){let r=i;i=null,r({value:void 0,done:!0})}return Promise.resolve({value:void 0,done:!0})}}}async count(e={}){return await this._ctx.ensureConnected(),Cc(this._findAllRaw(e))}async sum(e,t={}){return await this._ctx.ensureConnected(),Rc(this._findAllRaw(t),e)}async avg(e,t={}){return await this._ctx.ensureConnected(),kc(this._findAllRaw(t),e)}async groupBy(e,t={}){return await this._ctx.ensureConnected(),Lc(this._findAllRaw(t),e)}async findOne(e,t={}){await this._ctx.ensureConnected();let{populate:i,select:s,includeDeleted:n=!1}=t,r=this._findRaw(e,{includeDeleted:n});if(!r)return null;let a=this._projectDoc(r,s);if(i)await this._populateDoc(a,r,i);return a}async find(e,t={}){await this._ctx.ensureConnected();let i=Date.now(),{populate:s,select:n,sort:r,page:a=1,limit:l,session:o,includeDeleted:c=!1}=t;await this._ctx.plugins.run("beforeFind",{collection:this.name,filter:e,options:t});let h=this._getCandidates(e),u=Tc(e,this._fieldIndex?this._fieldIndex.indexedFields:new Set),d=[];for(let f of h){if(this._softDelete&&f._deletedAt&&!c)continue;if(!Y(f,u))continue;let p=this._projectDoc(f,n);if(s)await this._populateDoc(p,f,s);d.push(p)}if(r){let f=Object.keys(r);d.sort((p,m)=>{for(let w of f){let x=r[w];if(p[w]<m[w])return-x;if(p[w]>m[w])return x}return 0})}let _;if(l){let f=d.length,p=Math.ceil(f/l),m=(a-1)*l;d=d.slice(m,m+l),_={page:a,totalDocs:f,totalPages:p}}return this._ctx.queryLog?.record({collection:this.name,op:"find",filter:e,duration:Date.now()-i,resultCount:d.length}),this._ctx.sessionStats.recordRead(o),await this._ctx.plugins.run("afterFind",{collection:this.name,filter:e,options:t,docs:d}),_?{docs:d,..._}:{docs:d}}async search(e,{filter:t,limit:i=10,minScore:s=0,session:n}={}){await this._ctx.ensureConnected();let r=Date.now();await this._ctx.plugins.run("beforeSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s}});let a=await this._ctx.embed(e),l=t?this._findAllRaw(t):this._data,o=[];for(let d of l){if(!d._vector)continue;let _=tn(a,d._vector);if(_>=s)o.push({doc:d,score:_})}o.sort((d,_)=>_.score-d.score);let c=o.slice(0,i);this._ctx.queryLog?.record({collection:this.name,op:"search",query:e,duration:Date.now()-r,resultCount:c.length}),this._ctx.sessionStats.recordRead(n);let h=c.map((d)=>X(d.doc)),u=c.map((d)=>d.score);return await this._ctx.plugins.run("afterSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s},docs:h,scores:u}),{docs:h,scores:u}}async similar(e,{limit:t=10,minScore:i=0}={}){await this._ctx.ensureConnected();let s=this._index.get(e);if(!s||!s._vector)return{docs:[],scores:[]};let n=[];for(let a of this._data){if(a._id===e||!a._vector)continue;let l=tn(s._vector,a._vector);if(l>=i)n.push({doc:a,score:l})}n.sort((a,l)=>l.score-a.score);let r=n.slice(0,t);return{docs:r.map((a)=>X(a.doc)),scores:r.map((a)=>a.score)}}async deleteOne(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findRaw(e);if(!r)return null;let{docs:a}=await this._deleteCore("soft",[r],e,{save:i,session:s});return X(a[0])}let{docs:n}=await this._deleteCore("hard",null,e,{save:i,session:s});if(n.length===0)return null;return X(n[0])}async deleteMany(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findAllRaw(e);if(r.length===0)return[];let{docs:a}=await this._deleteCore("soft",r,e,{save:i,session:s});return a.map(X)}let{docs:n}=await this._deleteCore("hardMany",null,e,{save:i,session:s});return n.map(X)}async _deleteCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"delete",beforeHook:"beforeDelete",afterHook:"afterDelete",hookPayload:{collection:this.name,filter:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{if(r(),e==="soft"){let o=new Date;for(let c of t)c._deletedAt=o,c.updatedAt=o,this._index.set(c._id,c);return{docs:t}}if(e==="hard"){let o=this._findIndex(i);if(o===-1)return{docs:[]};let c=this._data.splice(o,1)[0];return this._index.delete(c._id),this._removeFromIndex(c),{docs:[c]}}let a=[],l=[];for(let o of this._data)if(Y(o,i))a.push(o),this._index.delete(o._id),this._removeFromIndex(o);else l.push(o);return this._data=l,{docs:a}}})}async export(e={},t={}){let{dir:i,name:s,format:n="json"}=t;try{let r=this._data.filter((h)=>Y(h,e));if(r.length===0)throw new et("ERR_SKALEX_QUERY_EXPORT_EMPTY",`export(): no documents matched the filter in "${this.name}"`,{collection:this.name});let a;if(n==="json")a=JSON.stringify(r,null,2);else{let h=(_)=>{if(_==null)return"";let f=typeof _==="object"?JSON.stringify(_):String(_);return f.includes(",")||f.includes('"')||f.includes(`
91
+ `))!==-1){let i=this._buffer.slice(0,t).trim();if(this._buffer=this._buffer.slice(t+1),i&&this._onMessage){let s;try{s=JSON.parse(i)}catch(n){this.send(De(null,Xi,"Parse error"));continue}this._onMessage(s).catch(()=>{})}}}),process.stdin.on("end",()=>{process.exit(0)})}stop(){process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),this._started=!1}}var bc={name:"skalex",version:"4.0.0-alpha"},Tc="2024-11-05";class jr{constructor(e,t={}){this._db=e,this._transport=t.transport||"stdio",this._port=t.port||3000,this._host=t.host||"127.0.0.1",this._allowedOrigin=t.allowedOrigin??null,this._maxBodySize=t.maxBodySize??1048576,this._scopes=t.scopes||{"*":["read"]},this._t=null}async listen(){if(this._transport==="http")this._t=new Pr({port:this._port,host:this._host,allowedOrigin:this._allowedOrigin,maxBodySize:this._maxBodySize});else this._t=new Mr;this._t.onMessage((e)=>this._handleMessage(e)),await this._t.start()}async connect(e){if(this._t=e,this._t.onMessage((t)=>this._handleMessage(t)),typeof this._t.start==="function")await this._t.start()}async close(){if(this._t&&typeof this._t.stop==="function")await this._t.stop();this._t=null}get transport(){return this._transport}get url(){return this._t?.url}async _handleMessage(e){let{msg:t,parseError:i}=typeof e==="string"?Sc(e):{msg:e};if(i){this._send(i);return}let{id:s,method:n,params:r}=t;if(s===void 0){if(n==="notifications/initialized")return;return}try{switch(n){case"initialize":this._send(at(s,{protocolVersion:Tc,capabilities:{tools:{}},serverInfo:bc}));break;case"tools/list":this._send(at(s,{tools:this._visibleTools()}));break;case"tools/call":await this._handleToolCall(s,r);break;case"ping":this._send(at(s,{}));break;default:this._send(De(s,Vs,`Method not found: ${n}`))}}catch(a){this._send(De(s,Ec,a.message||"Internal error"))}}async _handleToolCall(e,t){let i=t?.name,s=t?.arguments??{};if(!i){this._send(De(e,vc,"tools/call requires params.name"));return}let n=Hs.find((a)=>a.name===i);if(!n){this._send(De(e,Vs,`Unknown tool: ${i}`));return}let r=s.collection||s.collection_name||null;if(!this._hasScope(r,n.scope)){this._send(at(e,Js(`Access denied: "${i}" requires "${n.scope}" scope on collection "${r}".`)));return}try{let a=await Ac(i,s,this._db);this._send(at(e,Ic(JSON.stringify(a,null,2))))}catch(a){this._send(at(e,Js(a.message||String(a))))}}_visibleTools(){return Hs.filter((e)=>{let t=this._scopes["*"];if(t&&(t.includes(e.scope)||t.includes("admin")))return!0;for(let[,i]of Object.entries(this._scopes))if(i.includes(e.scope)||i.includes("admin"))return!0;return!1})}_hasScope(e,t){let i=(s)=>s.includes("admin")||s.includes(t);if(e&&this._scopes[e])return i(this._scopes[e]);if(this._scopes["*"])return i(this._scopes["*"]);return!1}_send(e){this._t?.send(e)}}var Ot="migrations",Ys=(e)=>JSON.stringify(e,function(t,i){let s=this[t];if(s instanceof Date)return{__skalex_date__:s.toISOString()};if(typeof i==="bigint")return{__skalex_bigint__:i.toString()};return i}),Ws=(e)=>JSON.parse(e,(t,i)=>{if(i&&typeof i==="object"){if("__skalex_bigint__"in i)return BigInt(i.__skalex_bigint__);if("__skalex_date__"in i)return new Date(i.__skalex_date__)}return i});class ie{constructor({path:e="./.db",format:t="gz",debug:i=!1,adapter:s,ai:n,encrypt:r,slowQueryLog:a,queryCache:l,memory:o,logger:c,plugins:h,llmAdapter:u,embeddingAdapter:d,regexMaxLength:_,idGenerator:f,serializer:p,deserializer:m,autoSave:w,ttlSweepInterval:x,lenientLoad:R}={}){if(this.dataDirectory=e,this.dataFormat=t,this.debug=i,!ie._errorsAttached)ie.SkalexError=qe,ie.ValidationError=D,ie.UniqueConstraintError=Ie,ie.TransactionError=ye,ie.PersistenceError=Le,ie.AdapterError=fe,ie.QueryError=Ze,ie._errorsAttached=!0;this._adapterConfig=s??null;let E=s||new yr({dir:e,format:t});if(r)E=new Or(E,r.key);if(this.fs=E,this._registry=new vr(gr),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._migrations=new wr,this._connectPromise=null,this.isConnected=!1,this._aiConfig=n||null,this._encryptConfig=r||null,this._pluginsConfig=Array.isArray(h)?h:null,this._memoryConfig=o||null,this._regexMaxLength=_??500,this._idGenerator=f??null,this._serializer=p??Ys,this._deserializer=m??Ws,this._autoSave=w??!1,this._txManager=new xr,this._ttlSweepInterval=x??0,this._ttlTimer=null,this._logger=c??qs,this._embeddingAdapter=d??(n?lc(n):null),this._aiAdapter=u??(n?cc(n):null),this._persistence=new Ar({adapter:this.fs,serializer:this._serializer,deserializer:this._deserializer,logger:this._logger,debug:this.debug,lenientLoad:R??!1}),this._changeLog=new $r(this),this._queryCache=new Dr(l||{}),this._eventBus=new Cr,this._queryLog=a?new Rr(a):null,this._sessionStats=new kr,this._plugins=new Lr,Array.isArray(h))for(let A of h)this._plugins.register(A)}async connect(){if(this._connectPromise)return this._connectPromise;return this._connectPromise=this._doConnect(),this._connectPromise}async _doConnect(){try{await this.loadData();let e=this._getMeta();if(e.queryCache)this._queryCache.fromJSON(e.queryCache);if(this._migrations._migrations.length>0){let t=e.appliedVersions||[],i=await this._migrations.run((s)=>this.useCollection(`_migration_${s}`),t);this._saveMeta({appliedVersions:i})}if(this._sweepTtl(),this._ttlSweepInterval>0){if(this._ttlTimer=setInterval(()=>this._sweepTtl(),this._ttlSweepInterval),this._ttlTimer?.unref)this._ttlTimer.unref()}this.isConnected=!0,this._log("> - Connected to the database (\u221A)")}catch(e){throw this._logger(`Error connecting to the database: ${e}`,"error"),e}}async disconnect(){try{if(this._ttlTimer)clearInterval(this._ttlTimer),this._ttlTimer=null;await this.saveData(),this._registry.clear(),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._connectPromise=null,this.isConnected=!1,this._log("> - Disconnected from the database (\u221A)")}catch(e){throw this._logger(`Error disconnecting from the database: ${e}`,"error"),e}}async _ensureConnected(){if(this.isConnected)return;return this.connect()}useCollection(e){return this._registry.get(e,this)}createCollection(e,t={}){return this._registry.create(e,t,this)}_createCollectionStore(e,t={}){this._registry.createStore(e,t)}async renameCollection(e,t){this._registry.rename(e,t),await this.saveData(t),await this.fs.delete(e)}async loadData(){await this._persistence.loadAll(this.collections,{parseSchema:_r,buildIndex:this._registry.buildIndex,IndexEngine:kt});for(let e in this._collectionInstances){let t=this.collections[e];if(t&&this._collectionInstances[e]._store!==t)this._collectionInstances[e]._store=t}}async saveData(e){await this._persistence.save(this.collections,e)}buildIndex(e,t){return this._registry.buildIndex(e,t)}addMigration(e){this._migrations.add(e)}migrationStatus(){let e=this._getMeta();return this._migrations.status(e.appliedVersions||[])}namespace(e){if(this._adapterConfig)throw new fe("ERR_SKALEX_ADAPTER_NAMESPACE_REQUIRES_FS","namespace() requires the default FsAdapter. When a custom storage adapter is configured, create a separate Skalex instance with your adapter instead.");let t=String(e).replace(/[^a-zA-Z0-9_-]/g,"_");if(!t)throw new D("ERR_SKALEX_VALIDATION_NAMESPACE_ID","namespace: id must contain at least one alphanumeric character",{id:e});return new ie({path:`${this.dataDirectory}/${t}`,format:this.dataFormat,debug:this.debug,ai:this._aiConfig||void 0,encrypt:this._encryptConfig||void 0,slowQueryLog:this._queryLog?{threshold:this._queryLog._threshold,maxEntries:this._queryLog._maxEntries}:void 0,queryCache:this._queryCache?{maxSize:this._queryCache._maxSize,ttl:this._queryCache._ttl}:void 0,plugins:this._pluginsConfig||void 0,memory:this._memoryConfig||void 0,logger:this._logger!==qs?this._logger:void 0,llmAdapter:this._aiAdapter&&!this._aiConfig?this._aiAdapter:void 0,embeddingAdapter:this._embeddingAdapter&&!this._aiConfig?this._embeddingAdapter:void 0,regexMaxLength:this._regexMaxLength!==500?this._regexMaxLength:void 0,idGenerator:this._idGenerator||void 0,serializer:this._serializer!==Ys?this._serializer:void 0,deserializer:this._deserializer!==Ws?this._deserializer:void 0,autoSave:this._autoSave||void 0,ttlSweepInterval:this._ttlSweepInterval||void 0})}use(e){this._plugins.register(e)}watch(e){return this._eventBus.on("*",e)}sessionStats(e){if(e!==void 0)return this._sessionStats.get(e);return this._sessionStats.all()}get _inTransaction(){return this._txManager.active}_emitEvent(e,t){if(!this._txManager.defer(()=>this._eventBus.emit(e,t)))this._eventBus.emit(e,t)}async _runAfterHook(e,t){if(!this._txManager.defer(()=>this._plugins.run(e,t)))await this._plugins.run(e,t)}async _logChange(e,t,i,s,n){if(!this._txManager.defer(()=>this._changeLog.log(e,t,i,s,n)))await this._changeLog.log(e,t,i,s,n)}async transaction(e,t={}){return this._txManager.run(e,this,t)}async seed(e,{reset:t=!1}={}){for(let[i,s]of Object.entries(e)){if(t&&this.collections[i])this._applySnapshot(i,{data:[],index:new Map}),delete this._collectionInstances[i];await this.useCollection(i).insertMany(s)}await this.saveData()}dump(){return this._registry.dump()}inspect(e){return this._registry.inspect(e)}async import(e){let t=await this.fs.readRaw(e),i;try{i=JSON.parse(t)}catch{throw new Le("ERR_SKALEX_PERSISTENCE_INVALID_JSON",`import: invalid JSON in file "${e}"`,{filePath:e})}let s=e.split("/").pop().replace(/\.[^.]+$/,"");return this.useCollection(s).insertMany(Array.isArray(i)?i:[i],{save:!0})}async embed(e){if(!this._embeddingAdapter)throw new fe("ERR_SKALEX_ADAPTER_EMBEDDING_REQUIRED","db.embed() requires an AI adapter. Pass { ai: { provider, apiKey } } to the Skalex constructor.");return this._embeddingAdapter.embed(e)}async ask(e,t,{limit:i=20}={}){if(!this._aiAdapter)throw new fe("ERR_SKALEX_ADAPTER_LLM_REQUIRED",'db.ask() requires a language model adapter. Configure { ai: { provider, model: "..." } }.');let s=this.useCollection(e),n=this.schema(e),r=this._queryCache.get(e,n,t);if(!r){r=await this._aiAdapter.generate(n,t);let a=wc(r,n);if(a.length)a.forEach((l)=>this._log(`[ask] ${l}`));this._queryCache.set(e,n,t,r),this._saveMeta({queryCache:this._queryCache.toJSON()})}return s.find(gc(r,{regexMaxLength:this._regexMaxLength}),{limit:i})}schema(e){return this._registry.schema(e)}useMemory(e){return new Nr(e,this)}changelog(){return this._changeLog}async restore(e,t,i={}){return this._changeLog.restore(e,t,i)}stats(e){return this._registry.stats(e)}slowQueries(e={}){if(!this._queryLog)return[];return this._queryLog.entries(e)}slowQueryCount(){return this._queryLog?this._queryLog.size:0}clearSlowQueries(){this._queryLog?.clear()}mcp(e={}){return new jr(this,e)}_getMeta(){let e=this.collections._meta;if(!e)return{};return e.index.get(Ot)||{}}_saveMeta(e){if(!this.collections._meta)this._createCollectionStore("_meta");let t=this.collections._meta,i=t.index.get(Ot);if(i)Object.assign(i,e);else{let s={_id:Ot,...e};t.data.push(s),t.index.set(Ot,s)}this._persistence.markDirty(this.collections,"_meta")}_sweepTtl(){for(let e in this.collections){let t=this.collections[e],i=tc(t.data,t.index,t.fieldIndex?(s)=>t.fieldIndex.remove(s):null);if(i>0)this._persistence.markDirty(this.collections,e),this._log(`TTL sweep: removed ${i} expired docs from "${e}"`)}}_buildCollectionContext(){let e=this;return{ensureConnected:()=>e._ensureConnected(),get txManager(){return e._txManager},get plugins(){return e._plugins},get eventBus(){return e._eventBus},get sessionStats(){return e._sessionStats},get queryLog(){return e._queryLog},get logger(){return e._logger},get persistence(){return e._persistence},get collections(){return e.collections},embed:(t)=>e.embed(t),get idGenerator(){return e._idGenerator},get autoSave(){return e._autoSave},saveCollection:(t)=>e.saveData(t),snapshotCollection:(t)=>e._snapshotCollection(t),getCollection:(t)=>e.useCollection(t),emitEvent:(t,i)=>e._emitEvent(t,i),runAfterHook:(t,i)=>e._runAfterHook(t,i),logChange:(t,i,s,n,r)=>e._logChange(t,i,s,n,r),get fs(){return e.fs},get dataDirectory(){return e.dataDirectory}}}_log(e){if(this.debug)this._logger(e,"info")}_snapshotCollection(e){return{data:structuredClone(e.data)}}_applySnapshot(e,t){let i=this.collections[e];if(!i)return;if(i.data=t.data,i.index=this.buildIndex(t.data,"_id"),i.fieldIndex)i.fieldIndex.buildFromData(t.data)}}function Oc(){let e=Date.now().toString(16),t;try{t=jo.randomBytes(8).toString("hex")}catch{let i=new Uint8Array(8);crypto.getRandomValues(i),t=Array.from(i).map((s)=>s.toString(16).padStart(2,"0")).join("")}return`${e}${t}`}function Qs(e,t){let i=e instanceof Error?e.message:e;if(t==="error")console.error(i);else console.log(i)}var Gs=new Set(["__proto__","constructor","prototype"]);function Ut(e,t){if(!t.includes(".")){if(Gs.has(t))return;return e[t]}let i=e;for(let s of t.split(".")){if(Gs.has(s))return;if(i==null)return;i=i[s]}return i}class Ke extends Error{constructor(e,t,i={}){super(t);this.name=this.constructor.name,this.code=e,this.details=i}}class C extends Ke{}class Te extends Ke{}class we extends Ke{}class Pe extends Ke{}class pe extends Ke{}class et extends Ke{}function Ei(e,t){if(e===t)return!0;if(e==null||t==null)return!1;if(typeof e!==typeof t)return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.source===t.source&&e.flags===t.flags;if(Array.isArray(e)){if(!Array.isArray(t)||e.length!==t.length)return!1;for(let i=0;i<e.length;i++)if(!Ei(e[i],t[i]))return!1;return!0}if(typeof e==="object"){if(Array.isArray(t))return!1;let i=Object.keys(e);if(i.length!==Object.keys(t).length)return!1;for(let s of i){if(!Object.prototype.hasOwnProperty.call(t,s))return!1;if(!Ei(e[s],t[s]))return!1}return!0}return!1}function Y(e,t){if(typeof t==="function")return t(e);if(t==null)return!0;if(typeof t==="object"&&Object.keys(t).length===0)return!0;if("$or"in t){let i=t.$or;if(!Array.isArray(i))throw new et("ERR_SKALEX_QUERY_INVALID_OPERATOR","$or must be an array of filters",{operator:"$or"});if(!i.some((s)=>Y(e,s)))return!1}if("$and"in t){let i=t.$and;if(!Array.isArray(i))throw new et("ERR_SKALEX_QUERY_INVALID_OPERATOR","$and must be an array of filters",{operator:"$and"});if(!i.every((s)=>Y(e,s)))return!1}if("$not"in t){if(Y(e,t.$not))return!1}for(let i in t){if(i==="$or"||i==="$and"||i==="$not")continue;let s=t[i],n;try{n=Ut(e,i)}catch{return!1}if(s instanceof RegExp){if(!s.test(String(n)))return!1}else if(typeof s==="object"&&s!==null){if(Object.keys(s).some((r)=>r.startsWith("$"))){if("$eq"in s&&n!==s.$eq)return!1;if("$ne"in s&&n===s.$ne)return!1;if("$gt"in s&&!(n>s.$gt))return!1;if("$lt"in s&&!(n<s.$lt))return!1;if("$gte"in s&&!(n>=s.$gte))return!1;if("$lte"in s&&!(n<=s.$lte))return!1;if("$in"in s&&!s.$in.includes(n))return!1;if("$nin"in s&&s.$nin.includes(n))return!1;if("$regex"in s){if(!(s.$regex instanceof RegExp?s.$regex:new RegExp(s.$regex)).test(String(n)))return!1}if("$fn"in s&&!s.$fn(n))return!1}else if(!Ei(n,s))return!1}else if(n!==s)return!1}return!0}function Nc(e,t=new Set){if(typeof e!=="object"||e===null||typeof e==="function")return e;let i=[],s=[],n=[],r=[],a=[];for(let o in e){if(o==="$or"||o==="$and"||o==="$not"){a.push(o);continue}let c=e[o];if(t.has(o))i.push(o);else if(c instanceof RegExp||typeof c==="object"&&c!==null&&(("$regex"in c)||("$fn"in c))||typeof c==="function")r.push(o);else if(typeof c==="object"&&c!==null&&(("$gt"in c)||("$lt"in c)||("$gte"in c)||("$lte"in c)||("$ne"in c)||("$in"in c)||("$nin"in c)))n.push(o);else s.push(o)}let l={};for(let o of[...i,...s,...n,...r,...a])l[o]=e[o];return l}var Si=new Set(["string","number","boolean","object","array","date","any"]);function Hi(e){if(Array.isArray(e))return"array";if(e instanceof Date)return"date";return typeof e}function qr(e){let t=new Map,i=[];for(let[s,n]of Object.entries(e)){let r;if(typeof n==="string"){if(!Si.has(n))throw new C("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${n}" for field "${s}"`,{field:s,type:n});r={type:n,required:!1,unique:!1}}else if(typeof n==="object"&&n!==null){let{type:a="any",required:l=!1,unique:o=!1,enum:c}=n;if(!Si.has(a))throw new C("ERR_SKALEX_VALIDATION_UNKNOWN_TYPE",`Unknown schema type "${a}" for field "${s}"`,{field:s,type:a});if(r={type:a,required:l,unique:o,enum:c},o)i.push(s)}else throw new C("ERR_SKALEX_VALIDATION_INVALID_SCHEMA",`Invalid schema definition for field "${s}"`,{field:s});t.set(s,r)}return{fields:t,uniqueFields:i}}function Zs(e,t,i=!1){let s=[];for(let[n,r]of t){let a=e[n],l=a===void 0||a===null;if(r.required&&l){s.push(`Field "${n}" is required`);continue}if(l)continue;if(r.type!=="any"){let o=Hi(a);if(o!==r.type)s.push(`Field "${n}" must be of type "${r.type}", got "${o}"`)}if(r.enum&&!r.enum.includes(a))s.push(`Field "${n}" must be one of [${r.enum.map((o)=>JSON.stringify(o)).join(", ")}], got ${JSON.stringify(a)}`)}if(i){for(let n of Object.keys(e))if(!n.startsWith("_")&&!t.has(n))s.push(`Unknown field "${n}" (strict mode)`)}return s}function en(e,t){let i={};for(let[s,n]of Object.entries(e)){if(s.startsWith("_")){i[s]=n;continue}if(!t.has(s))continue;let r=t.get(s);if(r.type!=="any"){if(Hi(n)!==r.type)continue}if(r.enum&&!r.enum.includes(n))continue;i[s]=n}return i}function $c(e){let t={};for(let[i,s]of Object.entries(e)){if(i.startsWith("_"))continue;let n=Hi(s);t[i]=Si.has(n)?n:"any"}return t}function Dc(e){if(typeof e==="number"){if(e<=0)throw new C("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got ${e}`,{ttl:e});return e*1000}if(typeof e!=="string")throw new C("ERR_SKALEX_VALIDATION_TTL",`Invalid TTL value: ${e}`,{ttl:e});let t=e.match(/^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/);if(!t)throw new C("ERR_SKALEX_VALIDATION_TTL_FORMAT",`Invalid TTL format: "${e}". Use e.g. 300 (seconds), "30m", "24h", "7d"`,{ttl:e});let i=parseFloat(t[1]);if(i<=0)throw new C("ERR_SKALEX_VALIDATION_TTL",`TTL must be positive, got "${e}"`,{ttl:e});let s=t[2],n=i*{ms:1,s:1000,m:60000,h:3600000,d:86400000}[s];if(!isFinite(n))throw new C("ERR_SKALEX_VALIDATION_TTL",`TTL value "${e}" is too large`,{ttl:e});return n}function Cc(e){return new Date(Date.now()+Dc(e))}function Rc(e,t,i=null){let s=Date.now(),n=0,r=e.length;while(r--){let a=e[r];if(a._expiresAt&&new Date(a._expiresAt).getTime()<=s){if(e.splice(r,1),t.delete(a._id),i)i(a);n++}}return n}function tn(e,t){if(e.length!==t.length)throw new et("ERR_SKALEX_QUERY_VECTOR_MISMATCH",`Vector dimension mismatch: ${e.length} vs ${t.length}`,{expected:e.length,got:t.length});let i=0,s=0,n=0;for(let a=0;a<e.length;a++)i+=e[a]*t[a],s+=e[a]*e[a],n+=t[a]*t[a];let r=Math.sqrt(s*n);return r===0?0:i/r}function X(e){if(!("_vector"in e))return{...e};let{_vector:t,...i}=e;return i}function kc(e){return e.length}function Lc(e,t){let i=0;for(let s of e){let n=Ut(s,t);if(typeof n==="number"&&!isNaN(n))i+=n}return i}function Pc(e,t){let i=0,s=0;for(let n of e){let r=Ut(n,t);if(typeof r==="number"&&!isNaN(r))i+=r,s++}return s===0?null:i/s}function Mc(e,t){let i=Object.create(null);for(let s of e){let n=String(Ut(s,t)??"__null__");if(!i[n])i[n]=[];i[n].push(s)}return i}class Kr{constructor(e){this._col=e}get _ctx(){return this._col._ctx}async execute({op:e,beforeHook:t,afterHook:i,hookPayload:s,mutate:n,afterHookPayload:r,save:a,session:l}){let o=this._ctx;await o.ensureConnected(),this._col._txSnapshotIfNeeded();let c=o.txManager,h=c.active&&this._col._activeTxId===c.context?.id,u=h?c.context.id:null,d=this._col._createdInTxId,_=()=>{if(u!==null&&c._abortedIds.has(u))throw new we("ERR_SKALEX_TX_ABORTED",`Transaction ${u} was aborted. No further mutations allowed.`);if(d!==null&&c._abortedIds.has(d))throw new we("ERR_SKALEX_TX_ABORTED",`Transaction ${d} was aborted. Collection obtained inside that transaction cannot be used for further mutations.`)};if(h||d!==null)_();if(t)await o.plugins.run(t,s);let{docs:f,prevDocs:p=[]}=await n(_);if(o.persistence.markDirty(o.collections,this._col.name),await this._col._saveIfNeeded(a),this._col._changelogEnabled)for(let m=0;m<f.length;m++)await o.logChange(e,this._col.name,f[m],p[m]??null,l||null);if(!h||!c.defer(()=>o.sessionStats.recordWrite(l)))o.sessionStats.recordWrite(l);for(let m of f)o.emitEvent(this._col.name,{op:e,collection:this._col.name,doc:X(m)});if(i)if(r)await o.runAfterHook(i,r(f));else for(let m of f)await o.runAfterHook(i,{collection:this._col.name,doc:X(m)});return{docs:f,prevDocs:p}}}function jc(e){let t={};for(let i in e){if(i.startsWith("$"))continue;let s=e[i];if(s&&typeof s==="object"&&!Array.isArray(s)){let n=Object.keys(s);if(n.length===1&&n[0]==="$eq")t[i]=s.$eq}else t[i]=s}return t}var Fr=new Set(["__proto__","constructor","prototype"]);function Ur(e){if(typeof e!=="object"||e===null||Array.isArray(e))return e;let t={};for(let i of Object.keys(e)){if(Fr.has(i))continue;t[i]=Ur(e[i])}return t}class zr{constructor(e,t){this.name=e.collectionName,this.database=t,this._ctx=t._buildCollectionContext(),this._store=e,this._pipeline=new Kr(this),this._createdInTxId=t._txManager.context?.id??null,this._activeTxId=null}get _data(){return this._store.data}set _data(e){this._store.data=e}get _index(){return this._store.index}get _fieldIndex(){return this._store.fieldIndex||null}get _schema(){return this._store.schema?this._store.schema.fields:null}get _changelogEnabled(){return this._store.changelog===!0}get _softDelete(){return this._store.softDelete===!0}get _versioning(){return this._store.versioning===!0}get _strict(){return this._store.strict===!0}get _onSchemaError(){return this._store.onSchemaError??"throw"}get _defaultTtl(){return this._store.defaultTtl||null}get _defaultEmbed(){return this._store.defaultEmbed||null}get _maxDocs(){return this._store.maxDocs||null}async insertOne(e,t={}){let{save:i,ifNotExists:s,ttl:n,embed:r,session:a}=t;if(s){await this._ctx.ensureConnected();let o=this._findRaw(e);if(o)return X({...o})}let{docs:l}=await this._insertCore([e],{ttl:n,embed:r,session:a,save:i});return X(l[0])}async insertMany(e,t={}){let{save:i,ttl:s,embed:n,session:r}=t,{docs:a}=await this._insertCore(e,{ttl:s,embed:n,session:r,save:i});return a.map(X)}async _insertCore(e,{ttl:t,embed:i,session:s,save:n}){return this._pipeline.execute({op:"insert",beforeHook:null,afterHook:"afterInsert",hookPayload:null,save:n,session:s,mutate:async(r)=>{let a=[],l=new Set;for(let o of e){let c=this._applyValidation(o);await this._ctx.plugins.run("beforeInsert",{collection:this.name,doc:c});let h=await this._buildDoc(c,{ttl:t,embed:i});if(this._index.has(h._id)||l.has(h._id))throw new Te("ERR_SKALEX_UNIQUE_DUPLICATE_ID",`Duplicate _id "${h._id}" in collection "${this.name}"`,{id:h._id,collection:this.name});l.add(h._id),a.push(h)}if(r(),this._fieldIndex)this._fieldIndex.assertUniqueBatch(a);for(let o of a)this._addToIndex(o);this._data.push(...a);for(let o of a)this._index.set(o._id,o);return this._enforceCapAfterInsert(),{docs:a}}})}async updateOne(e,t,i={}){await this._ctx.ensureConnected();let s=this._findRaw(e);if(!s)return null;let{save:n,session:r}=i,{docs:a}=await this._updateCore([s],e,t,{save:n,session:r});return X(a[0])}async updateMany(e,t,i={}){await this._ctx.ensureConnected();let s=this._findAllRaw(e);if(s.length===0)return[];let{save:n,session:r}=i,{docs:a}=await this._updateCore(s,e,t,{save:n,session:r});return a.map(X)}async _updateCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"update",beforeHook:"beforeUpdate",afterHook:"afterUpdate",hookPayload:{collection:this.name,filter:t,update:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:t,update:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{let a=this._changelogEnabled?e.map((h)=>structuredClone(h)):e.map(()=>null),l=e.map((h)=>this._prepareUpdatedDoc(h,i));this._assertUniqueCandidates(e,l),r();let o=new Set(e),c=new Map;for(let h=0;h<this._data.length;h++)if(o.has(this._data[h]))c.set(this._data[h],h);for(let h=0;h<e.length;h++)this._commitUpdatedDoc(e[h],l[h],c);return{docs:l,prevDocs:a}}})}applyUpdate(e,t){for(let i in t){if(Fr.has(i))continue;if(i==="_id"||i==="createdAt")continue;let s=t[i];if(Array.isArray(s))e[i]=s;else if(typeof s==="object"&&s!==null){let n=Object.keys(s);if(n.some((r)=>r.startsWith("$"))){for(let r of n)if(r==="$inc"&&typeof e[i]==="number")e[i]+=s[r];else if(r==="$push"){if(!Array.isArray(e[i]))e[i]=[];e[i].push(s[r])}}else e[i]=Ur(s)}else e[i]=s}if(e.updatedAt=new Date,this._versioning)e._version=(e._version??0)+1;return e}_prepareUpdatedDoc(e,t){let i=structuredClone(e),s=structuredClone(e);if(this.applyUpdate(s,t),!this._schema)return s;let n=Zs(s,this._schema,this._strict);if(!n.length)return s;switch(this._onSchemaError){case"throw":throw new C("ERR_SKALEX_VALIDATION_UPDATE",`Update validation failed on doc "${e._id}": ${n.join("; ")}`,{id:e._id,errors:n});case"strip":return this._stripCandidateToValid(s,i);default:return this._ctx.logger(`[${this.name}] Update validation warning: ${n.join("; ")}`,"warn"),s}}_stripCandidateToValid(e,t){let i=en(e,this._schema),s=structuredClone(t);for(let[n,r]of Object.entries(i)){if(n.startsWith("_"))continue;s[n]=r}if(s.updatedAt=e.updatedAt,this._versioning)s._version=e._version;return s}_commitUpdatedDoc(e,t,i){let s=i?i.get(e):this._data.indexOf(e);if(s===void 0||s===-1)throw new Pe("ERR_SKALEX_PERSISTENCE_DOC_MISSING",`Document "${e._id}" no longer exists in collection "${this.name}"`,{id:e._id,collection:this.name});this._data[s]=t,this._index.set(t._id,t),this._updateInIndex(e,t)}_assertUniqueCandidates(e,t){this._fieldIndex?.assertUniqueCandidates(e,t)}async upsert(e,t,i={}){if(await this._ctx.ensureConnected(),this._findRaw(e))return this.updateOne(e,t,i);return this.insertOne({...jc(e),...t},i)}async upsertMany(e,t,i={}){await this._ctx.ensureConnected();let{save:s,...n}=i,r=[];for(let a of e)r.push(await this.upsert({[t]:a[t]},a,{...n,save:!1}));return await this._saveIfNeeded(s),r}async restore(e,t={}){if(!this._softDelete)throw new et("ERR_SKALEX_QUERY_SOFT_DELETE_REQUIRED",`restore() requires softDelete on "${this.name}"`,{collection:this.name});await this._ctx.ensureConnected();let{save:i,session:s}=t,n=this._findRaw(e,{includeDeleted:!0});if(!n||!n._deletedAt)return null;let{docs:r}=await this._pipeline.execute({op:"restore",beforeHook:null,afterHook:null,hookPayload:null,save:i,session:s,mutate:async(a)=>{return a(),delete n._deletedAt,n.updatedAt=new Date,this._index.set(n._id,n),{docs:[n]}}});return X(r[0])}watch(e,t){if(typeof e==="function")t=e,e=null;if(t)return this._ctx.eventBus.on(this.name,(i)=>{if(!e||Y(i.doc,e))t(i)});return this._watchIterator(e)}_watchIterator(e){let t=[],i=null,s=!1,n=this._ctx.eventBus.on(this.name,(r)=>{if(e&&!Y(r.doc,e))return;if(i){let a=i;i=null,a({value:r,done:!1})}else t.push(r)});return{[Symbol.asyncIterator](){return this},next(){if(t.length>0)return Promise.resolve({value:t.shift(),done:!1});if(s)return Promise.resolve({value:void 0,done:!0});return new Promise((r)=>{i=r})},return(){if(s=!0,n(),i){let r=i;i=null,r({value:void 0,done:!0})}return Promise.resolve({value:void 0,done:!0})}}}async count(e={}){return await this._ctx.ensureConnected(),kc(this._findAllRaw(e))}async sum(e,t={}){return await this._ctx.ensureConnected(),Lc(this._findAllRaw(t),e)}async avg(e,t={}){return await this._ctx.ensureConnected(),Pc(this._findAllRaw(t),e)}async groupBy(e,t={}){return await this._ctx.ensureConnected(),Mc(this._findAllRaw(t),e)}async findOne(e,t={}){await this._ctx.ensureConnected();let{populate:i,select:s,includeDeleted:n=!1}=t,r=this._findRaw(e,{includeDeleted:n});if(!r)return null;let a=this._projectDoc(r,s);if(i)await this._populateDoc(a,r,i);return a}async find(e,t={}){await this._ctx.ensureConnected();let i=Date.now(),{populate:s,select:n,sort:r,page:a=1,limit:l,session:o,includeDeleted:c=!1}=t;await this._ctx.plugins.run("beforeFind",{collection:this.name,filter:e,options:t});let h=this._getCandidates(e),u=Nc(e,this._fieldIndex?this._fieldIndex.indexedFields:new Set),d=[];for(let f of h){if(this._softDelete&&f._deletedAt&&!c)continue;if(!Y(f,u))continue;let p=this._projectDoc(f,n);if(s)await this._populateDoc(p,f,s);d.push(p)}if(r){let f=Object.keys(r);d.sort((p,m)=>{for(let w of f){let x=r[w];if(p[w]<m[w])return-x;if(p[w]>m[w])return x}return 0})}let _;if(l){let f=d.length,p=Math.ceil(f/l),m=(a-1)*l;d=d.slice(m,m+l),_={page:a,totalDocs:f,totalPages:p}}return this._ctx.queryLog?.record({collection:this.name,op:"find",filter:e,duration:Date.now()-i,resultCount:d.length}),this._ctx.sessionStats.recordRead(o),await this._ctx.plugins.run("afterFind",{collection:this.name,filter:e,options:t,docs:d}),_?{docs:d,..._}:{docs:d}}async search(e,{filter:t,limit:i=10,minScore:s=0,session:n}={}){await this._ctx.ensureConnected();let r=Date.now();await this._ctx.plugins.run("beforeSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s}});let a=await this._ctx.embed(e),l=t?this._findAllRaw(t):this._data,o=[];for(let d of l){if(!d._vector)continue;let _=tn(a,d._vector);if(_>=s)o.push({doc:d,score:_})}o.sort((d,_)=>_.score-d.score);let c=o.slice(0,i);this._ctx.queryLog?.record({collection:this.name,op:"search",query:e,duration:Date.now()-r,resultCount:c.length}),this._ctx.sessionStats.recordRead(n);let h=c.map((d)=>X(d.doc)),u=c.map((d)=>d.score);return await this._ctx.plugins.run("afterSearch",{collection:this.name,query:e,options:{filter:t,limit:i,minScore:s},docs:h,scores:u}),{docs:h,scores:u}}async similar(e,{limit:t=10,minScore:i=0}={}){await this._ctx.ensureConnected();let s=this._index.get(e);if(!s||!s._vector)return{docs:[],scores:[]};let n=[];for(let a of this._data){if(a._id===e||!a._vector)continue;let l=tn(s._vector,a._vector);if(l>=i)n.push({doc:a,score:l})}n.sort((a,l)=>l.score-a.score);let r=n.slice(0,t);return{docs:r.map((a)=>X(a.doc)),scores:r.map((a)=>a.score)}}async deleteOne(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findRaw(e);if(!r)return null;let{docs:a}=await this._deleteCore("soft",[r],e,{save:i,session:s});return X(a[0])}let{docs:n}=await this._deleteCore("hard",null,e,{save:i,session:s});if(n.length===0)return null;return X(n[0])}async deleteMany(e,t={}){await this._ctx.ensureConnected();let{save:i,session:s}=t;if(this._softDelete){let r=this._findAllRaw(e);if(r.length===0)return[];let{docs:a}=await this._deleteCore("soft",r,e,{save:i,session:s});return a.map(X)}let{docs:n}=await this._deleteCore("hardMany",null,e,{save:i,session:s});return n.map(X)}async _deleteCore(e,t,i,{save:s,session:n}){return this._pipeline.execute({op:"delete",beforeHook:"beforeDelete",afterHook:"afterDelete",hookPayload:{collection:this.name,filter:i},save:s,session:n,afterHookPayload:(r)=>({collection:this.name,filter:i,result:r.length===1?r[0]:r}),mutate:async(r)=>{if(r(),e==="soft"){let o=new Date;for(let c of t)c._deletedAt=o,c.updatedAt=o,this._index.set(c._id,c);return{docs:t}}if(e==="hard"){let o=this._findIndex(i);if(o===-1)return{docs:[]};let c=this._data.splice(o,1)[0];return this._index.delete(c._id),this._removeFromIndex(c),{docs:[c]}}let a=[],l=[];for(let o of this._data)if(Y(o,i))a.push(o),this._index.delete(o._id),this._removeFromIndex(o);else l.push(o);return this._data=l,{docs:a}}})}async export(e={},t={}){let{dir:i,name:s,format:n="json"}=t;try{let r=this._data.filter((h)=>Y(h,e));if(r.length===0)throw new et("ERR_SKALEX_QUERY_EXPORT_EMPTY",`export(): no documents matched the filter in "${this.name}"`,{collection:this.name});let a;if(n==="json")a=JSON.stringify(r,null,2);else{let h=(_)=>{if(_==null)return"";let f=typeof _==="object"?JSON.stringify(_):String(_);return f.includes(",")||f.includes('"')||f.includes(`
92
92
  `)||f.includes("\r")?`"${f.replace(/"/g,'""')}"`:f},u=Object.keys(r[0]).map(h).join(","),d=r.map((_)=>Object.values(_).map(h).join(","));a=[u,...d].join(`
93
- `)}if(typeof this._ctx.fs.writeRaw!=="function")throw new pe("ERR_SKALEX_ADAPTER_NO_RAW_WRITE","export() requires a file-system adapter (FsAdapter). The current adapter does not support raw file writes.");let l=i||`${this._ctx.dataDirectory}/exports`,o=`${s||this.name}.${n}`,c=this._ctx.fs.join(l,o);this._ctx.fs.ensureDir(l),await this._ctx.fs.writeRaw(c,a)}catch(r){throw this._ctx.logger(`Error exporting "${this.name}": ${r.message}`,"error"),r}}_txSnapshotIfNeeded(){let e=this._ctx.txManager;if(!e.active)return;if(this._activeTxId!==e.context?.id)return;e.snapshotIfNeeded(this.name,this._store,(t)=>this._ctx.snapshotCollection(t))}async _saveIfNeeded(e){let t=this._ctx.txManager;if(t.active&&this._activeTxId===t.context?.id)return;if(e??this._ctx.autoSave)await this._ctx.saveCollection(this.name)}_applyValidation(e){if(!this._schema)return e;let t=Zs(e,this._schema,this._strict);if(!t.length)return e;switch(this._onSchemaError){case"warn":return this._ctx.logger(`[${this.name}] Validation warning: ${t.join("; ")}`,"warn"),e;case"strip":return en(e,this._schema);default:throw new C("ERR_SKALEX_VALIDATION_FAILED",`Validation failed: ${t.join("; ")}`,{errors:t})}}_enforceCapAfterInsert(){let e=this._maxDocs;if(!e||this._data.length<=e)return;let t=this._data.splice(0,this._data.length-e);for(let i of t)this._index.delete(i._id),this._removeFromIndex(i)}_findRaw(e,{includeDeleted:t=!1}={}){if(typeof e==="function"){for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(e(i))return i}return null}if(e._id){let i=this._index.get(e._id)||null;if(!i)return null;if(this._softDelete&&i._deletedAt&&!t)return null;if(Object.keys(e).length>1)return Y(i,e)?i:null;return i}if(this._fieldIndex)for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null){let n=this._fieldIndex._lookupIterable(i,s);if(n!==null){for(let r of n){if(this._softDelete&&r._deletedAt&&!t)continue;if(Y(r,e))return r}return null}}}for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(Y(i,e))return i}return null}_findAllRaw(e,{includeDeleted:t=!1}={}){if(e&&typeof e!=="function"&&e._id){let s=this._index.get(e._id);if(!s)return[];if(this._softDelete&&s._deletedAt&&!t)return[];return Y(s,e)?[s]:[]}let i=[];for(let s of this._getCandidates(e)){if(this._softDelete&&s._deletedAt&&!t)continue;if(Y(s,e))i.push(s)}return i}_getCandidates(e){if(!this._fieldIndex)return this._data;if(this._fieldIndex._compoundIndexes.size>0){let t={};for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null)t[i]=s}if(Object.keys(t).length>=2){let i=this._fieldIndex.lookupCompound(t);if(i!==null)return i}}for(let t in e){if(t==="$or"||t==="$and"||t==="$not")continue;let i=e[t];if(typeof i!=="object"||i===null){let s=this._fieldIndex._lookupIterable(t,i);if(s!==null)return s}}return this._data}_findIndex(e){for(let t=0;t<this._data.length;t++)if(Y(this._data[t],e))return t;return-1}_addToIndex(e){if(this._fieldIndex)this._fieldIndex.add(e)}_removeFromIndex(e){if(this._fieldIndex)this._fieldIndex.remove(e)}_updateInIndex(e,t){if(this._fieldIndex)this._fieldIndex.update(e,t)}async _buildDoc(e,{ttl:t,embed:i}={}){let s={...e,_id:e._id??(this._ctx.idGenerator??bc)(),createdAt:new Date,updatedAt:new Date},n=t??this._defaultTtl;if(n)s._expiresAt=$c(n);let r=i??this._defaultEmbed;if(r){let a=typeof r==="function"?r(s):s[r];s._vector=await this._ctx.embed(String(a))}if(this._versioning)s._version=1;return s}_projectDoc(e,t){if(t){let s={};for(let n of t){if(n==="_vector")continue;s[n]=e[n]}return s}let i={...e};return delete i._vector,i}async _populateDoc(e,t,i){for(let s of i){let n=await this._ctx.getCollection(s).findOne({_id:t[s]});if(n)e[s]=n}}}class Vi{async read(e){throw Error("StorageAdapter.read() not implemented")}async write(e,t){throw Error("StorageAdapter.write() not implemented")}async delete(e){throw Error("StorageAdapter.delete() not implemented")}async list(){throw Error("StorageAdapter.list() not implemented")}async writeAll(e){for(let{name:t,data:i}of e)await this.write(t,i)}}class Br extends Vi{constructor({dir:e,format:t="gz"}){super();this.dir=He.resolve(e),this.format=t,this._ensureDir(this.dir)}_ensureDir(e){if(!F.existsSync(e))F.mkdirSync(e,{recursive:!0})}_filePath(e){return He.join(this.dir,`${e}.${this.format}`)}async read(e){let t=this._filePath(e);try{let i=await F.promises.readFile(t);if(this.format==="gz")i=li.inflateSync(i);return i.toString("utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async write(e,t){let i=this._filePath(e),s=He.join(this.dir,`${e}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let n=li.deflateSync(t);await F.promises.writeFile(s,n)}else await F.promises.writeFile(s,t,"utf8");await F.promises.rename(s,i)}async writeAll(e){let t=[];try{for(let{name:i,data:s}of e){let n=this._filePath(i),r=He.join(this.dir,`${i}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let a=li.deflateSync(s);await F.promises.writeFile(r,a)}else await F.promises.writeFile(r,s,"utf8");t.push({tmp:r,fp:n})}for(let{tmp:i,fp:s}of t)await F.promises.rename(i,s)}catch(i){for(let{tmp:s}of t)try{await F.promises.unlink(s)}catch{}throw i}}async delete(e){let t=this._filePath(e);try{await F.promises.unlink(t)}catch(i){if(i.code!=="ENOENT")throw i}}async list(){try{let e=await F.promises.readdir(this.dir),t=`.${this.format}`;return e.filter((i)=>i.endsWith(t)&&!i.includes(".tmp.")).map((i)=>i.slice(0,-t.length))}catch(e){if(e.code==="ENOENT")return[];throw e}}join(...e){return He.join(...e)}ensureDir(e){this._ensureDir(e)}async writeRaw(e,t){this._ensureDir(He.dirname(e)),await F.promises.writeFile(e,t,"utf8")}async readRaw(e){return F.promises.readFile(He.resolve(e),"utf8")}}class Xr{constructor(){this._migrations=[]}add(e){let{version:t,up:i}=e;if(typeof t!=="number"||t<1)throw new C("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version must be a positive integer, got ${t}`,{version:t});if(typeof i!=="function")throw new C("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version ${t} must have an "up" function`,{version:t});if(this._migrations.some((s)=>s.version===t))throw new C("ERR_SKALEX_VALIDATION_MIGRATION_DUPLICATE",`Migration version ${t} is already registered`,{version:t});this._migrations.push({...e}),this._migrations.sort((s,n)=>s.version-n.version)}async run(e,t=[]){let i=new Set(t),s=this._migrations.filter((n)=>!i.has(n.version));for(let n of s){let r=e(n.version);await n.up(r),i.add(n.version)}return[...i].sort((n,r)=>n-r)}status(e=[]){let t=new Set(e),i=this._migrations.map((s)=>s.version).filter((s)=>!t.has(s));return{current:e.length?Math.max(...e):0,applied:[...t].sort((s,n)=>s-n),pending:i}}}var sn={[Symbol.iterator](){return{next(){return{done:!0}}}},size:0};function nn(e){return{[Symbol.iterator](){return e[Symbol.iterator]()},get size(){return e.size}}}function pi(e){return e.map((t)=>{if(t===null||t===void 0)return"\x00";if(typeof t==="boolean")return t?"\x01T":"\x01F";if(typeof t==="number")return`\x02${t}`;return`\x03${String(t)}`}).join("\x1F")}class Lt{constructor(e=[],t=[]){this._fields=new Set,this._compoundFields=[];for(let i of e)if(Array.isArray(i)){for(let s of i)this._validateFieldName(s);this._compoundFields.push(i)}else this._validateFieldName(i),this._fields.add(i);for(let i of t)this._validateFieldName(i);this._uniqueFields=new Set(t),this._indexedFields=new Set([...this._fields,...this._uniqueFields]),this._fieldIndexes=new Map,this._uniqueIndexes=new Map;for(let i of this._fields)this._fieldIndexes.set(i,new Map);for(let i of this._uniqueFields)if(this._uniqueIndexes.set(i,new Map),!this._fieldIndexes.has(i))this._fieldIndexes.set(i,new Map);this._compoundIndexes=new Map;for(let i of this._compoundFields)this._compoundIndexes.set(i.join("\x00"),{fields:i,map:new Map})}get indexedFields(){return this._indexedFields}buildFromData(e){for(let[,t]of this._fieldIndexes)t.clear();for(let[,t]of this._uniqueIndexes)t.clear();for(let[,t]of this._compoundIndexes)t.map.clear();for(let t of e)this._indexDoc(t)}add(e){this._checkUnique(e,null),this._indexDoc(e)}remove(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){let n=i.get(s);if(n){if(n.delete(e),n.size===0)i.delete(s)}}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.delete(s)}for(let[,t]of this._compoundIndexes){let i=pi(t.fields.map((n)=>e[n])),s=t.map.get(i);if(s){if(s.delete(e),s.size===0)t.map.delete(i)}}}update(e,t){this._checkUnique(t,e),this.remove(e);try{this._indexDoc(t)}catch(i){try{this._indexDoc(e)}catch{}throw i}}lookup(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?[...s]:[]}_lookupIterable(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?nn(s):sn}lookupCompound(e){let t=Object.keys(e).sort();for(let[,i]of this._compoundIndexes){let s=[...i.fields].sort();if(s.length!==t.length)continue;if(s.every((n,r)=>n===t[r])){let n=pi(i.fields.map((a)=>e[a])),r=i.map.get(n);return r?nn(r):sn}}return null}isUniqueTaken(e,t){let i=this._uniqueIndexes.get(e);if(!i)return!1;return i.has(t)}assertUniqueCandidates(e,t){if(this._uniqueFields.size===0)return;let i=new Set(e.map((s)=>s._id));for(let s of this._uniqueFields){let n=new Set,r=this._uniqueIndexes.get(s);if(r){for(let[l,o]of r.entries())if(!i.has(o._id))n.add(l)}let a=new Map;for(let l=0;l<t.length;l++){let o=t[l][s];if(o===void 0)continue;if(n.has(o))throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});let c=a.get(o);if(c&&c!==e[l]._id)throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});a.set(o,e[l]._id)}}}assertUniqueBatch(e){if(this._uniqueFields.size===0)return;for(let t of this._uniqueFields){let i=this._uniqueIndexes.get(t),s=new Set;for(let n of e){let r=n[t];if(r===void 0)continue;if(i&&i.has(r))throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${t}" value "${r}" already exists`,{field:t,value:r});if(s.has(r))throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: duplicate "${t}" value "${r}" within batch`,{field:t,value:r});s.add(r)}}}_validateFieldName(e){if(e.includes("."))throw new C("ERR_SKALEX_VALIDATION_INDEX_DOT_PATH",`Index fields cannot use dot-notation: "${e}". Use a flat field name.`,{field:e})}_indexDoc(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){if(!i.has(s))i.set(s,new Set);i.get(s).add(e)}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.set(s,e)}for(let[,t]of this._compoundIndexes){for(let s of t.fields){let n=e[s];if(n!==void 0&&n!==null&&typeof n==="object")throw new C("ERR_SKALEX_VALIDATION_COMPOUND_INDEX",`Compound index field "${s}" must be a scalar value (string, number, or boolean), got ${Array.isArray(n)?"array":typeof n}`,{field:s})}let i=pi(t.fields.map((s)=>e[s]));if(!t.map.has(i))t.map.set(i,new Set);t.map.get(i).add(e)}}_checkUnique(e,t){for(let i of this._uniqueFields){let s=e[i];if(s===void 0)continue;let n=this._uniqueIndexes.get(i);if(!n)continue;let r=n.get(s);if(r&&r._id!==t?._id)throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${i}" value "${s}" already exists`,{field:i,value:s})}}}var Nt="_flush",$t="migrations";class Hr{constructor({adapter:e,serializer:t,deserializer:i,logger:s,debug:n=!1,lenientLoad:r=!1}){this._adapter=e,this._serializer=t,this._deserializer=i,this._logger=s,this._debug=n,this._lenientLoad=r,this._saveLock=Promise.resolve()}_withSaveLock(e){let t=this._saveLock.then(e);return this._saveLock=t.catch(()=>{}),t}async loadAll(e,{parseSchema:t,buildIndex:i,IndexEngine:s}){try{let n=await this._adapter.list();await Promise.all(n.map(async(r)=>{try{let a=await this._adapter.read(r);if(!a)return;let l=this._deserializer(a),{collectionName:o,data:c}=l;if(!o)return;let h=e[o],u=h?.rawSchema??l.rawSchema??null,d=h?.schema??(u?t(u):null),_=h?.changelog??l.changelog??!1,f=h?.softDelete??l.softDelete??!1,p=h?.versioning??l.versioning??!1,m=h?.strict??l.strict??!1,w=h?.onSchemaError??l.onSchemaError??"throw",x=h?.defaultTtl??l.defaultTtl??null,R=h?.defaultEmbed??l.defaultEmbed??null,E=h?.maxDocs??l.maxDocs??null,A=h?h.fieldIndex:null;if(!A&&d?.uniqueFields?.length)A=new s([],d.uniqueFields);let Ue=i(c,"_id");if(A)A.buildFromData(c);e[o]={collectionName:o,data:c,index:Ue,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:d,rawSchema:u,fieldIndex:A,changelog:_,softDelete:f,versioning:p,strict:m,onSchemaError:w,defaultTtl:x,defaultEmbed:R,maxDocs:E}}catch(a){if(a.code==="ENOENT")return;if(this._lenientLoad){this._logger(`WARNING: Could not load collection "${r}": ${a.message}. Collection will be empty.`,"error");return}throw new Pe("ERR_SKALEX_PERSISTENCE_CORRUPT",`Failed to load collection "${r}": ${a.message}`,{collection:r})}})),this._detectIncompleteFlush(e),await this._cleanOrphanTempFiles()}catch(n){if(n.code!=="ENOENT")throw this._logger(`Error loading data: ${n}`,"error"),n}}async save(e,t){if(t)await this._saveOne(e,t);else await Promise.all(Object.keys(e).map((i)=>this._saveOne(e,i)))}async saveDirty(e){let t=Object.keys(e).filter((i)=>e[i]._dirty);if(t.length===0)return;await Promise.all(t.map((i)=>this._saveOne(e,i)))}saveAtomic(e,t){return this._withSaveLock(async()=>{if(t.length===0)return;this._writeFlushSentinel(e,t);let i=new Set(t);i.add("_meta");let s=[...i].filter((n)=>e[n]).map((n)=>({name:n,data:this._serializeCollection(e[n])}));try{await this._adapter.writeAll(s)}catch(n){throw new Pe("ERR_SKALEX_PERSISTENCE_FLUSH_FAILED",`Batch save failed during writeAll: ${n.message}`,{collections:t})}for(let n of t)if(e[n])e[n]._dirty=!1;try{this._clearFlushSentinel(e),await this._adapter.write("_meta",this._serializeCollection(e._meta))}catch(n){this._logger(`WARNING: Batch data committed but sentinel clear failed: ${n.message}. Next load will report an incomplete flush (false positive).`,"error")}})}markDirty(e,t){let i=e[t];if(i)i._dirty=!0}_serializeCollection(e){let t={collectionName:e.collectionName,data:e.data};if(e.rawSchema)t.rawSchema=e.rawSchema;if(e.changelog)t.changelog=e.changelog;if(e.softDelete)t.softDelete=e.softDelete;if(e.versioning)t.versioning=e.versioning;if(e.strict)t.strict=e.strict;if(e.onSchemaError!=="throw")t.onSchemaError=e.onSchemaError;if(e.defaultTtl)t.defaultTtl=e.defaultTtl;if(e.defaultEmbed)t.defaultEmbed=e.defaultEmbed;if(e.maxDocs)t.maxDocs=e.maxDocs;return this._serializer(t)}async _saveOne(e,t){let i=e[t];if(!i)return;if(i.isSaving)return i._pendingSave=!0,new Promise((s,n)=>{(i._saveWaiters??=[]).push({resolve:s,reject:n})});i.isSaving=!0,i._pendingSave=!1;try{await this._writeCollection(t,i);while(i._pendingSave)i._pendingSave=!1,await this._writeCollection(t,i);this._resolveSaveWaiters(i)}catch(s){throw this._rejectSaveWaiters(i,s),s}finally{i.isSaving=!1}}async _writeCollection(e,t){try{await this._adapter.write(e,this._serializeCollection(t)),t._dirty=!1}catch(i){throw this._logger(`Error saving "${e}": ${i.message}`,"error"),i}}_resolveSaveWaiters(e){let t=e._saveWaiters?.splice(0)??[];for(let i of t)i.resolve()}_rejectSaveWaiters(e,t){let i=e._saveWaiters?.splice(0)??[];for(let s of i)s.reject(t)}_writeFlushSentinel(e,t){let i=this._getOrCreateMeta(e);i[Nt]={startedAt:new Date().toISOString(),collections:t,completedAt:null}}_clearFlushSentinel(e){let t=this._getOrCreateMeta(e);if(t[Nt])t[Nt].completedAt=new Date().toISOString()}_detectIncompleteFlush(e){let t=e._meta;if(!t)return;let i=t.index.get($t);if(!i)return;let s=i[Nt];if(!s)return;if(s.startedAt&&!s.completedAt)this._logger(`WARNING: Incomplete flush detected (started ${s.startedAt}, collections: ${s.collections?.join(", ")}). Data may be inconsistent.`,"error")}async _cleanOrphanTempFiles(){if(typeof this._adapter.join!=="function")return;if(typeof this._adapter.list!=="function")return;try{let e=await import("fs"),t=await import("path"),i=this._adapter.dir;if(!i)return;let s=(await e.default.promises.readdir(i)).filter((n)=>n.includes(".tmp."));for(let n of s){let r=t.default.join(i,n);try{await e.default.promises.unlink(r),this._log(`Cleaned orphan temp file: ${n}`)}catch{}}}catch{}}_getOrCreateMeta(e){if(!e._meta)e._meta={collectionName:"_meta",data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:null,rawSchema:null,fieldIndex:null,changelog:!1,softDelete:!1,versioning:!1,strict:!1,onSchemaError:"throw",defaultTtl:null,defaultEmbed:null,maxDocs:null};let t=e._meta,i=t.index.get($t);if(!i)i={_id:$t},t.data.push(i),t.index.set($t,i);return i}_log(e){if(this._debug)this._logger(e,"info")}}var Mc=0;class Vr{constructor(){this._txLock=Promise.resolve(),this._ctx=null,this._abortedIds=new Set}get active(){return this._ctx!==null&&!this._ctx.aborted}get context(){return this._ctx}async run(e,t,{timeout:i=0}={}){let s=async()=>{await t._ensureConnected();let r=new Set(Object.keys(t.collections)),a={id:++Mc,startedAt:Date.now(),aborted:!1,preExisting:r,touchedCollections:new Set,snapshots:new Map,deferredEffects:[],timeout:i};this._ctx=a;let l=null,o=i>0?new Promise((u,d)=>{l=setTimeout(()=>{a.aborted=!0,d(new we("ERR_SKALEX_TX_TIMEOUT",`Transaction ${a.id} timed out after ${i}ms`))},i)}):null,c=this,h=new Proxy(t,{get(u,d){if(d==="_txId")return a.id;if(a!==c._ctx)throw new we("ERR_SKALEX_TX_STALE_PROXY",`Transaction ${a.id} has ended. This proxy is no longer usable.`);if(d==="collections")throw new we("ERR_SKALEX_TX_DIRECT_ACCESS","Direct access to db.collections inside transaction() is not covered by rollback. Use the collection API (db.useCollection) instead.");if(d==="useCollection")return(f)=>{let p=u.useCollection(f);return p._activeTxId=a.id,p};let _=Reflect.get(u,d);return typeof _==="function"?_.bind(u):_}});try{let u=e(h),d=o?await Promise.race([u,o]):await u;if(a.aborted)throw new we("ERR_SKALEX_TX_ABORTED",`Transaction ${a.id} was aborted`);let _=[...a.touchedCollections];if(_.length>0)await t._persistence.saveAtomic(t.collections,_);for(let f of a.deferredEffects)await f();return d}catch(u){for(let[d,_]of a.snapshots)if(a.preExisting.has(d)){if(t._applySnapshot(d,_),t.collections[d])t.collections[d]._dirty=_._dirty}for(let d in t.collections)if(!a.preExisting.has(d))delete t.collections[d],delete t._collectionInstances[d];throw u}finally{if(l)clearTimeout(l);if(a.aborted)this._abortedIds.add(a.id);this._ctx=null;for(let u in t._collectionInstances){let d=t._collectionInstances[u];if(d._createdInTxId===a.id)d._createdInTxId=null;if(d._activeTxId===a.id)d._activeTxId=null}}},n=this._txLock.then(s);return this._txLock=n.catch(()=>{}),n}snapshotIfNeeded(e,t,i){let s=this._ctx;if(!s)return;if(this._assertCtxNotAborted(s),!s.snapshots.has(e)){let n=i(t);n._dirty=t._dirty??!1,s.snapshots.set(e,n)}s.touchedCollections.add(e)}assertNotAborted(){let e=this._ctx;if(e)this._assertCtxNotAborted(e)}_assertCtxNotAborted(e){if(e.aborted)throw new we("ERR_SKALEX_TX_ABORTED",`Transaction ${e.id} was aborted. No further mutations allowed.`)}defer(e){if(this._ctx)return this._ctx.deferredEffects.push(e),!0;return!1}}class Jr{constructor(e){this._CollectionClass=e,this.stores={},this._instances={}}get(e,t){if(this._instances[e])return this._instances[e];if(!this.stores[e])this.createStore(e);let i=new this._CollectionClass(this.stores[e],t);return this._instances[e]=i,i}create(e,t={},i){this.createStore(e,t);let s=new this._CollectionClass(this.stores[e],i);return this._instances[e]=s,s}createStore(e,{schema:t,indexes:i=[],changelog:s=!1,softDelete:n=!1,versioning:r=!1,strict:a=!1,onSchemaError:l="throw",defaultTtl:o=null,defaultEmbed:c=null,maxDocs:h=null}={}){let u=null,d=null;if(t){u=qr(t);let _=u.uniqueFields;if(i.length||_.length)d=new Lt(i,_)}else if(i.length)d=new Lt(i,[]);this.stores[e]={collectionName:e,data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:u,rawSchema:t||null,fieldIndex:d,changelog:s,softDelete:n,versioning:r,strict:a,onSchemaError:l,defaultTtl:o,defaultEmbed:c,maxDocs:h}}rename(e,t){if(!this.stores[e])throw new Pe("ERR_SKALEX_PERSISTENCE_COLLECTION_NOT_FOUND",`Collection "${e}" not found`,{collection:e});if(this.stores[t])throw new Pe("ERR_SKALEX_PERSISTENCE_COLLECTION_EXISTS",`Collection "${t}" already exists`,{collection:t});let i=this.stores[e];if(i.collectionName=t,this.stores[t]=i,delete this.stores[e],this._instances[e]){let s=this._instances[e];s.name=t,this._instances[t]=s,delete this._instances[e]}}buildIndex(e,t){let i=new Map;for(let s of e)i.set(s[t],s);return i}inspect(e){if(e){let i=this.stores[e];if(!i)return null;return{name:e,count:i.data.length,schema:i.schema?Object.fromEntries(i.schema.fields):null,indexes:i.fieldIndex?[...i.fieldIndex.indexedFields]:[],softDelete:i.softDelete??!1,versioning:i.versioning??!1,strict:i.strict??!1,onSchemaError:i.onSchemaError??"throw",maxDocs:i.maxDocs??null}}let t={};for(let i in this.stores)t[i]=this.inspect(i);return t}dump(){let e={};for(let t in this.stores)if(!t.startsWith("_"))e[t]=structuredClone(this.stores[t].data);return e}schema(e){let t=this.stores[e];if(!t)return null;if(t.schema)return Object.fromEntries([...t.schema.fields.entries()].map(([i,s])=>[i,s.type]));if(t.data.length>0)return Oc(t.data[0]);return null}stats(e){let t=(i)=>{let s=this.stores[i];if(!s)return null;let n=s.data.length,r=0;for(let a of s.data)try{r+=JSON.stringify(a).length}catch(l){}return{collection:i,count:n,estimatedSize:r,avgDocSize:n>0?Math.round(r/n):0}};if(e)return t(e);return Object.keys(this.stores).map(t)}clear(){this.stores={},this._instances={}}}class Ji{async embed(e){throw Error("EmbeddingAdapter.embed() not implemented")}}var de=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Yr extends Ji{constructor({apiKey:e=de("OPENAI_API_KEY"),model:t=de("OPENAI_EMBED_MODEL")??"text-embedding-3-small",baseUrl:i=de("OPENAI_EMBED_BASE_URL")??"https://api.openai.com/v1/embeddings",dimensions:s=de("OPENAI_EMBED_DIMENSIONS")!=null?Number(de("OPENAI_EMBED_DIMENSIONS")):void 0,organization:n=de("OPENAI_ORGANIZATION")??void 0,timeout:r=de("OPENAI_EMBED_TIMEOUT")!=null?Number(de("OPENAI_EMBED_TIMEOUT")):void 0,retries:a=Number(de("OPENAI_EMBED_RETRIES")??0),retryDelay:l=Number(de("OPENAI_EMBED_RETRY_DELAY")??1000),headers:o={},fetch:c=globalThis.fetch}={}){super();if(!e)throw Error("OpenAIEmbeddingAdapter requires an apiKey");this.apiKey=e,this.model=t,this.baseUrl=i,this.dimensions=s,this.organization=n,this.timeout=r,this.retries=a,this.retryDelay=l,this.headers=o,this._fetch=c}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(this.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...this.organization&&{"OpenAI-Organization":this.organization},...this.headers},body:JSON.stringify({input:e,model:this.model,...this.dimensions!==void 0&&{dimensions:this.dimensions}}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`OpenAI embedding API error ${r.status}: ${a}`)}return(await r.json()).data[0].embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}var ot=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Wr extends Ji{constructor({model:e=ot("OLLAMA_EMBED_MODEL")??"nomic-embed-text",host:t=ot("OLLAMA_HOST")??"http://localhost:11434",timeout:i=ot("OLLAMA_EMBED_TIMEOUT")!=null?Number(ot("OLLAMA_EMBED_TIMEOUT")):void 0,retries:s=Number(ot("OLLAMA_EMBED_RETRIES")??0),retryDelay:n=Number(ot("OLLAMA_EMBED_RETRY_DELAY")??1000),headers:r={},fetch:a=globalThis.fetch}={}){super();this.model=e,this.host=t,this.timeout=i,this.retries=s,this.retryDelay=n,this.headers=r,this._fetch=a}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({model:this.model,prompt:e}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama embedding API error ${r.status}: ${a}`)}return(await r.json()).embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}class zt{async generate(e,t){throw Error("LLMAdapter.generate() not implemented")}async summarize(e){throw Error("LLMAdapter.summarize() not implemented")}}var Yi=`You are a database query assistant. Convert the user's natural language request into a JSON filter object for a document database.
93
+ `)}if(typeof this._ctx.fs.writeRaw!=="function")throw new pe("ERR_SKALEX_ADAPTER_NO_RAW_WRITE","export() requires a file-system adapter (FsAdapter). The current adapter does not support raw file writes.");let l=i||`${this._ctx.dataDirectory}/exports`,o=`${s||this.name}.${n}`,c=this._ctx.fs.join(l,o);this._ctx.fs.ensureDir(l),await this._ctx.fs.writeRaw(c,a)}catch(r){throw this._ctx.logger(`Error exporting "${this.name}": ${r.message}`,"error"),r}}_txSnapshotIfNeeded(){let e=this._ctx.txManager;if(!e.active)return;if(this._activeTxId!==e.context?.id)return;e.snapshotIfNeeded(this.name,this._store,(t)=>this._ctx.snapshotCollection(t))}async _saveIfNeeded(e){let t=this._ctx.txManager;if(t.active&&this._activeTxId===t.context?.id)return;if(e??this._ctx.autoSave)await this._ctx.saveCollection(this.name)}_applyValidation(e){if(!this._schema)return e;let t=Zs(e,this._schema,this._strict);if(!t.length)return e;switch(this._onSchemaError){case"warn":return this._ctx.logger(`[${this.name}] Validation warning: ${t.join("; ")}`,"warn"),e;case"strip":return en(e,this._schema);default:throw new C("ERR_SKALEX_VALIDATION_FAILED",`Validation failed: ${t.join("; ")}`,{errors:t})}}_enforceCapAfterInsert(){let e=this._maxDocs;if(!e||this._data.length<=e)return;let t=this._data.splice(0,this._data.length-e);for(let i of t)this._index.delete(i._id),this._removeFromIndex(i)}_findRaw(e,{includeDeleted:t=!1}={}){if(typeof e==="function"){for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(e(i))return i}return null}if(e._id){let i=this._index.get(e._id)||null;if(!i)return null;if(this._softDelete&&i._deletedAt&&!t)return null;if(Object.keys(e).length>1)return Y(i,e)?i:null;return i}if(this._fieldIndex)for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null){let n=this._fieldIndex._lookupIterable(i,s);if(n!==null){for(let r of n){if(this._softDelete&&r._deletedAt&&!t)continue;if(Y(r,e))return r}return null}}}for(let i of this._data){if(this._softDelete&&i._deletedAt&&!t)continue;if(Y(i,e))return i}return null}_findAllRaw(e,{includeDeleted:t=!1}={}){if(e&&typeof e!=="function"&&e._id){let s=this._index.get(e._id);if(!s)return[];if(this._softDelete&&s._deletedAt&&!t)return[];return Y(s,e)?[s]:[]}let i=[];for(let s of this._getCandidates(e)){if(this._softDelete&&s._deletedAt&&!t)continue;if(Y(s,e))i.push(s)}return i}_getCandidates(e){if(!this._fieldIndex)return this._data;if(this._fieldIndex._compoundIndexes.size>0){let t={};for(let i in e){if(i==="$or"||i==="$and"||i==="$not")continue;let s=e[i];if(typeof s!=="object"||s===null)t[i]=s}if(Object.keys(t).length>=2){let i=this._fieldIndex.lookupCompound(t);if(i!==null)return i}}for(let t in e){if(t==="$or"||t==="$and"||t==="$not")continue;let i=e[t];if(typeof i!=="object"||i===null){let s=this._fieldIndex._lookupIterable(t,i);if(s!==null)return s}}return this._data}_findIndex(e){for(let t=0;t<this._data.length;t++)if(Y(this._data[t],e))return t;return-1}_addToIndex(e){if(this._fieldIndex)this._fieldIndex.add(e)}_removeFromIndex(e){if(this._fieldIndex)this._fieldIndex.remove(e)}_updateInIndex(e,t){if(this._fieldIndex)this._fieldIndex.update(e,t)}async _buildDoc(e,{ttl:t,embed:i}={}){let s={...e,_id:e._id??(this._ctx.idGenerator??Oc)(),createdAt:new Date,updatedAt:new Date},n=t??this._defaultTtl;if(n)s._expiresAt=Cc(n);let r=i??this._defaultEmbed;if(r){let a=typeof r==="function"?r(s):s[r];s._vector=await this._ctx.embed(String(a))}if(this._versioning)s._version=1;return s}_projectDoc(e,t){if(t){let s={};for(let n of t){if(n==="_vector")continue;s[n]=e[n]}return s}let i={...e};return delete i._vector,i}async _populateDoc(e,t,i){for(let s of i){let n=await this._ctx.getCollection(s).findOne({_id:t[s]});if(n)e[s]=n}}}class Vi{async read(e){throw Error("StorageAdapter.read() not implemented")}async write(e,t){throw Error("StorageAdapter.write() not implemented")}async delete(e){throw Error("StorageAdapter.delete() not implemented")}async list(){throw Error("StorageAdapter.list() not implemented")}async writeAll(e){for(let{name:t,data:i}of e)await this.write(t,i)}}class Br extends Vi{constructor({dir:e,format:t="gz"}){super();this.dir=He.resolve(e),this.format=t,this._ensureDir(this.dir)}_ensureDir(e){if(!F.existsSync(e))F.mkdirSync(e,{recursive:!0})}_filePath(e){return He.join(this.dir,`${e}.${this.format}`)}async read(e){let t=this._filePath(e);try{let i=await F.promises.readFile(t);if(this.format==="gz")i=li.inflateSync(i);return i.toString("utf8")}catch(i){if(i.code==="ENOENT")return null;throw i}}async write(e,t){let i=this._filePath(e),s=He.join(this.dir,`${e}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let n=li.deflateSync(t);await F.promises.writeFile(s,n)}else await F.promises.writeFile(s,t,"utf8");await F.promises.rename(s,i)}async writeAll(e){let t=[];try{for(let{name:i,data:s}of e){let n=this._filePath(i),r=He.join(this.dir,`${i}_${globalThis.crypto.randomUUID()}.tmp.${this.format}`);if(this.format==="gz"){let a=li.deflateSync(s);await F.promises.writeFile(r,a)}else await F.promises.writeFile(r,s,"utf8");t.push({tmp:r,fp:n})}for(let{tmp:i,fp:s}of t)await F.promises.rename(i,s)}catch(i){for(let{tmp:s}of t)try{await F.promises.unlink(s)}catch{}throw i}}async delete(e){let t=this._filePath(e);try{await F.promises.unlink(t)}catch(i){if(i.code!=="ENOENT")throw i}}async list(){try{let e=await F.promises.readdir(this.dir),t=`.${this.format}`;return e.filter((i)=>i.endsWith(t)&&!i.includes(".tmp.")).map((i)=>i.slice(0,-t.length))}catch(e){if(e.code==="ENOENT")return[];throw e}}join(...e){return He.join(...e)}ensureDir(e){this._ensureDir(e)}async writeRaw(e,t){this._ensureDir(He.dirname(e)),await F.promises.writeFile(e,t,"utf8")}async readRaw(e){return F.promises.readFile(He.resolve(e),"utf8")}}class Xr{constructor(){this._migrations=[]}add(e){let{version:t,up:i}=e;if(typeof t!=="number"||t<1)throw new C("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version must be a positive integer, got ${t}`,{version:t});if(typeof i!=="function")throw new C("ERR_SKALEX_VALIDATION_MIGRATION",`Migration version ${t} must have an "up" function`,{version:t});if(this._migrations.some((s)=>s.version===t))throw new C("ERR_SKALEX_VALIDATION_MIGRATION_DUPLICATE",`Migration version ${t} is already registered`,{version:t});this._migrations.push({...e}),this._migrations.sort((s,n)=>s.version-n.version)}async run(e,t=[]){let i=new Set(t),s=this._migrations.filter((n)=>!i.has(n.version));for(let n of s){let r=e(n.version);await n.up(r),i.add(n.version)}return[...i].sort((n,r)=>n-r)}status(e=[]){let t=new Set(e),i=this._migrations.map((s)=>s.version).filter((s)=>!t.has(s));return{current:e.length?Math.max(...e):0,applied:[...t].sort((s,n)=>s-n),pending:i}}}var sn={[Symbol.iterator](){return{next(){return{done:!0}}}},size:0};function nn(e){return{[Symbol.iterator](){return e[Symbol.iterator]()},get size(){return e.size}}}function pi(e){return e.map((t)=>{if(t===null||t===void 0)return"\x00";if(typeof t==="boolean")return t?"\x01T":"\x01F";if(typeof t==="number")return`\x02${t}`;return`\x03${String(t)}`}).join("\x1F")}class Lt{constructor(e=[],t=[]){this._fields=new Set,this._compoundFields=[];for(let i of e)if(Array.isArray(i)){for(let s of i)this._validateFieldName(s);this._compoundFields.push(i)}else this._validateFieldName(i),this._fields.add(i);for(let i of t)this._validateFieldName(i);this._uniqueFields=new Set(t),this._indexedFields=new Set([...this._fields,...this._uniqueFields]),this._fieldIndexes=new Map,this._uniqueIndexes=new Map;for(let i of this._fields)this._fieldIndexes.set(i,new Map);for(let i of this._uniqueFields)if(this._uniqueIndexes.set(i,new Map),!this._fieldIndexes.has(i))this._fieldIndexes.set(i,new Map);this._compoundIndexes=new Map;for(let i of this._compoundFields)this._compoundIndexes.set(i.join("\x00"),{fields:i,map:new Map})}get indexedFields(){return this._indexedFields}buildFromData(e){for(let[,t]of this._fieldIndexes)t.clear();for(let[,t]of this._uniqueIndexes)t.clear();for(let[,t]of this._compoundIndexes)t.map.clear();for(let t of e)this._indexDoc(t)}add(e){this._checkUnique(e,null),this._indexDoc(e)}remove(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){let n=i.get(s);if(n){if(n.delete(e),n.size===0)i.delete(s)}}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.delete(s)}for(let[,t]of this._compoundIndexes){let i=pi(t.fields.map((n)=>e[n])),s=t.map.get(i);if(s){if(s.delete(e),s.size===0)t.map.delete(i)}}}update(e,t){this._checkUnique(t,e),this.remove(e);try{this._indexDoc(t)}catch(i){try{this._indexDoc(e)}catch{}throw i}}lookup(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?[...s]:[]}_lookupIterable(e,t){let i=this._fieldIndexes.get(e);if(!i)return null;let s=i.get(t);return s?nn(s):sn}lookupCompound(e){let t=Object.keys(e).sort();for(let[,i]of this._compoundIndexes){let s=[...i.fields].sort();if(s.length!==t.length)continue;if(s.every((n,r)=>n===t[r])){let n=pi(i.fields.map((a)=>e[a])),r=i.map.get(n);return r?nn(r):sn}}return null}isUniqueTaken(e,t){let i=this._uniqueIndexes.get(e);if(!i)return!1;return i.has(t)}assertUniqueCandidates(e,t){if(this._uniqueFields.size===0)return;let i=new Set(e.map((s)=>s._id));for(let s of this._uniqueFields){let n=new Set,r=this._uniqueIndexes.get(s);if(r){for(let[l,o]of r.entries())if(!i.has(o._id))n.add(l)}let a=new Map;for(let l=0;l<t.length;l++){let o=t[l][s];if(o===void 0)continue;if(n.has(o))throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});let c=a.get(o);if(c&&c!==e[l]._id)throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${s}" value "${o}" already exists`,{field:s,value:o});a.set(o,e[l]._id)}}}assertUniqueBatch(e){if(this._uniqueFields.size===0)return;for(let t of this._uniqueFields){let i=this._uniqueIndexes.get(t),s=new Set;for(let n of e){let r=n[t];if(r===void 0)continue;if(i&&i.has(r))throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${t}" value "${r}" already exists`,{field:t,value:r});if(s.has(r))throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: duplicate "${t}" value "${r}" within batch`,{field:t,value:r});s.add(r)}}}_validateFieldName(e){if(e.includes("."))throw new C("ERR_SKALEX_VALIDATION_INDEX_DOT_PATH",`Index fields cannot use dot-notation: "${e}". Use a flat field name.`,{field:e})}_indexDoc(e){for(let[t,i]of this._fieldIndexes){let s=e[t];if(s!==void 0){if(!i.has(s))i.set(s,new Set);i.get(s).add(e)}}for(let[t,i]of this._uniqueIndexes){let s=e[t];if(s!==void 0)i.set(s,e)}for(let[,t]of this._compoundIndexes){for(let s of t.fields){let n=e[s];if(n!==void 0&&n!==null&&typeof n==="object")throw new C("ERR_SKALEX_VALIDATION_COMPOUND_INDEX",`Compound index field "${s}" must be a scalar value (string, number, or boolean), got ${Array.isArray(n)?"array":typeof n}`,{field:s})}let i=pi(t.fields.map((s)=>e[s]));if(!t.map.has(i))t.map.set(i,new Set);t.map.get(i).add(e)}}_checkUnique(e,t){for(let i of this._uniqueFields){let s=e[i];if(s===void 0)continue;let n=this._uniqueIndexes.get(i);if(!n)continue;let r=n.get(s);if(r&&r._id!==t?._id)throw new Te("ERR_SKALEX_UNIQUE_VIOLATION",`Unique constraint violation: field "${i}" value "${s}" already exists`,{field:i,value:s})}}}var Nt="_flush",$t="migrations";class Hr{constructor({adapter:e,serializer:t,deserializer:i,logger:s,debug:n=!1,lenientLoad:r=!1}){this._adapter=e,this._serializer=t,this._deserializer=i,this._logger=s,this._debug=n,this._lenientLoad=r,this._saveLock=Promise.resolve()}_withSaveLock(e){let t=this._saveLock.then(e);return this._saveLock=t.catch(()=>{}),t}async loadAll(e,{parseSchema:t,buildIndex:i,IndexEngine:s}){try{let n=await this._adapter.list();await Promise.all(n.map(async(r)=>{try{let a=await this._adapter.read(r);if(!a)return;let l=this._deserializer(a),{collectionName:o,data:c}=l;if(!o)return;let h=e[o],u=h?.rawSchema??l.rawSchema??null,d=h?.schema??(u?t(u):null),_=h?.changelog??l.changelog??!1,f=h?.softDelete??l.softDelete??!1,p=h?.versioning??l.versioning??!1,m=h?.strict??l.strict??!1,w=h?.onSchemaError??l.onSchemaError??"throw",x=h?.defaultTtl??l.defaultTtl??null,R=h?.defaultEmbed??l.defaultEmbed??null,E=h?.maxDocs??l.maxDocs??null,A=h?h.fieldIndex:null;if(!A&&d?.uniqueFields?.length)A=new s([],d.uniqueFields);let Ue=i(c,"_id");if(A)A.buildFromData(c);e[o]={collectionName:o,data:c,index:Ue,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:d,rawSchema:u,fieldIndex:A,changelog:_,softDelete:f,versioning:p,strict:m,onSchemaError:w,defaultTtl:x,defaultEmbed:R,maxDocs:E}}catch(a){if(a.code==="ENOENT")return;if(this._lenientLoad){this._logger(`WARNING: Could not load collection "${r}": ${a.message}. Collection will be empty.`,"error");return}throw new Pe("ERR_SKALEX_PERSISTENCE_CORRUPT",`Failed to load collection "${r}": ${a.message}`,{collection:r})}})),this._detectIncompleteFlush(e),await this._cleanOrphanTempFiles()}catch(n){if(n.code!=="ENOENT")throw this._logger(`Error loading data: ${n}`,"error"),n}}async save(e,t){if(t)await this._saveOne(e,t);else await Promise.all(Object.keys(e).map((i)=>this._saveOne(e,i)))}async saveDirty(e){let t=Object.keys(e).filter((i)=>e[i]._dirty);if(t.length===0)return;await Promise.all(t.map((i)=>this._saveOne(e,i)))}saveAtomic(e,t){return this._withSaveLock(async()=>{if(t.length===0)return;this._writeFlushSentinel(e,t);let i=new Set(t);i.add("_meta");let s=[...i].filter((n)=>e[n]).map((n)=>({name:n,data:this._serializeCollection(e[n])}));try{await this._adapter.writeAll(s)}catch(n){throw new Pe("ERR_SKALEX_PERSISTENCE_FLUSH_FAILED",`Batch save failed during writeAll: ${n.message}`,{collections:t})}for(let n of t)if(e[n])e[n]._dirty=!1;try{this._clearFlushSentinel(e),await this._adapter.write("_meta",this._serializeCollection(e._meta))}catch(n){this._logger(`WARNING: Batch data committed but sentinel clear failed: ${n.message}. Next load will report an incomplete flush (false positive).`,"error")}})}markDirty(e,t){let i=e[t];if(i)i._dirty=!0}_serializeCollection(e){let t={collectionName:e.collectionName,data:e.data};if(e.rawSchema)t.rawSchema=e.rawSchema;if(e.changelog)t.changelog=e.changelog;if(e.softDelete)t.softDelete=e.softDelete;if(e.versioning)t.versioning=e.versioning;if(e.strict)t.strict=e.strict;if(e.onSchemaError!=="throw")t.onSchemaError=e.onSchemaError;if(e.defaultTtl)t.defaultTtl=e.defaultTtl;if(e.defaultEmbed)t.defaultEmbed=e.defaultEmbed;if(e.maxDocs)t.maxDocs=e.maxDocs;return this._serializer(t)}async _saveOne(e,t){let i=e[t];if(!i)return;if(i.isSaving)return i._pendingSave=!0,new Promise((s,n)=>{(i._saveWaiters??=[]).push({resolve:s,reject:n})});i.isSaving=!0,i._pendingSave=!1;try{await this._writeCollection(t,i);while(i._pendingSave)i._pendingSave=!1,await this._writeCollection(t,i);this._resolveSaveWaiters(i)}catch(s){throw this._rejectSaveWaiters(i,s),s}finally{i.isSaving=!1}}async _writeCollection(e,t){try{await this._adapter.write(e,this._serializeCollection(t)),t._dirty=!1}catch(i){throw this._logger(`Error saving "${e}": ${i.message}`,"error"),i}}_resolveSaveWaiters(e){let t=e._saveWaiters?.splice(0)??[];for(let i of t)i.resolve()}_rejectSaveWaiters(e,t){let i=e._saveWaiters?.splice(0)??[];for(let s of i)s.reject(t)}_writeFlushSentinel(e,t){let i=this._getOrCreateMeta(e);i[Nt]={startedAt:new Date().toISOString(),collections:t,completedAt:null}}_clearFlushSentinel(e){let t=this._getOrCreateMeta(e);if(t[Nt])t[Nt].completedAt=new Date().toISOString()}_detectIncompleteFlush(e){let t=e._meta;if(!t)return;let i=t.index.get($t);if(!i)return;let s=i[Nt];if(!s)return;if(s.startedAt&&!s.completedAt)this._logger(`WARNING: Incomplete flush detected (started ${s.startedAt}, collections: ${s.collections?.join(", ")}). Data may be inconsistent.`,"error")}async _cleanOrphanTempFiles(){if(typeof this._adapter.join!=="function")return;if(typeof this._adapter.list!=="function")return;try{let e=await import("fs"),t=await import("path"),i=this._adapter.dir;if(!i)return;let s=(await e.default.promises.readdir(i)).filter((n)=>n.includes(".tmp."));for(let n of s){let r=t.default.join(i,n);try{await e.default.promises.unlink(r),this._log(`Cleaned orphan temp file: ${n}`)}catch{}}}catch{}}_getOrCreateMeta(e){if(!e._meta)e._meta={collectionName:"_meta",data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:null,rawSchema:null,fieldIndex:null,changelog:!1,softDelete:!1,versioning:!1,strict:!1,onSchemaError:"throw",defaultTtl:null,defaultEmbed:null,maxDocs:null};let t=e._meta,i=t.index.get($t);if(!i)i={_id:$t},t.data.push(i),t.index.set($t,i);return i}_log(e){if(this._debug)this._logger(e,"info")}}var qc=0;class Vr{constructor(){this._txLock=Promise.resolve(),this._ctx=null,this._abortedIds=new Set}get active(){return this._ctx!==null&&!this._ctx.aborted}get context(){return this._ctx}async run(e,t,{timeout:i=0}={}){let s=async()=>{await t._ensureConnected();let r=new Set(Object.keys(t.collections)),a={id:++qc,startedAt:Date.now(),aborted:!1,preExisting:r,touchedCollections:new Set,snapshots:new Map,deferredEffects:[],timeout:i};this._ctx=a;let l=null,o=i>0?new Promise((u,d)=>{l=setTimeout(()=>{a.aborted=!0,d(new we("ERR_SKALEX_TX_TIMEOUT",`Transaction ${a.id} timed out after ${i}ms`))},i)}):null,c=this,h=new Proxy(t,{get(u,d){if(d==="_txId")return a.id;if(a!==c._ctx)throw new we("ERR_SKALEX_TX_STALE_PROXY",`Transaction ${a.id} has ended. This proxy is no longer usable.`);if(d==="collections")throw new we("ERR_SKALEX_TX_DIRECT_ACCESS","Direct access to db.collections inside transaction() is not covered by rollback. Use the collection API (db.useCollection) instead.");if(d==="useCollection")return(f)=>{let p=u.useCollection(f);return p._activeTxId=a.id,p};let _=Reflect.get(u,d);return typeof _==="function"?_.bind(u):_}});try{let u=e(h),d=o?await Promise.race([u,o]):await u;if(a.aborted)throw new we("ERR_SKALEX_TX_ABORTED",`Transaction ${a.id} was aborted`);let _=[...a.touchedCollections];if(_.length>0)await t._persistence.saveAtomic(t.collections,_);for(let f of a.deferredEffects)await f();return d}catch(u){for(let[d,_]of a.snapshots)if(a.preExisting.has(d)){if(t._applySnapshot(d,_),t.collections[d])t.collections[d]._dirty=_._dirty}for(let d in t.collections)if(!a.preExisting.has(d))delete t.collections[d],delete t._collectionInstances[d];throw u}finally{if(l)clearTimeout(l);if(a.aborted)this._abortedIds.add(a.id);this._ctx=null;for(let u in t._collectionInstances){let d=t._collectionInstances[u];if(d._createdInTxId===a.id)d._createdInTxId=null;if(d._activeTxId===a.id)d._activeTxId=null}}},n=this._txLock.then(s);return this._txLock=n.catch(()=>{}),n}snapshotIfNeeded(e,t,i){let s=this._ctx;if(!s)return;if(this._assertCtxNotAborted(s),!s.snapshots.has(e)){let n=i(t);n._dirty=t._dirty??!1,s.snapshots.set(e,n)}s.touchedCollections.add(e)}assertNotAborted(){let e=this._ctx;if(e)this._assertCtxNotAborted(e)}_assertCtxNotAborted(e){if(e.aborted)throw new we("ERR_SKALEX_TX_ABORTED",`Transaction ${e.id} was aborted. No further mutations allowed.`)}defer(e){if(this._ctx)return this._ctx.deferredEffects.push(e),!0;return!1}}class Jr{constructor(e){this._CollectionClass=e,this.stores={},this._instances={}}get(e,t){if(this._instances[e])return this._instances[e];if(!this.stores[e])this.createStore(e);let i=new this._CollectionClass(this.stores[e],t);return this._instances[e]=i,i}create(e,t={},i){this.createStore(e,t);let s=new this._CollectionClass(this.stores[e],i);return this._instances[e]=s,s}createStore(e,{schema:t,indexes:i=[],changelog:s=!1,softDelete:n=!1,versioning:r=!1,strict:a=!1,onSchemaError:l="throw",defaultTtl:o=null,defaultEmbed:c=null,maxDocs:h=null}={}){let u=null,d=null;if(t){u=qr(t);let _=u.uniqueFields;if(i.length||_.length)d=new Lt(i,_)}else if(i.length)d=new Lt(i,[]);this.stores[e]={collectionName:e,data:[],index:new Map,isSaving:!1,_pendingSave:!1,_dirty:!1,schema:u,rawSchema:t||null,fieldIndex:d,changelog:s,softDelete:n,versioning:r,strict:a,onSchemaError:l,defaultTtl:o,defaultEmbed:c,maxDocs:h}}rename(e,t){if(!this.stores[e])throw new Pe("ERR_SKALEX_PERSISTENCE_COLLECTION_NOT_FOUND",`Collection "${e}" not found`,{collection:e});if(this.stores[t])throw new Pe("ERR_SKALEX_PERSISTENCE_COLLECTION_EXISTS",`Collection "${t}" already exists`,{collection:t});let i=this.stores[e];if(i.collectionName=t,this.stores[t]=i,delete this.stores[e],this._instances[e]){let s=this._instances[e];s.name=t,this._instances[t]=s,delete this._instances[e]}}buildIndex(e,t){let i=new Map;for(let s of e)i.set(s[t],s);return i}inspect(e){if(e){let i=this.stores[e];if(!i)return null;return{name:e,count:i.data.length,schema:i.schema?Object.fromEntries(i.schema.fields):null,indexes:i.fieldIndex?[...i.fieldIndex.indexedFields]:[],softDelete:i.softDelete??!1,versioning:i.versioning??!1,strict:i.strict??!1,onSchemaError:i.onSchemaError??"throw",maxDocs:i.maxDocs??null}}let t={};for(let i in this.stores)t[i]=this.inspect(i);return t}dump(){let e={};for(let t in this.stores)if(!t.startsWith("_"))e[t]=structuredClone(this.stores[t].data);return e}schema(e){let t=this.stores[e];if(!t)return null;if(t.schema)return Object.fromEntries([...t.schema.fields.entries()].map(([i,s])=>[i,s.type]));if(t.data.length>0)return $c(t.data[0]);return null}stats(e){let t=(i)=>{let s=this.stores[i];if(!s)return null;let n=s.data.length,r=0;for(let a of s.data)try{r+=JSON.stringify(a).length}catch(l){}return{collection:i,count:n,estimatedSize:r,avgDocSize:n>0?Math.round(r/n):0}};if(e)return t(e);return Object.keys(this.stores).map(t)}clear(){this.stores={},this._instances={}}}class Ji{async embed(e){throw Error("EmbeddingAdapter.embed() not implemented")}}var de=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Yr extends Ji{constructor({apiKey:e=de("OPENAI_API_KEY"),model:t=de("OPENAI_EMBED_MODEL")??"text-embedding-3-small",baseUrl:i=de("OPENAI_EMBED_BASE_URL")??"https://api.openai.com/v1/embeddings",dimensions:s=de("OPENAI_EMBED_DIMENSIONS")!=null?Number(de("OPENAI_EMBED_DIMENSIONS")):void 0,organization:n=de("OPENAI_ORGANIZATION")??void 0,timeout:r=de("OPENAI_EMBED_TIMEOUT")!=null?Number(de("OPENAI_EMBED_TIMEOUT")):void 0,retries:a=Number(de("OPENAI_EMBED_RETRIES")??0),retryDelay:l=Number(de("OPENAI_EMBED_RETRY_DELAY")??1000),headers:o={},fetch:c=globalThis.fetch}={}){super();if(!e)throw Error("OpenAIEmbeddingAdapter requires an apiKey");this.apiKey=e,this.model=t,this.baseUrl=i,this.dimensions=s,this.organization=n,this.timeout=r,this.retries=a,this.retryDelay=l,this.headers=o,this._fetch=c}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(this.baseUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...this.organization&&{"OpenAI-Organization":this.organization},...this.headers},body:JSON.stringify({input:e,model:this.model,...this.dimensions!==void 0&&{dimensions:this.dimensions}}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`OpenAI embedding API error ${r.status}: ${a}`)}return(await r.json()).data[0].embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}var ot=(e)=>globalThis.process?.env?.[e]??globalThis.Deno?.env?.get(e);class Wr extends Ji{constructor({model:e=ot("OLLAMA_EMBED_MODEL")??"nomic-embed-text",host:t=ot("OLLAMA_HOST")??"http://localhost:11434",timeout:i=ot("OLLAMA_EMBED_TIMEOUT")!=null?Number(ot("OLLAMA_EMBED_TIMEOUT")):void 0,retries:s=Number(ot("OLLAMA_EMBED_RETRIES")??0),retryDelay:n=Number(ot("OLLAMA_EMBED_RETRY_DELAY")??1000),headers:r={},fetch:a=globalThis.fetch}={}){super();this.model=e,this.host=t,this.timeout=i,this.retries=s,this.retryDelay=n,this.headers=r,this._fetch=a}async embed(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify({model:this.model,prompt:e}),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama embedding API error ${r.status}: ${a}`)}return(await r.json()).embedding}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}class zt{async generate(e,t){throw Error("LLMAdapter.generate() not implemented")}async summarize(e){throw Error("LLMAdapter.summarize() not implemented")}}var Yi=`You are a database query assistant. Convert the user's natural language request into a JSON filter object for a document database.
94
94
 
95
95
  Rules:
96
96
  - Return ONLY a valid JSON object, nothing else
@@ -105,16 +105,16 @@ Schema: ${JSON.stringify(e)}`,messages:[{role:"user",content:t}]})).content[0].t
105
105
  Schema: ${JSON.stringify(e)}
106
106
  Query: ${t}`,s=await this._post({model:this.model,prompt:i,format:"json",options:{temperature:0},stream:!1});return JSON.parse(s.response)}async summarize(e){return(await this._post({model:this.model,prompt:`${this.summarizePrompt}
107
107
 
108
- ${e}`,options:{temperature:this.temperature,...this.topP!==void 0&&{top_p:this.topP},...this.topK!==void 0&&{top_k:this.topK}},stream:!1})).response.trim()}async _post(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify(e),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama API error ${r.status}: ${a}`)}return r.json()}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}function jc({provider:e,apiKey:t,embedModel:i,model:s,host:n,embedBaseUrl:r,dimensions:a,organization:l,embedTimeout:o,embedRetries:c,embedRetryDelay:h}){let u=i||s;switch(e){case"openai":return new Yr({apiKey:t,model:u,baseUrl:r,...a!==void 0&&{dimensions:a},...l!==void 0&&{organization:l},...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});case"ollama":return new Wr({model:u,host:n,...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});default:throw new pe("ERR_SKALEX_ADAPTER_UNKNOWN_PROVIDER",`Unknown AI provider: "${e}". Supported: "openai", "ollama".`,{provider:e})}}function qc({provider:e,apiKey:t,model:i,host:s,baseUrl:n,apiVersion:r,temperature:a,maxTokens:l,topP:o,topK:c,organization:h,timeout:u,retries:d,retryDelay:_,seed:f,generatePrompt:p,summarizePrompt:m}){if(!i)return null;switch(e){case"openai":return new Qr({apiKey:t,model:i,baseUrl:n,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...h!==void 0&&{organization:h},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...f!==void 0&&{seed:f},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"anthropic":return new Gr({apiKey:t,model:i,baseUrl:n,apiVersion:r,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"ollama":return new Zr({model:i,host:s,...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});default:return null}}var mi="AES-GCM",gt=12,Oe=32,Kc=new TextEncoder,Fc=new TextDecoder;class ea extends Vi{constructor(e,t){super();if(this._adapter=e,this._rawKey=typeof t==="string"?Uc(t):Uint8Array.from(t),this._rawKey.length!==Oe)throw new pe("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: key must be ${Oe} bytes (${Oe*2} hex chars), got ${this._rawKey.length}`);this._cryptoKey=null}async read(e){let t=await this._adapter.read(e);if(!t)return null;return this._decrypt(t)}async write(e,t){return this._adapter.write(e,await this._encrypt(t))}async delete(e){return this._adapter.delete(e)}async list(){return this._adapter.list()}async writeAll(e){let t=[];for(let{name:i,data:s}of e)t.push({name:i,data:await this._encrypt(s)});return this._adapter.writeAll(t)}join(...e){return this._adapter.join?.(...e)}ensureDir(e){return this._adapter.ensureDir?.(e)}async writeRaw(e,t){return this._adapter.writeRaw?.(e,await this._encrypt(t))}async readRaw(e){let t=await this._adapter.readRaw?.(e);if(!t)return null;return this._decrypt(t)}async _getKey(){if(!this._cryptoKey)this._cryptoKey=await globalThis.crypto.subtle.importKey("raw",this._rawKey,{name:mi},!1,["encrypt","decrypt"]);return this._cryptoKey}async _encrypt(e){let t=await this._getKey(),i=globalThis.crypto.getRandomValues(new Uint8Array(gt)),s=Kc.encode(e),n=await globalThis.crypto.subtle.encrypt({name:mi,iv:i,tagLength:128},t,s),r=new Uint8Array(gt+n.byteLength);return r.set(i,0),r.set(new Uint8Array(n),gt),zc(r)}async _decrypt(e){let t=await this._getKey(),i=Bc(e),s=i.slice(0,gt),n=i.slice(gt),r=await globalThis.crypto.subtle.decrypt({name:mi,iv:s,tagLength:128},t,n);return Fc.decode(r)}}function Uc(e){if(e.length!==Oe*2)throw new pe("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: hex key must be ${Oe*2} characters (${Oe} bytes)`);if(!/^[0-9a-fA-F]+$/.test(e))throw new pe("ERR_SKALEX_ADAPTER_INVALID_KEY","EncryptedAdapter: hex key contains invalid characters");let t=new Uint8Array(Oe);for(let i=0;i<Oe;i++)t[i]=parseInt(e.slice(i*2,i*2+2),16);return t}function zc(e){let t="";for(let i=0;i<e.length;i++)t+=String.fromCharCode(e[i]);return globalThis.btoa(t)}function Bc(e){let t=globalThis.atob(e),i=new Uint8Array(t.length);for(let s=0;s<t.length;s++)i[s]=t.charCodeAt(s);return i}var Xc=4;class ta{constructor(e,t){this.sessionId=e,this._db=t,this._col=t.useCollection(`_memory_${e}`)}async remember(e){let t=await this._col.insertOne({text:e,sessionId:this.sessionId},{embed:"text"}),i=this._db._memoryConfig?.maxEntries;if(i&&this._col._data.length>i)await this.compress({threshold:0});return t}async recall(e,{limit:t=10,minScore:i=0}={}){return this._col.search(e,{limit:t,minScore:i})}async history({since:e,limit:t}={}){let i=e?{createdAt:{$gte:new Date(e)}}:{},s={sort:{createdAt:1}};if(t)s.limit=t;let{docs:n}=await this._col.find(i,s);return n}async forget(e){return this._col.deleteOne({_id:e})}tokenCount(){let e=this._col._data;return{tokens:e.reduce((t,i)=>t+this._docTokens(i),0),count:e.length}}context({tokens:e=this._db._memoryConfig?.contextTokens??4000}={}){let t=this._sortedData("desc"),i=[],s=0;for(let n of t){let r=this._docTokens(n);if(s+r>e)break;i.push(n.text),s+=r}return i.reverse().join(`
108
+ ${e}`,options:{temperature:this.temperature,...this.topP!==void 0&&{top_p:this.topP},...this.topK!==void 0&&{top_k:this.topK}},stream:!1})).response.trim()}async _post(e){let t;for(let i=0;i<=this.retries;i++){let s=this.timeout!=null?new AbortController:null,n=s?setTimeout(()=>s.abort(),this.timeout):null;try{let r=await this._fetch(`${this.host}/api/generate`,{method:"POST",headers:{"Content-Type":"application/json",...this.headers},body:JSON.stringify(e),...s&&{signal:s.signal}});if(!r.ok){let a=(await r.text()).slice(0,200);throw Error(`Ollama API error ${r.status}: ${a}`)}return r.json()}catch(r){if(t=r,i<this.retries)await new Promise((a)=>setTimeout(a,this.retryDelay*2**i))}finally{if(n!==null)clearTimeout(n)}}throw t}}function Kc({provider:e,apiKey:t,embedModel:i,model:s,host:n,embedBaseUrl:r,dimensions:a,organization:l,embedTimeout:o,embedRetries:c,embedRetryDelay:h}){let u=i||s;switch(e){case"openai":return new Yr({apiKey:t,model:u,baseUrl:r,...a!==void 0&&{dimensions:a},...l!==void 0&&{organization:l},...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});case"ollama":return new Wr({model:u,host:n,...o!==void 0&&{timeout:o},...c!==void 0&&{retries:c},...h!==void 0&&{retryDelay:h}});default:throw new pe("ERR_SKALEX_ADAPTER_UNKNOWN_PROVIDER",`Unknown AI provider: "${e}". Supported: "openai", "ollama".`,{provider:e})}}function Fc({provider:e,apiKey:t,model:i,host:s,baseUrl:n,apiVersion:r,temperature:a,maxTokens:l,topP:o,topK:c,organization:h,timeout:u,retries:d,retryDelay:_,seed:f,generatePrompt:p,summarizePrompt:m}){if(!i)return null;switch(e){case"openai":return new Qr({apiKey:t,model:i,baseUrl:n,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...h!==void 0&&{organization:h},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...f!==void 0&&{seed:f},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"anthropic":return new Gr({apiKey:t,model:i,baseUrl:n,apiVersion:r,...l!==void 0&&{maxTokens:l},...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});case"ollama":return new Zr({model:i,host:s,...a!==void 0&&{temperature:a},...o!==void 0&&{topP:o},...c!==void 0&&{topK:c},...u!==void 0&&{timeout:u},...d!==void 0&&{retries:d},..._!==void 0&&{retryDelay:_},...p!==void 0&&{generatePrompt:p},...m!==void 0&&{summarizePrompt:m}});default:return null}}var mi="AES-GCM",gt=12,Oe=32,Uc=new TextEncoder,zc=new TextDecoder;class ea extends Vi{constructor(e,t){super();if(this._adapter=e,this._rawKey=typeof t==="string"?Bc(t):Uint8Array.from(t),this._rawKey.length!==Oe)throw new pe("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: key must be ${Oe} bytes (${Oe*2} hex chars), got ${this._rawKey.length}`);this._cryptoKey=null}async read(e){let t=await this._adapter.read(e);if(!t)return null;return this._decrypt(t)}async write(e,t){return this._adapter.write(e,await this._encrypt(t))}async delete(e){return this._adapter.delete(e)}async list(){return this._adapter.list()}async writeAll(e){let t=[];for(let{name:i,data:s}of e)t.push({name:i,data:await this._encrypt(s)});return this._adapter.writeAll(t)}join(...e){return this._adapter.join?.(...e)}ensureDir(e){return this._adapter.ensureDir?.(e)}async writeRaw(e,t){return this._adapter.writeRaw?.(e,await this._encrypt(t))}async readRaw(e){let t=await this._adapter.readRaw?.(e);if(!t)return null;return this._decrypt(t)}async _getKey(){if(!this._cryptoKey)this._cryptoKey=await globalThis.crypto.subtle.importKey("raw",this._rawKey,{name:mi},!1,["encrypt","decrypt"]);return this._cryptoKey}async _encrypt(e){let t=await this._getKey(),i=globalThis.crypto.getRandomValues(new Uint8Array(gt)),s=Uc.encode(e),n=await globalThis.crypto.subtle.encrypt({name:mi,iv:i,tagLength:128},t,s),r=new Uint8Array(gt+n.byteLength);return r.set(i,0),r.set(new Uint8Array(n),gt),Xc(r)}async _decrypt(e){let t=await this._getKey(),i=Hc(e),s=i.slice(0,gt),n=i.slice(gt),r=await globalThis.crypto.subtle.decrypt({name:mi,iv:s,tagLength:128},t,n);return zc.decode(r)}}function Bc(e){if(e.length!==Oe*2)throw new pe("ERR_SKALEX_ADAPTER_INVALID_KEY",`EncryptedAdapter: hex key must be ${Oe*2} characters (${Oe} bytes)`);if(!/^[0-9a-fA-F]+$/.test(e))throw new pe("ERR_SKALEX_ADAPTER_INVALID_KEY","EncryptedAdapter: hex key contains invalid characters");let t=new Uint8Array(Oe);for(let i=0;i<Oe;i++)t[i]=parseInt(e.slice(i*2,i*2+2),16);return t}function Xc(e){let t="";for(let i=0;i<e.length;i++)t+=String.fromCharCode(e[i]);return globalThis.btoa(t)}function Hc(e){let t=globalThis.atob(e),i=new Uint8Array(t.length);for(let s=0;s<t.length;s++)i[s]=t.charCodeAt(s);return i}var Vc=4;class ta{constructor(e,t){this.sessionId=e,this._db=t,this._col=t.useCollection(`_memory_${e}`)}async remember(e){let t=await this._col.insertOne({text:e,sessionId:this.sessionId},{embed:"text"}),i=this._db._memoryConfig?.maxEntries;if(i&&this._col._data.length>i)await this.compress({threshold:0});return t}async recall(e,{limit:t=10,minScore:i=0}={}){return this._col.search(e,{limit:t,minScore:i})}async history({since:e,limit:t}={}){let i=e?{createdAt:{$gte:new Date(e)}}:{},s={sort:{createdAt:1}};if(t)s.limit=t;let{docs:n}=await this._col.find(i,s);return n}async forget(e){return this._col.deleteOne({_id:e})}tokenCount(){let e=this._col._data;return{tokens:e.reduce((t,i)=>t+this._docTokens(i),0),count:e.length}}context({tokens:e=this._db._memoryConfig?.contextTokens??4000}={}){let t=this._sortedData("desc"),i=[],s=0;for(let n of t){let r=this._docTokens(n);if(s+r>e)break;i.push(n.text),s+=r}return i.reverse().join(`
109
109
  `)}async compress({threshold:e=this._db._memoryConfig?.compressionThreshold??8000,keepRecent:t=this._db._memoryConfig?.keepRecent??10}={}){let{tokens:i}=this.tokenCount();if(i<=e)return;if(!this._db._aiAdapter)throw Error('memory.compress() requires a language model adapter. Configure { ai: { model: "..." } }.');let s=this._sortedData("asc"),n=Math.max(0,s.length-t),r=s.slice(0,n);if(r.length===0)return;let a=r.map((o)=>o.text).join(`
110
- `),l=await this._db._aiAdapter.summarize(a);await this._col.deleteMany({_id:{$in:r.map((o)=>o._id)}}),await this._col.insertOne({text:l,sessionId:this.sessionId,compressed:!0})}_docTokens(e){return Math.ceil((e.text||"").length/Xc)}_sortedData(e){return[...this._col._data].sort(e==="asc"?(t,i)=>new Date(t.createdAt)-new Date(i.createdAt):(t,i)=>new Date(i.createdAt)-new Date(t.createdAt))}}class ia{constructor(e){this._db=e,this._restoring=!1}get _col(){return this._db.useCollection("_changelog")}async log(e,t,i,s=null,n=null){if(this._restoring)return;let r={op:e,collection:t,docId:i._id,doc:{...i},timestamp:new Date};if(s)r.prev={...s};if(n)r.session=n;await this._col.insertOne(r)}async query(e,{since:t,limit:i,session:s}={}){let n={collection:e};if(t)n.timestamp={$gte:new Date(t)};if(s)n.session=s;let r={sort:{timestamp:1}};if(i)r.limit=i;let{docs:a}=await this._col.find(n,r);return a}async restore(e,t,{_id:i}={}){let s=new Date(t),n=this._db.useCollection(e),r=(await this.query(e,{})).filter((l)=>new Date(l.timestamp)<=s);if(i){let l=r.filter((c)=>c.docId===i);if(l.length===0)return;let o=l[l.length-1];this._restoring=!0;try{if(o.op==="delete"){if(await n.findOne({_id:i}))await n.deleteOne({_id:i});return}if(await n.findOne({_id:i})){let{_id:c,createdAt:h,updatedAt:u,...d}=o.doc;await n.updateOne({_id:i},d)}else await n.insertOne({...o.doc})}finally{this._restoring=!1}await this._db.saveData(e);return}let a=new Map;for(let l of r)if(l.op==="insert"||l.op==="update")a.set(l.docId,{doc:l.doc,deleted:!1});else if(l.op==="delete")a.set(l.docId,{doc:null,deleted:!0});this._restoring=!0;try{await n.deleteMany({});for(let[,{doc:l,deleted:o}]of a)if(!o&&l)await n.insertOne({...l})}finally{this._restoring=!1}await this._db.saveData(e)}}function Hc(e){let t=5381;for(let i=0;i<e.length;i++)t=(t<<5)+t+e.charCodeAt(i)|0;return(t>>>0).toString(16).padStart(8,"0")}class sa{constructor({maxSize:e=500,ttl:t=0}={}){this._cache=new Map,this._maxSize=e,this._ttl=t}_key(e,t,i){return Hc(JSON.stringify({collectionName:e,schema:t,query:i}))}get(e,t,i){let s=this._key(e,t,i),n=this._cache.get(s);if(!n)return;if(this._ttl>0&&Date.now()-n.ts>this._ttl){this._cache.delete(s);return}return n.filter}set(e,t,i,s){let n=this._key(e,t,i);if(this._cache.size>=this._maxSize&&!this._cache.has(n))this._cache.delete(this._cache.keys().next().value);this._cache.set(n,{filter:s,ts:Date.now()})}toJSON(){return Object.fromEntries([...this._cache.entries()].map(([e,t])=>[e,t]))}fromJSON(e){if(!e||typeof e!=="object")return;for(let[t,i]of Object.entries(e))this._cache.set(t,i)}get size(){return this._cache.size}}function Vc(e,{regexMaxLength:t=500}={}){if(typeof e!=="object"||e===null)return e;let i={};for(let s of Object.keys(e)){let n=e[s];if(n&&typeof n==="object"&&!Array.isArray(n)){let r={};for(let a of Object.keys(n))if(a==="$regex"&&typeof n.$regex==="string"){if(n.$regex.length>t)throw Error(`$regex pattern too long (max ${t} characters)`);if(/\([^)]*[+*][^)]*\)[+*{]/.test(n.$regex))throw Error("$regex pattern rejected: nested quantifiers risk ReDoS");try{r.$regex=new RegExp(n.$regex)}catch{throw Error(`invalid $regex pattern: "${n.$regex}"`)}}else if(["$gt","$gte","$lt","$lte"].includes(a)&&Jc(n[a]))r[a]=new Date(n[a]);else r[a]=n[a];i[s]=r}else i[s]=n}return i}function Jc(e){if(typeof e!=="string")return!1;return/\d{4}-\d{2}-\d{2}/.test(e)&&!isNaN(Date.parse(e))}function Yc(e,t){let i=[];if(!t||typeof e!=="object"||e===null)return i;for(let s of Object.keys(e)){if(s.startsWith("$"))continue;if(!(s.split(".")[0]in t))i.push(`Unknown field referenced in generated filter: "${s}"`)}return i}class na{constructor(){this._listeners=new Map}on(e,t){if(!this._listeners.has(e))this._listeners.set(e,new Set);return this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}emit(e,t){for(let i of[e,"*"]){let s=this._listeners.get(i);if(!s)continue;for(let n of s)try{n(t)}catch(r){}}}removeAll(e){if(e)this._listeners.delete(e);else this._listeners.clear()}listenerCount(e){return this._listeners.get(e)?.size??0}}class ra{constructor({threshold:e=100,maxEntries:t=500}={}){this._threshold=e,this._maxEntries=t,this._entries=[]}record({collection:e,op:t,filter:i,query:s,duration:n,resultCount:r}){if(n<this._threshold)return;let a={collection:e,op:t,duration:n,resultCount:r,timestamp:new Date};if(i!==void 0)a.filter=i;if(s!==void 0)a.query=s;if(this._entries.push(a),this._entries.length>this._maxEntries)this._entries.shift()}entries({limit:e,minDuration:t,collection:i}={}){let s=this._entries;if(i)s=s.filter((n)=>n.collection===i);if(t)s=s.filter((n)=>n.duration>=t);if(e)s=s.slice(-e);return s}get size(){return this._entries.length}clear(){this._entries=[]}}class aa{constructor(){this._sessions=new Map}_ensure(e){if(!this._sessions.has(e))this._sessions.set(e,{reads:0,writes:0,lastActive:null});return this._sessions.get(e)}recordRead(e){if(!e)return;let t=this._ensure(e);t.reads++,t.lastActive=new Date}recordWrite(e){if(!e)return;let t=this._ensure(e);t.writes++,t.lastActive=new Date}get(e){let t=this._sessions.get(e);if(!t)return null;return{sessionId:e,...t}}all(){return[...this._sessions.entries()].map(([e,t])=>({sessionId:e,...t}))}clear(e){if(e)this._sessions.delete(e);else this._sessions.clear()}}class oa{constructor(){this._plugins=[]}register(e){if(typeof e!=="object"||e===null)throw TypeError("Plugin must be a non-null object.");this._plugins.push(e)}async run(e,t){for(let i of this._plugins)if(typeof i[e]==="function")await i[e](t)}get size(){return this._plugins.length}}function We(e){if(typeof e!=="string"||!e.trim())throw Error("collection name must be a non-empty string");if(/[/\\]/.test(e)||e.includes("..")||e.includes("\x00"))throw Error(`invalid collection name: "${e}"`);if(e.trim().startsWith("_"))throw Error(`access to system collection "${e}" is not permitted`);return e.trim()}var rn=[{name:"skalex_collections",description:"List all collection names in the database.",inputSchema:{type:"object",properties:{}},scope:"read"},{name:"skalex_schema",description:"Return the schema for a collection as a { field: type } map. Returns null if the collection is empty.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."}},required:["collection"]},scope:"read"},{name:"skalex_find",description:"Find documents in a collection that match a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter (MongoDB-style operators supported)."},limit:{type:"number",description:"Maximum number of results. Default: 20."},sort:{type:"object",description:"Sort descriptor: { field: 1 } for ascending, { field: -1 } for descending."}},required:["collection"]},scope:"read"},{name:"skalex_insert",description:"Insert a single document into a collection.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},doc:{type:"object",description:"Document to insert."}},required:["collection","doc"]},scope:"write"},{name:"skalex_update",description:"Update the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},update:{type:"object",description:"Fields to update (direct assignment, $inc, $push supported)."},many:{type:"boolean",description:"If true, update all matching documents. Default: false."}},required:["collection","filter","update"]},scope:"write"},{name:"skalex_delete",description:"Delete the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},many:{type:"boolean",description:"If true, delete all matching documents. Default: false."}},required:["collection","filter"]},scope:"write"},{name:"skalex_search",description:"Semantic similarity search. Requires an embedding adapter to be configured.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},query:{type:"string",description:"Natural-language query string to embed and compare."},limit:{type:"number",description:"Maximum number of results. Default: 10."},minScore:{type:"number",description:"Minimum cosine similarity score [0, 1]. Default: 0."},filter:{type:"object",description:"Optional structured pre-filter (hybrid search)."}},required:["collection","query"]},scope:"read"},{name:"skalex_ask",description:"Translate a natural-language question into a filter and query a collection. Requires a language model adapter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},question:{type:"string",description:"Natural-language question about the data."},limit:{type:"number",description:"Maximum number of results. Default: 20."}},required:["collection","question"]},scope:"read"}];async function Wc(e,t,i){switch(e){case"skalex_collections":return Object.keys(i.collections).filter((s)=>!s.startsWith("_"));case"skalex_schema":return i.schema(We(t.collection))??null;case"skalex_find":{let s=i.useCollection(We(t.collection)),n={};if(t.limit)n.limit=t.limit;if(t.sort)n.sort=t.sort;return s.find(t.filter||{},n)}case"skalex_insert":return i.useCollection(We(t.collection)).insertOne(t.doc||{});case"skalex_update":{let s=i.useCollection(We(t.collection));if(t.many)return s.updateMany(t.filter||{},t.update||{});return s.updateOne(t.filter||{},t.update||{})}case"skalex_delete":{let s=i.useCollection(We(t.collection));if(t.many)return s.deleteMany(t.filter||{});return s.deleteOne(t.filter||{})}case"skalex_search":return i.useCollection(We(t.collection)).search(t.query,{limit:t.limit??10,minScore:t.minScore??0,filter:t.filter});case"skalex_ask":return i.ask(We(t.collection),t.question,{limit:t.limit??20});default:throw Object.assign(Error(`Unknown tool: ${e}`),{code:"NOT_FOUND"})}}var Qi="2.0",Gi=-32700,Qc=-32600,an=-32601,Gc=-32602,Zc=-32603;function lt(e,t){return{jsonrpc:Qi,id:e,result:t}}function Ce(e,t,i,s){return{jsonrpc:Qi,id:e,error:{code:t,message:i}}}function eh(e){try{let t=JSON.parse(e);if(typeof t!=="object"||t===null||t.jsonrpc!==Qi)return{parseError:Ce(null,Qc,"Invalid JSON-RPC request")};return{msg:t}}catch(t){return{parseError:Ce(null,Gi,"Parse error")}}}function th(e){return{content:[{type:"text",text:e}]}}function on(e){return{content:[{type:"text",text:e}],isError:!0}}class la{constructor({port:e=3000,host:t="127.0.0.1",allowedOrigin:i=null,maxBodySize:s=1048576}={}){this._port=e,this._host=t,this._allowedOrigin=i,this._maxBodySize=s,this._clients=new Set,this._onMessage=null,this._server=null}onMessage(e){this._onMessage=e}send(e){let t=`data: ${JSON.stringify(e)}
110
+ `),l=await this._db._aiAdapter.summarize(a);await this._col.deleteMany({_id:{$in:r.map((o)=>o._id)}}),await this._col.insertOne({text:l,sessionId:this.sessionId,compressed:!0})}_docTokens(e){return Math.ceil((e.text||"").length/Vc)}_sortedData(e){return[...this._col._data].sort(e==="asc"?(t,i)=>new Date(t.createdAt)-new Date(i.createdAt):(t,i)=>new Date(i.createdAt)-new Date(t.createdAt))}}class ia{constructor(e){this._db=e,this._restoring=!1}get _col(){return this._db.useCollection("_changelog")}async log(e,t,i,s=null,n=null){if(this._restoring)return;let r={op:e,collection:t,docId:i._id,doc:{...i},timestamp:new Date};if(s)r.prev={...s};if(n)r.session=n;await this._col.insertOne(r)}async query(e,{since:t,limit:i,session:s}={}){let n={collection:e};if(t)n.timestamp={$gte:new Date(t)};if(s)n.session=s;let r={sort:{timestamp:1}};if(i)r.limit=i;let{docs:a}=await this._col.find(n,r);return a}async restore(e,t,{_id:i}={}){let s=new Date(t),n=this._db.useCollection(e),r=(await this.query(e,{})).filter((l)=>new Date(l.timestamp)<=s);if(i){let l=r.filter((c)=>c.docId===i);if(l.length===0)return;let o=l[l.length-1];this._restoring=!0;try{if(o.op==="delete"){if(await n.findOne({_id:i}))await n.deleteOne({_id:i});return}if(await n.findOne({_id:i})){let{_id:c,createdAt:h,updatedAt:u,...d}=o.doc;await n.updateOne({_id:i},d)}else await n.insertOne({...o.doc})}finally{this._restoring=!1}await this._db.saveData(e);return}let a=new Map;for(let l of r)if(l.op==="insert"||l.op==="update")a.set(l.docId,{doc:l.doc,deleted:!1});else if(l.op==="delete")a.set(l.docId,{doc:null,deleted:!0});this._restoring=!0;try{await n.deleteMany({});for(let[,{doc:l,deleted:o}]of a)if(!o&&l)await n.insertOne({...l})}finally{this._restoring=!1}await this._db.saveData(e)}}function Jc(e){let t=5381;for(let i=0;i<e.length;i++)t=(t<<5)+t+e.charCodeAt(i)|0;return(t>>>0).toString(16).padStart(8,"0")}class sa{constructor({maxSize:e=500,ttl:t=0}={}){this._cache=new Map,this._maxSize=e,this._ttl=t}_key(e,t,i){return Jc(JSON.stringify({collectionName:e,schema:t,query:i}))}get(e,t,i){let s=this._key(e,t,i),n=this._cache.get(s);if(!n)return;if(this._ttl>0&&Date.now()-n.ts>this._ttl){this._cache.delete(s);return}return n.filter}set(e,t,i,s){let n=this._key(e,t,i);if(this._cache.size>=this._maxSize&&!this._cache.has(n))this._cache.delete(this._cache.keys().next().value);this._cache.set(n,{filter:s,ts:Date.now()})}toJSON(){return Object.fromEntries([...this._cache.entries()].map(([e,t])=>[e,t]))}fromJSON(e){if(!e||typeof e!=="object")return;for(let[t,i]of Object.entries(e))this._cache.set(t,i)}get size(){return this._cache.size}}function Yc(e,{regexMaxLength:t=500}={}){if(typeof e!=="object"||e===null)return e;let i={};for(let s of Object.keys(e)){let n=e[s];if(n&&typeof n==="object"&&!Array.isArray(n)){let r={};for(let a of Object.keys(n))if(a==="$regex"&&typeof n.$regex==="string"){if(n.$regex.length>t)throw Error(`$regex pattern too long (max ${t} characters)`);if(/\([^)]*[+*][^)]*\)[+*{]/.test(n.$regex))throw Error("$regex pattern rejected: nested quantifiers risk ReDoS");try{r.$regex=new RegExp(n.$regex)}catch{throw Error(`invalid $regex pattern: "${n.$regex}"`)}}else if(["$gt","$gte","$lt","$lte"].includes(a)&&Wc(n[a]))r[a]=new Date(n[a]);else r[a]=n[a];i[s]=r}else i[s]=n}return i}function Wc(e){if(typeof e!=="string")return!1;return/\d{4}-\d{2}-\d{2}/.test(e)&&!isNaN(Date.parse(e))}function Qc(e,t){let i=[];if(!t||typeof e!=="object"||e===null)return i;for(let s of Object.keys(e)){if(s.startsWith("$"))continue;if(!(s.split(".")[0]in t))i.push(`Unknown field referenced in generated filter: "${s}"`)}return i}class na{constructor(){this._listeners=new Map}on(e,t){if(!this._listeners.has(e))this._listeners.set(e,new Set);return this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}emit(e,t){for(let i of[e,"*"]){let s=this._listeners.get(i);if(!s)continue;for(let n of s)try{n(t)}catch(r){}}}removeAll(e){if(e)this._listeners.delete(e);else this._listeners.clear()}listenerCount(e){return this._listeners.get(e)?.size??0}}class ra{constructor({threshold:e=100,maxEntries:t=500}={}){this._threshold=e,this._maxEntries=t,this._entries=[]}record({collection:e,op:t,filter:i,query:s,duration:n,resultCount:r}){if(n<this._threshold)return;let a={collection:e,op:t,duration:n,resultCount:r,timestamp:new Date};if(i!==void 0)a.filter=i;if(s!==void 0)a.query=s;if(this._entries.push(a),this._entries.length>this._maxEntries)this._entries.shift()}entries({limit:e,minDuration:t,collection:i}={}){let s=this._entries;if(i)s=s.filter((n)=>n.collection===i);if(t)s=s.filter((n)=>n.duration>=t);if(e)s=s.slice(-e);return s}get size(){return this._entries.length}clear(){this._entries=[]}}class aa{constructor(){this._sessions=new Map}_ensure(e){if(!this._sessions.has(e))this._sessions.set(e,{reads:0,writes:0,lastActive:null});return this._sessions.get(e)}recordRead(e){if(!e)return;let t=this._ensure(e);t.reads++,t.lastActive=new Date}recordWrite(e){if(!e)return;let t=this._ensure(e);t.writes++,t.lastActive=new Date}get(e){let t=this._sessions.get(e);if(!t)return null;return{sessionId:e,...t}}all(){return[...this._sessions.entries()].map(([e,t])=>({sessionId:e,...t}))}clear(e){if(e)this._sessions.delete(e);else this._sessions.clear()}}class oa{constructor(){this._plugins=[]}register(e){if(typeof e!=="object"||e===null)throw TypeError("Plugin must be a non-null object.");this._plugins.push(e)}async run(e,t){for(let i of this._plugins)if(typeof i[e]==="function")await i[e](t)}get size(){return this._plugins.length}}function We(e){if(typeof e!=="string"||!e.trim())throw Error("collection name must be a non-empty string");if(/[/\\]/.test(e)||e.includes("..")||e.includes("\x00"))throw Error(`invalid collection name: "${e}"`);if(e.trim().startsWith("_"))throw Error(`access to system collection "${e}" is not permitted`);return e.trim()}var rn=[{name:"skalex_collections",description:"List all collection names in the database.",inputSchema:{type:"object",properties:{}},scope:"read"},{name:"skalex_schema",description:"Return the schema for a collection as a { field: type } map. Returns null if the collection is empty.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."}},required:["collection"]},scope:"read"},{name:"skalex_find",description:"Find documents in a collection that match a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter (MongoDB-style operators supported)."},limit:{type:"number",description:"Maximum number of results. Default: 20."},sort:{type:"object",description:"Sort descriptor: { field: 1 } for ascending, { field: -1 } for descending."}},required:["collection"]},scope:"read"},{name:"skalex_insert",description:"Insert a single document into a collection.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},doc:{type:"object",description:"Document to insert."}},required:["collection","doc"]},scope:"write"},{name:"skalex_update",description:"Update the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},update:{type:"object",description:"Fields to update (direct assignment, $inc, $push supported)."},many:{type:"boolean",description:"If true, update all matching documents. Default: false."}},required:["collection","filter","update"]},scope:"write"},{name:"skalex_delete",description:"Delete the first document matching a filter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},filter:{type:"object",description:"Query filter to identify the document."},many:{type:"boolean",description:"If true, delete all matching documents. Default: false."}},required:["collection","filter"]},scope:"write"},{name:"skalex_search",description:"Semantic similarity search. Requires an embedding adapter to be configured.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},query:{type:"string",description:"Natural-language query string to embed and compare."},limit:{type:"number",description:"Maximum number of results. Default: 10."},minScore:{type:"number",description:"Minimum cosine similarity score [0, 1]. Default: 0."},filter:{type:"object",description:"Optional structured pre-filter (hybrid search)."}},required:["collection","query"]},scope:"read"},{name:"skalex_ask",description:"Translate a natural-language question into a filter and query a collection. Requires a language model adapter.",inputSchema:{type:"object",properties:{collection:{type:"string",description:"Collection name."},question:{type:"string",description:"Natural-language question about the data."},limit:{type:"number",description:"Maximum number of results. Default: 20."}},required:["collection","question"]},scope:"read"}];async function Gc(e,t,i){switch(e){case"skalex_collections":return Object.keys(i.collections).filter((s)=>!s.startsWith("_"));case"skalex_schema":return i.schema(We(t.collection))??null;case"skalex_find":{let s=i.useCollection(We(t.collection)),n={};if(t.limit)n.limit=t.limit;if(t.sort)n.sort=t.sort;return s.find(t.filter||{},n)}case"skalex_insert":return i.useCollection(We(t.collection)).insertOne(t.doc||{});case"skalex_update":{let s=i.useCollection(We(t.collection));if(t.many)return s.updateMany(t.filter||{},t.update||{});return s.updateOne(t.filter||{},t.update||{})}case"skalex_delete":{let s=i.useCollection(We(t.collection));if(t.many)return s.deleteMany(t.filter||{});return s.deleteOne(t.filter||{})}case"skalex_search":return i.useCollection(We(t.collection)).search(t.query,{limit:t.limit??10,minScore:t.minScore??0,filter:t.filter});case"skalex_ask":return i.ask(We(t.collection),t.question,{limit:t.limit??20});default:throw Object.assign(Error(`Unknown tool: ${e}`),{code:"NOT_FOUND"})}}var Qi="2.0",Gi=-32700,Zc=-32600,an=-32601,eh=-32602,th=-32603;function lt(e,t){return{jsonrpc:Qi,id:e,result:t}}function Ce(e,t,i,s){return{jsonrpc:Qi,id:e,error:{code:t,message:i}}}function ih(e){try{let t=JSON.parse(e);if(typeof t!=="object"||t===null||t.jsonrpc!==Qi)return{parseError:Ce(null,Zc,"Invalid JSON-RPC request")};return{msg:t}}catch(t){return{parseError:Ce(null,Gi,"Parse error")}}}function sh(e){return{content:[{type:"text",text:e}]}}function on(e){return{content:[{type:"text",text:e}],isError:!0}}class la{constructor({port:e=3000,host:t="127.0.0.1",allowedOrigin:i=null,maxBodySize:s=1048576}={}){this._port=e,this._host=t,this._allowedOrigin=i,this._maxBodySize=s,this._clients=new Set,this._onMessage=null,this._server=null}onMessage(e){this._onMessage=e}send(e){let t=`data: ${JSON.stringify(e)}
111
111
 
112
- `;for(let i of this._clients)try{i.write(t)}catch(s){this._clients.delete(i)}}start(){return new Promise((e,t)=>{this._server=Mo.createServer((i,s)=>{if(this._allowedOrigin)s.setHeader("Access-Control-Allow-Origin",this._allowedOrigin),s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type");if(i.method==="OPTIONS"){s.writeHead(204),s.end();return}if(i.method==="GET"&&i.url==="/sse")this._handleSSE(i,s);else if(i.method==="POST"&&i.url==="/message")this._handleMessage(i,s);else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not Found")}),this._server.on("error",t),this._server.listen(this._port,this._host,()=>e())})}stop(){return new Promise((e)=>{if(!this._server){e();return}for(let t of this._clients)try{t.end()}catch(i){}this._clients.clear(),this._server.close(()=>e()),this._server=null})}_handleSSE(e,t){t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),t.write(`event: endpoint
112
+ `;for(let i of this._clients)try{i.write(t)}catch(s){this._clients.delete(i)}}start(){return new Promise((e,t)=>{this._server=qo.createServer((i,s)=>{if(this._allowedOrigin)s.setHeader("Access-Control-Allow-Origin",this._allowedOrigin),s.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type");if(i.method==="OPTIONS"){s.writeHead(204),s.end();return}if(i.method==="GET"&&i.url==="/sse")this._handleSSE(i,s);else if(i.method==="POST"&&i.url==="/message")this._handleMessage(i,s);else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not Found")}),this._server.on("error",t),this._server.listen(this._port,this._host,()=>e())})}stop(){return new Promise((e)=>{if(!this._server){e();return}for(let t of this._clients)try{t.end()}catch(i){}this._clients.clear(),this._server.close(()=>e()),this._server=null})}_handleSSE(e,t){t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),t.write(`event: endpoint
113
113
  data: /message
114
114
 
115
115
  `),this._clients.add(t),e.on("close",()=>{this._clients.delete(t)})}async _handleMessage(e,t){let i="";e.setEncoding("utf8"),e.on("data",(s)=>{if(i+=s,i.length>this._maxBodySize)e.destroy(),t.writeHead(413,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"Request body too large"}))}),e.on("end",async()=>{t.writeHead(202,{"Content-Type":"application/json"}),t.end("{}");let s;try{s=JSON.parse(i)}catch(n){this.send(Ce(null,Gi,"Parse error"));return}if(this._onMessage)await this._onMessage(s).catch(()=>{})})}get port(){return this._port}get host(){return this._host}get url(){return`http://${this._host}:${this._port}`}get sseUrl(){return`${this.url}/sse`}}class ca{constructor(){this._onMessage=null,this._buffer="",this._started=!1}onMessage(e){this._onMessage=e}send(e){process.stdout.write(JSON.stringify(e)+`
116
116
  `)}start(){if(this._started)return;this._started=!0,process.stdin.setEncoding("utf8"),process.stdin.on("data",(e)=>{this._buffer+=e;let t;while((t=this._buffer.indexOf(`
117
- `))!==-1){let i=this._buffer.slice(0,t).trim();if(this._buffer=this._buffer.slice(t+1),i&&this._onMessage){let s;try{s=JSON.parse(i)}catch(n){this.send(Ce(null,Gi,"Parse error"));continue}this._onMessage(s).catch(()=>{})}}}),process.stdin.on("end",()=>{process.exit(0)})}stop(){process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),this._started=!1}}var ih={name:"skalex",version:"4.0.0-alpha"},sh="2024-11-05";class ha{constructor(e,t={}){this._db=e,this._transport=t.transport||"stdio",this._port=t.port||3000,this._host=t.host||"127.0.0.1",this._allowedOrigin=t.allowedOrigin??null,this._maxBodySize=t.maxBodySize??1048576,this._scopes=t.scopes||{"*":["read"]},this._t=null}async listen(){if(this._transport==="http")this._t=new la({port:this._port,host:this._host,allowedOrigin:this._allowedOrigin,maxBodySize:this._maxBodySize});else this._t=new ca;this._t.onMessage((e)=>this._handleMessage(e)),await this._t.start()}async connect(e){if(this._t=e,this._t.onMessage((t)=>this._handleMessage(t)),typeof this._t.start==="function")await this._t.start()}async close(){if(this._t&&typeof this._t.stop==="function")await this._t.stop();this._t=null}get transport(){return this._transport}get url(){return this._t?.url}async _handleMessage(e){let{msg:t,parseError:i}=typeof e==="string"?eh(e):{msg:e};if(i){this._send(i);return}let{id:s,method:n,params:r}=t;if(s===void 0){if(n==="notifications/initialized")return;return}try{switch(n){case"initialize":this._send(lt(s,{protocolVersion:sh,capabilities:{tools:{}},serverInfo:ih}));break;case"tools/list":this._send(lt(s,{tools:this._visibleTools()}));break;case"tools/call":await this._handleToolCall(s,r);break;case"ping":this._send(lt(s,{}));break;default:this._send(Ce(s,an,`Method not found: ${n}`))}}catch(a){this._send(Ce(s,Zc,a.message||"Internal error"))}}async _handleToolCall(e,t){let i=t?.name,s=t?.arguments??{};if(!i){this._send(Ce(e,Gc,"tools/call requires params.name"));return}let n=rn.find((a)=>a.name===i);if(!n){this._send(Ce(e,an,`Unknown tool: ${i}`));return}let r=s.collection||s.collection_name||null;if(!this._hasScope(r,n.scope)){this._send(lt(e,on(`Access denied: "${i}" requires "${n.scope}" scope on collection "${r}".`)));return}try{let a=await Wc(i,s,this._db);this._send(lt(e,th(JSON.stringify(a,null,2))))}catch(a){this._send(lt(e,on(a.message||String(a))))}}_visibleTools(){return rn.filter((e)=>{let t=this._scopes["*"];if(t&&(t.includes(e.scope)||t.includes("admin")))return!0;for(let[,i]of Object.entries(this._scopes))if(i.includes(e.scope)||i.includes("admin"))return!0;return!1})}_hasScope(e,t){let i=(s)=>s.includes("admin")||s.includes(t);if(e&&this._scopes[e])return i(this._scopes[e]);if(this._scopes["*"])return i(this._scopes["*"]);return!1}_send(e){this._t?.send(e)}}var Dt="migrations",ln=(e)=>JSON.stringify(e,function(t,i){let s=this[t];if(s instanceof Date)return{__skalex_date__:s.toISOString()};if(typeof i==="bigint")return{__skalex_bigint__:i.toString()};return i}),cn=(e)=>JSON.parse(e,(t,i)=>{if(i&&typeof i==="object"){if("__skalex_bigint__"in i)return BigInt(i.__skalex_bigint__);if("__skalex_date__"in i)return new Date(i.__skalex_date__)}return i});class se{constructor({path:e="./.db",format:t="gz",debug:i=!1,adapter:s,ai:n,encrypt:r,slowQueryLog:a,queryCache:l,memory:o,logger:c,plugins:h,llmAdapter:u,embeddingAdapter:d,regexMaxLength:_,idGenerator:f,serializer:p,deserializer:m,autoSave:w,ttlSweepInterval:x,lenientLoad:R}={}){if(this.dataDirectory=e,this.dataFormat=t,this.debug=i,!se._errorsAttached)se.SkalexError=Ke,se.ValidationError=C,se.UniqueConstraintError=Te,se.TransactionError=we,se.PersistenceError=Pe,se.AdapterError=pe,se.QueryError=et,se._errorsAttached=!0;this._adapterConfig=s??null;let E=s||new Br({dir:e,format:t});if(r)E=new ea(E,r.key);if(this.fs=E,this._registry=new Jr(zr),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._migrations=new Xr,this._connectPromise=null,this.isConnected=!1,this._aiConfig=n||null,this._encryptConfig=r||null,this._pluginsConfig=Array.isArray(h)?h:null,this._memoryConfig=o||null,this._regexMaxLength=_??500,this._idGenerator=f??null,this._serializer=p??ln,this._deserializer=m??cn,this._autoSave=w??!1,this._txManager=new Vr,this._ttlSweepInterval=x??0,this._ttlTimer=null,this._logger=c??Qs,this._embeddingAdapter=d??(n?jc(n):null),this._aiAdapter=u??(n?qc(n):null),this._persistence=new Hr({adapter:this.fs,serializer:this._serializer,deserializer:this._deserializer,logger:this._logger,debug:this.debug,lenientLoad:R??!1}),this._changeLog=new ia(this),this._queryCache=new sa(l||{}),this._eventBus=new na,this._queryLog=a?new ra(a):null,this._sessionStats=new aa,this._plugins=new oa,Array.isArray(h))for(let A of h)this._plugins.register(A)}async connect(){if(this._connectPromise)return this._connectPromise;return this._connectPromise=this._doConnect(),this._connectPromise}async _doConnect(){try{await this.loadData();let e=this._getMeta();if(e.queryCache)this._queryCache.fromJSON(e.queryCache);if(this._migrations._migrations.length>0){let t=e.appliedVersions||[],i=await this._migrations.run((s)=>this.useCollection(`_migration_${s}`),t);this._saveMeta({appliedVersions:i})}if(this._sweepTtl(),this._ttlSweepInterval>0){if(this._ttlTimer=setInterval(()=>this._sweepTtl(),this._ttlSweepInterval),this._ttlTimer?.unref)this._ttlTimer.unref()}this.isConnected=!0,this._log("> - Connected to the database (\u221A)")}catch(e){throw this._logger(`Error connecting to the database: ${e}`,"error"),e}}async disconnect(){try{if(this._ttlTimer)clearInterval(this._ttlTimer),this._ttlTimer=null;await this.saveData(),this._registry.clear(),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._connectPromise=null,this.isConnected=!1,this._log("> - Disconnected from the database (\u221A)")}catch(e){throw this._logger(`Error disconnecting from the database: ${e}`,"error"),e}}async _ensureConnected(){if(this.isConnected)return;return this.connect()}useCollection(e){return this._registry.get(e,this)}createCollection(e,t={}){return this._registry.create(e,t,this)}_createCollectionStore(e,t={}){this._registry.createStore(e,t)}async renameCollection(e,t){this._registry.rename(e,t),await this.saveData(t),await this.fs.delete(e)}async loadData(){await this._persistence.loadAll(this.collections,{parseSchema:qr,buildIndex:this._registry.buildIndex,IndexEngine:Lt});for(let e in this._collectionInstances){let t=this.collections[e];if(t&&this._collectionInstances[e]._store!==t)this._collectionInstances[e]._store=t}}async saveData(e){await this._persistence.save(this.collections,e)}buildIndex(e,t){return this._registry.buildIndex(e,t)}addMigration(e){this._migrations.add(e)}migrationStatus(){let e=this._getMeta();return this._migrations.status(e.appliedVersions||[])}namespace(e){if(this._adapterConfig)throw new pe("ERR_SKALEX_ADAPTER_NAMESPACE_REQUIRES_FS","namespace() requires the default FsAdapter. When a custom storage adapter is configured, create a separate Skalex instance with your adapter instead.");let t=String(e).replace(/[^a-zA-Z0-9_-]/g,"_");if(!t)throw new C("ERR_SKALEX_VALIDATION_NAMESPACE_ID","namespace: id must contain at least one alphanumeric character",{id:e});return new se({path:`${this.dataDirectory}/${t}`,format:this.dataFormat,debug:this.debug,ai:this._aiConfig||void 0,encrypt:this._encryptConfig||void 0,slowQueryLog:this._queryLog?{threshold:this._queryLog._threshold,maxEntries:this._queryLog._maxEntries}:void 0,queryCache:this._queryCache?{maxSize:this._queryCache._maxSize,ttl:this._queryCache._ttl}:void 0,plugins:this._pluginsConfig||void 0,memory:this._memoryConfig||void 0,logger:this._logger!==Qs?this._logger:void 0,llmAdapter:this._aiAdapter&&!this._aiConfig?this._aiAdapter:void 0,embeddingAdapter:this._embeddingAdapter&&!this._aiConfig?this._embeddingAdapter:void 0,regexMaxLength:this._regexMaxLength!==500?this._regexMaxLength:void 0,idGenerator:this._idGenerator||void 0,serializer:this._serializer!==ln?this._serializer:void 0,deserializer:this._deserializer!==cn?this._deserializer:void 0,autoSave:this._autoSave||void 0,ttlSweepInterval:this._ttlSweepInterval||void 0})}use(e){this._plugins.register(e)}watch(e){return this._eventBus.on("*",e)}sessionStats(e){if(e!==void 0)return this._sessionStats.get(e);return this._sessionStats.all()}get _inTransaction(){return this._txManager.active}_emitEvent(e,t){if(!this._txManager.defer(()=>this._eventBus.emit(e,t)))this._eventBus.emit(e,t)}async _runAfterHook(e,t){if(!this._txManager.defer(()=>this._plugins.run(e,t)))await this._plugins.run(e,t)}async _logChange(e,t,i,s,n){if(!this._txManager.defer(()=>this._changeLog.log(e,t,i,s,n)))await this._changeLog.log(e,t,i,s,n)}async transaction(e,t={}){return this._txManager.run(e,this,t)}async seed(e,{reset:t=!1}={}){for(let[i,s]of Object.entries(e)){if(t&&this.collections[i])this._applySnapshot(i,{data:[],index:new Map}),delete this._collectionInstances[i];await this.useCollection(i).insertMany(s)}await this.saveData()}dump(){return this._registry.dump()}inspect(e){return this._registry.inspect(e)}async import(e){let t=await this.fs.readRaw(e),i;try{i=JSON.parse(t)}catch{throw new Pe("ERR_SKALEX_PERSISTENCE_INVALID_JSON",`import: invalid JSON in file "${e}"`,{filePath:e})}let s=e.split("/").pop().replace(/\.[^.]+$/,"");return this.useCollection(s).insertMany(Array.isArray(i)?i:[i],{save:!0})}async embed(e){if(!this._embeddingAdapter)throw new pe("ERR_SKALEX_ADAPTER_EMBEDDING_REQUIRED","db.embed() requires an AI adapter. Pass { ai: { provider, apiKey } } to the Skalex constructor.");return this._embeddingAdapter.embed(e)}async ask(e,t,{limit:i=20}={}){if(!this._aiAdapter)throw new pe("ERR_SKALEX_ADAPTER_LLM_REQUIRED",'db.ask() requires a language model adapter. Configure { ai: { provider, model: "..." } }.');let s=this.useCollection(e),n=this.schema(e),r=this._queryCache.get(e,n,t);if(!r){r=await this._aiAdapter.generate(n,t);let a=Yc(r,n);if(a.length)a.forEach((l)=>this._log(`[ask] ${l}`));this._queryCache.set(e,n,t,r),this._saveMeta({queryCache:this._queryCache.toJSON()})}return s.find(Vc(r,{regexMaxLength:this._regexMaxLength}),{limit:i})}schema(e){return this._registry.schema(e)}useMemory(e){return new ta(e,this)}changelog(){return this._changeLog}async restore(e,t,i={}){return this._changeLog.restore(e,t,i)}stats(e){return this._registry.stats(e)}slowQueries(e={}){if(!this._queryLog)return[];return this._queryLog.entries(e)}slowQueryCount(){return this._queryLog?this._queryLog.size:0}clearSlowQueries(){this._queryLog?.clear()}mcp(e={}){return new ha(this,e)}_getMeta(){let e=this.collections._meta;if(!e)return{};return e.index.get(Dt)||{}}_saveMeta(e){if(!this.collections._meta)this._createCollectionStore("_meta");let t=this.collections._meta,i=t.index.get(Dt);if(i)Object.assign(i,e);else{let s={_id:Dt,...e};t.data.push(s),t.index.set(Dt,s)}this._persistence.markDirty(this.collections,"_meta")}_sweepTtl(){for(let e in this.collections){let t=this.collections[e],i=Dc(t.data,t.index,t.fieldIndex?(s)=>t.fieldIndex.remove(s):null);if(i>0)this._persistence.markDirty(this.collections,e),this._log(`TTL sweep: removed ${i} expired docs from "${e}"`)}}_buildCollectionContext(){let e=this;return{ensureConnected:()=>e._ensureConnected(),get txManager(){return e._txManager},get plugins(){return e._plugins},get eventBus(){return e._eventBus},get sessionStats(){return e._sessionStats},get queryLog(){return e._queryLog},get logger(){return e._logger},get persistence(){return e._persistence},get collections(){return e.collections},embed:(t)=>e.embed(t),get idGenerator(){return e._idGenerator},get autoSave(){return e._autoSave},saveCollection:(t)=>e.saveData(t),snapshotCollection:(t)=>e._snapshotCollection(t),getCollection:(t)=>e.useCollection(t),emitEvent:(t,i)=>e._emitEvent(t,i),runAfterHook:(t,i)=>e._runAfterHook(t,i),logChange:(t,i,s,n,r)=>e._logChange(t,i,s,n,r),get fs(){return e.fs},get dataDirectory(){return e.dataDirectory}}}_log(e){if(this.debug)this._logger(e,"info")}_snapshotCollection(e){return{data:structuredClone(e.data)}}_applySnapshot(e,t){let i=this.collections[e];if(!i)return;if(i.data=t.data,i.index=this.buildIndex(t.data,"_id"),i.fieldIndex)i.fieldIndex.buildFromData(t.data)}}class da{}var nh=new Map;function rh(e,t){nh.set(e,t)}var hn=()=>new Date().toISOString();function I(e){if(!e)return e;let{_id:t,createdAt:i,updatedAt:s,_version:n,_expiresAt:r,...a}=e,l={...a};if(l.createdAt==null&&i!=null)l.createdAt=i instanceof Date?i.toISOString():String(i);if(l.updatedAt==null&&s!=null)l.updatedAt=s instanceof Date?s.toISOString():String(s);return l}class Zi extends da{dataDir;encryptionKey;lockPath;lockFd=null;db;tasks;config;gitRepos;bookmarks;notifications;pluginState;constructor(e){super();this.dataDir=e.dataDir,this.encryptionKey=e.encryptionKey,this.lockPath=Lo(e.dataDir,".agent-db.lock")}static async create(e){if(!$o(e.dataDir))Do(e.dataDir,{recursive:!0});let t=new Zi(e);t.acquireLock();try{await t.init()}catch(i){throw t.releaseLock(),i}return t}acquireLock(){try{this.lockFd=Co(this.lockPath,"wx",384),ko(this.lockFd,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()}));return}catch(t){if(t.code!=="EEXIST")throw t}let e=!1;try{let t=JSON.parse(Ro(this.lockPath,"utf8"));if(!t.pid)e=!0;else try{process.kill(t.pid,0)}catch{e=!0}}catch{e=!0}if(e){try{fs(this.lockPath)}catch{}this.acquireLock();return}throw Error(`Agent database is already open by another process (${this.lockPath})`)}releaseLock(){if(this.lockFd!==null){try{No(this.lockFd)}catch{}this.lockFd=null}try{fs(this.lockPath)}catch{}}async init(){this.db=new se({path:this.dataDir,encrypt:{key:this.encryptionKey},autoSave:!0,format:"gz",lenientLoad:!0}),this.tasks=this.db.createCollection("tasks",{schema:{id:{type:"string",required:!0,unique:!0},type:{type:"string",required:!0,enum:["command","script","file_operation"]},status:{type:"string",required:!0,enum:["pending","running","completed","failed"]},payload:{type:"string",required:!0},result:{type:"string"},error:{type:"string"},calendarTaskId:{type:"string"},exitCode:{type:"number"},timeout:{type:"number"}},indexes:["status","type"]}),this.config=this.db.createCollection("agent_config",{schema:{key:{type:"string",required:!0,unique:!0},value:{type:"string",required:!0}}}),this.gitRepos=this.db.createCollection("git_repositories",{schema:{id:{type:"string",required:!0,unique:!0},path:{type:"string",required:!0,unique:!0},name:{type:"string",required:!0},parentPath:{type:"string"},isSubmodule:{type:"boolean"},projectType:{type:"string"},vitePort:{type:"number"},lastScanned:{type:"string"}},indexes:["parentPath"]}),this.bookmarks=this.db.createCollection("bookmarked_commands",{schema:{id:{type:"string",required:!0,unique:!0},projectId:{type:"string"},command:{type:"string",required:!0},description:{type:"string"},category:{type:"string"}},indexes:["projectId","category"]}),this.notifications=this.db.createCollection("notifications",{schema:{id:{type:"string",required:!0,unique:!0},sessionName:{type:"string"},projectId:{type:"string"},type:{type:"string",required:!0,enum:["info","success","warning","error"]},title:{type:"string",required:!0},message:{type:"string",required:!0},status:{type:"string",required:!0,enum:["unread","read"]}},indexes:["status","projectId"]}),this.pluginState=this.db.createCollection("plugin_state",{schema:{pluginName:{type:"string",required:!0},key:{type:"string",required:!0},value:{type:"string",required:!0}},indexes:["pluginName"]}),await this.db.connect()}async close(){if(this.db?.isConnected)await this.db.disconnect();this.releaseLock()}getDbPath(){return this.dataDir}async createTask(e){let t={id:e.id,type:e.type,status:e.status,payload:e.payload};if(e.result!=null)t.result=e.result;if(e.error!=null)t.error=e.error;if(e.calendarTaskId!=null)t.calendarTaskId=e.calendarTaskId;if(e.exitCode!=null)t.exitCode=e.exitCode;if(e.timeout!=null)t.timeout=e.timeout;let i=await this.tasks.insertOne(t);return I(i)}async getTask(e){let t=await this.tasks.findOne({id:e});return t?I(t):void 0}async getAllTasks(){return(await this.tasks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>I(e))}async getPendingTasks(){return(await this.tasks.find({status:"pending"},{sort:{createdAt:1}})).docs.map((e)=>I(e))}async updateTask(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.tasks.updateOne({id:e},i)}async cancelTask(e){let t=await this.tasks.findOne({id:e});if(!t||t.status!=="pending"&&t.status!=="running")return!1;return await this.tasks.updateOne({id:e},{status:"failed",error:"Cancelled"}),!0}async getConfig(e){return(await this.config.findOne({key:e}))?.value}async setConfig(e,t){await this.config.upsert({key:e},{key:e,value:t})}async deleteConfig(e){return await this.config.deleteOne({key:e})!==null}async getAllConfig(){let e=await this.config.find(),t={};for(let i of e.docs)t[i.key]=i.value;return t}async bulkSetConfig(e){for(let[t,i]of Object.entries(e))await this.config.upsert({key:t},{key:t,value:i})}async getConfigStatus(){let e=await this.config.find(),t=null;for(let i of e.docs){let s=i.updatedAt,n=s instanceof Date?s.toISOString():typeof s==="string"?s:null;if(n&&(!t||n>t))t=n}return{totalKeys:e.docs.length,lastUpdated:t}}async createGitRepository(e){let t={id:e.id,path:e.path,name:e.name,isSubmodule:Boolean(e.isSubmodule),lastScanned:hn()};if(e.parentPath!=null)t.parentPath=e.parentPath;if(e.projectType!=null)t.projectType=e.projectType;if(e.vitePort!=null)t.vitePort=e.vitePort;let i=await this.gitRepos.insertOne(t);return I(i)}async getGitRepository(e){let t=await this.gitRepos.findOne({id:e});return t?I(t):void 0}async getGitRepositoryByPath(e){let t=await this.gitRepos.findOne({path:e});return t?I(t):void 0}async getAllGitRepositories(){return(await this.gitRepos.find(void 0,{sort:{path:1}})).docs.map((e)=>I(e))}async updateGitRepository(e,t){let i={lastScanned:hn()};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;if(s==="isSubmodule"){i[s]=Boolean(n);continue}i[s]=n??null}await this.gitRepos.updateOne({id:e},i)}async deleteGitRepository(e){return await this.gitRepos.deleteOne({id:e})!==null}async fixGitHierarchy(){let e=await this.getAllGitRepositories(),t=0;for(let i of e){if(i.isSubmodule)continue;let s=e.find((n)=>n.id!==i.id&&i.path.startsWith(`${n.path}/`)&&!n.isSubmodule);if(s&&i.parentPath!==s.path)await this.updateGitRepository(i.id,{parentPath:s.path}),t++}return{fixed:t}}async createBookmarkedCommand(e){let t={id:e.id,command:e.command};if(e.projectId!=null)t.projectId=e.projectId;if(e.description!=null)t.description=e.description;if(e.category!=null)t.category=e.category;let i=await this.bookmarks.insertOne(t);return I(i)}async getBookmarkedCommand(e){let t=await this.bookmarks.findOne({id:e});return t?I(t):void 0}async getAllBookmarkedCommands(){return(await this.bookmarks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>I(e))}async getBookmarkedCommandsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.bookmarks.find(t,{sort:{createdAt:-1}})).docs.map((i)=>I(i))}async getBookmarkedCommandsByCategory(e){return(await this.bookmarks.find({category:e},{sort:{createdAt:-1}})).docs.map((t)=>I(t))}async updateBookmarkedCommand(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.bookmarks.updateOne({id:e},i)}async deleteBookmarkedCommand(e){return await this.bookmarks.deleteOne({id:e})!==null}async executeBookmarkedCommand(e){return this.getBookmarkedCommand(e)}async createNotification(e){let t={id:e.id,type:e.type,title:e.title,message:e.message,status:e.status};if(e.sessionName!=null)t.sessionName=e.sessionName;if(e.projectId!=null)t.projectId=e.projectId;let i=await this.notifications.insertOne(t);return I(i)}async getNotification(e){let t=await this.notifications.findOne({id:e});return t?I(t):void 0}async getAllNotifications(){return(await this.notifications.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>I(e))}async getNotificationsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.notifications.find(t,{sort:{createdAt:-1}})).docs.map((i)=>I(i))}async getGlobalNotifications(){return this.getNotificationsByProject(null)}async getUnreadNotifications(){return(await this.notifications.find({status:"unread"},{sort:{createdAt:-1}})).docs.map((e)=>I(e))}async updateNotificationStatus(e,t){await this.notifications.updateOne({id:e},{status:t})}async markAllNotificationsRead(){return(await this.notifications.updateMany({status:"unread"},{status:"read"})).length}async deleteNotification(e){return await this.notifications.deleteOne({id:e})!==null}async clearOldNotifications(e=30){let t=new Date(Date.now()-e*24*60*60*1000);return(await this.notifications.deleteMany({createdAt:{$fn:(i)=>i instanceof Date&&i<t}})).length}async getPluginState(e,t){return(await this.pluginState.findOne({$and:[{pluginName:e},{key:t}]}))?.value}async setPluginState(e,t,i){await this.pluginState.upsert({$and:[{pluginName:e},{key:t}]},{pluginName:e,key:t,value:i})}async deletePluginState(e,t){return await this.pluginState.deleteOne({$and:[{pluginName:e},{key:t}]})!==null}async getAllPluginState(e){return(await this.pluginState.find({pluginName:e},{sort:{key:1}})).docs.map((t)=>{let i=t.updatedAt,s=i instanceof Date?i.toISOString():typeof i==="string"?i:void 0;return{key:t.key,value:t.value,updatedAt:s}})}async deleteAllPluginState(e){return(await this.pluginState.deleteMany({pluginName:e})).length}}var ua=(e)=>Zi.create(e);rh("skalex",ua);var ah=new Map;function _a(e,t){ah.set(e,t)}class fa{}_a("skalex",ua);var dn=()=>new Date().toISOString();function b(e){if(!e)return e;let{_id:t,createdAt:i,updatedAt:s,_version:n,_expiresAt:r,...a}=e,l={...a};if(l.createdAt==null&&i!=null)l.createdAt=i instanceof Date?i.toISOString():String(i);if(l.updatedAt==null&&s!=null)l.updatedAt=s instanceof Date?s.toISOString():String(s);return l}class es extends fa{dataDir;encryptionKey;lockPath;lockFd=null;db;tasks;config;gitRepos;bookmarks;notifications;pluginState;constructor(e){super();this.dataDir=e.dataDir,this.encryptionKey=e.encryptionKey,this.lockPath=bo(e.dataDir,".agent-db.lock")}static async create(e){if(!xo(e.dataDir))vo(e.dataDir,{recursive:!0});let t=new es(e);t.acquireLock();try{await t.init()}catch(i){throw t.releaseLock(),i}return t}acquireLock(){try{this.lockFd=Eo(this.lockPath,"wx",384),Io(this.lockFd,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()}));return}catch(t){if(t.code!=="EEXIST")throw t}let e=!1;try{let t=JSON.parse(So(this.lockPath,"utf8"));if(!t.pid)e=!0;else try{process.kill(t.pid,0)}catch{e=!0}}catch{e=!0}if(e){try{_s(this.lockPath)}catch{}this.acquireLock();return}throw Error(`Agent database is already open by another process (${this.lockPath})`)}releaseLock(){if(this.lockFd!==null){try{Ao(this.lockFd)}catch{}this.lockFd=null}try{_s(this.lockPath)}catch{}}async init(){this.db=new ie({path:this.dataDir,encrypt:{key:this.encryptionKey},autoSave:!0,format:"gz",lenientLoad:!0}),this.tasks=this.db.createCollection("tasks",{schema:{id:{type:"string",required:!0,unique:!0},type:{type:"string",required:!0,enum:["command","script","file_operation"]},status:{type:"string",required:!0,enum:["pending","running","completed","failed"]},payload:{type:"string",required:!0},result:{type:"string"},error:{type:"string"},calendarTaskId:{type:"string"},exitCode:{type:"number"},timeout:{type:"number"}},indexes:["status","type"]}),this.config=this.db.createCollection("agent_config",{schema:{key:{type:"string",required:!0,unique:!0},value:{type:"string",required:!0}}}),this.gitRepos=this.db.createCollection("git_repositories",{schema:{id:{type:"string",required:!0,unique:!0},path:{type:"string",required:!0,unique:!0},name:{type:"string",required:!0},parentPath:{type:"string"},isSubmodule:{type:"boolean"},projectType:{type:"string"},vitePort:{type:"number"},lastScanned:{type:"string"}},indexes:["parentPath"]}),this.bookmarks=this.db.createCollection("bookmarked_commands",{schema:{id:{type:"string",required:!0,unique:!0},projectId:{type:"string"},command:{type:"string",required:!0},description:{type:"string"},category:{type:"string"}},indexes:["projectId","category"]}),this.notifications=this.db.createCollection("notifications",{schema:{id:{type:"string",required:!0,unique:!0},sessionName:{type:"string"},projectId:{type:"string"},type:{type:"string",required:!0,enum:["info","success","warning","error"]},title:{type:"string",required:!0},message:{type:"string",required:!0},status:{type:"string",required:!0,enum:["unread","read"]}},indexes:["status","projectId"]}),this.pluginState=this.db.createCollection("plugin_state",{schema:{pluginName:{type:"string",required:!0},key:{type:"string",required:!0},value:{type:"string",required:!0}},indexes:["pluginName"]}),await this.db.connect()}async close(){if(this.db?.isConnected)await this.db.disconnect();this.releaseLock()}getDbPath(){return this.dataDir}async createTask(e){let t={id:e.id,type:e.type,status:e.status,payload:e.payload};if(e.result!=null)t.result=e.result;if(e.error!=null)t.error=e.error;if(e.calendarTaskId!=null)t.calendarTaskId=e.calendarTaskId;if(e.exitCode!=null)t.exitCode=e.exitCode;if(e.timeout!=null)t.timeout=e.timeout;let i=await this.tasks.insertOne(t);return b(i)}async getTask(e){let t=await this.tasks.findOne({id:e});return t?b(t):void 0}async getAllTasks(){return(await this.tasks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>b(e))}async getPendingTasks(){return(await this.tasks.find({status:"pending"},{sort:{createdAt:1}})).docs.map((e)=>b(e))}async updateTask(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.tasks.updateOne({id:e},i)}async cancelTask(e){let t=await this.tasks.findOne({id:e});if(!t||t.status!=="pending"&&t.status!=="running")return!1;return await this.tasks.updateOne({id:e},{status:"failed",error:"Cancelled"}),!0}async getConfig(e){return(await this.config.findOne({key:e}))?.value}async setConfig(e,t){await this.config.upsert({key:e},{key:e,value:t})}async deleteConfig(e){return await this.config.deleteOne({key:e})!==null}async getAllConfig(){let e=await this.config.find(),t={};for(let i of e.docs)t[i.key]=i.value;return t}async bulkSetConfig(e){for(let[t,i]of Object.entries(e))await this.config.upsert({key:t},{key:t,value:i})}async getConfigStatus(){let e=await this.config.find(),t=null;for(let i of e.docs){let s=i.updatedAt,n=s instanceof Date?s.toISOString():typeof s==="string"?s:null;if(n&&(!t||n>t))t=n}return{totalKeys:e.docs.length,lastUpdated:t}}async createGitRepository(e){let t={id:e.id,path:e.path,name:e.name,isSubmodule:Boolean(e.isSubmodule),lastScanned:dn()};if(e.parentPath!=null)t.parentPath=e.parentPath;if(e.projectType!=null)t.projectType=e.projectType;if(e.vitePort!=null)t.vitePort=e.vitePort;let i=await this.gitRepos.insertOne(t);return b(i)}async getGitRepository(e){let t=await this.gitRepos.findOne({id:e});return t?b(t):void 0}async getGitRepositoryByPath(e){let t=await this.gitRepos.findOne({path:e});return t?b(t):void 0}async getAllGitRepositories(){return(await this.gitRepos.find(void 0,{sort:{path:1}})).docs.map((e)=>b(e))}async updateGitRepository(e,t){let i={lastScanned:dn()};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;if(s==="isSubmodule"){i[s]=Boolean(n);continue}i[s]=n??null}await this.gitRepos.updateOne({id:e},i)}async deleteGitRepository(e){return await this.gitRepos.deleteOne({id:e})!==null}async fixGitHierarchy(){let e=await this.getAllGitRepositories(),t=0;for(let i of e){if(i.isSubmodule)continue;let s=e.find((n)=>n.id!==i.id&&i.path.startsWith(`${n.path}/`)&&!n.isSubmodule);if(s&&i.parentPath!==s.path)await this.updateGitRepository(i.id,{parentPath:s.path}),t++}return{fixed:t}}async createBookmarkedCommand(e){let t={id:e.id,command:e.command};if(e.projectId!=null)t.projectId=e.projectId;if(e.description!=null)t.description=e.description;if(e.category!=null)t.category=e.category;let i=await this.bookmarks.insertOne(t);return b(i)}async getBookmarkedCommand(e){let t=await this.bookmarks.findOne({id:e});return t?b(t):void 0}async getAllBookmarkedCommands(){return(await this.bookmarks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>b(e))}async getBookmarkedCommandsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.bookmarks.find(t,{sort:{createdAt:-1}})).docs.map((i)=>b(i))}async getBookmarkedCommandsByCategory(e){return(await this.bookmarks.find({category:e},{sort:{createdAt:-1}})).docs.map((t)=>b(t))}async updateBookmarkedCommand(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.bookmarks.updateOne({id:e},i)}async deleteBookmarkedCommand(e){return await this.bookmarks.deleteOne({id:e})!==null}async executeBookmarkedCommand(e){return this.getBookmarkedCommand(e)}async createNotification(e){let t={id:e.id,type:e.type,title:e.title,message:e.message,status:e.status};if(e.sessionName!=null)t.sessionName=e.sessionName;if(e.projectId!=null)t.projectId=e.projectId;let i=await this.notifications.insertOne(t);return b(i)}async getNotification(e){let t=await this.notifications.findOne({id:e});return t?b(t):void 0}async getAllNotifications(){return(await this.notifications.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>b(e))}async getNotificationsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.notifications.find(t,{sort:{createdAt:-1}})).docs.map((i)=>b(i))}async getGlobalNotifications(){return this.getNotificationsByProject(null)}async getUnreadNotifications(){return(await this.notifications.find({status:"unread"},{sort:{createdAt:-1}})).docs.map((e)=>b(e))}async updateNotificationStatus(e,t){await this.notifications.updateOne({id:e},{status:t})}async markAllNotificationsRead(){return(await this.notifications.updateMany({status:"unread"},{status:"read"})).length}async deleteNotification(e){return await this.notifications.deleteOne({id:e})!==null}async clearOldNotifications(e=30){let t=new Date(Date.now()-e*24*60*60*1000);return(await this.notifications.deleteMany({createdAt:{$fn:(i)=>i instanceof Date&&i<t}})).length}async getPluginState(e,t){return(await this.pluginState.findOne({$and:[{pluginName:e},{key:t}]}))?.value}async setPluginState(e,t,i){await this.pluginState.upsert({$and:[{pluginName:e},{key:t}]},{pluginName:e,key:t,value:i})}async deletePluginState(e,t){return await this.pluginState.deleteOne({$and:[{pluginName:e},{key:t}]})!==null}async getAllPluginState(e){return(await this.pluginState.find({pluginName:e},{sort:{key:1}})).docs.map((t)=>{let i=t.updatedAt,s=i instanceof Date?i.toISOString():typeof i==="string"?i:void 0;return{key:t.key,value:t.value,updatedAt:s}})}async deleteAllPluginState(e){return(await this.pluginState.deleteMany({pluginName:e})).length}}var pa=(e)=>es.create(e);_a("skalex",pa);var oh=new Map;function ma(e,t){oh.set(e,t)}class ga{}ma("skalex",pa);var un=()=>new Date().toISOString();function T(e){if(!e)return e;let{_id:t,createdAt:i,updatedAt:s,_version:n,_expiresAt:r,...a}=e,l={...a};if(l.createdAt==null&&i!=null)l.createdAt=i instanceof Date?i.toISOString():String(i);if(l.updatedAt==null&&s!=null)l.updatedAt=s instanceof Date?s.toISOString():String(s);return l}class ts extends ga{dataDir;encryptionKey;lockPath;lockFd=null;db;tasks;config;gitRepos;bookmarks;notifications;pluginState;constructor(e){super();this.dataDir=e.dataDir,this.encryptionKey=e.encryptionKey,this.lockPath=go(e.dataDir,".agent-db.lock")}static async create(e){if(!uo(e.dataDir))_o(e.dataDir,{recursive:!0});let t=new ts(e);t.acquireLock();try{await t.init()}catch(i){throw t.releaseLock(),i}return t}acquireLock(){try{this.lockFd=fo(this.lockPath,"wx",384),mo(this.lockFd,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()}));return}catch(t){if(t.code!=="EEXIST")throw t}let e=!1;try{let t=JSON.parse(po(this.lockPath,"utf8"));if(!t.pid)e=!0;else try{process.kill(t.pid,0)}catch{e=!0}}catch{e=!0}if(e){try{us(this.lockPath)}catch{}this.acquireLock();return}throw Error(`Agent database is already open by another process (${this.lockPath})`)}releaseLock(){if(this.lockFd!==null){try{ho(this.lockFd)}catch{}this.lockFd=null}try{us(this.lockPath)}catch{}}async init(){this.db=new te({path:this.dataDir,encrypt:{key:this.encryptionKey},autoSave:!0,format:"gz",lenientLoad:!0}),this.tasks=this.db.createCollection("tasks",{schema:{id:{type:"string",required:!0,unique:!0},type:{type:"string",required:!0,enum:["command","script","file_operation"]},status:{type:"string",required:!0,enum:["pending","running","completed","failed"]},payload:{type:"string",required:!0},result:{type:"string"},error:{type:"string"},calendarTaskId:{type:"string"},exitCode:{type:"number"},timeout:{type:"number"}},indexes:["status","type"]}),this.config=this.db.createCollection("agent_config",{schema:{key:{type:"string",required:!0,unique:!0},value:{type:"string",required:!0}}}),this.gitRepos=this.db.createCollection("git_repositories",{schema:{id:{type:"string",required:!0,unique:!0},path:{type:"string",required:!0,unique:!0},name:{type:"string",required:!0},parentPath:{type:"string"},isSubmodule:{type:"boolean"},projectType:{type:"string"},vitePort:{type:"number"},lastScanned:{type:"string"}},indexes:["parentPath"]}),this.bookmarks=this.db.createCollection("bookmarked_commands",{schema:{id:{type:"string",required:!0,unique:!0},projectId:{type:"string"},command:{type:"string",required:!0},description:{type:"string"},category:{type:"string"}},indexes:["projectId","category"]}),this.notifications=this.db.createCollection("notifications",{schema:{id:{type:"string",required:!0,unique:!0},sessionName:{type:"string"},projectId:{type:"string"},type:{type:"string",required:!0,enum:["info","success","warning","error"]},title:{type:"string",required:!0},message:{type:"string",required:!0},status:{type:"string",required:!0,enum:["unread","read"]}},indexes:["status","projectId"]}),this.pluginState=this.db.createCollection("plugin_state",{schema:{pluginName:{type:"string",required:!0},key:{type:"string",required:!0},value:{type:"string",required:!0}},indexes:["pluginName"]}),await this.db.connect()}async close(){if(this.db?.isConnected)await this.db.disconnect();this.releaseLock()}getDbPath(){return this.dataDir}async createTask(e){let t={id:e.id,type:e.type,status:e.status,payload:e.payload};if(e.result!=null)t.result=e.result;if(e.error!=null)t.error=e.error;if(e.calendarTaskId!=null)t.calendarTaskId=e.calendarTaskId;if(e.exitCode!=null)t.exitCode=e.exitCode;if(e.timeout!=null)t.timeout=e.timeout;let i=await this.tasks.insertOne(t);return T(i)}async getTask(e){let t=await this.tasks.findOne({id:e});return t?T(t):void 0}async getAllTasks(){return(await this.tasks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>T(e))}async getPendingTasks(){return(await this.tasks.find({status:"pending"},{sort:{createdAt:1}})).docs.map((e)=>T(e))}async updateTask(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.tasks.updateOne({id:e},i)}async cancelTask(e){let t=await this.tasks.findOne({id:e});if(!t||t.status!=="pending"&&t.status!=="running")return!1;return await this.tasks.updateOne({id:e},{status:"failed",error:"Cancelled"}),!0}async getConfig(e){return(await this.config.findOne({key:e}))?.value}async setConfig(e,t){await this.config.upsert({key:e},{key:e,value:t})}async deleteConfig(e){return await this.config.deleteOne({key:e})!==null}async getAllConfig(){let e=await this.config.find(),t={};for(let i of e.docs)t[i.key]=i.value;return t}async bulkSetConfig(e){for(let[t,i]of Object.entries(e))await this.config.upsert({key:t},{key:t,value:i})}async getConfigStatus(){let e=await this.config.find(),t=null;for(let i of e.docs){let s=i.updatedAt,n=s instanceof Date?s.toISOString():typeof s==="string"?s:null;if(n&&(!t||n>t))t=n}return{totalKeys:e.docs.length,lastUpdated:t}}async createGitRepository(e){let t={id:e.id,path:e.path,name:e.name,isSubmodule:Boolean(e.isSubmodule),lastScanned:un()};if(e.parentPath!=null)t.parentPath=e.parentPath;if(e.projectType!=null)t.projectType=e.projectType;if(e.vitePort!=null)t.vitePort=e.vitePort;let i=await this.gitRepos.insertOne(t);return T(i)}async getGitRepository(e){let t=await this.gitRepos.findOne({id:e});return t?T(t):void 0}async getGitRepositoryByPath(e){let t=await this.gitRepos.findOne({path:e});return t?T(t):void 0}async getAllGitRepositories(){return(await this.gitRepos.find(void 0,{sort:{path:1}})).docs.map((e)=>T(e))}async updateGitRepository(e,t){let i={lastScanned:un()};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;if(s==="isSubmodule"){i[s]=Boolean(n);continue}i[s]=n??null}await this.gitRepos.updateOne({id:e},i)}async deleteGitRepository(e){return await this.gitRepos.deleteOne({id:e})!==null}async fixGitHierarchy(){let e=await this.getAllGitRepositories(),t=0;for(let i of e){if(i.isSubmodule)continue;let s=e.find((n)=>n.id!==i.id&&i.path.startsWith(`${n.path}/`)&&!n.isSubmodule);if(s&&i.parentPath!==s.path)await this.updateGitRepository(i.id,{parentPath:s.path}),t++}return{fixed:t}}async createBookmarkedCommand(e){let t={id:e.id,command:e.command};if(e.projectId!=null)t.projectId=e.projectId;if(e.description!=null)t.description=e.description;if(e.category!=null)t.category=e.category;let i=await this.bookmarks.insertOne(t);return T(i)}async getBookmarkedCommand(e){let t=await this.bookmarks.findOne({id:e});return t?T(t):void 0}async getAllBookmarkedCommands(){return(await this.bookmarks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>T(e))}async getBookmarkedCommandsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.bookmarks.find(t,{sort:{createdAt:-1}})).docs.map((i)=>T(i))}async getBookmarkedCommandsByCategory(e){return(await this.bookmarks.find({category:e},{sort:{createdAt:-1}})).docs.map((t)=>T(t))}async updateBookmarkedCommand(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.bookmarks.updateOne({id:e},i)}async deleteBookmarkedCommand(e){return await this.bookmarks.deleteOne({id:e})!==null}async executeBookmarkedCommand(e){return this.getBookmarkedCommand(e)}async createNotification(e){let t={id:e.id,type:e.type,title:e.title,message:e.message,status:e.status};if(e.sessionName!=null)t.sessionName=e.sessionName;if(e.projectId!=null)t.projectId=e.projectId;let i=await this.notifications.insertOne(t);return T(i)}async getNotification(e){let t=await this.notifications.findOne({id:e});return t?T(t):void 0}async getAllNotifications(){return(await this.notifications.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>T(e))}async getNotificationsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.notifications.find(t,{sort:{createdAt:-1}})).docs.map((i)=>T(i))}async getGlobalNotifications(){return this.getNotificationsByProject(null)}async getUnreadNotifications(){return(await this.notifications.find({status:"unread"},{sort:{createdAt:-1}})).docs.map((e)=>T(e))}async updateNotificationStatus(e,t){await this.notifications.updateOne({id:e},{status:t})}async markAllNotificationsRead(){return(await this.notifications.updateMany({status:"unread"},{status:"read"})).length}async deleteNotification(e){return await this.notifications.deleteOne({id:e})!==null}async clearOldNotifications(e=30){let t=new Date(Date.now()-e*24*60*60*1000);return(await this.notifications.deleteMany({createdAt:{$fn:(i)=>i instanceof Date&&i<t}})).length}async getPluginState(e,t){return(await this.pluginState.findOne({$and:[{pluginName:e},{key:t}]}))?.value}async setPluginState(e,t,i){await this.pluginState.upsert({$and:[{pluginName:e},{key:t}]},{pluginName:e,key:t,value:i})}async deletePluginState(e,t){return await this.pluginState.deleteOne({$and:[{pluginName:e},{key:t}]})!==null}async getAllPluginState(e){return(await this.pluginState.find({pluginName:e},{sort:{key:1}})).docs.map((t)=>{let i=t.updatedAt,s=i instanceof Date?i.toISOString():typeof i==="string"?i:void 0;return{key:t.key,value:t.value,updatedAt:s}})}async deleteAllPluginState(e){return(await this.pluginState.deleteMany({pluginName:e})).length}}var ya=(e)=>ts.create(e);ma("skalex",ya);var lh=new Map;function wa(e,t){lh.set(e,t)}class Aa{}wa("skalex",ya);var _n=()=>new Date().toISOString();function O(e){if(!e)return e;let{_id:t,createdAt:i,updatedAt:s,_version:n,_expiresAt:r,...a}=e,l={...a};if(l.createdAt==null&&i!=null)l.createdAt=i instanceof Date?i.toISOString():String(i);if(l.updatedAt==null&&s!=null)l.updatedAt=s instanceof Date?s.toISOString():String(s);return l}class is extends Aa{dataDir;encryptionKey;lockPath;lockFd=null;db;tasks;config;gitRepos;bookmarks;notifications;pluginState;constructor(e){super();this.dataDir=e.dataDir,this.encryptionKey=e.encryptionKey,this.lockPath=oo(e.dataDir,".agent-db.lock")}static async create(e){if(!io(e.dataDir))so(e.dataDir,{recursive:!0});let t=new is(e);t.acquireLock();try{await t.init()}catch(i){throw t.releaseLock(),i}return t}acquireLock(){try{this.lockFd=no(this.lockPath,"wx",384),ao(this.lockFd,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()}));return}catch(t){if(t.code!=="EEXIST")throw t}let e=!1;try{let t=JSON.parse(ro(this.lockPath,"utf8"));if(!t.pid)e=!0;else try{process.kill(t.pid,0)}catch{e=!0}}catch{e=!0}if(e){try{ds(this.lockPath)}catch{}this.acquireLock();return}throw Error(`Agent database is already open by another process (${this.lockPath})`)}releaseLock(){if(this.lockFd!==null){try{to(this.lockFd)}catch{}this.lockFd=null}try{ds(this.lockPath)}catch{}}async init(){this.db=new ee({path:this.dataDir,encrypt:{key:this.encryptionKey},autoSave:!0,format:"gz",lenientLoad:!0}),this.tasks=this.db.createCollection("tasks",{schema:{id:{type:"string",required:!0,unique:!0},type:{type:"string",required:!0,enum:["command","script","file_operation"]},status:{type:"string",required:!0,enum:["pending","running","completed","failed"]},payload:{type:"string",required:!0},result:{type:"string"},error:{type:"string"},calendarTaskId:{type:"string"},exitCode:{type:"number"},timeout:{type:"number"}},indexes:["status","type"]}),this.config=this.db.createCollection("agent_config",{schema:{key:{type:"string",required:!0,unique:!0},value:{type:"string",required:!0}}}),this.gitRepos=this.db.createCollection("git_repositories",{schema:{id:{type:"string",required:!0,unique:!0},path:{type:"string",required:!0,unique:!0},name:{type:"string",required:!0},parentPath:{type:"string"},isSubmodule:{type:"boolean"},projectType:{type:"string"},vitePort:{type:"number"},lastScanned:{type:"string"}},indexes:["parentPath"]}),this.bookmarks=this.db.createCollection("bookmarked_commands",{schema:{id:{type:"string",required:!0,unique:!0},projectId:{type:"string"},command:{type:"string",required:!0},description:{type:"string"},category:{type:"string"}},indexes:["projectId","category"]}),this.notifications=this.db.createCollection("notifications",{schema:{id:{type:"string",required:!0,unique:!0},sessionName:{type:"string"},projectId:{type:"string"},type:{type:"string",required:!0,enum:["info","success","warning","error"]},title:{type:"string",required:!0},message:{type:"string",required:!0},status:{type:"string",required:!0,enum:["unread","read"]}},indexes:["status","projectId"]}),this.pluginState=this.db.createCollection("plugin_state",{schema:{pluginName:{type:"string",required:!0},key:{type:"string",required:!0},value:{type:"string",required:!0}},indexes:["pluginName"]}),await this.db.connect()}async close(){if(this.db?.isConnected)await this.db.disconnect();this.releaseLock()}getDbPath(){return this.dataDir}async createTask(e){let t={id:e.id,type:e.type,status:e.status,payload:e.payload};if(e.result!=null)t.result=e.result;if(e.error!=null)t.error=e.error;if(e.calendarTaskId!=null)t.calendarTaskId=e.calendarTaskId;if(e.exitCode!=null)t.exitCode=e.exitCode;if(e.timeout!=null)t.timeout=e.timeout;let i=await this.tasks.insertOne(t);return O(i)}async getTask(e){let t=await this.tasks.findOne({id:e});return t?O(t):void 0}async getAllTasks(){return(await this.tasks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>O(e))}async getPendingTasks(){return(await this.tasks.find({status:"pending"},{sort:{createdAt:1}})).docs.map((e)=>O(e))}async updateTask(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.tasks.updateOne({id:e},i)}async cancelTask(e){let t=await this.tasks.findOne({id:e});if(!t||t.status!=="pending"&&t.status!=="running")return!1;return await this.tasks.updateOne({id:e},{status:"failed",error:"Cancelled"}),!0}async getConfig(e){return(await this.config.findOne({key:e}))?.value}async setConfig(e,t){await this.config.upsert({key:e},{key:e,value:t})}async deleteConfig(e){return await this.config.deleteOne({key:e})!==null}async getAllConfig(){let e=await this.config.find(),t={};for(let i of e.docs)t[i.key]=i.value;return t}async bulkSetConfig(e){for(let[t,i]of Object.entries(e))await this.config.upsert({key:t},{key:t,value:i})}async getConfigStatus(){let e=await this.config.find(),t=null;for(let i of e.docs){let s=i.updatedAt,n=s instanceof Date?s.toISOString():typeof s==="string"?s:null;if(n&&(!t||n>t))t=n}return{totalKeys:e.docs.length,lastUpdated:t}}async createGitRepository(e){let t={id:e.id,path:e.path,name:e.name,isSubmodule:Boolean(e.isSubmodule),lastScanned:_n()};if(e.parentPath!=null)t.parentPath=e.parentPath;if(e.projectType!=null)t.projectType=e.projectType;if(e.vitePort!=null)t.vitePort=e.vitePort;let i=await this.gitRepos.insertOne(t);return O(i)}async getGitRepository(e){let t=await this.gitRepos.findOne({id:e});return t?O(t):void 0}async getGitRepositoryByPath(e){let t=await this.gitRepos.findOne({path:e});return t?O(t):void 0}async getAllGitRepositories(){return(await this.gitRepos.find(void 0,{sort:{path:1}})).docs.map((e)=>O(e))}async updateGitRepository(e,t){let i={lastScanned:_n()};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;if(s==="isSubmodule"){i[s]=Boolean(n);continue}i[s]=n??null}await this.gitRepos.updateOne({id:e},i)}async deleteGitRepository(e){return await this.gitRepos.deleteOne({id:e})!==null}async fixGitHierarchy(){let e=await this.getAllGitRepositories(),t=0;for(let i of e){if(i.isSubmodule)continue;let s=e.find((n)=>n.id!==i.id&&i.path.startsWith(`${n.path}/`)&&!n.isSubmodule);if(s&&i.parentPath!==s.path)await this.updateGitRepository(i.id,{parentPath:s.path}),t++}return{fixed:t}}async createBookmarkedCommand(e){let t={id:e.id,command:e.command};if(e.projectId!=null)t.projectId=e.projectId;if(e.description!=null)t.description=e.description;if(e.category!=null)t.category=e.category;let i=await this.bookmarks.insertOne(t);return O(i)}async getBookmarkedCommand(e){let t=await this.bookmarks.findOne({id:e});return t?O(t):void 0}async getAllBookmarkedCommands(){return(await this.bookmarks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>O(e))}async getBookmarkedCommandsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.bookmarks.find(t,{sort:{createdAt:-1}})).docs.map((i)=>O(i))}async getBookmarkedCommandsByCategory(e){return(await this.bookmarks.find({category:e},{sort:{createdAt:-1}})).docs.map((t)=>O(t))}async updateBookmarkedCommand(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.bookmarks.updateOne({id:e},i)}async deleteBookmarkedCommand(e){return await this.bookmarks.deleteOne({id:e})!==null}async executeBookmarkedCommand(e){return this.getBookmarkedCommand(e)}async createNotification(e){let t={id:e.id,type:e.type,title:e.title,message:e.message,status:e.status};if(e.sessionName!=null)t.sessionName=e.sessionName;if(e.projectId!=null)t.projectId=e.projectId;let i=await this.notifications.insertOne(t);return O(i)}async getNotification(e){let t=await this.notifications.findOne({id:e});return t?O(t):void 0}async getAllNotifications(){return(await this.notifications.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>O(e))}async getNotificationsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.notifications.find(t,{sort:{createdAt:-1}})).docs.map((i)=>O(i))}async getGlobalNotifications(){return this.getNotificationsByProject(null)}async getUnreadNotifications(){return(await this.notifications.find({status:"unread"},{sort:{createdAt:-1}})).docs.map((e)=>O(e))}async updateNotificationStatus(e,t){await this.notifications.updateOne({id:e},{status:t})}async markAllNotificationsRead(){return(await this.notifications.updateMany({status:"unread"},{status:"read"})).length}async deleteNotification(e){return await this.notifications.deleteOne({id:e})!==null}async clearOldNotifications(e=30){let t=new Date(Date.now()-e*24*60*60*1000);return(await this.notifications.deleteMany({createdAt:{$fn:(i)=>i instanceof Date&&i<t}})).length}async getPluginState(e,t){return(await this.pluginState.findOne({$and:[{pluginName:e},{key:t}]}))?.value}async setPluginState(e,t,i){await this.pluginState.upsert({$and:[{pluginName:e},{key:t}]},{pluginName:e,key:t,value:i})}async deletePluginState(e,t){return await this.pluginState.deleteOne({$and:[{pluginName:e},{key:t}]})!==null}async getAllPluginState(e){return(await this.pluginState.find({pluginName:e},{sort:{key:1}})).docs.map((t)=>{let i=t.updatedAt,s=i instanceof Date?i.toISOString():typeof i==="string"?i:void 0;return{key:t.key,value:t.value,updatedAt:s}})}async deleteAllPluginState(e){return(await this.pluginState.deleteMany({pluginName:e})).length}}var xa=(e)=>is.create(e);wa("skalex",xa);var ss=new Map;function ch(e,t){ss.set(e,t)}function fn(e){return ss.get(e)}function hh(){return Array.from(ss.keys())}async function dh(e){if(e.adapterFactory)return e.adapterFactory;let t=e.adapterName??process.env.VIBE_STORAGE_ADAPTER??"skalex";if(t.startsWith("custom:")){let s=t.slice(7);if(!s)throw Error("VIBE_STORAGE_ADAPTER=custom: requires a module path after the colon");let n=await import(s),r=n.default??n.createAdapter;if(typeof r!=="function")throw Error(`Custom storage adapter at ${s} must export a default function (or \`createAdapter\`) of type AgentStorageAdapterFactory`);return r}let i=fn(t);if(!i){let s={skalex:"@vibecontrols/vibe-plugin-storage-skalex",postgres:"@vibecontrols/vibe-plugin-storage-postgres",postgresql:"@vibecontrols/vibe-plugin-storage-postgres"}[t];if(s)try{await import(s),i=fn(t)}catch{}}if(!i)throw Error(`Unknown storage adapter: "${t}". Registered adapters: ${hh().join(", ")||`(none \u2014 did you install @vibecontrols/vibe-plugin-storage-${t})?`}`);return i}async function va(e){if(!e.encryptionKey)throw Error("createAgentDatabase(): encryptionKey is required. Storage is always encrypted at rest.");if(!e.dbPath)throw Error("createAgentDatabase(): dbPath is required.");return(await dh(e))({dataDir:e.dbPath,encryptionKey:e.encryptionKey,adapterOptions:e.adapterOptions})}ch("skalex",xa);var uh="@vibecontrols/vibe-plugin-storage",fd=_h();function _h(){try{let e=ni(eo(import.meta.url));for(let t=0;t<10&&e&&e!==ni(e);t++){let i=Za(e,"package.json");if(Qa(i))try{let s=JSON.parse(Ga(i,"utf8"));if(s.name===uh&&typeof s.version==="string")return s.version}catch{}e=ni(e)}}catch{}return"0.0.0"}import Ht from"os";import{mkdirSync as fh}from"fs";import{join as ph}from"path";var ct="profile-reconciler",mh=60000,gh=5000,yh=30000,wh=15,Ah=200,xh=`
117
+ `))!==-1){let i=this._buffer.slice(0,t).trim();if(this._buffer=this._buffer.slice(t+1),i&&this._onMessage){let s;try{s=JSON.parse(i)}catch(n){this.send(Ce(null,Gi,"Parse error"));continue}this._onMessage(s).catch(()=>{})}}}),process.stdin.on("end",()=>{process.exit(0)})}stop(){process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),this._started=!1}}var nh={name:"skalex",version:"4.0.0-alpha"},rh="2024-11-05";class ha{constructor(e,t={}){this._db=e,this._transport=t.transport||"stdio",this._port=t.port||3000,this._host=t.host||"127.0.0.1",this._allowedOrigin=t.allowedOrigin??null,this._maxBodySize=t.maxBodySize??1048576,this._scopes=t.scopes||{"*":["read"]},this._t=null}async listen(){if(this._transport==="http")this._t=new la({port:this._port,host:this._host,allowedOrigin:this._allowedOrigin,maxBodySize:this._maxBodySize});else this._t=new ca;this._t.onMessage((e)=>this._handleMessage(e)),await this._t.start()}async connect(e){if(this._t=e,this._t.onMessage((t)=>this._handleMessage(t)),typeof this._t.start==="function")await this._t.start()}async close(){if(this._t&&typeof this._t.stop==="function")await this._t.stop();this._t=null}get transport(){return this._transport}get url(){return this._t?.url}async _handleMessage(e){let{msg:t,parseError:i}=typeof e==="string"?ih(e):{msg:e};if(i){this._send(i);return}let{id:s,method:n,params:r}=t;if(s===void 0){if(n==="notifications/initialized")return;return}try{switch(n){case"initialize":this._send(lt(s,{protocolVersion:rh,capabilities:{tools:{}},serverInfo:nh}));break;case"tools/list":this._send(lt(s,{tools:this._visibleTools()}));break;case"tools/call":await this._handleToolCall(s,r);break;case"ping":this._send(lt(s,{}));break;default:this._send(Ce(s,an,`Method not found: ${n}`))}}catch(a){this._send(Ce(s,th,a.message||"Internal error"))}}async _handleToolCall(e,t){let i=t?.name,s=t?.arguments??{};if(!i){this._send(Ce(e,eh,"tools/call requires params.name"));return}let n=rn.find((a)=>a.name===i);if(!n){this._send(Ce(e,an,`Unknown tool: ${i}`));return}let r=s.collection||s.collection_name||null;if(!this._hasScope(r,n.scope)){this._send(lt(e,on(`Access denied: "${i}" requires "${n.scope}" scope on collection "${r}".`)));return}try{let a=await Gc(i,s,this._db);this._send(lt(e,sh(JSON.stringify(a,null,2))))}catch(a){this._send(lt(e,on(a.message||String(a))))}}_visibleTools(){return rn.filter((e)=>{let t=this._scopes["*"];if(t&&(t.includes(e.scope)||t.includes("admin")))return!0;for(let[,i]of Object.entries(this._scopes))if(i.includes(e.scope)||i.includes("admin"))return!0;return!1})}_hasScope(e,t){let i=(s)=>s.includes("admin")||s.includes(t);if(e&&this._scopes[e])return i(this._scopes[e]);if(this._scopes["*"])return i(this._scopes["*"]);return!1}_send(e){this._t?.send(e)}}var Dt="migrations",ln=(e)=>JSON.stringify(e,function(t,i){let s=this[t];if(s instanceof Date)return{__skalex_date__:s.toISOString()};if(typeof i==="bigint")return{__skalex_bigint__:i.toString()};return i}),cn=(e)=>JSON.parse(e,(t,i)=>{if(i&&typeof i==="object"){if("__skalex_bigint__"in i)return BigInt(i.__skalex_bigint__);if("__skalex_date__"in i)return new Date(i.__skalex_date__)}return i});class se{constructor({path:e="./.db",format:t="gz",debug:i=!1,adapter:s,ai:n,encrypt:r,slowQueryLog:a,queryCache:l,memory:o,logger:c,plugins:h,llmAdapter:u,embeddingAdapter:d,regexMaxLength:_,idGenerator:f,serializer:p,deserializer:m,autoSave:w,ttlSweepInterval:x,lenientLoad:R}={}){if(this.dataDirectory=e,this.dataFormat=t,this.debug=i,!se._errorsAttached)se.SkalexError=Ke,se.ValidationError=C,se.UniqueConstraintError=Te,se.TransactionError=we,se.PersistenceError=Pe,se.AdapterError=pe,se.QueryError=et,se._errorsAttached=!0;this._adapterConfig=s??null;let E=s||new Br({dir:e,format:t});if(r)E=new ea(E,r.key);if(this.fs=E,this._registry=new Jr(zr),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._migrations=new Xr,this._connectPromise=null,this.isConnected=!1,this._aiConfig=n||null,this._encryptConfig=r||null,this._pluginsConfig=Array.isArray(h)?h:null,this._memoryConfig=o||null,this._regexMaxLength=_??500,this._idGenerator=f??null,this._serializer=p??ln,this._deserializer=m??cn,this._autoSave=w??!1,this._txManager=new Vr,this._ttlSweepInterval=x??0,this._ttlTimer=null,this._logger=c??Qs,this._embeddingAdapter=d??(n?Kc(n):null),this._aiAdapter=u??(n?Fc(n):null),this._persistence=new Hr({adapter:this.fs,serializer:this._serializer,deserializer:this._deserializer,logger:this._logger,debug:this.debug,lenientLoad:R??!1}),this._changeLog=new ia(this),this._queryCache=new sa(l||{}),this._eventBus=new na,this._queryLog=a?new ra(a):null,this._sessionStats=new aa,this._plugins=new oa,Array.isArray(h))for(let A of h)this._plugins.register(A)}async connect(){if(this._connectPromise)return this._connectPromise;return this._connectPromise=this._doConnect(),this._connectPromise}async _doConnect(){try{await this.loadData();let e=this._getMeta();if(e.queryCache)this._queryCache.fromJSON(e.queryCache);if(this._migrations._migrations.length>0){let t=e.appliedVersions||[],i=await this._migrations.run((s)=>this.useCollection(`_migration_${s}`),t);this._saveMeta({appliedVersions:i})}if(this._sweepTtl(),this._ttlSweepInterval>0){if(this._ttlTimer=setInterval(()=>this._sweepTtl(),this._ttlSweepInterval),this._ttlTimer?.unref)this._ttlTimer.unref()}this.isConnected=!0,this._log("> - Connected to the database (\u221A)")}catch(e){throw this._logger(`Error connecting to the database: ${e}`,"error"),e}}async disconnect(){try{if(this._ttlTimer)clearInterval(this._ttlTimer),this._ttlTimer=null;await this.saveData(),this._registry.clear(),this.collections=this._registry.stores,this._collectionInstances=this._registry._instances,this._connectPromise=null,this.isConnected=!1,this._log("> - Disconnected from the database (\u221A)")}catch(e){throw this._logger(`Error disconnecting from the database: ${e}`,"error"),e}}async _ensureConnected(){if(this.isConnected)return;return this.connect()}useCollection(e){return this._registry.get(e,this)}createCollection(e,t={}){return this._registry.create(e,t,this)}_createCollectionStore(e,t={}){this._registry.createStore(e,t)}async renameCollection(e,t){this._registry.rename(e,t),await this.saveData(t),await this.fs.delete(e)}async loadData(){await this._persistence.loadAll(this.collections,{parseSchema:qr,buildIndex:this._registry.buildIndex,IndexEngine:Lt});for(let e in this._collectionInstances){let t=this.collections[e];if(t&&this._collectionInstances[e]._store!==t)this._collectionInstances[e]._store=t}}async saveData(e){await this._persistence.save(this.collections,e)}buildIndex(e,t){return this._registry.buildIndex(e,t)}addMigration(e){this._migrations.add(e)}migrationStatus(){let e=this._getMeta();return this._migrations.status(e.appliedVersions||[])}namespace(e){if(this._adapterConfig)throw new pe("ERR_SKALEX_ADAPTER_NAMESPACE_REQUIRES_FS","namespace() requires the default FsAdapter. When a custom storage adapter is configured, create a separate Skalex instance with your adapter instead.");let t=String(e).replace(/[^a-zA-Z0-9_-]/g,"_");if(!t)throw new C("ERR_SKALEX_VALIDATION_NAMESPACE_ID","namespace: id must contain at least one alphanumeric character",{id:e});return new se({path:`${this.dataDirectory}/${t}`,format:this.dataFormat,debug:this.debug,ai:this._aiConfig||void 0,encrypt:this._encryptConfig||void 0,slowQueryLog:this._queryLog?{threshold:this._queryLog._threshold,maxEntries:this._queryLog._maxEntries}:void 0,queryCache:this._queryCache?{maxSize:this._queryCache._maxSize,ttl:this._queryCache._ttl}:void 0,plugins:this._pluginsConfig||void 0,memory:this._memoryConfig||void 0,logger:this._logger!==Qs?this._logger:void 0,llmAdapter:this._aiAdapter&&!this._aiConfig?this._aiAdapter:void 0,embeddingAdapter:this._embeddingAdapter&&!this._aiConfig?this._embeddingAdapter:void 0,regexMaxLength:this._regexMaxLength!==500?this._regexMaxLength:void 0,idGenerator:this._idGenerator||void 0,serializer:this._serializer!==ln?this._serializer:void 0,deserializer:this._deserializer!==cn?this._deserializer:void 0,autoSave:this._autoSave||void 0,ttlSweepInterval:this._ttlSweepInterval||void 0})}use(e){this._plugins.register(e)}watch(e){return this._eventBus.on("*",e)}sessionStats(e){if(e!==void 0)return this._sessionStats.get(e);return this._sessionStats.all()}get _inTransaction(){return this._txManager.active}_emitEvent(e,t){if(!this._txManager.defer(()=>this._eventBus.emit(e,t)))this._eventBus.emit(e,t)}async _runAfterHook(e,t){if(!this._txManager.defer(()=>this._plugins.run(e,t)))await this._plugins.run(e,t)}async _logChange(e,t,i,s,n){if(!this._txManager.defer(()=>this._changeLog.log(e,t,i,s,n)))await this._changeLog.log(e,t,i,s,n)}async transaction(e,t={}){return this._txManager.run(e,this,t)}async seed(e,{reset:t=!1}={}){for(let[i,s]of Object.entries(e)){if(t&&this.collections[i])this._applySnapshot(i,{data:[],index:new Map}),delete this._collectionInstances[i];await this.useCollection(i).insertMany(s)}await this.saveData()}dump(){return this._registry.dump()}inspect(e){return this._registry.inspect(e)}async import(e){let t=await this.fs.readRaw(e),i;try{i=JSON.parse(t)}catch{throw new Pe("ERR_SKALEX_PERSISTENCE_INVALID_JSON",`import: invalid JSON in file "${e}"`,{filePath:e})}let s=e.split("/").pop().replace(/\.[^.]+$/,"");return this.useCollection(s).insertMany(Array.isArray(i)?i:[i],{save:!0})}async embed(e){if(!this._embeddingAdapter)throw new pe("ERR_SKALEX_ADAPTER_EMBEDDING_REQUIRED","db.embed() requires an AI adapter. Pass { ai: { provider, apiKey } } to the Skalex constructor.");return this._embeddingAdapter.embed(e)}async ask(e,t,{limit:i=20}={}){if(!this._aiAdapter)throw new pe("ERR_SKALEX_ADAPTER_LLM_REQUIRED",'db.ask() requires a language model adapter. Configure { ai: { provider, model: "..." } }.');let s=this.useCollection(e),n=this.schema(e),r=this._queryCache.get(e,n,t);if(!r){r=await this._aiAdapter.generate(n,t);let a=Qc(r,n);if(a.length)a.forEach((l)=>this._log(`[ask] ${l}`));this._queryCache.set(e,n,t,r),this._saveMeta({queryCache:this._queryCache.toJSON()})}return s.find(Yc(r,{regexMaxLength:this._regexMaxLength}),{limit:i})}schema(e){return this._registry.schema(e)}useMemory(e){return new ta(e,this)}changelog(){return this._changeLog}async restore(e,t,i={}){return this._changeLog.restore(e,t,i)}stats(e){return this._registry.stats(e)}slowQueries(e={}){if(!this._queryLog)return[];return this._queryLog.entries(e)}slowQueryCount(){return this._queryLog?this._queryLog.size:0}clearSlowQueries(){this._queryLog?.clear()}mcp(e={}){return new ha(this,e)}_getMeta(){let e=this.collections._meta;if(!e)return{};return e.index.get(Dt)||{}}_saveMeta(e){if(!this.collections._meta)this._createCollectionStore("_meta");let t=this.collections._meta,i=t.index.get(Dt);if(i)Object.assign(i,e);else{let s={_id:Dt,...e};t.data.push(s),t.index.set(Dt,s)}this._persistence.markDirty(this.collections,"_meta")}_sweepTtl(){for(let e in this.collections){let t=this.collections[e],i=Rc(t.data,t.index,t.fieldIndex?(s)=>t.fieldIndex.remove(s):null);if(i>0)this._persistence.markDirty(this.collections,e),this._log(`TTL sweep: removed ${i} expired docs from "${e}"`)}}_buildCollectionContext(){let e=this;return{ensureConnected:()=>e._ensureConnected(),get txManager(){return e._txManager},get plugins(){return e._plugins},get eventBus(){return e._eventBus},get sessionStats(){return e._sessionStats},get queryLog(){return e._queryLog},get logger(){return e._logger},get persistence(){return e._persistence},get collections(){return e.collections},embed:(t)=>e.embed(t),get idGenerator(){return e._idGenerator},get autoSave(){return e._autoSave},saveCollection:(t)=>e.saveData(t),snapshotCollection:(t)=>e._snapshotCollection(t),getCollection:(t)=>e.useCollection(t),emitEvent:(t,i)=>e._emitEvent(t,i),runAfterHook:(t,i)=>e._runAfterHook(t,i),logChange:(t,i,s,n,r)=>e._logChange(t,i,s,n,r),get fs(){return e.fs},get dataDirectory(){return e.dataDirectory}}}_log(e){if(this.debug)this._logger(e,"info")}_snapshotCollection(e){return{data:structuredClone(e.data)}}_applySnapshot(e,t){let i=this.collections[e];if(!i)return;if(i.data=t.data,i.index=this.buildIndex(t.data,"_id"),i.fieldIndex)i.fieldIndex.buildFromData(t.data)}}class da{}var ah=new Map;function oh(e,t){ah.set(e,t)}var hn=()=>new Date().toISOString();function I(e){if(!e)return e;let{_id:t,createdAt:i,updatedAt:s,_version:n,_expiresAt:r,...a}=e,l={...a};if(l.createdAt==null&&i!=null)l.createdAt=i instanceof Date?i.toISOString():String(i);if(l.updatedAt==null&&s!=null)l.updatedAt=s instanceof Date?s.toISOString():String(s);return l}class Zi extends da{dataDir;encryptionKey;lockPath;lockFd=null;db;tasks;config;gitRepos;bookmarks;notifications;pluginState;constructor(e){super();this.dataDir=e.dataDir,this.encryptionKey=e.encryptionKey,this.lockPath=Mo(e.dataDir,".agent-db.lock")}static async create(e){if(!Co(e.dataDir))Ro(e.dataDir,{recursive:!0});let t=new Zi(e);t.acquireLock();try{await t.init()}catch(i){throw t.releaseLock(),i}return t}acquireLock(){try{this.lockFd=ko(this.lockPath,"wx",384),Po(this.lockFd,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()}));return}catch(t){if(t.code!=="EEXIST")throw t}let e=!1;try{let t=JSON.parse(Lo(this.lockPath,"utf8"));if(!t.pid)e=!0;else try{process.kill(t.pid,0)}catch{e=!0}}catch{e=!0}if(e){try{fs(this.lockPath)}catch{}this.acquireLock();return}throw Error(`Agent database is already open by another process (${this.lockPath})`)}releaseLock(){if(this.lockFd!==null){try{Do(this.lockFd)}catch{}this.lockFd=null}try{fs(this.lockPath)}catch{}}async init(){this.db=new se({path:this.dataDir,encrypt:{key:this.encryptionKey},autoSave:!0,format:"gz",lenientLoad:!0}),this.tasks=this.db.createCollection("tasks",{schema:{id:{type:"string",required:!0,unique:!0},type:{type:"string",required:!0,enum:["command","script","file_operation"]},status:{type:"string",required:!0,enum:["pending","running","completed","failed"]},payload:{type:"string",required:!0},result:{type:"string"},error:{type:"string"},calendarTaskId:{type:"string"},exitCode:{type:"number"},timeout:{type:"number"}},indexes:["status","type"]}),this.config=this.db.createCollection("agent_config",{schema:{key:{type:"string",required:!0,unique:!0},value:{type:"string",required:!0}}}),this.gitRepos=this.db.createCollection("git_repositories",{schema:{id:{type:"string",required:!0,unique:!0},path:{type:"string",required:!0,unique:!0},name:{type:"string",required:!0},parentPath:{type:"string"},isSubmodule:{type:"boolean"},projectType:{type:"string"},vitePort:{type:"number"},lastScanned:{type:"string"}},indexes:["parentPath"]}),this.bookmarks=this.db.createCollection("bookmarked_commands",{schema:{id:{type:"string",required:!0,unique:!0},projectId:{type:"string"},command:{type:"string",required:!0},description:{type:"string"},category:{type:"string"}},indexes:["projectId","category"]}),this.notifications=this.db.createCollection("notifications",{schema:{id:{type:"string",required:!0,unique:!0},sessionName:{type:"string"},projectId:{type:"string"},type:{type:"string",required:!0,enum:["info","success","warning","error"]},title:{type:"string",required:!0},message:{type:"string",required:!0},status:{type:"string",required:!0,enum:["unread","read"]}},indexes:["status","projectId"]}),this.pluginState=this.db.createCollection("plugin_state",{schema:{pluginName:{type:"string",required:!0},key:{type:"string",required:!0},value:{type:"string",required:!0}},indexes:["pluginName"]}),await this.db.connect()}async close(){if(this.db?.isConnected)await this.db.disconnect();this.releaseLock()}getDbPath(){return this.dataDir}async createTask(e){let t={id:e.id,type:e.type,status:e.status,payload:e.payload};if(e.result!=null)t.result=e.result;if(e.error!=null)t.error=e.error;if(e.calendarTaskId!=null)t.calendarTaskId=e.calendarTaskId;if(e.exitCode!=null)t.exitCode=e.exitCode;if(e.timeout!=null)t.timeout=e.timeout;let i=await this.tasks.insertOne(t);return I(i)}async getTask(e){let t=await this.tasks.findOne({id:e});return t?I(t):void 0}async getAllTasks(){return(await this.tasks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>I(e))}async getPendingTasks(){return(await this.tasks.find({status:"pending"},{sort:{createdAt:1}})).docs.map((e)=>I(e))}async updateTask(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.tasks.updateOne({id:e},i)}async cancelTask(e){let t=await this.tasks.findOne({id:e});if(!t||t.status!=="pending"&&t.status!=="running")return!1;return await this.tasks.updateOne({id:e},{status:"failed",error:"Cancelled"}),!0}async getConfig(e){return(await this.config.findOne({key:e}))?.value}async setConfig(e,t){await this.config.upsert({key:e},{key:e,value:t})}async deleteConfig(e){return await this.config.deleteOne({key:e})!==null}async getAllConfig(){let e=await this.config.find(),t={};for(let i of e.docs)t[i.key]=i.value;return t}async bulkSetConfig(e){for(let[t,i]of Object.entries(e))await this.config.upsert({key:t},{key:t,value:i})}async getConfigStatus(){let e=await this.config.find(),t=null;for(let i of e.docs){let s=i.updatedAt,n=s instanceof Date?s.toISOString():typeof s==="string"?s:null;if(n&&(!t||n>t))t=n}return{totalKeys:e.docs.length,lastUpdated:t}}async createGitRepository(e){let t={id:e.id,path:e.path,name:e.name,isSubmodule:Boolean(e.isSubmodule),lastScanned:hn()};if(e.parentPath!=null)t.parentPath=e.parentPath;if(e.projectType!=null)t.projectType=e.projectType;if(e.vitePort!=null)t.vitePort=e.vitePort;let i=await this.gitRepos.insertOne(t);return I(i)}async getGitRepository(e){let t=await this.gitRepos.findOne({id:e});return t?I(t):void 0}async getGitRepositoryByPath(e){let t=await this.gitRepos.findOne({path:e});return t?I(t):void 0}async getAllGitRepositories(){return(await this.gitRepos.find(void 0,{sort:{path:1}})).docs.map((e)=>I(e))}async updateGitRepository(e,t){let i={lastScanned:hn()};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;if(s==="isSubmodule"){i[s]=Boolean(n);continue}i[s]=n??null}await this.gitRepos.updateOne({id:e},i)}async deleteGitRepository(e){return await this.gitRepos.deleteOne({id:e})!==null}async fixGitHierarchy(){let e=await this.getAllGitRepositories(),t=0;for(let i of e){if(i.isSubmodule)continue;let s=e.find((n)=>n.id!==i.id&&i.path.startsWith(`${n.path}/`)&&!n.isSubmodule);if(s&&i.parentPath!==s.path)await this.updateGitRepository(i.id,{parentPath:s.path}),t++}return{fixed:t}}async createBookmarkedCommand(e){let t={id:e.id,command:e.command};if(e.projectId!=null)t.projectId=e.projectId;if(e.description!=null)t.description=e.description;if(e.category!=null)t.category=e.category;let i=await this.bookmarks.insertOne(t);return I(i)}async getBookmarkedCommand(e){let t=await this.bookmarks.findOne({id:e});return t?I(t):void 0}async getAllBookmarkedCommands(){return(await this.bookmarks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>I(e))}async getBookmarkedCommandsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.bookmarks.find(t,{sort:{createdAt:-1}})).docs.map((i)=>I(i))}async getBookmarkedCommandsByCategory(e){return(await this.bookmarks.find({category:e},{sort:{createdAt:-1}})).docs.map((t)=>I(t))}async updateBookmarkedCommand(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.bookmarks.updateOne({id:e},i)}async deleteBookmarkedCommand(e){return await this.bookmarks.deleteOne({id:e})!==null}async executeBookmarkedCommand(e){return this.getBookmarkedCommand(e)}async createNotification(e){let t={id:e.id,type:e.type,title:e.title,message:e.message,status:e.status};if(e.sessionName!=null)t.sessionName=e.sessionName;if(e.projectId!=null)t.projectId=e.projectId;let i=await this.notifications.insertOne(t);return I(i)}async getNotification(e){let t=await this.notifications.findOne({id:e});return t?I(t):void 0}async getAllNotifications(){return(await this.notifications.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>I(e))}async getNotificationsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.notifications.find(t,{sort:{createdAt:-1}})).docs.map((i)=>I(i))}async getGlobalNotifications(){return this.getNotificationsByProject(null)}async getUnreadNotifications(){return(await this.notifications.find({status:"unread"},{sort:{createdAt:-1}})).docs.map((e)=>I(e))}async updateNotificationStatus(e,t){await this.notifications.updateOne({id:e},{status:t})}async markAllNotificationsRead(){return(await this.notifications.updateMany({status:"unread"},{status:"read"})).length}async deleteNotification(e){return await this.notifications.deleteOne({id:e})!==null}async clearOldNotifications(e=30){let t=new Date(Date.now()-e*24*60*60*1000);return(await this.notifications.deleteMany({createdAt:{$fn:(i)=>i instanceof Date&&i<t}})).length}async getPluginState(e,t){return(await this.pluginState.findOne({$and:[{pluginName:e},{key:t}]}))?.value}async setPluginState(e,t,i){await this.pluginState.upsert({$and:[{pluginName:e},{key:t}]},{pluginName:e,key:t,value:i})}async deletePluginState(e,t){return await this.pluginState.deleteOne({$and:[{pluginName:e},{key:t}]})!==null}async getAllPluginState(e){return(await this.pluginState.find({pluginName:e},{sort:{key:1}})).docs.map((t)=>{let i=t.updatedAt,s=i instanceof Date?i.toISOString():typeof i==="string"?i:void 0;return{key:t.key,value:t.value,updatedAt:s}})}async deleteAllPluginState(e){return(await this.pluginState.deleteMany({pluginName:e})).length}}var ua=(e)=>Zi.create(e);oh("skalex",ua);var lh=new Map;function _a(e,t){lh.set(e,t)}class fa{}_a("skalex",ua);var dn=()=>new Date().toISOString();function b(e){if(!e)return e;let{_id:t,createdAt:i,updatedAt:s,_version:n,_expiresAt:r,...a}=e,l={...a};if(l.createdAt==null&&i!=null)l.createdAt=i instanceof Date?i.toISOString():String(i);if(l.updatedAt==null&&s!=null)l.updatedAt=s instanceof Date?s.toISOString():String(s);return l}class es extends fa{dataDir;encryptionKey;lockPath;lockFd=null;db;tasks;config;gitRepos;bookmarks;notifications;pluginState;constructor(e){super();this.dataDir=e.dataDir,this.encryptionKey=e.encryptionKey,this.lockPath=Oo(e.dataDir,".agent-db.lock")}static async create(e){if(!Eo(e.dataDir))So(e.dataDir,{recursive:!0});let t=new es(e);t.acquireLock();try{await t.init()}catch(i){throw t.releaseLock(),i}return t}acquireLock(){try{this.lockFd=Io(this.lockPath,"wx",384),To(this.lockFd,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()}));return}catch(t){if(t.code!=="EEXIST")throw t}let e=!1;try{let t=JSON.parse(bo(this.lockPath,"utf8"));if(!t.pid)e=!0;else try{process.kill(t.pid,0)}catch{e=!0}}catch{e=!0}if(e){try{_s(this.lockPath)}catch{}this.acquireLock();return}throw Error(`Agent database is already open by another process (${this.lockPath})`)}releaseLock(){if(this.lockFd!==null){try{vo(this.lockFd)}catch{}this.lockFd=null}try{_s(this.lockPath)}catch{}}async init(){this.db=new ie({path:this.dataDir,encrypt:{key:this.encryptionKey},autoSave:!0,format:"gz",lenientLoad:!0}),this.tasks=this.db.createCollection("tasks",{schema:{id:{type:"string",required:!0,unique:!0},type:{type:"string",required:!0,enum:["command","script","file_operation"]},status:{type:"string",required:!0,enum:["pending","running","completed","failed"]},payload:{type:"string",required:!0},result:{type:"string"},error:{type:"string"},calendarTaskId:{type:"string"},exitCode:{type:"number"},timeout:{type:"number"}},indexes:["status","type"]}),this.config=this.db.createCollection("agent_config",{schema:{key:{type:"string",required:!0,unique:!0},value:{type:"string",required:!0}}}),this.gitRepos=this.db.createCollection("git_repositories",{schema:{id:{type:"string",required:!0,unique:!0},path:{type:"string",required:!0,unique:!0},name:{type:"string",required:!0},parentPath:{type:"string"},isSubmodule:{type:"boolean"},projectType:{type:"string"},vitePort:{type:"number"},lastScanned:{type:"string"}},indexes:["parentPath"]}),this.bookmarks=this.db.createCollection("bookmarked_commands",{schema:{id:{type:"string",required:!0,unique:!0},projectId:{type:"string"},command:{type:"string",required:!0},description:{type:"string"},category:{type:"string"}},indexes:["projectId","category"]}),this.notifications=this.db.createCollection("notifications",{schema:{id:{type:"string",required:!0,unique:!0},sessionName:{type:"string"},projectId:{type:"string"},type:{type:"string",required:!0,enum:["info","success","warning","error"]},title:{type:"string",required:!0},message:{type:"string",required:!0},status:{type:"string",required:!0,enum:["unread","read"]}},indexes:["status","projectId"]}),this.pluginState=this.db.createCollection("plugin_state",{schema:{pluginName:{type:"string",required:!0},key:{type:"string",required:!0},value:{type:"string",required:!0}},indexes:["pluginName"]}),await this.db.connect()}async close(){if(this.db?.isConnected)await this.db.disconnect();this.releaseLock()}getDbPath(){return this.dataDir}async createTask(e){let t={id:e.id,type:e.type,status:e.status,payload:e.payload};if(e.result!=null)t.result=e.result;if(e.error!=null)t.error=e.error;if(e.calendarTaskId!=null)t.calendarTaskId=e.calendarTaskId;if(e.exitCode!=null)t.exitCode=e.exitCode;if(e.timeout!=null)t.timeout=e.timeout;let i=await this.tasks.insertOne(t);return b(i)}async getTask(e){let t=await this.tasks.findOne({id:e});return t?b(t):void 0}async getAllTasks(){return(await this.tasks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>b(e))}async getPendingTasks(){return(await this.tasks.find({status:"pending"},{sort:{createdAt:1}})).docs.map((e)=>b(e))}async updateTask(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.tasks.updateOne({id:e},i)}async cancelTask(e){let t=await this.tasks.findOne({id:e});if(!t||t.status!=="pending"&&t.status!=="running")return!1;return await this.tasks.updateOne({id:e},{status:"failed",error:"Cancelled"}),!0}async getConfig(e){return(await this.config.findOne({key:e}))?.value}async setConfig(e,t){await this.config.upsert({key:e},{key:e,value:t})}async deleteConfig(e){return await this.config.deleteOne({key:e})!==null}async getAllConfig(){let e=await this.config.find(),t={};for(let i of e.docs)t[i.key]=i.value;return t}async bulkSetConfig(e){for(let[t,i]of Object.entries(e))await this.config.upsert({key:t},{key:t,value:i})}async getConfigStatus(){let e=await this.config.find(),t=null;for(let i of e.docs){let s=i.updatedAt,n=s instanceof Date?s.toISOString():typeof s==="string"?s:null;if(n&&(!t||n>t))t=n}return{totalKeys:e.docs.length,lastUpdated:t}}async createGitRepository(e){let t={id:e.id,path:e.path,name:e.name,isSubmodule:Boolean(e.isSubmodule),lastScanned:dn()};if(e.parentPath!=null)t.parentPath=e.parentPath;if(e.projectType!=null)t.projectType=e.projectType;if(e.vitePort!=null)t.vitePort=e.vitePort;let i=await this.gitRepos.insertOne(t);return b(i)}async getGitRepository(e){let t=await this.gitRepos.findOne({id:e});return t?b(t):void 0}async getGitRepositoryByPath(e){let t=await this.gitRepos.findOne({path:e});return t?b(t):void 0}async getAllGitRepositories(){return(await this.gitRepos.find(void 0,{sort:{path:1}})).docs.map((e)=>b(e))}async updateGitRepository(e,t){let i={lastScanned:dn()};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;if(s==="isSubmodule"){i[s]=Boolean(n);continue}i[s]=n??null}await this.gitRepos.updateOne({id:e},i)}async deleteGitRepository(e){return await this.gitRepos.deleteOne({id:e})!==null}async fixGitHierarchy(){let e=await this.getAllGitRepositories(),t=0;for(let i of e){if(i.isSubmodule)continue;let s=e.find((n)=>n.id!==i.id&&i.path.startsWith(`${n.path}/`)&&!n.isSubmodule);if(s&&i.parentPath!==s.path)await this.updateGitRepository(i.id,{parentPath:s.path}),t++}return{fixed:t}}async createBookmarkedCommand(e){let t={id:e.id,command:e.command};if(e.projectId!=null)t.projectId=e.projectId;if(e.description!=null)t.description=e.description;if(e.category!=null)t.category=e.category;let i=await this.bookmarks.insertOne(t);return b(i)}async getBookmarkedCommand(e){let t=await this.bookmarks.findOne({id:e});return t?b(t):void 0}async getAllBookmarkedCommands(){return(await this.bookmarks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>b(e))}async getBookmarkedCommandsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.bookmarks.find(t,{sort:{createdAt:-1}})).docs.map((i)=>b(i))}async getBookmarkedCommandsByCategory(e){return(await this.bookmarks.find({category:e},{sort:{createdAt:-1}})).docs.map((t)=>b(t))}async updateBookmarkedCommand(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.bookmarks.updateOne({id:e},i)}async deleteBookmarkedCommand(e){return await this.bookmarks.deleteOne({id:e})!==null}async executeBookmarkedCommand(e){return this.getBookmarkedCommand(e)}async createNotification(e){let t={id:e.id,type:e.type,title:e.title,message:e.message,status:e.status};if(e.sessionName!=null)t.sessionName=e.sessionName;if(e.projectId!=null)t.projectId=e.projectId;let i=await this.notifications.insertOne(t);return b(i)}async getNotification(e){let t=await this.notifications.findOne({id:e});return t?b(t):void 0}async getAllNotifications(){return(await this.notifications.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>b(e))}async getNotificationsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.notifications.find(t,{sort:{createdAt:-1}})).docs.map((i)=>b(i))}async getGlobalNotifications(){return this.getNotificationsByProject(null)}async getUnreadNotifications(){return(await this.notifications.find({status:"unread"},{sort:{createdAt:-1}})).docs.map((e)=>b(e))}async updateNotificationStatus(e,t){await this.notifications.updateOne({id:e},{status:t})}async markAllNotificationsRead(){return(await this.notifications.updateMany({status:"unread"},{status:"read"})).length}async deleteNotification(e){return await this.notifications.deleteOne({id:e})!==null}async clearOldNotifications(e=30){let t=new Date(Date.now()-e*24*60*60*1000);return(await this.notifications.deleteMany({createdAt:{$fn:(i)=>i instanceof Date&&i<t}})).length}async getPluginState(e,t){return(await this.pluginState.findOne({$and:[{pluginName:e},{key:t}]}))?.value}async setPluginState(e,t,i){await this.pluginState.upsert({$and:[{pluginName:e},{key:t}]},{pluginName:e,key:t,value:i})}async deletePluginState(e,t){return await this.pluginState.deleteOne({$and:[{pluginName:e},{key:t}]})!==null}async getAllPluginState(e){return(await this.pluginState.find({pluginName:e},{sort:{key:1}})).docs.map((t)=>{let i=t.updatedAt,s=i instanceof Date?i.toISOString():typeof i==="string"?i:void 0;return{key:t.key,value:t.value,updatedAt:s}})}async deleteAllPluginState(e){return(await this.pluginState.deleteMany({pluginName:e})).length}}var pa=(e)=>es.create(e);_a("skalex",pa);var ch=new Map;function ma(e,t){ch.set(e,t)}class ga{}ma("skalex",pa);var un=()=>new Date().toISOString();function T(e){if(!e)return e;let{_id:t,createdAt:i,updatedAt:s,_version:n,_expiresAt:r,...a}=e,l={...a};if(l.createdAt==null&&i!=null)l.createdAt=i instanceof Date?i.toISOString():String(i);if(l.updatedAt==null&&s!=null)l.updatedAt=s instanceof Date?s.toISOString():String(s);return l}class ts extends ga{dataDir;encryptionKey;lockPath;lockFd=null;db;tasks;config;gitRepos;bookmarks;notifications;pluginState;constructor(e){super();this.dataDir=e.dataDir,this.encryptionKey=e.encryptionKey,this.lockPath=wo(e.dataDir,".agent-db.lock")}static async create(e){if(!fo(e.dataDir))po(e.dataDir,{recursive:!0});let t=new ts(e);t.acquireLock();try{await t.init()}catch(i){throw t.releaseLock(),i}return t}acquireLock(){try{this.lockFd=mo(this.lockPath,"wx",384),yo(this.lockFd,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()}));return}catch(t){if(t.code!=="EEXIST")throw t}let e=!1;try{let t=JSON.parse(go(this.lockPath,"utf8"));if(!t.pid)e=!0;else try{process.kill(t.pid,0)}catch{e=!0}}catch{e=!0}if(e){try{us(this.lockPath)}catch{}this.acquireLock();return}throw Error(`Agent database is already open by another process (${this.lockPath})`)}releaseLock(){if(this.lockFd!==null){try{_o(this.lockFd)}catch{}this.lockFd=null}try{us(this.lockPath)}catch{}}async init(){this.db=new te({path:this.dataDir,encrypt:{key:this.encryptionKey},autoSave:!0,format:"gz",lenientLoad:!0}),this.tasks=this.db.createCollection("tasks",{schema:{id:{type:"string",required:!0,unique:!0},type:{type:"string",required:!0,enum:["command","script","file_operation"]},status:{type:"string",required:!0,enum:["pending","running","completed","failed"]},payload:{type:"string",required:!0},result:{type:"string"},error:{type:"string"},calendarTaskId:{type:"string"},exitCode:{type:"number"},timeout:{type:"number"}},indexes:["status","type"]}),this.config=this.db.createCollection("agent_config",{schema:{key:{type:"string",required:!0,unique:!0},value:{type:"string",required:!0}}}),this.gitRepos=this.db.createCollection("git_repositories",{schema:{id:{type:"string",required:!0,unique:!0},path:{type:"string",required:!0,unique:!0},name:{type:"string",required:!0},parentPath:{type:"string"},isSubmodule:{type:"boolean"},projectType:{type:"string"},vitePort:{type:"number"},lastScanned:{type:"string"}},indexes:["parentPath"]}),this.bookmarks=this.db.createCollection("bookmarked_commands",{schema:{id:{type:"string",required:!0,unique:!0},projectId:{type:"string"},command:{type:"string",required:!0},description:{type:"string"},category:{type:"string"}},indexes:["projectId","category"]}),this.notifications=this.db.createCollection("notifications",{schema:{id:{type:"string",required:!0,unique:!0},sessionName:{type:"string"},projectId:{type:"string"},type:{type:"string",required:!0,enum:["info","success","warning","error"]},title:{type:"string",required:!0},message:{type:"string",required:!0},status:{type:"string",required:!0,enum:["unread","read"]}},indexes:["status","projectId"]}),this.pluginState=this.db.createCollection("plugin_state",{schema:{pluginName:{type:"string",required:!0},key:{type:"string",required:!0},value:{type:"string",required:!0}},indexes:["pluginName"]}),await this.db.connect()}async close(){if(this.db?.isConnected)await this.db.disconnect();this.releaseLock()}getDbPath(){return this.dataDir}async createTask(e){let t={id:e.id,type:e.type,status:e.status,payload:e.payload};if(e.result!=null)t.result=e.result;if(e.error!=null)t.error=e.error;if(e.calendarTaskId!=null)t.calendarTaskId=e.calendarTaskId;if(e.exitCode!=null)t.exitCode=e.exitCode;if(e.timeout!=null)t.timeout=e.timeout;let i=await this.tasks.insertOne(t);return T(i)}async getTask(e){let t=await this.tasks.findOne({id:e});return t?T(t):void 0}async getAllTasks(){return(await this.tasks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>T(e))}async getPendingTasks(){return(await this.tasks.find({status:"pending"},{sort:{createdAt:1}})).docs.map((e)=>T(e))}async updateTask(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.tasks.updateOne({id:e},i)}async cancelTask(e){let t=await this.tasks.findOne({id:e});if(!t||t.status!=="pending"&&t.status!=="running")return!1;return await this.tasks.updateOne({id:e},{status:"failed",error:"Cancelled"}),!0}async getConfig(e){return(await this.config.findOne({key:e}))?.value}async setConfig(e,t){await this.config.upsert({key:e},{key:e,value:t})}async deleteConfig(e){return await this.config.deleteOne({key:e})!==null}async getAllConfig(){let e=await this.config.find(),t={};for(let i of e.docs)t[i.key]=i.value;return t}async bulkSetConfig(e){for(let[t,i]of Object.entries(e))await this.config.upsert({key:t},{key:t,value:i})}async getConfigStatus(){let e=await this.config.find(),t=null;for(let i of e.docs){let s=i.updatedAt,n=s instanceof Date?s.toISOString():typeof s==="string"?s:null;if(n&&(!t||n>t))t=n}return{totalKeys:e.docs.length,lastUpdated:t}}async createGitRepository(e){let t={id:e.id,path:e.path,name:e.name,isSubmodule:Boolean(e.isSubmodule),lastScanned:un()};if(e.parentPath!=null)t.parentPath=e.parentPath;if(e.projectType!=null)t.projectType=e.projectType;if(e.vitePort!=null)t.vitePort=e.vitePort;let i=await this.gitRepos.insertOne(t);return T(i)}async getGitRepository(e){let t=await this.gitRepos.findOne({id:e});return t?T(t):void 0}async getGitRepositoryByPath(e){let t=await this.gitRepos.findOne({path:e});return t?T(t):void 0}async getAllGitRepositories(){return(await this.gitRepos.find(void 0,{sort:{path:1}})).docs.map((e)=>T(e))}async updateGitRepository(e,t){let i={lastScanned:un()};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;if(s==="isSubmodule"){i[s]=Boolean(n);continue}i[s]=n??null}await this.gitRepos.updateOne({id:e},i)}async deleteGitRepository(e){return await this.gitRepos.deleteOne({id:e})!==null}async fixGitHierarchy(){let e=await this.getAllGitRepositories(),t=0;for(let i of e){if(i.isSubmodule)continue;let s=e.find((n)=>n.id!==i.id&&i.path.startsWith(`${n.path}/`)&&!n.isSubmodule);if(s&&i.parentPath!==s.path)await this.updateGitRepository(i.id,{parentPath:s.path}),t++}return{fixed:t}}async createBookmarkedCommand(e){let t={id:e.id,command:e.command};if(e.projectId!=null)t.projectId=e.projectId;if(e.description!=null)t.description=e.description;if(e.category!=null)t.category=e.category;let i=await this.bookmarks.insertOne(t);return T(i)}async getBookmarkedCommand(e){let t=await this.bookmarks.findOne({id:e});return t?T(t):void 0}async getAllBookmarkedCommands(){return(await this.bookmarks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>T(e))}async getBookmarkedCommandsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.bookmarks.find(t,{sort:{createdAt:-1}})).docs.map((i)=>T(i))}async getBookmarkedCommandsByCategory(e){return(await this.bookmarks.find({category:e},{sort:{createdAt:-1}})).docs.map((t)=>T(t))}async updateBookmarkedCommand(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.bookmarks.updateOne({id:e},i)}async deleteBookmarkedCommand(e){return await this.bookmarks.deleteOne({id:e})!==null}async executeBookmarkedCommand(e){return this.getBookmarkedCommand(e)}async createNotification(e){let t={id:e.id,type:e.type,title:e.title,message:e.message,status:e.status};if(e.sessionName!=null)t.sessionName=e.sessionName;if(e.projectId!=null)t.projectId=e.projectId;let i=await this.notifications.insertOne(t);return T(i)}async getNotification(e){let t=await this.notifications.findOne({id:e});return t?T(t):void 0}async getAllNotifications(){return(await this.notifications.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>T(e))}async getNotificationsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.notifications.find(t,{sort:{createdAt:-1}})).docs.map((i)=>T(i))}async getGlobalNotifications(){return this.getNotificationsByProject(null)}async getUnreadNotifications(){return(await this.notifications.find({status:"unread"},{sort:{createdAt:-1}})).docs.map((e)=>T(e))}async updateNotificationStatus(e,t){await this.notifications.updateOne({id:e},{status:t})}async markAllNotificationsRead(){return(await this.notifications.updateMany({status:"unread"},{status:"read"})).length}async deleteNotification(e){return await this.notifications.deleteOne({id:e})!==null}async clearOldNotifications(e=30){let t=new Date(Date.now()-e*24*60*60*1000);return(await this.notifications.deleteMany({createdAt:{$fn:(i)=>i instanceof Date&&i<t}})).length}async getPluginState(e,t){return(await this.pluginState.findOne({$and:[{pluginName:e},{key:t}]}))?.value}async setPluginState(e,t,i){await this.pluginState.upsert({$and:[{pluginName:e},{key:t}]},{pluginName:e,key:t,value:i})}async deletePluginState(e,t){return await this.pluginState.deleteOne({$and:[{pluginName:e},{key:t}]})!==null}async getAllPluginState(e){return(await this.pluginState.find({pluginName:e},{sort:{key:1}})).docs.map((t)=>{let i=t.updatedAt,s=i instanceof Date?i.toISOString():typeof i==="string"?i:void 0;return{key:t.key,value:t.value,updatedAt:s}})}async deleteAllPluginState(e){return(await this.pluginState.deleteMany({pluginName:e})).length}}var ya=(e)=>ts.create(e);ma("skalex",ya);var hh=new Map;function wa(e,t){hh.set(e,t)}class Aa{}wa("skalex",ya);var _n=()=>new Date().toISOString();function O(e){if(!e)return e;let{_id:t,createdAt:i,updatedAt:s,_version:n,_expiresAt:r,...a}=e,l={...a};if(l.createdAt==null&&i!=null)l.createdAt=i instanceof Date?i.toISOString():String(i);if(l.updatedAt==null&&s!=null)l.updatedAt=s instanceof Date?s.toISOString():String(s);return l}class is extends Aa{dataDir;encryptionKey;lockPath;lockFd=null;db;tasks;config;gitRepos;bookmarks;notifications;pluginState;constructor(e){super();this.dataDir=e.dataDir,this.encryptionKey=e.encryptionKey,this.lockPath=co(e.dataDir,".agent-db.lock")}static async create(e){if(!no(e.dataDir))ro(e.dataDir,{recursive:!0});let t=new is(e);t.acquireLock();try{await t.init()}catch(i){throw t.releaseLock(),i}return t}acquireLock(){try{this.lockFd=ao(this.lockPath,"wx",384),lo(this.lockFd,JSON.stringify({pid:process.pid,createdAt:new Date().toISOString()}));return}catch(t){if(t.code!=="EEXIST")throw t}let e=!1;try{let t=JSON.parse(oo(this.lockPath,"utf8"));if(!t.pid)e=!0;else try{process.kill(t.pid,0)}catch{e=!0}}catch{e=!0}if(e){try{ds(this.lockPath)}catch{}this.acquireLock();return}throw Error(`Agent database is already open by another process (${this.lockPath})`)}releaseLock(){if(this.lockFd!==null){try{so(this.lockFd)}catch{}this.lockFd=null}try{ds(this.lockPath)}catch{}}async init(){this.db=new ee({path:this.dataDir,encrypt:{key:this.encryptionKey},autoSave:!0,format:"gz",lenientLoad:!0}),this.tasks=this.db.createCollection("tasks",{schema:{id:{type:"string",required:!0,unique:!0},type:{type:"string",required:!0,enum:["command","script","file_operation"]},status:{type:"string",required:!0,enum:["pending","running","completed","failed"]},payload:{type:"string",required:!0},result:{type:"string"},error:{type:"string"},calendarTaskId:{type:"string"},exitCode:{type:"number"},timeout:{type:"number"}},indexes:["status","type"]}),this.config=this.db.createCollection("agent_config",{schema:{key:{type:"string",required:!0,unique:!0},value:{type:"string",required:!0}}}),this.gitRepos=this.db.createCollection("git_repositories",{schema:{id:{type:"string",required:!0,unique:!0},path:{type:"string",required:!0,unique:!0},name:{type:"string",required:!0},parentPath:{type:"string"},isSubmodule:{type:"boolean"},projectType:{type:"string"},vitePort:{type:"number"},lastScanned:{type:"string"}},indexes:["parentPath"]}),this.bookmarks=this.db.createCollection("bookmarked_commands",{schema:{id:{type:"string",required:!0,unique:!0},projectId:{type:"string"},command:{type:"string",required:!0},description:{type:"string"},category:{type:"string"}},indexes:["projectId","category"]}),this.notifications=this.db.createCollection("notifications",{schema:{id:{type:"string",required:!0,unique:!0},sessionName:{type:"string"},projectId:{type:"string"},type:{type:"string",required:!0,enum:["info","success","warning","error"]},title:{type:"string",required:!0},message:{type:"string",required:!0},status:{type:"string",required:!0,enum:["unread","read"]}},indexes:["status","projectId"]}),this.pluginState=this.db.createCollection("plugin_state",{schema:{pluginName:{type:"string",required:!0},key:{type:"string",required:!0},value:{type:"string",required:!0}},indexes:["pluginName"]}),await this.db.connect()}async close(){if(this.db?.isConnected)await this.db.disconnect();this.releaseLock()}getDbPath(){return this.dataDir}async createTask(e){let t={id:e.id,type:e.type,status:e.status,payload:e.payload};if(e.result!=null)t.result=e.result;if(e.error!=null)t.error=e.error;if(e.calendarTaskId!=null)t.calendarTaskId=e.calendarTaskId;if(e.exitCode!=null)t.exitCode=e.exitCode;if(e.timeout!=null)t.timeout=e.timeout;let i=await this.tasks.insertOne(t);return O(i)}async getTask(e){let t=await this.tasks.findOne({id:e});return t?O(t):void 0}async getAllTasks(){return(await this.tasks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>O(e))}async getPendingTasks(){return(await this.tasks.find({status:"pending"},{sort:{createdAt:1}})).docs.map((e)=>O(e))}async updateTask(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.tasks.updateOne({id:e},i)}async cancelTask(e){let t=await this.tasks.findOne({id:e});if(!t||t.status!=="pending"&&t.status!=="running")return!1;return await this.tasks.updateOne({id:e},{status:"failed",error:"Cancelled"}),!0}async getConfig(e){return(await this.config.findOne({key:e}))?.value}async setConfig(e,t){await this.config.upsert({key:e},{key:e,value:t})}async deleteConfig(e){return await this.config.deleteOne({key:e})!==null}async getAllConfig(){let e=await this.config.find(),t={};for(let i of e.docs)t[i.key]=i.value;return t}async bulkSetConfig(e){for(let[t,i]of Object.entries(e))await this.config.upsert({key:t},{key:t,value:i})}async getConfigStatus(){let e=await this.config.find(),t=null;for(let i of e.docs){let s=i.updatedAt,n=s instanceof Date?s.toISOString():typeof s==="string"?s:null;if(n&&(!t||n>t))t=n}return{totalKeys:e.docs.length,lastUpdated:t}}async createGitRepository(e){let t={id:e.id,path:e.path,name:e.name,isSubmodule:Boolean(e.isSubmodule),lastScanned:_n()};if(e.parentPath!=null)t.parentPath=e.parentPath;if(e.projectType!=null)t.projectType=e.projectType;if(e.vitePort!=null)t.vitePort=e.vitePort;let i=await this.gitRepos.insertOne(t);return O(i)}async getGitRepository(e){let t=await this.gitRepos.findOne({id:e});return t?O(t):void 0}async getGitRepositoryByPath(e){let t=await this.gitRepos.findOne({path:e});return t?O(t):void 0}async getAllGitRepositories(){return(await this.gitRepos.find(void 0,{sort:{path:1}})).docs.map((e)=>O(e))}async updateGitRepository(e,t){let i={lastScanned:_n()};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;if(s==="isSubmodule"){i[s]=Boolean(n);continue}i[s]=n??null}await this.gitRepos.updateOne({id:e},i)}async deleteGitRepository(e){return await this.gitRepos.deleteOne({id:e})!==null}async fixGitHierarchy(){let e=await this.getAllGitRepositories(),t=0;for(let i of e){if(i.isSubmodule)continue;let s=e.find((n)=>n.id!==i.id&&i.path.startsWith(`${n.path}/`)&&!n.isSubmodule);if(s&&i.parentPath!==s.path)await this.updateGitRepository(i.id,{parentPath:s.path}),t++}return{fixed:t}}async createBookmarkedCommand(e){let t={id:e.id,command:e.command};if(e.projectId!=null)t.projectId=e.projectId;if(e.description!=null)t.description=e.description;if(e.category!=null)t.category=e.category;let i=await this.bookmarks.insertOne(t);return O(i)}async getBookmarkedCommand(e){let t=await this.bookmarks.findOne({id:e});return t?O(t):void 0}async getAllBookmarkedCommands(){return(await this.bookmarks.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>O(e))}async getBookmarkedCommandsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.bookmarks.find(t,{sort:{createdAt:-1}})).docs.map((i)=>O(i))}async getBookmarkedCommandsByCategory(e){return(await this.bookmarks.find({category:e},{sort:{createdAt:-1}})).docs.map((t)=>O(t))}async updateBookmarkedCommand(e,t){let i={};for(let[s,n]of Object.entries(t)){if(s==="id"||s==="createdAt"||s==="updatedAt")continue;i[s]=n??null}if(Object.keys(i).length===0)return;await this.bookmarks.updateOne({id:e},i)}async deleteBookmarkedCommand(e){return await this.bookmarks.deleteOne({id:e})!==null}async executeBookmarkedCommand(e){return this.getBookmarkedCommand(e)}async createNotification(e){let t={id:e.id,type:e.type,title:e.title,message:e.message,status:e.status};if(e.sessionName!=null)t.sessionName=e.sessionName;if(e.projectId!=null)t.projectId=e.projectId;let i=await this.notifications.insertOne(t);return O(i)}async getNotification(e){let t=await this.notifications.findOne({id:e});return t?O(t):void 0}async getAllNotifications(){return(await this.notifications.find(void 0,{sort:{createdAt:-1}})).docs.map((e)=>O(e))}async getNotificationsByProject(e){let t=e===null?{projectId:{$fn:(i)=>i==null}}:{projectId:e};return(await this.notifications.find(t,{sort:{createdAt:-1}})).docs.map((i)=>O(i))}async getGlobalNotifications(){return this.getNotificationsByProject(null)}async getUnreadNotifications(){return(await this.notifications.find({status:"unread"},{sort:{createdAt:-1}})).docs.map((e)=>O(e))}async updateNotificationStatus(e,t){await this.notifications.updateOne({id:e},{status:t})}async markAllNotificationsRead(){return(await this.notifications.updateMany({status:"unread"},{status:"read"})).length}async deleteNotification(e){return await this.notifications.deleteOne({id:e})!==null}async clearOldNotifications(e=30){let t=new Date(Date.now()-e*24*60*60*1000);return(await this.notifications.deleteMany({createdAt:{$fn:(i)=>i instanceof Date&&i<t}})).length}async getPluginState(e,t){return(await this.pluginState.findOne({$and:[{pluginName:e},{key:t}]}))?.value}async setPluginState(e,t,i){await this.pluginState.upsert({$and:[{pluginName:e},{key:t}]},{pluginName:e,key:t,value:i})}async deletePluginState(e,t){return await this.pluginState.deleteOne({$and:[{pluginName:e},{key:t}]})!==null}async getAllPluginState(e){return(await this.pluginState.find({pluginName:e},{sort:{key:1}})).docs.map((t)=>{let i=t.updatedAt,s=i instanceof Date?i.toISOString():typeof i==="string"?i:void 0;return{key:t.key,value:t.value,updatedAt:s}})}async deleteAllPluginState(e){return(await this.pluginState.deleteMany({pluginName:e})).length}}var xa=(e)=>is.create(e);wa("skalex",xa);var ss=new Map;function dh(e,t){ss.set(e,t)}function fn(e){return ss.get(e)}function uh(){return Array.from(ss.keys())}async function _h(e){if(e.adapterFactory)return e.adapterFactory;let t=e.adapterName??process.env.VIBE_STORAGE_ADAPTER??"skalex";if(t.startsWith("custom:")){let s=t.slice(7);if(!s)throw Error("VIBE_STORAGE_ADAPTER=custom: requires a module path after the colon");let n=await import(s),r=n.default??n.createAdapter;if(typeof r!=="function")throw Error(`Custom storage adapter at ${s} must export a default function (or \`createAdapter\`) of type AgentStorageAdapterFactory`);return r}let i=fn(t);if(!i){let s={skalex:"@vibecontrols/vibe-plugin-storage-skalex",postgres:"@vibecontrols/vibe-plugin-storage-postgres",postgresql:"@vibecontrols/vibe-plugin-storage-postgres"}[t];if(s)try{await import(s),i=fn(t)}catch{}}if(!i)throw Error(`Unknown storage adapter: "${t}". Registered adapters: ${uh().join(", ")||`(none \u2014 did you install @vibecontrols/vibe-plugin-storage-${t})?`}`);return i}async function va(e){if(!e.encryptionKey)throw Error("createAgentDatabase(): encryptionKey is required. Storage is always encrypted at rest.");if(!e.dbPath)throw Error("createAgentDatabase(): dbPath is required.");return(await _h(e))({dataDir:e.dbPath,encryptionKey:e.encryptionKey,adapterOptions:e.adapterOptions})}dh("skalex",xa);var fh="@vibecontrols/vibe-plugin-storage",pd=ph();function ph(){try{let e=ni(io(import.meta.url));for(let t=0;t<10&&e&&e!==ni(e);t++){let i=to(e,"package.json");if(Za(i))try{let s=JSON.parse(eo(i,"utf8"));if(s.name===fh&&typeof s.version==="string")return s.version}catch{}e=ni(e)}}catch{}return"0.0.0"}import Ht from"os";import{mkdirSync as mh}from"fs";import{join as gh}from"path";var ct="profile-reconciler",yh=60000,wh=5000,Ah=30000,xh=15,vh=200,Eh=`
118
118
  query VibecontrolsAgentProfiles($agentId: ID!) {
119
119
  vibecontrolsAgentProfiles(agentId: $agentId) {
120
120
  id
@@ -123,14 +123,14 @@ data: /message
123
123
  isDefault
124
124
  }
125
125
  }
126
- `,vh=`
126
+ `,Sh=`
127
127
  mutation UpdateVibecontrolsAgentProfile($id: ID!, $input: UpdateVibecontrolsAgentProfileInput!) {
128
128
  updateVibecontrolsAgentProfile(id: $id, input: $input) {
129
129
  id
130
130
  status
131
131
  }
132
132
  }
133
- `;function Bt(e){return ph(Ia(),"agents",Xt(e))}async function $a(e){try{let t=await yt({dir:Bt(e),scope:Xt(e)});return Boolean(t.clientId&&t.clientSecret)}catch{return!1}}async function Eh(e){for(let t=0;t<wh;t++){if(await $a(e))return!0;await new Promise((i)=>setTimeout(i,Ah))}return!1}async function Sh(e,t,i){let s,n=new Promise((r,a)=>{s=setTimeout(()=>a(Error(`${i} timed out after ${t}ms`)),t)});try{return await Promise.race([e,n])}finally{if(s)clearTimeout(s)}}var ht=null,ns=!1;async function Ea(e,t){try{await v.workspaceQuery(vh,{id:e,input:{status:t}})}catch{}}async function Sa(e){if(!v.isConfigured()||ns)return;ns=!0;let t=g().logger;try{let i=await e.getConfig("gateway-auth:agentRecordId");if(!i)return;let s=await v.workspaceQuery(xh,{agentId:i});if(s.errors?.length)return;let n=s.data?.vibecontrolsAgentProfiles??[];if(n.length===0)return;let r=g().name,a;try{a=await yt({dir:Bt(r),scope:r})}catch{a=void 0}for(let l of n){if(l.isDefault||l.name===r||l.name==="default")continue;let o=Ta.get(l.name);if(o&&o.getBootState()==="ready"){if(l.status!=="ready")await Ea(l.id,"ready");continue}if(a?.clientId&&a.clientSecret&&!await $a(l.name))try{if(fh(Bt(l.name),{recursive:!0}),ba({globalGatewayUrl:a.globalGatewayUrl,workspaceGatewayUrl:a.workspaceGatewayUrl,workspaceId:a.workspaceId,organizationId:a.organizationId,clientId:a.clientId,clientSecret:a.clientSecret},{dir:Bt(l.name),scope:Xt(l.name)}),!await Eh(l.name)){t.warn(ct,`Seeded creds for profile '${l.name}' not yet readable; retrying next tick`);continue}}catch(c){t.warn(ct,`Failed to seed config for profile '${l.name}'`,{error:c instanceof Error?c.message:String(c)});continue}t.info(ct,`Reconciling desired profile '${l.name}' from control plane`);try{let c=Oa(l.name),h=await Sh(Na(c),yh,`attach '${l.name}'`),u=c.getBootState();await Ea(l.id,u),t.info(ct,`Profile '${l.name}' reconciled`,{ok:h.ok,status:u,error:h.error})}catch(c){t.warn(ct,`Failed to reconcile profile '${l.name}'`,{error:c instanceof Error?c.message:String(c)})}}}catch(i){g().logger.debug(ct,`Reconcile pass failed: ${i instanceof Error?i.message:String(i)}`)}finally{ns=!1}}function dt(e,t){if(ht)return;let i=Number(process.env.VIBE_PROFILE_RECONCILE_MS),s=Number.isFinite(i)&&i>0?Math.max(i,gh):t??mh;Sa(e),ht=setInterval(()=>{Sa(e)},s),ht.unref?.()}function Ed(){if(ht)clearInterval(ht),ht=null}var Fe=10,rs=3000,y="auto-report",Ih=`
133
+ `;function Bt(e){return gh(Ia(),"agents",Xt(e))}async function $a(e){try{let t=await yt({dir:Bt(e),scope:Xt(e)});return Boolean(t.clientId&&t.clientSecret)}catch{return!1}}async function Ih(e){for(let t=0;t<xh;t++){if(await $a(e))return!0;await new Promise((i)=>setTimeout(i,vh))}return!1}async function bh(e,t,i){let s,n=new Promise((r,a)=>{s=setTimeout(()=>a(Error(`${i} timed out after ${t}ms`)),t)});try{return await Promise.race([e,n])}finally{if(s)clearTimeout(s)}}var ht=null,ns=!1;async function Ea(e,t){try{await v.workspaceQuery(Sh,{id:e,input:{status:t}})}catch{}}async function Sa(e){if(!v.isConfigured()||ns)return;ns=!0;let t=g().logger;try{let i=await e.getConfig("gateway-auth:agentRecordId");if(!i)return;let s=await v.workspaceQuery(Eh,{agentId:i});if(s.errors?.length)return;let n=s.data?.vibecontrolsAgentProfiles??[];if(n.length===0)return;let r=g().name,a;try{a=await yt({dir:Bt(r),scope:r})}catch{a=void 0}for(let l of n){if(l.isDefault||l.name===r||l.name==="default")continue;let o=Ta.get(l.name);if(o&&o.getBootState()==="ready"){if(l.status!=="ready")await Ea(l.id,"ready");continue}if(a?.clientId&&a.clientSecret&&!await $a(l.name))try{if(mh(Bt(l.name),{recursive:!0}),ba({globalGatewayUrl:a.globalGatewayUrl,workspaceGatewayUrl:a.workspaceGatewayUrl,workspaceId:a.workspaceId,organizationId:a.organizationId,clientId:a.clientId,clientSecret:a.clientSecret},{dir:Bt(l.name),scope:Xt(l.name)}),!await Ih(l.name)){t.warn(ct,`Seeded creds for profile '${l.name}' not yet readable; retrying next tick`);continue}}catch(c){t.warn(ct,`Failed to seed config for profile '${l.name}'`,{error:c instanceof Error?c.message:String(c)});continue}t.info(ct,`Reconciling desired profile '${l.name}' from control plane`);try{let c=Oa(l.name),h=await bh(Na(c),Ah,`attach '${l.name}'`),u=c.getBootState();await Ea(l.id,u),t.info(ct,`Profile '${l.name}' reconciled`,{ok:h.ok,status:u,error:h.error})}catch(c){t.warn(ct,`Failed to reconcile profile '${l.name}'`,{error:c instanceof Error?c.message:String(c)})}}}catch(i){g().logger.debug(ct,`Reconcile pass failed: ${i instanceof Error?i.message:String(i)}`)}finally{ns=!1}}function dt(e,t){if(ht)return;let i=Number(process.env.VIBE_PROFILE_RECONCILE_MS),s=Number.isFinite(i)&&i>0?Math.max(i,wh):t??yh;Sa(e),ht=setInterval(()=>{Sa(e)},s),ht.unref?.()}function Sd(){if(ht)clearInterval(ht),ht=null}var Fe=10,rs=3000,y="auto-report",La=`
134
134
  mutation RegisterInstalledAgent($workspaceId: ID!, $input: RegisterInstalledAgentInput!) {
135
135
  registerInstalledAgent(workspaceId: $workspaceId, input: $input) {
136
136
  id
@@ -155,7 +155,7 @@ data: /message
155
155
  tunnelUrl
156
156
  }
157
157
  }
158
- `,bh=`
158
+ `,Th=`
159
159
  mutation AgentHeartbeat($id: ID!) {
160
160
  vibecontrolsAgentHeartbeat(id: $id) {
161
161
  id
@@ -163,16 +163,16 @@ data: /message
163
163
  lastHeartbeat
164
164
  }
165
165
  }
166
- `,Th=`
166
+ `,Oh=`
167
167
  mutation DeactivateVibecontrolsAgent($id: ID!) {
168
168
  deactivateVibecontrolsAgent(id: $id) {
169
169
  id
170
170
  isActive
171
171
  }
172
172
  }
173
- `;async function Oh(e){if(process.env.AGENT_TUNNEL_URL){let t=Ca(process.env.AGENT_TUNNEL_URL);if(!t)return g().logger.warn(y,"Ignoring invalid AGENT_TUNNEL_URL"),null;return g().logger.debug(y,`Using AGENT_TUNNEL_URL from environment: ${t}`),t}for(let t=1;t<=Fe;t++){let i=[],s=e.getProvider("tunnel");if(s)i.push(s);for(let n of e.listProvidersForType("tunnel")){let r=e.getProviderByName("tunnel",n.pluginName);if(r&&!i.includes(r))i.push(r)}for(let n of i){if(!n.getActiveTunnelUrl)continue;let r=await n.getActiveTunnelUrl(),a=os(r);if(a)return g().logger.debug(y,`Tunnel URL available on attempt ${t}: ${a}`),a;if(r)g().logger.warn(y,"Tunnel provider returned invalid URL",{url:r})}if(t<Fe)g().logger.debug(y,`Tunnel URL not ready, retrying in ${rs/1000}s (attempt ${t}/${Fe})`),await new Promise((n)=>setTimeout(n,rs))}return g().logger.warn(y,`Tunnel URL not available after ${Fe} attempts`),null}async function as(e,t){let i=await e.getConfig("gateway-auth:agentRecordId");if(i)return i;let s=await e.getConfig("gateway-auth:workspaceId");if(!s)return null;let n=await v.workspaceQuery(Yt,{workspaceId:s});if(n.errors?.length)return g().logger.warn(y,"Failed to discover existing agent record",{errors:n.errors.map((l)=>l.message)}),null;let r=t.toLowerCase(),a=n.data?.vibecontrolsAgents?.find((l)=>l.hostname.toLowerCase()===r);if(!a)return null;return await e.setConfig("gateway-auth:agentRecordId",a.id),g().logger.info(y,"Recovered existing agent record ID",{agentRecordId:a.id,hostname:t}),a.id}async function Nh(e,t){try{let i=await v.workspaceQuery(Yt,{workspaceId:e});if(i.errors?.length)return!0;let s=i.data?.vibecontrolsAgents;if(!s)return!0;return s.some((n)=>n.id===t)}catch{return!0}}async function Wt(e,t){if(!v.isConfigured())return;let i=await as(e,process.env.VIBE_AGENT_NAME||Ht.hostname());if(!i)return;if(t!=="killed"){g().logger.debug(y,`Skipping '${t}' lifecycle sync \u2014 startup auto-report already refreshes the live agent record and the current backend schema has no dedicated lifecycle field.`);return}let s=await v.workspaceQuery(Th,{id:i});if(s.errors?.length)g().logger.warn(y,`Failed to report lifecycle state '${t}'`,{errors:s.errors.map((n)=>n.message)});else g().logger.info(y,`Reported lifecycle state: ${t}`)}async function Da(e,t,i){let s=i||v.getConfig()?.workspaceId||"";for(let n=1;n<=3;n++){await new Promise((o)=>setTimeout(o,1500));let l=(await v.workspaceQuery(Yt,{workspaceId:s})).data?.vibecontrolsAgents?.find((o)=>o.id===e)?.tunnelUrl??null;if(l===t)return g().logger.info(y,`Verified: backend tunnelUrl matches (attempt ${n})`),!0;g().logger.warn(y,`Verification failed (attempt ${n}/3): backend has '${l}', expected '${t}' \u2014 retrying update`),await v.workspaceQuery(Jt,{id:e,input:{tunnelUrl:t||null,tunnelStatus:t?"CONNECTED":"DISCONNECTED"}})}return g().logger.error(y,"Failed to verify tunnel URL update after 3 attempts"),!1}async function Vt(e){try{let t=await v.workspaceQuery(bh,{id:e});if(t.errors?.length)g().logger.debug(y,"Heartbeat returned errors",{errors:t.errors.map((i)=>i.message)});else g().logger.debug(y,"Heartbeat sent successfully")}catch(t){g().logger.debug(y,`Heartbeat failed: ${t instanceof Error?t.message:String(t)}`)}}var $h=`
173
+ `;async function Nh(e){if(process.env.AGENT_TUNNEL_URL){let t=Ra(process.env.AGENT_TUNNEL_URL);if(!t)return g().logger.warn(y,"Ignoring invalid AGENT_TUNNEL_URL"),null;return g().logger.debug(y,`Using AGENT_TUNNEL_URL from environment: ${t}`),t}for(let t=1;t<=Fe;t++){let i=[],s=e.getProvider("tunnel");if(s)i.push(s);for(let n of e.listProvidersForType("tunnel")){let r=e.getProviderByName("tunnel",n.pluginName);if(r&&!i.includes(r))i.push(r)}for(let n of i){if(!n.getActiveTunnelUrl)continue;let r=await n.getActiveTunnelUrl(),a=os(r);if(a)return g().logger.debug(y,`Tunnel URL available on attempt ${t}: ${a}`),a;if(r)g().logger.warn(y,"Tunnel provider returned invalid URL",{url:r})}if(t<Fe)g().logger.debug(y,`Tunnel URL not ready, retrying in ${rs/1000}s (attempt ${t}/${Fe})`),await new Promise((n)=>setTimeout(n,rs))}return g().logger.warn(y,`Tunnel URL not available after ${Fe} attempts`),null}async function as(e,t){let i=await e.getConfig("gateway-auth:agentRecordId");if(i)return i;let s=await e.getConfig("gateway-auth:workspaceId");if(!s)return null;let n=await v.workspaceQuery(Yt,{workspaceId:s});if(n.errors?.length)return g().logger.warn(y,"Failed to discover existing agent record",{errors:n.errors.map((l)=>l.message)}),null;let r=t.toLowerCase(),a=n.data?.vibecontrolsAgents?.find((l)=>l.hostname.toLowerCase()===r);if(!a)return null;return await e.setConfig("gateway-auth:agentRecordId",a.id),g().logger.info(y,"Recovered existing agent record ID",{agentRecordId:a.id,hostname:t}),a.id}async function $h(e,t){try{let i=await v.workspaceQuery(Yt,{workspaceId:e});if(i.errors?.length)return!0;let s=i.data?.vibecontrolsAgents;if(!s)return!0;return s.some((n)=>n.id===t)}catch{return!0}}async function Wt(e,t){if(!v.isConfigured())return;let i=await as(e,process.env.VIBE_AGENT_NAME||Ht.hostname());if(!i)return;if(t!=="killed"){g().logger.debug(y,`Skipping '${t}' lifecycle sync \u2014 startup auto-report already refreshes the live agent record and the current backend schema has no dedicated lifecycle field.`);return}let s=await v.workspaceQuery(Oh,{id:i});if(s.errors?.length)g().logger.warn(y,`Failed to report lifecycle state '${t}'`,{errors:s.errors.map((n)=>n.message)});else g().logger.info(y,`Reported lifecycle state: ${t}`)}async function Da(e,t,i){let s=i||v.getConfig()?.workspaceId||"";for(let n=1;n<=3;n++){await new Promise((o)=>setTimeout(o,1500));let l=(await v.workspaceQuery(Yt,{workspaceId:s})).data?.vibecontrolsAgents?.find((o)=>o.id===e)?.tunnelUrl??null;if(l===t)return g().logger.info(y,`Verified: backend tunnelUrl matches (attempt ${n})`),!0;g().logger.warn(y,`Verification failed (attempt ${n}/3): backend has '${l}', expected '${t}' \u2014 retrying update`),await v.workspaceQuery(Jt,{id:e,input:{tunnelUrl:t||null,tunnelStatus:t?"CONNECTED":"DISCONNECTED"}})}return g().logger.error(y,"Failed to verify tunnel URL update after 3 attempts"),!1}async function Ca(e,t){try{let i=await v.workspaceQuery(La,{workspaceId:e,input:{name:t.hostname,hostname:t.hostname,platform:t.platform,architecture:t.arch,tunnelUrl:t.tunnelUrl||null,agentApiKey:t.apiKey}});if(i.errors?.length)g().logger.debug(y,"API key re-assertion returned errors (non-fatal)",{errors:i.errors.map((s)=>s.message)});else g().logger.debug(y,"Re-asserted agent API key to backend")}catch(i){g().logger.debug(y,`API key re-assertion failed (non-fatal): ${i instanceof Error?i.message:String(i)}`)}}async function Vt(e){try{let t=await v.workspaceQuery(Th,{id:e});if(t.errors?.length)g().logger.debug(y,"Heartbeat returned errors",{errors:t.errors.map((i)=>i.message)});else g().logger.debug(y,"Heartbeat sent successfully")}catch(t){g().logger.debug(y,`Heartbeat failed: ${t instanceof Error?t.message:String(t)}`)}}var Dh=`
174
174
  mutation NotifyVibecontrolsAgentPluginChange($agentId: ID!) {
175
175
  notifyVibecontrolsAgentPluginChange(agentId: $agentId)
176
176
  }
177
- `;async function Dd(e){try{if(!v.isConfigured())return;let t=await e.getConfig("gateway-auth:agentRecordId");if(!t)return;let i=await v.workspaceQuery($h,{agentId:t});if(i.errors?.length)g().logger.debug(y,"Plugin-change notify returned errors",{errors:i.errors.map((s)=>s.message)})}catch(t){g().logger.debug(y,`Plugin-change notify failed: ${t instanceof Error?t.message:String(t)}`)}}var ut=null,_t=null;function wt(e,t,i){if(ut)return;let s=Number(process.env.VIBE_TUNNEL_SYNC_MS),n=Number.isFinite(s)&&s>0?s:i??60000;ut=setInterval(async()=>{if(!v.isConfigured())return;try{let r=t.getProvider("tunnel");if(!r||!r.getActiveTunnelUrl)return;let a=os(await r.getActiveTunnelUrl()),l=await e.getConfig("gateway-auth:agentRecordId");if(!l)return;if(await Vt(l),!a)return;let o=v.getConfig()?.workspaceId||"",c;if(o)c=(await v.workspaceQuery(Yt,{workspaceId:o})).data?.vibecontrolsAgents?.find((f)=>f.id===l)?.tunnelUrl??null;let h=a!==_t,u=c!==void 0&&c!==a;if(!h&&!u)return;g().logger.info(y,"Re-publishing tunnel URL",{reason:u?"backend-drift":"local-change",backend:c,local:a,lastReported:_t});let d=await v.workspaceQuery(Jt,{id:l,input:{tunnelUrl:a,tunnelStatus:"CONNECTED"}});if(!d.errors?.length)_t=a,g().logger.info(y,"Tunnel URL synced to backend",{tunnelUrl:a});else g().logger.warn(y,"Tunnel URL sync returned errors",{errors:d.errors.map((_)=>_.message)})}catch(r){g().logger.debug(y,`Tunnel sync check failed: ${r instanceof Error?r.message:String(r)}`)}},n),ut.unref?.()}function Cd(){if(ut)clearInterval(ut),ut=null}async function Rd(e,t,i){if(!v.isConfigured()){g().logger.debug(y,"Gateway auth not configured \u2014 skipping auto-report");return}let s=await e.getConfig("gateway-auth:workspaceId");if(!s){g().logger.warn(y,"No workspaceId configured \u2014 skipping auto-report. "+"Configure via POST /api/agent/gateway-auth with workspaceId.");return}g().logger.info(y,"Starting auto-report to backend...");try{let n=process.env.VIBE_AGENT_NAME||Ht.hostname(),r=Ht.platform(),a=Ht.arch(),l=Ra(),o=await Oh(t),c=await as(e,n);if(c){g().logger.info(y,`Updating agent record ${c} via workspace gateway`);let u=await v.workspaceQuery(Jt,{id:c,input:{tunnelUrl:o||null,tunnelStatus:o?"CONNECTED":"DISCONNECTED"}});if(u.errors?.length){if(g().logger.warn(y,"Update mutation returned errors",{errors:u.errors.map((_)=>_.message)}),await Nh(s,c)){g().logger.warn(y,"Agent record still exists \u2014 treating update failure as transient; will retry on next sync (NOT registering a duplicate)",{agentRecordId:c}),await Vt(c),_t=o,wt(e,t),dt(e);return}g().logger.info(y,"Cached agent record no longer exists \u2014 clearing cache and registering fresh",{agentRecordId:c}),await e.setConfig("gateway-auth:agentRecordId",""),c=null}else{g().logger.info(y,"Agent record updated successfully",{agentRecordId:c,tunnelUrl:o}),await Da(c,o,s),await Vt(c),_t=o,wt(e,t),dt(e);return}}g().logger.info(y,`Registering installed agent via workspace gateway (hostname: ${n})`);for(let u=1;u<=Fe&&!c;u++){if(u>1){let p=await as(e,n);if(p){c=p,g().logger.info(y,"Adopted an agent record discovered after a retry (not registering a duplicate)",{agentRecordId:c});break}}let d=await v.workspaceQuery(Ih,{workspaceId:s,input:{name:n,hostname:n,platform:r,architecture:a,tunnelUrl:o||null,agentApiKey:i}}),_=d.errors?.length?void 0:d.data?.registerInstalledAgent?.id;if(_){await e.setConfig("gateway-auth:agentRecordId",_),c=_,g().logger.info(y,"Agent registered successfully",{agentRecordId:_,name:d.data?.registerInstalledAgent?.name,tunnelUrl:o,version:l,attempt:u});break}let f=d.errors?.length?d.errors.map((p)=>p.message):["registerInstalledAgent returned no id"];if(u<Fe){let p=Math.min(30000,rs*2**(u-1));g().logger.warn(y,`Register installed agent failed (attempt ${u}/${Fe}) \u2014 retrying in ${Math.round(p/1000)}s`,{errors:f}),await new Promise((m)=>setTimeout(m,p));continue}g().logger.error(y,"Register installed agent failed after retries \u2014 agent is running but NOT registered with the workspace",{errors:f}),g().recordDegradedReason("agent-registration",`registerInstalledAgent failed after ${Fe} attempts: ${f.join("; ")}`)}if(!c){wt(e,t),dt(e);return}let h=await v.workspaceQuery(Jt,{id:c,input:{tunnelUrl:o||null,tunnelStatus:o?"CONNECTED":"DISCONNECTED"}});if(h.errors?.length)g().logger.warn(y,"Post-registration agent update returned errors",{errors:h.errors.map((u)=>u.message)});else g().logger.info(y,"Post-registration agent sync completed",{agentRecordId:c,tunnelUrl:o});if(await Da(c,o,s),await Vt(c),_t=o,wt(e,t),dt(e),process.env.VIBE_BRIDGE_DISABLED!=="1")try{let{bridgeClient:u}=await import("./bridge-client-341r9rry.js"),d=process.env.VIBECONTROLS_PROFILE||"default";u.start(c,d)}catch(u){g().logger.warn(y,`bridge-client start failed: ${u instanceof Error?u.message:String(u)}`)}}catch(n){g().logger.error(y,`Auto-report failed: ${n instanceof Error?n.message:String(n)}`);try{wt(e,t),dt(e)}catch{}}}var S="lifecycle";class ls{serviceRegistry;pluginManager;db;app;hostServices;appStopFn;state="running";transition=Promise.resolve();constructor(e,t,i,s,n,r){this.serviceRegistry=e;this.pluginManager=t;this.db=i;this.app=s;this.hostServices=n;this.appStopFn=r}getState(){return this.state}enqueueTransition(e,t){let i=this.transition.then(t,t);return this.transition=i.catch((s)=>{g().logger.warn(S,`Lifecycle transition '${e}' failed`,{error:String(s)})}),i}async stop(){return this.enqueueTransition("stop",async()=>{if(this.state==="stopped"){g().logger.warn(S,"Agent is already stopped");return}g().logger.info(S,"Stopping agent..."),this.state="stopped";let e=this.serviceRegistry.getProvider("session");if(e)try{let t=await e.list();for(let i of t)if(i.status==="active")try{await e.kill(i.id),g().logger.debug(S,`Killed session ${i.id}`)}catch(s){g().logger.warn(S,`Failed to kill session ${i.id}`,{error:String(s)})}}catch(t){g().logger.warn(S,"Failed to list/stop sessions",{error:String(t)})}try{await this.pluginManager.dispatchServerStop()}catch(t){g().logger.warn(S,"Error during plugin stop dispatch",{error:String(t)})}g().logger.info(S,"Agent stopped (tunnel + HTTP still alive)");try{await Wt(this.db,"stopped")}catch(t){g().logger.warn(S,"Failed to report stopped state to backend",{error:String(t)})}})}async start(){return this.enqueueTransition("start",async()=>{if(this.state==="running"){g().logger.warn(S,"Agent is already running");return}g().logger.info(S,"Starting agent..."),this.state="running";try{await this.pluginManager.dispatchServerStart(this.app,this.hostServices),await this.pluginManager.dispatchServerReady(this.app,this.hostServices)}catch(e){g().logger.warn(S,"Error during plugin start dispatch",{error:String(e)})}g().logger.info(S,"Agent started");try{await Wt(this.db,"running")}catch(e){g().logger.warn(S,"Failed to report running state to backend",{error:String(e)})}})}async softStop(){return this.enqueueTransition("softStop",async()=>{g().logger.info(S,"Soft-stopping agent (hot-reload)...");try{await this.pluginManager.dispatchServerStop({reason:"reload"})}catch(e){g().logger.warn(S,"Error during plugin soft-stop dispatch",{error:String(e)})}try{await this.appStopFn({reason:"reload"})}catch{}g().logger.info(S,"Agent soft-stopped \u2014 exiting for reload"),process.exit(0)})}async prepareForReset(){return this.enqueueTransition("prepareForReset",async()=>{g().logger.info(S,"Preparing agent for reset..."),this.state="stopped";try{await this.pluginManager.dispatchServerStop({reason:"shutdown"})}catch(e){g().logger.warn(S,"Error during reset stop dispatch",{error:String(e)})}})}async kill(){return this.enqueueTransition("kill",async()=>{g().logger.info(S,"Killing agent...");try{await Promise.race([Wt(this.db,"killed"),new Promise((t,i)=>setTimeout(()=>i(Error("Timeout")),5000))])}catch(t){g().logger.warn(S,"Failed to report killed state to backend",{error:String(t)})}let e=this.serviceRegistry.getProvider("tunnel");if(e)try{let t=await e.list();for(let i of t)try{await e.stop(i.id)}catch{}}catch(t){g().logger.warn(S,"Failed to stop tunnels",{error:String(t)})}try{await this.appStopFn()}catch{}g().logger.info(S,"Agent killed \u2014 exiting process"),process.exit(0)})}}async function Dh(e){let t=await Ch(e);if(t)return t;return Rh(e.name)}async function Ch(e){let t;try{t=await yt({dir:e.dataDir,scope:e.name})}catch{return null}if(!t.clientId||!t.clientSecret||!t.globalGatewayUrl||!t.workspaceGatewayUrl||!t.workspaceId)return null;return{clientId:t.clientId,clientSecret:t.clientSecret,globalGatewayUrl:t.globalGatewayUrl,workspaceGatewayUrl:t.workspaceGatewayUrl,workspaceId:t.workspaceId,organizationId:t.organizationId}}function Rh(e){let t=e.replace(/[^A-Za-z0-9_]/g,"_").toUpperCase(),i=(o)=>process.env[`VIBE_${t}_${o}`],s=i("CLIENT_ID"),n=i("CLIENT_SECRET"),r=i("GLOBAL_GATEWAY_URL"),a=i("WORKSPACE_GATEWAY_URL"),l=i("WORKSPACE_ID");if(!s||!n||!r||!a||!l)return null;return{clientId:s,clientSecret:n,globalGatewayUrl:r,workspaceGatewayUrl:a,workspaceId:l,organizationId:i("ORGANIZATION_ID")}}async function Na(e){let t=await Dh(e);if(!t)return{ok:!1,error:`no creds for profile '${e.name}' (run gateway-auth against this profile or set VIBE_${e.name.toUpperCase()}_* env vars)`};e.setBootState("initializing");let i;try{let l=await hs(t);i=await va({dbPath:e.dataDir,encryptionKey:l})}catch(l){return e.setBootState("awaiting-config"),{ok:!1,error:l instanceof Error?l.message:String(l)}}let s=new Ma(i);await s.hydrateDefaultsFromDb();let n=new Ka(i);await n.loadCorePlugins();try{await n.loadAll()}catch(l){e.logger.warn("secondary-profile-attach","failed to load some external plugins for secondary profile",{error:l instanceof Error?l.message:String(l)})}let r={storage:{async get(l,o){return await i.getPluginState(l,o)??null},async set(l,o,c){await i.setPluginState(l,o,c)},async delete(l,o){return i.deletePluginState(l,o)},async list(l){return await i.getAllPluginState(l)},async deleteAll(l){return i.deleteAllPluginState(l)}},logger:e.logger,serviceRegistry:s,getProvider:(l)=>s.getProvider(l),getAgentBaseUrl:()=>process.env.AGENT_URL||"http://localhost:0",getAgentVersion:()=>"0.0.0",broadcast:()=>{},workspaceQuery:async()=>({}),isGatewayConfigured:()=>!0,getAgentRecordId:async()=>await i.getConfig("gateway-auth:agentRecordId")??null,getWorkspaceId:async()=>await i.getConfig("gateway-auth:workspaceId")??null,getConfig:async(l)=>await i.getConfig(l)??void 0,getPluginRegistry:()=>"",getDataDir:()=>e.dataDir,cliContributors:new ja,audit:{emit:(l,o)=>e.audit.emit("agent",l,o??{})},telemetry:{emit:()=>{}},os:ka(),iframeBridge:qa()},a=new ls(s,n,i,{},r,async()=>{});s.registerService("agent","lifecycle",a),e.attachServices({db:i,serviceRegistry:s,pluginManager:n,lifecycle:a,hostServices:r});try{Pa(e)}catch(l){e.logger.warn("secondary-profile-attach","failed to mount per-profile plugin routes",{error:l instanceof Error?l.message:String(l)})}try{await e.keyVault.bindApiKey(La())}catch{}return e.setBootState("ready"),{ok:!0}}
178
- export{va as u,hs as v,ls as w,Na as x,Ed as y,Dd as z,Cd as A,Rd as B};
177
+ `;async function Cd(e){try{if(!v.isConfigured())return;let t=await e.getConfig("gateway-auth:agentRecordId");if(!t)return;let i=await v.workspaceQuery(Dh,{agentId:t});if(i.errors?.length)g().logger.debug(y,"Plugin-change notify returned errors",{errors:i.errors.map((s)=>s.message)})}catch(t){g().logger.debug(y,`Plugin-change notify failed: ${t instanceof Error?t.message:String(t)}`)}}var ut=null,_t=null;function wt(e,t,i){if(ut)return;let s=Number(process.env.VIBE_TUNNEL_SYNC_MS),n=Number.isFinite(s)&&s>0?s:i??60000;ut=setInterval(async()=>{if(!v.isConfigured())return;try{let r=t.getProvider("tunnel");if(!r||!r.getActiveTunnelUrl)return;let a=os(await r.getActiveTunnelUrl()),l=await e.getConfig("gateway-auth:agentRecordId");if(!l)return;if(await Vt(l),!a)return;let o=v.getConfig()?.workspaceId||"",c;if(o)c=(await v.workspaceQuery(Yt,{workspaceId:o})).data?.vibecontrolsAgents?.find((f)=>f.id===l)?.tunnelUrl??null;let h=a!==_t,u=c!==void 0&&c!==a;if(!h&&!u)return;g().logger.info(y,"Re-publishing tunnel URL",{reason:u?"backend-drift":"local-change",backend:c,local:a,lastReported:_t});let d=await v.workspaceQuery(Jt,{id:l,input:{tunnelUrl:a,tunnelStatus:"CONNECTED"}});if(!d.errors?.length)_t=a,g().logger.info(y,"Tunnel URL synced to backend",{tunnelUrl:a});else g().logger.warn(y,"Tunnel URL sync returned errors",{errors:d.errors.map((_)=>_.message)})}catch(r){g().logger.debug(y,`Tunnel sync check failed: ${r instanceof Error?r.message:String(r)}`)}},n),ut.unref?.()}function Rd(){if(ut)clearInterval(ut),ut=null}async function kd(e,t,i){if(!v.isConfigured()){g().logger.debug(y,"Gateway auth not configured \u2014 skipping auto-report");return}let s=await e.getConfig("gateway-auth:workspaceId");if(!s){g().logger.warn(y,"No workspaceId configured \u2014 skipping auto-report. "+"Configure via POST /api/agent/gateway-auth with workspaceId.");return}g().logger.info(y,"Starting auto-report to backend...");try{let n=process.env.VIBE_AGENT_NAME||Ht.hostname(),r=Ht.platform(),a=Ht.arch(),l=ka(),o=await Nh(t),c=await as(e,n);if(c){g().logger.info(y,`Updating agent record ${c} via workspace gateway`);let u=await v.workspaceQuery(Jt,{id:c,input:{tunnelUrl:o||null,tunnelStatus:o?"CONNECTED":"DISCONNECTED",agentApiKey:i}});if(u.errors?.length){if(g().logger.warn(y,"Update mutation returned errors",{errors:u.errors.map((_)=>_.message)}),await $h(s,c)){g().logger.warn(y,"Agent record still exists \u2014 treating update failure as transient; will retry on next sync (NOT registering a duplicate)",{agentRecordId:c}),await Ca(s,{hostname:n,platform:r,arch:a,tunnelUrl:o,apiKey:i}),await Vt(c),_t=o,wt(e,t),dt(e);return}g().logger.info(y,"Cached agent record no longer exists \u2014 clearing cache and registering fresh",{agentRecordId:c}),await e.setConfig("gateway-auth:agentRecordId",""),c=null}else{g().logger.info(y,"Agent record updated successfully",{agentRecordId:c,tunnelUrl:o}),await Da(c,o,s),await Ca(s,{hostname:n,platform:r,arch:a,tunnelUrl:o,apiKey:i}),await Vt(c),_t=o,wt(e,t),dt(e);return}}g().logger.info(y,`Registering installed agent via workspace gateway (hostname: ${n})`);for(let u=1;u<=Fe&&!c;u++){if(u>1){let p=await as(e,n);if(p){c=p,g().logger.info(y,"Adopted an agent record discovered after a retry (not registering a duplicate)",{agentRecordId:c});break}}let d=await v.workspaceQuery(La,{workspaceId:s,input:{name:n,hostname:n,platform:r,architecture:a,tunnelUrl:o||null,agentApiKey:i}}),_=d.errors?.length?void 0:d.data?.registerInstalledAgent?.id;if(_){await e.setConfig("gateway-auth:agentRecordId",_),c=_,g().logger.info(y,"Agent registered successfully",{agentRecordId:_,name:d.data?.registerInstalledAgent?.name,tunnelUrl:o,version:l,attempt:u});break}let f=d.errors?.length?d.errors.map((p)=>p.message):["registerInstalledAgent returned no id"];if(u<Fe){let p=Math.min(30000,rs*2**(u-1));g().logger.warn(y,`Register installed agent failed (attempt ${u}/${Fe}) \u2014 retrying in ${Math.round(p/1000)}s`,{errors:f}),await new Promise((m)=>setTimeout(m,p));continue}g().logger.error(y,"Register installed agent failed after retries \u2014 agent is running but NOT registered with the workspace",{errors:f}),g().recordDegradedReason("agent-registration",`registerInstalledAgent failed after ${Fe} attempts: ${f.join("; ")}`)}if(!c){wt(e,t),dt(e);return}let h=await v.workspaceQuery(Jt,{id:c,input:{tunnelUrl:o||null,tunnelStatus:o?"CONNECTED":"DISCONNECTED"}});if(h.errors?.length)g().logger.warn(y,"Post-registration agent update returned errors",{errors:h.errors.map((u)=>u.message)});else g().logger.info(y,"Post-registration agent sync completed",{agentRecordId:c,tunnelUrl:o});if(await Da(c,o,s),await Vt(c),_t=o,wt(e,t),dt(e),process.env.VIBE_BRIDGE_DISABLED!=="1")try{let{bridgeClient:u}=await import("./bridge-client-1fxza4p7.js"),d=process.env.VIBECONTROLS_PROFILE||"default";u.start(c,d)}catch(u){g().logger.warn(y,`bridge-client start failed: ${u instanceof Error?u.message:String(u)}`)}}catch(n){g().logger.error(y,`Auto-report failed: ${n instanceof Error?n.message:String(n)}`);try{wt(e,t),dt(e)}catch{}}}var S="lifecycle";class ls{serviceRegistry;pluginManager;db;app;hostServices;appStopFn;state="running";transition=Promise.resolve();constructor(e,t,i,s,n,r){this.serviceRegistry=e;this.pluginManager=t;this.db=i;this.app=s;this.hostServices=n;this.appStopFn=r}getState(){return this.state}enqueueTransition(e,t){let i=this.transition.then(t,t);return this.transition=i.catch((s)=>{g().logger.warn(S,`Lifecycle transition '${e}' failed`,{error:String(s)})}),i}async stop(){return this.enqueueTransition("stop",async()=>{if(this.state==="stopped"){g().logger.warn(S,"Agent is already stopped");return}g().logger.info(S,"Stopping agent..."),this.state="stopped";let e=this.serviceRegistry.getProvider("session");if(e)try{let t=await e.list();for(let i of t)if(i.status==="active")try{await e.kill(i.id),g().logger.debug(S,`Killed session ${i.id}`)}catch(s){g().logger.warn(S,`Failed to kill session ${i.id}`,{error:String(s)})}}catch(t){g().logger.warn(S,"Failed to list/stop sessions",{error:String(t)})}try{await this.pluginManager.dispatchServerStop()}catch(t){g().logger.warn(S,"Error during plugin stop dispatch",{error:String(t)})}g().logger.info(S,"Agent stopped (tunnel + HTTP still alive)");try{await Wt(this.db,"stopped")}catch(t){g().logger.warn(S,"Failed to report stopped state to backend",{error:String(t)})}})}async start(){return this.enqueueTransition("start",async()=>{if(this.state==="running"){g().logger.warn(S,"Agent is already running");return}g().logger.info(S,"Starting agent..."),this.state="running";try{await this.pluginManager.dispatchServerStart(this.app,this.hostServices),await this.pluginManager.dispatchServerReady(this.app,this.hostServices)}catch(e){g().logger.warn(S,"Error during plugin start dispatch",{error:String(e)})}g().logger.info(S,"Agent started");try{await Wt(this.db,"running")}catch(e){g().logger.warn(S,"Failed to report running state to backend",{error:String(e)})}})}async softStop(){return this.enqueueTransition("softStop",async()=>{g().logger.info(S,"Soft-stopping agent (hot-reload)...");try{await this.pluginManager.dispatchServerStop({reason:"reload"})}catch(e){g().logger.warn(S,"Error during plugin soft-stop dispatch",{error:String(e)})}try{await this.appStopFn({reason:"reload"})}catch{}g().logger.info(S,"Agent soft-stopped \u2014 exiting for reload"),process.exit(0)})}async prepareForReset(){return this.enqueueTransition("prepareForReset",async()=>{g().logger.info(S,"Preparing agent for reset..."),this.state="stopped";try{await this.pluginManager.dispatchServerStop({reason:"shutdown"})}catch(e){g().logger.warn(S,"Error during reset stop dispatch",{error:String(e)})}})}async kill(){return this.enqueueTransition("kill",async()=>{g().logger.info(S,"Killing agent...");try{await Promise.race([Wt(this.db,"killed"),new Promise((t,i)=>setTimeout(()=>i(Error("Timeout")),5000))])}catch(t){g().logger.warn(S,"Failed to report killed state to backend",{error:String(t)})}let e=this.serviceRegistry.getProvider("tunnel");if(e)try{let t=await e.list();for(let i of t)try{await e.stop(i.id)}catch{}}catch(t){g().logger.warn(S,"Failed to stop tunnels",{error:String(t)})}try{await this.appStopFn()}catch{}g().logger.info(S,"Agent killed \u2014 exiting process"),process.exit(0)})}}async function Ch(e){let t=await Rh(e);if(t)return t;return kh(e.name)}async function Rh(e){let t;try{t=await yt({dir:e.dataDir,scope:e.name})}catch{return null}if(!t.clientId||!t.clientSecret||!t.globalGatewayUrl||!t.workspaceGatewayUrl||!t.workspaceId)return null;return{clientId:t.clientId,clientSecret:t.clientSecret,globalGatewayUrl:t.globalGatewayUrl,workspaceGatewayUrl:t.workspaceGatewayUrl,workspaceId:t.workspaceId,organizationId:t.organizationId}}function kh(e){let t=e.replace(/[^A-Za-z0-9_]/g,"_").toUpperCase(),i=(o)=>process.env[`VIBE_${t}_${o}`],s=i("CLIENT_ID"),n=i("CLIENT_SECRET"),r=i("GLOBAL_GATEWAY_URL"),a=i("WORKSPACE_GATEWAY_URL"),l=i("WORKSPACE_ID");if(!s||!n||!r||!a||!l)return null;return{clientId:s,clientSecret:n,globalGatewayUrl:r,workspaceGatewayUrl:a,workspaceId:l,organizationId:i("ORGANIZATION_ID")}}async function Na(e){let t=await Ch(e);if(!t)return{ok:!1,error:`no creds for profile '${e.name}' (run gateway-auth against this profile or set VIBE_${e.name.toUpperCase()}_* env vars)`};e.setBootState("initializing");let i;try{let l=await hs(t);i=await va({dbPath:e.dataDir,encryptionKey:l})}catch(l){return e.setBootState("awaiting-config"),{ok:!1,error:l instanceof Error?l.message:String(l)}}let s=new qa(i);await s.hydrateDefaultsFromDb();let n=new Ua(i);await n.loadCorePlugins();try{await n.loadAll()}catch(l){e.logger.warn("secondary-profile-attach","failed to load some external plugins for secondary profile",{error:l instanceof Error?l.message:String(l)})}let r={storage:{async get(l,o){return await i.getPluginState(l,o)??null},async set(l,o,c){await i.setPluginState(l,o,c)},async delete(l,o){return i.deletePluginState(l,o)},async list(l){return await i.getAllPluginState(l)},async deleteAll(l){return i.deleteAllPluginState(l)}},logger:e.logger,serviceRegistry:s,getProvider:(l)=>s.getProvider(l),getAgentBaseUrl:()=>process.env.AGENT_URL||"http://localhost:0",getAgentVersion:()=>"0.0.0",broadcast:()=>{},workspaceQuery:async()=>({}),isGatewayConfigured:()=>!0,getAgentRecordId:async()=>await i.getConfig("gateway-auth:agentRecordId")??null,getWorkspaceId:async()=>await i.getConfig("gateway-auth:workspaceId")??null,getConfig:async(l)=>await i.getConfig(l)??void 0,getPluginRegistry:()=>"",getDataDir:()=>e.dataDir,cliContributors:new Ka,audit:{emit:(l,o)=>e.audit.emit("agent",l,o??{})},telemetry:{emit:()=>{}},os:Pa(),iframeBridge:Fa()},a=new ls(s,n,i,{},r,async()=>{});s.registerService("agent","lifecycle",a),e.attachServices({db:i,serviceRegistry:s,pluginManager:n,lifecycle:a,hostServices:r});try{ja(e)}catch(l){e.logger.warn("secondary-profile-attach","failed to mount per-profile plugin routes",{error:l instanceof Error?l.message:String(l)})}try{await e.keyVault.bindApiKey(Ma())}catch{}return e.setBootState("ready"),{ok:!0}}
178
+ export{va as u,hs as v,ls as w,Na as x,Sd as y,Cd as z,Rd as A,kd as B};