@cartanova/qgrid-cli 2.4.5 → 2.4.7

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/bundle/dist/application/monit/log-buffer.js +76 -0
  2. package/bundle/dist/application/monit/monit.frame.js +86 -0
  3. package/bundle/dist/application/monit/monit.types.js +42 -0
  4. package/bundle/dist/application/qgrid/oauth.js +1 -1
  5. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +3 -3
  6. package/bundle/dist/application/qgrid/qgrid.frame.js +9 -9
  7. package/bundle/dist/application/queries.generated.js +7 -2
  8. package/bundle/dist/application/request-log/request-log.model.js +1 -1
  9. package/bundle/dist/sonamu.config.js +14 -10
  10. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +5 -2
  11. package/bundle/dist/utils/providers/anthropic/claude-session.js +3 -3
  12. package/bundle/dist/utils/providers/openai/codex-worker.js +3 -3
  13. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +8 -2
  14. package/bundle/src/application/monit/log-buffer.test.ts +121 -0
  15. package/bundle/src/application/monit/log-buffer.ts +121 -0
  16. package/bundle/src/application/monit/monit.frame.test.ts +176 -0
  17. package/bundle/src/application/monit/monit.frame.ts +77 -0
  18. package/bundle/src/application/monit/monit.types.ts +54 -0
  19. package/bundle/src/application/queries.generated.ts +8 -0
  20. package/bundle/src/application/sonamu.generated.http +12 -0
  21. package/bundle/src/sonamu.config.ts +5 -2
  22. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +5 -0
  23. package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +16 -0
  24. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +11 -0
  25. package/bundle/web-dist/client/assets/index-CYnw2kNG.js +78 -0
  26. package/bundle/web-dist/client/assets/index-yZcjDoV0.css +1 -0
  27. package/bundle/web-dist/client/assets/{logs-BMzzMMRA.js → logs-CnXIN-jp.js} +1 -1
  28. package/bundle/web-dist/client/assets/monit-DRuDGJj4.js +1 -0
  29. package/bundle/web-dist/client/assets/{routes-XqQHRGxI.js → routes-CuyNd-ya.js} +1 -1
  30. package/bundle/web-dist/client/assets/{sd.generated-WA5SGJYZ.js → sd.generated-D2Y9QeiN.js} +1 -1
  31. package/bundle/web-dist/client/assets/{services.generated-DzZLnb7S.js → services.generated-CmxXl220.js} +1 -1
  32. package/bundle/web-dist/client/assets/{show-63BsotX6.js → show-EleAOzJv.js} +3 -3
  33. package/bundle/web-dist/client/assets/{tokens-C416mWQ-.js → tokens-DxFeKC8Q.js} +1 -1
  34. package/bundle/web-dist/client/assets/use-update-token-mutation-6J1T9U2-.js +1 -0
  35. package/bundle/web-dist/client/index.html +3 -3
  36. package/bundle/web-dist/server/assets/{lazyRouteComponent-BrPAFtBA.js → lazyRouteComponent-BlfOh9S3.js} +1 -1
  37. package/bundle/web-dist/server/assets/{logs-CKM6W3W6.js → logs-DYly4ipQ.js} +3 -3
  38. package/bundle/web-dist/server/assets/monit-CYyY2S2f.js +1577 -0
  39. package/bundle/web-dist/server/assets/{routes-VY2um2KO.js → routes-Dqu3osXt.js} +4 -4
  40. package/bundle/web-dist/server/assets/{sd.generated-Cwg2f53z.js → sd.generated-CE6D5clm.js} +1 -1
  41. package/bundle/web-dist/server/assets/{services.generated-CsotZP44.js → services.generated-DyZUzXiq.js} +39 -2
  42. package/bundle/web-dist/server/assets/{show-CV2UFjaH.js → show-BDul8xLb.js} +3 -3
  43. package/bundle/web-dist/server/assets/{tokens-DfGj1y2v.js → tokens-fzMW4G74.js} +4 -4
  44. package/bundle/web-dist/server/assets/{use-update-token-mutation-BL96w-Pg.js → use-update-token-mutation-BejUW5sw.js} +1 -1
  45. package/bundle/web-dist/server/entry-server.generated.js +71 -27
  46. package/package.json +2 -2
  47. package/skills/qgrid/references/ai-sdk-provider-contract.md +25 -0
  48. package/bundle/web-dist/client/assets/index-D0dRwMp0.js +0 -78
  49. package/bundle/web-dist/client/assets/index-Dc-qeEPm.css +0 -1
  50. package/bundle/web-dist/client/assets/use-update-token-mutation-BV6msjuy.js +0 -1
