llm-simple-router 0.10.12 → 0.10.13

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 (47) hide show
  1. package/dist/admin/usage.js +0 -1
  2. package/dist/db/index.d.ts +1 -1
  3. package/dist/db/index.js +1 -1
  4. package/dist/db/metrics.js +3 -3
  5. package/dist/db/migrations/047_fix_remaining_is_complete.sql +16 -0
  6. package/dist/db/stats.js +0 -1
  7. package/dist/db/usage-windows.d.ts +2 -0
  8. package/dist/db/usage-windows.js +4 -1
  9. package/dist/metrics/sse-parser.js +6 -3
  10. package/dist/utils/time-range.js +6 -2
  11. package/frontend-dist/assets/{CardContent-D8q9vc5O.js → CardContent-DfVo-N85.js} +1 -1
  12. package/frontend-dist/assets/{CardTitle-yA_25649.js → CardTitle-npwJSAlz.js} +1 -1
  13. package/frontend-dist/assets/{Checkbox-DOkFBp83.js → Checkbox-Ddnzkh_i.js} +1 -1
  14. package/frontend-dist/assets/{CollapsibleContent-DzBUfYYw.js → CollapsibleContent-BTVazeoQ.js} +1 -1
  15. package/frontend-dist/assets/{CollapsibleTrigger-CHYSp36W.js → CollapsibleTrigger-DCQeyHrt.js} +1 -1
  16. package/frontend-dist/assets/{Dashboard-BvYHnpcJ.js → Dashboard-DjnImtwH.js} +1 -1
  17. package/frontend-dist/assets/{Input-CcyqZXkU.js → Input-Ey_q_5_r.js} +1 -1
  18. package/frontend-dist/assets/{Label-CzP8C4iz.js → Label-Dw5HcYsL.js} +1 -1
  19. package/frontend-dist/assets/{Login-CxzSo3yb.js → Login-CSrfhhm9.js} +1 -1
  20. package/frontend-dist/assets/{Logs-Bxqdk7eE.js → Logs-HR1DZs1M.js} +1 -1
  21. package/frontend-dist/assets/{MappingEntryEditor-B1DXrpQE.js → MappingEntryEditor-C9pgNL0Q.js} +1 -1
  22. package/frontend-dist/assets/{ModelCard-CfnNmO62.js → ModelCard-IQMwlnCm.js} +1 -1
  23. package/frontend-dist/assets/{ModelMappings-BER9jpBp.js → ModelMappings-kRx-GL_7.js} +1 -1
  24. package/frontend-dist/assets/{Monitor-DTRiQd_f.js → Monitor-y1ofDNK7.js} +1 -1
  25. package/frontend-dist/assets/{Providers-CFDV-w7E.js → Providers-C1bP2PoM.js} +1 -1
  26. package/frontend-dist/assets/{ProxyEnhancement-DsmirUED.js → ProxyEnhancement-DQx4coxn.js} +1 -1
  27. package/frontend-dist/assets/{QuickSetup-Ch84omRO.js → QuickSetup-DHX9-CnO.js} +1 -1
  28. package/frontend-dist/assets/{RetryRules-Dp5LarPp.js → RetryRules-zdJE0bFL.js} +1 -1
  29. package/frontend-dist/assets/{RouterKeys-BAddL89X.js → RouterKeys-CD0rI4kv.js} +1 -1
  30. package/frontend-dist/assets/{RovingFocusItem-CRi6yQVX.js → RovingFocusItem-CFmjbm49.js} +1 -1
  31. package/frontend-dist/assets/{Schedules-C_bDqD0b.js → Schedules-BUm3cC6w.js} +1 -1
  32. package/frontend-dist/assets/{Settings-Bcfiljtn.js → Settings-D7z5IRkY.js} +1 -1
  33. package/frontend-dist/assets/{Setup-BHAW_Tm2.js → Setup-i9inmgjB.js} +1 -1
  34. package/frontend-dist/assets/{Switch-OzhbhGwX.js → Switch-C9DeYAnK.js} +1 -1
  35. package/frontend-dist/assets/{TooltipTrigger-DOgXsxyY.js → TooltipTrigger-Dr6kqGSH.js} +1 -1
  36. package/frontend-dist/assets/{TransformRulesForm-IKRT5A3_.js → TransformRulesForm-CyXh4jHa.js} +1 -1
  37. package/frontend-dist/assets/{UnifiedRequestDialog-DYS5gkoE.js → UnifiedRequestDialog-6ZRBfjko.js} +1 -1
  38. package/frontend-dist/assets/{VisuallyHiddenInput-C3oWOQXr.js → VisuallyHiddenInput-CwE9jREu.js} +1 -1
  39. package/frontend-dist/assets/{button-C1QSPeLI.js → button-C7HO6Dyb.js} +2 -2
  40. package/frontend-dist/assets/{copy-Cv_Emnxv.js → copy-DxwFlq2A.js} +1 -1
  41. package/frontend-dist/assets/{dialog-BBGI9zKO.js → dialog-BWB1aLcT.js} +1 -1
  42. package/frontend-dist/assets/{index-247t8K8M.js → index-itL9--Q_.js} +2 -2
  43. package/frontend-dist/assets/{trash-2-DtOp0hat.js → trash-2-D2SrfECO.js} +1 -1
  44. package/frontend-dist/assets/{useClipboard-Bd3JzV3b.js → useClipboard-CttzUerj.js} +1 -1
  45. package/frontend-dist/assets/{useLogRetention-BrbC5bfG.js → useLogRetention-Dv0deAan.js} +1 -1
  46. package/frontend-dist/index.html +2 -2
  47. package/package.json +1 -1
