llm-simple-router 0.10.4 → 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.
Files changed (45) hide show
  1. package/dist/core/concurrency/adaptive-controller.d.ts +2 -0
  2. package/dist/core/concurrency/adaptive-controller.js +58 -36
  3. package/dist/core/concurrency/types.d.ts +3 -1
  4. package/dist/core/monitor/request-tracker.d.ts +1 -0
  5. package/dist/core/monitor/request-tracker.js +42 -4
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +1 -0
  8. package/dist/proxy/orchestration/orchestrator.js +5 -3
  9. package/frontend-dist/assets/{CardContent-B3NpaDJW.js → CardContent-B3BkvaAc.js} +1 -1
  10. package/frontend-dist/assets/{CardTitle-C-cyX3iO.js → CardTitle-_AfAmHWW.js} +1 -1
  11. package/frontend-dist/assets/{Checkbox-Gyk5KBde.js → Checkbox-Bq_JpeJR.js} +1 -1
  12. package/frontend-dist/assets/{CollapsibleContent-DMDLLq9x.js → CollapsibleContent-DqPh91QX.js} +1 -1
  13. package/frontend-dist/assets/{CollapsibleTrigger-Cuf_Ec1W.js → CollapsibleTrigger-LG3l2pdm.js} +1 -1
  14. package/frontend-dist/assets/{Dashboard-CAtXlJc5.js → Dashboard-0LPjTck9.js} +1 -1
  15. package/frontend-dist/assets/{Input-y93GdDnC.js → Input-BwMPjZew.js} +1 -1
  16. package/frontend-dist/assets/{Label-DhDyFy2K.js → Label-rIqXe61w.js} +1 -1
  17. package/frontend-dist/assets/{Login-B0Wzgfpt.js → Login-W85mNIn5.js} +1 -1
  18. package/frontend-dist/assets/{Logs-CsEVfnaw.js → Logs-ahc8KSDe.js} +1 -1
  19. package/frontend-dist/assets/{MappingEntryEditor--PH4opRr.js → MappingEntryEditor-7Kf2-J2B.js} +1 -1
  20. package/frontend-dist/assets/{ModelCard-DqPMwc7c.js → ModelCard-BfAUo6un.js} +1 -1
  21. package/frontend-dist/assets/{ModelMappings-BJdLraaJ.js → ModelMappings-BSbzeof5.js} +1 -1
  22. package/frontend-dist/assets/{Monitor-L-kxM94E.js → Monitor-dCya3SFN.js} +1 -1
  23. package/frontend-dist/assets/{Providers-Cy9Sf_PQ.js → Providers-1wDl4D_R.js} +1 -1
  24. package/frontend-dist/assets/{ProxyEnhancement-BMqjyzYh.js → ProxyEnhancement-D_IU9PcA.js} +1 -1
  25. package/frontend-dist/assets/{QuickSetup-DlGBDNqN.js → QuickSetup-xS9ROA_-.js} +1 -1
  26. package/frontend-dist/assets/{RetryRules-DgQ5Vys1.js → RetryRules-16bxf7eE.js} +1 -1
  27. package/frontend-dist/assets/{RouterKeys-2mb13vx1.js → RouterKeys-busp00XZ.js} +1 -1
  28. package/frontend-dist/assets/{RovingFocusItem-BiL81wTl.js → RovingFocusItem-CmGUQVbI.js} +1 -1
  29. package/frontend-dist/assets/{Schedules-Rj1ujFuY.js → Schedules-DIOQSB85.js} +1 -1
  30. package/frontend-dist/assets/{Settings-CAZpS-nE.js → Settings-BZ40lTsk.js} +1 -1
  31. package/frontend-dist/assets/{Setup-DPhGJve7.js → Setup-kCvg6E-U.js} +1 -1
  32. package/frontend-dist/assets/{Switch-D0zRSMEx.js → Switch-CWJEJhAE.js} +1 -1
  33. package/frontend-dist/assets/{TooltipTrigger-R37E-Tih.js → TooltipTrigger-BirqVXYf.js} +1 -1
  34. package/frontend-dist/assets/{TransformRulesForm-DngqhgRH.js → TransformRulesForm-CxfgQX02.js} +1 -1
  35. package/frontend-dist/assets/{UnifiedRequestDialog-CxKfPeEb.js → UnifiedRequestDialog-CDQ17q1s.js} +1 -1
  36. package/frontend-dist/assets/{VisuallyHiddenInput-CRpwrr9A.js → VisuallyHiddenInput-D-mGxG1B.js} +1 -1
  37. package/frontend-dist/assets/{button-BQGfqOaD.js → button-DtYZp433.js} +2 -2
  38. package/frontend-dist/assets/{copy-BGvRQjGW.js → copy-DEIL_qqy.js} +1 -1
  39. package/frontend-dist/assets/{dialog-J03VLwvc.js → dialog-CKP56XIn.js} +1 -1
  40. package/frontend-dist/assets/{index-B22b454x.js → index-CWlf_u-I.js} +2 -2
  41. package/frontend-dist/assets/{trash-2-Dtaa0BOA.js → trash-2-CYe-L1uQ.js} +1 -1
  42. package/frontend-dist/assets/{useClipboard-Doiae-Ms.js → useClipboard-DojwGFBn.js} +1 -1
  43. package/frontend-dist/assets/{useLogRetention-BjZhZJaf.js → useLogRetention-BrYP2mf7.js} +1 -1
  44. package/frontend-dist/index.html +2 -2
  45. 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
