@lunora/studio 1.0.0-alpha.142 → 1.0.0-alpha.144

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 (95) hide show
  1. package/dist/index.d.mts +15 -4
  2. package/dist/index.d.ts +15 -4
  3. package/dist/index.mjs +1 -1
  4. package/dist/mount.d.mts +2 -1
  5. package/dist/mount.d.ts +2 -1
  6. package/dist/mount.mjs +1 -1
  7. package/dist/packem_chunks/HealthPanel.mjs +1 -1
  8. package/dist/packem_chunks/MetricsPanel.mjs +1 -1
  9. package/dist/packem_chunks/analytics-panel.mjs +1 -1
  10. package/dist/packem_chunks/issues-panel.mjs +1 -1
  11. package/dist/packem_chunks/kv-browser.mjs +1 -1
  12. package/dist/packem_chunks/migrations-route.mjs +1 -1
  13. package/dist/packem_chunks/schedule-panel.mjs +1 -1
  14. package/dist/packem_shared/{ScheduledJobs-oDVEymk5.mjs → ScheduledJobs-Db0HZ8R9.mjs} +1 -1
  15. package/dist/packem_shared/{Studio-5eRSjGmd.mjs → Studio-UxOpDgEl.mjs} +1 -1
  16. package/dist/packem_shared/StudioApp-BdisV3FN.mjs +1 -0
  17. package/dist/packem_shared/aggregateMetrics-CY05xrYU.mjs +1 -0
  18. package/dist/packem_shared/{app.d-D1bPR8FO.d.mts → app.d-DFjg4Uki.d.mts} +33 -1
  19. package/dist/packem_shared/{app.d-D1bPR8FO.d.ts → app.d-DFjg4Uki.d.ts} +33 -1
  20. package/dist/packem_shared/{select-Cx8-CokP.mjs → select-DPyS18Vy.mjs} +1 -1
  21. package/dist/packem_shared/{studio-4odoxrh9.mjs → studio-DE8N0tIQ.mjs} +1 -1
  22. package/dist/standalone/{chunk-7GHBT32T.js → chunk-24XD27OU.js} +1 -1
  23. package/dist/standalone/chunk-2BN33A2H.js +1 -0
  24. package/dist/standalone/{chunk-3MNTCYQ3.js → chunk-2OLPNCFW.js} +1 -1
  25. package/dist/standalone/{chunk-GCYNOU4C.js → chunk-2V436GDL.js} +1 -1
  26. package/dist/standalone/{chunk-DRFQ3BUM.js → chunk-2WVC52MX.js} +1 -1
  27. package/dist/standalone/{chunk-YRNEKBFM.js → chunk-4RPBRBOA.js} +1 -1
  28. package/dist/standalone/{chunk-BP7MDQY5.js → chunk-5NCE6W7L.js} +1 -1
  29. package/dist/standalone/{chunk-F2R2UX27.js → chunk-6DHQ3IIO.js} +1 -1
  30. package/dist/standalone/{chunk-6H36JL4I.js → chunk-6HKQM3CN.js} +1 -1
  31. package/dist/standalone/{chunk-SPP7FEDA.js → chunk-6VDI4D53.js} +1 -1
  32. package/dist/standalone/{chunk-BDZFZT2N.js → chunk-7MXYEEMC.js} +1 -1
  33. package/dist/standalone/{chunk-BYWVVRKM.js → chunk-ADDPGZY7.js} +1 -1
  34. package/dist/standalone/chunk-BAKGFOG4.js +1 -0
  35. package/dist/standalone/{chunk-S4HBMTJ3.js → chunk-BGAQFHQC.js} +1 -1
  36. package/dist/standalone/{chunk-ATO3Y6BD.js → chunk-BOEMUL7H.js} +1 -1
  37. package/dist/standalone/{chunk-37VWQZEF.js → chunk-DMAQKIMP.js} +2 -2
  38. package/dist/standalone/{chunk-IMUTQDOB.js → chunk-DNNLYDKX.js} +1 -1
  39. package/dist/standalone/{chunk-NZMUY7ZG.js → chunk-DZVEJZ3C.js} +1 -1
  40. package/dist/standalone/{chunk-7DNDONOI.js → chunk-E3AFG6TS.js} +1 -1
  41. package/dist/standalone/{chunk-PCOD3V5E.js → chunk-ESVQSHW2.js} +1 -1
  42. package/dist/standalone/{chunk-BMAP2J7X.js → chunk-FOILW5QP.js} +1 -1
  43. package/dist/standalone/{chunk-NPHUYLGW.js → chunk-FSOA4SEY.js} +1 -1
  44. package/dist/standalone/{chunk-HCO5STOE.js → chunk-H2GRI4BS.js} +1 -1
  45. package/dist/standalone/{chunk-I27WXF7C.js → chunk-HD7R6NQT.js} +1 -1
  46. package/dist/standalone/{chunk-L6KA7M4B.js → chunk-IP6LZ2OL.js} +1 -1
  47. package/dist/standalone/{chunk-PNFIPQJO.js → chunk-IYS3RM7B.js} +1 -1
  48. package/dist/standalone/{chunk-BNGOZSCT.js → chunk-JWORA33E.js} +1 -1
  49. package/dist/standalone/chunk-KASQ7MFV.js +1 -0
  50. package/dist/standalone/{chunk-PV2LCZ6D.js → chunk-KDELXUQD.js} +1 -1
  51. package/dist/standalone/{chunk-B5FXTB7H.js → chunk-LSRUM2JJ.js} +1 -1
  52. package/dist/standalone/{chunk-XSLMHPP2.js → chunk-MFMUFECI.js} +1 -1
  53. package/dist/standalone/{chunk-7ZWZNTKG.js → chunk-MFXZDB7X.js} +1 -1
  54. package/dist/standalone/{chunk-WZYKLEU5.js → chunk-MMSQ35RC.js} +1 -1
  55. package/dist/standalone/{chunk-LPFRXMG7.js → chunk-MZXZ2XVQ.js} +1 -1
  56. package/dist/standalone/{chunk-KBSJO66O.js → chunk-N6Q4ORVH.js} +1 -1
  57. package/dist/standalone/{chunk-HS7MSYK7.js → chunk-NK7VUSL2.js} +1 -1
  58. package/dist/standalone/{chunk-QEN7S6YK.js → chunk-OJN5A2JI.js} +1 -1
  59. package/dist/standalone/{chunk-HJOKETMZ.js → chunk-OT4I4LMO.js} +1 -1
  60. package/dist/standalone/{chunk-BAIGKYAI.js → chunk-P3MCKI2S.js} +1 -1
  61. package/dist/standalone/chunk-PPNBTM7O.js +11 -0
  62. package/dist/standalone/{chunk-4TKQNBNV.js → chunk-Q2Q4UUXS.js} +1 -1
  63. package/dist/standalone/{chunk-XUKH3NTP.js → chunk-S6K7T563.js} +1 -1
  64. package/dist/standalone/chunk-S73X6JFA.js +1 -0
  65. package/dist/standalone/{chunk-WHWI6KXH.js → chunk-SNHEWTJY.js} +1 -1
  66. package/dist/standalone/{chunk-X43AA6RX.js → chunk-SOUQNAE7.js} +1 -1
  67. package/dist/standalone/chunk-SUDJTC4S.js +1 -0
  68. package/dist/standalone/{chunk-W7E5WYFI.js → chunk-TFNVT4ZJ.js} +1 -1
  69. package/dist/standalone/{chunk-T2IE5GKA.js → chunk-UODFNQOY.js} +4 -4
  70. package/dist/standalone/{chunk-JXELPXLG.js → chunk-URVSYGSQ.js} +1 -1
  71. package/dist/standalone/{chunk-O32757IN.js → chunk-V4EMZ3HJ.js} +1 -1
  72. package/dist/standalone/{chunk-PKCC4J5W.js → chunk-V7665E6Y.js} +1 -1
  73. package/dist/standalone/{chunk-WIFKQ25E.js → chunk-VAMUCQ75.js} +1 -1
  74. package/dist/standalone/{chunk-YKUEP7AA.js → chunk-VGGVQFKU.js} +1 -1
  75. package/dist/standalone/{chunk-ZNPR3SGG.js → chunk-VNK6MRM6.js} +1 -1
  76. package/dist/standalone/{chunk-HZX6KSC2.js → chunk-WISI2EBQ.js} +1 -1
  77. package/dist/standalone/{chunk-QM3SGSVK.js → chunk-WQWZR452.js} +1 -1
  78. package/dist/standalone/{chunk-AR46S3PP.js → chunk-X6GR3SDI.js} +1 -1
  79. package/dist/standalone/{chunk-A4MLWW6Q.js → chunk-XDLUQ6RQ.js} +1 -1
  80. package/dist/standalone/{chunk-IXLH5YBD.js → chunk-XTMBNA4V.js} +1 -1
  81. package/dist/standalone/{chunk-IXMHWLSN.js → chunk-Y3YXQ6EU.js} +1 -1
  82. package/dist/standalone/{chunk-V5ITAZCZ.js → chunk-YBWZUB6A.js} +1 -1
  83. package/dist/standalone/{chunk-IGBQ2CPW.js → chunk-YW3RHFAI.js} +1 -1
  84. package/dist/standalone/{chunk-LELCKAUP.js → chunk-ZQ2PIQE4.js} +1 -1
  85. package/dist/standalone/studio.js +7 -7
  86. package/package.json +6 -6
  87. package/dist/packem_shared/StudioApp-Bkym2DjT.mjs +0 -1
  88. package/dist/packem_shared/aggregateMetrics-A-Y7OH6R.mjs +0 -1
  89. package/dist/standalone/chunk-2O5QDSR2.js +0 -1
  90. package/dist/standalone/chunk-45T7VWRY.js +0 -1
  91. package/dist/standalone/chunk-AZOLR4BN.js +0 -1
  92. package/dist/standalone/chunk-CKZQXAZE.js +0 -1
  93. package/dist/standalone/chunk-TQCXJX4I.js +0 -1
  94. package/dist/standalone/chunk-XDT5DXOI.js +0 -11
  95. /package/dist/standalone/{chunk-YEBHHIAY.js → chunk-U5JDESCI.js} +0 -0
