oc2token 0.1.0

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 (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +399 -0
  3. package/dist/src/accounting/index.d.ts +1 -0
  4. package/dist/src/accounting/index.js +2 -0
  5. package/dist/src/accounting/index.js.map +1 -0
  6. package/dist/src/accounting/reducer.d.ts +21 -0
  7. package/dist/src/accounting/reducer.js +105 -0
  8. package/dist/src/accounting/reducer.js.map +1 -0
  9. package/dist/src/antigravity/discovery.d.ts +18 -0
  10. package/dist/src/antigravity/discovery.js +95 -0
  11. package/dist/src/antigravity/discovery.js.map +1 -0
  12. package/dist/src/antigravity/doctor.d.ts +6 -0
  13. package/dist/src/antigravity/doctor.js +78 -0
  14. package/dist/src/antigravity/doctor.js.map +1 -0
  15. package/dist/src/antigravity/index.d.ts +3 -0
  16. package/dist/src/antigravity/index.js +4 -0
  17. package/dist/src/antigravity/index.js.map +1 -0
  18. package/dist/src/antigravity/proto.d.ts +73 -0
  19. package/dist/src/antigravity/proto.js +259 -0
  20. package/dist/src/antigravity/proto.js.map +1 -0
  21. package/dist/src/antigravity/scanner.d.ts +8 -0
  22. package/dist/src/antigravity/scanner.js +552 -0
  23. package/dist/src/antigravity/scanner.js.map +1 -0
  24. package/dist/src/application.d.ts +73 -0
  25. package/dist/src/application.js +657 -0
  26. package/dist/src/application.js.map +1 -0
  27. package/dist/src/cache/filesystem.d.ts +8 -0
  28. package/dist/src/cache/filesystem.js +70 -0
  29. package/dist/src/cache/filesystem.js.map +1 -0
  30. package/dist/src/cache/index.d.ts +5 -0
  31. package/dist/src/cache/index.js +6 -0
  32. package/dist/src/cache/index.js.map +1 -0
  33. package/dist/src/cache/lock.d.ts +40 -0
  34. package/dist/src/cache/lock.js +227 -0
  35. package/dist/src/cache/lock.js.map +1 -0
  36. package/dist/src/cache/schema.d.ts +45 -0
  37. package/dist/src/cache/schema.js +308 -0
  38. package/dist/src/cache/schema.js.map +1 -0
  39. package/dist/src/cache/store.d.ts +46 -0
  40. package/dist/src/cache/store.js +396 -0
  41. package/dist/src/cache/store.js.map +1 -0
  42. package/dist/src/cache/types.d.ts +130 -0
  43. package/dist/src/cache/types.js +6 -0
  44. package/dist/src/cache/types.js.map +1 -0
  45. package/dist/src/cli.d.ts +8 -0
  46. package/dist/src/cli.js +874 -0
  47. package/dist/src/cli.js.map +1 -0
  48. package/dist/src/codex/discovery.d.ts +6 -0
  49. package/dist/src/codex/discovery.js +88 -0
  50. package/dist/src/codex/discovery.js.map +1 -0
  51. package/dist/src/codex/doctor.d.ts +6 -0
  52. package/dist/src/codex/doctor.js +52 -0
  53. package/dist/src/codex/doctor.js.map +1 -0
  54. package/dist/src/codex/index.d.ts +3 -0
  55. package/dist/src/codex/index.js +3 -0
  56. package/dist/src/codex/index.js.map +1 -0
  57. package/dist/src/codex/scanner.d.ts +6 -0
  58. package/dist/src/codex/scanner.js +487 -0
  59. package/dist/src/codex/scanner.js.map +1 -0
  60. package/dist/src/codex/types.d.ts +31 -0
  61. package/dist/src/codex/types.js +5 -0
  62. package/dist/src/codex/types.js.map +1 -0
  63. package/dist/src/collector/collector.d.ts +15 -0
  64. package/dist/src/collector/collector.js +597 -0
  65. package/dist/src/collector/collector.js.map +1 -0
  66. package/dist/src/collector/index.d.ts +3 -0
  67. package/dist/src/collector/index.js +3 -0
  68. package/dist/src/collector/index.js.map +1 -0
  69. package/dist/src/collector/types.d.ts +55 -0
  70. package/dist/src/collector/types.js +18 -0
  71. package/dist/src/collector/types.js.map +1 -0
  72. package/dist/src/dashboard/render/ansi.d.ts +53 -0
  73. package/dist/src/dashboard/render/ansi.js +106 -0
  74. package/dist/src/dashboard/render/ansi.js.map +1 -0
  75. package/dist/src/dashboard/render/dashboard.d.ts +13 -0
  76. package/dist/src/dashboard/render/dashboard.js +750 -0
  77. package/dist/src/dashboard/render/dashboard.js.map +1 -0
  78. package/dist/src/dashboard/render/format.d.ts +23 -0
  79. package/dist/src/dashboard/render/format.js +169 -0
  80. package/dist/src/dashboard/render/format.js.map +1 -0
  81. package/dist/src/dashboard/render/redraw.d.ts +13 -0
  82. package/dist/src/dashboard/render/redraw.js +24 -0
  83. package/dist/src/dashboard/render/redraw.js.map +1 -0
  84. package/dist/src/dashboard/render/types.d.ts +83 -0
  85. package/dist/src/dashboard/render/types.js +528 -0
  86. package/dist/src/dashboard/render/types.js.map +1 -0
  87. package/dist/src/dashboard/scheduler/index.d.ts +1 -0
  88. package/dist/src/dashboard/scheduler/index.js +2 -0
  89. package/dist/src/dashboard/scheduler/index.js.map +1 -0
  90. package/dist/src/dashboard/scheduler/refresh-scheduler.d.ts +46 -0
  91. package/dist/src/dashboard/scheduler/refresh-scheduler.js +137 -0
  92. package/dist/src/dashboard/scheduler/refresh-scheduler.js.map +1 -0
  93. package/dist/src/dashboard/settings/index.d.ts +25 -0
  94. package/dist/src/dashboard/settings/index.js +162 -0
  95. package/dist/src/dashboard/settings/index.js.map +1 -0
  96. package/dist/src/dashboard/state/index.d.ts +2 -0
  97. package/dist/src/dashboard/state/index.js +3 -0
  98. package/dist/src/dashboard/state/index.js.map +1 -0
  99. package/dist/src/dashboard/state/refresh-coordinator.d.ts +72 -0
  100. package/dist/src/dashboard/state/refresh-coordinator.js +346 -0
  101. package/dist/src/dashboard/state/refresh-coordinator.js.map +1 -0
  102. package/dist/src/dashboard/state/types.d.ts +68 -0
  103. package/dist/src/dashboard/state/types.js +2 -0
  104. package/dist/src/dashboard/state/types.js.map +1 -0
  105. package/dist/src/domain/contracts.d.ts +219 -0
  106. package/dist/src/domain/contracts.js +2 -0
  107. package/dist/src/domain/contracts.js.map +1 -0
  108. package/dist/src/domain/errors.d.ts +25 -0
  109. package/dist/src/domain/errors.js +65 -0
  110. package/dist/src/domain/errors.js.map +1 -0
  111. package/dist/src/domain/index.d.ts +5 -0
  112. package/dist/src/domain/index.js +6 -0
  113. package/dist/src/domain/index.js.map +1 -0
  114. package/dist/src/domain/records.d.ts +59 -0
  115. package/dist/src/domain/records.js +141 -0
  116. package/dist/src/domain/records.js.map +1 -0
  117. package/dist/src/domain/tokens.d.ts +51 -0
  118. package/dist/src/domain/tokens.js +93 -0
  119. package/dist/src/domain/tokens.js.map +1 -0
  120. package/dist/src/domain/windows.d.ts +59 -0
  121. package/dist/src/domain/windows.js +272 -0
  122. package/dist/src/domain/windows.js.map +1 -0
  123. package/dist/src/index.d.ts +9 -0
  124. package/dist/src/index.js +9 -0
  125. package/dist/src/index.js.map +1 -0
  126. package/dist/src/opencode/adapter.d.ts +47 -0
  127. package/dist/src/opencode/adapter.js +118 -0
  128. package/dist/src/opencode/adapter.js.map +1 -0
  129. package/dist/src/opencode/client.d.ts +64 -0
  130. package/dist/src/opencode/client.js +118 -0
  131. package/dist/src/opencode/client.js.map +1 -0
  132. package/dist/src/opencode/doctor.d.ts +28 -0
  133. package/dist/src/opencode/doctor.js +82 -0
  134. package/dist/src/opencode/doctor.js.map +1 -0
  135. package/dist/src/opencode/index.d.ts +5 -0
  136. package/dist/src/opencode/index.js +6 -0
  137. package/dist/src/opencode/index.js.map +1 -0
  138. package/dist/src/opencode/stats.d.ts +8 -0
  139. package/dist/src/opencode/stats.js +174 -0
  140. package/dist/src/opencode/stats.js.map +1 -0
  141. package/dist/src/opencode/transport.d.ts +54 -0
  142. package/dist/src/opencode/transport.js +621 -0
  143. package/dist/src/opencode/transport.js.map +1 -0
  144. package/dist/src/output/index.d.ts +20 -0
  145. package/dist/src/output/index.js +46 -0
  146. package/dist/src/output/index.js.map +1 -0
  147. package/dist/src/output/json.d.ts +72 -0
  148. package/dist/src/output/json.js +133 -0
  149. package/dist/src/output/json.js.map +1 -0
  150. package/dist/src/output/table.d.ts +4 -0
  151. package/dist/src/output/table.js +81 -0
  152. package/dist/src/output/table.js.map +1 -0
  153. package/dist/src/pricing/index.d.ts +1 -0
  154. package/dist/src/pricing/index.js +2 -0
  155. package/dist/src/pricing/index.js.map +1 -0
  156. package/dist/src/pricing/pricing.d.ts +19 -0
  157. package/dist/src/pricing/pricing.js +441 -0
  158. package/dist/src/pricing/pricing.js.map +1 -0
  159. package/package.json +27 -0
@@ -0,0 +1,137 @@
1
+ export const DEFAULT_REFRESH_INTERVAL_SECONDS = 300;
2
+ export const DEFAULT_REFRESH_INTERVAL_MS = DEFAULT_REFRESH_INTERVAL_SECONDS * 1000;
3
+ const systemTimers = {
4
+ setTimeout(callback, delayMilliseconds) {
5
+ const handle = setTimeout(callback, delayMilliseconds);
6
+ // Do not keep a non-interactive process alive solely for a dashboard timer.
7
+ if (typeof handle === "object" && handle !== null && "unref" in handle) {
8
+ handle.unref();
9
+ }
10
+ return handle;
11
+ },
12
+ clearTimeout(handle) {
13
+ clearTimeout(handle);
14
+ },
15
+ };
16
+ /**
17
+ * Monotonic, one-shot refresh scheduler.
18
+ *
19
+ * There is only ever one armed timer. Resetting it invalidates the old timer
20
+ * callback as well as clearing it, which protects fake timer implementations
21
+ * and hosts that deliver a callback after clearTimeout.
22
+ */
23
+ export class RefreshScheduler {
24
+ clock;
25
+ onRequest;
26
+ timers;
27
+ intervalMilliseconds;
28
+ running = false;
29
+ deadline;
30
+ timerHandle;
31
+ timerToken = 0;
32
+ constructor(options) {
33
+ if (!Number.isFinite(options.refreshIntervalSeconds ?? DEFAULT_REFRESH_INTERVAL_SECONDS)) {
34
+ throw new RangeError("refreshIntervalSeconds must be finite");
35
+ }
36
+ const intervalSeconds = options.refreshIntervalSeconds ?? DEFAULT_REFRESH_INTERVAL_SECONDS;
37
+ if (intervalSeconds < 0) {
38
+ throw new RangeError("refreshIntervalSeconds must be non-negative");
39
+ }
40
+ this.clock = options.clock;
41
+ this.onRequest = options.onRequest;
42
+ this.timers = options.timers ?? systemTimers;
43
+ this.intervalMilliseconds = intervalSeconds * 1000;
44
+ }
45
+ get refreshIntervalSeconds() {
46
+ return this.intervalMilliseconds / 1000;
47
+ }
48
+ setRefreshIntervalSeconds(seconds) {
49
+ if (!Number.isFinite(seconds)) {
50
+ throw new RangeError("refreshIntervalSeconds must be finite");
51
+ }
52
+ if (seconds < 0 || !Number.isSafeInteger(seconds)) {
53
+ throw new RangeError("refreshIntervalSeconds must be a non-negative integer");
54
+ }
55
+ const nextMilliseconds = seconds * 1000;
56
+ if (nextMilliseconds === this.intervalMilliseconds)
57
+ return;
58
+ this.intervalMilliseconds = nextMilliseconds;
59
+ if (this.running) {
60
+ this.resetDeadline();
61
+ }
62
+ }
63
+ get isRunning() {
64
+ return this.running;
65
+ }
66
+ start() {
67
+ if (this.running) {
68
+ return;
69
+ }
70
+ this.running = true;
71
+ this.resetDeadline();
72
+ }
73
+ stop() {
74
+ this.running = false;
75
+ this.deadline = undefined;
76
+ this.timerToken += 1;
77
+ this.clearTimer();
78
+ }
79
+ /** Trigger an immediate refresh and restart the automatic cadence. */
80
+ manual() {
81
+ if (!this.running) {
82
+ return;
83
+ }
84
+ this.resetDeadline();
85
+ this.onRequest("manual");
86
+ }
87
+ /** Treat wake as one invalidation, never as one callback per missed tick. */
88
+ wake() {
89
+ if (!this.running) {
90
+ return;
91
+ }
92
+ this.resetDeadline();
93
+ this.onRequest("wake");
94
+ }
95
+ nextRefreshAt() {
96
+ return this.deadline;
97
+ }
98
+ countdownSeconds() {
99
+ if (!this.running || this.deadline === undefined) {
100
+ return undefined;
101
+ }
102
+ return Math.max(0, Math.ceil((this.deadline - this.clock.monotonicNow()) / 1000));
103
+ }
104
+ /** Reset the cadence after a completed refresh or an externally detected wake. */
105
+ reset() {
106
+ if (this.running) {
107
+ this.resetDeadline();
108
+ }
109
+ }
110
+ resetDeadline() {
111
+ this.timerToken += 1;
112
+ this.clearTimer();
113
+ if (this.intervalMilliseconds === 0) {
114
+ this.deadline = undefined;
115
+ return;
116
+ }
117
+ this.deadline = this.clock.monotonicNow() + this.intervalMilliseconds;
118
+ const token = this.timerToken;
119
+ this.timerHandle = this.timers.setTimeout(() => {
120
+ if (!this.running || token !== this.timerToken) {
121
+ return;
122
+ }
123
+ this.timerHandle = undefined;
124
+ // Schedule from the current monotonic instant. This collapses delayed
125
+ // callbacks after sleep instead of replaying every missed interval.
126
+ this.resetDeadline();
127
+ this.onRequest("timer");
128
+ }, this.intervalMilliseconds);
129
+ }
130
+ clearTimer() {
131
+ if (this.timerHandle !== undefined) {
132
+ this.timers.clearTimeout(this.timerHandle);
133
+ this.timerHandle = undefined;
134
+ }
135
+ }
136
+ }
137
+ //# sourceMappingURL=refresh-scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh-scheduler.js","sourceRoot":"","sources":["../../../../src/dashboard/scheduler/refresh-scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type ProviderKind } from "../../domain/index.js";
2
+ export declare const SETTINGS_MIN_REFRESH_SECONDS = 60;
3
+ export declare const SETTINGS_MAX_REFRESH_SECONDS: number;
4
+ export declare const SETTINGS_DEFAULT_REFRESH_SECONDS = 300;
5
+ export declare const ALL_PROVIDER_KINDS: readonly ProviderKind[];
6
+ export interface DashboardSettings {
7
+ readonly enabledProviders: ReadonlyArray<ProviderKind>;
8
+ readonly refreshIntervalSeconds: number;
9
+ }
10
+ export declare function clampRefreshIntervalSeconds(value: number): number;
11
+ export declare function normalizeRefreshIntervalSeconds(value: unknown): number;
12
+ export declare function formatRefreshInterval(seconds: number): string;
13
+ export declare function settingsToFilterProviders(settings: DashboardSettings): Set<ProviderKind> | undefined;
14
+ export declare function filterProvidersToEnabled(filterProviders?: Set<ProviderKind>): ReadonlyArray<ProviderKind>;
15
+ export declare function normalizeEnabledProviders(value: unknown): ReadonlyArray<ProviderKind>;
16
+ export declare function normalizeSettings(value: unknown): DashboardSettings;
17
+ export declare function settingsFilePath(cacheDirectory?: string): string;
18
+ export declare function loadDashboardSettings(cacheDirectory?: string): Promise<DashboardSettings | undefined>;
19
+ export declare function saveDashboardSettings(settings: DashboardSettings, cacheDirectory?: string): Promise<void>;
20
+ export declare const REFRESH_INTERVAL_PRESETS: readonly number[];
21
+ export declare function nearestPresetIndex(value: number): number;
22
+ export declare function adjustRefreshIntervalByPreset(currentSeconds: number, deltaSteps: number): number;
23
+ export declare function adjustRefreshInterval(currentSeconds: number, deltaSteps: number): number;
24
+ export declare function refreshIntervalPresetIndex(value: number): number;
25
+ export declare function refreshIntervalForPresetIndex(index: number): number;
@@ -0,0 +1,162 @@
1
+ import { promises as fs } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { defaultCacheDirectory } from "../../application.js";
4
+ import { isProviderKind } from "../../domain/records.js";
5
+ export const SETTINGS_MIN_REFRESH_SECONDS = 60;
6
+ export const SETTINGS_MAX_REFRESH_SECONDS = 4 * 60 * 60; // 14400
7
+ export const SETTINGS_DEFAULT_REFRESH_SECONDS = 300;
8
+ export const ALL_PROVIDER_KINDS = ["opencode", "codex", "antigravity"];
9
+ export function clampRefreshIntervalSeconds(value) {
10
+ if (!Number.isFinite(value))
11
+ return SETTINGS_DEFAULT_REFRESH_SECONDS;
12
+ const floored = Math.floor(value);
13
+ return Math.max(SETTINGS_MIN_REFRESH_SECONDS, Math.min(SETTINGS_MAX_REFRESH_SECONDS, floored));
14
+ }
15
+ export function normalizeRefreshIntervalSeconds(value) {
16
+ if (typeof value !== "number" || !Number.isFinite(value))
17
+ return SETTINGS_DEFAULT_REFRESH_SECONDS;
18
+ return clampRefreshIntervalSeconds(value);
19
+ }
20
+ export function formatRefreshInterval(seconds) {
21
+ const clamped = clampRefreshIntervalSeconds(seconds);
22
+ if (clamped % 3600 === 0) {
23
+ const h = clamped / 3600;
24
+ return `${h}h`;
25
+ }
26
+ if (clamped >= 3600) {
27
+ const h = Math.floor(clamped / 3600);
28
+ const m = Math.floor((clamped % 3600) / 60);
29
+ if (m === 0)
30
+ return `${h}h`;
31
+ return `${h}h ${m}m`;
32
+ }
33
+ if (clamped % 60 === 0) {
34
+ return `${clamped / 60}m`;
35
+ }
36
+ // For non-multiples of 60 (should still clamp but allow display)
37
+ const m = Math.floor(clamped / 60);
38
+ const s = clamped % 60;
39
+ if (m === 0)
40
+ return `${s}s`;
41
+ return `${m}m ${s}s`;
42
+ }
43
+ export function settingsToFilterProviders(settings) {
44
+ const enabled = settings.enabledProviders;
45
+ if (enabled.length === ALL_PROVIDER_KINDS.length) {
46
+ // All enabled => no filter (collect all)
47
+ return undefined;
48
+ }
49
+ if (enabled.length === 0) {
50
+ // Empty would mean nothing to collect; caller should prevent but map to empty set
51
+ return new Set();
52
+ }
53
+ return new Set(enabled);
54
+ }
55
+ export function filterProvidersToEnabled(filterProviders) {
56
+ if (filterProviders === undefined || filterProviders.size === 0) {
57
+ return [...ALL_PROVIDER_KINDS];
58
+ }
59
+ const result = [];
60
+ for (const kind of ALL_PROVIDER_KINDS) {
61
+ if (filterProviders.has(kind))
62
+ result.push(kind);
63
+ }
64
+ // Preserve order of ALL_PROVIDER_KINDS, ignore unknown
65
+ return result;
66
+ }
67
+ export function normalizeEnabledProviders(value) {
68
+ if (!Array.isArray(value))
69
+ return [...ALL_PROVIDER_KINDS];
70
+ const filtered = value.filter(isProviderKind);
71
+ // Dedupe preserve order
72
+ const seen = new Set();
73
+ const ordered = [];
74
+ for (const kind of ALL_PROVIDER_KINDS) {
75
+ if (filtered.includes(kind) && !seen.has(kind)) {
76
+ seen.add(kind);
77
+ ordered.push(kind);
78
+ }
79
+ }
80
+ // If input contained valid providers but not in order, include them
81
+ for (const kind of filtered) {
82
+ if (!seen.has(kind)) {
83
+ seen.add(kind);
84
+ ordered.push(kind);
85
+ }
86
+ }
87
+ if (ordered.length === 0)
88
+ return [...ALL_PROVIDER_KINDS];
89
+ return ordered;
90
+ }
91
+ export function normalizeSettings(value) {
92
+ if (typeof value !== "object" || value === null) {
93
+ return { enabledProviders: [...ALL_PROVIDER_KINDS], refreshIntervalSeconds: SETTINGS_DEFAULT_REFRESH_SECONDS };
94
+ }
95
+ const record = value;
96
+ const enabled = normalizeEnabledProviders(record.enabledProviders ?? record.providers ?? record.filterProviders);
97
+ const interval = normalizeRefreshIntervalSeconds(record.refreshIntervalSeconds);
98
+ return { enabledProviders: enabled, refreshIntervalSeconds: interval };
99
+ }
100
+ export function settingsFilePath(cacheDirectory) {
101
+ const directory = cacheDirectory ?? defaultCacheDirectory();
102
+ return join(directory, "settings.json");
103
+ }
104
+ export async function loadDashboardSettings(cacheDirectory) {
105
+ const path = settingsFilePath(cacheDirectory);
106
+ try {
107
+ const contents = await fs.readFile(path, "utf8");
108
+ const parsed = JSON.parse(contents);
109
+ return normalizeSettings(parsed);
110
+ }
111
+ catch {
112
+ return undefined;
113
+ }
114
+ }
115
+ export async function saveDashboardSettings(settings, cacheDirectory) {
116
+ const path = settingsFilePath(cacheDirectory);
117
+ const directory = cacheDirectory ?? defaultCacheDirectory();
118
+ try {
119
+ await fs.mkdir(directory, { recursive: true, mode: 0o700 });
120
+ }
121
+ catch { }
122
+ const payload = JSON.stringify({
123
+ version: 1,
124
+ enabledProviders: [...settings.enabledProviders],
125
+ refreshIntervalSeconds: clampRefreshIntervalSeconds(settings.refreshIntervalSeconds),
126
+ }, null, 2);
127
+ try {
128
+ await fs.writeFile(path, `${payload}\n`, "utf8");
129
+ }
130
+ catch { }
131
+ }
132
+ export const REFRESH_INTERVAL_PRESETS = [60, 120, 300, 600, 900, 1800, 3600, 7200, 14400];
133
+ export function nearestPresetIndex(value) {
134
+ const clamped = clampRefreshIntervalSeconds(value);
135
+ let bestIndex = 0;
136
+ let bestDiff = Infinity;
137
+ for (let i = 0; i < REFRESH_INTERVAL_PRESETS.length; i += 1) {
138
+ const diff = Math.abs(REFRESH_INTERVAL_PRESETS[i] - clamped);
139
+ if (diff < bestDiff) {
140
+ bestDiff = diff;
141
+ bestIndex = i;
142
+ }
143
+ }
144
+ return bestIndex;
145
+ }
146
+ export function adjustRefreshIntervalByPreset(currentSeconds, deltaSteps) {
147
+ const idx = nearestPresetIndex(currentSeconds);
148
+ const nextIdx = Math.max(0, Math.min(REFRESH_INTERVAL_PRESETS.length - 1, idx + deltaSteps));
149
+ return REFRESH_INTERVAL_PRESETS[nextIdx];
150
+ }
151
+ export function adjustRefreshInterval(currentSeconds, deltaSteps) {
152
+ // Back-compat: delegate to preset stepping for consistent UI increments
153
+ return adjustRefreshIntervalByPreset(currentSeconds, deltaSteps);
154
+ }
155
+ export function refreshIntervalPresetIndex(value) {
156
+ return nearestPresetIndex(value);
157
+ }
158
+ export function refreshIntervalForPresetIndex(index) {
159
+ const clamped = Math.max(0, Math.min(REFRESH_INTERVAL_PRESETS.length - 1, Math.floor(index)));
160
+ return REFRESH_INTERVAL_PRESETS[clamped];
161
+ }
162
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/dashboard/settings/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from "./refresh-coordinator.js";
2
+ export * from "./types.js";
@@ -0,0 +1,3 @@
1
+ export * from "./refresh-coordinator.js";
2
+ export * from "./types.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/dashboard/state/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { type UsageWindowKind } from "../../domain/windows.js";
2
+ import { RefreshScheduler, type TimerDriver } from "../scheduler/refresh-scheduler.js";
3
+ import type { Clock, DashboardNavigation, RefreshOutcome, RefreshReason, RefreshSchedulerLike, RefreshState, UsageSource } from "./types.js";
4
+ import type { CollectionResult } from "../../domain/index.js";
5
+ export interface RefreshCoordinatorOptions<Navigation = DashboardNavigation> {
6
+ readonly source: UsageSource;
7
+ readonly clock: Clock;
8
+ readonly timezone: string;
9
+ readonly project?: string;
10
+ readonly refreshIntervalSeconds?: number;
11
+ readonly timers?: TimerDriver;
12
+ readonly scheduler?: RefreshSchedulerLike;
13
+ readonly initialPeriod?: UsageWindowKind;
14
+ readonly initialNavigation?: Navigation;
15
+ /** Optional normalized cache snapshot shown while the first live refresh runs. */
16
+ readonly initialSnapshot?: CollectionResult;
17
+ readonly onStateChange?: (state: RefreshState<Navigation>) => void;
18
+ /** Maximum time to wait for a source that ignores AbortSignal during quit. */
19
+ readonly cleanupTimeoutMilliseconds?: number;
20
+ }
21
+ export type RefreshListener<Navigation> = (state: RefreshState<Navigation>) => void;
22
+ /**
23
+ * Owns every visible refresh transition. Sources do not mutate dashboard
24
+ * state; they return one result which is committed only by its current
25
+ * generation.
26
+ */
27
+ export declare class RefreshCoordinator<Navigation = DashboardNavigation> {
28
+ private readonly source;
29
+ private readonly clock;
30
+ private readonly timezone;
31
+ private readonly project;
32
+ private readonly listeners;
33
+ private readonly scheduler;
34
+ private readonly cleanupTimeoutMilliseconds;
35
+ private state;
36
+ private active;
37
+ private pendingReason;
38
+ private pendingWaiters;
39
+ private nextGeneration;
40
+ private started;
41
+ private quitting;
42
+ private startPromise;
43
+ private readonly configuredOnStateChange;
44
+ constructor(options: RefreshCoordinatorOptions<Navigation>);
45
+ get refreshScheduler(): RefreshSchedulerLike;
46
+ get isRefreshing(): boolean;
47
+ get isStopped(): boolean;
48
+ getState(): RefreshState<Navigation>;
49
+ subscribe(listener: RefreshListener<Navigation>): () => void;
50
+ setPeriod(period: UsageWindowKind): void;
51
+ setNavigation(navigation: Navigation): void;
52
+ get refreshIntervalSeconds(): number;
53
+ setRefreshIntervalSeconds(seconds: number): void;
54
+ /** Start the scheduler and immediately issue exactly one initial refresh. */
55
+ start(): Promise<RefreshOutcome>;
56
+ /** Request a refresh; concurrent requests are reduced to one pending reason. */
57
+ request(reason?: Exclude<RefreshReason, "initial"> | "initial"): Promise<RefreshOutcome>;
58
+ refresh(): Promise<RefreshOutcome>;
59
+ manualRefresh(): Promise<RefreshOutcome>;
60
+ wake(): Promise<RefreshOutcome>;
61
+ /**
62
+ * Stop scheduling, invalidate the current generation, abort network work,
63
+ * and wait only briefly for sources which honor cancellation.
64
+ */
65
+ quit(): Promise<void>;
66
+ private begin;
67
+ private mergePendingReason;
68
+ private handleScheduledRequest;
69
+ private waitForCleanup;
70
+ private emit;
71
+ }
72
+ export { RefreshScheduler };