@lunora/studio 1.0.0-alpha.142 → 1.0.0-alpha.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +15 -4
- package/dist/index.d.ts +15 -4
- package/dist/index.mjs +1 -1
- package/dist/mount.d.mts +2 -1
- package/dist/mount.d.ts +2 -1
- package/dist/mount.mjs +1 -1
- package/dist/packem_chunks/HealthPanel.mjs +1 -1
- package/dist/packem_chunks/MetricsPanel.mjs +1 -1
- package/dist/packem_chunks/analytics-panel.mjs +1 -1
- package/dist/packem_chunks/issues-panel.mjs +1 -1
- package/dist/packem_chunks/kv-browser.mjs +1 -1
- package/dist/packem_chunks/schedule-panel.mjs +1 -1
- package/dist/packem_shared/{ScheduledJobs-oDVEymk5.mjs → ScheduledJobs-Db0HZ8R9.mjs} +1 -1
- package/dist/packem_shared/{Studio-5eRSjGmd.mjs → Studio-UxOpDgEl.mjs} +1 -1
- package/dist/packem_shared/StudioApp-BdisV3FN.mjs +1 -0
- package/dist/packem_shared/aggregateMetrics-CY05xrYU.mjs +1 -0
- package/dist/packem_shared/{app.d-D1bPR8FO.d.mts → app.d-DFjg4Uki.d.mts} +33 -1
- package/dist/packem_shared/{app.d-D1bPR8FO.d.ts → app.d-DFjg4Uki.d.ts} +33 -1
- package/dist/packem_shared/{select-Cx8-CokP.mjs → select-DPyS18Vy.mjs} +1 -1
- package/dist/packem_shared/{studio-4odoxrh9.mjs → studio-DE8N0tIQ.mjs} +1 -1
- package/dist/standalone/chunk-2BN33A2H.js +1 -0
- package/dist/standalone/{chunk-A4MLWW6Q.js → chunk-2DRUQ42V.js} +1 -1
- package/dist/standalone/{chunk-WIFKQ25E.js → chunk-44XP35PZ.js} +1 -1
- package/dist/standalone/{chunk-WZYKLEU5.js → chunk-4RDRBZ3Z.js} +1 -1
- package/dist/standalone/{chunk-BMAP2J7X.js → chunk-5OSOXQGT.js} +1 -1
- package/dist/standalone/chunk-5OWAVF7Y.js +1 -0
- package/dist/standalone/{chunk-NZMUY7ZG.js → chunk-5UFDH5PE.js} +1 -1
- package/dist/standalone/{chunk-S4HBMTJ3.js → chunk-64KROZ2C.js} +1 -1
- package/dist/standalone/{chunk-ZNPR3SGG.js → chunk-6DSKJTA4.js} +1 -1
- package/dist/standalone/{chunk-PNFIPQJO.js → chunk-6GTVFSLV.js} +1 -1
- package/dist/standalone/{chunk-IGBQ2CPW.js → chunk-73TWF2G4.js} +1 -1
- package/dist/standalone/{chunk-PV2LCZ6D.js → chunk-76EQ5JUU.js} +1 -1
- package/dist/standalone/{chunk-2O5QDSR2.js → chunk-ADJTCEH3.js} +1 -1
- package/dist/standalone/{chunk-3MNTCYQ3.js → chunk-AQI7ZNT2.js} +1 -1
- package/dist/standalone/{chunk-F2R2UX27.js → chunk-CDTGKA5J.js} +1 -1
- package/dist/standalone/{chunk-BAIGKYAI.js → chunk-DHSCHEJZ.js} +1 -1
- package/dist/standalone/chunk-DPS5Q64N.js +1 -0
- package/dist/standalone/{chunk-WHWI6KXH.js → chunk-FRIPZLHV.js} +1 -1
- package/dist/standalone/{chunk-YRNEKBFM.js → chunk-FSFJ5LI2.js} +1 -1
- package/dist/standalone/{chunk-LPFRXMG7.js → chunk-GUIGDTCU.js} +1 -1
- package/dist/standalone/{chunk-I27WXF7C.js → chunk-I6GOQSDQ.js} +1 -1
- package/dist/standalone/{chunk-7ZWZNTKG.js → chunk-ICVRD6K5.js} +1 -1
- package/dist/standalone/{chunk-O32757IN.js → chunk-IPIFMAW4.js} +1 -1
- package/dist/standalone/{chunk-YKUEP7AA.js → chunk-KVPXTLKG.js} +1 -1
- package/dist/standalone/{chunk-BP7MDQY5.js → chunk-M5ROVSBF.js} +1 -1
- package/dist/standalone/{chunk-L6KA7M4B.js → chunk-MM322O3E.js} +1 -1
- package/dist/standalone/{chunk-DRFQ3BUM.js → chunk-MOSQV7WU.js} +1 -1
- package/dist/standalone/{chunk-GCYNOU4C.js → chunk-MUOVSMDK.js} +1 -1
- package/dist/standalone/{chunk-QM3SGSVK.js → chunk-MWHKPKQC.js} +1 -1
- package/dist/standalone/{chunk-SPP7FEDA.js → chunk-NDVLXSQJ.js} +1 -1
- package/dist/standalone/{chunk-HJOKETMZ.js → chunk-OAEQLGGA.js} +1 -1
- package/dist/standalone/{chunk-BNGOZSCT.js → chunk-OIZ7KE2D.js} +1 -1
- package/dist/standalone/{chunk-LELCKAUP.js → chunk-OVCT4ANW.js} +1 -1
- package/dist/standalone/{chunk-7GHBT32T.js → chunk-P6NXPLYT.js} +1 -1
- package/dist/standalone/{chunk-QEN7S6YK.js → chunk-Q2ONYLZ3.js} +1 -1
- package/dist/standalone/{chunk-XDT5DXOI.js → chunk-Q3627RWT.js} +2 -2
- package/dist/standalone/{chunk-XUKH3NTP.js → chunk-QDUP4VDB.js} +1 -1
- package/dist/standalone/{chunk-PCOD3V5E.js → chunk-RI6SDJNF.js} +1 -1
- package/dist/standalone/{chunk-IMUTQDOB.js → chunk-RROTBODU.js} +1 -1
- package/dist/standalone/{chunk-BDZFZT2N.js → chunk-SFZVHU6C.js} +1 -1
- package/dist/standalone/chunk-SUDJTC4S.js +1 -0
- package/dist/standalone/{chunk-HCO5STOE.js → chunk-T5JCEI5W.js} +1 -1
- package/dist/standalone/{chunk-ATO3Y6BD.js → chunk-TJPEAOEL.js} +1 -1
- package/dist/standalone/{chunk-V5ITAZCZ.js → chunk-TUHIU3JC.js} +1 -1
- package/dist/standalone/{chunk-37VWQZEF.js → chunk-UAN6GGJ4.js} +1 -1
- package/dist/standalone/{chunk-KBSJO66O.js → chunk-UVY6KN6G.js} +1 -1
- package/dist/standalone/{chunk-HZX6KSC2.js → chunk-V7HAXWCR.js} +1 -1
- package/dist/standalone/{chunk-X43AA6RX.js → chunk-VFMJJZVG.js} +1 -1
- package/dist/standalone/{chunk-BYWVVRKM.js → chunk-VKYBRQC2.js} +1 -1
- package/dist/standalone/{chunk-7DNDONOI.js → chunk-VQS5E53D.js} +1 -1
- package/dist/standalone/{chunk-NPHUYLGW.js → chunk-VRLTD6I6.js} +1 -1
- package/dist/standalone/{chunk-JXELPXLG.js → chunk-WJBOVMUO.js} +1 -1
- package/dist/standalone/{chunk-W7E5WYFI.js → chunk-WRLGCVLF.js} +1 -1
- package/dist/standalone/{chunk-HS7MSYK7.js → chunk-X6KMHRS7.js} +1 -1
- package/dist/standalone/{chunk-AR46S3PP.js → chunk-XKABJHJG.js} +1 -1
- package/dist/standalone/{chunk-IXMHWLSN.js → chunk-XYZBO7IN.js} +1 -1
- package/dist/standalone/{chunk-6H36JL4I.js → chunk-YM62NSM6.js} +1 -1
- package/dist/standalone/{chunk-IXLH5YBD.js → chunk-YQOVNRK5.js} +1 -1
- package/dist/standalone/{chunk-4TKQNBNV.js → chunk-ZJ6AMQGH.js} +1 -1
- package/dist/standalone/studio.js +7 -7
- package/package.json +4 -4
- package/dist/packem_shared/StudioApp-Bkym2DjT.mjs +0 -1
- package/dist/packem_shared/aggregateMetrics-A-Y7OH6R.mjs +0 -1
- package/dist/standalone/chunk-45T7VWRY.js +0 -1
- package/dist/standalone/chunk-AZOLR4BN.js +0 -1
- package/dist/standalone/chunk-CKZQXAZE.js +0 -1
- package/dist/standalone/chunk-TQCXJX4I.js +0 -1
- /package/dist/standalone/{chunk-YEBHHIAY.js → chunk-U5JDESCI.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as I}from"react/compiler-runtime";import{useLunora as $}from"@lunora/react";import{useState as
|
|
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-
|
|
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: ({
|
|
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: ({
|
|
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{
|
|
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};
|