@@ -0,0 +1,1577 @@
1
+ import { Z as __toESM, _ as require_jsx_runtime, c as _enum, p as require_react_dom, u as object, v as require_react } from "./sd.generated-CE6D5clm.js";
2
+ import { s as useQuery, t as MonitService } from "./services.generated-DyZUzXiq.js";
3
+ import { a as clsx, r as Route } from "../entry-server.generated.js";
4
+ //#region ../../node_modules/.pnpm/@tanstack+virtual-core@3.17.4/node_modules/@tanstack/virtual-core/dist/esm/lazy-measurements.js
5
+ var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
6
+ var import_react_dom = /* @__PURE__ */ __toESM(require_react_dom(), 1);
7
+ function createLazyMeasurementsView(count, flat, getItemKey) {
8
+ const cache = new Array(count);
9
+ return new Proxy(cache, { get(target, prop, receiver) {
10
+ if (typeof prop === "string") {
11
+ const c = prop.charCodeAt(0);
12
+ if (c >= 48 && c <= 57) {
13
+ const i = +prop;
14
+ if (Number.isInteger(i) && i >= 0 && i < count) {
15
+ let v = target[i];
16
+ if (!v) {
17
+ const s = flat[i * 2];
18
+ v = target[i] = {
19
+ index: i,
20
+ key: getItemKey(i),
21
+ start: s,
22
+ size: flat[i * 2 + 1],
23
+ end: s + flat[i * 2 + 1],
24
+ lane: 0
25
+ };
26
+ }
27
+ return v;
28
+ }
29
+ }
30
+ if (prop === "length") return count;
31
+ }
32
+ return Reflect.get(target, prop, receiver);
33
+ } });
34
+ }
35
+ //#endregion
36
+ //#region ../../node_modules/.pnpm/@tanstack+virtual-core@3.17.4/node_modules/@tanstack/virtual-core/dist/esm/utils.js
37
+ function memo(getDeps, fn, opts) {
38
+ let deps = opts.initialDeps ?? [];
39
+ let result;
40
+ let isInitial = true;
41
+ function memoizedFunction() {
42
+ var _a;
43
+ const debugEnabled = process.env.NODE_ENV !== "production" && !!opts.key && !!((_a = opts.debug) == null ? void 0 : _a.call(opts));
44
+ let depTime = 0;
45
+ if (debugEnabled) depTime = Date.now();
46
+ const newDeps = getDeps();
47
+ if (!(newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep))) return result;
48
+ deps = newDeps;
49
+ let resultTime = 0;
50
+ if (debugEnabled) resultTime = Date.now();
51
+ result = fn(...newDeps);
52
+ if (debugEnabled) {
53
+ const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;
54
+ const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;
55
+ const resultFpsPercentage = resultEndTime / 16;
56
+ const pad = (str, num) => {
57
+ str = String(str);
58
+ while (str.length < num) str = " " + str;
59
+ return str;
60
+ };
61
+ console.info(`%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`, `
62
+ font-size: .6rem;
63
+ font-weight: bold;
64
+ color: hsl(${Math.max(0, Math.min(120 - 120 * resultFpsPercentage, 120))}deg 100% 31%);`, opts == null ? void 0 : opts.key);
65
+ }
66
+ if ((opts == null ? void 0 : opts.onChange) && !(isInitial && opts.skipInitialOnChange)) opts.onChange(result);
67
+ isInitial = false;
68
+ return result;
69
+ }
70
+ memoizedFunction.updateDeps = (newDeps) => {
71
+ deps = newDeps;
72
+ };
73
+ return memoizedFunction;
74
+ }
75
+ function notUndefined(value, msg) {
76
+ if (value === void 0) throw new Error(`Unexpected undefined${msg ? `: ${msg}` : ""}`);
77
+ else return value;
78
+ }
79
+ var approxEqual = (a, b) => Math.abs(a - b) < 1.01;
80
+ var debounce = (targetWindow, fn, ms) => {
81
+ let timeoutId;
82
+ return function(...args) {
83
+ targetWindow.clearTimeout(timeoutId);
84
+ timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms);
85
+ };
86
+ };
87
+ //#endregion
88
+ //#region ../../node_modules/.pnpm/@tanstack+virtual-core@3.17.4/node_modules/@tanstack/virtual-core/dist/esm/index.js
89
+ var _isIOSResult;
90
+ var isIOSWebKit = () => {
91
+ if (_isIOSResult !== void 0) return _isIOSResult;
92
+ if (typeof navigator === "undefined") return _isIOSResult = false;
93
+ if (/iP(hone|od|ad)/.test(navigator.userAgent)) return _isIOSResult = true;
94
+ const mtp = navigator.maxTouchPoints;
95
+ return _isIOSResult = navigator.platform === "MacIntel" && mtp !== void 0 && mtp > 0;
96
+ };
97
+ var getRect = (element) => {
98
+ const { offsetWidth, offsetHeight } = element;
99
+ return {
100
+ width: offsetWidth,
101
+ height: offsetHeight
102
+ };
103
+ };
104
+ var defaultKeyExtractor = (index) => index;
105
+ var defaultRangeExtractor = (range) => {
106
+ const start = Math.max(range.startIndex - range.overscan, 0);
107
+ const len = Math.min(range.endIndex + range.overscan, range.count - 1) - start + 1;
108
+ const arr = new Array(len);
109
+ for (let i = 0; i < len; i++) arr[i] = start + i;
110
+ return arr;
111
+ };
112
+ var observeElementRect = (instance, cb) => {
113
+ const element = instance.scrollElement;
114
+ if (!element) return;
115
+ const targetWindow = instance.targetWindow;
116
+ if (!targetWindow) return;
117
+ const handler = (rect) => {
118
+ const { width, height } = rect;
119
+ cb({
120
+ width: Math.round(width),
121
+ height: Math.round(height)
122
+ });
123
+ };
124
+ handler(getRect(element));
125
+ if (!targetWindow.ResizeObserver) return () => {};
126
+ const observer = new targetWindow.ResizeObserver((entries) => {
127
+ const run = () => {
128
+ const entry = entries[0];
129
+ if (entry == null ? void 0 : entry.borderBoxSize) {
130
+ const box = entry.borderBoxSize[0];
131
+ if (box) {
132
+ handler({
133
+ width: box.inlineSize,
134
+ height: box.blockSize
135
+ });
136
+ return;
137
+ }
138
+ }
139
+ handler(getRect(element));
140
+ };
141
+ instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
142
+ });
143
+ observer.observe(element, { box: "border-box" });
144
+ return () => {
145
+ observer.unobserve(element);
146
+ };
147
+ };
148
+ var addEventListenerOptions = { passive: true };
149
+ var supportsScrollend = typeof window == "undefined" ? true : "onscrollend" in window;
150
+ var observeOffset = (instance, cb, readOffset) => {
151
+ const element = instance.scrollElement;
152
+ if (!element) return;
153
+ const targetWindow = instance.targetWindow;
154
+ if (!targetWindow) return;
155
+ const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;
156
+ let offset = 0;
157
+ const fallback = registerScrollendEvent ? null : debounce(targetWindow, () => cb(offset, false), instance.options.isScrollingResetDelay);
158
+ const createHandler = (isScrolling) => () => {
159
+ offset = readOffset(element);
160
+ fallback?.();
161
+ cb(offset, isScrolling);
162
+ };
163
+ const handler = createHandler(true);
164
+ const endHandler = createHandler(false);
165
+ element.addEventListener("scroll", handler, addEventListenerOptions);
166
+ if (registerScrollendEvent) element.addEventListener("scrollend", endHandler, addEventListenerOptions);
167
+ return () => {
168
+ element.removeEventListener("scroll", handler);
169
+ if (registerScrollendEvent) element.removeEventListener("scrollend", endHandler);
170
+ };
171
+ };
172
+ var observeElementOffset = (instance, cb) => observeOffset(instance, cb, (el) => {
173
+ const { horizontal, isRtl } = instance.options;
174
+ return horizontal ? el.scrollLeft * (isRtl && -1 || 1) : el.scrollTop;
175
+ });
176
+ var measureElement = (element, entry, instance) => {
177
+ if (instance.options.useCachedMeasurements) {
178
+ const index = instance.indexFromElement(element);
179
+ const key = instance.options.getItemKey(index);
180
+ return instance.itemSizeCache.get(key) ?? instance.options.estimateSize(index);
181
+ }
182
+ if (entry == null ? void 0 : entry.borderBoxSize) {
183
+ const box = entry.borderBoxSize[0];
184
+ if (box) return Math.round(box[instance.options.horizontal ? "inlineSize" : "blockSize"]);
185
+ }
186
+ if (!entry) {
187
+ const index = instance.indexFromElement(element);
188
+ const key = instance.options.getItemKey(index);
189
+ const cachedSize = instance.itemSizeCache.get(key);
190
+ if (cachedSize !== void 0) return cachedSize;
191
+ }
192
+ return element[instance.options.horizontal ? "offsetWidth" : "offsetHeight"];
193
+ };
194
+ var scrollWithAdjustments = (offset, { adjustments = 0, behavior }, instance) => {
195
+ var _a, _b;
196
+ (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null || _b.call(_a, {
197
+ [instance.options.horizontal ? "left" : "top"]: offset + adjustments,
198
+ behavior
199
+ });
200
+ };
201
+ var elementScroll = scrollWithAdjustments;
202
+ var Virtualizer = class {
203
+ constructor(opts) {
204
+ this.unsubs = [];
205
+ this.scrollElement = null;
206
+ this.targetWindow = null;
207
+ this.isScrolling = false;
208
+ this.scrollState = null;
209
+ this.measurementsCache = [];
210
+ this._flatMeasurements = null;
211
+ this.itemSizeCache = /* @__PURE__ */ new Map();
212
+ this.itemSizeCacheVersion = 0;
213
+ this.laneAssignments = /* @__PURE__ */ new Map();
214
+ this.pendingMin = null;
215
+ this.prevLanes = void 0;
216
+ this.lanesChangedFlag = false;
217
+ this.lanesSettling = false;
218
+ this.pendingScrollAnchor = null;
219
+ this.scrollRect = null;
220
+ this.scrollOffset = null;
221
+ this.scrollDirection = null;
222
+ this.scrollAdjustments = 0;
223
+ this._iosDeferredAdjustment = 0;
224
+ this._iosTouching = false;
225
+ this._iosJustTouchEnded = false;
226
+ this._iosTouchEndTimerId = null;
227
+ this._intendedScrollOffset = null;
228
+ this.elementsCache = /* @__PURE__ */ new Map();
229
+ this.now = () => {
230
+ var _a, _b, _c;
231
+ return ((_c = (_b = (_a = this.targetWindow) == null ? void 0 : _a.performance) == null ? void 0 : _b.now) == null ? void 0 : _c.call(_b)) ?? Date.now();
232
+ };
233
+ this.observer = /* @__PURE__ */ (() => {
234
+ let _ro = null;
235
+ const get = () => {
236
+ if (_ro) return _ro;
237
+ if (!this.targetWindow || !this.targetWindow.ResizeObserver) return null;
238
+ return _ro = new this.targetWindow.ResizeObserver((entries) => {
239
+ entries.forEach((entry) => {
240
+ const run = () => {
241
+ const node = entry.target;
242
+ const index = this.indexFromElement(node);
243
+ if (!node.isConnected) {
244
+ this.observer.unobserve(node);
245
+ for (const [cacheKey, cachedNode] of this.elementsCache) if (cachedNode === node) {
246
+ this.elementsCache.delete(cacheKey);
247
+ break;
248
+ }
249
+ return;
250
+ }
251
+ if (this.shouldMeasureDuringScroll(index)) this.resizeItem(index, this.options.measureElement(node, entry, this));
252
+ };
253
+ this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
254
+ });
255
+ });
256
+ };
257
+ return {
258
+ disconnect: () => {
259
+ var _a;
260
+ (_a = get()) == null || _a.disconnect();
261
+ _ro = null;
262
+ },
263
+ observe: (target) => {
264
+ var _a;
265
+ return (_a = get()) == null ? void 0 : _a.observe(target, { box: "border-box" });
266
+ },
267
+ unobserve: (target) => {
268
+ var _a;
269
+ return (_a = get()) == null ? void 0 : _a.unobserve(target);
270
+ }
271
+ };
272
+ })();
273
+ this.range = null;
274
+ this.setOptions = (opts2) => {
275
+ var _a, _b;
276
+ const merged = {
277
+ debug: false,
278
+ initialOffset: 0,
279
+ overscan: 1,
280
+ paddingStart: 0,
281
+ paddingEnd: 0,
282
+ scrollPaddingStart: 0,
283
+ scrollPaddingEnd: 0,
284
+ horizontal: false,
285
+ getItemKey: defaultKeyExtractor,
286
+ rangeExtractor: defaultRangeExtractor,
287
+ onChange: () => {},
288
+ measureElement,
289
+ initialRect: {
290
+ width: 0,
291
+ height: 0
292
+ },
293
+ scrollMargin: 0,
294
+ gap: 0,
295
+ indexAttribute: "data-index",
296
+ initialMeasurementsCache: [],
297
+ lanes: 1,
298
+ anchorTo: "start",
299
+ followOnAppend: false,
300
+ scrollEndThreshold: 1,
301
+ isScrollingResetDelay: 150,
302
+ enabled: true,
303
+ isRtl: false,
304
+ useScrollendEvent: false,
305
+ useAnimationFrameWithResizeObserver: false,
306
+ laneAssignmentMode: "estimate",
307
+ useCachedMeasurements: false
308
+ };
309
+ for (const key in opts2) {
310
+ const v = opts2[key];
311
+ if (v !== void 0) merged[key] = v;
312
+ }
313
+ const prevOptions = this.options;
314
+ let anchor = null;
315
+ let followOnAppend = null;
316
+ let edgeKeysChanged = false;
317
+ if (prevOptions !== void 0 && prevOptions.enabled && merged.enabled && merged.anchorTo === "end" && this.scrollElement !== null) {
318
+ const prevCount = prevOptions.count;
319
+ const nextCount = merged.count;
320
+ const measurements = this.getMeasurements();
321
+ const prevFirstKey = prevCount > 0 ? ((_a = measurements[0]) == null ? void 0 : _a.key) ?? prevOptions.getItemKey(0) : null;
322
+ const prevLastKey = prevCount > 0 ? ((_b = measurements[prevCount - 1]) == null ? void 0 : _b.key) ?? prevOptions.getItemKey(prevCount - 1) : null;
323
+ if (nextCount !== prevCount || prevCount > 0 && nextCount > 0 && (merged.getItemKey(0) !== prevFirstKey || merged.getItemKey(nextCount - 1) !== prevLastKey)) {
324
+ edgeKeysChanged = true;
325
+ const item = prevCount > 0 ? this.getVirtualItemForOffset(this.getScrollOffset()) ?? measurements[0] : null;
326
+ if (item) anchor = [item.key, this.getScrollOffset() - item.start];
327
+ const behavior = merged.followOnAppend === true ? "auto" : merged.followOnAppend || null;
328
+ if (behavior && nextCount > prevCount && this.isAtEnd(prevOptions.scrollEndThreshold) && (prevCount === 0 || merged.getItemKey(nextCount - 1) !== prevLastKey)) followOnAppend = behavior;
329
+ }
330
+ }
331
+ this.options = merged;
332
+ if (edgeKeysChanged) {
333
+ this.pendingMin = 0;
334
+ this.itemSizeCacheVersion++;
335
+ }
336
+ let anchorResolved = false;
337
+ let anchorDelta = 0;
338
+ if (anchor && this.scrollOffset !== null) {
339
+ const [anchorKey, anchorOffset] = anchor;
340
+ const newMeasurements = this.getMeasurements();
341
+ const { count, getItemKey } = this.options;
342
+ let idx = 0;
343
+ while (idx < count && getItemKey(idx) !== anchorKey) idx++;
344
+ if (idx < count) {
345
+ const anchorItem = newMeasurements[idx];
346
+ if (anchorItem) {
347
+ const newOffset = anchorItem.start + anchorOffset;
348
+ if (newOffset !== this.scrollOffset) {
349
+ anchorDelta = newOffset - this.scrollOffset;
350
+ this.scrollOffset = newOffset;
351
+ anchorResolved = true;
352
+ }
353
+ }
354
+ }
355
+ }
356
+ if (anchorResolved || followOnAppend) this.pendingScrollAnchor = [
357
+ anchorResolved ? anchor[0] : null,
358
+ anchorResolved ? anchor[1] : 0,
359
+ followOnAppend,
360
+ anchorDelta
361
+ ];
362
+ };
363
+ this.notify = (sync) => {
364
+ var _a, _b;
365
+ (_b = (_a = this.options).onChange) == null || _b.call(_a, this, sync);
366
+ };
367
+ this.maybeNotify = memo(() => {
368
+ this.calculateRange();
369
+ return [
370
+ this.isScrolling,
371
+ this.range ? this.range.startIndex : null,
372
+ this.range ? this.range.endIndex : null
373
+ ];
374
+ }, (isScrolling) => {
375
+ this.notify(isScrolling);
376
+ }, {
377
+ key: process.env.NODE_ENV !== "production" && "maybeNotify",
378
+ debug: () => this.options.debug,
379
+ initialDeps: [
380
+ this.isScrolling,
381
+ this.range ? this.range.startIndex : null,
382
+ this.range ? this.range.endIndex : null
383
+ ]
384
+ });
385
+ this.cleanup = () => {
386
+ this.unsubs.filter(Boolean).forEach((d) => d());
387
+ this.unsubs = [];
388
+ this.observer.disconnect();
389
+ if (this.rafId != null && this.targetWindow) {
390
+ this.targetWindow.cancelAnimationFrame(this.rafId);
391
+ this.rafId = null;
392
+ }
393
+ this.scrollState = null;
394
+ this._iosDeferredAdjustment = 0;
395
+ this._iosTouching = false;
396
+ this._iosJustTouchEnded = false;
397
+ this.scrollElement = null;
398
+ this.targetWindow = null;
399
+ };
400
+ this._didMount = () => {
401
+ return () => {
402
+ this.cleanup();
403
+ };
404
+ };
405
+ this._willUpdate = () => {
406
+ var _a;
407
+ const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;
408
+ if (this.scrollElement !== scrollElement) {
409
+ this.cleanup();
410
+ if (!scrollElement) {
411
+ this.maybeNotify();
412
+ return;
413
+ }
414
+ this.scrollElement = scrollElement;
415
+ if (this.scrollElement && "ownerDocument" in this.scrollElement) this.targetWindow = this.scrollElement.ownerDocument.defaultView;
416
+ else this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;
417
+ this.elementsCache.forEach((cached) => {
418
+ this.observer.observe(cached);
419
+ });
420
+ this.unsubs.push(this.options.observeElementRect(this, (rect) => {
421
+ this.scrollRect = rect;
422
+ this.maybeNotify();
423
+ }));
424
+ this.unsubs.push(this.options.observeElementOffset(this, (offset, isScrolling) => {
425
+ if (isScrolling && this._intendedScrollOffset === null && offset === this.scrollOffset) return;
426
+ if (this._intendedScrollOffset !== null && Math.abs(offset - this._intendedScrollOffset) < 1.5) offset = this._intendedScrollOffset;
427
+ this._intendedScrollOffset = null;
428
+ this.scrollAdjustments = 0;
429
+ const prevOffset = this.getScrollOffset();
430
+ this.scrollDirection = isScrolling ? prevOffset === offset ? this.scrollDirection : prevOffset < offset ? "forward" : "backward" : null;
431
+ this.scrollOffset = offset;
432
+ this.isScrolling = isScrolling;
433
+ this._flushIosDeferredIfReady();
434
+ if (this.scrollState) this.scheduleScrollReconcile();
435
+ this.maybeNotify();
436
+ }));
437
+ if ("addEventListener" in this.scrollElement) {
438
+ const scrollEl = this.scrollElement;
439
+ const onTouchStart = () => {
440
+ this._iosTouching = true;
441
+ this._iosJustTouchEnded = false;
442
+ if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {
443
+ this.targetWindow.clearTimeout(this._iosTouchEndTimerId);
444
+ this._iosTouchEndTimerId = null;
445
+ }
446
+ };
447
+ const onTouchEnd = () => {
448
+ this._iosTouching = false;
449
+ if (!isIOSWebKit() || this.targetWindow == null) return;
450
+ this._iosJustTouchEnded = true;
451
+ this._iosTouchEndTimerId = this.targetWindow.setTimeout(() => {
452
+ this._iosJustTouchEnded = false;
453
+ this._iosTouchEndTimerId = null;
454
+ this._flushIosDeferredIfReady();
455
+ }, 150);
456
+ };
457
+ scrollEl.addEventListener("touchstart", onTouchStart, addEventListenerOptions);
458
+ scrollEl.addEventListener("touchend", onTouchEnd, addEventListenerOptions);
459
+ this.unsubs.push(() => {
460
+ scrollEl.removeEventListener("touchstart", onTouchStart);
461
+ scrollEl.removeEventListener("touchend", onTouchEnd);
462
+ if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {
463
+ this.targetWindow.clearTimeout(this._iosTouchEndTimerId);
464
+ this._iosTouchEndTimerId = null;
465
+ }
466
+ });
467
+ }
468
+ this._scrollToOffset(this.getScrollOffset(), {
469
+ adjustments: void 0,
470
+ behavior: void 0
471
+ });
472
+ }
473
+ const anchor = this.pendingScrollAnchor;
474
+ this.pendingScrollAnchor = null;
475
+ if (anchor && this.scrollElement && this.options.enabled) {
476
+ const [key, _offset, followOnAppend, anchorDelta] = anchor;
477
+ if (key !== null && !followOnAppend) if (isIOSWebKit() && (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)) {
478
+ if (anchorDelta !== 0) this._iosDeferredAdjustment += anchorDelta;
479
+ } else this._scrollToOffset(this.getScrollOffset(), {
480
+ adjustments: void 0,
481
+ behavior: void 0
482
+ });
483
+ if (followOnAppend) this.scrollToEnd({ behavior: followOnAppend });
484
+ }
485
+ };
486
+ this._flushIosDeferredIfReady = () => {
487
+ if (this._iosDeferredAdjustment === 0) return;
488
+ if (this.isScrolling) return;
489
+ if (this._iosTouching) return;
490
+ if (this._iosJustTouchEnded) return;
491
+ const cur = this.getScrollOffset();
492
+ const max = this.getMaxScrollOffset();
493
+ if (cur < 0 || cur > max) return;
494
+ const delta = this._iosDeferredAdjustment;
495
+ this._iosDeferredAdjustment = 0;
496
+ this._scrollToOffset(cur, {
497
+ adjustments: this.scrollAdjustments += delta,
498
+ behavior: void 0
499
+ });
500
+ };
501
+ this.rafId = null;
502
+ this.getSize = () => {
503
+ if (!this.options.enabled) {
504
+ this.scrollRect = null;
505
+ return 0;
506
+ }
507
+ this.scrollRect = this.scrollRect ?? this.options.initialRect;
508
+ return this.scrollRect[this.options.horizontal ? "width" : "height"];
509
+ };
510
+ this.getScrollOffset = () => {
511
+ if (!this.options.enabled) {
512
+ this.scrollOffset = null;
513
+ return 0;
514
+ }
515
+ this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset === "function" ? this.options.initialOffset() : this.options.initialOffset);
516
+ return this.scrollOffset;
517
+ };
518
+ this.getMeasurementOptions = memo(() => [
519
+ this.options.count,
520
+ this.options.paddingStart,
521
+ this.options.scrollMargin,
522
+ this.options.getItemKey,
523
+ this.options.enabled,
524
+ this.options.lanes,
525
+ this.options.laneAssignmentMode,
526
+ this.options.gap
527
+ ], (count, paddingStart, scrollMargin, getItemKey, enabled, lanes, laneAssignmentMode, gap) => {
528
+ if (this.prevLanes !== void 0 && this.prevLanes !== lanes) this.lanesChangedFlag = true;
529
+ this.prevLanes = lanes;
530
+ this.pendingMin = null;
531
+ return {
532
+ count,
533
+ paddingStart,
534
+ scrollMargin,
535
+ getItemKey,
536
+ enabled,
537
+ lanes,
538
+ laneAssignmentMode,
539
+ gap
540
+ };
541
+ }, { key: false });
542
+ this.getMeasurements = memo(() => [this.getMeasurementOptions(), this.itemSizeCacheVersion], ({ count, paddingStart, scrollMargin, getItemKey, enabled, lanes, laneAssignmentMode, gap }, _itemSizeCacheVersion) => {
543
+ const itemSizeCache = this.itemSizeCache;
544
+ if (!enabled) {
545
+ this.measurementsCache = [];
546
+ this.itemSizeCache.clear();
547
+ this.laneAssignments.clear();
548
+ return [];
549
+ }
550
+ if (this.laneAssignments.size > count) {
551
+ for (const index of this.laneAssignments.keys()) if (index >= count) this.laneAssignments.delete(index);
552
+ }
553
+ if (this.lanesChangedFlag) {
554
+ this.lanesChangedFlag = false;
555
+ this.lanesSettling = true;
556
+ this.measurementsCache = [];
557
+ this.itemSizeCache.clear();
558
+ this.laneAssignments.clear();
559
+ this.pendingMin = null;
560
+ }
561
+ if (this.measurementsCache.length === 0 && !this.lanesSettling) {
562
+ this.measurementsCache = this.options.initialMeasurementsCache;
563
+ this.measurementsCache.forEach((item) => {
564
+ this.itemSizeCache.set(item.key, item.size);
565
+ });
566
+ }
567
+ const min = this.lanesSettling ? 0 : this.pendingMin ?? 0;
568
+ this.pendingMin = null;
569
+ if (this.lanesSettling && this.measurementsCache.length === count) this.lanesSettling = false;
570
+ if (lanes === 1) {
571
+ const need = count * 2;
572
+ let flat = this._flatMeasurements;
573
+ if (!flat || flat.length < need) {
574
+ const next = new Float64Array(need);
575
+ if (flat && min > 0) next.set(flat.subarray(0, min * 2));
576
+ flat = next;
577
+ this._flatMeasurements = flat;
578
+ }
579
+ let runningStart;
580
+ if (min === 0) runningStart = paddingStart + scrollMargin;
581
+ else {
582
+ const prevIdx = min - 1;
583
+ runningStart = flat[prevIdx * 2] + flat[prevIdx * 2 + 1] + gap;
584
+ }
585
+ for (let i = min; i < count; i++) {
586
+ const key = getItemKey(i);
587
+ const measuredSize = itemSizeCache.get(key);
588
+ const size = typeof measuredSize === "number" ? measuredSize : this.options.estimateSize(i);
589
+ flat[i * 2] = runningStart;
590
+ flat[i * 2 + 1] = size;
591
+ runningStart += size + gap;
592
+ }
593
+ const view = createLazyMeasurementsView(count, flat, getItemKey);
594
+ this.measurementsCache = view;
595
+ return view;
596
+ }
597
+ const measurements = this.measurementsCache.slice(0, min);
598
+ const laneLastIndex = new Array(lanes).fill(void 0);
599
+ const laneEnds = new Float64Array(lanes);
600
+ let filledLanes = 0;
601
+ for (let m = 0; m < min; m++) {
602
+ const item = measurements[m];
603
+ if (item) {
604
+ if (laneLastIndex[item.lane] === void 0) filledLanes++;
605
+ laneLastIndex[item.lane] = m;
606
+ laneEnds[item.lane] = item.end;
607
+ }
608
+ }
609
+ for (let i = min; i < count; i++) {
610
+ const key = getItemKey(i);
611
+ const cachedLane = this.laneAssignments.get(i);
612
+ let lane;
613
+ let start;
614
+ const shouldCacheLane = laneAssignmentMode === "estimate" || itemSizeCache.has(key);
615
+ if (cachedLane !== void 0 && this.options.lanes > 1) {
616
+ lane = cachedLane;
617
+ const prevIndex = laneLastIndex[lane];
618
+ const prevInLane = prevIndex !== void 0 ? measurements[prevIndex] : void 0;
619
+ start = prevInLane ? prevInLane.end + gap : paddingStart + scrollMargin;
620
+ } else if (filledLanes === lanes) {
621
+ let bestLane = 0;
622
+ let bestEnd = laneEnds[0];
623
+ let bestIdx = laneLastIndex[0];
624
+ for (let l = 1; l < lanes; l++) {
625
+ const e = laneEnds[l];
626
+ if (e < bestEnd || e === bestEnd && laneLastIndex[l] < bestIdx) {
627
+ bestLane = l;
628
+ bestEnd = e;
629
+ bestIdx = laneLastIndex[l];
630
+ }
631
+ }
632
+ lane = bestLane;
633
+ start = bestEnd + gap;
634
+ if (shouldCacheLane) this.laneAssignments.set(i, lane);
635
+ } else {
636
+ lane = i % this.options.lanes;
637
+ start = paddingStart + scrollMargin;
638
+ if (shouldCacheLane) this.laneAssignments.set(i, lane);
639
+ }
640
+ const measuredSize = itemSizeCache.get(key);
641
+ const size = typeof measuredSize === "number" ? measuredSize : this.options.estimateSize(i);
642
+ const end = start + size;
643
+ measurements[i] = {
644
+ index: i,
645
+ start,
646
+ size,
647
+ end,
648
+ key,
649
+ lane
650
+ };
651
+ if (laneLastIndex[lane] === void 0) filledLanes++;
652
+ laneLastIndex[lane] = i;
653
+ laneEnds[lane] = end;
654
+ }
655
+ this.measurementsCache = measurements;
656
+ return measurements;
657
+ }, {
658
+ key: process.env.NODE_ENV !== "production" && "getMeasurements",
659
+ debug: () => this.options.debug
660
+ });
661
+ this.calculateRange = memo(() => [
662
+ this.getMeasurements(),
663
+ this.getSize(),
664
+ this.getScrollOffset(),
665
+ this.options.lanes
666
+ ], (measurements, outerSize, scrollOffset, lanes) => {
667
+ if (measurements.length === 0 || outerSize === 0) {
668
+ this.range = null;
669
+ return null;
670
+ }
671
+ this.range = calculateRangeImpl(measurements, outerSize, scrollOffset, lanes, lanes === 1 && this._flatMeasurements != null ? this._flatMeasurements : null);
672
+ return this.range;
673
+ }, {
674
+ key: process.env.NODE_ENV !== "production" && "calculateRange",
675
+ debug: () => this.options.debug
676
+ });
677
+ this.getVirtualIndexes = memo(() => {
678
+ let startIndex = null;
679
+ let endIndex = null;
680
+ const range = this.calculateRange();
681
+ if (range) {
682
+ startIndex = range.startIndex;
683
+ endIndex = range.endIndex;
684
+ }
685
+ this.maybeNotify.updateDeps([
686
+ this.isScrolling,
687
+ startIndex,
688
+ endIndex
689
+ ]);
690
+ return [
691
+ this.options.rangeExtractor,
692
+ this.options.overscan,
693
+ this.options.count,
694
+ startIndex,
695
+ endIndex
696
+ ];
697
+ }, (rangeExtractor, overscan, count, startIndex, endIndex) => {
698
+ return startIndex === null || endIndex === null ? [] : rangeExtractor({
699
+ startIndex,
700
+ endIndex,
701
+ overscan,
702
+ count
703
+ });
704
+ }, {
705
+ key: process.env.NODE_ENV !== "production" && "getVirtualIndexes",
706
+ debug: () => this.options.debug
707
+ });
708
+ this.indexFromElement = (node) => {
709
+ const attributeName = this.options.indexAttribute;
710
+ const indexStr = node.getAttribute(attributeName);
711
+ if (!indexStr) {
712
+ console.warn(`Missing attribute name '${attributeName}={index}' on measured element.`);
713
+ return -1;
714
+ }
715
+ return parseInt(indexStr, 10);
716
+ };
717
+ this.shouldMeasureDuringScroll = (index) => {
718
+ var _a;
719
+ if (!this.scrollState || this.scrollState.behavior !== "smooth") return true;
720
+ const scrollIndex = this.scrollState.index ?? ((_a = this.getVirtualItemForOffset(this.scrollState.lastTargetOffset)) == null ? void 0 : _a.index);
721
+ if (scrollIndex !== void 0 && this.range) {
722
+ const bufferSize = Math.max(this.options.overscan, Math.ceil((this.range.endIndex - this.range.startIndex) / 2));
723
+ const minIndex = Math.max(0, scrollIndex - bufferSize);
724
+ const maxIndex = Math.min(this.options.count - 1, scrollIndex + bufferSize);
725
+ return index >= minIndex && index <= maxIndex;
726
+ }
727
+ return true;
728
+ };
729
+ this.measureElement = (node) => {
730
+ if (!node) {
731
+ this.elementsCache.forEach((cached, key2) => {
732
+ if (!cached.isConnected) {
733
+ this.observer.unobserve(cached);
734
+ this.elementsCache.delete(key2);
735
+ }
736
+ });
737
+ return;
738
+ }
739
+ const index = this.indexFromElement(node);
740
+ const key = this.options.getItemKey(index);
741
+ const prevNode = this.elementsCache.get(key);
742
+ if (prevNode !== node) {
743
+ if (prevNode) this.observer.unobserve(prevNode);
744
+ this.observer.observe(node);
745
+ this.elementsCache.set(key, node);
746
+ }
747
+ if ((!this.isScrolling || this.scrollState) && this.shouldMeasureDuringScroll(index)) this.resizeItem(index, this.options.measureElement(node, void 0, this));
748
+ };
749
+ this.resizeItem = (index, size) => {
750
+ var _a, _b;
751
+ if (index < 0 || index >= this.options.count) return;
752
+ let cachedSize;
753
+ let itemStart;
754
+ let key;
755
+ const flat = this._flatMeasurements;
756
+ if (this.options.lanes === 1 && flat !== null) {
757
+ key = this.options.getItemKey(index);
758
+ itemStart = flat[index * 2];
759
+ cachedSize = flat[index * 2 + 1];
760
+ } else {
761
+ const item = this.measurementsCache[index];
762
+ if (!item) return;
763
+ key = item.key;
764
+ itemStart = item.start;
765
+ cachedSize = item.size;
766
+ }
767
+ const delta = size - (this.itemSizeCache.get(key) ?? cachedSize);
768
+ if (delta !== 0) {
769
+ const wasAtEnd = this.options.anchorTo === "end" && ((_a = this.scrollState) == null ? void 0 : _a.behavior) !== "smooth" && this.getVirtualDistanceFromEnd() <= this.options.scrollEndThreshold;
770
+ const prevTotalSize = wasAtEnd ? this.getTotalSize() : 0;
771
+ const shouldAdjustScroll = ((_b = this.scrollState) == null ? void 0 : _b.behavior) !== "smooth" && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(this.measurementsCache[index] ?? {
772
+ index,
773
+ key,
774
+ start: itemStart,
775
+ size: cachedSize,
776
+ end: itemStart + cachedSize,
777
+ lane: 0
778
+ }, delta, this) : itemStart < this.getScrollOffset() + this.scrollAdjustments && (!this.itemSizeCache.has(key) || this.scrollDirection !== "backward"));
779
+ if (this.pendingMin === null || index < this.pendingMin) this.pendingMin = index;
780
+ this.itemSizeCache.set(key, size);
781
+ this.itemSizeCacheVersion++;
782
+ if (wasAtEnd) this.applyScrollAdjustment(this.getTotalSize() - prevTotalSize);
783
+ else if (shouldAdjustScroll) this.applyScrollAdjustment(delta);
784
+ this.notify(false);
785
+ }
786
+ };
787
+ this.getVirtualItems = memo(() => [this.getVirtualIndexes(), this.getMeasurements()], (indexes, measurements) => {
788
+ const virtualItems = [];
789
+ for (let k = 0, len = indexes.length; k < len; k++) {
790
+ const measurement = measurements[indexes[k]];
791
+ virtualItems.push(measurement);
792
+ }
793
+ return virtualItems;
794
+ }, {
795
+ key: process.env.NODE_ENV !== "production" && "getVirtualItems",
796
+ debug: () => this.options.debug
797
+ });
798
+ this.getVirtualItemForOffset = (offset) => {
799
+ const measurements = this.getMeasurements();
800
+ if (measurements.length === 0) return;
801
+ const flat = this._flatMeasurements;
802
+ const useFlat = this.options.lanes === 1 && flat != null;
803
+ return notUndefined(measurements[findNearestBinarySearch(0, measurements.length - 1, useFlat ? (i) => flat[i * 2] : (i) => notUndefined(measurements[i]).start, offset)]);
804
+ };
805
+ this.getMaxScrollOffset = () => {
806
+ if (!this.scrollElement) return 0;
807
+ if ("scrollHeight" in this.scrollElement) return this.options.horizontal ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth : this.scrollElement.scrollHeight - this.scrollElement.clientHeight;
808
+ else {
809
+ const doc = this.scrollElement.document.documentElement;
810
+ return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;
811
+ }
812
+ };
813
+ this.getVirtualDistanceFromEnd = () => {
814
+ return Math.max(this.getTotalSize() - this.getSize() - this.getScrollOffset(), 0);
815
+ };
816
+ this.getDistanceFromEnd = () => {
817
+ return Math.max(this.getMaxScrollOffset() - this.getScrollOffset(), 0);
818
+ };
819
+ this.isAtEnd = (threshold = this.options.scrollEndThreshold) => {
820
+ return this.getDistanceFromEnd() <= threshold;
821
+ };
822
+ this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {
823
+ if (!this.scrollElement) return 0;
824
+ const size = this.getSize();
825
+ const scrollOffset = this.getScrollOffset();
826
+ if (align === "auto") align = toOffset >= scrollOffset + size ? "end" : "start";
827
+ if (align === "center") toOffset += (itemSize - size) / 2;
828
+ else if (align === "end") toOffset -= size;
829
+ const maxOffset = this.getMaxScrollOffset();
830
+ return Math.max(Math.min(maxOffset, toOffset), 0);
831
+ };
832
+ this.getOffsetForIndex = (index, align = "auto") => {
833
+ index = Math.max(0, Math.min(index, this.options.count - 1));
834
+ const size = this.getSize();
835
+ const scrollOffset = this.getScrollOffset();
836
+ const item = this.measurementsCache[index];
837
+ if (!item) return;
838
+ if (align === "auto") if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) align = "end";
839
+ else if (item.start <= scrollOffset + this.options.scrollPaddingStart) align = "start";
840
+ else return [scrollOffset, align];
841
+ if (align === "end" && index === this.options.count - 1) return [this.getMaxScrollOffset(), align];
842
+ const toOffset = align === "end" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;
843
+ return [this.getOffsetForAlignment(toOffset, align, item.size), align];
844
+ };
845
+ this.scrollToOffset = (toOffset, { align = "start", behavior = "auto" } = {}) => {
846
+ const offset = this.getOffsetForAlignment(toOffset, align);
847
+ this.scrollState = {
848
+ index: null,
849
+ align,
850
+ behavior,
851
+ startedAt: this.now(),
852
+ lastTargetOffset: offset,
853
+ stableFrames: 0
854
+ };
855
+ this._scrollToOffset(offset, {
856
+ adjustments: void 0,
857
+ behavior
858
+ });
859
+ this.scheduleScrollReconcile();
860
+ };
861
+ this.scrollToIndex = (index, { align: initialAlign = "auto", behavior = "auto" } = {}) => {
862
+ index = Math.max(0, Math.min(index, this.options.count - 1));
863
+ const offsetInfo = this.getOffsetForIndex(index, initialAlign);
864
+ if (!offsetInfo) return;
865
+ const [offset, align] = offsetInfo;
866
+ const now = this.now();
867
+ this.scrollState = {
868
+ index,
869
+ align,
870
+ behavior,
871
+ startedAt: now,
872
+ lastTargetOffset: offset,
873
+ stableFrames: 0
874
+ };
875
+ this._scrollToOffset(offset, {
876
+ adjustments: void 0,
877
+ behavior
878
+ });
879
+ this.scheduleScrollReconcile();
880
+ };
881
+ this.scrollBy = (delta, { behavior = "auto" } = {}) => {
882
+ const offset = this.getScrollOffset() + delta;
883
+ this.scrollState = {
884
+ index: null,
885
+ align: "start",
886
+ behavior,
887
+ startedAt: this.now(),
888
+ lastTargetOffset: offset,
889
+ stableFrames: 0
890
+ };
891
+ this._scrollToOffset(offset, {
892
+ adjustments: void 0,
893
+ behavior
894
+ });
895
+ this.scheduleScrollReconcile();
896
+ };
897
+ this.scrollToEnd = ({ behavior = "auto" } = {}) => {
898
+ if (this.options.count > 0) {
899
+ this.scrollToIndex(this.options.count - 1, {
900
+ align: "end",
901
+ behavior
902
+ });
903
+ return;
904
+ }
905
+ this.scrollToOffset(Math.max(this.getTotalSize() - this.getSize(), 0), { behavior });
906
+ };
907
+ this.getTotalSize = () => {
908
+ var _a;
909
+ const measurements = this.getMeasurements();
910
+ let end;
911
+ if (measurements.length === 0) end = this.options.paddingStart;
912
+ else if (this.options.lanes === 1) {
913
+ const lastIdx = measurements.length - 1;
914
+ const flat = this._flatMeasurements;
915
+ if (flat != null) end = flat[lastIdx * 2] + flat[lastIdx * 2 + 1];
916
+ else end = ((_a = measurements[lastIdx]) == null ? void 0 : _a.end) ?? 0;
917
+ } else {
918
+ const endByLane = Array(this.options.lanes).fill(null);
919
+ let endIndex = measurements.length - 1;
920
+ while (endIndex >= 0 && endByLane.some((val) => val === null)) {
921
+ const item = measurements[endIndex];
922
+ if (endByLane[item.lane] === null) endByLane[item.lane] = item.end;
923
+ endIndex--;
924
+ }
925
+ end = Math.max(...endByLane.filter((val) => val !== null));
926
+ }
927
+ return Math.max(end - this.options.scrollMargin + this.options.paddingEnd, 0);
928
+ };
929
+ this.takeSnapshot = () => {
930
+ const snapshot = [];
931
+ if (this.itemSizeCache.size === 0) return snapshot;
932
+ const m = this.getMeasurements();
933
+ for (const item of m) if (item && this.itemSizeCache.has(item.key)) snapshot.push({
934
+ index: item.index,
935
+ key: item.key,
936
+ start: item.start,
937
+ size: item.size,
938
+ end: item.end,
939
+ lane: item.lane
940
+ });
941
+ return snapshot;
942
+ };
943
+ this._scrollToOffset = (offset, { adjustments, behavior }) => {
944
+ this._intendedScrollOffset = offset + (adjustments ?? 0);
945
+ this.options.scrollToFn(offset, {
946
+ behavior,
947
+ adjustments
948
+ }, this);
949
+ };
950
+ this.measure = () => {
951
+ this.pendingMin = null;
952
+ this.itemSizeCache.clear();
953
+ this.laneAssignments.clear();
954
+ this.itemSizeCacheVersion++;
955
+ this.notify(false);
956
+ };
957
+ this.setOptions(opts);
958
+ }
959
+ applyScrollAdjustment(delta, behavior) {
960
+ if (delta === 0) return;
961
+ if (process.env.NODE_ENV !== "production" && this.options.debug) console.info("correction", delta);
962
+ if (isIOSWebKit() && (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)) this._iosDeferredAdjustment += delta;
963
+ else {
964
+ this._scrollToOffset(this.getScrollOffset(), {
965
+ adjustments: this.scrollAdjustments += delta,
966
+ behavior
967
+ });
968
+ if (this.scrollOffset !== null) {
969
+ this.scrollOffset += this.scrollAdjustments;
970
+ this.scrollAdjustments = 0;
971
+ }
972
+ }
973
+ }
974
+ scheduleScrollReconcile() {
975
+ if (!this.targetWindow) {
976
+ this.scrollState = null;
977
+ return;
978
+ }
979
+ if (this.rafId != null) return;
980
+ this.rafId = this.targetWindow.requestAnimationFrame(() => {
981
+ this.rafId = null;
982
+ this.reconcileScroll();
983
+ });
984
+ }
985
+ reconcileScroll() {
986
+ if (!this.scrollState) return;
987
+ if (!this.scrollElement) return;
988
+ if (this.now() - this.scrollState.startedAt > 5e3) {
989
+ this.scrollState = null;
990
+ return;
991
+ }
992
+ const offsetInfo = this.scrollState.index != null ? this.getOffsetForIndex(this.scrollState.index, this.scrollState.align) : void 0;
993
+ const targetOffset = offsetInfo ? offsetInfo[0] : this.scrollState.lastTargetOffset;
994
+ const STABLE_FRAMES = 1;
995
+ const targetChanged = targetOffset !== this.scrollState.lastTargetOffset;
996
+ if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) {
997
+ this.scrollState.stableFrames++;
998
+ if (this.scrollState.stableFrames >= STABLE_FRAMES) {
999
+ if (this.getScrollOffset() !== targetOffset) this._scrollToOffset(targetOffset, {
1000
+ adjustments: void 0,
1001
+ behavior: "auto"
1002
+ });
1003
+ this.scrollState = null;
1004
+ return;
1005
+ }
1006
+ } else {
1007
+ this.scrollState.stableFrames = 0;
1008
+ if (targetChanged) {
1009
+ const viewport = this.getSize() || 600;
1010
+ const distance = Math.abs(targetOffset - this.getScrollOffset());
1011
+ const keepSmooth = this.scrollState.behavior === "smooth" && distance > viewport;
1012
+ this.scrollState.lastTargetOffset = targetOffset;
1013
+ if (!keepSmooth) this.scrollState.behavior = "auto";
1014
+ this._scrollToOffset(targetOffset, {
1015
+ adjustments: void 0,
1016
+ behavior: keepSmooth ? "smooth" : "auto"
1017
+ });
1018
+ }
1019
+ }
1020
+ this.scheduleScrollReconcile();
1021
+ }
1022
+ };
1023
+ var findNearestBinarySearch = (low, high, getCurrentValue, value) => {
1024
+ while (low <= high) {
1025
+ const middle = (low + high) / 2 | 0;
1026
+ const currentValue = getCurrentValue(middle);
1027
+ if (currentValue < value) low = middle + 1;
1028
+ else if (currentValue > value) high = middle - 1;
1029
+ else return middle;
1030
+ }
1031
+ if (low > 0) return low - 1;
1032
+ else return 0;
1033
+ };
1034
+ function findNearestBinarySearchFlat(flat, high, value) {
1035
+ let low = 0;
1036
+ while (low <= high) {
1037
+ const middle = (low + high) / 2 | 0;
1038
+ const currentValue = flat[middle * 2];
1039
+ if (currentValue < value) low = middle + 1;
1040
+ else if (currentValue > value) high = middle - 1;
1041
+ else return middle;
1042
+ }
1043
+ return low > 0 ? low - 1 : 0;
1044
+ }
1045
+ function calculateRangeImpl(measurements, outerSize, scrollOffset, lanes, flat) {
1046
+ const lastIndex = measurements.length - 1;
1047
+ if (measurements.length <= lanes) return {
1048
+ startIndex: 0,
1049
+ endIndex: lastIndex
1050
+ };
1051
+ if (lanes === 1 && flat !== null) {
1052
+ const startIndex2 = findNearestBinarySearchFlat(flat, lastIndex, scrollOffset);
1053
+ let endIndex2 = startIndex2;
1054
+ const limit = scrollOffset + outerSize;
1055
+ while (endIndex2 < lastIndex && flat[endIndex2 * 2] + flat[endIndex2 * 2 + 1] < limit) endIndex2++;
1056
+ return {
1057
+ startIndex: startIndex2,
1058
+ endIndex: endIndex2
1059
+ };
1060
+ }
1061
+ const getStart = (index) => measurements[index].start;
1062
+ let startIndex = findNearestBinarySearch(0, lastIndex, getStart, scrollOffset);
1063
+ let endIndex = startIndex;
1064
+ if (lanes === 1) while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) endIndex++;
1065
+ else if (lanes > 1) {
1066
+ const endPerLane = Array(lanes).fill(0);
1067
+ while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {
1068
+ const item = measurements[endIndex];
1069
+ endPerLane[item.lane] = item.end;
1070
+ endIndex++;
1071
+ }
1072
+ const startPerLane = Array(lanes).fill(scrollOffset + outerSize);
1073
+ while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {
1074
+ const item = measurements[startIndex];
1075
+ startPerLane[item.lane] = item.start;
1076
+ startIndex--;
1077
+ }
1078
+ startIndex = Math.max(0, startIndex - startIndex % lanes);
1079
+ endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));
1080
+ }
1081
+ return {
1082
+ startIndex,
1083
+ endIndex
1084
+ };
1085
+ }
1086
+ //#endregion
1087
+ //#region ../../node_modules/.pnpm/@tanstack+react-virtual@3.14.6_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@tanstack/react-virtual/dist/esm/index.js
1088
+ var useIsomorphicLayoutEffect = typeof document !== "undefined" ? import_react.useLayoutEffect : import_react.useEffect;
1089
+ function useVirtualizerBase({ useFlushSync = true, directDomUpdates = false, directDomUpdatesMode = "transform", ...options }) {
1090
+ const rerender = import_react.useReducer((x) => x + 1, 0)[1];
1091
+ const directRef = import_react.useRef({
1092
+ enabled: directDomUpdates,
1093
+ mode: directDomUpdatesMode,
1094
+ container: null,
1095
+ lastSize: null,
1096
+ lastPositions: /* @__PURE__ */ new WeakMap(),
1097
+ prevRange: null
1098
+ });
1099
+ directRef.current.enabled = directDomUpdates;
1100
+ directRef.current.mode = directDomUpdatesMode;
1101
+ const applyDirectStyles = (instance2) => {
1102
+ const state = directRef.current;
1103
+ if (!state.enabled || !state.container) return;
1104
+ const totalSize = instance2.getTotalSize();
1105
+ if (totalSize !== state.lastSize) {
1106
+ state.lastSize = totalSize;
1107
+ const sizeAxis = instance2.options.horizontal ? "width" : "height";
1108
+ state.container.style[sizeAxis] = `${totalSize}px`;
1109
+ }
1110
+ const horizontal = !!instance2.options.horizontal;
1111
+ const useTransform = state.mode === "transform";
1112
+ const posAxis = horizontal ? "left" : "top";
1113
+ const scrollMargin = instance2.options.scrollMargin;
1114
+ const items = instance2.getVirtualItems();
1115
+ for (const item of items) {
1116
+ const next = item.start - scrollMargin;
1117
+ const el = instance2.elementsCache.get(item.key);
1118
+ if (!el) continue;
1119
+ if (state.lastPositions.get(el) === next) continue;
1120
+ state.lastPositions.set(el, next);
1121
+ if (useTransform) el.style.transform = horizontal ? `translate3d(${next}px, 0, 0)` : `translate3d(0, ${next}px, 0)`;
1122
+ else el.style[posAxis] = `${next}px`;
1123
+ }
1124
+ };
1125
+ const resolvedOptions = {
1126
+ ...options,
1127
+ onChange: (instance2, sync) => {
1128
+ var _a;
1129
+ const state = directRef.current;
1130
+ let shouldRerender = true;
1131
+ if (state.enabled) {
1132
+ applyDirectStyles(instance2);
1133
+ const range = instance2.range;
1134
+ const prev = state.prevRange;
1135
+ shouldRerender = !prev || prev.isScrolling !== instance2.isScrolling || prev.startIndex !== (range == null ? void 0 : range.startIndex) || prev.endIndex !== (range == null ? void 0 : range.endIndex);
1136
+ if (shouldRerender) state.prevRange = range ? {
1137
+ startIndex: range.startIndex,
1138
+ endIndex: range.endIndex,
1139
+ isScrolling: instance2.isScrolling
1140
+ } : null;
1141
+ }
1142
+ if (shouldRerender) if (useFlushSync && sync) (0, import_react_dom.flushSync)(rerender);
1143
+ else rerender();
1144
+ (_a = options.onChange) == null || _a.call(options, instance2, sync);
1145
+ }
1146
+ };
1147
+ const [instance] = import_react.useState(() => {
1148
+ const v = new Virtualizer(resolvedOptions);
1149
+ return Object.assign(v, { containerRef: (node) => {
1150
+ const state = directRef.current;
1151
+ state.container = node;
1152
+ state.lastSize = null;
1153
+ if (node && state.enabled) {
1154
+ const total = v.getTotalSize();
1155
+ state.lastSize = total;
1156
+ const axis = v.options.horizontal ? "width" : "height";
1157
+ node.style[axis] = `${total}px`;
1158
+ }
1159
+ } });
1160
+ });
1161
+ instance.setOptions(resolvedOptions);
1162
+ useIsomorphicLayoutEffect(() => {
1163
+ return instance._didMount();
1164
+ }, []);
1165
+ useIsomorphicLayoutEffect(() => {
1166
+ return instance._willUpdate();
1167
+ });
1168
+ useIsomorphicLayoutEffect(() => {
1169
+ applyDirectStyles(instance);
1170
+ });
1171
+ return instance;
1172
+ }
1173
+ function useVirtualizer(options) {
1174
+ return useVirtualizerBase({
1175
+ observeElementRect,
1176
+ observeElementOffset,
1177
+ scrollToFn: elementScroll,
1178
+ ...options
1179
+ });
1180
+ }
1181
+ //#endregion
1182
+ //#region ~icons/lucide/refresh-cw.jsx
1183
+ var import_jsx_runtime = require_jsx_runtime();
1184
+ var lucideRefreshCw = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
1185
+ viewBox: "0 0 24 24",
1186
+ width: "1.2em",
1187
+ height: "1.2em",
1188
+ ...props,
1189
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", {
1190
+ fill: "none",
1191
+ stroke: "currentColor",
1192
+ strokeLinecap: "round",
1193
+ strokeLinejoin: "round",
1194
+ strokeWidth: 2,
1195
+ children: [
1196
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 12a9 9 0 0 1 9-9a9.75 9.75 0 0 1 6.74 2.74L21 8" }),
1197
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 3v5h-5m5 4a9 9 0 0 1-9 9a9.75 9.75 0 0 1-6.74-2.74L3 16" }),
1198
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 16H3v5" })
1199
+ ]
1200
+ })
1201
+ });
1202
+ //#endregion
1203
+ //#region src/components/qgrid/MonitConsole.tsx
1204
+ var POLL_INTERVAL_MS = 1e3;
1205
+ var STALE_AFTER_MS = 5e3;
1206
+ var MIRROR_CAP = 4e3;
1207
+ var LEVEL_RANK = {
1208
+ trace: 0,
1209
+ debug: 1,
1210
+ info: 2,
1211
+ warning: 3,
1212
+ error: 4,
1213
+ fatal: 5
1214
+ };
1215
+ var SCALING_PATTERN = /autoscale|worker/i;
1216
+ var LEVEL_LABEL = {
1217
+ trace: "TRC",
1218
+ debug: "DBG",
1219
+ info: "INF",
1220
+ warning: "WRN",
1221
+ error: "ERR",
1222
+ fatal: "FTL"
1223
+ };
1224
+ var TIME_FORMATTER = new Intl.DateTimeFormat("en-GB", {
1225
+ hour: "2-digit",
1226
+ minute: "2-digit",
1227
+ second: "2-digit",
1228
+ hour12: false
1229
+ });
1230
+ function formatTime(epochMs) {
1231
+ return TIME_FORMATTER.format(new Date(epochMs));
1232
+ }
1233
+ function categoryLabel(category) {
1234
+ return category.join("·");
1235
+ }
1236
+ function MonitConsole({ search, onSearchChange }) {
1237
+ const [items, setItems] = (0, import_react.useState)([]);
1238
+ const cursorRef = (0, import_react.useRef)(void 0);
1239
+ const epochRef = (0, import_react.useRef)(void 0);
1240
+ const keyRef = (0, import_react.useRef)(0);
1241
+ const [clock, setClock] = (0, import_react.useState)(() => Date.now());
1242
+ const query = useQuery({
1243
+ queryKey: ["Monit", "monitLogs"],
1244
+ queryFn: () => MonitService.monitLogs(cursorRef.current),
1245
+ refetchInterval: POLL_INTERVAL_MS,
1246
+ retry: false
1247
+ });
1248
+ const info = useQuery({
1249
+ ...MonitService.monitInfoQueryOptions(),
1250
+ staleTime: Infinity
1251
+ }).data;
1252
+ const vitals = query.data?.vitals;
1253
+ (0, import_react.useEffect)(() => {
1254
+ const chunk = query.data;
1255
+ if (!chunk) return;
1256
+ applyChunk(chunk);
1257
+ }, [query.data]);
1258
+ function applyChunk(chunk) {
1259
+ const nextKey = () => ++keyRef.current;
1260
+ setItems((prev) => {
1261
+ let base = prev;
1262
+ const appended = [];
1263
+ if (epochRef.current !== void 0 && chunk.processStartedAt !== epochRef.current) {
1264
+ base = [];
1265
+ appended.push({
1266
+ kind: "restart",
1267
+ key: nextKey(),
1268
+ processStartedAt: chunk.processStartedAt
1269
+ });
1270
+ } else if (chunk.dropped > 0) appended.push({
1271
+ kind: "dropped",
1272
+ key: nextKey(),
1273
+ count: chunk.dropped
1274
+ });
1275
+ epochRef.current = chunk.processStartedAt;
1276
+ cursorRef.current = chunk.nextCursor;
1277
+ const lastSeq = base.findLast((item) => item.kind === "log")?.entry.seq;
1278
+ for (const entry of chunk.entries) {
1279
+ if (lastSeq !== void 0 && entry.seq <= lastSeq) continue;
1280
+ appended.push({
1281
+ kind: "log",
1282
+ key: nextKey(),
1283
+ entry
1284
+ });
1285
+ }
1286
+ if (appended.length === 0) return prev;
1287
+ const next = [...base, ...appended];
1288
+ return next.length > MIRROR_CAP ? next.slice(-MIRROR_CAP) : next;
1289
+ });
1290
+ }
1291
+ (0, import_react.useEffect)(() => {
1292
+ const timer = window.setInterval(() => setClock(Date.now()), 2e3);
1293
+ return () => window.clearInterval(timer);
1294
+ }, []);
1295
+ const isStale = items.length > 0 && (query.isRefetchError || query.dataUpdatedAt > 0 && clock - query.dataUpdatedAt > STALE_AFTER_MS);
1296
+ const visible = (0, import_react.useMemo)(() => {
1297
+ return items.filter((item) => {
1298
+ if (item.kind !== "log") return true;
1299
+ switch (search.level) {
1300
+ case "scaling": return SCALING_PATTERN.test(item.entry.text);
1301
+ case "warn": return (LEVEL_RANK[item.entry.level] ?? 2) >= 3;
1302
+ case "error": return (LEVEL_RANK[item.entry.level] ?? 2) >= 4;
1303
+ default: return true;
1304
+ }
1305
+ });
1306
+ }, [items, search.level]);
1307
+ const parentRef = (0, import_react.useRef)(null);
1308
+ const virtualizer = useVirtualizer({
1309
+ count: visible.length,
1310
+ getScrollElement: () => parentRef.current,
1311
+ estimateSize: () => 20,
1312
+ getItemKey: (index) => visible[index].key,
1313
+ anchorTo: "end",
1314
+ followOnAppend: true,
1315
+ scrollEndThreshold: 80,
1316
+ overscan: 12
1317
+ });
1318
+ const atEnd = virtualizer.isAtEnd();
1319
+ const hasFirstData = query.dataUpdatedAt > 0;
1320
+ const firstLoadFailed = !hasFirstData && query.isError;
1321
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
1322
+ className: "panel overflow-hidden",
1323
+ children: [
1324
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
1325
+ className: "panel-header flex min-h-11 flex-wrap items-center gap-x-3 gap-y-2 px-4 py-2 sm:px-5",
1326
+ children: [
1327
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
1328
+ className: "text-[13px] font-semibold tracking-[-0.01em] text-sand-800",
1329
+ children: "Server logs"
1330
+ }),
1331
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1332
+ className: "inline-flex items-center gap-1.5 text-[11px] font-medium text-sand-700",
1333
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: clsx("size-1.5 rounded-full", isStale || firstLoadFailed ? "bg-danger-400" : "bg-sienna-500 motion-safe:animate-pulse") }), firstLoadFailed ? "Disconnected" : isStale ? "Stale" : hasFirstData ? "Live" : "…"]
1334
+ }),
1335
+ epochRef.current !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1336
+ className: "text-[11px] text-sand-500",
1337
+ children: ["ephemeral · resets on restart · since ", formatTime(epochRef.current)]
1338
+ }),
1339
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1340
+ className: "ml-auto flex flex-wrap items-center gap-2",
1341
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1342
+ className: "segmented-control inline-flex",
1343
+ role: "tablist",
1344
+ "aria-label": "Log filter",
1345
+ children: [
1346
+ {
1347
+ value: "all",
1348
+ label: "All"
1349
+ },
1350
+ {
1351
+ value: "scaling",
1352
+ label: "Scaling"
1353
+ },
1354
+ {
1355
+ value: "warn",
1356
+ label: "Warn+"
1357
+ },
1358
+ {
1359
+ value: "error",
1360
+ label: "Err+"
1361
+ }
1362
+ ].map((option) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
1363
+ type: "button",
1364
+ "data-active": search.level === option.value,
1365
+ onClick: () => onSearchChange({
1366
+ ...search,
1367
+ level: option.value
1368
+ }),
1369
+ className: "rounded-[6px] px-2.5 py-1 text-[11px] font-medium text-sand-500 transition-colors hover:text-sand-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sienna-300 data-[active=true]:text-sand-900",
1370
+ children: option.label
1371
+ }, option.value))
1372
+ })
1373
+ })
1374
+ ]
1375
+ }),
1376
+ info && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1377
+ className: "flex flex-wrap items-center gap-x-5 gap-y-1 border-b border-sand-100 bg-sand-50/60 px-4 py-2 text-[11px] text-sand-600 sm:px-5",
1378
+ children: [
1379
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: ["server ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1380
+ className: "font-mono text-sand-800",
1381
+ children: info.serverUrl
1382
+ })] }),
1383
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
1384
+ "db",
1385
+ " ",
1386
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1387
+ className: "font-mono text-sand-800",
1388
+ children: [
1389
+ info.dbHost,
1390
+ "/",
1391
+ info.dbName
1392
+ ]
1393
+ })
1394
+ ] }),
1395
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
1396
+ "workers/token",
1397
+ " ",
1398
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1399
+ className: "font-mono text-sand-800",
1400
+ children: [
1401
+ info.openai.minWorkersPerToken,
1402
+ "–",
1403
+ info.openai.maxWorkersPerToken
1404
+ ]
1405
+ }),
1406
+ " ",
1407
+ info.openai.autoscale ? "autoscale" : "fixed"
1408
+ ] }),
1409
+ vitals && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
1410
+ "openai workers",
1411
+ " ",
1412
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1413
+ className: "font-mono text-sand-800",
1414
+ children: [
1415
+ vitals.openaiReadyWorkerCount,
1416
+ "/",
1417
+ vitals.openaiWorkerCount
1418
+ ]
1419
+ }),
1420
+ " ",
1421
+ "ready"
1422
+ ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
1423
+ "queue",
1424
+ " ",
1425
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1426
+ className: clsx("font-mono", vitals.openaiQueueLength > 0 ? "font-semibold text-caution-500" : "text-sand-800"),
1427
+ children: vitals.openaiQueueLength
1428
+ })
1429
+ ] })] })
1430
+ ]
1431
+ }),
1432
+ vitals && (vitals.openaiWorkersByToken.length > 0 || vitals.anthropicTokenNames.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1433
+ className: "space-y-1.5 border-b border-sand-100 px-4 py-2.5 sm:px-5",
1434
+ children: [vitals.openaiWorkersByToken.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1435
+ className: "flex flex-wrap items-center gap-2",
1436
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1437
+ className: "w-[4.5rem] shrink-0 text-[10px] font-medium uppercase tracking-[0.08em] text-sand-400",
1438
+ children: "openai"
1439
+ }), vitals.openaiWorkersByToken.map((token) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1440
+ title: `${token.name}: ${token.count} workers`,
1441
+ className: "inline-flex items-baseline gap-1.5 rounded-md border border-sand-200 bg-white px-2 py-1",
1442
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1443
+ className: "font-mono text-[11px] text-sand-600",
1444
+ children: token.name.split("/").pop()
1445
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1446
+ className: "font-mono text-[13px] font-semibold tracking-[-0.02em] text-sand-900",
1447
+ children: token.count
1448
+ })]
1449
+ }, token.name))]
1450
+ }), vitals.anthropicTokenNames.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1451
+ className: "flex flex-wrap items-center gap-2",
1452
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1453
+ className: "w-[4.5rem] shrink-0 text-[10px] font-medium uppercase tracking-[0.08em] text-sand-400",
1454
+ children: "anthropic"
1455
+ }), vitals.anthropicTokenNames.map((name) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1456
+ title: name,
1457
+ className: "inline-flex items-baseline rounded-md border border-sand-200 bg-white px-2 py-1 font-mono text-[11px] text-sand-600",
1458
+ children: name.split("/").pop()
1459
+ }, name))]
1460
+ })]
1461
+ }),
1462
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1463
+ className: "relative",
1464
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1465
+ ref: parentRef,
1466
+ role: "log",
1467
+ "aria-label": "Server process logs",
1468
+ tabIndex: 0,
1469
+ className: "main-scroll h-[calc(100vh-232px)] min-h-[320px] overflow-y-auto bg-sand-900 px-4 py-3 font-mono text-[12px] leading-[1.6] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-sienna-400",
1470
+ children: firstLoadFailed ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1471
+ className: "flex h-full flex-col items-center justify-center gap-3 text-sand-400",
1472
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
1473
+ className: "text-[12px]",
1474
+ children: ["Could not reach the qgrid server — is it running?", query.error instanceof Error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1475
+ className: "block text-center text-[11px] text-sand-500",
1476
+ children: query.error.message
1477
+ })]
1478
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
1479
+ type: "button",
1480
+ onClick: () => void query.refetch(),
1481
+ className: "inline-flex items-center gap-1.5 rounded-md border border-sand-600 px-2.5 py-1.5 text-[11px] font-medium text-sand-300 transition-colors hover:bg-sand-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sienna-400",
1482
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideRefreshCw, { className: "size-3" }), "Retry now"]
1483
+ })]
1484
+ }) : !hasFirstData ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1485
+ className: "flex h-full items-center justify-center text-[12px] text-sand-500",
1486
+ children: "Connecting to server logs…"
1487
+ }) : visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1488
+ className: "flex h-full items-center justify-center text-[12px] text-sand-500",
1489
+ children: items.length === 0 ? `No log lines yet — waiting for activity since ${epochRef.current !== void 0 ? formatTime(epochRef.current) : "startup"}.` : "No lines match the current filters."
1490
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1491
+ className: "relative w-full",
1492
+ style: { height: `${virtualizer.getTotalSize()}px` },
1493
+ children: virtualizer.getVirtualItems().map((virtualRow) => {
1494
+ const item = visible[virtualRow.index];
1495
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1496
+ ref: virtualizer.measureElement,
1497
+ "data-index": virtualRow.index,
1498
+ className: "absolute left-0 top-0 w-full",
1499
+ style: { transform: `translateY(${virtualRow.start}px)` },
1500
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogLine, { item })
1501
+ }, virtualRow.key);
1502
+ })
1503
+ })
1504
+ }), hasFirstData && !firstLoadFailed && !atEnd && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
1505
+ type: "button",
1506
+ onClick: () => virtualizer.scrollToEnd(),
1507
+ className: "absolute bottom-4 right-5 inline-flex items-center gap-1.5 rounded-full border border-sand-600 bg-sand-800/90 px-3 py-1.5 text-[11px] font-medium text-sand-200 shadow-lg backdrop-blur transition-colors hover:bg-sand-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sienna-400",
1508
+ children: "↓ Jump to live"
1509
+ })]
1510
+ })
1511
+ ]
1512
+ });
1513
+ }
1514
+ function LogLine({ item }) {
1515
+ if (item.kind === "restart") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1516
+ className: "py-1 text-center text-[11px] text-caution-400",
1517
+ children: [
1518
+ "── process restarted · ",
1519
+ formatTime(item.processStartedAt),
1520
+ " ──"
1521
+ ]
1522
+ });
1523
+ if (item.kind === "dropped") return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1524
+ className: "py-1 text-center text-[11px] italic text-sand-500",
1525
+ children: [
1526
+ "── ",
1527
+ item.count,
1528
+ " lines dropped (buffer overflow) ──"
1529
+ ]
1530
+ });
1531
+ const { entry } = item;
1532
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1533
+ className: "whitespace-pre-wrap break-words text-sand-200",
1534
+ children: [
1535
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1536
+ className: "text-sand-500",
1537
+ children: formatTime(entry.timestamp)
1538
+ }),
1539
+ " ",
1540
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1541
+ className: clsx("font-semibold", entry.level === "fatal" || entry.level === "error" ? "text-danger-400" : entry.level === "warning" ? "text-caution-400" : "text-sand-400"),
1542
+ children: LEVEL_LABEL[entry.level] ?? entry.level.slice(0, 3).toUpperCase()
1543
+ }),
1544
+ " ",
1545
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1546
+ className: "text-sienna-300",
1547
+ children: categoryLabel(entry.category)
1548
+ }),
1549
+ " ",
1550
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: entry.text })
1551
+ ]
1552
+ });
1553
+ }
1554
+ //#endregion
1555
+ //#region src/routes/monit.tsx?tsr-split=component
1556
+ object({ level: _enum([
1557
+ "all",
1558
+ "scaling",
1559
+ "warn",
1560
+ "error"
1561
+ ]).optional().default("all") });
1562
+ function MonitPage() {
1563
+ const search = Route.useSearch();
1564
+ const navigate = Route.useNavigate();
1565
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1566
+ className: "max-w-[100rem] mx-auto",
1567
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MonitConsole, {
1568
+ search,
1569
+ onSearchChange: (next) => navigate({
1570
+ search: next,
1571
+ replace: true
1572
+ })
1573
+ })
1574
+ });
1575
+ }
1576
+ //#endregion
1577
+ export { MonitPage as component };