@myko/ui-svelte 4.4.0 → 4.4.3

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 (80) hide show
  1. package/{src/lib → dist}/components/ConnectionStats.svelte +8 -22
  2. package/dist/components/ConnectionStats.svelte.d.ts +10 -0
  3. package/dist/components/EntityDiffBadge.svelte +10 -0
  4. package/dist/components/EntityDiffBadge.svelte.d.ts +7 -0
  5. package/{src/lib → dist}/components/EntityDiffFields.svelte +27 -49
  6. package/dist/components/EntityDiffFields.svelte.d.ts +11 -0
  7. package/{src/lib → dist}/components/EntityDiffNode.svelte +25 -43
  8. package/dist/components/EntityDiffNode.svelte.d.ts +14 -0
  9. package/{src/lib → dist}/components/EntityDiffTree.svelte +150 -200
  10. package/dist/components/EntityDiffTree.svelte.d.ts +21 -0
  11. package/dist/components/Logs.svelte +30 -0
  12. package/dist/components/Logs.svelte.d.ts +7 -0
  13. package/dist/components/Query.svelte +21 -0
  14. package/dist/components/Query.svelte.d.ts +35 -0
  15. package/dist/components/Report.svelte +13 -0
  16. package/dist/components/Report.svelte.d.ts +32 -0
  17. package/dist/components/Search.svelte +46 -0
  18. package/dist/components/Search.svelte.d.ts +56 -0
  19. package/dist/components/ServerView.svelte +76 -0
  20. package/dist/components/ServerView.svelte.d.ts +8 -0
  21. package/dist/components/state/resolutions.d.ts +11 -0
  22. package/dist/components/state/resolutions.js +129 -0
  23. package/dist/components/state/viewstate.svelte.d.ts +60 -0
  24. package/dist/components/state/viewstate.svelte.js +259 -0
  25. package/dist/components/state/windback.svelte.d.ts +16 -0
  26. package/dist/components/state/windback.svelte.js +65 -0
  27. package/dist/components/transactions/EntityHistory.svelte +135 -0
  28. package/dist/components/transactions/EntityHistory.svelte.d.ts +10 -0
  29. package/{src/lib → dist}/components/transactions/TimeStrip.svelte +18 -25
  30. package/dist/components/transactions/TimeStrip.svelte.d.ts +3 -0
  31. package/dist/components/transactions/TransactionDetails.svelte +24 -0
  32. package/dist/components/transactions/TransactionDetails.svelte.d.ts +7 -0
  33. package/{src/lib → dist}/components/transactions/TransactionEvent.svelte +20 -32
  34. package/dist/components/transactions/TransactionEvent.svelte.d.ts +7 -0
  35. package/{src/lib → dist}/components/transactions/TransactionEventGroup.svelte +8 -13
  36. package/dist/components/transactions/TransactionEventGroup.svelte.d.ts +8 -0
  37. package/dist/components/transactions/Transactions.svelte +94 -0
  38. package/dist/components/transactions/Transactions.svelte.d.ts +8 -0
  39. package/{src/lib → dist}/components/transactions/TransactonView.svelte +3 -7
  40. package/dist/components/transactions/TransactonView.svelte.d.ts +7 -0
  41. package/{src/lib → dist}/components/windback/WindbackFrame.svelte +3 -6
  42. package/dist/components/windback/WindbackFrame.svelte.d.ts +7 -0
  43. package/dist/components/windback/index.js +1 -0
  44. package/dist/index.d.ts +18 -0
  45. package/{src/lib/index.ts → dist/index.js} +2 -15
  46. package/dist/services/svelte-client.svelte.d.ts +278 -0
  47. package/dist/services/svelte-client.svelte.js +678 -0
  48. package/dist/utils/entity-apply.d.ts +17 -0
  49. package/dist/utils/entity-apply.js +35 -0
  50. package/dist/utils/entity-diff.d.ts +40 -0
  51. package/dist/utils/entity-diff.js +57 -0
  52. package/dist/utils/entity-tree.d.ts +24 -0
  53. package/dist/utils/entity-tree.js +111 -0
  54. package/package.json +13 -9
  55. package/.prettierignore +0 -4
  56. package/.prettierrc +0 -15
  57. package/src/app.d.ts +0 -13
  58. package/src/app.html +0 -12
  59. package/src/lib/components/EntityDiffBadge.svelte +0 -18
  60. package/src/lib/components/Logs.svelte +0 -37
  61. package/src/lib/components/Query.svelte +0 -34
  62. package/src/lib/components/Report.svelte +0 -25
  63. package/src/lib/components/Search.svelte +0 -85
  64. package/src/lib/components/ServerView.svelte +0 -95
  65. package/src/lib/components/state/resolutions.ts +0 -137
  66. package/src/lib/components/state/viewstate.svelte.ts +0 -375
  67. package/src/lib/components/state/windback.svelte.ts +0 -88
  68. package/src/lib/components/transactions/EntityHistory.svelte +0 -173
  69. package/src/lib/components/transactions/TransactionDetails.svelte +0 -26
  70. package/src/lib/components/transactions/Transactions.svelte +0 -111
  71. package/src/lib/services/svelte-client.svelte.ts +0 -863
  72. package/src/lib/utils/entity-apply.ts +0 -47
  73. package/src/lib/utils/entity-diff.ts +0 -105
  74. package/src/lib/utils/entity-tree.ts +0 -130
  75. package/src/routes/+page.svelte +0 -3
  76. package/static/favicon.png +0 -0
  77. package/svelte.config.js +0 -18
  78. package/tsconfig.json +0 -13
  79. package/vite.config.ts +0 -6
  80. /package/{src/lib/components/windback/index.ts → dist/components/windback/index.d.ts} +0 -0