- probeActive: true,
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
- s.consecutiveSuccesses++;
84
- s.consecutiveFailures = 0;
101
+ // 冷却期内不累计成功计数
85
102
  if (Date.now() < s.cooldownUntil)
86
103
  return;
87
- if (s.consecutiveSuccesses >= SUCCESS_THRESHOLD) {
88
- if (!s.probeActive) {
89
- s.probeActive = true;
90
- s.consecutiveSuccesses = 0;
91
- const effective = Math.min(Math.max(s.currentLimit + 1, ADAPTIVE_MIN), entry.max);
92
- this.logger?.info?.({ providerId, requestId: result.requestId, prevLimit: s.currentLimit, newLimit: s.currentLimit, effectiveLimit: effective, action: "probe_open" }, "Adaptive: probe window opened");
93
- }
94
- else {
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.consecutiveSuccesses = 0;
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: 非并发问题(如 upstream 200 body error 但未命中重试规则),不触发退避
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 / HALF_DIVISOR), ADAPTIVE_MIN);
122
- s.probeActive = false;
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: COOLDOWN_MS, statusCode, action: "rate_limit_backoff" }, "Adaptive: 429 rate limit, halved concurrency and entered cooldown");
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 if (s.consecutiveFailures >= FAILURE_THRESHOLD) {
129
- const prevLimit = s.currentLimit;
130
- s.currentLimit = Math.max(s.currentLimit - DECREASE_STEP, ADAPTIVE_MIN);
131
- s.probeActive = false;
132
- s.consecutiveFailures = 0;
133
- this.syncToSemaphore(providerId);
134
- this.logger?.warn?.({ providerId, requestId: result.requestId, prevLimit, newLimit: s.currentLimit, statusCode, retryRuleMatched: result.retryRuleMatched ?? false, action: "failure_backoff" }, "Adaptive: sustained failures, decreased concurrency");
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
- // probeActive 时额外加 1 个探针槽位,但不超过 max
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
- probeActive: boolean;
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
  }
