llm-simple-router 0.10.5 → 0.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/concurrency/adaptive-controller.d.ts +2 -0
- package/dist/core/concurrency/adaptive-controller.js +58 -36
- package/dist/core/concurrency/types.d.ts +3 -1
- package/dist/proxy/orchestration/orchestrator.js +5 -3
- package/frontend-dist/assets/{CardContent-CkdwrZW4.js → CardContent-B3BkvaAc.js} +1 -1
- package/frontend-dist/assets/{CardTitle-DSy7RCiB.js → CardTitle-_AfAmHWW.js} +1 -1
- package/frontend-dist/assets/{Checkbox-C3NmNtqa.js → Checkbox-Bq_JpeJR.js} +1 -1
- package/frontend-dist/assets/{CollapsibleContent-DBzDxLSb.js → CollapsibleContent-DqPh91QX.js} +1 -1
- package/frontend-dist/assets/{CollapsibleTrigger-B2f-xQJ0.js → CollapsibleTrigger-LG3l2pdm.js} +1 -1
- package/frontend-dist/assets/{Dashboard-D8wX4CUe.js → Dashboard-0LPjTck9.js} +1 -1
- package/frontend-dist/assets/{Input-CWz3gSq7.js → Input-BwMPjZew.js} +1 -1
- package/frontend-dist/assets/{Label-DtNVUGfD.js → Label-rIqXe61w.js} +1 -1
- package/frontend-dist/assets/{Login-CWveR_5r.js → Login-W85mNIn5.js} +1 -1
- package/frontend-dist/assets/{Logs-Bi1whdhz.js → Logs-ahc8KSDe.js} +1 -1
- package/frontend-dist/assets/{MappingEntryEditor-BRm2vENX.js → MappingEntryEditor-7Kf2-J2B.js} +1 -1
- package/frontend-dist/assets/{ModelCard-7k6e0d6o.js → ModelCard-BfAUo6un.js} +1 -1
- package/frontend-dist/assets/{ModelMappings-BA2biFmT.js → ModelMappings-BSbzeof5.js} +1 -1
- package/frontend-dist/assets/{Monitor-B0ZTNvv5.js → Monitor-dCya3SFN.js} +1 -1
- package/frontend-dist/assets/{Providers-62LJNLRi.js → Providers-1wDl4D_R.js} +1 -1
- package/frontend-dist/assets/{ProxyEnhancement-dcYVsc3f.js → ProxyEnhancement-D_IU9PcA.js} +1 -1
- package/frontend-dist/assets/{QuickSetup-CRcUhnmK.js → QuickSetup-xS9ROA_-.js} +1 -1
- package/frontend-dist/assets/{RetryRules-B-Yaery1.js → RetryRules-16bxf7eE.js} +1 -1
- package/frontend-dist/assets/{RouterKeys-HMyzbiSY.js → RouterKeys-busp00XZ.js} +1 -1
- package/frontend-dist/assets/{RovingFocusItem-BLxXLvHz.js → RovingFocusItem-CmGUQVbI.js} +1 -1
- package/frontend-dist/assets/{Schedules-DuXBLzKL.js → Schedules-DIOQSB85.js} +1 -1
- package/frontend-dist/assets/{Settings--oVZQg3A.js → Settings-BZ40lTsk.js} +1 -1
- package/frontend-dist/assets/{Setup-DCtJiJxI.js → Setup-kCvg6E-U.js} +1 -1
- package/frontend-dist/assets/{Switch-Cvlk-GzL.js → Switch-CWJEJhAE.js} +1 -1
- package/frontend-dist/assets/{TooltipTrigger-Caej0jjH.js → TooltipTrigger-BirqVXYf.js} +1 -1
- package/frontend-dist/assets/{TransformRulesForm-kWP-wmEh.js → TransformRulesForm-CxfgQX02.js} +1 -1
- package/frontend-dist/assets/{UnifiedRequestDialog-Vwxh-lNJ.js → UnifiedRequestDialog-CDQ17q1s.js} +1 -1
- package/frontend-dist/assets/{VisuallyHiddenInput-DVhdgqSs.js → VisuallyHiddenInput-D-mGxG1B.js} +1 -1
- package/frontend-dist/assets/{button--Qf6nmZk.js → button-DtYZp433.js} +2 -2
- package/frontend-dist/assets/{copy-DBByuQcn.js → copy-DEIL_qqy.js} +1 -1
- package/frontend-dist/assets/{dialog-MkZTr6jd.js → dialog-CKP56XIn.js} +1 -1
- package/frontend-dist/assets/{index-Bg5CP0c1.js → index-CWlf_u-I.js} +2 -2
- package/frontend-dist/assets/{trash-2-C1sEBLn-.js → trash-2-CYe-L1uQ.js} +1 -1
- package/frontend-dist/assets/{useClipboard-BQ-_hkN0.js → useClipboard-DojwGFBn.js} +1 -1
- package/frontend-dist/assets/{useLogRetention-PhhUFWsW.js → useLogRetention-BrYP2mf7.js} +1 -1
- package/frontend-dist/index.html +2 -2
- package/package.json +1 -1
|
@@ -18,6 +18,8 @@ export declare class AdaptiveController {
|
|
|
18
18
|
onRequestComplete(providerId: string, result: AdaptiveResult): void;
|
|
19
19
|
getStatus(providerId: string): AdaptiveState | undefined;
|
|
20
20
|
syncProvider(providerId: string, p: ProviderConcurrencyParams): void;
|
|
21
|
+
/** 根据当前位置和容量推导行为参数,实现水位梯度控制 */
|
|
22
|
+
private deriveProfile;
|
|
21
23
|
private transitionSuccess;
|
|
22
24
|
private transitionFailure;
|
|
23
25
|
private syncToSemaphore;
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
const SUCCESS_THRESHOLD = 3;
|
|
2
|
-
const FAILURE_THRESHOLD = 3;
|
|
3
|
-
const DECREASE_STEP = 2;
|
|
4
|
-
const COOLDOWN_MS = 30_000;
|
|
5
1
|
const RATE_LIMIT_STATUS = 429;
|
|
6
|
-
const HALF_DIVISOR = 2;
|
|
7
2
|
const HTTP_SERVER_ERROR_MIN = 500;
|
|
8
3
|
const ADAPTIVE_MIN = 1;
|
|
4
|
+
// deriveProfile 参数常量
|
|
5
|
+
const CAPACITY_LOG_BASE = 7;
|
|
6
|
+
const CLIMB_BASE = 2;
|
|
7
|
+
const CLIMB_CAPACITY_WEIGHT = 2;
|
|
8
|
+
const CLIMB_LEVEL_WEIGHT = 2;
|
|
9
|
+
const DROP_BASE = 5;
|
|
10
|
+
const DROP_CAPACITY_WEIGHT = 2;
|
|
11
|
+
const DROP_LEVEL_WEIGHT = 2;
|
|
12
|
+
const KEEP_RATIO_MIN = 0.5;
|
|
13
|
+
const COOLDOWN_BASE_MS = 10_000;
|
|
14
|
+
const COOLDOWN_LEVEL_MS = 10_000;
|
|
15
|
+
const SAFE_ZONE_DIVISOR = 2;
|
|
9
16
|
export class AdaptiveController {
|
|
10
17
|
semaphoreControl;
|
|
11
18
|
logger;
|
|
@@ -19,7 +26,7 @@ export class AdaptiveController {
|
|
|
19
26
|
this.entries.set(providerId, {
|
|
20
27
|
state: {
|
|
21
28
|
currentLimit: initialLimit,
|
|
22
|
-
|
|
29
|
+
limitReached: false,
|
|
23
30
|
consecutiveSuccesses: 0,
|
|
24
31
|
consecutiveFailures: 0,
|
|
25
32
|
cooldownUntil: 0,
|
|
@@ -78,26 +85,40 @@ export class AdaptiveController {
|
|
|
78
85
|
});
|
|
79
86
|
}
|
|
80
87
|
}
|
|
88
|
+
/** 根据当前位置和容量推导行为参数,实现水位梯度控制 */
|
|
89
|
+
deriveProfile(currentLimit, max) {
|
|
90
|
+
const level = Math.min(1, currentLimit / max);
|
|
91
|
+
const capacity = Math.min(1, Math.log2(max) / CAPACITY_LOG_BASE);
|
|
92
|
+
return {
|
|
93
|
+
climbThreshold: Math.max(CLIMB_BASE, Math.round(CLIMB_BASE + capacity * CLIMB_CAPACITY_WEIGHT + level * CLIMB_LEVEL_WEIGHT)),
|
|
94
|
+
dropThreshold: Math.max(1, Math.round(DROP_BASE - capacity * DROP_CAPACITY_WEIGHT - level * DROP_LEVEL_WEIGHT)),
|
|
95
|
+
keepRatio: currentLimit > 1 ? 1 - 1 / currentLimit : KEEP_RATIO_MIN,
|
|
96
|
+
cooldownMs: Math.round(COOLDOWN_BASE_MS + level * COOLDOWN_LEVEL_MS),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
81
99
|
transitionSuccess(providerId, entry, result) {
|
|
82
100
|
const s = entry.state;
|
|
83
|
-
|
|
84
|
-
s.consecutiveFailures = 0;
|
|
101
|
+
// 冷却期内不累计成功计数
|
|
85
102
|
if (Date.now() < s.cooldownUntil)
|
|
86
103
|
return;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
104
|
+
s.consecutiveSuccesses++;
|
|
105
|
+
s.consecutiveFailures = 0;
|
|
106
|
+
// 利用率信号:请求排过队说明 limit 被实际触及
|
|
107
|
+
if (result.wasQueued) {
|
|
108
|
+
s.limitReached = true;
|
|
109
|
+
}
|
|
110
|
+
const profile = this.deriveProfile(s.currentLimit, entry.max);
|
|
111
|
+
if (s.consecutiveSuccesses >= profile.climbThreshold) {
|
|
112
|
+
// 利用率门控:安全区(limit <= max/2) 或 limitReached 才爬升
|
|
113
|
+
const safeZone = s.currentLimit <= Math.floor(entry.max / SAFE_ZONE_DIVISOR);
|
|
114
|
+
if (safeZone || s.limitReached) {
|
|
95
115
|
const prevLimit = s.currentLimit;
|
|
96
116
|
s.currentLimit = Math.min(s.currentLimit + 1, entry.max);
|
|
97
|
-
s.
|
|
98
|
-
const effective = Math.min(Math.max(s.currentLimit + 1, ADAPTIVE_MIN), entry.max);
|
|
99
|
-
this.logger?.info?.({ providerId, requestId: result.requestId, prevLimit, newLimit: s.currentLimit, effectiveLimit: effective, max: entry.max, action: "limit_increased" }, "Adaptive: limit increased by 1");
|
|
117
|
+
this.logger?.info?.({ providerId, requestId: result.requestId, prevLimit, newLimit: s.currentLimit, action: "limit_increased" }, "Adaptive: limit increased by 1");
|
|
100
118
|
}
|
|
119
|
+
// 无论是否爬升,都重置计数周期
|
|
120
|
+
s.consecutiveSuccesses = 0;
|
|
121
|
+
s.limitReached = false;
|
|
101
122
|
this.syncToSemaphore(providerId);
|
|
102
123
|
}
|
|
103
124
|
}
|
|
@@ -105,10 +126,10 @@ export class AdaptiveController {
|
|
|
105
126
|
const statusCode = result.statusCode;
|
|
106
127
|
// 过滤非并发相关的错误:
|
|
107
128
|
// - retryRuleMatched=true → resilience 层根据重试规则判断为可重试的失败,计入退避
|
|
108
|
-
// - 429:
|
|
129
|
+
// - 429: 限流,计入退避(含信号量超时/队列满,orchestrator 统一传入 429)
|
|
109
130
|
// - 5xx: 服务端错误(可能过载),计入退避
|
|
110
131
|
// - undefined: 网络异常,计入退避
|
|
111
|
-
// - 2xx/4xx 且 retryRuleMatched!=true:
|
|
132
|
+
// - 2xx/4xx 且 retryRuleMatched!=true: 非并发问题,不触发退避
|
|
112
133
|
if (!result.retryRuleMatched && statusCode !== undefined && statusCode !== RATE_LIMIT_STATUS && statusCode < HTTP_SERVER_ERROR_MIN) {
|
|
113
134
|
this.logger?.debug?.({ providerId, statusCode, action: "failure_ignored" }, "Adaptive: non-concurrency failure ignored");
|
|
114
135
|
return;
|
|
@@ -117,31 +138,32 @@ export class AdaptiveController {
|
|
|
117
138
|
s.consecutiveFailures++;
|
|
118
139
|
s.consecutiveSuccesses = 0;
|
|
119
140
|
if (statusCode === RATE_LIMIT_STATUS) {
|
|
141
|
+
// 429 和信号量错误:丢 1 格 + 冷却
|
|
142
|
+
const profile = this.deriveProfile(s.currentLimit, entry.max);
|
|
120
143
|
const prevLimit = s.currentLimit;
|
|
121
|
-
s.currentLimit = Math.max(Math.floor(s.currentLimit
|
|
122
|
-
s.
|
|
123
|
-
s.cooldownUntil = Date.now() + COOLDOWN_MS;
|
|
144
|
+
s.currentLimit = Math.max(Math.floor(s.currentLimit * profile.keepRatio), ADAPTIVE_MIN);
|
|
145
|
+
s.cooldownUntil = Date.now() + profile.cooldownMs;
|
|
124
146
|
s.consecutiveFailures = 0;
|
|
125
147
|
this.syncToSemaphore(providerId);
|
|
126
|
-
this.logger?.warn?.({ providerId, requestId: result.requestId, prevLimit, newLimit: s.currentLimit, cooldownMs:
|
|
148
|
+
this.logger?.warn?.({ providerId, requestId: result.requestId, prevLimit, newLimit: s.currentLimit, cooldownMs: profile.cooldownMs, statusCode, action: "rate_limit_backoff" }, "Adaptive: 429/semaphore, lost 1 slot and entered cooldown");
|
|
127
149
|
}
|
|
128
|
-
else
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
s.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
150
|
+
else {
|
|
151
|
+
// 5xx / 网络错误(statusCode=undefined):连续失败退避
|
|
152
|
+
const profile = this.deriveProfile(s.currentLimit, entry.max);
|
|
153
|
+
if (s.consecutiveFailures >= profile.dropThreshold) {
|
|
154
|
+
const prevLimit = s.currentLimit;
|
|
155
|
+
s.currentLimit = Math.max(s.currentLimit - 1, ADAPTIVE_MIN);
|
|
156
|
+
s.consecutiveFailures = 0;
|
|
157
|
+
this.syncToSemaphore(providerId);
|
|
158
|
+
this.logger?.warn?.({ providerId, requestId: result.requestId, prevLimit, newLimit: s.currentLimit, statusCode, retryRuleMatched: result.retryRuleMatched ?? false, action: "failure_backoff" }, "Adaptive: sustained failures, decreased concurrency");
|
|
159
|
+
}
|
|
135
160
|
}
|
|
136
161
|
}
|
|
137
162
|
syncToSemaphore(providerId) {
|
|
138
163
|
const entry = this.entries.get(providerId);
|
|
139
164
|
if (!entry)
|
|
140
165
|
return;
|
|
141
|
-
|
|
142
|
-
const effectiveLimit = entry.state.probeActive
|
|
143
|
-
? Math.min(Math.max(entry.state.currentLimit + 1, ADAPTIVE_MIN), entry.max)
|
|
144
|
-
: Math.max(entry.state.currentLimit, ADAPTIVE_MIN);
|
|
166
|
+
const effectiveLimit = Math.max(entry.state.currentLimit, ADAPTIVE_MIN);
|
|
145
167
|
this.semaphoreControl.updateConfig(providerId, {
|
|
146
168
|
maxConcurrency: effectiveLimit,
|
|
147
169
|
queueTimeoutMs: entry.queueTimeoutMs,
|
|
@@ -7,7 +7,7 @@ export interface ConcurrencyConfig {
|
|
|
7
7
|
/** Internal state of adaptive concurrency for a provider. */
|
|
8
8
|
export interface AdaptiveState {
|
|
9
9
|
currentLimit: number;
|
|
10
|
-
|
|
10
|
+
limitReached: boolean;
|
|
11
11
|
consecutiveSuccesses: number;
|
|
12
12
|
consecutiveFailures: number;
|
|
13
13
|
cooldownUntil: number;
|
|
@@ -18,6 +18,8 @@ export interface AdaptiveResult {
|
|
|
18
18
|
statusCode?: number;
|
|
19
19
|
/** 重试规则是否匹配(resilience 层判断为可重试的失败),为 true 时忽略 statusCode 过滤 */
|
|
20
20
|
retryRuleMatched?: boolean;
|
|
21
|
+
/** 此请求是否曾经排过队 */
|
|
22
|
+
wasQueued?: boolean;
|
|
21
23
|
/** 触发此反馈的请求日志 ID,用于日志关联 */
|
|
22
24
|
requestId?: string;
|
|
23
25
|
}
|
|
@@ -31,6 +31,7 @@ export class ProxyOrchestrator {
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
const trackerReq = this.buildActiveRequest(request, config, apiType);
|
|
34
|
+
let wasEverQueued = false;
|
|
34
35
|
try {
|
|
35
36
|
const result = await this.deps.trackerScope.track(trackerReq, () => {
|
|
36
37
|
// kill 回调必须在 tracker.start() 之后注册,确保请求已在 activeMap 中
|
|
@@ -44,6 +45,7 @@ export class ProxyOrchestrator {
|
|
|
44
45
|
return this.deps.semaphoreScope.withSlot(providerId, controller.signal, () => {
|
|
45
46
|
trackerReq.queued = true;
|
|
46
47
|
this.deps.trackerScope.markQueued(trackerReq.id, true);
|
|
48
|
+
wasEverQueued = true; // 闭包捕获外层变量
|
|
47
49
|
}, () => {
|
|
48
50
|
if (trackerReq.queued) {
|
|
49
51
|
trackerReq.queued = false;
|
|
@@ -61,7 +63,7 @@ export class ProxyOrchestrator {
|
|
|
61
63
|
// 如果有重试尝试(非 throw 类型),说明 resilience 层的重试规则匹配了,
|
|
62
64
|
// 意味着这是一个"有意义的失败"——即使上游返回 200 body error 也应该计入退避
|
|
63
65
|
const retryRuleMatched = status === "failed" && result.attempts.length > 1;
|
|
64
|
-
this.deps.adaptiveController?.onRequestComplete(providerId, { success: status === "completed", statusCode, retryRuleMatched, requestId: config.trackerId });
|
|
66
|
+
this.deps.adaptiveController?.onRequestComplete(providerId, { success: status === "completed", statusCode, retryRuleMatched, requestId: config.trackerId, wasQueued: wasEverQueued });
|
|
65
67
|
this.sendResponse(reply, result.result, ctx);
|
|
66
68
|
return result;
|
|
67
69
|
}
|
|
@@ -69,11 +71,11 @@ export class ProxyOrchestrator {
|
|
|
69
71
|
if (e instanceof ProviderSwitchNeeded) {
|
|
70
72
|
const lastResult = e.lastResult;
|
|
71
73
|
const statusCode = lastResult && "statusCode" in lastResult ? lastResult.statusCode : undefined;
|
|
72
|
-
this.deps.adaptiveController?.onRequestComplete(providerId, { success: false, statusCode, retryRuleMatched: true, requestId: config.trackerId });
|
|
74
|
+
this.deps.adaptiveController?.onRequestComplete(providerId, { success: false, statusCode, retryRuleMatched: true, requestId: config.trackerId, wasQueued: wasEverQueued });
|
|
73
75
|
}
|
|
74
76
|
else if (e instanceof SemaphoreTimeoutError || e instanceof SemaphoreQueueFullError) {
|
|
75
77
|
// 信号量超时或队列满:说明并发压力大,上报给自适应控制器
|
|
76
|
-
this.deps.adaptiveController?.onRequestComplete(providerId, { success: false, requestId: config.trackerId });
|
|
78
|
+
this.deps.adaptiveController?.onRequestComplete(providerId, { success: false, statusCode: 429, requestId: config.trackerId });
|
|
77
79
|
}
|
|
78
80
|
throw e;
|
|
79
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Bt as e,Ht as t,Z as n,et as r,ft as i,ht as a,r as o}from"./button
|
|
1
|
+
import{Bt as e,Ht as t,Z as n,et as r,ft as i,ht as a,r as o}from"./button-DtYZp433.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:t(e(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:t(e(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{Bt as e,Ht as t,Z as n,et as r,ft as i,ht as a,r as o}from"./button
|
|
1
|
+
import{Bt as e,Ht as t,Z as n,et as r,ft as i,ht as a,r as o}from"./button-DtYZp433.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:t(e(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:t(e(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,Bt as t,Tt as n,U as r,Ut as i,W 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
|
|
1
|
+
import{$ as e,Bt as t,Tt as n,U as r,Ut as i,W 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-DtYZp433.js";import{t as b}from"./VisuallyHiddenInput-D-mGxG1B.js";import{t as x}from"./RovingFocusItem-CmGUQVbI.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-CWlf_u-I.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:i}){let l=e,m=i,{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,i)=>(u(),s(c(t(S)?.rovingFocus.value?t(x):t(f)),v(e.$attrs,{id:e.id,ref:t(_),role:`checkbox`,"as-child":e.asChild,as:e.as,type:e.as===`button`?`button`:void 0,"aria-checked":t(M)(j.value)?`mixed`:j.value,"aria-required":e.required,"aria-label":e.$attrs[`aria-label`]||L.value,"data-state":t(N)(j.value),"data-disabled":D.value?``:void 0,disabled:D.value,focusable:t(S)?.rovingFocus.value?!D.value:void 0,onKeydown:r(a(()=>{},[`prevent`]),[`enter`]),onClick:P}),{default:n(()=>[d(e.$slots,`default`,{modelValue:t(T),state:j.value}),t(I)&&e.name&&!t(S)?(u(),s(t(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(r){let{forwardRef:i}=h(),a=P();return(r,o)=>(u(),s(t(T),{present:r.forceMount||t(M)(t(a).state.value)||t(a).state.value===!0},{default:n(()=>[e(t(f),v({ref:t(i),"data-state":t(N)(t(a).state.value),"data-disabled":t(a).disabled.value?``:void 0,style:{pointerEvents:`none`},"as-child":r.asChild,as:r.as},r.$attrs),{default:n(()=>[d(r.$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(r,{emit:a}){let o=r,c=a,l=S(y(o,`class`),c);return(r,a)=>(u(),s(t(I),v({"data-slot":`checkbox`},t(l),{class:t(_)(`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:n(a=>[e(t(L),{"data-slot":`checkbox-indicator`,class:`[&>svg]:size-3.5 grid place-content-center text-current transition-none`},{default:n(()=>[d(r.$slots,`default`,i(m(a)),()=>[e(t(O))])]),_:2},1024)]),_:3},16,[`class`]))}});export{R as t};
|
package/frontend-dist/assets/{CollapsibleContent-DBzDxLSb.js → CollapsibleContent-DqPh91QX.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as e,Bt as t,Nt as n,Rt as r,St as i,Tt as a,Ut 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
|
|
1
|
+
import{$ as e,Bt as t,Nt as n,Rt as r,St as i,Tt as a,Ut 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-DtYZp433.js";import{B as x,L as S,q as C,z as w}from"./index-CWlf_u-I.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:n,emit:i}){let o=e,s=h(o,`open`,i,{defaultValue:o.defaultOpen,passive:o.open===void 0}),{disabled:l,unmountOnHide:u}=r(o);return E({contentId:``,disabled:l,open:s,unmountOnHide:u,onOpenToggle:()=>{l.value||(s.value=!s.value)}}),n({open:s}),_(),(e,n)=>(f(),c(t(m),{as:e.as,"as-child":o.asChild,"data-state":t(s)?`open`:`closed`,"data-disabled":t(l)?``:void 0},{default:a(()=>[p(e.$slots,`default`,{open:t(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(r,{emit:o}){let d=r,h=o,g=T();g.contentId||=w(void 0,`reka-collapsible-content`);let x=n(),{forwardRef:C,currentElement:E}=_(),D=n(0),O=n(0),k=v(()=>g.open.value),A=n(k.value),j=n();i(()=>[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`)})}),(n,r)=>(f(),c(t(S),{ref_key:`presentRef`,ref:x,present:n.forceMount||t(g).open.value,"force-mount":!0},{default:a(({present:r})=>[e(t(m),y(n.$attrs,{id:t(g).contentId,ref:t(C),"as-child":d.asChild,as:n.as,hidden:r?void 0:t(g).unmountOnHide.value?``:`until-found`,"data-state":M.value?void 0:t(g).open.value?`open`:`closed`,"data-disabled":t(g).disabled?.value?``:void 0,style:{"--reka-collapsible-content-height":`${O.value}px`,"--reka-collapsible-content-width":`${D.value}px`}}),{default:a(()=>[!t(g).unmountOnHide.value||r?p(n.$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:n}){let r=x(e,n);return(e,n)=>(f(),c(t(D),y({"data-slot":`collapsible`},t(r)),{default:a(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 n=e;return(e,r)=>(f(),c(t(O),y({"data-slot":`collapsible-content`},n),{default:a(()=>[p(e.$slots,`default`)]),_:3},16))}});export{k as n,T as r,A as t};
|
package/frontend-dist/assets/{CollapsibleTrigger-B2f-xQJ0.js → CollapsibleTrigger-LG3l2pdm.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Bt as e,Tt 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
|
|
1
|
+
import{Bt as e,Tt 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-DtYZp433.js";import{r as l}from"./CollapsibleContent-DqPh91QX.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(e(o),{type:r.as===`button`?`button`:void 0,as:r.as,"as-child":c.asChild,"aria-controls":e(u).contentId,"aria-expanded":e(u).open.value,"data-state":e(u).open.value?`open`:`closed`,"data-disabled":e(u).disabled?.value?``:void 0,disabled:e(u).disabled?.value,onClick:e(u).onOpenToggle},{default:t(()=>[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(e(u),c({"data-slot":`collapsible-trigger`},o),{default:t(()=>[a(r.$slots,`default`)]),_:3},16))}});export{d as t};
|