llm-simple-router 0.10.11 → 0.10.12

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 (50) hide show
  1. package/dist/core/monitor/types.d.ts +2 -0
  2. package/dist/core/types.d.ts +3 -0
  3. package/dist/proxy/handler/failover-loop.js +5 -3
  4. package/dist/proxy/orchestration/orchestrator.d.ts +3 -1
  5. package/dist/proxy/orchestration/orchestrator.js +1 -0
  6. package/dist/proxy/pipeline-snapshot.d.ts +2 -0
  7. package/dist/proxy/routing/mapping-resolver.js +8 -2
  8. package/dist/utils/mapping-reason-parser.d.ts +7 -0
  9. package/dist/utils/mapping-reason-parser.js +43 -0
  10. package/frontend-dist/assets/{CardContent-BinBedFB.js → CardContent-D8q9vc5O.js} +1 -1
  11. package/frontend-dist/assets/{CardTitle-DYzajCM3.js → CardTitle-yA_25649.js} +1 -1
  12. package/frontend-dist/assets/{Checkbox-BKbm21iJ.js → Checkbox-DOkFBp83.js} +1 -1
  13. package/frontend-dist/assets/{CollapsibleContent-Dec5HJHa.js → CollapsibleContent-DzBUfYYw.js} +1 -1
  14. package/frontend-dist/assets/{CollapsibleTrigger-DMwCWydb.js → CollapsibleTrigger-CHYSp36W.js} +1 -1
  15. package/frontend-dist/assets/{Dashboard-Cl-WroBl.js → Dashboard-BvYHnpcJ.js} +1 -1
  16. package/frontend-dist/assets/{Input-BM3GbnIl.js → Input-CcyqZXkU.js} +1 -1
  17. package/frontend-dist/assets/{Label-birmlOXE.js → Label-CzP8C4iz.js} +1 -1
  18. package/frontend-dist/assets/{Login-C7taA6PX.js → Login-CxzSo3yb.js} +1 -1
  19. package/frontend-dist/assets/{Logs-CK-PZhH3.js → Logs-Bxqdk7eE.js} +1 -1
  20. package/frontend-dist/assets/{MappingEntryEditor-pNMmCPFo.js → MappingEntryEditor-B1DXrpQE.js} +1 -1
  21. package/frontend-dist/assets/{ModelCard-Bq5fCmh_.js → ModelCard-CfnNmO62.js} +1 -1
  22. package/frontend-dist/assets/{ModelMappings-8Udu3uKC.js → ModelMappings-BER9jpBp.js} +1 -1
  23. package/frontend-dist/assets/{Monitor-D8jwoxpP.js → Monitor-DTRiQd_f.js} +1 -1
  24. package/frontend-dist/assets/{Providers-B-7RP1SK.js → Providers-CFDV-w7E.js} +1 -1
  25. package/frontend-dist/assets/{ProxyEnhancement-CePqXqlz.js → ProxyEnhancement-DsmirUED.js} +1 -1
  26. package/frontend-dist/assets/{QuickSetup-C9s5YJIx.js → QuickSetup-Ch84omRO.js} +1 -1
  27. package/frontend-dist/assets/{RetryRules-T5erHKxg.js → RetryRules-Dp5LarPp.js} +1 -1
  28. package/frontend-dist/assets/{RouterKeys-CXFTloiI.js → RouterKeys-BAddL89X.js} +1 -1
  29. package/frontend-dist/assets/{RovingFocusItem-4aJoL5yC.js → RovingFocusItem-CRi6yQVX.js} +1 -1
  30. package/frontend-dist/assets/{Schedules-XHeewD4H.js → Schedules-C_bDqD0b.js} +1 -1
  31. package/frontend-dist/assets/{Settings-DAM3J0JW.js → Settings-Bcfiljtn.js} +1 -1
  32. package/frontend-dist/assets/{Setup-Cb9g-O9o.js → Setup-BHAW_Tm2.js} +1 -1
  33. package/frontend-dist/assets/{Switch-C7cnRCS5.js → Switch-OzhbhGwX.js} +1 -1
  34. package/frontend-dist/assets/{TooltipTrigger-C1BCMETT.js → TooltipTrigger-DOgXsxyY.js} +1 -1
  35. package/frontend-dist/assets/{TransformRulesForm-Cv_Ih3In.js → TransformRulesForm-IKRT5A3_.js} +1 -1
  36. package/frontend-dist/assets/{UnifiedRequestDialog-CBIzu-3j.js → UnifiedRequestDialog-DYS5gkoE.js} +3 -3
  37. package/frontend-dist/assets/{VisuallyHiddenInput-C9vzGFfc.js → VisuallyHiddenInput-C3oWOQXr.js} +1 -1
  38. package/frontend-dist/assets/{button-DTwl8zzX.js → button-C1QSPeLI.js} +2 -2
  39. package/frontend-dist/assets/{copy-Mm5hFXXX.js → copy-Cv_Emnxv.js} +1 -1
  40. package/frontend-dist/assets/{dialog-B8BVRE0T.js → dialog-BBGI9zKO.js} +1 -1
  41. package/frontend-dist/assets/{index-DjBiyR45.js → index-247t8K8M.js} +2 -2
  42. package/frontend-dist/assets/requestDetail-3KCtYe1N.js +1 -0
  43. package/frontend-dist/assets/requestDetail-DZ55ph4h.js +1 -0
  44. package/frontend-dist/assets/{trash-2-Blf2lMVT.js → trash-2-DtOp0hat.js} +1 -1
  45. package/frontend-dist/assets/{useClipboard-D4oejP66.js → useClipboard-Bd3JzV3b.js} +1 -1
  46. package/frontend-dist/assets/{useLogRetention-aAVdCW7-.js → useLogRetention-BrbC5bfG.js} +1 -1
  47. package/frontend-dist/index.html +2 -2
  48. package/package.json +1 -1
  49. package/frontend-dist/assets/requestDetail-DZltcrAt.js +0 -1
  50. package/frontend-dist/assets/requestDetail-NrvqHtpI.js +0 -1