@@ -28,6 +28,7 @@ export declare class RequestTracker {
28
28
  private streamContentTimer;
29
29
  private killCallbacks;
30
30
  private killedRequests;
31
+ private completedDetails;
31
32
  /** Visible for testing */
32
33
  readonly statsAggregator: StatsAggregator;
33
34
  readonly runtimeCollector: RuntimeCollector;
@@ -20,6 +20,7 @@ export class RequestTracker {
20
20
  streamContentTimer = null;
21
21
  killCallbacks = new Map();
22
22
  killedRequests = new Set();
23
+ completedDetails = new Map();
23
24
  /** Visible for testing */
24
25
  statsAggregator;
25
26
  runtimeCollector;
@@ -105,8 +106,20 @@ export class RequestTracker {
105
106
  this.statsAggregator.recordLatency(latency);
106
107
  this.statsAggregator.recordRequest(req.providerId, req.providerName, statusCode, req.retryCount > 0, false);
107
108
  this.statsAggregator.recordProviderLatency(req.providerId, latency);
109
+ // 分离大字段到 completedDetails,recentCompleted 仅保留摘要
110
+ const { clientRequest, upstreamRequest, ...rest } = req;
111
+ if (clientRequest !== undefined || upstreamRequest !== undefined) {
112
+ this.completedDetails.set(id, { clientRequest, upstreamRequest, completedAt: now });
113
+ // completedDetails 容量保护:超过上限时移除最早条目
114
+ // Map 按插入顺序迭代,complete() 按时间顺序调用,首个 key 即最旧
115
+ if (this.completedDetails.size > RECENT_COMPLETED_MAX) {
116
+ const oldestKey = this.completedDetails.keys().next().value;
117
+ if (oldestKey !== undefined)
118
+ this.completedDetails.delete(oldestKey);
119
+ }
120
+ }
108
121
  const completed = {
109
- ...req,
122
+ ...rest,
110
123
  status: wasKilled ? "failed" : result.status,
111
124
  completedAt: now,
112
125
  attempts: result.attempts ?? req.attempts,
@@ -151,7 +164,18 @@ export class RequestTracker {
151
164
  }
152
165
  /** Public alias for API endpoint use — returns full request data including clientRequest */
153
166
  getRequestById(id) {
154
- return this.get(id);
167
+ // 1. 先从 activeMap 查找(pending 请求,完整数据)
168
+ const active = this.activeMap.get(id);
169
+ if (active)
170
+ return active;
171
+ // 2. 从 recentCompleted 查找摘要,合并 completedDetails
172
+ const completed = this.recentCompleted.find((r) => r.id === id);
173
+ if (!completed)
174
+ return undefined;
175
+ const details = this.completedDetails.get(id);
176
+ if (!details)
177
+ return completed;
178
+ return { ...completed, clientRequest: details.clientRequest, upstreamRequest: details.upstreamRequest };
155
179
  }
156
180
  /** 注册请求的终止回调,由 orchestrator 在请求开始时调用 */
157
181
  registerKillCallback(id, callback) {
@@ -213,7 +237,11 @@ export class RequestTracker {
213
237
  }
214
238
  /** 向单个客户端发送当前活跃请求快照(保留 clientRequest 以便前端即时展示) */
215
239
  sendInitialSnapshot(client) {
216
- const active = this.getActive();
240
+ const active = this.getActive().map((req) => {
241
+ const copy = { ...req };
242
+ delete copy.upstreamRequest;
243
+ return copy;
244
+ });
217
245
  const msg = `event: request_update\ndata: ${JSON.stringify(active)}\n\n`;
218
246
  try {
219
247
  if (!client.writableEnded)
@@ -280,12 +308,14 @@ export class RequestTracker {
280
308
  payload = data.map((req) => {
281
309
  const copy = { ...req };
282
310
  delete copy.clientRequest;
311
+ delete copy.upstreamRequest;
283
312
  return copy;
284
313
  });
285
314
  }
286
315
  else if ((event === "request_complete" || event === "request_start") && data && typeof data === "object") {
287
316
  const copy = { ...data };
288
317
  delete copy.clientRequest;
318
+ delete copy.upstreamRequest;
289
319
  payload = copy;
290
320
  }
291
321
  const msg = `event: ${event}\ndata: ${JSON.stringify(payload)}\n\n`;
@@ -327,7 +357,15 @@ export class RequestTracker {
327
357
  break;
328
358
  }
329
359
  }
330
- this.recentCompleted = this.recentCompleted.slice(0, Math.min(i, RECENT_COMPLETED_MAX));
360
+ // 收集被 slice 丢弃的条目 ID,同步清理 completedDetails
361
+ const trimmed = this.recentCompleted.slice(0, Math.min(i, RECENT_COMPLETED_MAX));
362
+ const trimmedIds = new Set(trimmed.map((r) => r.id));
363
+ for (const entry of this.recentCompleted) {
364
+ if (!trimmedIds.has(entry.id)) {
365
+ this.completedDetails.delete(entry.id);
366
+ }
367
+ }
368
+ this.recentCompleted = trimmed;
331
369
  }
332
370
  /** 最终一致性兜底:清理异常残留的 active 条目 */
333
371
  cleanupStaleActive() {
package/dist/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export declare function buildApp(options?: AppOptions): Promise<{
20
20
  app: FastifyInstance;
21
21
  db: Database.Database;
22
22
  usageWindowTracker: UsageWindowTracker;
23
+ tracker: RequestTracker;
23
24
  close: () => Promise<void>;
24
25
  }>;
25
26
  export declare function main(): Promise<void>;
package/dist/index.js CHANGED
@@ -363,6 +363,7 @@ export async function buildApp(options) {
363
363
  app,
364
364
  db,
365
365
  usageWindowTracker,
366
+ tracker,
366
367
  close,
367
368
  };
368
369
  }
@@ -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-BQGfqOaD.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
+ 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-BQGfqOaD.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
+ 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-BQGfqOaD.js";import{t as b}from"./VisuallyHiddenInput-CRpwrr9A.js";import{t as x}from"./RovingFocusItem-BiL81wTl.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-B22b454x.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};
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};
@@ -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-BQGfqOaD.js";import{B as x,L as S,q as C,z as w}from"./index-B22b454x.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};
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};
@@ -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-BQGfqOaD.js";import{r as l}from"./CollapsibleContent-DMDLLq9x.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};
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};