@@ -1 +1 @@
1
- import{c as O}from"react/compiler-runtime";import{useMemo as N,useState as P}from"react";import{useT as R}from"../packem_shared/DEFAULT_LOCALE-A1Yg5ORA.mjs";import{c as S}from"../packem_shared/utils-bhneXptQ.mjs";import{MigrationsPanel as H}from"../packem_shared/MigrationsPanel-BZJ_Rv4t.mjs";import{useNavigate as V,useSearch as Q}from"@tanstack/react-router";import{E as G}from"../packem_shared/error-alert-CWs6gA3I.mjs";import{E as K}from"../packem_shared/empty-state-D7jEML_T.mjs";import{u as T}from"../packem_shared/use-admin-query-C7JRlFIE.mjs";import{ADMIN_FUNCTIONS as I}from"../packem_shared/ADMIN_FUNCTIONS-B8yyk5BX.mjs";import{i as L,f as U}from"../packem_shared/internal-CwaF9YNk.mjs";import{S as _}from"../packem_shared/schema-diagram-DU83ObYH.mjs";import{jsx as c,jsxs as x}from"react/jsx-runtime";const M=1,$=t=>typeof t=="object"&&t!==null,B=t=>$(t)&&$(t.fields)&&$(t.indexes)&&$(t.relations)&&typeof t.shardMode=="string",W=t=>{if(t===void 0||t.trim()==="")return{status:"absent"};let e;try{e=JSON.parse(t)}catch(s){return{error:`baseline is not valid JSON: ${s instanceof Error?s.message:String(s)}`,status:"invalid"}}if(!$(e)||e.version!==M||!$(e.tables))return{error:`baseline is malformed or written by an incompatible version (expected version ${String(M)})`,status:"invalid"};for(const[s,n]of Object.entries(e.tables))if(!B(n))return{error:`baseline table "${s}" has an invalid structure`,status:"invalid"};return{snapshot:{jurisdiction:typeof e.jurisdiction=="string"?e.jurisdiction:void 0,migrationIds:Array.isArray(e.migrationIds)?e.migrationIds:[],tables:e.tables,version:M},status:"ok"}},z=(t,e)=>t.unique===e.unique&&t.fields.length===e.fields.length&&t.fields.every((i,s)=>i===e.fields[s]),X=(t,e,i,s)=>{const n=[];return i.kind!==s.kind&&n.push({remediation:"backfill",severity:"breaking",summary:`field ${t}.${e} changed type: ${i.kind} → ${s.kind} — add a data migration to convert existing values`,table:t,scope:"table",type:"changedFieldKind"}),i.optional&&!s.optional?n.push({remediation:"backfill",severity:"breaking",summary:`field ${t}.${e} became required — rows missing it would be invalid; add a data migration to backfill it`,table:t,scope:"table",type:"fieldOptionalToRequired"}):!i.optional&&s.optional&&n.push({remediation:"none",scope:"table",severity:"safe",summary:`field ${t}.${e} became optional`,table:t,type:"fieldRequiredToOptional"}),n},Y=(t,e,i)=>i.optional?{remediation:"none",scope:"table",severity:"safe",summary:`added optional field ${t}.${e}`,table:t,type:"addedOptionalField"}:{remediation:"backfill",severity:"breaking",summary:`added required field ${t}.${e} — existing rows have no value; add a data migration to backfill it`,table:t,scope:"table",type:"addedRequiredField"},Z=(t,e,i,s)=>{for(const[n,o]of Object.entries(i.fields)){const a=e.fields[n];a===void 0?s.push(Y(t,n,o)):s.push(...X(t,n,a,o))}for(const n of Object.keys(e.fields))i.fields[n]===void 0&&s.push({remediation:"backfill",severity:"breaking",summary:`removed field ${t}.${n} — add a data migration if stored data must be cleaned up`,table:t,scope:"table",type:"removedField"})},ee=(t,e,i,s)=>{for(const[n,o]of Object.entries(i.indexes)){const a=e.indexes[n];if(a===void 0){s.push({remediation:"none",scope:"table",severity:"safe",summary:`added index ${n} on ${t}`,table:t,type:"addedIndex"});continue}z(a,o)||s.push({remediation:"code",severity:"breaking",summary:`index ${n} on ${t} changed shape — a query may have relied on the old index`,table:t,scope:"table",type:"changedIndex"})}for(const n of Object.keys(e.indexes))i.indexes[n]===void 0&&s.push({remediation:"code",severity:"breaking",summary:`removed index ${n} on ${t} — a query that used \`.withIndex("${n}")\` would break`,table:t,scope:"table",type:"removedIndex"})},te=(t,e,i,s)=>{for(const n of Object.keys(i.relations))e.relations[n]===void 0&&s.push({remediation:"none",scope:"schema",severity:"safe",summary:`added relation ${t}.${n}`,table:t,type:"addedRelation"});for(const n of Object.keys(e.relations))i.relations[n]===void 0&&s.push({remediation:"code",scope:"schema",severity:"breaking",summary:`removed relation ${t}.${n}`,table:t,type:"removedRelation"})},se=(t,e,i,s)=>{e.shardMode!==i.shardMode&&s.push({remediation:"rehome",severity:"breaking",summary:`table ${t} changed shard mode: ${e.shardMode} → ${i.shardMode} — its physical storage moves, and existing rows do NOT follow the schema; re-home them with an export/import round trip (https://lunora.sh/docs/concepts/sharding#migrating-a-populated-table)`,table:t,scope:"table",type:"changedShardMode"}),Z(t,e,i,s),ee(t,e,i,s),te(t,e,i,s)},ie=(t,e)=>{const i=[],s=t?.tables??{};for(const[n,o]of Object.entries(e.tables)){const a=s[n];if(a===void 0){i.push({remediation:"none",scope:"table",severity:"safe",summary:`added table ${n}`,table:n,type:"addedTable"});continue}se(n,a,o,i)}for(const n of Object.keys(s))e.tables[n]===void 0&&i.push({remediation:"rehome",scope:"table",severity:"breaking",summary:`removed table ${n} — its rows stay in each shard's SQLite, unreachable through the schema; export the shard first if the data must be kept`,table:n,type:"removedTable"});if(t!==void 0&&t.jurisdiction!==e.jurisdiction){const n=t.jurisdiction??"(none)",o=e.jurisdiction??"(none)";i.push({remediation:"rehome",scope:"schema",severity:"breaking",summary:`Durable Object jurisdiction changed from ${n} to ${o} — this re-homes every DO and strands all existing shard, scheduler, and session-DO data in the old region (no in-place migration; export then import to move it). Revert the change, or override the gate to proceed intentionally.`,type:"changedJurisdiction"})}return{changes:i}},A=t=>Object.entries(t.fields).map(([e,i])=>({name:e,optional:i.optional,ref:Object.values(t.relations).find(s=>s.field===e&&s.kind==="one")?.table,type:i.kind})),C=(t,e)=>{const i={},s=t?.fields??{},n=e?.fields??{};for(const[o,a]of Object.entries(n)){const r=s[o];r===void 0?i[o]=t===void 0?"unchanged":"added":i[o]=r.kind===a.kind&&r.optional===a.optional?"unchanged":"changed"}for(const o of Object.keys(s))n[o]===void 0&&(i[o]="removed");return i},ne=(t,e)=>{const{changes:i}=ie(t,e),s=new Set(i.filter(a=>a.scope==="table"&&a.table!==void 0).map(a=>a.table)),n=[],o=(a,r)=>a?"added":s.has(r)?"changed":"context";for(const[a,r]of Object.entries(e.tables)){const d=t?.tables[a],m=o(d===void 0,a);n.push({columns:A(r),fieldStatus:C(d,r),name:a,shardMode:r.shardMode,status:m})}for(const[a,r]of Object.entries(t?.tables??{}))e.tables[a]===void 0&&n.push({columns:A(r),fieldStatus:C(r,void 0),name:a,shardMode:r.shardMode,status:"removed"});return n.sort((a,r)=>a.name.localeCompare(r.name)),{breakingCount:i.filter(a=>a.severity==="breaking").length,changes:i,tables:n}},E=t=>{const e=W(t);return e.status==="ok"?e.snapshot:void 0},ae={added:"ring-2 ring-emerald-500/60",changed:"ring-2 ring-amber-500/70",context:"opacity-55",removed:"opacity-70 ring-2 ring-destructive/60"},oe=t=>t==="global"?"global":"shard",re=t=>{const e=O(24),{appliedAt:i,hash:s,onSelect:n,selected:o,seq:a}=t,r=o?"border-s-primary bg-accent/60 text-foreground":"border-s-transparent text-muted-foreground hover:bg-accent/30 hover:text-foreground";let d;e[0]!==r?(d=S("flex w-full flex-col items-start gap-1 border-s-2 px-4 py-3 text-start outline-none transition-colors",r),e[0]=r,e[1]=d):d=e[1];const m=`sh-version-${s}`;let u;e[2]!==s||e[3]!==n?(u=()=>{n(s)},e[2]=s,e[3]=n,e[4]=u):u=e[4];let h;e[5]!==a?(h=x("span",{className:"font-mono text-[13px] tabular-nums",children:["v",a]}),e[5]=a,e[6]=h):h=e[6];let b;e[7]!==s?(b=s.slice(0,7),e[7]=s,e[8]=b):b=e[8];let p;e[9]!==b?(p=c("span",{className:"ms-auto font-mono text-[10px] tracking-wider text-muted-foreground/70 uppercase",children:b}),e[9]=b,e[10]=p):p=e[10];let f;e[11]!==h||e[12]!==p?(f=x("span",{className:"flex w-full items-baseline gap-2",children:[h,p]}),e[11]=h,e[12]=p,e[13]=f):f=e[13];let g;e[14]!==i?(g=L(i),e[14]=i,e[15]=g):g=e[15];let v;e[16]!==g?(v=c("span",{className:"font-mono text-[10px] tracking-wide text-muted-foreground/70",children:g}),e[16]=g,e[17]=v):v=e[17];let y;return e[18]!==v||e[19]!==d||e[20]!==m||e[21]!==u||e[22]!==f?(y=c("li",{children:x("button",{className:d,"data-testid":m,onClick:u,type:"button",children:[f,v]})}),e[18]=v,e[19]=d,e[20]=m,e[21]=u,e[22]=f,e[23]=y):y=e[23],y},de=t=>{const e=O(26),{breaking:i,count:s,first:n}=t,o=R();if(n){let p;e[0]!==s?(p=c("span",{className:"text-3xl leading-none font-light tracking-tight tabular-nums",children:s}),e[0]=s,e[1]=p):p=e[1];let f;e[2]!==o?(f=o("tables"),e[2]=o,e[3]=f):f=e[3];let g;e[4]!==f?(g=c("span",{className:"font-mono text-[11px] tracking-widest text-muted-foreground uppercase",children:f}),e[4]=f,e[5]=g):g=e[5];let v;return e[6]!==p||e[7]!==g?(v=x("div",{className:"flex items-baseline gap-3","data-testid":"sh-summary",children:[p,g]}),e[6]=p,e[7]=g,e[8]=v):v=e[8],v}const a=i>0&&"text-destructive";let r;e[9]!==a?(r=S("text-3xl leading-none font-light tracking-tight tabular-nums",a),e[9]=a,e[10]=r):r=e[10];let d;e[11]!==s||e[12]!==r?(d=c("span",{className:r,children:s}),e[11]=s,e[12]=r,e[13]=d):d=e[13];let m;e[14]!==s||e[15]!==o?(m=o(s===1?"change":"changes"),e[14]=s,e[15]=o,e[16]=m):m=e[16];let u;e[17]!==m?(u=c("span",{className:"font-mono text-[11px] tracking-widest text-muted-foreground uppercase",children:m}),e[17]=m,e[18]=u):u=e[18];let h;e[19]!==i||e[20]!==o?(h=i>0&&x("span",{className:"font-mono text-[11px] tracking-widest text-destructive uppercase",children:["· ",o("{count} breaking",{count:i})]}),e[19]=i,e[20]=o,e[21]=h):h=e[21];let b;return e[22]!==d||e[23]!==u||e[24]!==h?(b=x("div",{className:"flex items-baseline gap-3","data-testid":"sh-summary",children:[d,u,h]}),e[22]=d,e[23]=u,e[24]=h,e[25]=b):b=e[25],b},D={addedIndex:{action:"added",kind:"index"},addedOptionalField:{action:"added",kind:"field?"},addedRelation:{action:"added",kind:"relation"},addedRequiredField:{action:"added",kind:"field"},addedTable:{action:"added",kind:"table"},changedFieldKind:{action:"changed",kind:"field kind"},changedIndex:{action:"changed",kind:"index"},changedJurisdiction:{action:"changed",kind:"jurisdiction"},changedShardMode:{action:"changed",kind:"shard mode"},fieldOptionalToRequired:{action:"changed",kind:"field → required"},fieldRequiredToOptional:{action:"changed",kind:"field → optional"},removedField:{action:"removed",kind:"field"},removedIndex:{action:"removed",kind:"index"},removedRelation:{action:"removed",kind:"relation"},removedTable:{action:"removed",kind:"table"}},le=(t,e)=>{const i=`${D[t.type].action} ${e} `;return t.summary.startsWith(i)?t.summary.slice(i.length):t.summary},ce=t=>{const e=new Map;for(const s of t){const n=s.table??"",o=e.get(n);o===void 0?e.set(n,[s]):o.push(s)}const i=[...e].map(([s,n])=>({changes:n,table:s}));return[...i.filter(s=>s.table!==""),...i.filter(s=>s.table==="")]},me=t=>{const e=O(2),{children:i}=t;let s;return e[0]!==i?(s=c("div",{className:"px-4 pt-4 pb-2 font-mono text-[10px] tracking-widest text-muted-foreground/70 uppercase",children:i}),e[0]=i,e[1]=s):s=e[1],s},fe=({pane:t,shardKey:e=""})=>{const i=R(),s=V(),o=Q({strict:!1}).version,a=l=>{U(s({search:{version:l},to:"/migrations"}))},r=T(I.schemaHistory,{},{shardKey:e}),d=r.data?.versions??[],m=o!==void 0&&d.some(l=>l.hash===o)?o:d[0]?.hash,u=d.findIndex(l=>l.hash===m),h=u===-1?void 0:d[u+1]?.hash,b=T(I.schemaVersion,{hash:m??""},{enabled:m!==void 0,shardKey:e}),p=T(I.schemaVersion,{hash:h??""},{enabled:h!==void 0,shardKey:e}),f=N(()=>{const l=E(b.data?.version?.snapshotJson);if(l!==void 0)return ne(E(p.data?.version?.snapshotJson),l)},[b.data,p.data]),g=N(()=>(f?.tables??[]).map(l=>({columns:l.columns,name:l.name,tier:oe(l.shardMode)})),[f]),v=N(()=>{const l={};for(const w of f?.tables??[])l[w.name]=ae[w.status];return l},[f]);if(r.error!==null)return c(G,{error:r.errorSource,testId:"sh-error"});if(d.length===0)return c(K,{description:i("Each distinct schema shape this shard runs is recorded here, so you can see what changed and when."),testId:"sh-empty",title:i("No schema versions recorded yet.")});const y=f?.changes??[];return x("div",{className:"flex min-h-0 flex-1 gap-4","data-testid":"lunora-schema-history",children:[x("nav",{className:"flex w-56 shrink-0 flex-col overflow-hidden border-e border-border","data-testid":"sh-timeline-rail",children:[c(me,{children:i("Schema versions")}),c("ul",{className:"min-h-0 flex-1 overflow-y-auto","data-testid":"sh-timeline",children:d.map(l=>c(re,{appliedAt:l.appliedAt,hash:l.hash,onSelect:a,selected:l.hash===m,seq:l.seq},l.hash))})]}),x("div",{className:"flex min-h-0 min-w-0 flex-1 flex-col gap-4 pe-1 pt-4",children:[c(de,{breaking:f?.breakingCount??0,count:h===void 0?g.length:y.length,first:h===void 0}),t==="diagram"?c("div",{className:"flex min-h-0 flex-1 flex-col",children:c(_,{fill:!0,nodeClasses:v,tables:g,testIdPrefix:"sh"})}):c("div",{className:"min-h-0 flex-1 overflow-y-auto","data-testid":"sh-changes",children:ce(y).map(l=>{const w=(f?.tables??[]).find(k=>k.name===l.table);return x("section",{className:"mb-6",children:[x("div",{className:"flex items-baseline gap-3 border-b border-border/60 pb-1.5",children:[c("span",{className:"font-mono text-[13px] text-foreground",children:l.table===""?i("schema"):l.table}),w!==void 0&&c("span",{className:"font-mono text-[10px] tracking-widest text-muted-foreground/70 tabular-nums uppercase",children:i("{count} columns",{count:w.columns.length})}),l.changes.length>1&&c("span",{className:"ms-auto font-mono text-[10px] tracking-widest text-muted-foreground/70 tabular-nums",children:l.changes.length})]}),c("ul",{children:l.changes.map(k=>{const{action:J,kind:q}=D[k.type],j=k.severity==="breaking",F=le(k,q);return x("li",{className:"flex items-baseline gap-4 border-s-2 py-1.5 ps-3 transition-colors hover:bg-accent/30",children:[c("span",{"aria-hidden":"true",className:S("-ms-3 h-3 w-0.5 shrink-0 self-center",j?"bg-destructive":"bg-transparent")}),x("span",{className:"w-44 shrink-0 font-mono text-[10px] tracking-widest text-muted-foreground/70 uppercase",children:[i(J)," ",q]}),F!==l.table&&c("span",{className:S("min-w-0 font-mono text-[13px]",j?"text-destructive":"text-foreground"),children:F}),j&&c("span",{className:"ms-auto shrink-0 font-mono text-[10px] tracking-widest text-destructive uppercase",children:i("breaking")})]},`${k.type}-${k.summary}`)})})]},l.table)})})]})]})},he=t=>S("-mb-px border-b-2 px-3 py-2.5 font-mono text-[11px] tracking-wider uppercase transition-colors outline-none","hover:bg-accent/40 focus-visible:bg-accent/40",t?"border-primary text-foreground":"border-transparent text-muted-foreground hover:text-foreground"),Ne=t=>{const e=O(11),{initialShardKey:i}=t,s=R(),[n,o]=P("diagram");let a;e[0]!==n?(a=(h,b,p,f)=>x("button",{"aria-selected":n===h,className:he(n===h),"data-testid":p,onClick:()=>{o(h)},role:"tab",type:"button",children:[b,f!==void 0&&c("span",{className:"ms-2 tabular-nums text-muted-foreground/70",children:f})]}),e[0]=n,e[1]=a):a=e[1];const r=a;let d;e[2]!==s||e[3]!==r?(d=x("div",{className:"flex shrink-0 items-center gap-1 border-b border-border px-3","data-testid":"mg-panes",role:"tablist",children:[r("diagram",s("Diagram"),"mg-pane-diagram"),r("changes",s("Changes"),"mg-pane-changes"),r("data",s("Data migrations"),"mg-pane-data")]}),e[2]=s,e[3]=r,e[4]=d):d=e[4];let m;e[5]!==i||e[6]!==n?(m=c("div",{className:"flex min-h-0 flex-1 flex-col",children:n==="data"?c("div",{className:"min-h-0 flex-1 overflow-y-auto px-4",children:c(H,{initialShardKey:i})}):c(fe,{pane:n,shardKey:i})}),e[5]=i,e[6]=n,e[7]=m):m=e[7];let u;return e[8]!==d||e[9]!==m?(u=x("div",{className:"flex min-h-0 flex-1 flex-col pt-4","data-testid":"lunora-migrations-route",children:[d,m]}),e[8]=d,e[9]=m,e[10]=u):u=e[10],u};export{Ne as default};
1
+ import{c as q}from"react/compiler-runtime";import{useMemo as I,useState as G}from"react";import{useT as E}from"../packem_shared/DEFAULT_LOCALE-A1Yg5ORA.mjs";import{c as O}from"../packem_shared/utils-bhneXptQ.mjs";import{MigrationsPanel as W}from"../packem_shared/MigrationsPanel-BZJ_Rv4t.mjs";import{useNavigate as _,useSearch as B}from"@tanstack/react-router";import{E as z}from"../packem_shared/error-alert-CWs6gA3I.mjs";import{E as X}from"../packem_shared/empty-state-D7jEML_T.mjs";import{u as M}from"../packem_shared/use-admin-query-C7JRlFIE.mjs";import{ADMIN_FUNCTIONS as R}from"../packem_shared/ADMIN_FUNCTIONS-B8yyk5BX.mjs";import{i as Y,f as Z}from"../packem_shared/internal-CwaF9YNk.mjs";import{S as ee}from"../packem_shared/schema-diagram-DU83ObYH.mjs";import{jsx as c,jsxs as v}from"react/jsx-runtime";const A=1;function te(t){const e={},s=Object.keys(t);s.sort();for(const n of s)e[n]=t[n];return e}const w=t=>typeof t=="object"&&t!==null,ne=t=>w(t)&&w(t.fields)&&w(t.indexes)&&w(t.relations)&&typeof t.shardMode=="string",se=t=>{if(t===void 0||t.trim()==="")return{status:"absent"};let e;try{e=JSON.parse(t)}catch(n){return{error:`baseline is not valid JSON: ${n instanceof Error?n.message:String(n)}`,status:"invalid"}}if(!w(e)||e.version!==A||!w(e.tables))return{error:`baseline is malformed or written by an incompatible version (expected version ${String(A)})`,status:"invalid"};for(const[n,i]of Object.entries(e.tables))if(!ne(i))return{error:`baseline table "${n}" has an invalid structure`,status:"invalid"};return{snapshot:{jurisdiction:typeof e.jurisdiction=="string"?e.jurisdiction:void 0,migrationIds:Array.isArray(e.migrationIds)?e.migrationIds:[],tables:e.tables,version:A},status:"ok"}},ie=(t,e)=>t.unique===e.unique&&t.fields.length===e.fields.length&&t.fields.every((s,n)=>s===e.fields[n]),J=t=>t.unique!==void 0,C=({nullable:t,optional:e,refined:s,unique:n,...i})=>JSON.stringify(te(i)),P=t=>t.kind==="union"&&t.members?t.members.map(e=>C(e)):[C(t)],ae=(t,e)=>{if(e.kind!=="union")return!1;const s=new Set(P(e));return P(t).every(n=>s.has(n))},y=t=>{switch(t.kind){case"array":return`array(${t.of?y(t.of):"?"})`;case"id":return`id(${t.ref??"?"})`;case"literal":return`literal(${t.literal??"?"})`;case"object":return`object({ ${Object.keys(t.fields??{}).join(", ")} })`;case"record":return`record(${t.key?y(t.key):"?"}, ${t.of?y(t.of):"?"})`;case"union":return(t.members??[]).map(e=>y(e)).join(" | ");default:return t.kind}},j=(t,e,s)=>({remediation:"backfill",scope:"table",severity:"breaking",summary:s,table:t,type:e}),F=(t,e,s)=>({remediation:"none",scope:"table",severity:"safe",summary:s,table:t,type:e}),oe=(t,e,s,n,i)=>{if(!(s.kind===n.kind&&(!i||C(s)===C(n))))return i&&ae(s,n)?F(t,"widenedFieldShape",`field ${t}.${e} widened: ${y(s)} → ${y(n)} — every stored value stays valid`):s.kind!==n.kind?j(t,"changedFieldKind",`field ${t}.${e} changed type: ${s.kind} → ${n.kind} — add a data migration to convert existing values`):j(t,"changedFieldShape",`field ${t}.${e} changed shape: ${y(s)} → ${y(n)} — stored values were written against the old shape; add a data migration to convert them`)},re=(t,e,s,n)=>{const i=[];return s.unique!==n.unique&&i.push(n.unique===!0?j(t,"addedFieldConstraint",`field ${t}.${e} became unique — existing duplicates would violate it; add a data migration to de-duplicate first`):F(t,"relaxedFieldConstraint",`field ${t}.${e} is no longer unique`)),s.nullable!==n.nullable&&i.push(n.nullable===!0?F(t,"relaxedFieldConstraint",`field ${t}.${e} became nullable`):j(t,"addedFieldConstraint",`field ${t}.${e} is no longer nullable — rows holding NULL would be invalid; add a data migration to backfill them`)),s.refined!==n.refined&&i.push(n.refined===!0?j(t,"addedFieldConstraint",`field ${t}.${e} gained a validation refinement — stored values were never checked against it; add a data migration if any could fail`):F(t,"relaxedFieldConstraint",`field ${t}.${e} dropped its validation refinement`)),i},L=(t,e,s,n)=>{const i=[],o=J(s)&&J(n),a=oe(t,e,s,n,o);return a&&i.push(a),o&&i.push(...re(t,e,s,n)),s.optional&&!n.optional?i.push({remediation:"backfill",severity:"breaking",summary:`field ${t}.${e} became required — rows missing it would be invalid; add a data migration to backfill it`,table:t,scope:"table",type:"fieldOptionalToRequired"}):!s.optional&&n.optional&&i.push({remediation:"none",scope:"table",severity:"safe",summary:`field ${t}.${e} became optional`,table:t,type:"fieldRequiredToOptional"}),i},de=(t,e,s)=>s.optional?{remediation:"none",scope:"table",severity:"safe",summary:`added optional field ${t}.${e}`,table:t,type:"addedOptionalField"}:{remediation:"backfill",severity:"breaking",summary:`added required field ${t}.${e} — existing rows have no value; add a data migration to backfill it`,table:t,scope:"table",type:"addedRequiredField"},le=(t,e,s,n)=>{for(const[i,o]of Object.entries(s.fields)){const a=e.fields[i];a===void 0?n.push(de(t,i,o)):n.push(...L(t,i,a,o))}for(const i of Object.keys(e.fields))s.fields[i]===void 0&&n.push({remediation:"backfill",severity:"breaking",summary:`removed field ${t}.${i} — add a data migration if stored data must be cleaned up`,table:t,scope:"table",type:"removedField"})},ce=(t,e,s,n)=>{for(const[i,o]of Object.entries(s.indexes)){const a=e.indexes[i];if(a===void 0){n.push({remediation:"none",scope:"table",severity:"safe",summary:`added index ${i} on ${t}`,table:t,type:"addedIndex"});continue}ie(a,o)||n.push({remediation:"code",severity:"breaking",summary:`index ${i} on ${t} changed shape — a query may have relied on the old index`,table:t,scope:"table",type:"changedIndex"})}for(const i of Object.keys(e.indexes))s.indexes[i]===void 0&&n.push({remediation:"code",severity:"breaking",summary:`removed index ${i} on ${t} — a query that used \`.withIndex("${i}")\` would break`,table:t,scope:"table",type:"removedIndex"})},ue=(t,e,s,n)=>{for(const i of Object.keys(s.relations))e.relations[i]===void 0&&n.push({remediation:"none",scope:"schema",severity:"safe",summary:`added relation ${t}.${i}`,table:t,type:"addedRelation"});for(const i of Object.keys(e.relations))s.relations[i]===void 0&&n.push({remediation:"code",scope:"schema",severity:"breaking",summary:`removed relation ${t}.${i}`,table:t,type:"removedRelation"})},me=(t,e,s,n)=>{e.shardMode!==s.shardMode&&n.push({remediation:"rehome",severity:"breaking",summary:`table ${t} changed shard mode: ${e.shardMode} → ${s.shardMode} — its physical storage moves, and existing rows do NOT follow the schema; re-home them with an export/import round trip (https://lunora.sh/docs/concepts/sharding#migrating-a-populated-table)`,table:t,scope:"table",type:"changedShardMode"}),le(t,e,s,n),ce(t,e,s,n),ue(t,e,s,n)},he=(t,e)=>{const s=[],n=t?.tables??{};for(const[i,o]of Object.entries(e.tables)){const a=n[i];if(a===void 0){s.push({remediation:"none",scope:"table",severity:"safe",summary:`added table ${i}`,table:i,type:"addedTable"});continue}me(i,a,o,s)}for(const i of Object.keys(n))e.tables[i]===void 0&&s.push({remediation:"rehome",scope:"table",severity:"breaking",summary:`removed table ${i} — its rows stay in each shard's SQLite, unreachable through the schema; export the shard first if the data must be kept`,table:i,type:"removedTable"});if(t!==void 0&&t.jurisdiction!==e.jurisdiction){const i=t.jurisdiction??"(none)",o=e.jurisdiction??"(none)";s.push({remediation:"rehome",scope:"schema",severity:"breaking",summary:`Durable Object jurisdiction changed from ${i} to ${o} — this re-homes every DO and strands all existing shard, scheduler, and session-DO data in the old region (no in-place migration; export then import to move it). Revert the change, or override the gate to proceed intentionally.`,type:"changedJurisdiction"})}return{changes:s}},H=t=>Object.entries(t.fields).map(([e,s])=>({name:e,optional:s.optional,ref:Object.values(t.relations).find(n=>n.field===e&&n.kind==="one")?.table,type:y(s)})),V=(t,e,s)=>{const n={},i=e?.fields??{},o=s?.fields??{};for(const[a,r]of Object.entries(o)){const d=i[a];d===void 0?n[a]=e===void 0?"unchanged":"added":n[a]=L(t,a,d,r).length===0?"unchanged":"changed"}for(const a of Object.keys(i))o[a]===void 0&&(n[a]="removed");return n},fe=(t,e)=>{const{changes:s}=he(t,e),n=new Set(s.filter(a=>a.scope==="table"&&a.table!==void 0).map(a=>a.table)),i=[],o=(a,r)=>a?"added":n.has(r)?"changed":"context";for(const[a,r]of Object.entries(e.tables)){const d=t?.tables[a],u=o(d===void 0,a);i.push({columns:H(r),fieldStatus:V(a,d,r),name:a,shardMode:r.shardMode,status:u})}for(const[a,r]of Object.entries(t?.tables??{}))e.tables[a]===void 0&&i.push({columns:H(r),fieldStatus:V(a,r,void 0),name:a,shardMode:r.shardMode,status:"removed"});return i.sort((a,r)=>a.name.localeCompare(r.name)),{breakingCount:s.filter(a=>a.severity==="breaking").length,changes:s,tables:i}},Q=t=>{const e=se(t);return e.status==="ok"?e.snapshot:void 0},pe={added:"ring-2 ring-emerald-500/60",changed:"ring-2 ring-amber-500/70",context:"opacity-55",removed:"opacity-70 ring-2 ring-destructive/60"},ge=t=>t==="global"?"global":"shard",be=t=>{const e=q(24),{appliedAt:s,hash:n,onSelect:i,selected:o,seq:a}=t,r=o?"border-s-primary bg-accent/60 text-foreground":"border-s-transparent text-muted-foreground hover:bg-accent/30 hover:text-foreground";let d;e[0]!==r?(d=O("flex w-full flex-col items-start gap-1 border-s-2 px-4 py-3 text-start outline-none transition-colors",r),e[0]=r,e[1]=d):d=e[1];const u=`sh-version-${n}`;let f;e[2]!==n||e[3]!==i?(f=()=>{i(n)},e[2]=n,e[3]=i,e[4]=f):f=e[4];let h;e[5]!==a?(h=v("span",{className:"font-mono text-[13px] tabular-nums",children:["v",a]}),e[5]=a,e[6]=h):h=e[6];let g;e[7]!==n?(g=n.slice(0,7),e[7]=n,e[8]=g):g=e[8];let p;e[9]!==g?(p=c("span",{className:"ms-auto font-mono text-[10px] tracking-wider text-muted-foreground/70 uppercase",children:g}),e[9]=g,e[10]=p):p=e[10];let m;e[11]!==h||e[12]!==p?(m=v("span",{className:"flex w-full items-baseline gap-2",children:[h,p]}),e[11]=h,e[12]=p,e[13]=m):m=e[13];let b;e[14]!==s?(b=Y(s),e[14]=s,e[15]=b):b=e[15];let x;e[16]!==b?(x=c("span",{className:"font-mono text-[10px] tracking-wide text-muted-foreground/70",children:b}),e[16]=b,e[17]=x):x=e[17];let k;return e[18]!==x||e[19]!==d||e[20]!==u||e[21]!==f||e[22]!==m?(k=c("li",{children:v("button",{className:d,"data-testid":u,onClick:f,type:"button",children:[m,x]})}),e[18]=x,e[19]=d,e[20]=u,e[21]=f,e[22]=m,e[23]=k):k=e[23],k},ve=t=>{const e=q(26),{breaking:s,count:n,first:i}=t,o=E();if(i){let p;e[0]!==n?(p=c("span",{className:"text-3xl leading-none font-light tracking-tight tabular-nums",children:n}),e[0]=n,e[1]=p):p=e[1];let m;e[2]!==o?(m=o("tables"),e[2]=o,e[3]=m):m=e[3];let b;e[4]!==m?(b=c("span",{className:"font-mono text-[11px] tracking-widest text-muted-foreground uppercase",children:m}),e[4]=m,e[5]=b):b=e[5];let x;return e[6]!==p||e[7]!==b?(x=v("div",{className:"flex items-baseline gap-3","data-testid":"sh-summary",children:[p,b]}),e[6]=p,e[7]=b,e[8]=x):x=e[8],x}const a=s>0&&"text-destructive";let r;e[9]!==a?(r=O("text-3xl leading-none font-light tracking-tight tabular-nums",a),e[9]=a,e[10]=r):r=e[10];let d;e[11]!==n||e[12]!==r?(d=c("span",{className:r,children:n}),e[11]=n,e[12]=r,e[13]=d):d=e[13];let u;e[14]!==n||e[15]!==o?(u=o(n===1?"change":"changes"),e[14]=n,e[15]=o,e[16]=u):u=e[16];let f;e[17]!==u?(f=c("span",{className:"font-mono text-[11px] tracking-widest text-muted-foreground uppercase",children:u}),e[17]=u,e[18]=f):f=e[18];let h;e[19]!==s||e[20]!==o?(h=s>0&&v("span",{className:"font-mono text-[11px] tracking-widest text-destructive uppercase",children:["· ",o("{count} breaking",{count:s})]}),e[19]=s,e[20]=o,e[21]=h):h=e[21];let g;return e[22]!==d||e[23]!==f||e[24]!==h?(g=v("div",{className:"flex items-baseline gap-3","data-testid":"sh-summary",children:[d,f,h]}),e[22]=d,e[23]=f,e[24]=h,e[25]=g):g=e[25],g},K={addedFieldConstraint:{action:"added",kind:"constraint"},addedIndex:{action:"added",kind:"index"},addedOptionalField:{action:"added",kind:"field?"},addedRelation:{action:"added",kind:"relation"},addedRequiredField:{action:"added",kind:"field"},addedTable:{action:"added",kind:"table"},changedFieldKind:{action:"changed",kind:"field kind"},changedFieldShape:{action:"changed",kind:"field shape"},changedIndex:{action:"changed",kind:"index"},changedJurisdiction:{action:"changed",kind:"jurisdiction"},changedShardMode:{action:"changed",kind:"shard mode"},fieldOptionalToRequired:{action:"changed",kind:"field → required"},fieldRequiredToOptional:{action:"changed",kind:"field → optional"},relaxedFieldConstraint:{action:"removed",kind:"constraint"},removedField:{action:"removed",kind:"field"},removedIndex:{action:"removed",kind:"index"},removedRelation:{action:"removed",kind:"relation"},removedTable:{action:"removed",kind:"table"},widenedFieldShape:{action:"changed",kind:"field → wider"}},xe=(t,e)=>{const s=`${K[t.type].action} ${e} `;return t.summary.startsWith(s)?t.summary.slice(s.length):t.summary},ye=t=>{const e=new Map;for(const n of t){const i=n.table??"",o=e.get(i);o===void 0?e.set(i,[n]):o.push(n)}const s=[...e].map(([n,i])=>({changes:i,table:n}));return[...s.filter(n=>n.table!==""),...s.filter(n=>n.table==="")]},ke=t=>{const e=q(2),{children:s}=t;let n;return e[0]!==s?(n=c("div",{className:"px-4 pt-4 pb-2 font-mono text-[10px] tracking-widest text-muted-foreground/70 uppercase",children:s}),e[0]=s,e[1]=n):n=e[1],n},$e=({pane:t,shardKey:e=""})=>{const s=E(),n=_(),o=B({strict:!1}).version,a=l=>{Z(n({search:{version:l},to:"/migrations"}))},r=M(R.schemaHistory,{},{shardKey:e}),d=r.data?.versions??[],u=o!==void 0&&d.some(l=>l.hash===o)?o:d[0]?.hash,f=d.findIndex(l=>l.hash===u),h=f===-1?void 0:d[f+1]?.hash,g=M(R.schemaVersion,{hash:u??""},{enabled:u!==void 0,shardKey:e}),p=M(R.schemaVersion,{hash:h??""},{enabled:h!==void 0,shardKey:e}),m=I(()=>{const l=Q(g.data?.version?.snapshotJson);if(l!==void 0)return fe(Q(p.data?.version?.snapshotJson),l)},[g.data,p.data]),b=I(()=>(m?.tables??[]).map(l=>({columns:l.columns,name:l.name,tier:ge(l.shardMode)})),[m]),x=I(()=>{const l={};for(const S of m?.tables??[])l[S.name]=pe[S.status];return l},[m]);if(r.error!==null)return c(z,{error:r.errorSource,testId:"sh-error"});if(d.length===0)return c(X,{description:s("Each distinct schema shape this shard runs is recorded here, so you can see what changed and when."),testId:"sh-empty",title:s("No schema versions recorded yet.")});const k=m?.changes??[];return v("div",{className:"flex min-h-0 flex-1 gap-4","data-testid":"lunora-schema-history",children:[v("nav",{className:"flex w-56 shrink-0 flex-col overflow-hidden border-e border-border","data-testid":"sh-timeline-rail",children:[c(ke,{children:s("Schema versions")}),c("ul",{className:"min-h-0 flex-1 overflow-y-auto","data-testid":"sh-timeline",children:d.map(l=>c(be,{appliedAt:l.appliedAt,hash:l.hash,onSelect:a,selected:l.hash===u,seq:l.seq},l.hash))})]}),v("div",{className:"flex min-h-0 min-w-0 flex-1 flex-col gap-4 pe-1 pt-4",children:[c(ve,{breaking:m?.breakingCount??0,count:h===void 0?b.length:k.length,first:h===void 0}),t==="diagram"?c("div",{className:"flex min-h-0 flex-1 flex-col",children:c(ee,{fill:!0,nodeClasses:x,tables:b,testIdPrefix:"sh"})}):c("div",{className:"min-h-0 flex-1 overflow-y-auto","data-testid":"sh-changes",children:ye(k).map(l=>{const S=(m?.tables??[]).find($=>$.name===l.table);return v("section",{className:"mb-6",children:[v("div",{className:"flex items-baseline gap-3 border-b border-border/60 pb-1.5",children:[c("span",{className:"font-mono text-[13px] text-foreground",children:l.table===""?s("schema"):l.table}),S!==void 0&&c("span",{className:"font-mono text-[10px] tracking-widest text-muted-foreground/70 tabular-nums uppercase",children:s("{count} columns",{count:S.columns.length})}),l.changes.length>1&&c("span",{className:"ms-auto font-mono text-[10px] tracking-widest text-muted-foreground/70 tabular-nums",children:l.changes.length})]}),c("ul",{children:l.changes.map($=>{const{action:U,kind:N}=K[$.type],T=$.severity==="breaking",D=xe($,N);return v("li",{className:"flex items-baseline gap-4 border-s-2 py-1.5 ps-3 transition-colors hover:bg-accent/30",children:[c("span",{"aria-hidden":"true",className:O("-ms-3 h-3 w-0.5 shrink-0 self-center",T?"bg-destructive":"bg-transparent")}),v("span",{className:"w-44 shrink-0 font-mono text-[10px] tracking-widest text-muted-foreground/70 uppercase",children:[s(U)," ",N]}),D!==l.table&&c("span",{className:O("min-w-0 font-mono text-[13px]",T?"text-destructive":"text-foreground"),children:D}),T&&c("span",{className:"ms-auto shrink-0 font-mono text-[10px] tracking-widest text-destructive uppercase",children:s("breaking")})]},`${$.type}-${$.summary}`)})})]},l.table)})})]})]})},we=t=>O("-mb-px border-b-2 px-3 py-2.5 font-mono text-[11px] tracking-wider uppercase transition-colors outline-none","hover:bg-accent/40 focus-visible:bg-accent/40",t?"border-primary text-foreground":"border-transparent text-muted-foreground hover:text-foreground"),De=t=>{const e=q(11),{initialShardKey:s}=t,n=E(),[i,o]=G("diagram");let a;e[0]!==i?(a=(h,g,p,m)=>v("button",{"aria-selected":i===h,className:we(i===h),"data-testid":p,onClick:()=>{o(h)},role:"tab",type:"button",children:[g,m!==void 0&&c("span",{className:"ms-2 tabular-nums text-muted-foreground/70",children:m})]}),e[0]=i,e[1]=a):a=e[1];const r=a;let d;e[2]!==n||e[3]!==r?(d=v("div",{className:"flex shrink-0 items-center gap-1 border-b border-border px-3","data-testid":"mg-panes",role:"tablist",children:[r("diagram",n("Diagram"),"mg-pane-diagram"),r("changes",n("Changes"),"mg-pane-changes"),r("data",n("Data migrations"),"mg-pane-data")]}),e[2]=n,e[3]=r,e[4]=d):d=e[4];let u;e[5]!==s||e[6]!==i?(u=c("div",{className:"flex min-h-0 flex-1 flex-col",children:i==="data"?c("div",{className:"min-h-0 flex-1 overflow-y-auto px-4",children:c(W,{initialShardKey:s})}):c($e,{pane:i,shardKey:s})}),e[5]=s,e[6]=i,e[7]=u):u=e[7];let f;return e[8]!==d||e[9]!==u?(f=v("div",{className:"flex min-h-0 flex-1 flex-col pt-4","data-testid":"lunora-migrations-route",children:[d,u]}),e[8]=d,e[9]=u,e[10]=f):f=e[10],f};export{De as default};
@@ -1 +1 @@
1
- import{c as D}from"react/compiler-runtime";import{useState as F}from"react";import{B as Y}from"../packem_shared/button-q0UYSmrn.mjs";import{useT as M}from"../packem_shared/DEFAULT_LOCALE-A1Yg5ORA.mjs";import{useLunora as V}from"@lunora/react";import{ConfirmButton as G}from"../packem_shared/ConfirmButton-DU4p72Er.mjs";import{B as O}from"../packem_shared/badge-r_5B4LHP.mjs";import{C as P,a as R}from"../packem_shared/card--2hKx4L2.mjs";import{E as W}from"../packem_shared/empty-state-D7jEML_T.mjs";import{T as Q,a as K,b as q,c as x,d as z,e as b}from"../packem_shared/table-D0SBiDu-.mjs";import{b as H}from"../packem_shared/use-admin-query-C7JRlFIE.mjs";import{f as A,b as U,i as j}from"../packem_shared/internal-CwaF9YNk.mjs";import{jsxs as u,jsx as t}from"react/jsx-runtime";import{useAutoRefresh as X}from"../packem_shared/DEFAULT_AUTO_REFRESH_MS-DuULO4XM.mjs";import{ScheduledJobs as ee}from"../packem_shared/ScheduledJobs-oDVEymk5.mjs";const te={kind:"idle"},re=(n,e,c)=>c!==void 0?c:e===void 0?a=>n.runCronJob(a):void 0,le=({loadCronJobs:n,runCronJob:e}={})=>{const c=V(),a=M(),[p,o]=F({}),s=H(["lunora-cron-jobs",n?"custom":"default"],()=>(n??(()=>c.getCronJobs()))()),{data:r,error:y}=s,h=re(c,n,e),i=async l=>{if(h!==void 0){o(d=>({...d,[l]:{kind:"running"}}));try{await h(l),o(d=>({...d,[l]:{kind:"ok"}})),s.refetch()}catch(d){o(g=>({...g,[l]:{kind:"error",message:U(d)}}))}}};return u("div",{className:"flex flex-col gap-3","data-testid":"lunora-cron-triggers",children:[y!==null&&t("p",{className:"text-sm text-destructive","data-testid":"cron-error",role:"alert",children:y}),r?.length===0&&t(W,{description:a("Triggers declared with the cronJobs() builder appear here."),icon:u("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:[t("circle",{cx:"12",cy:"12",r:"9"}),t("path",{d:"M12 7.5V12l4 2"})]}),testId:"cron-empty",title:a("No cron triggers.")}),r!==void 0&&r.length>0&&t(P,{className:"overflow-hidden py-0",children:t(R,{className:"px-0",children:u(Q,{"data-testid":"cron-table",children:[t(K,{children:u(q,{children:[t(x,{children:a("name")}),t(x,{children:a("schedule")}),t(x,{children:a("target")}),t(x,{children:a("shard")}),h!==void 0&&t(x,{"aria-label":a("Actions")})]})}),t(z,{children:r.map(l=>{const d=p[l.name]??te;return u(q,{"data-testid":`cron-row-${l.name}`,children:[t(b,{children:l.name}),t(b,{className:"font-mono text-xs tabular-nums",children:l.cron}),t(b,{children:u("span",{className:"flex items-center gap-2",children:[l.workflow===void 0?t(O,{variant:"outline",children:a("function")}):t(O,{variant:"secondary",children:a("workflow")}),t("span",{className:"font-mono text-xs",children:l.workflow??l.functionPath})]})}),t(b,{children:l.shardKey??""}),h!==void 0&&t(b,{className:"text-right",children:u("span",{className:"flex items-center justify-end gap-2",children:[d.kind==="ok"&&t("span",{className:"text-xs text-muted-foreground","data-testid":`cron-ran-${l.name}`,children:a("ran")}),d.kind==="error"&&t("span",{className:"text-xs text-destructive","data-testid":`cron-run-error-${l.name}`,role:"alert",children:d.message}),t(G,{confirmLabel:a("Run now?"),disabled:d.kind==="running",onConfirm:()=>{A(i(l.name))},testId:`cron-run-${l.name}`,children:d.kind==="running"?a("Running…"):a("Run now")})]})})]},`${l.cron}:${l.name}`)})})]})})})]})},se=n=>Number.isFinite(n)?j(n,"—"):"—",ne=n=>{const e=D(34);let c;e[0]!==n?(c=n===void 0?{}:n,e[0]=n,e[1]=c):c=e[1];const{loadJobs:a,removeJob:p,retryJob:o}=c,s=V(),r=M();let y;e[2]===Symbol.for("react.memo_cache_sentinel")?(y=["lunora-dead-jobs"],e[2]=y):y=e[2];let h;e[3]!==s||e[4]!==a?(h=async()=>(await(a??(()=>s.listDeadJobs()))()).toSorted(oe),e[3]=s,e[4]=a,e[5]=h):h=e[5];const i=H(y,h),l=i.data,[d,g]=F(void 0),N=i.error??d,f=a===void 0;let C;e[6]!==s||e[7]!==f||e[8]!==o?(C=o??(f?m=>s.retryDeadJob(m):void 0),e[6]=s,e[7]=f,e[8]=o,e[9]=C):C=e[9];const v=C;let k;e[10]!==s||e[11]!==f||e[12]!==p?(k=p??(f?m=>s.removeDeadJob(m):void 0),e[10]=s,e[11]=f,e[12]=p,e[13]=k):k=e[13];const S=k;let $;e[14]!==i?($=()=>{i.refetch()},e[14]=i,e[15]=$):$=e[15],X($,!0);let I;e[16]!==i?(I=async m=>{g(void 0);try{await m,i.refetch()}catch(Z){g(U(Z))}},e[16]=i,e[17]=I):I=e[17];const L=I,T=v!==void 0||S!==void 0;let J;e[18]!==N?(J=N!==void 0&&t("p",{className:"text-sm text-destructive","data-testid":"dlq-error",role:"alert",children:N}),e[18]=N,e[19]=J):J=e[19];let w;e[20]!==l?.length||e[21]!==r?(w=l?.length===0&&t(W,{description:r("Jobs that exhaust their retry budget are parked here instead of being dropped."),icon:t("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:t("path",{d:"M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14"})}),testId:"dlq-empty",title:r("No dead-letter jobs.")}),e[20]=l?.length,e[21]=r,e[22]=w):w=e[22];let _;e[23]!==L||e[24]!==T||e[25]!==l||e[26]!==S||e[27]!==v||e[28]!==r?(_=l!==void 0&&l.length>0&&t(P,{className:"overflow-hidden py-0",children:t(R,{className:"px-0",children:u(Q,{"data-testid":"dlq-table",children:[t(K,{children:u(q,{children:[t(x,{children:r("function")}),t(x,{children:r("attempts")}),t(x,{children:r("last tried")}),t(x,{children:r("pool")}),t(x,{children:r("shard")}),t(x,{children:r("id")}),T&&t(x,{"aria-label":r("Actions")})]})}),t(z,{children:l.map(m=>u(q,{"data-testid":`dlq-row-${m.id}`,children:[t(b,{className:"font-mono text-xs",children:m.functionPath}),t(b,{className:"tabular-nums",children:m.attempts??0}),t(b,{className:"text-muted-foreground tabular-nums",children:se(m.scheduledFor)}),t(b,{className:"font-mono text-xs",children:m.pool??""}),t(b,{children:m.shardKey??""}),t(b,{className:"font-mono text-xs",children:m.id}),T&&t(b,{className:"text-right",children:u("div",{className:"flex justify-end gap-1.5",children:[v!==void 0&&t(Y,{"data-testid":`dlq-retry-${m.id}`,onClick:()=>{A(L(v(m.id)))},size:"sm",type:"button",variant:"outline",children:r("Retry")}),S!==void 0&&t(G,{confirmLabel:r("Drop job?"),onConfirm:()=>{A(L(S(m.id)))},testId:`dlq-remove-${m.id}`,children:r("Drop")})]})})]},m.id))})]})})}),e[23]=L,e[24]=T,e[25]=l,e[26]=S,e[27]=v,e[28]=r,e[29]=_):_=e[29];let B;return e[30]!==_||e[31]!==J||e[32]!==w?(B=u("div",{className:"flex flex-col gap-3","data-testid":"lunora-dead-letter",children:[J,w,_]}),e[30]=_,e[31]=J,e[32]=w,e[33]=B):B=e[33],B};function oe(n,e){return(e.attempts??0)-(n.attempts??0)}const E=n=>{const e=D(8),{label:c,testId:a,value:p}=n;let o;e[0]!==c?(o=t("span",{className:"text-xs text-muted-foreground",children:c}),e[0]=c,e[1]=o):o=e[1];let s;e[2]!==a||e[3]!==p?(s=t("span",{className:"text-2xl font-semibold tabular-nums","data-testid":a,children:p}),e[2]=a,e[3]=p,e[4]=s):s=e[4];let r;return e[5]!==o||e[6]!==s?(r=t(P,{className:"flex-1 py-0",children:u(R,{className:"flex flex-col gap-1 p-4",children:[o,s]})}),e[5]=o,e[6]=s,e[7]=r):r=e[7],r},ae=n=>{const e=D(25);let c;e[0]!==n?(c=n===void 0?{}:n,e[0]=n,e[1]=c):c=e[1];const{loadStatus:a}=c,p=V(),o=M(),s=a===void 0;let r;e[2]!==s?(r=["lunora-scheduler-status",s],e[2]=s,e[3]=r):r=e[3];let y;e[4]!==p||e[5]!==a?(y=async()=>{const k=await(a??(()=>p.schedulerStatus()))();return{...k,pools:k.pools.toSorted(ie)}},e[4]=p,e[5]=a,e[6]=y):y=e[6];const h=H(r,y),{data:i,error:l}=h;let d;e[7]!==h?(d=()=>{h.refetch()},e[7]=h,e[8]=d):d=e[8],X(d,!0);let g;e[9]!==l?(g=l!==null&&t("p",{className:"text-sm text-destructive","data-testid":"pools-error",role:"alert",children:l}),e[9]=l,e[10]=g):g=e[10];let N;e[11]!==i||e[12]!==o?(N=i!==void 0&&u("div",{className:"flex gap-3","data-testid":"pools-totals",children:[t(E,{label:o("backlog"),testId:"pools-backlog",value:i.backlog}),t(E,{label:o("in flight"),testId:"pools-inflight",value:i.inFlight}),t(E,{label:o("pools"),testId:"pools-count",value:i.pools.length})]}),e[11]=i,e[12]=o,e[13]=N):N=e[13];let f;e[14]!==i?.pools.length||e[15]!==o?(f=i?.pools.length===0&&t(W,{description:o("Pools created with createWorkpool appear here once they have activity."),icon:t("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:t("path",{d:"M4 7h16M4 12h16M4 17h16"})}),testId:"pools-empty",title:o("No workpools.")}),e[14]=i?.pools.length,e[15]=o,e[16]=f):f=e[16];let C;e[17]!==i||e[18]!==o?(C=i!==void 0&&i.pools.length>0&&t(P,{className:"overflow-hidden py-0",children:t(R,{className:"px-0",children:u(Q,{"data-testid":"pools-table",children:[t(K,{children:u(q,{children:[t(x,{children:o("pool")}),t(x,{children:o("queued")}),t(x,{children:o("in flight")}),t(x,{children:o("max concurrency")})]})}),t(z,{children:i.pools.map(de)})]})})}),e[17]=i,e[18]=o,e[19]=C):C=e[19];let v;return e[20]!==g||e[21]!==N||e[22]!==f||e[23]!==C?(v=u("div",{className:"flex flex-col gap-3","data-testid":"lunora-scheduler-pools",children:[g,N,f,C]}),e[20]=g,e[21]=N,e[22]=f,e[23]=C,e[24]=v):v=e[24],v};function ie(n,e){return e.queued-n.queued}function de(n){return u(q,{"data-testid":`pools-row-${n.name}`,children:[t(b,{className:"font-mono text-xs",children:n.name}),t(b,{className:"tabular-nums",children:n.queued}),u(b,{className:"tabular-nums",children:[n.inFlight," / ",n.maxConcurrency]}),t(b,{className:"tabular-nums",children:n.maxConcurrency})]},n.name)}const ce=["jobs","dead","pools","cron"],Ie=n=>{const e=D(41);let c;e[0]!==n?(c=n===void 0?{}:n,e[0]=n,e[1]=c):c=e[1];const{loadCronJobs:a,scheduledCancel:p,scheduledLoad:o}=c,s=M(),[r,y]=F("jobs");let h;e[2]!==s?(h=s("Cron triggers"),e[2]=s,e[3]=h):h=e[3];let i;e[4]!==s?(i=s("Dead letter"),e[4]=s,e[5]=i):i=e[5];let l;e[6]!==s?(l=s("Scheduled jobs"),e[6]=s,e[7]=l):l=e[7];let d;e[8]!==s?(d=s("Pools"),e[8]=s,e[9]=d):d=e[9];let g;e[10]!==h||e[11]!==i||e[12]!==l||e[13]!==d?(g={cron:h,dead:i,jobs:l,pools:d},e[10]=h,e[11]=i,e[12]=l,e[13]=d,e[14]=g):g=e[14];const N=g;let f;e[15]===Symbol.for("react.memo_cache_sentinel")?(f=w=>{y(w.currentTarget.dataset.view)},e[15]=f):f=e[15];const C=f;let v;e[16]!==s?(v=s("Schedule view"),e[16]=s,e[17]=v):v=e[17];let k;e[18]!==r||e[19]!==N?(k=ce.map(w=>t(Y,{"aria-selected":r===w,"data-testid":`schedule-view-${w}`,"data-view":w,onClick:C,role:"tab",size:"sm",type:"button",variant:r===w?"default":"outline",children:N[w]},w)),e[18]=r,e[19]=N,e[20]=k):k=e[20];let S;e[21]!==v||e[22]!==k?(S=t("div",{"aria-label":v,className:"flex gap-1.5","data-testid":"schedule-view-toggle",role:"tablist",children:k}),e[21]=v,e[22]=k,e[23]=S):S=e[23];let $;e[24]!==p||e[25]!==o||e[26]!==r?($=r==="jobs"&&t(ee,{cancelJob:p,loadJobs:o}),e[24]=p,e[25]=o,e[26]=r,e[27]=$):$=e[27];let I;e[28]!==r?(I=r==="dead"&&t(ne,{}),e[28]=r,e[29]=I):I=e[29];let L;e[30]!==r?(L=r==="pools"&&t(ae,{}),e[30]=r,e[31]=L):L=e[31];let T;e[32]!==a||e[33]!==r?(T=r==="cron"&&t(le,{loadCronJobs:a}),e[32]=a,e[33]=r,e[34]=T):T=e[34];let J;return e[35]!==S||e[36]!==$||e[37]!==I||e[38]!==L||e[39]!==T?(J=u("div",{className:"flex flex-col gap-4","data-testid":"lunora-schedule",children:[S,$,I,L,T]}),e[35]=S,e[36]=$,e[37]=I,e[38]=L,e[39]=T,e[40]=J):J=e[40],J};export{Ie as SchedulePanel};
1
+ import{c as D}from"react/compiler-runtime";import{useState as F}from"react";import{B as Y}from"../packem_shared/button-q0UYSmrn.mjs";import{useT as M}from"../packem_shared/DEFAULT_LOCALE-A1Yg5ORA.mjs";import{useLunora as V}from"@lunora/react";import{ConfirmButton as G}from"../packem_shared/ConfirmButton-DU4p72Er.mjs";import{B as O}from"../packem_shared/badge-r_5B4LHP.mjs";import{C as P,a as R}from"../packem_shared/card--2hKx4L2.mjs";import{E as W}from"../packem_shared/empty-state-D7jEML_T.mjs";import{T as Q,a as K,b as q,c as x,d as z,e as b}from"../packem_shared/table-D0SBiDu-.mjs";import{b as H}from"../packem_shared/use-admin-query-C7JRlFIE.mjs";import{f as A,b as U,i as j}from"../packem_shared/internal-CwaF9YNk.mjs";import{jsxs as m,jsx as t}from"react/jsx-runtime";import{useAutoRefresh as X}from"../packem_shared/DEFAULT_AUTO_REFRESH_MS-DuULO4XM.mjs";import{ScheduledJobs as ee}from"../packem_shared/ScheduledJobs-Db0HZ8R9.mjs";const te={kind:"idle"},re=(n,e,c)=>c!==void 0?c:e===void 0?a=>n.runCronJob(a):void 0,le=({loadCronJobs:n,runCronJob:e}={})=>{const c=V(),a=M(),[p,o]=F({}),s=H(["lunora-cron-jobs",n?"custom":"default"],()=>(n??(()=>c.getCronJobs()))()),{data:r,error:y}=s,h=re(c,n,e),i=async l=>{if(h!==void 0){o(d=>({...d,[l]:{kind:"running"}}));try{await h(l),o(d=>({...d,[l]:{kind:"ok"}})),s.refetch()}catch(d){o(g=>({...g,[l]:{kind:"error",message:U(d)}}))}}};return m("div",{className:"flex flex-col gap-3","data-testid":"lunora-cron-triggers",children:[y!==null&&t("p",{className:"text-sm text-destructive","data-testid":"cron-error",role:"alert",children:y}),r?.length===0&&t(W,{description:a("Triggers declared with the cronJobs() builder appear here."),icon:m("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:[t("circle",{cx:"12",cy:"12",r:"9"}),t("path",{d:"M12 7.5V12l4 2"})]}),testId:"cron-empty",title:a("No cron triggers.")}),r!==void 0&&r.length>0&&t(P,{className:"overflow-hidden py-0",children:t(R,{className:"px-0",children:m(Q,{"data-testid":"cron-table",children:[t(K,{children:m(q,{children:[t(x,{children:a("name")}),t(x,{children:a("schedule")}),t(x,{children:a("target")}),t(x,{children:a("shard")}),h!==void 0&&t(x,{"aria-label":a("Actions")})]})}),t(z,{children:r.map(l=>{const d=p[l.name]??te;return m(q,{"data-testid":`cron-row-${l.name}`,children:[t(b,{children:l.name}),t(b,{className:"font-mono text-xs tabular-nums",children:l.cron}),t(b,{children:m("span",{className:"flex items-center gap-2",children:[l.workflow===void 0?t(O,{variant:"outline",children:a("function")}):t(O,{variant:"secondary",children:a("workflow")}),t("span",{className:"font-mono text-xs",children:l.workflow??l.functionPath})]})}),t(b,{children:l.shardKey??""}),h!==void 0&&t(b,{className:"text-right",children:m("span",{className:"flex items-center justify-end gap-2",children:[d.kind==="ok"&&t("span",{className:"text-xs text-muted-foreground","data-testid":`cron-ran-${l.name}`,children:a("ran")}),d.kind==="error"&&t("span",{className:"text-xs text-destructive","data-testid":`cron-run-error-${l.name}`,role:"alert",children:d.message}),t(G,{confirmLabel:a("Run now?"),disabled:d.kind==="running",onConfirm:()=>{A(i(l.name))},testId:`cron-run-${l.name}`,children:d.kind==="running"?a("Running…"):a("Run now")})]})})]},`${l.cron}:${l.name}`)})})]})})})]})},se=n=>Number.isFinite(n)?j(n,"—"):"—",ne=n=>{const e=D(34);let c;e[0]!==n?(c=n===void 0?{}:n,e[0]=n,e[1]=c):c=e[1];const{loadJobs:a,removeJob:p,retryJob:o}=c,s=V(),r=M();let y;e[2]===Symbol.for("react.memo_cache_sentinel")?(y=["lunora-dead-jobs"],e[2]=y):y=e[2];let h;e[3]!==s||e[4]!==a?(h=async()=>(await(a??(()=>s.listDeadJobs()))()).toSorted(oe),e[3]=s,e[4]=a,e[5]=h):h=e[5];const i=H(y,h),l=i.data,[d,g]=F(void 0),N=i.error??d,f=a===void 0;let C;e[6]!==s||e[7]!==f||e[8]!==o?(C=o??(f?u=>s.retryDeadJob(u):void 0),e[6]=s,e[7]=f,e[8]=o,e[9]=C):C=e[9];const v=C;let k;e[10]!==s||e[11]!==f||e[12]!==p?(k=p??(f?u=>s.removeDeadJob(u):void 0),e[10]=s,e[11]=f,e[12]=p,e[13]=k):k=e[13];const S=k;let $;e[14]!==i?($=()=>{i.refetch()},e[14]=i,e[15]=$):$=e[15],X($,!0);let I;e[16]!==i?(I=async u=>{g(void 0);try{await u,i.refetch()}catch(Z){g(U(Z))}},e[16]=i,e[17]=I):I=e[17];const L=I,T=v!==void 0||S!==void 0;let J;e[18]!==N?(J=N!==void 0&&t("p",{className:"text-sm text-destructive","data-testid":"dlq-error",role:"alert",children:N}),e[18]=N,e[19]=J):J=e[19];let w;e[20]!==l?.length||e[21]!==r?(w=l?.length===0&&t(W,{description:r("Jobs that exhaust their retry budget are parked here instead of being dropped."),icon:t("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:t("path",{d:"M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14"})}),testId:"dlq-empty",title:r("No dead-letter jobs.")}),e[20]=l?.length,e[21]=r,e[22]=w):w=e[22];let _;e[23]!==L||e[24]!==T||e[25]!==l||e[26]!==S||e[27]!==v||e[28]!==r?(_=l!==void 0&&l.length>0&&t(P,{className:"overflow-hidden py-0",children:t(R,{className:"px-0",children:m(Q,{"data-testid":"dlq-table",children:[t(K,{children:m(q,{children:[t(x,{children:r("function")}),t(x,{children:r("attempts")}),t(x,{children:r("last tried")}),t(x,{children:r("pool")}),t(x,{children:r("shard")}),t(x,{children:r("id")}),T&&t(x,{"aria-label":r("Actions")})]})}),t(z,{children:l.map(u=>m(q,{"data-testid":`dlq-row-${u.id}`,children:[t(b,{className:"font-mono text-xs",children:u.workflow??u.functionPath}),t(b,{className:"tabular-nums",children:u.attempts??0}),t(b,{className:"text-muted-foreground tabular-nums",children:se(u.scheduledFor)}),t(b,{className:"font-mono text-xs",children:u.pool??""}),t(b,{children:u.shardKey??""}),t(b,{className:"font-mono text-xs",children:u.id}),T&&t(b,{className:"text-right",children:m("div",{className:"flex justify-end gap-1.5",children:[v!==void 0&&t(Y,{"data-testid":`dlq-retry-${u.id}`,onClick:()=>{A(L(v(u.id)))},size:"sm",type:"button",variant:"outline",children:r("Retry")}),S!==void 0&&t(G,{confirmLabel:r("Drop job?"),onConfirm:()=>{A(L(S(u.id)))},testId:`dlq-remove-${u.id}`,children:r("Drop")})]})})]},u.id))})]})})}),e[23]=L,e[24]=T,e[25]=l,e[26]=S,e[27]=v,e[28]=r,e[29]=_):_=e[29];let B;return e[30]!==_||e[31]!==J||e[32]!==w?(B=m("div",{className:"flex flex-col gap-3","data-testid":"lunora-dead-letter",children:[J,w,_]}),e[30]=_,e[31]=J,e[32]=w,e[33]=B):B=e[33],B};function oe(n,e){return(e.attempts??0)-(n.attempts??0)}const E=n=>{const e=D(8),{label:c,testId:a,value:p}=n;let o;e[0]!==c?(o=t("span",{className:"text-xs text-muted-foreground",children:c}),e[0]=c,e[1]=o):o=e[1];let s;e[2]!==a||e[3]!==p?(s=t("span",{className:"text-2xl font-semibold tabular-nums","data-testid":a,children:p}),e[2]=a,e[3]=p,e[4]=s):s=e[4];let r;return e[5]!==o||e[6]!==s?(r=t(P,{className:"flex-1 py-0",children:m(R,{className:"flex flex-col gap-1 p-4",children:[o,s]})}),e[5]=o,e[6]=s,e[7]=r):r=e[7],r},ae=n=>{const e=D(25);let c;e[0]!==n?(c=n===void 0?{}:n,e[0]=n,e[1]=c):c=e[1];const{loadStatus:a}=c,p=V(),o=M(),s=a===void 0;let r;e[2]!==s?(r=["lunora-scheduler-status",s],e[2]=s,e[3]=r):r=e[3];let y;e[4]!==p||e[5]!==a?(y=async()=>{const k=await(a??(()=>p.schedulerStatus()))();return{...k,pools:k.pools.toSorted(ie)}},e[4]=p,e[5]=a,e[6]=y):y=e[6];const h=H(r,y),{data:i,error:l}=h;let d;e[7]!==h?(d=()=>{h.refetch()},e[7]=h,e[8]=d):d=e[8],X(d,!0);let g;e[9]!==l?(g=l!==null&&t("p",{className:"text-sm text-destructive","data-testid":"pools-error",role:"alert",children:l}),e[9]=l,e[10]=g):g=e[10];let N;e[11]!==i||e[12]!==o?(N=i!==void 0&&m("div",{className:"flex gap-3","data-testid":"pools-totals",children:[t(E,{label:o("backlog"),testId:"pools-backlog",value:i.backlog}),t(E,{label:o("in flight"),testId:"pools-inflight",value:i.inFlight}),t(E,{label:o("pools"),testId:"pools-count",value:i.pools.length})]}),e[11]=i,e[12]=o,e[13]=N):N=e[13];let f;e[14]!==i?.pools.length||e[15]!==o?(f=i?.pools.length===0&&t(W,{description:o("Pools created with createWorkpool appear here once they have activity."),icon:t("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:t("path",{d:"M4 7h16M4 12h16M4 17h16"})}),testId:"pools-empty",title:o("No workpools.")}),e[14]=i?.pools.length,e[15]=o,e[16]=f):f=e[16];let C;e[17]!==i||e[18]!==o?(C=i!==void 0&&i.pools.length>0&&t(P,{className:"overflow-hidden py-0",children:t(R,{className:"px-0",children:m(Q,{"data-testid":"pools-table",children:[t(K,{children:m(q,{children:[t(x,{children:o("pool")}),t(x,{children:o("queued")}),t(x,{children:o("in flight")}),t(x,{children:o("max concurrency")})]})}),t(z,{children:i.pools.map(de)})]})})}),e[17]=i,e[18]=o,e[19]=C):C=e[19];let v;return e[20]!==g||e[21]!==N||e[22]!==f||e[23]!==C?(v=m("div",{className:"flex flex-col gap-3","data-testid":"lunora-scheduler-pools",children:[g,N,f,C]}),e[20]=g,e[21]=N,e[22]=f,e[23]=C,e[24]=v):v=e[24],v};function ie(n,e){return e.queued-n.queued}function de(n){return m(q,{"data-testid":`pools-row-${n.name}`,children:[t(b,{className:"font-mono text-xs",children:n.name}),t(b,{className:"tabular-nums",children:n.queued}),m(b,{className:"tabular-nums",children:[n.inFlight," / ",n.maxConcurrency]}),t(b,{className:"tabular-nums",children:n.maxConcurrency})]},n.name)}const ce=["jobs","dead","pools","cron"],Ie=n=>{const e=D(41);let c;e[0]!==n?(c=n===void 0?{}:n,e[0]=n,e[1]=c):c=e[1];const{loadCronJobs:a,scheduledCancel:p,scheduledLoad:o}=c,s=M(),[r,y]=F("jobs");let h;e[2]!==s?(h=s("Cron triggers"),e[2]=s,e[3]=h):h=e[3];let i;e[4]!==s?(i=s("Dead letter"),e[4]=s,e[5]=i):i=e[5];let l;e[6]!==s?(l=s("Scheduled jobs"),e[6]=s,e[7]=l):l=e[7];let d;e[8]!==s?(d=s("Pools"),e[8]=s,e[9]=d):d=e[9];let g;e[10]!==h||e[11]!==i||e[12]!==l||e[13]!==d?(g={cron:h,dead:i,jobs:l,pools:d},e[10]=h,e[11]=i,e[12]=l,e[13]=d,e[14]=g):g=e[14];const N=g;let f;e[15]===Symbol.for("react.memo_cache_sentinel")?(f=w=>{y(w.currentTarget.dataset.view)},e[15]=f):f=e[15];const C=f;let v;e[16]!==s?(v=s("Schedule view"),e[16]=s,e[17]=v):v=e[17];let k;e[18]!==r||e[19]!==N?(k=ce.map(w=>t(Y,{"aria-selected":r===w,"data-testid":`schedule-view-${w}`,"data-view":w,onClick:C,role:"tab",size:"sm",type:"button",variant:r===w?"default":"outline",children:N[w]},w)),e[18]=r,e[19]=N,e[20]=k):k=e[20];let S;e[21]!==v||e[22]!==k?(S=t("div",{"aria-label":v,className:"flex gap-1.5","data-testid":"schedule-view-toggle",role:"tablist",children:k}),e[21]=v,e[22]=k,e[23]=S):S=e[23];let $;e[24]!==p||e[25]!==o||e[26]!==r?($=r==="jobs"&&t(ee,{cancelJob:p,loadJobs:o}),e[24]=p,e[25]=o,e[26]=r,e[27]=$):$=e[27];let I;e[28]!==r?(I=r==="dead"&&t(ne,{}),e[28]=r,e[29]=I):I=e[29];let L;e[30]!==r?(L=r==="pools"&&t(ae,{}),e[30]=r,e[31]=L):L=e[31];let T;e[32]!==a||e[33]!==r?(T=r==="cron"&&t(le,{loadCronJobs:a}),e[32]=a,e[33]=r,e[34]=T):T=e[34];let J;return e[35]!==S||e[36]!==$||e[37]!==I||e[38]!==L||e[39]!==T?(J=m("div",{className:"flex flex-col gap-4","data-testid":"lunora-schedule",children:[S,$,I,L,T]}),e[35]=S,e[36]=$,e[37]=I,e[38]=L,e[39]=T,e[40]=J):J=e[40],J};export{Ie as SchedulePanel};
@@ -1 +1 @@
1
- import{c as I}from"react/compiler-runtime";import{useLunora as $}from"@lunora/react";import{useState as w,useEffect as H}from"react";import{ConfirmButton as M}from"./ConfirmButton-DU4p72Er.mjs";import{C as P,a as Q}from"./card--2hKx4L2.mjs";import{E as R}from"./empty-state-D7jEML_T.mjs";import{T as q,a as D,b as J,c as l,d as K,e as i}from"./table-D0SBiDu-.mjs";import{b as V}from"./use-admin-query-C7JRlFIE.mjs";import{useAutoRefresh as W}from"./DEFAULT_AUTO_REFRESH_MS-DuULO4XM.mjs";import{useT as z}from"./DEFAULT_LOCALE-A1Yg5ORA.mjs";import{f as G,i as O,b as U}from"./internal-CwaF9YNk.mjs";import{jsx as t,jsxs as p}from"react/jsx-runtime";const X=s=>Number.isFinite(s)?O(s,"—"):"—",j=s=>s.toSorted((e,u)=>e.scheduledFor-u.scheduledFor),Y=(s,e,u)=>e!==void 0?e:u===void 0?f=>s.cancelScheduledJob(f):void 0,he=s=>{const e=I(16),{cancelJob:u,loadJobs:f}=s===void 0?{}:s,n=$(),o=z(),c=f===void 0;let b;e[0]===Symbol.for("react.memo_cache_sentinel")?(b=["lunora-scheduled-jobs"],e[0]=b):b=e[0];const d=V(b,async()=>{const r=await(f??(()=>n.listScheduledJobs()))();return j(r)}),[F,L]=w(void 0),[A,S]=w(void 0);let v,x;e[1]!==n||e[2]!==c?(v=()=>{if(c)return n.subscribeScheduledJobs(r=>{S(void 0),L(j(r))})},x=[c,n],e[1]=n,e[2]=c,e[3]=v,e[4]=x):(v=e[3],x=e[4]),H(v,x);let y;e[5]!==d?(y=()=>{d.refetch()},e[5]=d,e[6]=y):y=e[6],W(y,!c);const C=Y(n,u,f),a=F??d.data,N=A??d.error,E=async r=>{if(C!==void 0){S(void 0);try{await C(r),c||d.refetch()}catch(_){S(U(_))}}},k="flex flex-col gap-3",B="lunora-scheduled-jobs";let m;e[7]!==N?(m=N!==null&&t("p",{className:"text-sm text-destructive","data-testid":"sj-error",role:"alert",children:N}),e[7]=N,e[8]=m):m=e[8];let h;e[9]!==a?.length||e[10]!==o?(h=a?.length===0&&t(R,{description:o("Jobs queued with runAfter / runAt will appear here."),icon:p("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:[t("circle",{cx:"12",cy:"12",r:"9"}),t("path",{d:"M12 7.5V12l4 2"})]}),testId:"sj-empty",title:o("No scheduled jobs.")}),e[9]=a?.length,e[10]=o,e[11]=h):h=e[11];const T=a!==void 0&&a.length>0&&t(P,{className:"overflow-hidden py-0",children:t(Q,{className:"px-0",children:p(q,{"data-testid":"sj-table",children:[t(D,{children:p(J,{children:[t(l,{children:o("function")}),t(l,{children:o("scheduled for")}),t(l,{children:o("pool")}),t(l,{children:o("attempts")}),t(l,{children:o("shard")}),t(l,{children:o("id")}),C!==void 0&&t(l,{"aria-label":o("Actions")})]})}),t(K,{children:a.map(r=>p(J,{"data-testid":`sj-row-${r.id}`,children:[t(i,{className:"font-mono text-xs",children:r.functionPath}),t(i,{className:"text-muted-foreground tabular-nums",children:X(r.scheduledFor)}),t(i,{className:"font-mono text-xs",children:r.pool??""}),t(i,{className:"tabular-nums",children:r.attempts??0}),t(i,{children:r.shardKey??""}),t(i,{className:"font-mono text-xs",children:r.id}),C!==void 0&&t(i,{className:"text-right",children:t(M,{confirmLabel:o("Cancel job?"),onConfirm:()=>{G(E(r.id))},testId:`sj-cancel-${r.id}`,children:o("Cancel")})})]},r.id))})]})})});let g;return e[12]!==T||e[13]!==m||e[14]!==h?(g=p("div",{className:k,"data-testid":B,children:[m,h,T]}),e[12]=T,e[13]=m,e[14]=h,e[15]=g):g=e[15],g};export{he as ScheduledJobs};
1
+ import{c as I}from"react/compiler-runtime";import{useLunora as $}from"@lunora/react";import{useState as T,useEffect as H}from"react";import{ConfirmButton as M}from"./ConfirmButton-DU4p72Er.mjs";import{C as P,a as Q}from"./card--2hKx4L2.mjs";import{E as R}from"./empty-state-D7jEML_T.mjs";import{T as q,a as D,b as J,c as l,d as K,e as i}from"./table-D0SBiDu-.mjs";import{b as V}from"./use-admin-query-C7JRlFIE.mjs";import{useAutoRefresh as W}from"./DEFAULT_AUTO_REFRESH_MS-DuULO4XM.mjs";import{useT as z}from"./DEFAULT_LOCALE-A1Yg5ORA.mjs";import{f as G,i as O,b as U}from"./internal-CwaF9YNk.mjs";import{jsx as t,jsxs as p}from"react/jsx-runtime";const X=s=>Number.isFinite(s)?O(s,"—"):"—",F=s=>s.toSorted((e,u)=>e.scheduledFor-u.scheduledFor),Y=(s,e,u)=>e!==void 0?e:u===void 0?f=>s.cancelScheduledJob(f):void 0,he=s=>{const e=I(16),{cancelJob:u,loadJobs:f}=s===void 0?{}:s,n=$(),o=z(),c=f===void 0;let b;e[0]===Symbol.for("react.memo_cache_sentinel")?(b=["lunora-scheduled-jobs"],e[0]=b):b=e[0];const d=V(b,async()=>{const r=await(f??(()=>n.listScheduledJobs()))();return F(r)}),[L,j]=T(void 0),[k,w]=T(void 0);let v,x;e[1]!==n||e[2]!==c?(v=()=>{if(c)return n.subscribeScheduledJobs(r=>{w(void 0),j(F(r))})},x=[c,n],e[1]=n,e[2]=c,e[3]=v,e[4]=x):(v=e[3],x=e[4]),H(v,x);let y;e[5]!==d?(y=()=>{d.refetch()},e[5]=d,e[6]=y):y=e[6],W(y,!c);const C=Y(n,u,f),a=L??d.data,N=k??d.error,A=async r=>{if(C!==void 0){w(void 0);try{await C(r),c||d.refetch()}catch(_){w(U(_))}}},E="flex flex-col gap-3",B="lunora-scheduled-jobs";let m;e[7]!==N?(m=N!==null&&t("p",{className:"text-sm text-destructive","data-testid":"sj-error",role:"alert",children:N}),e[7]=N,e[8]=m):m=e[8];let h;e[9]!==a?.length||e[10]!==o?(h=a?.length===0&&t(R,{description:o("Jobs queued with runAfter / runAt will appear here."),icon:p("svg",{"aria-hidden":"true",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.6,viewBox:"0 0 24 24",children:[t("circle",{cx:"12",cy:"12",r:"9"}),t("path",{d:"M12 7.5V12l4 2"})]}),testId:"sj-empty",title:o("No scheduled jobs.")}),e[9]=a?.length,e[10]=o,e[11]=h):h=e[11];const S=a!==void 0&&a.length>0&&t(P,{className:"overflow-hidden py-0",children:t(Q,{className:"px-0",children:p(q,{"data-testid":"sj-table",children:[t(D,{children:p(J,{children:[t(l,{children:o("function")}),t(l,{children:o("scheduled for")}),t(l,{children:o("pool")}),t(l,{children:o("attempts")}),t(l,{children:o("shard")}),t(l,{children:o("id")}),C!==void 0&&t(l,{"aria-label":o("Actions")})]})}),t(K,{children:a.map(r=>p(J,{"data-testid":`sj-row-${r.id}`,children:[t(i,{className:"font-mono text-xs",children:r.workflow??r.functionPath}),t(i,{className:"text-muted-foreground tabular-nums",children:X(r.scheduledFor)}),t(i,{className:"font-mono text-xs",children:r.pool??""}),t(i,{className:"tabular-nums",children:r.attempts??0}),t(i,{children:r.shardKey??""}),t(i,{className:"font-mono text-xs",children:r.id}),C!==void 0&&t(i,{className:"text-right",children:t(M,{confirmLabel:o("Cancel job?"),onConfirm:()=>{G(A(r.id))},testId:`sj-cancel-${r.id}`,children:o("Cancel")})})]},r.id))})]})})});let g;return e[12]!==S||e[13]!==m||e[14]!==h?(g=p("div",{className:E,"data-testid":B,children:[m,h,S]}),e[12]=S,e[13]=m,e[14]=h,e[15]=g):g=e[15],g};export{he as ScheduledJobs};
@@ -1 +1 @@
1
- import{S as b}from"./studio-4odoxrh9.mjs";import"./ErrorBoundary-BWNF98VF.mjs";import"./operation-console-provider-DoloEvon.mjs";import"./badge-r_5B4LHP.mjs";import"./input-CXhxesPC.mjs";import"./skeleton-DX1gfixl.mjs";import"./home-panel-ChKczU0I.mjs";import"./DEFAULT_LOCALE-A1Yg5ORA.mjs";import"./StudioI18nProvider-fVsCSs5L.mjs";import"./data-view-params-qoSTqjAj.mjs";import"./internal-CwaF9YNk.mjs";import"./utils-bhneXptQ.mjs";import"./CommandPalette-C4UrhLxv.mjs";export{b as Studio};
1
+ import{S as b}from"./studio-DE8N0tIQ.mjs";import"./ErrorBoundary-BWNF98VF.mjs";import"./operation-console-provider-DoloEvon.mjs";import"./badge-r_5B4LHP.mjs";import"./input-CXhxesPC.mjs";import"./skeleton-DX1gfixl.mjs";import"./home-panel-ChKczU0I.mjs";import"./DEFAULT_LOCALE-A1Yg5ORA.mjs";import"./StudioI18nProvider-fVsCSs5L.mjs";import"./data-view-params-qoSTqjAj.mjs";import"./internal-CwaF9YNk.mjs";import"./utils-bhneXptQ.mjs";import"./CommandPalette-C4UrhLxv.mjs";export{b as Studio};
@@ -0,0 +1 @@
1
+ import{c as O}from"react/compiler-runtime";import{LunoraClient as G}from"@lunora/client";import{LunoraProvider as H}from"@lunora/react";import{useState as B,useEffect as $}from"react";import{ErrorBoundary as z}from"./ErrorBoundary-BWNF98VF.mjs";import{u as U,B as V,T as Y,a as q,S as J}from"./studio-DE8N0tIQ.mjs";import Q from"./useDebounced-DVeQ5-oW.mjs";import{useT as j,createStudioI18n as X}from"./DEFAULT_LOCALE-A1Yg5ORA.mjs";import{StudioI18nProvider as D}from"./StudioI18nProvider-fVsCSs5L.mjs";import{r as Z}from"./internal-CwaF9YNk.mjs";import{w as R}from"./recording-client-BGyq5_JP.mjs";import F from"./STUDIO_ROOT_CLASS-C6MccdVk.mjs";import{a as K}from"./browser-storage-BH1MxLZs.mjs";import{c as W}from"./utils-bhneXptQ.mjs";import{B as ee}from"./button-q0UYSmrn.mjs";import{I as te}from"./input-CXhxesPC.mjs";import{jsx as m,jsxs as P}from"react/jsx-runtime";const L="lunora-studio-admin-token",oe=()=>{try{return K("session")?.getItem(L)??""}catch{return""}},ne=u=>{const e=K("session");if(e!==void 0)try{u===""?e.removeItem(L):e.setItem(L,u)}catch{}},se="/_lunora/admin/ws-token",ie=1e4,re=u=>{const e=u;return typeof e?.token=="string"&&e.token.length>0&&typeof e.expiresAtMs=="number"},le=u=>{const{adminToken:e,baseUrl:d}=u,o=u.fetchImpl??fetch;let i=d;for(;i.endsWith("/");)i=i.slice(0,-1);const r=`${i}${se}`;let t,n=!1,s;const l=async()=>{const c=await o(r,{headers:{authorization:`Bearer ${e}`},method:"POST"});if(c.status===404||c.status===405)return n=!0,e;if(!c.ok)throw new Error(`ws-token mint failed: ${String(c.status)}`);const a=await c.json().catch(()=>{});if(!re(a))throw new Error("ws-token mint failed: malformed response body");return t=a,a.token};return{getToken:async()=>n?e:t!==void 0&&t.expiresAtMs-ie>Date.now()?t.token:(s??=l().finally(()=>{s=void 0}),s),invalidate:()=>{t=void 0}}},ae=u=>{const e=O(42),{onSubmit:d}=u,o=j(),[i,r]=B("");let t;e[0]!==i?(t=i.trim(),e[0]=i,e[1]=t):t=e[1];const n=t;let s;e[2]!==d||e[3]!==n?(s=_=>{_.preventDefault(),n!==""&&d(n)},e[2]=d,e[3]=n,e[4]=s):s=e[4];const l=s;let c;e[5]===Symbol.for("react.memo_cache_sentinel")?(c=m("div",{className:"h-10 w-10 text-foreground",children:m(V,{})}),e[5]=c):c=e[5];let a;e[6]!==o?(a=o("Connect to Lunora Studio"),e[6]=o,e[7]=a):a=e[7];let v;e[8]!==a?(v=m("h1",{className:"text-base font-semibold text-foreground",children:a}),e[8]=a,e[9]=v):v=e[9];let k;e[10]!==o?(k=o("Enter your admin token to access the studio."),e[10]=o,e[11]=k):k=e[11];let p;e[12]!==k?(p=m("p",{className:"text-[13px] text-muted-foreground",children:k}),e[12]=k,e[13]=p):p=e[13];let h;e[14]!==v||e[15]!==p?(h=P("div",{className:"flex flex-col items-center gap-3 text-center",children:[c,P("div",{className:"flex flex-col gap-1",children:[v,p]})]}),e[14]=v,e[15]=p,e[16]=h):h=e[16];let g;e[17]!==o?(g=o("admin token"),e[17]=o,e[18]=g):g=e[18];let f;e[19]!==g?(f=m("label",{className:"text-xs font-medium text-foreground",htmlFor:"lunora-studio-login-token",children:g}),e[19]=g,e[20]=f):f=e[20];let b;e[21]===Symbol.for("react.memo_cache_sentinel")?(b=_=>{r(_.target.value)},e[21]=b):b=e[21];let x;e[22]!==i?(x=m(te,{autoComplete:"off",autoFocus:!0,"data-testid":"lunora-studio-login-token",id:"lunora-studio-login-token",onChange:b,placeholder:"LUNORA_ADMIN_TOKEN",type:"password",value:i}),e[22]=i,e[23]=x):x=e[23];let T;e[24]!==o?(T=o("From your worker's LUNORA_ADMIN_TOKEN — your project's .dev.vars in dev, or a deployment secret in production."),e[24]=o,e[25]=T):T=e[25];let I;e[26]!==T?(I=m("p",{className:"text-[11px] text-muted-foreground",children:T}),e[26]=T,e[27]=I):I=e[27];let S;e[28]!==f||e[29]!==x||e[30]!==I?(S=P("div",{className:"flex flex-col gap-1.5",children:[f,x,I]}),e[28]=f,e[29]=x,e[30]=I,e[31]=S):S=e[31];const E=n==="";let y;e[32]!==o?(y=o("Connect"),e[32]=o,e[33]=y):y=e[33];let w;e[34]!==E||e[35]!==y?(w=m(ee,{"data-testid":"lunora-studio-login-submit",disabled:E,type:"submit",children:y}),e[34]=E,e[35]=y,e[36]=w):w=e[36];let N;return e[37]!==l||e[38]!==S||e[39]!==w||e[40]!==h?(N=P("form",{className:"flex w-full max-w-sm flex-col gap-5 rounded-xl border border-border bg-card p-7 shadow-lg","data-testid":"lunora-studio-login",onSubmit:l,children:[h,S,w]}),e[37]=l,e[38]=S,e[39]=w,e[40]=h,e[41]=N):N=e[41],N},de=u=>{const e=O(10),{i18n:d,onSubmit:o}=u,{resolvedTheme:i}=U(),r=i==="dark"&&"dark";let t;e[0]!==r?(t=W(F,r,"flex h-dvh items-center justify-center bg-sidebar p-6 text-sm text-foreground"),e[0]=r,e[1]=t):t=e[1];let n;e[2]!==o?(n=m(ae,{onSubmit:o}),e[2]=o,e[3]=n):n=e[3];let s;e[4]!==d||e[5]!==n?(s=m(D,{i18n:d,children:n}),e[4]=d,e[5]=n,e[6]=s):s=e[6];let l;return e[7]!==t||e[8]!==s?(l=m("div",{className:t,"data-testid":"lunora-studio-login-root",children:s}),e[7]=t,e[8]=s,e[9]=l):l=e[9],l},ce=u=>{const e=O(15),{basePath:d,chrome:o,studio:i}=u,r=j();let t;e[0]!==r?(t=r("Studio failed"),e[0]=r,e[1]=t):t=e[1];let n;e[2]!==r?(n=r("Studio"),e[2]=r,e[3]=n):n=e[3];let s;e[4]!==r?(s=r("Try again"),e[4]=r,e[5]=s):s=e[5];let l;e[6]!==d||e[7]!==o||e[8]!==i?(l=m(J,{...i,basePath:d,chrome:o}),e[6]=d,e[7]=o,e[8]=i,e[9]=l):l=e[9];let c;return e[10]!==t||e[11]!==n||e[12]!==s||e[13]!==l?(c=m(z,{fallbackTitle:t,label:n,retryLabel:s,children:l}),e[10]=t,e[11]=n,e[12]=s,e[13]=l,e[14]=c):c=e[14],c},fe=u=>{const e=O(20),{basePath:d,clearToken:o,client:i,i18n:r,onTokenChange:t,rulesInstalled:n,studio:s,token:l}=u,{resolvedTheme:c}=U();let a;e[0]!==o||e[1]!==t||e[2]!==n||e[3]!==l?(a={clearToken:o,onTokenChange:t,rulesInstalled:n,token:l},e[0]=o,e[1]=t,e[2]=n,e[3]=l,e[4]=a):a=e[4];const v=a,k=c==="dark"&&"dark";let p;e[5]!==k?(p=W(F,k,"flex h-dvh flex-col overflow-hidden bg-sidebar text-sm text-foreground"),e[5]=k,e[6]=p):p=e[6];let h;e[7]!==d||e[8]!==v||e[9]!==s?(h=m(q,{children:m(ce,{basePath:d,chrome:v,studio:s})}),e[7]=d,e[8]=v,e[9]=s,e[10]=h):h=e[10];let g;e[11]!==r||e[12]!==h?(g=m(D,{i18n:r,children:h}),e[11]=r,e[12]=h,e[13]=g):g=e[13];let f;e[14]!==i||e[15]!==g?(f=m(H,{client:i,children:g}),e[14]=i,e[15]=g,e[16]=f):f=e[16];let b;return e[17]!==p||e[18]!==f?(b=m("div",{className:p,"data-testid":"lunora-studio-app",children:f}),e[17]=p,e[18]=f,e[19]=b):b=e[19],b},Ee=u=>{const e=O(28);let d;e[0]!==u?(d=u===void 0?{}:u,e[0]=u,e[1]=d):d=e[1];const{adminToken:o,basePath:i,baseUrl:r,client:t,rulesInstalled:n,studio:s,locale:l}=d;let c;e[2]!==o?(c=()=>o??oe(),e[2]=o,e[3]=c):c=e[3];const[a,v]=B(c);let k,p;e[4]!==a?(k=()=>{ne(a)},p=[a],e[4]=a,e[5]=k,e[6]=p):(k=e[5],p=e[6]),$(k,p);const h=Q(a,300);let g;e:{if(t!==void 0){let A;e[7]!==t?(A=R(t),e[7]=t,e[8]=A):A=e[8],g=A;break e}let _;if(e[9]!==r||e[10]!==h){const A=Z(r),M=h===""?void 0:le({adminToken:h,baseUrl:A}),C=new G({url:A,...M===void 0?{}:{wsToken:M.getToken}});M!==void 0&&(C.setAuthToken(h),C.onTokenExpired(M.invalidate)),_=R(C),e[9]=r,e[10]=h,e[11]=_}else _=e[11];g=_}const f=g;let b,x;e[12]!==f||e[13]!==t?(b=()=>()=>{t===void 0&&f.close()},x=[f,t],e[12]=f,e[13]=t,e[14]=b,e[15]=x):(b=e[14],x=e[15]),$(b,x);let T;e[16]===Symbol.for("react.memo_cache_sentinel")?(T=_=>{v(_.target.value)},e[16]=T):T=e[16];const I=T;let S;e[17]===Symbol.for("react.memo_cache_sentinel")?(S=()=>{v("")},e[17]=S):S=e[17];const E=S;let y;e[18]!==l?(y=X(l),e[18]=l,e[19]=y):y=e[19];const w=y;let N;return e[20]!==i||e[21]!==f||e[22]!==w||e[23]!==t||e[24]!==n||e[25]!==s||e[26]!==a?(N=m(Y,{children:a===""&&t===void 0?m(de,{i18n:w,onSubmit:v}):m(fe,{basePath:i,clearToken:E,client:f,i18n:w,onTokenChange:I,rulesInstalled:n,studio:s,token:a})}),e[20]=i,e[21]=f,e[22]=w,e[23]=t,e[24]=n,e[25]=s,e[26]=a,e[27]=N):N=e[27],N};export{Ee as StudioApp};
@@ -0,0 +1 @@
1
+ const u=t=>{let e=0,c=0,s=0,n=0,r=0,i=0,a=0;for(const{metrics:o}of t){if(o===null){r+=1;continue}n+=1,e+=o.requests,c+=o.errors,s+=o.databaseSize??0,o.cache&&(i+=o.cache.hits,a+=o.cache.hits+o.cache.misses)}return{failed:r,hitRate:a===0?null:i/a,reachable:n,totalDatabaseSize:s,totalErrors:c,totalRequests:e}},h=(t,e)=>{const c=new Set,s=[];for(const n of["",t.trim(),...e])c.has(n)||(c.add(n),s.push(n));return s},l=(t,e)=>{if(t.length===0)return 0;if(t.sort((s,n)=>s-n),e<=0)return t[0]??0;if(e>=100)return t.at(-1)??0;const c=Math.ceil(e/100*t.length)-1;return t[c]??0},f=t=>{const c=t.functions;if(!c||c.length===0)return{p90:0,p95:0};const s=1e3,n=[];for(const r of c){if(r.calls<=0)continue;const i=r.totalDurationMs/r.calls,a=Math.min(r.calls,s);for(let o=0;o<a;o+=1)n.push(i)}return n.length===0?{p90:0,p95:0}:{p90:l([...n],90),p95:l([...n],95)}},p=(t,e,c="neutral")=>{const s=e-t,n=t===0?null:s/t*100;return{delta:s,direction:c,pct:n}},g=t=>t.map(e=>({...e,avgDurationMs:e.execCount>0?e.totalDurationMs/e.execCount:0}));export{u as aggregateMetrics,p as computeDelta,f as computeLatencyPercentiles,g as enrichQueryStats,l as percentile,h as shardsToAggregate};
@@ -1,6 +1,23 @@
1
1
  import { CronJobInfo, ScheduleRecord, LunoraClient } from '@lunora/client';
2
2
  import { ReactElement } from 'react';
3
3
  import { I18n } from '@lingui/core';
4
+ import { AnalyticsSqlResult } from '@lunora/bindings/analytics';
5
+ interface AnalyticsPanelProps {
6
+ /**
7
+ * Dataset name to query (the `analytics_engine_datasets[].dataset`, default
8
+ * `ANALYTICS` — the value the config layer reconciles).
9
+ */
10
+ readonly dataset?: string;
11
+ /**
12
+ * Run one Analytics Engine SQL statement and resolve its result. The panel has
13
+ * no default: the AE SQL API authenticates with an **account-scoped Cloudflare
14
+ * API token**, and a browser bundle is the last place that may hold one. The
15
+ * host supplies a runner that proxies the statement through its own worker
16
+ * (thread it in as `StudioProps.analyticsQuery`); with none, the panel renders
17
+ * an empty state and makes no network call.
18
+ */
19
+ readonly runQuery?: (sql: string) => Promise<AnalyticsSqlResult>;
20
+ }
4
21
  interface CronTriggersPanelProps {
5
22
  /**
6
23
  * Load the code-defined cron triggers. Defaults to `client.getCronJobs`,
@@ -92,6 +109,21 @@ interface FunctionDescriptor {
92
109
  /** Outcome of a single `FunctionRunner` invocation. */
93
110
  type RunStatus = "error" | "idle" | "running" | "success";
94
111
  interface StudioProps {
112
+ /**
113
+ * Run one Analytics Engine SQL statement for the Analytics tab. There is no
114
+ * default: the AE SQL API authenticates with an account-scoped Cloudflare API
115
+ * token, and inlining one into this browser bundle would leak it to anyone who
116
+ * views source. Supply a runner that proxies the statement through your own
117
+ * worker (which holds the token server-side). Without it the Analytics tab
118
+ * renders an empty state and issues no request.
119
+ *
120
+ * Pass a STABLE reference — a module-level function, or one held in a
121
+ * `useCallback`/ref. It is read while building the tab router, so a fresh
122
+ * inline arrow on every render rebuilds the router and remounts the panel
123
+ * tree, losing in-progress query state. The same holds for `scheduledLoad`,
124
+ * `scheduledCancel` and `scheduledCron`.
125
+ */
126
+ readonly analyticsQuery?: AnalyticsPanelProps["runQuery"];
95
127
  /**
96
128
  * URL path prefix the studio is mounted under, passed to the router as its
97
129
  * `basepath`. Defaults to `/` (mounted at the origin root). The `@lunora/vite`
@@ -197,7 +229,7 @@ interface StudioChrome {
197
229
  * (`StudioApp` owns one for the top bar too) or the shared default — instead
198
230
  * of nesting a second, redundant provider.
199
231
  */
200
- declare const Studio: ({ basePath, chrome, dataEditable, functions, i18n, initialShardKey, locale, openApiSpec, openRpcSpec, runAsIdentity, schemaEditable, scheduledCancel, scheduledCron, scheduledLoad }: StudioProps) => ReactElement;
232
+ declare const Studio: ({ i18n, locale, ...shellProps }: StudioProps) => ReactElement;
201
233
  interface StudioAppProps {
202
234
  /**
203
235
  * Admin bearer token to send with every admin request. When omitted the app
@@ -1,6 +1,23 @@
1
1
  import { CronJobInfo, ScheduleRecord, LunoraClient } from '@lunora/client';
2
2
  import { ReactElement } from 'react';
3
3
  import { I18n } from '@lingui/core';
4
+ import { AnalyticsSqlResult } from '@lunora/bindings/analytics';
5
+ interface AnalyticsPanelProps {
6
+ /**
7
+ * Dataset name to query (the `analytics_engine_datasets[].dataset`, default
8
+ * `ANALYTICS` — the value the config layer reconciles).
9
+ */
10
+ readonly dataset?: string;
11
+ /**
12
+ * Run one Analytics Engine SQL statement and resolve its result. The panel has
13
+ * no default: the AE SQL API authenticates with an **account-scoped Cloudflare
14
+ * API token**, and a browser bundle is the last place that may hold one. The
15
+ * host supplies a runner that proxies the statement through its own worker
16
+ * (thread it in as `StudioProps.analyticsQuery`); with none, the panel renders
17
+ * an empty state and makes no network call.
18
+ */
19
+ readonly runQuery?: (sql: string) => Promise<AnalyticsSqlResult>;
20
+ }
4
21
  interface CronTriggersPanelProps {
5
22
  /**
6
23
  * Load the code-defined cron triggers. Defaults to `client.getCronJobs`,
@@ -92,6 +109,21 @@ interface FunctionDescriptor {
92
109
  /** Outcome of a single `FunctionRunner` invocation. */
93
110
  type RunStatus = "error" | "idle" | "running" | "success";
94
111
  interface StudioProps {
112
+ /**
113
+ * Run one Analytics Engine SQL statement for the Analytics tab. There is no
114
+ * default: the AE SQL API authenticates with an account-scoped Cloudflare API
115
+ * token, and inlining one into this browser bundle would leak it to anyone who
116
+ * views source. Supply a runner that proxies the statement through your own
117
+ * worker (which holds the token server-side). Without it the Analytics tab
118
+ * renders an empty state and issues no request.
119
+ *
120
+ * Pass a STABLE reference — a module-level function, or one held in a
121
+ * `useCallback`/ref. It is read while building the tab router, so a fresh
122
+ * inline arrow on every render rebuilds the router and remounts the panel
123
+ * tree, losing in-progress query state. The same holds for `scheduledLoad`,
124
+ * `scheduledCancel` and `scheduledCron`.
125
+ */
126
+ readonly analyticsQuery?: AnalyticsPanelProps["runQuery"];
95
127
  /**
96
128
  * URL path prefix the studio is mounted under, passed to the router as its
97
129
  * `basepath`. Defaults to `/` (mounted at the origin root). The `@lunora/vite`
@@ -197,7 +229,7 @@ interface StudioChrome {
197
229
  * (`StudioApp` owns one for the top bar too) or the shared default — instead
198
230
  * of nesting a second, redundant provider.
199
231
  */
200
- declare const Studio: ({ basePath, chrome, dataEditable, functions, i18n, initialShardKey, locale, openApiSpec, openRpcSpec, runAsIdentity, schemaEditable, scheduledCancel, scheduledCron, scheduledLoad }: StudioProps) => ReactElement;
232
+ declare const Studio: ({ i18n, locale, ...shellProps }: StudioProps) => ReactElement;
201
233
  interface StudioAppProps {
202
234
  /**
203
235
  * Admin bearer token to send with every admin request. When omitted the app
@@ -1,2 +1,2 @@
1
1
  'use client';
2
- import{c as u}from"react/compiler-runtime";import{Select as l}from"@base-ui/react/select";import{c}from"./utils-bhneXptQ.mjs";import{HugeiconsIcon as m}from"@hugeicons/react";import{UnfoldMoreIcon as g,Tick02Icon as v,ArrowUp01Icon as b,ArrowDown01Icon as h}from"@hugeicons/core-free-icons";import{jsx as i,jsxs as p}from"react/jsx-runtime";const I=l.Root;function $(s){const e=u(8);let t,o;e[0]!==s?({className:t,...o}=s,e[0]=s,e[1]=t,e[2]=o):(t=e[1],o=e[2]);let a;e[3]!==t?(a=c("flex flex-1 text-start",t),e[3]=t,e[4]=a):a=e[4];let r;return e[5]!==o||e[6]!==a?(r=i(l.Value,{"data-slot":"select-value",className:a,...o}),e[5]=o,e[6]=a,e[7]=r):r=e[7],r}function j({className:s,size:e="default",children:t,...o}){return p(l.Trigger,{"data-slot":"select-trigger","data-size":e,className:c("flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pe-2 ps-2.5 text-xs whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-md *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",s),...o,children:[t,i(l.Icon,{render:i(m,{icon:g,strokeWidth:2,className:"pointer-events-none size-4 text-muted-foreground"})})]})}function A({className:s,children:e,side:t="bottom",sideOffset:o=4,align:a="center",alignOffset:r=0,alignItemWithTrigger:n=!0,...d}){return i(l.Portal,{children:i(l.Positioner,{side:t,sideOffset:o,align:a,alignOffset:r,alignItemWithTrigger:n,className:"isolate z-50",children:p(l.Popup,{"data-slot":"select-content","data-align-trigger":n,className:c("isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-start-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 animate-none! relative bg-popover before:pointer-events-none before:absolute before:inset-0 before:-z-1 before:rounded-[inherit] **:data-[slot$=-item]:focus:bg-foreground/10 **:data-[slot$=-item]:data-highlighted:bg-foreground/10 **:data-[slot$=-separator]:bg-foreground/5 **:data-[slot$=-trigger]:focus:bg-foreground/10 **:data-[slot$=-trigger]:aria-expanded:bg-foreground/10! **:data-[variant=destructive]:focus:bg-foreground/10! **:data-[variant=destructive]:text-accent-foreground! **:data-[variant=destructive]:**:text-accent-foreground!",s),...d,children:[i(x,{}),i(l.List,{children:e}),i(w,{})]})})})}function U(s){const e=u(13);let t,o,a;e[0]!==s?({className:o,children:t,...a}=s,e[0]=s,e[1]=t,e[2]=o,e[3]=a):(t=e[1],o=e[2],a=e[3]);let r;e[4]!==o?(r=c("relative flex w-full cursor-default items-center gap-2 rounded-md py-2 pe-8 ps-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",o),e[4]=o,e[5]=r):r=e[5];let n;e[6]!==t?(n=i(l.ItemText,{className:"flex flex-1 shrink-0 gap-2 whitespace-nowrap",children:t}),e[6]=t,e[7]=n):n=e[7];let d;e[8]===Symbol.for("react.memo_cache_sentinel")?(d=i(l.ItemIndicator,{render:i("span",{className:"pointer-events-none absolute end-2 flex size-4 items-center justify-center"}),children:i(m,{icon:v,strokeWidth:2,className:"pointer-events-none"})}),e[8]=d):d=e[8];let f;return e[9]!==a||e[10]!==r||e[11]!==n?(f=p(l.Item,{"data-slot":"select-item",className:r,...a,children:[n,d]}),e[9]=a,e[10]=r,e[11]=n,e[12]=f):f=e[12],f}function x(s){const e=u(9);let t,o;e[0]!==s?({className:t,...o}=s,e[0]=s,e[1]=t,e[2]=o):(t=e[1],o=e[2]);let a;e[3]!==t?(a=c("top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",t),e[3]=t,e[4]=a):a=e[4];let r;e[5]===Symbol.for("react.memo_cache_sentinel")?(r=i(m,{icon:b,strokeWidth:2}),e[5]=r):r=e[5];let n;return e[6]!==o||e[7]!==a?(n=i(l.ScrollUpArrow,{"data-slot":"select-scroll-up-button",className:a,...o,children:r}),e[6]=o,e[7]=a,e[8]=n):n=e[8],n}function w(s){const e=u(9);let t,o;e[0]!==s?({className:t,...o}=s,e[0]=s,e[1]=t,e[2]=o):(t=e[1],o=e[2]);let a;e[3]!==t?(a=c("bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",t),e[3]=t,e[4]=a):a=e[4];let r;e[5]===Symbol.for("react.memo_cache_sentinel")?(r=i(m,{icon:h,strokeWidth:2}),e[5]=r):r=e[5];let n;return e[6]!==o||e[7]!==a?(n=i(l.ScrollDownArrow,{"data-slot":"select-scroll-down-button",className:a,...o,children:r}),e[6]=o,e[7]=a,e[8]=n):n=e[8],n}export{$ as S,j as a,A as b,U as c,I as d};
2
+ import{c as u}from"react/compiler-runtime";import{Select as l}from"@base-ui/react/select";import{c}from"./utils-bhneXptQ.mjs";import{HugeiconsIcon as m}from"@hugeicons/react";import{Tick02Icon as g,UnfoldMoreIcon as v,ArrowUp01Icon as b,ArrowDown01Icon as h}from"@hugeicons/core-free-icons";import{jsx as i,jsxs as p}from"react/jsx-runtime";const I=l.Root;function $(s){const e=u(8);let t,o;e[0]!==s?({className:t,...o}=s,e[0]=s,e[1]=t,e[2]=o):(t=e[1],o=e[2]);let a;e[3]!==t?(a=c("flex flex-1 text-start",t),e[3]=t,e[4]=a):a=e[4];let r;return e[5]!==o||e[6]!==a?(r=i(l.Value,{"data-slot":"select-value",className:a,...o}),e[5]=o,e[6]=a,e[7]=r):r=e[7],r}function j({className:s,size:e="default",children:t,...o}){return p(l.Trigger,{"data-slot":"select-trigger","data-size":e,className:c("flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pe-2 ps-2.5 text-xs whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-md *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",s),...o,children:[t,i(l.Icon,{render:i(m,{icon:v,strokeWidth:2,className:"pointer-events-none size-4 text-muted-foreground"})})]})}function A({className:s,children:e,side:t="bottom",sideOffset:o=4,align:a="center",alignOffset:r=0,alignItemWithTrigger:n=!0,...d}){return i(l.Portal,{children:i(l.Positioner,{side:t,sideOffset:o,align:a,alignOffset:r,alignItemWithTrigger:n,className:"isolate z-50",children:p(l.Popup,{"data-slot":"select-content","data-align-trigger":n,className:c("isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-start-2 data-[side=inline-start]:slide-in-from-end-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 animate-none! relative bg-popover before:pointer-events-none before:absolute before:inset-0 before:-z-1 before:rounded-[inherit] **:data-[slot$=-item]:focus:bg-foreground/10 **:data-[slot$=-item]:data-highlighted:bg-foreground/10 **:data-[slot$=-separator]:bg-foreground/5 **:data-[slot$=-trigger]:focus:bg-foreground/10 **:data-[slot$=-trigger]:aria-expanded:bg-foreground/10! **:data-[variant=destructive]:focus:bg-foreground/10! **:data-[variant=destructive]:text-accent-foreground! **:data-[variant=destructive]:**:text-accent-foreground!",s),...d,children:[i(x,{}),i(l.List,{children:e}),i(w,{})]})})})}function U(s){const e=u(13);let t,o,a;e[0]!==s?({className:o,children:t,...a}=s,e[0]=s,e[1]=t,e[2]=o,e[3]=a):(t=e[1],o=e[2],a=e[3]);let r;e[4]!==o?(r=c("relative flex w-full cursor-default items-center gap-2 rounded-md py-2 pe-8 ps-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",o),e[4]=o,e[5]=r):r=e[5];let n;e[6]!==t?(n=i(l.ItemText,{className:"flex flex-1 shrink-0 gap-2 whitespace-nowrap",children:t}),e[6]=t,e[7]=n):n=e[7];let d;e[8]===Symbol.for("react.memo_cache_sentinel")?(d=i(l.ItemIndicator,{render:i("span",{className:"pointer-events-none absolute end-2 flex size-4 items-center justify-center"}),children:i(m,{icon:g,strokeWidth:2,className:"pointer-events-none"})}),e[8]=d):d=e[8];let f;return e[9]!==a||e[10]!==r||e[11]!==n?(f=p(l.Item,{"data-slot":"select-item",className:r,...a,children:[n,d]}),e[9]=a,e[10]=r,e[11]=n,e[12]=f):f=e[12],f}function x(s){const e=u(9);let t,o;e[0]!==s?({className:t,...o}=s,e[0]=s,e[1]=t,e[2]=o):(t=e[1],o=e[2]);let a;e[3]!==t?(a=c("top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",t),e[3]=t,e[4]=a):a=e[4];let r;e[5]===Symbol.for("react.memo_cache_sentinel")?(r=i(m,{icon:b,strokeWidth:2}),e[5]=r):r=e[5];let n;return e[6]!==o||e[7]!==a?(n=i(l.ScrollUpArrow,{"data-slot":"select-scroll-up-button",className:a,...o,children:r}),e[6]=o,e[7]=a,e[8]=n):n=e[8],n}function w(s){const e=u(9);let t,o;e[0]!==s?({className:t,...o}=s,e[0]=s,e[1]=t,e[2]=o):(t=e[1],o=e[2]);let a;e[3]!==t?(a=c("bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",t),e[3]=t,e[4]=a):a=e[4];let r;e[5]===Symbol.for("react.memo_cache_sentinel")?(r=i(m,{icon:h,strokeWidth:2}),e[5]=r):r=e[5];let n;return e[6]!==o||e[7]!==a?(n=i(l.ScrollDownArrow,{"data-slot":"select-scroll-down-button",className:a,...o,children:r}),e[6]=o,e[7]=a,e[8]=n):n=e[8],n}export{$ as S,j as a,A as b,U as c,I as d};