llm-simple-router 0.10.1 → 0.10.2

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 (48) hide show
  1. package/dist/admin/monitor.js +8 -0
  2. package/dist/proxy/handler/failover-loop.js +7 -0
  3. package/dist/proxy/orchestration/orchestrator.d.ts +0 -1
  4. package/dist/proxy/orchestration/orchestrator.js +27 -19
  5. package/dist/proxy/orchestration/scope.d.ts +2 -0
  6. package/dist/proxy/orchestration/scope.js +4 -0
  7. package/frontend-dist/assets/{CardContent-go9x8eec.js → CardContent-DPvg3Xcs.js} +1 -1
  8. package/frontend-dist/assets/{CardTitle-BRlxAJ4B.js → CardTitle-DM5fz-mG.js} +1 -1
  9. package/frontend-dist/assets/{Checkbox-CNapa1C_.js → Checkbox-unFaqtdp.js} +1 -1
  10. package/frontend-dist/assets/{CollapsibleContent-C_hdLxxg.js → CollapsibleContent-B1F8U0rL.js} +1 -1
  11. package/frontend-dist/assets/{CollapsibleTrigger-DnPjb7Dr.js → CollapsibleTrigger-DvM-Vi0u.js} +1 -1
  12. package/frontend-dist/assets/{Dashboard-BD10zBkl.js → Dashboard-BEYLmW9j.js} +1 -1
  13. package/frontend-dist/assets/{Input-DY_kIwJO.js → Input-DNNW9ZDa.js} +1 -1
  14. package/frontend-dist/assets/{Label-DwD9QWfW.js → Label-Pt8u8M0A.js} +1 -1
  15. package/frontend-dist/assets/{Login-DVqJBb-O.js → Login-DBI0zYS0.js} +1 -1
  16. package/frontend-dist/assets/{Logs-3ckBDY_r.js → Logs-CSuY_LsY.js} +1 -1
  17. package/frontend-dist/assets/{MappingEntryEditor-DiuJMr6L.js → MappingEntryEditor-a6jg8S1l.js} +1 -1
  18. package/frontend-dist/assets/{ModelCard-M7BUbO4-.js → ModelCard-B8qOJN2O.js} +1 -1
  19. package/frontend-dist/assets/{ModelMappings-CAYfszaz.js → ModelMappings-DtsHJUoO.js} +1 -1
  20. package/frontend-dist/assets/Monitor-Bflzm0d-.js +1 -0
  21. package/frontend-dist/assets/{Providers-DoB7cAWp.js → Providers-2chCOkvt.js} +1 -1
  22. package/frontend-dist/assets/{ProxyEnhancement-CPiIq5wS.js → ProxyEnhancement-D5aXFYHw.js} +1 -1
  23. package/frontend-dist/assets/{QuickSetup-BN_YqbgQ.js → QuickSetup-CLlXPDT9.js} +1 -1
  24. package/frontend-dist/assets/{RetryRules-DIxgHt-G.js → RetryRules-DCKWN0O-.js} +1 -1
  25. package/frontend-dist/assets/{RouterKeys-hBEzqWaf.js → RouterKeys-BXtcQ-ZY.js} +1 -1
  26. package/frontend-dist/assets/{RovingFocusItem-DXXOzxYf.js → RovingFocusItem-CdltOaZP.js} +1 -1
  27. package/frontend-dist/assets/{Schedules-C8FBA29A.js → Schedules-CgHcxg_a.js} +1 -1
  28. package/frontend-dist/assets/{Settings-CsLsfZkl.js → Settings-Ft71iRqu.js} +1 -1
  29. package/frontend-dist/assets/{Setup-DE72fHWm.js → Setup-CHnudyek.js} +1 -1
  30. package/frontend-dist/assets/{Switch-QKmayVBf.js → Switch-C7kp2SaI.js} +1 -1
  31. package/frontend-dist/assets/{TooltipTrigger-CTzZDwpq.js → TooltipTrigger-CsJ-5Zto.js} +1 -1
  32. package/frontend-dist/assets/{TransformRulesForm-B1xYEDqV.js → TransformRulesForm-BiHTLWx0.js} +1 -1
  33. package/frontend-dist/assets/{UnifiedRequestDialog-D2Rmt-2C.js → UnifiedRequestDialog-ClLWPhI1.js} +1 -1
  34. package/frontend-dist/assets/{VisuallyHiddenInput-C0PhLv6-.js → VisuallyHiddenInput-D1bFtdXQ.js} +1 -1
  35. package/frontend-dist/assets/{button-DIkr5-e9.js → button-DNp6t9kr.js} +2 -2
  36. package/frontend-dist/assets/{copy-wxL8rXSb.js → copy-DS0tLfiJ.js} +1 -1
  37. package/frontend-dist/assets/{dialog-VRNiQWvn.js → dialog-90VLRpob.js} +1 -1
  38. package/frontend-dist/assets/{index-BkaQT-Ad.js → index-DXl9LuoU.js} +2 -2
  39. package/frontend-dist/assets/monitor-C9j7ppMj.js +1 -0
  40. package/frontend-dist/assets/monitor-CaDMr_KG.js +1 -0
  41. package/frontend-dist/assets/{trash-2-DP4nWvuZ.js → trash-2-DYG5YFsN.js} +1 -1
  42. package/frontend-dist/assets/{useClipboard-tOb7LUo7.js → useClipboard-R5Arm9GN.js} +1 -1
  43. package/frontend-dist/assets/{useLogRetention-WLn9pgNe.js → useLogRetention-BqzKX9wH.js} +1 -1
  44. package/frontend-dist/index.html +2 -2
  45. package/package.json +1 -1
  46. package/frontend-dist/assets/Monitor-DcJP6XHy.js +0 -1
  47. package/frontend-dist/assets/monitor-Baldqd3x.js +0 -1
  48. package/frontend-dist/assets/monitor-DeInYpBf.js +0 -1