@@ -1,3 +1,4 @@
1
+ import type { MappingReason } from "../types.js";
1
2
  /** Abstract SSE client interface (decouples from Node http ServerResponse). */
2
3
  export interface SSEClient {
3
4
  write(data: string): void;
@@ -35,6 +36,7 @@ export interface ActiveRequest {
35
36
  streamContent?: StreamContentSnapshot;
36
37
  clientIp?: string;
37
38
  sessionId?: string;
39
+ mappingReason?: MappingReason;
38
40
  clientRequest?: string;
39
41
  upstreamRequest?: string;
40
42
  completedAt?: number;
@@ -21,6 +21,7 @@ export interface ConcurrencyOverride {
21
21
  queue_timeout_ms?: number;
22
22
  max_queue_size?: number;
23
23
  }
24
+ export type MappingReason = "direct_format" | "group_base_rule" | "group_schedule" | "fallback_provider" | "overflow_redirect" | "failover_retry";
24
25
  export interface ResolveResult {
25
26
  target: Target;
26
27
  concurrency_override?: ConcurrencyOverride;
@@ -28,6 +29,8 @@ export interface ResolveResult {
28
29
  targetCount: number;
29
30
  /** 排除前的完整 target 列表,用于请求级缓存(BP-H2) */
30
31
  allTargets?: Target[];
32
+ /** 映射解析原因,标识走了哪条解析路径 */
33
+ mappingReason: MappingReason;
31
34
  }
32
35
  export interface MetricsResult {
33
36
  input_tokens: number | null;
@@ -150,7 +150,7 @@ export async function executeFailoverLoop(ctx, errors, deps, upstreamPath, adapt
150
150
  if (cachedTargets) {
151
151
  const filtered = filterExcluded(cachedTargets, excludeTargets);
152
152
  resolveResult = filtered.length > 0
153
- ? { target: filtered[0], concurrency_override: cachedConcurrencyOverride, targetCount: cachedTargets.length }
153
+ ? { target: filtered[0], concurrency_override: cachedConcurrencyOverride, targetCount: cachedTargets.length, mappingReason: "failover_retry" }
154
154
  : null;
155
155
  }
156
156
  else {
@@ -191,6 +191,7 @@ export async function executeFailoverLoop(ctx, errors, deps, upstreamPath, adapt
191
191
  }
192
192
  }
193
193
  // --- 溢出重定向 ---
194
+ let effectiveMappingReason = resolveResult.mappingReason;
194
195
  const overflowResult = applyOverflowRedirect(resolved, db, currentBody);
195
196
  if (overflowResult) {
196
197
  const overflowProvider = getProviderById(db, overflowResult.provider_id);
@@ -198,6 +199,7 @@ export async function executeFailoverLoop(ctx, errors, deps, upstreamPath, adapt
198
199
  resolved = { ...resolved, provider_id: overflowResult.provider_id, backend_model: overflowResult.backend_model };
199
200
  provider = overflowProvider;
200
201
  currentBody = { ...currentBody, model: overflowResult.backend_model };
202
+ effectiveMappingReason = "overflow_redirect";
201
203
  }
202
204
  }
203
205
  // 当前迭代的工具错误刷新闭包(统一 6 处调用)
@@ -210,7 +212,7 @@ export async function executeFailoverLoop(ctx, errors, deps, upstreamPath, adapt
210
212
  const needsTransform = resolvedPath.needsTransform;
211
213
  // --- routing ---
212
214
  currentBody = { ...currentBody, model: resolved.backend_model };
213
- iterationSnapshot.add({ stage: "routing", client_model: clientModel, backend_model: resolved.backend_model, provider_id: resolved.provider_id, strategy: resolveResult.targetCount > 1 ? "failover" : "scheduled" });
215
+ iterationSnapshot.add({ stage: "routing", client_model: clientModel, backend_model: resolved.backend_model, provider_id: resolved.provider_id, strategy: resolveResult.targetCount > 1 ? "failover" : "scheduled", mapping_reason: effectiveMappingReason });
214
216
  iterationSnapshot.add({ stage: "overflow", triggered: overflowResult != null });
215
217
  // --- Plugin 调整 body 和 headers ---
216
218
  const pluginResult = applyPluginAdjustments(pluginRegistry, currentBody, clientApiType, provider);
@@ -289,7 +291,7 @@ export async function executeFailoverLoop(ctx, errors, deps, upstreamPath, adapt
289
291
  const pipelineSnapshot = iterationSnapshot.toJSON();
290
292
  // --- Execute through orchestrator ---
291
293
  try {
292
- const resilienceResult = await orchestrator.handle(request, reply, clientApiType, { resolved, provider, clientModel, isStream, trackerId: logId, sessionId: ctx.metadata.get("session_id"), clientRequest: clientReq, upstreamRequest: upstreamReqBase, concurrencyOverride }, { retryBaseDelayMs: config.RETRY_BASE_DELAY_MS, isFailover, ruleMatcher: matcher, transportFn });
294
+ const resilienceResult = await orchestrator.handle(request, reply, clientApiType, { resolved, provider, clientModel, isStream, trackerId: logId, sessionId: ctx.metadata.get("session_id"), clientRequest: clientReq, upstreamRequest: upstreamReqBase, concurrencyOverride, mappingReason: effectiveMappingReason }, { retryBaseDelayMs: config.RETRY_BASE_DELAY_MS, isFailover, ruleMatcher: matcher, transportFn });
293
295
  // 日志记录
294
296
  const lastLogId = logResilienceResult(db, {
295
297
  apiType: clientApiType,
@@ -1,6 +1,6 @@
1
1
  import type { FastifyReply, FastifyRequest } from "fastify";
2
2
  import type { TransportResult } from "../types.js";
3
- import type { Target, ConcurrencyOverride } from "../../core/types.js";
3
+ import type { Target, ConcurrencyOverride, MappingReason } from "../../core/types.js";
4
4
  import type { ResilienceLayer, ResilienceResult } from "./resilience.js";
5
5
  import type { RetryRuleMatcher } from "./retry-rules.js";
6
6
  import type { SemaphoreScope } from "./scope.js";
@@ -30,6 +30,8 @@ export interface OrchestratorConfig {
30
30
  upstreamRequest?: string;
31
31
  /** Schedule 层的并发覆盖配置,覆盖 Provider 默认并发限制 */
32
32
  concurrencyOverride?: ConcurrencyOverride;
33
+ /** 映射解析原因 */
34
+ mappingReason?: MappingReason;
33
35
  }
34
36
  export interface HandleContext {
35
37
  streamTimeoutMs?: number;
@@ -97,6 +97,7 @@ export class ProxyOrchestrator {
97
97
  sessionId: config.sessionId,
98
98
  clientRequest: config.clientRequest,
99
99
  upstreamRequest: config.upstreamRequest,
100
+ mappingReason: config.mappingReason,
100
101
  };
101
102
  }
102
103
  async executeResilience(config, ctx) {
@@ -12,6 +12,7 @@ export type StageRecord = {
12
12
  backend_model: string;
13
13
  provider_id: string;
14
14
  strategy: string;
15
+ mapping_reason?: MappingReason;
15
16
  } | {
16
17
  stage: "overflow";
17
18
  triggered: boolean;
@@ -21,6 +22,7 @@ export type StageRecord = {
21
22
  stage: "provider_patch";
22
23
  types: string[];
23
24
  };
25
+ import type { MappingReason } from "../core/types.js";
24
26
  export declare class PipelineSnapshot {
25
27
  private readonly stages;
26
28
  constructor(initial?: StageRecord[]);
@@ -118,7 +118,7 @@ export function resolveMapping(db, clientModel, context) {
118
118
  if (provider) {
119
119
  const modelEntries = parseModels(provider.models);
120
120
  if (modelEntries.some(m => m.name === backendModel)) {
121
- return { target: { backend_model: backendModel, provider_id: provider.id }, targetCount: 1 };
121
+ return { target: { backend_model: backendModel, provider_id: provider.id }, targetCount: 1, mappingReason: "direct_format" };
122
122
  }
123
123
  }
124
124
  return null;
@@ -131,7 +131,7 @@ export function resolveMapping(db, clientModel, context) {
131
131
  for (const p of providers) {
132
132
  const modelEntries = parseModels(p.models);
133
133
  if (modelEntries.some(m => m.name === clientModel)) {
134
- return { target: { backend_model: clientModel, provider_id: p.id }, targetCount: 1 };
134
+ return { target: { backend_model: clientModel, provider_id: p.id }, targetCount: 1, mappingReason: "fallback_provider" };
135
135
  }
136
136
  }
137
137
  return null;
@@ -158,10 +158,15 @@ export function resolveMapping(db, clientModel, context) {
158
158
  // 5. 确定使用的 targets:schedule 优先,否则 base
159
159
  let activeTargets = baseTargets;
160
160
  let concurrencyOverride;
161
+ let mappingReason = "group_base_rule";
161
162
  if (matchedSchedule) {
162
163
  const scheduleTargets = parseScheduleTargets(matchedSchedule.mapping_rule);
164
+ // schedule 命中但 targets 解析失败时,activeTargets 仍为 base targets
165
+ // mappingReason 保持 group_base_rule(实际使用的 targets 来源)
166
+ // concurrencyOverride 来自 schedule(有意保留,schedule 控制并发上限)
163
167
  if (scheduleTargets.length > 0) {
164
168
  activeTargets = scheduleTargets;
169
+ mappingReason = "group_schedule";
165
170
  }
166
171
  concurrencyOverride = parseConcurrencyRule(matchedSchedule.concurrency_rule);
167
172
  }
@@ -174,5 +179,6 @@ export function resolveMapping(db, clientModel, context) {
174
179
  concurrency_override: concurrencyOverride,
175
180
  targetCount: activeTargets.length,
176
181
  allTargets: activeTargets,
182
+ mappingReason,
177
183
  };
178
184
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 从 pipeline_snapshot JSON 中提取映射原因。
3
+ * 优先检查 overflow stage(triggered === true → "overflow_redirect"),
4
+ * 否则取 routing stage 的 mapping_reason 字段。
5
+ * 只返回白名单中的值,避免未知的 mapping_reason 导致 i18n key 断裂。
6
+ */
7
+ export declare function parseMappingReason(snapshot: string | null | undefined): string | undefined;
@@ -0,0 +1,43 @@
1
+ const KNOWN_MAPPING_REASONS = new Set([
2
+ "direct_format",
3
+ "group_base_rule",
4
+ "group_schedule",
5
+ "fallback_provider",
6
+ "overflow_redirect",
7
+ "failover_retry",
8
+ ]);
9
+ /**
10
+ * 从 pipeline_snapshot JSON 中提取映射原因。
11
+ * 优先检查 overflow stage(triggered === true → "overflow_redirect"),
12
+ * 否则取 routing stage 的 mapping_reason 字段。
13
+ * 只返回白名单中的值,避免未知的 mapping_reason 导致 i18n key 断裂。
14
+ */
15
+ export function parseMappingReason(snapshot) {
16
+ if (!snapshot)
17
+ return undefined;
18
+ try {
19
+ const parsed = JSON.parse(snapshot);
20
+ const stages = Array.isArray(parsed)
21
+ ? parsed
22
+ : [];
23
+ if (stages.length === 0)
24
+ return undefined;
25
+ for (const stage of stages) {
26
+ if (stage.stage === "overflow" && stage.triggered === true) {
27
+ return "overflow_redirect";
28
+ }
29
+ }
30
+ for (const stage of stages) {
31
+ if (stage.stage === "routing" &&
32
+ typeof stage.mapping_reason === "string") {
33
+ return KNOWN_MAPPING_REASONS.has(stage.mapping_reason)
34
+ ? stage.mapping_reason
35
+ : undefined;
36
+ }
37
+ }
38
+ return undefined;
39
+ }
40
+ catch {
41
+ return undefined;
42
+ }
43
+ }
@@ -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-DTwl8zzX.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-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 +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-DTwl8zzX.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-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 +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-DTwl8zzX.js";import{t as b}from"./VisuallyHiddenInput-C9vzGFfc.js";import{t as x}from"./RovingFocusItem-4aJoL5yC.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-DjBiyR45.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-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 +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-DTwl8zzX.js";import{B as x,L as S,q as C,z as w}from"./index-DjBiyR45.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-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 +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-DTwl8zzX.js";import{r as l}from"./CollapsibleContent-Dec5HJHa.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-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};