@@ -8,7 +8,6 @@ const UsageQuerySchema = Type.Object({
8
8
  });
9
9
  function getDailyUsage(db, startTime, endTime, routerKeyId, providerId) {
10
10
  const conditions = [
11
- "rm.is_complete = 1",
12
11
  "rm.created_at >= datetime(?)",
13
12
  "rm.created_at < datetime(?)",
14
13
  ];
@@ -16,7 +16,7 @@ export { getStats, getLatestMetricTime } from "./stats.js";
16
16
  export type { Stats } from "./stats.js";
17
17
  export { getSetting, setSetting, isInitialized } from "./settings.js";
18
18
  export { getDbMaxSizeMb, setDbMaxSizeMb, getLogTableMaxSizeMb, setLogTableMaxSizeMb, } from "./settings.js";
19
- export { insertWindow, getLatestWindow, getWindowsInRange, getWindowUsage, } from "./usage-windows.js";
19
+ export { insertWindow, getLatestWindow, getLatestWindowByProvider, getWindowsInRange, getWindowUsage, } from "./usage-windows.js";
20
20
  export type { UsageWindow, WindowUsage } from "./usage-windows.js";
21
21
  export { getModelContextWindowOverride, getModelInfoForProvider, setModelInfoForProvider, deleteAllModelInfoForProvider, getAllModelInfo, } from "./model-info.js";
22
22
  export type { ProviderModelInfo } from "./model-info.js";
package/dist/db/index.js CHANGED
@@ -148,7 +148,7 @@ export { getMetricsSummary, getMetricsTimeseries, insertMetrics, getClientTypeBr
148
148
  export { getStats, getLatestMetricTime } from "./stats.js";
149
149
  export { getSetting, setSetting, isInitialized } from "./settings.js";
150
150
  export { getDbMaxSizeMb, setDbMaxSizeMb, getLogTableMaxSizeMb, setLogTableMaxSizeMb, } from "./settings.js";
151
- export { insertWindow, getLatestWindow, getWindowsInRange, getWindowUsage, } from "./usage-windows.js";
151
+ export { insertWindow, getLatestWindow, getLatestWindowByProvider, getWindowsInRange, getWindowUsage, } from "./usage-windows.js";
152
152
  export { getModelContextWindowOverride, getModelInfoForProvider, setModelInfoForProvider, deleteAllModelInfoForProvider, getAllModelInfo, } from "./model-info.js";
153
153
  export { getSchedulesByGroup, getActiveSchedulesForGroup, getScheduleById, getAllSchedules, createSchedule, updateSchedule, deleteSchedule, deleteSchedulesByGroup, } from "./schedules.js";
154
154
  export { collectDbSizeInfo, runSizeBasedCleanup, scheduleDbSizeMonitor, } from "./db-size-monitor.js";
@@ -54,7 +54,7 @@ function buildTimeCondition(period, startTime, endTime) {
54
54
  }
55
55
  export function getMetricsSummary(db, period, providerId, backendModel, routerKeyId, startTime, endTime, clientType) {
56
56
  const { timeWhere, timeParams } = buildTimeCondition(period, startTime, endTime);
57
- const conditions = ["rm.is_complete = 1", timeWhere];
57
+ const conditions = [timeWhere];
58
58
  const params = [...timeParams];
59
59
  const joins = ["LEFT JOIN providers p ON p.id = rm.provider_id"];
60
60
  if (providerId) {
@@ -89,7 +89,7 @@ export function getMetricsSummary(db, period, providerId, backendModel, routerKe
89
89
  }
90
90
  export function getClientTypeBreakdown(db, period, providerId, backendModel, routerKeyId, startTime, endTime) {
91
91
  const { timeWhere, timeParams } = buildTimeCondition(period, startTime, endTime);
92
- const conditions = ["rm.is_complete = 1", timeWhere];
92
+ const conditions = [timeWhere];
93
93
  const params = [...timeParams];
94
94
  if (providerId) {
95
95
  conditions.push("rm.provider_id = ?");
@@ -135,7 +135,7 @@ export function getMetricsTimeseries(db, period, metric, providerId, backendMode
135
135
  ? calcBucketSec((new Date(endTime).getTime() - new Date(startTime).getTime()) / MS_PER_SECOND)
136
136
  : calcBucketSec(PERIOD_TOTAL_SEC[period]);
137
137
  const { timeWhere, timeParams } = buildTimeCondition(period, startTime, endTime);
138
- const conditions = ["rm.is_complete = 1", timeWhere];
138
+ const conditions = [timeWhere];
139
139
  const params = [...timeParams];
140
140
  if (providerId) {
141
141
  conditions.push("rm.provider_id = ?");
@@ -0,0 +1,16 @@
1
+ -- Fix remaining historical request_metrics where is_complete=0 despite
2
+ -- successful HTTP responses (status_code=200).
3
+ --
4
+ -- Migration 046 already fixed records with output_tokens>0 AND total_duration_ms>0,
5
+ -- but missed:
6
+ -- 1. Records created after migration 046 ran (the root cause: SSE parser swallowed
7
+ -- [DONE] events, so metrics extractor never set complete=true)
8
+ -- 2. Records with status_code=200 but null/zero tokens or duration (e.g. empty
9
+ -- responses, or streams where [DONE] was the only event)
10
+ --
11
+ -- Since the dashboard no longer filters by is_complete (see dashboard query fixes),
12
+ -- this is primarily a data integrity fix.
13
+ UPDATE request_metrics
14
+ SET is_complete = 1
15
+ WHERE is_complete = 0
16
+ AND status_code = 200;
package/dist/db/stats.js CHANGED
@@ -16,7 +16,6 @@ export function getLatestMetricTime(db, providerId, routerKeyId) {
16
16
  }
17
17
  export function getStats(db, startTime, endTime, routerKeyId, providerId, backendModel) {
18
18
  const conditions = [
19
- "rm.is_complete = 1",
20
19
  "rm.created_at >= datetime(?)",
21
20
  "rm.created_at < datetime(?)",
22
21
  ];
@@ -14,6 +14,8 @@ export interface WindowUsage {
14
14
  }
15
15
  export declare function insertWindow(db: Database.Database, w: Omit<UsageWindow, "created_at">): string;
16
16
  export declare function getLatestWindow(db: Database.Database, routerKeyId?: string, providerId?: string): UsageWindow | null;
17
+ /** 获取指定 provider 的最新窗口,忽略 router_key_id 过滤。当 dashboard 等调用方不知道 router_key_id 时使用。 */
18
+ export declare function getLatestWindowByProvider(db: Database.Database, providerId: string): UsageWindow | null;
17
19
  /** 返回与 [start, end) 区间有重叠的窗口。可选参数不传表示不过滤该维度(与 getLatestWindow 的 IS NULL 语义不同) */
18
20
  export declare function getWindowsInRange(db: Database.Database, start: string, end: string, routerKeyId?: string, providerId?: string): UsageWindow[];
19
21
  /** 聚合指定时间窗口内的请求计数和 token 用量 */
@@ -24,6 +24,10 @@ export function getLatestWindow(db, routerKeyId, providerId) {
24
24
  const sql = `SELECT * FROM usage_windows WHERE ${conditions.join(" AND ")} ORDER BY start_time DESC LIMIT 1`;
25
25
  return db.prepare(sql).get(...params) ?? null;
26
26
  }
27
+ /** 获取指定 provider 的最新窗口,忽略 router_key_id 过滤。当 dashboard 等调用方不知道 router_key_id 时使用。 */
28
+ export function getLatestWindowByProvider(db, providerId) {
29
+ return db.prepare("SELECT * FROM usage_windows WHERE provider_id = ? ORDER BY start_time DESC LIMIT 1").get(providerId) ?? null;
30
+ }
27
31
  /** 返回与 [start, end) 区间有重叠的窗口。可选参数不传表示不过滤该维度(与 getLatestWindow 的 IS NULL 语义不同) */
28
32
  export function getWindowsInRange(db, start, end, routerKeyId, providerId) {
29
33
  const conditions = ["start_time < ?", "end_time > ?"];
@@ -41,7 +45,6 @@ export function getWindowsInRange(db, start, end, routerKeyId, providerId) {
41
45
  /** 聚合指定时间窗口内的请求计数和 token 用量 */
42
46
  export function getWindowUsage(db, startTime, endTime, routerKeyId, providerId) {
43
47
  const conditions = [
44
- "rm.is_complete = 1",
45
48
  "rm.created_at >= datetime(?)",
46
49
  "rm.created_at < datetime(?)",
47
50
  ];
@@ -61,12 +61,15 @@ export class SSEParser {
61
61
  }
62
62
  else if (line.startsWith("data:")) {
63
63
  const value = this.extractFieldValue(line);
64
- // [DONE] 是流结束信号,不作为普通事件返回
64
+ // [DONE] 是流结束信号,标记 isDone 阻止后续解析,同时作为普通事件返回
65
+ // 让 metrics extractor 的 processOpenAIEvent 能收到并设置 complete = true
65
66
  if (value === "[DONE]") {
66
67
  this.isDone = true;
67
- return null;
68
+ dataLines.push(value);
69
+ }
70
+ else {
71
+ dataLines.push(value);
68
72
  }
69
- dataLines.push(value);
70
73
  }
71
74
  // 其他 field(id:, retry:, etc.)按 SSE 规范忽略
72
75
  }
@@ -1,4 +1,4 @@
1
- import { getLatestWindow } from "../db/usage-windows.js";
1
+ import { getLatestWindow, getLatestWindowByProvider } from "../db/usage-windows.js";
2
2
  import { toSqliteDatetime, parseSqliteDatetime } from "./datetime.js";
3
3
  import { getLatestMetricTime } from "../db/stats.js";
4
4
  const WINDOW_HOURS = 5;
@@ -14,7 +14,11 @@ export function resolveTimeRange(period, db, routerKeyId, providerId) {
14
14
  const now = new Date();
15
15
  switch (period) {
16
16
  case "window": {
17
- const latest = getLatestWindow(db, routerKeyId, providerId);
17
+ // providerId 但无 routerKeyId 时,忽略 router_key_id 查找最新窗口
18
+ // (dashboard 等调用方不知道 router_key_id 时,也能匹配到实际窗口)
19
+ const latest = providerId && !routerKeyId
20
+ ? getLatestWindowByProvider(db, providerId)
21
+ : getLatestWindow(db, routerKeyId, providerId);
18
22
  if (latest && now <= parseSqliteDatetime(latest.end_time)) {
19
23
  // 有未过期窗口 → 直接使用窗口范围
20
24
  return { startTime: latest.start_time, endTime: latest.end_time };
@@ -1 +1 @@
1
- import{Ut as e,Vt as t,Z as n,et as r,ft as i,ht as a,r as o}from"./button-C1QSPeLI.js";var s=[`data-size`],c=r({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]},size:{default:`default`}},setup(r){let c=r;return(l,u)=>(i(),n(`div`,{"data-slot":`card`,"data-size":r.size,class:e(t(o)(`ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col`,c.class))},[a(l.$slots,`default`)],10,s))}}),l=r({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`div`,{"data-slot":`card-content`,class:e(t(o)(`px-4 group-data-[size=sm]/card:px-3`,s.class))},[a(r.$slots,`default`)],2))}});export{c as n,l as t};
1
+ import{Ut as e,Vt as t,Z as n,et as r,ft as i,ht as a,r as o}from"./button-C7HO6Dyb.js";var s=[`data-size`],c=r({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]},size:{default:`default`}},setup(r){let c=r;return(l,u)=>(i(),n(`div`,{"data-slot":`card`,"data-size":r.size,class:e(t(o)(`ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col`,c.class))},[a(l.$slots,`default`)],10,s))}}),l=r({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`div`,{"data-slot":`card-content`,class:e(t(o)(`px-4 group-data-[size=sm]/card:px-3`,s.class))},[a(r.$slots,`default`)],2))}});export{c as n,l as t};
@@ -1 +1 @@
1
- import{Ut as e,Vt as t,Z as n,et as r,ft as i,ht as a,r as o}from"./button-C1QSPeLI.js";var s=r({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`div`,{"data-slot":`card-header`,class:e(t(o)(`gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]`,s.class))},[a(r.$slots,`default`)],2))}}),c=r({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`div`,{"data-slot":`card-title`,class:e(t(o)(`text-base leading-snug font-medium group-data-[size=sm]/card:text-sm cn-font-heading`,s.class))},[a(r.$slots,`default`)],2))}});export{s as n,c as t};
1
+ import{Ut as e,Vt as t,Z as n,et as r,ft as i,ht as a,r as o}from"./button-C7HO6Dyb.js";var s=r({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`div`,{"data-slot":`card-header`,class:e(t(o)(`gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]`,s.class))},[a(r.$slots,`default`)],2))}}),c=r({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(r){let s=r;return(r,c)=>(i(),n(`div`,{"data-slot":`card-title`,class:e(t(o)(`text-base leading-snug font-medium group-data-[size=sm]/card:text-sm cn-font-heading`,s.class))},[a(r.$slots,`default`)],2))}});export{s as n,c as t};
@@ -1 +1 @@
1
- import{$ as e,Tt as t,U as n,Vt as r,W as i,Wt as a,X as o,Y as s,_t as c,et as l,ft as u,ht as d,i as f,m as p,nt as m,o as h,q as g,r as _,st as v,x as y}from"./button-C1QSPeLI.js";import{t as b}from"./VisuallyHiddenInput-C3oWOQXr.js";import{t as x}from"./RovingFocusItem-CRi6yQVX.js";import{B as S,G as C,H as w,L as T,Y as E,q as D,ut as O}from"./index-247t8K8M.js";function k(e,t){return C(e)?!1:Array.isArray(e)?e.some(e=>E(e,t)):E(e,t)}var[A,j]=D(`CheckboxGroupRoot`);function M(e){return e===`indeterminate`}function N(e){return M(e)?`indeterminate`:e?`checked`:`unchecked`}var[P,F]=D(`CheckboxRoot`),I=l({inheritAttrs:!1,__name:`CheckboxRoot`,props:{defaultValue:{type:null,required:!1},modelValue:{type:null,required:!1,default:void 0},disabled:{type:Boolean,required:!1},value:{type:null,required:!1,default:`on`},id:{type:String,required:!1},trueValue:{type:null,required:!1,default:()=>!0},falseValue:{type:null,required:!1,default:()=>!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`},name:{type:String,required:!1},required:{type:Boolean,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let l=e,m=a,{forwardRef:_,currentElement:y}=h(),S=A(null),T=p(l,`modelValue`,m,{defaultValue:l.defaultValue??l.falseValue,passive:l.modelValue===void 0}),D=g(()=>S?.disabled.value||l.disabled),O=g(()=>E(T.value,l.trueValue)),j=g(()=>C(S?.modelValue.value)?T.value===`indeterminate`?`indeterminate`:O.value:k(S.modelValue.value,l.value));function P(){if(C(S?.modelValue.value))T.value===`indeterminate`?T.value=l.trueValue:T.value=O.value?l.falseValue:l.trueValue;else{let e=[...S.modelValue.value||[]];if(k(e,l.value)){let t=e.findIndex(e=>E(e,l.value));e.splice(t,1)}else e.push(l.value);S.modelValue.value=e}}let I=w(y),L=g(()=>l.id&&y.value?document.querySelector(`[for="${l.id}"]`)?.innerText:void 0);return F({disabled:D,state:j}),(e,a)=>(u(),s(c(r(S)?.rovingFocus.value?r(x):r(f)),v(e.$attrs,{id:e.id,ref:r(_),role:`checkbox`,"as-child":e.asChild,as:e.as,type:e.as===`button`?`button`:void 0,"aria-checked":r(M)(j.value)?`mixed`:j.value,"aria-required":e.required,"aria-label":e.$attrs[`aria-label`]||L.value,"data-state":r(N)(j.value),"data-disabled":D.value?``:void 0,disabled:D.value,focusable:r(S)?.rovingFocus.value?!D.value:void 0,onKeydown:n(i(()=>{},[`prevent`]),[`enter`]),onClick:P}),{default:t(()=>[d(e.$slots,`default`,{modelValue:r(T),state:j.value}),r(I)&&e.name&&!r(S)?(u(),s(r(b),{key:0,type:`checkbox`,checked:!!j.value,name:e.name,value:e.value,disabled:D.value,required:e.required},null,8,[`checked`,`name`,`value`,`disabled`,`required`])):o(`v-if`,!0)]),_:3},16,[`id`,`as-child`,`as`,`type`,`aria-checked`,`aria-required`,`aria-label`,`data-state`,`data-disabled`,`disabled`,`focusable`,`onKeydown`]))}}),L=l({__name:`CheckboxIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(n){let{forwardRef:i}=h(),a=P();return(n,o)=>(u(),s(r(T),{present:n.forceMount||r(M)(r(a).state.value)||r(a).state.value===!0},{default:t(()=>[e(r(f),v({ref:r(i),"data-state":r(N)(r(a).state.value),"data-disabled":r(a).disabled.value?``:void 0,style:{pointerEvents:`none`},"as-child":n.asChild,as:n.as},n.$attrs),{default:t(()=>[d(n.$slots,`default`)]),_:3},16,[`data-state`,`data-disabled`,`as-child`,`as`])]),_:3},8,[`present`]))}}),R=l({__name:`Checkbox`,props:{defaultValue:{},modelValue:{},disabled:{type:Boolean},value:{},id:{},trueValue:{},falseValue:{},asChild:{type:Boolean},as:{},name:{},required:{type:Boolean},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(n,{emit:i}){let o=n,c=i,l=S(y(o,`class`),c);return(n,i)=>(u(),s(r(I),v({"data-slot":`checkbox`},r(l),{class:r(_)(`border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-md border transition-colors group-has-disabled/field:opacity-50 focus-visible:ring-3 aria-invalid:ring-3 peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50`,o.class)}),{default:t(i=>[e(r(L),{"data-slot":`checkbox-indicator`,class:`[&>svg]:size-3.5 grid place-content-center text-current transition-none`},{default:t(()=>[d(n.$slots,`default`,a(m(i)),()=>[e(r(O))])]),_:2},1024)]),_:3},16,[`class`]))}});export{R as t};
1
+ import{$ as e,Tt as t,U as n,Vt as r,W as i,Wt as a,X as o,Y as s,_t as c,et as l,ft as u,ht as d,i as f,m as p,nt as m,o as h,q as g,r as _,st as v,x as y}from"./button-C7HO6Dyb.js";import{t as b}from"./VisuallyHiddenInput-CwE9jREu.js";import{t as x}from"./RovingFocusItem-CFmjbm49.js";import{B as S,G as C,H as w,L as T,Y as E,q as D,ut as O}from"./index-itL9--Q_.js";function k(e,t){return C(e)?!1:Array.isArray(e)?e.some(e=>E(e,t)):E(e,t)}var[A,j]=D(`CheckboxGroupRoot`);function M(e){return e===`indeterminate`}function N(e){return M(e)?`indeterminate`:e?`checked`:`unchecked`}var[P,F]=D(`CheckboxRoot`),I=l({inheritAttrs:!1,__name:`CheckboxRoot`,props:{defaultValue:{type:null,required:!1},modelValue:{type:null,required:!1,default:void 0},disabled:{type:Boolean,required:!1},value:{type:null,required:!1,default:`on`},id:{type:String,required:!1},trueValue:{type:null,required:!1,default:()=>!0},falseValue:{type:null,required:!1,default:()=>!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`},name:{type:String,required:!1},required:{type:Boolean,required:!1}},emits:[`update:modelValue`],setup(e,{emit:a}){let l=e,m=a,{forwardRef:_,currentElement:y}=h(),S=A(null),T=p(l,`modelValue`,m,{defaultValue:l.defaultValue??l.falseValue,passive:l.modelValue===void 0}),D=g(()=>S?.disabled.value||l.disabled),O=g(()=>E(T.value,l.trueValue)),j=g(()=>C(S?.modelValue.value)?T.value===`indeterminate`?`indeterminate`:O.value:k(S.modelValue.value,l.value));function P(){if(C(S?.modelValue.value))T.value===`indeterminate`?T.value=l.trueValue:T.value=O.value?l.falseValue:l.trueValue;else{let e=[...S.modelValue.value||[]];if(k(e,l.value)){let t=e.findIndex(e=>E(e,l.value));e.splice(t,1)}else e.push(l.value);S.modelValue.value=e}}let I=w(y),L=g(()=>l.id&&y.value?document.querySelector(`[for="${l.id}"]`)?.innerText:void 0);return F({disabled:D,state:j}),(e,a)=>(u(),s(c(r(S)?.rovingFocus.value?r(x):r(f)),v(e.$attrs,{id:e.id,ref:r(_),role:`checkbox`,"as-child":e.asChild,as:e.as,type:e.as===`button`?`button`:void 0,"aria-checked":r(M)(j.value)?`mixed`:j.value,"aria-required":e.required,"aria-label":e.$attrs[`aria-label`]||L.value,"data-state":r(N)(j.value),"data-disabled":D.value?``:void 0,disabled:D.value,focusable:r(S)?.rovingFocus.value?!D.value:void 0,onKeydown:n(i(()=>{},[`prevent`]),[`enter`]),onClick:P}),{default:t(()=>[d(e.$slots,`default`,{modelValue:r(T),state:j.value}),r(I)&&e.name&&!r(S)?(u(),s(r(b),{key:0,type:`checkbox`,checked:!!j.value,name:e.name,value:e.value,disabled:D.value,required:e.required},null,8,[`checked`,`name`,`value`,`disabled`,`required`])):o(`v-if`,!0)]),_:3},16,[`id`,`as-child`,`as`,`type`,`aria-checked`,`aria-required`,`aria-label`,`data-state`,`data-disabled`,`disabled`,`focusable`,`onKeydown`]))}}),L=l({__name:`CheckboxIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(n){let{forwardRef:i}=h(),a=P();return(n,o)=>(u(),s(r(T),{present:n.forceMount||r(M)(r(a).state.value)||r(a).state.value===!0},{default:t(()=>[e(r(f),v({ref:r(i),"data-state":r(N)(r(a).state.value),"data-disabled":r(a).disabled.value?``:void 0,style:{pointerEvents:`none`},"as-child":n.asChild,as:n.as},n.$attrs),{default:t(()=>[d(n.$slots,`default`)]),_:3},16,[`data-state`,`data-disabled`,`as-child`,`as`])]),_:3},8,[`present`]))}}),R=l({__name:`Checkbox`,props:{defaultValue:{},modelValue:{},disabled:{type:Boolean},value:{},id:{},trueValue:{},falseValue:{},asChild:{type:Boolean},as:{},name:{},required:{type:Boolean},class:{type:[Boolean,null,String,Object,Array]}},emits:[`update:modelValue`],setup(n,{emit:i}){let o=n,c=i,l=S(y(o,`class`),c);return(n,i)=>(u(),s(r(I),v({"data-slot":`checkbox`},r(l),{class:r(_)(`border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-md border transition-colors group-has-disabled/field:opacity-50 focus-visible:ring-3 aria-invalid:ring-3 peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50`,o.class)}),{default:t(i=>[e(r(L),{"data-slot":`checkbox-indicator`,class:`[&>svg]:size-3.5 grid place-content-center text-current transition-none`},{default:t(()=>[d(n.$slots,`default`,a(m(i)),()=>[e(r(O))])]),_:2},1024)]),_:3},16,[`class`]))}});export{R as t};
@@ -1 +1 @@
1
- import{$ as e,Nt as t,Rt as n,St as r,Tt as i,Vt as a,Wt as o,X as s,Y as c,ct as l,d as u,et as d,ft as f,ht as p,i as m,m as h,nt as g,o as _,q as v,st as y,ut as b}from"./button-C1QSPeLI.js";import{B as x,L as S,q as C,z as w}from"./index-247t8K8M.js";var[T,E]=C(`CollapsibleRoot`),D=d({__name:`CollapsibleRoot`,props:{defaultOpen:{type:Boolean,required:!1,default:!1},open:{type:Boolean,required:!1,default:void 0},disabled:{type:Boolean,required:!1},unmountOnHide:{type:Boolean,required:!1,default:!0},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:open`],setup(e,{expose:t,emit:r}){let o=e,s=h(o,`open`,r,{defaultValue:o.defaultOpen,passive:o.open===void 0}),{disabled:l,unmountOnHide:u}=n(o);return E({contentId:``,disabled:l,open:s,unmountOnHide:u,onOpenToggle:()=>{l.value||(s.value=!s.value)}}),t({open:s}),_(),(e,t)=>(f(),c(a(m),{as:e.as,"as-child":o.asChild,"data-state":a(s)?`open`:`closed`,"data-disabled":a(l)?``:void 0},{default:i(()=>[p(e.$slots,`default`,{open:a(s)})]),_:3},8,[`as`,`as-child`,`data-state`,`data-disabled`]))}}),O=d({inheritAttrs:!1,__name:`CollapsibleContent`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`contentFound`],setup(n,{emit:o}){let d=n,h=o,g=T();g.contentId||=w(void 0,`reka-collapsible-content`);let x=t(),{forwardRef:C,currentElement:E}=_(),D=t(0),O=t(0),k=v(()=>g.open.value),A=t(k.value),j=t();r(()=>[k.value,x.value?.present],async()=>{await l();let e=E.value;if(!e)return;j.value=j.value||{transitionDuration:e.style.transitionDuration,animationName:e.style.animationName},e.style.transitionDuration=`0s`,e.style.animationName=`none`;let t=e.getBoundingClientRect();O.value=t.height,D.value=t.width,A.value||(e.style.transitionDuration=j.value.transitionDuration,e.style.animationName=j.value.animationName)},{immediate:!0});let M=v(()=>A.value&&g.open.value);return b(()=>{requestAnimationFrame(()=>{A.value=!1})}),u(E,`beforematch`,e=>{requestAnimationFrame(()=>{g.onOpenToggle(),h(`contentFound`)})}),(t,n)=>(f(),c(a(S),{ref_key:`presentRef`,ref:x,present:t.forceMount||a(g).open.value,"force-mount":!0},{default:i(({present:n})=>[e(a(m),y(t.$attrs,{id:a(g).contentId,ref:a(C),"as-child":d.asChild,as:t.as,hidden:n?void 0:a(g).unmountOnHide.value?``:`until-found`,"data-state":M.value?void 0:a(g).open.value?`open`:`closed`,"data-disabled":a(g).disabled?.value?``:void 0,style:{"--reka-collapsible-content-height":`${O.value}px`,"--reka-collapsible-content-width":`${D.value}px`}}),{default:i(()=>[!a(g).unmountOnHide.value||n?p(t.$slots,`default`,{key:0}):s(`v-if`,!0)]),_:2},1040,[`id`,`as-child`,`as`,`hidden`,`data-state`,`data-disabled`,`style`])]),_:3},8,[`present`]))}}),k=d({__name:`Collapsible`,props:{defaultOpen:{type:Boolean},open:{type:Boolean},disabled:{type:Boolean},unmountOnHide:{type:Boolean},asChild:{type:Boolean},as:{}},emits:[`update:open`],setup(e,{emit:t}){let n=x(e,t);return(e,t)=>(f(),c(a(D),y({"data-slot":`collapsible`},a(n)),{default:i(t=>[p(e.$slots,`default`,o(g(t)))]),_:3},16))}}),A=d({__name:`CollapsibleContent`,props:{forceMount:{type:Boolean},asChild:{type:Boolean},as:{}},setup(e){let t=e;return(e,n)=>(f(),c(a(O),y({"data-slot":`collapsible-content`},t),{default:i(()=>[p(e.$slots,`default`)]),_:3},16))}});export{k as n,T as r,A as t};
1
+ import{$ as e,Nt as t,Rt as n,St as r,Tt as i,Vt as a,Wt as o,X as s,Y as c,ct as l,d as u,et as d,ft as f,ht as p,i as m,m as h,nt as g,o as _,q as v,st as y,ut as b}from"./button-C7HO6Dyb.js";import{B as x,L as S,q as C,z as w}from"./index-itL9--Q_.js";var[T,E]=C(`CollapsibleRoot`),D=d({__name:`CollapsibleRoot`,props:{defaultOpen:{type:Boolean,required:!1,default:!1},open:{type:Boolean,required:!1,default:void 0},disabled:{type:Boolean,required:!1},unmountOnHide:{type:Boolean,required:!1,default:!0},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`update:open`],setup(e,{expose:t,emit:r}){let o=e,s=h(o,`open`,r,{defaultValue:o.defaultOpen,passive:o.open===void 0}),{disabled:l,unmountOnHide:u}=n(o);return E({contentId:``,disabled:l,open:s,unmountOnHide:u,onOpenToggle:()=>{l.value||(s.value=!s.value)}}),t({open:s}),_(),(e,t)=>(f(),c(a(m),{as:e.as,"as-child":o.asChild,"data-state":a(s)?`open`:`closed`,"data-disabled":a(l)?``:void 0},{default:i(()=>[p(e.$slots,`default`,{open:a(s)})]),_:3},8,[`as`,`as-child`,`data-state`,`data-disabled`]))}}),O=d({inheritAttrs:!1,__name:`CollapsibleContent`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`contentFound`],setup(n,{emit:o}){let d=n,h=o,g=T();g.contentId||=w(void 0,`reka-collapsible-content`);let x=t(),{forwardRef:C,currentElement:E}=_(),D=t(0),O=t(0),k=v(()=>g.open.value),A=t(k.value),j=t();r(()=>[k.value,x.value?.present],async()=>{await l();let e=E.value;if(!e)return;j.value=j.value||{transitionDuration:e.style.transitionDuration,animationName:e.style.animationName},e.style.transitionDuration=`0s`,e.style.animationName=`none`;let t=e.getBoundingClientRect();O.value=t.height,D.value=t.width,A.value||(e.style.transitionDuration=j.value.transitionDuration,e.style.animationName=j.value.animationName)},{immediate:!0});let M=v(()=>A.value&&g.open.value);return b(()=>{requestAnimationFrame(()=>{A.value=!1})}),u(E,`beforematch`,e=>{requestAnimationFrame(()=>{g.onOpenToggle(),h(`contentFound`)})}),(t,n)=>(f(),c(a(S),{ref_key:`presentRef`,ref:x,present:t.forceMount||a(g).open.value,"force-mount":!0},{default:i(({present:n})=>[e(a(m),y(t.$attrs,{id:a(g).contentId,ref:a(C),"as-child":d.asChild,as:t.as,hidden:n?void 0:a(g).unmountOnHide.value?``:`until-found`,"data-state":M.value?void 0:a(g).open.value?`open`:`closed`,"data-disabled":a(g).disabled?.value?``:void 0,style:{"--reka-collapsible-content-height":`${O.value}px`,"--reka-collapsible-content-width":`${D.value}px`}}),{default:i(()=>[!a(g).unmountOnHide.value||n?p(t.$slots,`default`,{key:0}):s(`v-if`,!0)]),_:2},1040,[`id`,`as-child`,`as`,`hidden`,`data-state`,`data-disabled`,`style`])]),_:3},8,[`present`]))}}),k=d({__name:`Collapsible`,props:{defaultOpen:{type:Boolean},open:{type:Boolean},disabled:{type:Boolean},unmountOnHide:{type:Boolean},asChild:{type:Boolean},as:{}},emits:[`update:open`],setup(e,{emit:t}){let n=x(e,t);return(e,t)=>(f(),c(a(D),y({"data-slot":`collapsible`},a(n)),{default:i(t=>[p(e.$slots,`default`,o(g(t)))]),_:3},16))}}),A=d({__name:`CollapsibleContent`,props:{forceMount:{type:Boolean},asChild:{type:Boolean},as:{}},setup(e){let t=e;return(e,n)=>(f(),c(a(O),y({"data-slot":`collapsible-content`},t),{default:i(()=>[p(e.$slots,`default`)]),_:3},16))}});export{k as n,T as r,A as t};
@@ -1 +1 @@
1
- import{Tt as e,Vt as t,Y as n,et as r,ft as i,ht as a,i as o,o as s,st as c}from"./button-C1QSPeLI.js";import{r as l}from"./CollapsibleContent-DzBUfYYw.js";var u=r({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`}},setup(r){let c=r;s();let u=l();return(r,s)=>(i(),n(t(o),{type:r.as===`button`?`button`:void 0,as:r.as,"as-child":c.asChild,"aria-controls":t(u).contentId,"aria-expanded":t(u).open.value,"data-state":t(u).open.value?`open`:`closed`,"data-disabled":t(u).disabled?.value?``:void 0,disabled:t(u).disabled?.value,onClick:t(u).onOpenToggle},{default:e(()=>[a(r.$slots,`default`)]),_:3},8,[`type`,`as`,`as-child`,`aria-controls`,`aria-expanded`,`data-state`,`data-disabled`,`disabled`,`onClick`]))}}),d=r({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean},as:{}},setup(r){let o=r;return(r,s)=>(i(),n(t(u),c({"data-slot":`collapsible-trigger`},o),{default:e(()=>[a(r.$slots,`default`)]),_:3},16))}});export{d as t};
1
+ import{Tt as e,Vt as t,Y as n,et as r,ft as i,ht as a,i as o,o as s,st as c}from"./button-C7HO6Dyb.js";import{r as l}from"./CollapsibleContent-BTVazeoQ.js";var u=r({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`}},setup(r){let c=r;s();let u=l();return(r,s)=>(i(),n(t(o),{type:r.as===`button`?`button`:void 0,as:r.as,"as-child":c.asChild,"aria-controls":t(u).contentId,"aria-expanded":t(u).open.value,"data-state":t(u).open.value?`open`:`closed`,"data-disabled":t(u).disabled?.value?``:void 0,disabled:t(u).disabled?.value,onClick:t(u).onOpenToggle},{default:e(()=>[a(r.$slots,`default`)]),_:3},8,[`type`,`as`,`as-child`,`aria-controls`,`aria-expanded`,`data-state`,`data-disabled`,`disabled`,`onClick`]))}}),d=r({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean},as:{}},setup(r){let o=r;return(r,s)=>(i(),n(t(u),c({"data-slot":`collapsible-trigger`},o),{default:e(()=>[a(r.$slots,`default`)]),_:3},16))}});export{d as t};