@@ -1,137 +0,0 @@
1
- import { Duration } from 'luxon';
2
-
3
- export type Resolution = {
4
- milis: number;
5
- majorFormat: string;
6
- minorFormat: string;
7
- };
8
-
9
- export const resolutions = [
10
- {
11
- label: '1ms',
12
- majorFormat: 'dd MMM HH:mm:ss.SSS',
13
- minorFormat: '.SSS',
14
- milis: Duration.fromObject({ milliseconds: 1 }).as('milliseconds')
15
- },
16
- {
17
- label: '5ms',
18
- majorFormat: 'dd MMM HH:mm:ss.SSS',
19
- minorFormat: '.SSS',
20
- milis: Duration.fromObject({ milliseconds: 5 }).as('milliseconds')
21
- },
22
- {
23
- label: '10ms',
24
- minorFormat: '.SSS',
25
- majorFormat: 'dd MMM HH:mm:ss.SSS',
26
- milis: Duration.fromObject({ milliseconds: 10 }).as('milliseconds')
27
- },
28
- {
29
- label: '50ms',
30
- minorFormat: '.SSS',
31
- majorFormat: 'dd MMM HH:mm:ss.SSS',
32
- milis: Duration.fromObject({ milliseconds: 50 }).as('milliseconds')
33
- },
34
- {
35
- label: '100ms',
36
- majorFormat: 'dd MMM HH:mm:ss.SSS',
37
- minorFormat: '.SSS',
38
-
39
- milis: Duration.fromObject({ milliseconds: 100 }).as('milliseconds')
40
- },
41
- {
42
- label: '500ms',
43
- majorFormat: 'dd MMM HH:mm:ss.SSS',
44
- minorFormat: '.SSS',
45
- milis: Duration.fromObject({ milliseconds: 500 }).as('milliseconds')
46
- },
47
- {
48
- label: '1s',
49
- majorFormat: 'dd MMM HH:mm:ss',
50
- minorFormat: 'ss',
51
- milis: Duration.fromObject({ seconds: 1 }).as('milliseconds')
52
- },
53
- {
54
- label: '5s',
55
- majorFormat: 'dd MMM HH:mm:ss',
56
- minorFormat: 'ss',
57
- milis: Duration.fromObject({ seconds: 5 }).as('milliseconds')
58
- },
59
- {
60
- label: '10s',
61
- majorFormat: 'dd MMM HH:mm:ss',
62
- minorFormat: 'ss',
63
- milis: Duration.fromObject({ seconds: 10 }).as('milliseconds')
64
- },
65
- {
66
- label: '30s',
67
- majorFormat: 'dd MMM HH:mm:ss',
68
- minorFormat: 'ss',
69
- milis: Duration.fromObject({ seconds: 30 }).as('milliseconds')
70
- },
71
- {
72
- label: '1m',
73
- majorFormat: 'dd MMM HH:mm:ss',
74
- minorFormat: 'mm:ss',
75
- milis: Duration.fromObject({ minutes: 1 }).as('milliseconds')
76
- },
77
- {
78
- label: '5m',
79
- majorFormat: 'dd MMM HH:mm:ss',
80
- minorFormat: 'mm:ss',
81
- milis: Duration.fromObject({ minutes: 5 }).as('milliseconds')
82
- },
83
- {
84
- label: '10m',
85
- majorFormat: 'dd MMM HH:mm:ss',
86
- minorFormat: 'mm:ss',
87
- milis: Duration.fromObject({ minutes: 10 }).as('milliseconds')
88
- },
89
- {
90
- label: '30m',
91
- majorFormat: 'dd MMM HH:mm:ss',
92
- minorFormat: 'mm:ss',
93
- milis: Duration.fromObject({ minutes: 30 }).as('milliseconds')
94
- },
95
- {
96
- label: '1h',
97
- majorFormat: 'dd MMM HH:mm:ss',
98
- minorFormat: 'HH:mm',
99
- milis: Duration.fromObject({ hours: 1 }).as('milliseconds')
100
- },
101
- {
102
- label: '6h',
103
- majorFormat: 'dd MMM HH:mm:ss',
104
- minorFormat: 'HH:mm',
105
- milis: Duration.fromObject({ hours: 6 }).as('milliseconds')
106
- },
107
- {
108
- label: '12h',
109
- majorFormat: 'dd MMM',
110
- minorFormat: 'HH:mm',
111
- milis: Duration.fromObject({ hours: 12 }).as('milliseconds')
112
- },
113
- {
114
- label: '1d',
115
- majorFormat: 'dd MMM',
116
- minorFormat: 'dd',
117
- milis: Duration.fromObject({ days: 1 }).as('milliseconds')
118
- },
119
- {
120
- label: '1w',
121
- majorFormat: 'dd MMM yyyy',
122
- minorFormat: 'dd',
123
- milis: Duration.fromObject({ weeks: 1 }).as('milliseconds')
124
- },
125
- {
126
- label: '1M',
127
- majorFormat: 'MMM yyyy',
128
- minorFormat: 'MMM',
129
- milis: Duration.fromObject({ months: 1 }).as('milliseconds')
130
- },
131
- {
132
- label: '1y',
133
- majorFormat: 'yyyy',
134
- minorFormat: 'yyyy',
135
- milis: Duration.fromObject({ years: 1 }).as('milliseconds')
136
- }
137
- ];
@@ -1,375 +0,0 @@
1
- import { DateTime, type Duration } from 'luxon';
2
- import { memoizeWith, uniq } from 'ramda';
3
- import { SvelteSet } from 'svelte/reactivity';
4
- import { resolutions, type Resolution } from './resolutions.js';
5
- import type { WindbackState } from './windback.svelte.js';
6
-
7
- export class TransactionsViewState {
8
- #visibleEvents = new SvelteSet<string>();
9
-
10
- #timeZero: DateTime = $state(DateTime.now());
11
-
12
- #leftTimeMilis = $state(DateTime.utc().minus({ minutes: 1 }).toMillis());
13
-
14
- #rightTimeMilis: number | null = $state(DateTime.now().toMillis());
15
-
16
- #widthPx: number = $state(0);
17
-
18
- #now: DateTime = $state(DateTime.now());
19
-
20
- #mouseX: number = $state(0);
21
-
22
- #draggingWindback = $state(false);
23
-
24
- readonly #leftTime: DateTime = $derived(fromMillisMemo(this.#leftTimeMilis));
25
- readonly #rightTime: DateTime | null = $derived(
26
- this.#rightTimeMilis ? fromMillisMemo(this.#rightTimeMilis) : null
27
- );
28
-
29
- readonly #timeRangeMilis: number = $derived(this.rightTimeMilis - this.#leftTimeMilis);
30
-
31
- readonly #durationMilisPerPx = $derived(this.#timeRangeMilis / this.#widthPx);
32
-
33
- constructor(readonly windbackState: WindbackState) {
34
- const updateTime = () => {
35
- this.#now = DateTime.now();
36
-
37
- requestAnimationFrame(updateTime);
38
- };
39
-
40
- updateTime();
41
-
42
- $effect(() => {
43
- if (!this.#draggingWindback) return;
44
-
45
- this.windbackState.updateCursor(this.mouseTime);
46
- });
47
- }
48
-
49
- get windbackX() {
50
- if (!this.windbackState.cursor) {
51
- return 0;
52
- }
53
-
54
- const time = this.windbackState.cursor.toMillis();
55
-
56
- const left = this.#leftTimeMilis;
57
- const right = this.rightTimeMilis;
58
-
59
- const range = right - left;
60
-
61
- const norm = (time - left) / range;
62
-
63
- return norm * this.#widthPx;
64
- }
65
-
66
- get windbackFullX() {
67
- if (!this.windbackState.cursor) {
68
- return 0;
69
- }
70
-
71
- const time = this.windbackState.cursor.toMillis();
72
-
73
- const left = this.#timeZero.toMillis();
74
- const right = this.#now.toMillis();
75
-
76
- const range = right - left;
77
-
78
- const norm = (time - left) / range;
79
-
80
- return norm * this.#widthPx;
81
- }
82
-
83
- registerEvents(events: string[]) {
84
- events.forEach((event) => this.#visibleEvents.add(event));
85
- }
86
-
87
- get rightTime(): DateTime {
88
- return this.#rightTime ?? this.#now;
89
- }
90
-
91
- set rightTime(_value: DateTime) {
92
- throw new Error('Cannot set rightTime use rightTimeMilis');
93
- }
94
-
95
- get rightTimeMilis(): number {
96
- return this.#rightTimeMilis ?? this.#now.toMillis();
97
- }
98
-
99
- set rightTimeMilis(_value: number) {
100
- throw new Error('Cannot set rightTimeMilis. [readonly]');
101
- }
102
-
103
- get durationMilisPerPx(): number {
104
- return this.#durationMilisPerPx;
105
- }
106
-
107
- set durationMilisPerPx(_value: number) {
108
- throw new Error('Cannot set durationMilisPerPx. [readonly]');
109
- }
110
-
111
- get leftTime(): DateTime {
112
- return this.#leftTime;
113
- }
114
-
115
- set leftTime(_value: DateTime) {
116
- throw new Error('Cannot set leftTime [readonly]');
117
- }
118
-
119
- get leftTimeMilis(): number {
120
- return this.#leftTimeMilis;
121
- }
122
-
123
- set leftTimeMilis(_value: number) {
124
- throw new Error('Cannot set leftTimeMilis [readonly]');
125
- }
126
-
127
- get timeRangeMilis(): number {
128
- return this.#timeRangeMilis;
129
- }
130
-
131
- set timeRangeMilis(_value: number) {
132
- throw new Error('Cannot set timeRangeMilis [readonly]');
133
- }
134
-
135
- get milisPerPx(): number {
136
- return this.#timeRangeMilis / this.#widthPx;
137
- }
138
-
139
- set milisPerPx(_value: number) {
140
- throw new Error('Cannot set milisPerPx [readonly]');
141
- }
142
-
143
- set width(value: number) {
144
- this.#widthPx = value;
145
- }
146
-
147
- get width(): number {
148
- return this.#widthPx;
149
- }
150
-
151
- set timeZero(value: DateTime) {
152
- this.#timeZero = value;
153
- }
154
-
155
- get timeZero(): DateTime {
156
- return this.#timeZero;
157
- }
158
-
159
- get now(): DateTime {
160
- return this.#now;
161
- }
162
-
163
- set now(_value: DateTime) {
164
- throw new Error('Cannot set now [readonly]');
165
- }
166
-
167
- set mouseX(value: number) {
168
- this.#mouseX = value;
169
- }
170
-
171
- get isOverWindback(): boolean {
172
- return Math.abs(this.#mouseX - this.windbackX) < 10;
173
- }
174
-
175
- get mouseX(): number {
176
- if (!this.windbackState.ctx) {
177
- return this.#mouseX;
178
- }
179
-
180
- if (this.isOverWindback) {
181
- return this.windbackX;
182
- }
183
-
184
- return this.#mouseX;
185
- }
186
-
187
- get mouseTime(): DateTime {
188
- const milis = this.#leftTimeMilis + this.#mouseX * this.#durationMilisPerPx;
189
- return fromMillisMemo(milis);
190
- }
191
-
192
- set mouseTime(_value: DateTime) {
193
- throw new Error('Cannot set mouseTime [readonly]');
194
- }
195
-
196
- get mouseTimeRelative(): Duration {
197
- return this.#now.diff(this.mouseTime);
198
- }
199
-
200
- get allEventTimestamps(): number[] {
201
- const times = Array.from(this.#visibleEvents.values()).map((ts) => fromISOMemo(ts).toMillis());
202
-
203
- const adjustedMs = times.map((t) => t - this.#timeZero.toMillis());
204
-
205
- const remap = (t: number) => {
206
- return (t / (this.#now.toMillis() - this.#timeZero.toMillis())) * this.#widthPx;
207
- };
208
-
209
- const adjustedPx = adjustedMs.map(remap).map(Math.round);
210
-
211
- return uniq(adjustedPx);
212
- }
213
-
214
- set allEventTimestamps(_value: number[]) {
215
- throw new Error('Cannot set allEventTimestamps [readonly]');
216
- }
217
-
218
- get majorResolution(): Resolution {
219
- return resolutions[this.majorResolutionIndex];
220
- }
221
-
222
- get majorResolutionIndex(): number {
223
- const real = resolutions.findIndex(
224
- (resolution) => resolution.milis * (1 / this.#durationMilisPerPx) >= 100
225
- );
226
-
227
- const safe = Math.max(0, Math.min(real, resolutions.length - 1));
228
-
229
- return safe;
230
- }
231
-
232
- get majors() {
233
- const majorWidth = this.majorResolution.milis / this.durationMilisPerPx;
234
-
235
- const majorLefts = this.width / majorWidth + 2;
236
-
237
- const firstMajorTime = this.leftTimeMilis - (this.leftTimeMilis % this.majorResolution.milis);
238
-
239
- const majorTimes = Array.from({ length: majorLefts }).map(
240
- (_, i) => firstMajorTime + i * this.majorResolution.milis
241
- );
242
-
243
- const majorBundles = majorTimes.map((x) => {
244
- const leftTimeMilis = x - this.leftTimeMilis;
245
- const leftPx = leftTimeMilis / this.durationMilisPerPx;
246
- return {
247
- leftPx,
248
- time: x
249
- };
250
- });
251
-
252
- return majorBundles;
253
- }
254
-
255
- get minorResolution(): Resolution {
256
- const minorIndex = this.majorResolutionIndex - 1;
257
- if (minorIndex < 0) {
258
- return resolutions[0];
259
- }
260
-
261
- if (minorIndex > resolutions.length - 1) {
262
- return resolutions[resolutions.length - 1];
263
- }
264
-
265
- return resolutions[minorIndex];
266
- }
267
-
268
- get minors() {
269
- const numMinors = this.majorResolution.milis / this.minorResolution.milis - 1;
270
-
271
- const minorWidth = this.minorResolution.milis / this.durationMilisPerPx;
272
-
273
- const minorLefts = Array.from({ length: numMinors }).map((_, i) => ({
274
- leftPx: (i + 1) * minorWidth,
275
- time: (i + 1) * this.minorResolution.milis
276
- }));
277
-
278
- return minorLefts;
279
- }
280
-
281
- zoomAllTheWayOut() {
282
- this.#rightTimeMilis = this.#now.toMillis();
283
- this.#leftTimeMilis = this.#timeZero.toMillis();
284
- }
285
-
286
- zoom(delta: number) {
287
- const factor = 1 + delta / 1000;
288
- const oldTimeRangeMilis = this.#timeRangeMilis;
289
- const newTimeRangeMilis = oldTimeRangeMilis * factor;
290
-
291
- const normX = this.#mouseX / this.#widthPx;
292
-
293
- const timeRangeDiff = newTimeRangeMilis - oldTimeRangeMilis;
294
-
295
- const rightTimeDiff = timeRangeDiff * (1 - normX);
296
- const leftTimeDiff = timeRangeDiff * normX;
297
-
298
- const nowMilis = DateTime.now().toMillis();
299
- const leftTimeMilis = this.leftTime.toMillis();
300
- const rightTimeMilis = this.rightTime.toMillis();
301
-
302
- const newRightTimeMilis = Math.min(rightTimeMilis + rightTimeDiff, nowMilis);
303
- const newLeftTimeMilis = Math.max(leftTimeMilis - leftTimeDiff, this.#timeZero.toMillis());
304
-
305
- this.#rightTimeMilis = newRightTimeMilis;
306
-
307
- this.#leftTimeMilis = newLeftTimeMilis;
308
- }
309
-
310
- pan(delta: number) {
311
- const factor = delta / -5000;
312
-
313
- const timeRangeMilis = this.#timeRangeMilis;
314
-
315
- const timeDiff = timeRangeMilis * factor;
316
-
317
- const newLeftTimeMilis = this.leftTime.toMillis() + timeDiff;
318
- const newRightTimeMilis = this.rightTime.toMillis() + timeDiff;
319
-
320
- const nowMilis = DateTime.now().toMillis();
321
- const zeroMilis = this.#timeZero.toMillis();
322
-
323
- if (newRightTimeMilis > nowMilis) {
324
- const diff = newRightTimeMilis - nowMilis;
325
-
326
- const adjustedNewLeftTimeMilis = newLeftTimeMilis - diff;
327
-
328
- this.#rightTimeMilis = nowMilis;
329
- this.#leftTimeMilis = adjustedNewLeftTimeMilis;
330
-
331
- return;
332
- }
333
-
334
- if (newLeftTimeMilis < zeroMilis) {
335
- const diff = zeroMilis - newLeftTimeMilis;
336
-
337
- const adjustedNewRightTimeMilis = newRightTimeMilis + diff;
338
-
339
- this.#leftTimeMilis = zeroMilis;
340
- this.#rightTimeMilis = adjustedNewRightTimeMilis;
341
-
342
- return;
343
- }
344
-
345
- this.#leftTimeMilis = newLeftTimeMilis;
346
- this.#rightTimeMilis = newRightTimeMilis;
347
- }
348
-
349
- startDragWindback() {
350
- if (!this.windbackState.ctx) {
351
- return;
352
- }
353
-
354
- if (!this.isOverWindback) {
355
- return;
356
- }
357
- this.#draggingWindback = true;
358
- }
359
-
360
- stopDragWindback() {
361
- this.#draggingWindback = false;
362
- this.windbackState.saveWindbackTime();
363
- }
364
- }
365
-
366
- export const TRANSACTIONS_VIEW_STATE = Symbol('transactions-view-state');
367
-
368
- export const FULL_DATE_FORMAT = `yyyy-MM-dd HH:mm:ss`;
369
-
370
- export const fromISOMemo = memoizeWith((isoString) => isoString, DateTime.fromISO);
371
- export const fromMillisMemo = memoizeWith((millis) => millis.toString(), DateTime.fromMillis);
372
- export const isoToMillisMemo = memoizeWith(
373
- (isoString) => isoString,
374
- (isoString: string) => DateTime.fromISO(isoString).toMillis()
375
- );
@@ -1,88 +0,0 @@
1
- import { myko as client } from '../../services/svelte-client.svelte.js';
2
- import {
3
- ClearClientWindbackTime,
4
- SetClientWindbackTime,
5
- WindbackStatus,
6
- type MItemStub,
7
- type WindbackStatusOutput
8
- } from '@myko/core';
9
- import { DateTime } from 'luxon';
10
-
11
- export class WindbackState {
12
- #ctx: Omit<MItemStub, 'hash'> | undefined = $state();
13
-
14
- #liveWindbackTime: string | null = $state(null);
15
-
16
- #localWindbackTime: DateTime | undefined = $state();
17
-
18
- constructor() {
19
- client.watchReport(new WindbackStatus({})).subscribe((result: WindbackStatusOutput) => {
20
- this.#liveWindbackTime = result.windback;
21
- this.#localWindbackTime = result.windback ? DateTime.fromISO(result.windback) : undefined;
22
- });
23
- }
24
-
25
- get ctx(): Omit<MItemStub, 'hash'> | undefined {
26
- return this.#ctx;
27
- }
28
-
29
- set ctx(value: Omit<MItemStub, 'hash'> | undefined) {
30
- this.#ctx = value;
31
- }
32
-
33
- get windingBack() {
34
- return !!this.#liveWindbackTime && !!this.#ctx;
35
- }
36
-
37
- get cursor(): DateTime | undefined {
38
- return this.#localWindbackTime ? this.#localWindbackTime : undefined;
39
- }
40
-
41
- get caughtUp() {
42
- console.log('Caught up', this.#liveWindbackTime, this.#localWindbackTime?.toUTC()?.toISO());
43
- return this.#liveWindbackTime === this.#localWindbackTime?.toUTC()?.toISO();
44
- }
45
-
46
- updateCursor(time: DateTime) {
47
- this.#localWindbackTime = time;
48
- }
49
-
50
- saveWindbackTime() {
51
- if (!this.#ctx) {
52
- return;
53
- }
54
-
55
- if (!this.#localWindbackTime) {
56
- return;
57
- }
58
-
59
- const valid = this.#localWindbackTime.toUTC().toISO();
60
-
61
- if (!valid) {
62
- console.error('Invalid time', this.#localWindbackTime);
63
- return;
64
- }
65
- client.sendCommand(new SetClientWindbackTime({ windback: valid }));
66
- }
67
- }
68
-
69
- export const windbackState = new WindbackState();
70
-
71
- export const startWindback = (root: Omit<MItemStub, 'hash'>) => {
72
- const windback = DateTime.utc().minus({ seconds: 5 }).toISO();
73
- if (!windback) return;
74
-
75
- client
76
- .sendCommand(new SetClientWindbackTime({ windback }))
77
- .then((x) => {
78
- if (!x) {
79
- return;
80
- }
81
- windbackState.ctx = root;
82
- });
83
- };
84
-
85
- export const exitWindback = () => {
86
- windbackState.ctx = undefined;
87
- client.sendCommand(new ClearClientWindbackTime({}));
88
- };