@@ -34,5 +34,13 @@ export const adminMonitorRoutes = (app, options, done) => {
34
34
  return reply.code(HTTP_NOT_FOUND).send(apiError(API_CODE.NOT_FOUND, "Not found"));
35
35
  return req;
36
36
  });
37
+ app.delete("/admin/api/monitor/request/:id", async (request, reply) => {
38
+ const { id } = request.params;
39
+ const killed = tracker.killRequest(id);
40
+ if (!killed) {
41
+ return reply.code(HTTP_NOT_FOUND).send(apiError(API_CODE.NOT_FOUND, "Request not found or already completed"));
42
+ }
43
+ return { killed: true };
44
+ });
37
45
  done();
38
46
  };
@@ -107,6 +107,9 @@ export async function executeFailoverLoop(ctx, errors, deps, upstreamPath, adapt
107
107
  const clientApiType = ctx.apiType;
108
108
  let failoverIteration = 0;
109
109
  while (true) {
110
+ // 请求被 kill 后 reply 已销毁,直接退出避免浪费 failover 迭代
111
+ if (reply.raw.destroyed)
112
+ return reply;
110
113
  if (++failoverIteration > MAX_FAILOVER_ITERATIONS) {
111
114
  return reply.code(HTTP_SERVICE_UNAVAILABLE).send({
112
115
  error: { message: `Max failover iterations (${MAX_FAILOVER_ITERATIONS}) exceeded`, type: "server_error", code: "failover_limit_exceeded" },
@@ -367,6 +370,10 @@ export async function executeFailoverLoop(ctx, errors, deps, upstreamPath, adapt
367
370
  if (e instanceof SemaphoreTimeoutError) {
368
371
  return rejectAndReply(reply, rCtx, errors.concurrencyTimeout(provider.id, e.timeoutMs), `Concurrency wait timeout for provider '${provider.id}' (${e.timeoutMs}ms)`, provider.id, flushCurrentErrors);
369
372
  }
373
+ // 请求被主动 kill(abort + reply destroy),直接退出不写日志
374
+ if (e instanceof Error && e.name === "AbortError") {
375
+ return reply;
376
+ }
370
377
  // 其他未知错误
371
378
  const errMsg = e instanceof Error ? e.message : e instanceof Error ? e.message : JSON.stringify(e);
372
379
  request.log.debug({ logId, error: errMsg, action: "upstream_error" });
@@ -54,7 +54,6 @@ export declare class ProxyOrchestrator {
54
54
  });
55
55
  handle(request: FastifyRequest, reply: FastifyReply, apiType: "openai" | "openai-responses" | "anthropic", config: OrchestratorConfig, ctx?: HandleContext): Promise<ResilienceResult>;
56
56
  private buildActiveRequest;
57
- private createAbortSignal;
58
57
  private executeResilience;
59
58
  private sendResponse;
60
59
  private extractTrackStatus;
@@ -23,18 +23,35 @@ export class ProxyOrchestrator {
23
23
  }
24
24
  async handle(request, reply, apiType, config, ctx) {
25
25
  const providerId = config.provider.id;
26
+ const controller = new AbortController();
27
+ // 客户端断连时自动 abort(保留原有行为)
28
+ request.raw.on("close", () => {
29
+ if (!request.raw.readableEnded) {
30
+ controller.abort();
31
+ }
32
+ });
26
33
  const trackerReq = this.buildActiveRequest(request, config, apiType);
27
34
  try {
28
- const result = await this.deps.trackerScope.track(trackerReq, () => this.deps.semaphoreScope.withSlot(providerId, this.createAbortSignal(request), () => {
29
- trackerReq.queued = true;
30
- this.deps.trackerScope.markQueued(trackerReq.id, true);
31
- }, () => {
32
- if (trackerReq.queued) {
33
- trackerReq.queued = false;
34
- this.deps.trackerScope.markQueued(trackerReq.id, false);
35
- }
36
- return this.executeResilience(config, ctx);
37
- }, config.concurrencyOverride), (result) => this.extractTrackStatus(result), (result) => result.attempts.map(a => ({
35
+ const result = await this.deps.trackerScope.track(trackerReq, () => {
36
+ // kill 回调必须在 tracker.start() 之后注册,确保请求已在 activeMap 中
37
+ this.deps.trackerScope.registerKillCallback(trackerReq.id, () => {
38
+ controller.abort();
39
+ try {
40
+ reply.raw.destroy();
41
+ }
42
+ catch { /* reply may already be destroyed */ } // eslint-disable-line taste/no-silent-catch
43
+ });
44
+ return this.deps.semaphoreScope.withSlot(providerId, controller.signal, () => {
45
+ trackerReq.queued = true;
46
+ this.deps.trackerScope.markQueued(trackerReq.id, true);
47
+ }, () => {
48
+ if (trackerReq.queued) {
49
+ trackerReq.queued = false;
50
+ this.deps.trackerScope.markQueued(trackerReq.id, false);
51
+ }
52
+ return this.executeResilience(config, ctx);
53
+ }, config.concurrencyOverride);
54
+ }, (result) => this.extractTrackStatus(result), (result) => result.attempts.map(a => ({
38
55
  statusCode: a.statusCode,
39
56
  error: a.error,
40
57
  latencyMs: a.latencyMs,
@@ -80,15 +97,6 @@ export class ProxyOrchestrator {
80
97
  upstreamRequest: config.upstreamRequest,
81
98
  };
82
99
  }
83
- createAbortSignal(request) {
84
- const controller = new AbortController();
85
- request.raw.on("close", () => {
86
- if (!request.raw.readableEnded) {
87
- controller.abort();
88
- }
89
- });
90
- return controller.signal;
91
- }
92
100
  async executeResilience(config, ctx) {
93
101
  if (!ctx?.transportFn)
94
102
  throw new Error("HandleContext.transportFn is required");
@@ -16,4 +16,6 @@ export declare class TrackerScope {
16
16
  }, extractAttempts?: (result: T) => AttemptSnapshot[]): Promise<T>;
17
17
  /** 通知 tracker 请求进入/离开信号量队列,触发前端即时广播 */
18
18
  markQueued(id: string, queued: boolean): void;
19
+ /** 注册请求终止回调,代理到 RequestTracker */
20
+ registerKillCallback(id: string, callback: () => void): void;
19
21
  }
@@ -36,4 +36,8 @@ export class TrackerScope {
36
36
  markQueued(id, queued) {
37
37
  this.tracker.update(id, { queued });
38
38
  }
39
+ /** 注册请求终止回调,代理到 RequestTracker */
40
+ registerKillCallback(id, callback) {
41
+ this.tracker.registerKillCallback(id, callback);
42
+ }
39
43
  }
@@ -1 +1 @@
1
- import{$ as e,Vt as t,X as n,dt as r,mt as i,r as a,zt as o}from"./button-DIkr5-e9.js";var s=[`data-size`],c=e({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]},size:{default:`default`}},setup(e){let c=e;return(l,u)=>(r(),n(`div`,{"data-slot":`card`,"data-size":e.size,class:t(o(a)(`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))},[i(l.$slots,`default`)],10,s))}}),l=e({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let s=e;return(e,c)=>(r(),n(`div`,{"data-slot":`card-content`,class:t(o(a)(`px-4 group-data-[size=sm]/card:px-3`,s.class))},[i(e.$slots,`default`)],2))}});export{c as n,l as t};
1
+ import{$ as e,Vt as t,X as n,dt as r,mt as i,r as a,zt as o}from"./button-DNp6t9kr.js";var s=[`data-size`],c=e({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]},size:{default:`default`}},setup(e){let c=e;return(l,u)=>(r(),n(`div`,{"data-slot":`card`,"data-size":e.size,class:t(o(a)(`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))},[i(l.$slots,`default`)],10,s))}}),l=e({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let s=e;return(e,c)=>(r(),n(`div`,{"data-slot":`card-content`,class:t(o(a)(`px-4 group-data-[size=sm]/card:px-3`,s.class))},[i(e.$slots,`default`)],2))}});export{c as n,l as t};
@@ -1 +1 @@
1
- import{$ as e,Vt as t,X as n,dt as r,mt as i,r as a,zt as o}from"./button-DIkr5-e9.js";var s=e({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let s=e;return(e,c)=>(r(),n(`div`,{"data-slot":`card-header`,class:t(o(a)(`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))},[i(e.$slots,`default`)],2))}}),c=e({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let s=e;return(e,c)=>(r(),n(`div`,{"data-slot":`card-title`,class:t(o(a)(`text-base leading-snug font-medium group-data-[size=sm]/card:text-sm cn-font-heading`,s.class))},[i(e.$slots,`default`)],2))}});export{s as n,c as t};
1
+ import{$ as e,Vt as t,X as n,dt as r,mt as i,r as a,zt as o}from"./button-DNp6t9kr.js";var s=e({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let s=e;return(e,c)=>(r(),n(`div`,{"data-slot":`card-header`,class:t(o(a)(`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))},[i(e.$slots,`default`)],2))}}),c=e({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let s=e;return(e,c)=>(r(),n(`div`,{"data-slot":`card-title`,class:t(o(a)(`text-base leading-snug font-medium group-data-[size=sm]/card:text-sm cn-font-heading`,s.class))},[i(e.$slots,`default`)],2))}});export{s as n,c as t};
@@ -1 +1 @@
1
- import{$ as e,H as t,Ht as n,J as r,K as i,Q as a,U as o,Y as s,dt as c,gt as l,i as u,m as d,mt as f,o as p,ot as m,r as h,tt as g,wt as _,x as v,zt as y}from"./button-DIkr5-e9.js";import{t as b}from"./VisuallyHiddenInput-C0PhLv6-.js";import{t as x}from"./RovingFocusItem-DXXOzxYf.js";import{B as S,G as C,H as w,L as T,Y as E,nt as D,q as O}from"./index-BkaQT-Ad.js";function k(e,t){return C(e)?!1:Array.isArray(e)?e.some(e=>E(e,t)):E(e,t)}var[A,j]=O(`CheckboxGroupRoot`);function M(e){return e===`indeterminate`}function N(e){return M(e)?`indeterminate`:e?`checked`:`unchecked`}var[P,F]=O(`CheckboxRoot`),I=e({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:n}){let a=e,h=n,{forwardRef:g,currentElement:v}=p(),S=A(null),T=d(a,`modelValue`,h,{defaultValue:a.defaultValue??a.falseValue,passive:a.modelValue===void 0}),D=i(()=>S?.disabled.value||a.disabled),O=i(()=>E(T.value,a.trueValue)),j=i(()=>C(S?.modelValue.value)?T.value===`indeterminate`?`indeterminate`:O.value:k(S.modelValue.value,a.value));function P(){if(C(S?.modelValue.value))T.value===`indeterminate`?T.value=a.trueValue:T.value=O.value?a.falseValue:a.trueValue;else{let e=[...S.modelValue.value||[]];if(k(e,a.value)){let t=e.findIndex(e=>E(e,a.value));e.splice(t,1)}else e.push(a.value);S.modelValue.value=e}}let I=w(v),L=i(()=>a.id&&v.value?document.querySelector(`[for="${a.id}"]`)?.innerText:void 0);return F({disabled:D,state:j}),(e,n)=>(c(),r(l(y(S)?.rovingFocus.value?y(x):y(u)),m(e.$attrs,{id:e.id,ref:y(g),role:`checkbox`,"as-child":e.asChild,as:e.as,type:e.as===`button`?`button`:void 0,"aria-checked":y(M)(j.value)?`mixed`:j.value,"aria-required":e.required,"aria-label":e.$attrs[`aria-label`]||L.value,"data-state":y(N)(j.value),"data-disabled":D.value?``:void 0,disabled:D.value,focusable:y(S)?.rovingFocus.value?!D.value:void 0,onKeydown:t(o(()=>{},[`prevent`]),[`enter`]),onClick:P}),{default:_(()=>[f(e.$slots,`default`,{modelValue:y(T),state:j.value}),y(I)&&e.name&&!y(S)?(c(),r(y(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`])):s(`v-if`,!0)]),_:3},16,[`id`,`as-child`,`as`,`type`,`aria-checked`,`aria-required`,`aria-label`,`data-state`,`data-disabled`,`disabled`,`focusable`,`onKeydown`]))}}),L=e({__name:`CheckboxIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let{forwardRef:t}=p(),n=P();return(e,i)=>(c(),r(y(T),{present:e.forceMount||y(M)(y(n).state.value)||y(n).state.value===!0},{default:_(()=>[a(y(u),m({ref:y(t),"data-state":y(N)(y(n).state.value),"data-disabled":y(n).disabled.value?``:void 0,style:{pointerEvents:`none`},"as-child":e.asChild,as:e.as},e.$attrs),{default:_(()=>[f(e.$slots,`default`)]),_:3},16,[`data-state`,`data-disabled`,`as-child`,`as`])]),_:3},8,[`present`]))}}),R=e({__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(e,{emit:t}){let i=e,o=t,s=S(v(i,`class`),o);return(e,t)=>(c(),r(y(I),m({"data-slot":`checkbox`},y(s),{class:y(h)(`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`,i.class)}),{default:_(t=>[a(y(L),{"data-slot":`checkbox-indicator`,class:`[&>svg]:size-3.5 grid place-content-center text-current transition-none`},{default:_(()=>[f(e.$slots,`default`,n(g(t)),()=>[a(y(D))])]),_:2},1024)]),_:3},16,[`class`]))}});export{R as t};
1
+ import{$ as e,H as t,Ht as n,J as r,K as i,Q as a,U as o,Y as s,dt as c,gt as l,i as u,m as d,mt as f,o as p,ot as m,r as h,tt as g,wt as _,x as v,zt as y}from"./button-DNp6t9kr.js";import{t as b}from"./VisuallyHiddenInput-D1bFtdXQ.js";import{t as x}from"./RovingFocusItem-CdltOaZP.js";import{B as S,G as C,H as w,L as T,Y as E,nt as D,q as O}from"./index-DXl9LuoU.js";function k(e,t){return C(e)?!1:Array.isArray(e)?e.some(e=>E(e,t)):E(e,t)}var[A,j]=O(`CheckboxGroupRoot`);function M(e){return e===`indeterminate`}function N(e){return M(e)?`indeterminate`:e?`checked`:`unchecked`}var[P,F]=O(`CheckboxRoot`),I=e({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:n}){let a=e,h=n,{forwardRef:g,currentElement:v}=p(),S=A(null),T=d(a,`modelValue`,h,{defaultValue:a.defaultValue??a.falseValue,passive:a.modelValue===void 0}),D=i(()=>S?.disabled.value||a.disabled),O=i(()=>E(T.value,a.trueValue)),j=i(()=>C(S?.modelValue.value)?T.value===`indeterminate`?`indeterminate`:O.value:k(S.modelValue.value,a.value));function P(){if(C(S?.modelValue.value))T.value===`indeterminate`?T.value=a.trueValue:T.value=O.value?a.falseValue:a.trueValue;else{let e=[...S.modelValue.value||[]];if(k(e,a.value)){let t=e.findIndex(e=>E(e,a.value));e.splice(t,1)}else e.push(a.value);S.modelValue.value=e}}let I=w(v),L=i(()=>a.id&&v.value?document.querySelector(`[for="${a.id}"]`)?.innerText:void 0);return F({disabled:D,state:j}),(e,n)=>(c(),r(l(y(S)?.rovingFocus.value?y(x):y(u)),m(e.$attrs,{id:e.id,ref:y(g),role:`checkbox`,"as-child":e.asChild,as:e.as,type:e.as===`button`?`button`:void 0,"aria-checked":y(M)(j.value)?`mixed`:j.value,"aria-required":e.required,"aria-label":e.$attrs[`aria-label`]||L.value,"data-state":y(N)(j.value),"data-disabled":D.value?``:void 0,disabled:D.value,focusable:y(S)?.rovingFocus.value?!D.value:void 0,onKeydown:t(o(()=>{},[`prevent`]),[`enter`]),onClick:P}),{default:_(()=>[f(e.$slots,`default`,{modelValue:y(T),state:j.value}),y(I)&&e.name&&!y(S)?(c(),r(y(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`])):s(`v-if`,!0)]),_:3},16,[`id`,`as-child`,`as`,`type`,`aria-checked`,`aria-required`,`aria-label`,`data-state`,`data-disabled`,`disabled`,`focusable`,`onKeydown`]))}}),L=e({__name:`CheckboxIndicator`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`span`}},setup(e){let{forwardRef:t}=p(),n=P();return(e,i)=>(c(),r(y(T),{present:e.forceMount||y(M)(y(n).state.value)||y(n).state.value===!0},{default:_(()=>[a(y(u),m({ref:y(t),"data-state":y(N)(y(n).state.value),"data-disabled":y(n).disabled.value?``:void 0,style:{pointerEvents:`none`},"as-child":e.asChild,as:e.as},e.$attrs),{default:_(()=>[f(e.$slots,`default`)]),_:3},16,[`data-state`,`data-disabled`,`as-child`,`as`])]),_:3},8,[`present`]))}}),R=e({__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(e,{emit:t}){let i=e,o=t,s=S(v(i,`class`),o);return(e,t)=>(c(),r(y(I),m({"data-slot":`checkbox`},y(s),{class:y(h)(`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`,i.class)}),{default:_(t=>[a(y(L),{"data-slot":`checkbox-indicator`,class:`[&>svg]:size-3.5 grid place-content-center text-current transition-none`},{default:_(()=>[f(e.$slots,`default`,n(g(t)),()=>[a(y(D))])]),_:2},1024)]),_:3},16,[`class`]))}});export{R as t};
@@ -1 +1 @@
1
- import{$ as e,Ht as t,J as n,K as r,Lt as i,Mt as a,Q as o,Y as s,d as c,dt as l,i as u,lt as d,m as f,mt as p,o as m,ot as h,st as g,tt as _,wt as v,xt as y,zt as b}from"./button-DIkr5-e9.js";import{B as x,L as S,q as C,z as w}from"./index-BkaQT-Ad.js";var[T,E]=C(`CollapsibleRoot`),D=e({__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 a=e,o=f(a,`open`,r,{defaultValue:a.defaultOpen,passive:a.open===void 0}),{disabled:s,unmountOnHide:c}=i(a);return E({contentId:``,disabled:s,open:o,unmountOnHide:c,onOpenToggle:()=>{s.value||(o.value=!o.value)}}),t({open:o}),m(),(e,t)=>(l(),n(b(u),{as:e.as,"as-child":a.asChild,"data-state":b(o)?`open`:`closed`,"data-disabled":b(s)?``:void 0},{default:v(()=>[p(e.$slots,`default`,{open:b(o)})]),_:3},8,[`as`,`as-child`,`data-state`,`data-disabled`]))}}),O=e({inheritAttrs:!1,__name:`CollapsibleContent`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`contentFound`],setup(e,{emit:t}){let i=e,f=t,_=T();_.contentId||=w(void 0,`reka-collapsible-content`);let x=a(),{forwardRef:C,currentElement:E}=m(),D=a(0),O=a(0),k=r(()=>_.open.value),A=a(k.value),j=a();y(()=>[k.value,x.value?.present],async()=>{await g();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=r(()=>A.value&&_.open.value);return d(()=>{requestAnimationFrame(()=>{A.value=!1})}),c(E,`beforematch`,e=>{requestAnimationFrame(()=>{_.onOpenToggle(),f(`contentFound`)})}),(e,t)=>(l(),n(b(S),{ref_key:`presentRef`,ref:x,present:e.forceMount||b(_).open.value,"force-mount":!0},{default:v(({present:t})=>[o(b(u),h(e.$attrs,{id:b(_).contentId,ref:b(C),"as-child":i.asChild,as:e.as,hidden:t?void 0:b(_).unmountOnHide.value?``:`until-found`,"data-state":M.value?void 0:b(_).open.value?`open`:`closed`,"data-disabled":b(_).disabled?.value?``:void 0,style:{"--reka-collapsible-content-height":`${O.value}px`,"--reka-collapsible-content-width":`${D.value}px`}}),{default:v(()=>[!b(_).unmountOnHide.value||t?p(e.$slots,`default`,{key:0}):s(`v-if`,!0)]),_:2},1040,[`id`,`as-child`,`as`,`hidden`,`data-state`,`data-disabled`,`style`])]),_:3},8,[`present`]))}}),k=e({__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:r}){let i=x(e,r);return(e,r)=>(l(),n(b(D),h({"data-slot":`collapsible`},b(i)),{default:v(n=>[p(e.$slots,`default`,t(_(n)))]),_:3},16))}}),A=e({__name:`CollapsibleContent`,props:{forceMount:{type:Boolean},asChild:{type:Boolean},as:{}},setup(e){let t=e;return(e,r)=>(l(),n(b(O),h({"data-slot":`collapsible-content`},t),{default:v(()=>[p(e.$slots,`default`)]),_:3},16))}});export{k as n,T as r,A as t};
1
+ import{$ as e,Ht as t,J as n,K as r,Lt as i,Mt as a,Q as o,Y as s,d as c,dt as l,i as u,lt as d,m as f,mt as p,o as m,ot as h,st as g,tt as _,wt as v,xt as y,zt as b}from"./button-DNp6t9kr.js";import{B as x,L as S,q as C,z as w}from"./index-DXl9LuoU.js";var[T,E]=C(`CollapsibleRoot`),D=e({__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 a=e,o=f(a,`open`,r,{defaultValue:a.defaultOpen,passive:a.open===void 0}),{disabled:s,unmountOnHide:c}=i(a);return E({contentId:``,disabled:s,open:o,unmountOnHide:c,onOpenToggle:()=>{s.value||(o.value=!o.value)}}),t({open:o}),m(),(e,t)=>(l(),n(b(u),{as:e.as,"as-child":a.asChild,"data-state":b(o)?`open`:`closed`,"data-disabled":b(s)?``:void 0},{default:v(()=>[p(e.$slots,`default`,{open:b(o)})]),_:3},8,[`as`,`as-child`,`data-state`,`data-disabled`]))}}),O=e({inheritAttrs:!1,__name:`CollapsibleContent`,props:{forceMount:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},emits:[`contentFound`],setup(e,{emit:t}){let i=e,f=t,_=T();_.contentId||=w(void 0,`reka-collapsible-content`);let x=a(),{forwardRef:C,currentElement:E}=m(),D=a(0),O=a(0),k=r(()=>_.open.value),A=a(k.value),j=a();y(()=>[k.value,x.value?.present],async()=>{await g();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=r(()=>A.value&&_.open.value);return d(()=>{requestAnimationFrame(()=>{A.value=!1})}),c(E,`beforematch`,e=>{requestAnimationFrame(()=>{_.onOpenToggle(),f(`contentFound`)})}),(e,t)=>(l(),n(b(S),{ref_key:`presentRef`,ref:x,present:e.forceMount||b(_).open.value,"force-mount":!0},{default:v(({present:t})=>[o(b(u),h(e.$attrs,{id:b(_).contentId,ref:b(C),"as-child":i.asChild,as:e.as,hidden:t?void 0:b(_).unmountOnHide.value?``:`until-found`,"data-state":M.value?void 0:b(_).open.value?`open`:`closed`,"data-disabled":b(_).disabled?.value?``:void 0,style:{"--reka-collapsible-content-height":`${O.value}px`,"--reka-collapsible-content-width":`${D.value}px`}}),{default:v(()=>[!b(_).unmountOnHide.value||t?p(e.$slots,`default`,{key:0}):s(`v-if`,!0)]),_:2},1040,[`id`,`as-child`,`as`,`hidden`,`data-state`,`data-disabled`,`style`])]),_:3},8,[`present`]))}}),k=e({__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:r}){let i=x(e,r);return(e,r)=>(l(),n(b(D),h({"data-slot":`collapsible`},b(i)),{default:v(n=>[p(e.$slots,`default`,t(_(n)))]),_:3},16))}}),A=e({__name:`CollapsibleContent`,props:{forceMount:{type:Boolean},asChild:{type:Boolean},as:{}},setup(e){let t=e;return(e,r)=>(l(),n(b(O),h({"data-slot":`collapsible-content`},t),{default:v(()=>[p(e.$slots,`default`)]),_:3},16))}});export{k as n,T as r,A as t};
@@ -1 +1 @@
1
- import{$ as e,J as t,dt as n,i as r,mt as i,o as a,ot as o,wt as s,zt as c}from"./button-DIkr5-e9.js";import{r as l}from"./CollapsibleContent-C_hdLxxg.js";var u=e({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`}},setup(e){let o=e;a();let u=l();return(e,a)=>(n(),t(c(r),{type:e.as===`button`?`button`:void 0,as:e.as,"as-child":o.asChild,"aria-controls":c(u).contentId,"aria-expanded":c(u).open.value,"data-state":c(u).open.value?`open`:`closed`,"data-disabled":c(u).disabled?.value?``:void 0,disabled:c(u).disabled?.value,onClick:c(u).onOpenToggle},{default:s(()=>[i(e.$slots,`default`)]),_:3},8,[`type`,`as`,`as-child`,`aria-controls`,`aria-expanded`,`data-state`,`data-disabled`,`disabled`,`onClick`]))}}),d=e({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean},as:{}},setup(e){let r=e;return(e,a)=>(n(),t(c(u),o({"data-slot":`collapsible-trigger`},r),{default:s(()=>[i(e.$slots,`default`)]),_:3},16))}});export{d as t};
1
+ import{$ as e,J as t,dt as n,i as r,mt as i,o as a,ot as o,wt as s,zt as c}from"./button-DNp6t9kr.js";import{r as l}from"./CollapsibleContent-B1F8U0rL.js";var u=e({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean,required:!1},as:{type:null,required:!1,default:`button`}},setup(e){let o=e;a();let u=l();return(e,a)=>(n(),t(c(r),{type:e.as===`button`?`button`:void 0,as:e.as,"as-child":o.asChild,"aria-controls":c(u).contentId,"aria-expanded":c(u).open.value,"data-state":c(u).open.value?`open`:`closed`,"data-disabled":c(u).disabled?.value?``:void 0,disabled:c(u).disabled?.value,onClick:c(u).onOpenToggle},{default:s(()=>[i(e.$slots,`default`)]),_:3},8,[`type`,`as`,`as-child`,`aria-controls`,`aria-expanded`,`data-state`,`data-disabled`,`disabled`,`onClick`]))}}),d=e({__name:`CollapsibleTrigger`,props:{asChild:{type:Boolean},as:{}},setup(e){let r=e;return(e,a)=>(n(),t(c(u),o({"data-slot":`collapsible-trigger`},r),{default:s(()=>[i(e.$slots,`default`)]),_:3},16))}});export{d as t};