@myko/ui-svelte 4.4.1 → 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 +8 -4
  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
@@ -0,0 +1,259 @@
1
+ import { DateTime } from 'luxon';
2
+ import { memoizeWith, uniq } from 'ramda';
3
+ import { SvelteSet } from 'svelte/reactivity';
4
+ import { resolutions } from './resolutions.js';
5
+ export class TransactionsViewState {
6
+ windbackState;
7
+ #visibleEvents = new SvelteSet();
8
+ #timeZero = $state(DateTime.now());
9
+ #leftTimeMilis = $state(DateTime.utc().minus({ minutes: 1 }).toMillis());
10
+ #rightTimeMilis = $state(DateTime.now().toMillis());
11
+ #widthPx = $state(0);
12
+ #now = $state(DateTime.now());
13
+ #mouseX = $state(0);
14
+ #draggingWindback = $state(false);
15
+ #leftTime = $derived(fromMillisMemo(this.#leftTimeMilis));
16
+ #rightTime = $derived(this.#rightTimeMilis ? fromMillisMemo(this.#rightTimeMilis) : null);
17
+ #timeRangeMilis = $derived(this.rightTimeMilis - this.#leftTimeMilis);
18
+ #durationMilisPerPx = $derived(this.#timeRangeMilis / this.#widthPx);
19
+ constructor(windbackState) {
20
+ this.windbackState = windbackState;
21
+ const updateTime = () => {
22
+ this.#now = DateTime.now();
23
+ requestAnimationFrame(updateTime);
24
+ };
25
+ updateTime();
26
+ $effect(() => {
27
+ if (!this.#draggingWindback)
28
+ return;
29
+ this.windbackState.updateCursor(this.mouseTime);
30
+ });
31
+ }
32
+ get windbackX() {
33
+ if (!this.windbackState.cursor) {
34
+ return 0;
35
+ }
36
+ const time = this.windbackState.cursor.toMillis();
37
+ const left = this.#leftTimeMilis;
38
+ const right = this.rightTimeMilis;
39
+ const range = right - left;
40
+ const norm = (time - left) / range;
41
+ return norm * this.#widthPx;
42
+ }
43
+ get windbackFullX() {
44
+ if (!this.windbackState.cursor) {
45
+ return 0;
46
+ }
47
+ const time = this.windbackState.cursor.toMillis();
48
+ const left = this.#timeZero.toMillis();
49
+ const right = this.#now.toMillis();
50
+ const range = right - left;
51
+ const norm = (time - left) / range;
52
+ return norm * this.#widthPx;
53
+ }
54
+ registerEvents(events) {
55
+ events.forEach((event) => this.#visibleEvents.add(event));
56
+ }
57
+ get rightTime() {
58
+ return this.#rightTime ?? this.#now;
59
+ }
60
+ set rightTime(_value) {
61
+ throw new Error('Cannot set rightTime use rightTimeMilis');
62
+ }
63
+ get rightTimeMilis() {
64
+ return this.#rightTimeMilis ?? this.#now.toMillis();
65
+ }
66
+ set rightTimeMilis(_value) {
67
+ throw new Error('Cannot set rightTimeMilis. [readonly]');
68
+ }
69
+ get durationMilisPerPx() {
70
+ return this.#durationMilisPerPx;
71
+ }
72
+ set durationMilisPerPx(_value) {
73
+ throw new Error('Cannot set durationMilisPerPx. [readonly]');
74
+ }
75
+ get leftTime() {
76
+ return this.#leftTime;
77
+ }
78
+ set leftTime(_value) {
79
+ throw new Error('Cannot set leftTime [readonly]');
80
+ }
81
+ get leftTimeMilis() {
82
+ return this.#leftTimeMilis;
83
+ }
84
+ set leftTimeMilis(_value) {
85
+ throw new Error('Cannot set leftTimeMilis [readonly]');
86
+ }
87
+ get timeRangeMilis() {
88
+ return this.#timeRangeMilis;
89
+ }
90
+ set timeRangeMilis(_value) {
91
+ throw new Error('Cannot set timeRangeMilis [readonly]');
92
+ }
93
+ get milisPerPx() {
94
+ return this.#timeRangeMilis / this.#widthPx;
95
+ }
96
+ set milisPerPx(_value) {
97
+ throw new Error('Cannot set milisPerPx [readonly]');
98
+ }
99
+ set width(value) {
100
+ this.#widthPx = value;
101
+ }
102
+ get width() {
103
+ return this.#widthPx;
104
+ }
105
+ set timeZero(value) {
106
+ this.#timeZero = value;
107
+ }
108
+ get timeZero() {
109
+ return this.#timeZero;
110
+ }
111
+ get now() {
112
+ return this.#now;
113
+ }
114
+ set now(_value) {
115
+ throw new Error('Cannot set now [readonly]');
116
+ }
117
+ set mouseX(value) {
118
+ this.#mouseX = value;
119
+ }
120
+ get isOverWindback() {
121
+ return Math.abs(this.#mouseX - this.windbackX) < 10;
122
+ }
123
+ get mouseX() {
124
+ if (!this.windbackState.ctx) {
125
+ return this.#mouseX;
126
+ }
127
+ if (this.isOverWindback) {
128
+ return this.windbackX;
129
+ }
130
+ return this.#mouseX;
131
+ }
132
+ get mouseTime() {
133
+ const milis = this.#leftTimeMilis + this.#mouseX * this.#durationMilisPerPx;
134
+ return fromMillisMemo(milis);
135
+ }
136
+ set mouseTime(_value) {
137
+ throw new Error('Cannot set mouseTime [readonly]');
138
+ }
139
+ get mouseTimeRelative() {
140
+ return this.#now.diff(this.mouseTime);
141
+ }
142
+ get allEventTimestamps() {
143
+ const times = Array.from(this.#visibleEvents.values()).map((ts) => fromISOMemo(ts).toMillis());
144
+ const adjustedMs = times.map((t) => t - this.#timeZero.toMillis());
145
+ const remap = (t) => {
146
+ return (t / (this.#now.toMillis() - this.#timeZero.toMillis())) * this.#widthPx;
147
+ };
148
+ const adjustedPx = adjustedMs.map(remap).map(Math.round);
149
+ return uniq(adjustedPx);
150
+ }
151
+ set allEventTimestamps(_value) {
152
+ throw new Error('Cannot set allEventTimestamps [readonly]');
153
+ }
154
+ get majorResolution() {
155
+ return resolutions[this.majorResolutionIndex];
156
+ }
157
+ get majorResolutionIndex() {
158
+ const real = resolutions.findIndex((resolution) => resolution.milis * (1 / this.#durationMilisPerPx) >= 100);
159
+ const safe = Math.max(0, Math.min(real, resolutions.length - 1));
160
+ return safe;
161
+ }
162
+ get majors() {
163
+ const majorWidth = this.majorResolution.milis / this.durationMilisPerPx;
164
+ const majorLefts = this.width / majorWidth + 2;
165
+ const firstMajorTime = this.leftTimeMilis - (this.leftTimeMilis % this.majorResolution.milis);
166
+ const majorTimes = Array.from({ length: majorLefts }).map((_, i) => firstMajorTime + i * this.majorResolution.milis);
167
+ const majorBundles = majorTimes.map((x) => {
168
+ const leftTimeMilis = x - this.leftTimeMilis;
169
+ const leftPx = leftTimeMilis / this.durationMilisPerPx;
170
+ return {
171
+ leftPx,
172
+ time: x
173
+ };
174
+ });
175
+ return majorBundles;
176
+ }
177
+ get minorResolution() {
178
+ const minorIndex = this.majorResolutionIndex - 1;
179
+ if (minorIndex < 0) {
180
+ return resolutions[0];
181
+ }
182
+ if (minorIndex > resolutions.length - 1) {
183
+ return resolutions[resolutions.length - 1];
184
+ }
185
+ return resolutions[minorIndex];
186
+ }
187
+ get minors() {
188
+ const numMinors = this.majorResolution.milis / this.minorResolution.milis - 1;
189
+ const minorWidth = this.minorResolution.milis / this.durationMilisPerPx;
190
+ const minorLefts = Array.from({ length: numMinors }).map((_, i) => ({
191
+ leftPx: (i + 1) * minorWidth,
192
+ time: (i + 1) * this.minorResolution.milis
193
+ }));
194
+ return minorLefts;
195
+ }
196
+ zoomAllTheWayOut() {
197
+ this.#rightTimeMilis = this.#now.toMillis();
198
+ this.#leftTimeMilis = this.#timeZero.toMillis();
199
+ }
200
+ zoom(delta) {
201
+ const factor = 1 + delta / 1000;
202
+ const oldTimeRangeMilis = this.#timeRangeMilis;
203
+ const newTimeRangeMilis = oldTimeRangeMilis * factor;
204
+ const normX = this.#mouseX / this.#widthPx;
205
+ const timeRangeDiff = newTimeRangeMilis - oldTimeRangeMilis;
206
+ const rightTimeDiff = timeRangeDiff * (1 - normX);
207
+ const leftTimeDiff = timeRangeDiff * normX;
208
+ const nowMilis = DateTime.now().toMillis();
209
+ const leftTimeMilis = this.leftTime.toMillis();
210
+ const rightTimeMilis = this.rightTime.toMillis();
211
+ const newRightTimeMilis = Math.min(rightTimeMilis + rightTimeDiff, nowMilis);
212
+ const newLeftTimeMilis = Math.max(leftTimeMilis - leftTimeDiff, this.#timeZero.toMillis());
213
+ this.#rightTimeMilis = newRightTimeMilis;
214
+ this.#leftTimeMilis = newLeftTimeMilis;
215
+ }
216
+ pan(delta) {
217
+ const factor = delta / -5000;
218
+ const timeRangeMilis = this.#timeRangeMilis;
219
+ const timeDiff = timeRangeMilis * factor;
220
+ const newLeftTimeMilis = this.leftTime.toMillis() + timeDiff;
221
+ const newRightTimeMilis = this.rightTime.toMillis() + timeDiff;
222
+ const nowMilis = DateTime.now().toMillis();
223
+ const zeroMilis = this.#timeZero.toMillis();
224
+ if (newRightTimeMilis > nowMilis) {
225
+ const diff = newRightTimeMilis - nowMilis;
226
+ const adjustedNewLeftTimeMilis = newLeftTimeMilis - diff;
227
+ this.#rightTimeMilis = nowMilis;
228
+ this.#leftTimeMilis = adjustedNewLeftTimeMilis;
229
+ return;
230
+ }
231
+ if (newLeftTimeMilis < zeroMilis) {
232
+ const diff = zeroMilis - newLeftTimeMilis;
233
+ const adjustedNewRightTimeMilis = newRightTimeMilis + diff;
234
+ this.#leftTimeMilis = zeroMilis;
235
+ this.#rightTimeMilis = adjustedNewRightTimeMilis;
236
+ return;
237
+ }
238
+ this.#leftTimeMilis = newLeftTimeMilis;
239
+ this.#rightTimeMilis = newRightTimeMilis;
240
+ }
241
+ startDragWindback() {
242
+ if (!this.windbackState.ctx) {
243
+ return;
244
+ }
245
+ if (!this.isOverWindback) {
246
+ return;
247
+ }
248
+ this.#draggingWindback = true;
249
+ }
250
+ stopDragWindback() {
251
+ this.#draggingWindback = false;
252
+ this.windbackState.saveWindbackTime();
253
+ }
254
+ }
255
+ export const TRANSACTIONS_VIEW_STATE = Symbol('transactions-view-state');
256
+ export const FULL_DATE_FORMAT = `yyyy-MM-dd HH:mm:ss`;
257
+ export const fromISOMemo = memoizeWith((isoString) => isoString, DateTime.fromISO);
258
+ export const fromMillisMemo = memoizeWith((millis) => millis.toString(), DateTime.fromMillis);
259
+ export const isoToMillisMemo = memoizeWith((isoString) => isoString, (isoString) => DateTime.fromISO(isoString).toMillis());
@@ -0,0 +1,16 @@
1
+ import { type MItemStub } from '@myko/core';
2
+ import { DateTime } from 'luxon';
3
+ export declare class WindbackState {
4
+ #private;
5
+ constructor();
6
+ get ctx(): Omit<MItemStub, 'hash'> | undefined;
7
+ set ctx(value: Omit<MItemStub, 'hash'> | undefined);
8
+ get windingBack(): boolean;
9
+ get cursor(): DateTime | undefined;
10
+ get caughtUp(): boolean;
11
+ updateCursor(time: DateTime): void;
12
+ saveWindbackTime(): void;
13
+ }
14
+ export declare const windbackState: WindbackState;
15
+ export declare const startWindback: (root: Omit<MItemStub, "hash">) => void;
16
+ export declare const exitWindback: () => void;
@@ -0,0 +1,65 @@
1
+ import { myko as client } from '../../services/svelte-client.svelte.js';
2
+ import { ClearClientWindbackTime, SetClientWindbackTime, WindbackStatus } from '@myko/core';
3
+ import { DateTime } from 'luxon';
4
+ export class WindbackState {
5
+ #ctx = $state();
6
+ #liveWindbackTime = $state(null);
7
+ #localWindbackTime = $state();
8
+ constructor() {
9
+ client.watchReport(new WindbackStatus({})).subscribe((result) => {
10
+ this.#liveWindbackTime = result.windback;
11
+ this.#localWindbackTime = result.windback ? DateTime.fromISO(result.windback) : undefined;
12
+ });
13
+ }
14
+ get ctx() {
15
+ return this.#ctx;
16
+ }
17
+ set ctx(value) {
18
+ this.#ctx = value;
19
+ }
20
+ get windingBack() {
21
+ return !!this.#liveWindbackTime && !!this.#ctx;
22
+ }
23
+ get cursor() {
24
+ return this.#localWindbackTime ? this.#localWindbackTime : undefined;
25
+ }
26
+ get caughtUp() {
27
+ console.log('Caught up', this.#liveWindbackTime, this.#localWindbackTime?.toUTC()?.toISO());
28
+ return this.#liveWindbackTime === this.#localWindbackTime?.toUTC()?.toISO();
29
+ }
30
+ updateCursor(time) {
31
+ this.#localWindbackTime = time;
32
+ }
33
+ saveWindbackTime() {
34
+ if (!this.#ctx) {
35
+ return;
36
+ }
37
+ if (!this.#localWindbackTime) {
38
+ return;
39
+ }
40
+ const valid = this.#localWindbackTime.toUTC().toISO();
41
+ if (!valid) {
42
+ console.error('Invalid time', this.#localWindbackTime);
43
+ return;
44
+ }
45
+ client.sendCommand(new SetClientWindbackTime({ windback: valid }));
46
+ }
47
+ }
48
+ export const windbackState = new WindbackState();
49
+ export const startWindback = (root) => {
50
+ const windback = DateTime.utc().minus({ seconds: 5 }).toISO();
51
+ if (!windback)
52
+ return;
53
+ client
54
+ .sendCommand(new SetClientWindbackTime({ windback }))
55
+ .then((x) => {
56
+ if (!x) {
57
+ return;
58
+ }
59
+ windbackState.ctx = root;
60
+ });
61
+ };
62
+ export const exitWindback = () => {
63
+ windbackState.ctx = undefined;
64
+ client.sendCommand(new ClearClientWindbackTime({}));
65
+ };
@@ -0,0 +1,135 @@
1
+ <script lang="ts">import { myko as client } from "../../services/svelte-client.svelte.js";
2
+ import { ChildEntitiesAllTime, EventsForEntity } from "@myko/core";
3
+ import { startWith } from "rxjs";
4
+ import { getContext } from "svelte";
5
+ import {
6
+ fromISOMemo,
7
+ isoToMillisMemo,
8
+ TRANSACTIONS_VIEW_STATE
9
+ } from "../state/viewstate.svelte.js";
10
+ import { inview } from "svelte-inview";
11
+ import EntityHistory from "./EntityHistory.svelte";
12
+ import TransactionEvent from "./TransactionEvent.svelte";
13
+ import TransactionEventGroup from "./TransactionEventGroup.svelte";
14
+ const {
15
+ id,
16
+ itemType,
17
+ level = 0
18
+ } = $props();
19
+ const viewState = getContext(TRANSACTIONS_VIEW_STATE);
20
+ const start = $derived(viewState.leftTime.toUTC().toISO());
21
+ const end = $derived(viewState.rightTime.toUTC().toISO());
22
+ const isRoot = $derived(level == 0);
23
+ const history = client.watchQuery(new EventsForEntity(id)).pipe(startWith([]));
24
+ const name = $derived(
25
+ $history.length > 0 && $history[0].event.item && typeof $history[0].event.item === "object" && "name" in $history[0].event.item ? $history[0].event.item["name"] : `Unknown ${itemType}`
26
+ );
27
+ $effect(() => {
28
+ const firstEvent = $history && $history.length > 0 ? $history[0] : void 0;
29
+ if (isRoot && firstEvent) {
30
+ viewState.timeZero = fromISOMemo(firstEvent.event.createdAt);
31
+ }
32
+ });
33
+ $effect(() => {
34
+ viewState.registerEvents($history.map((x) => x.event.createdAt));
35
+ });
36
+ const visibleEvents = $derived(
37
+ $history.filter(
38
+ (x) => (start ? x.event.createdAt >= start : true) && (end ? x.event.createdAt <= end : true)
39
+ )
40
+ );
41
+ const visibleEventRenders = $derived(
42
+ visibleEvents.map((x) => {
43
+ const timeMilis = $derived(isoToMillisMemo(x.event.createdAt));
44
+ const leftTimeMilis = $derived(timeMilis - viewState.leftTimeMilis);
45
+ const leftPx = $derived(leftTimeMilis / viewState.durationMilisPerPx);
46
+ return {
47
+ eventContainer: x,
48
+ leftPx
49
+ };
50
+ })
51
+ );
52
+ const eventGroups = $derived(
53
+ visibleEventRenders.reduce((acc, x) => {
54
+ const lastGroup = acc[acc.length - 1];
55
+ if (lastGroup && x.leftPx - lastGroup.lastPx < 10) {
56
+ lastGroup.lastPx = x.leftPx;
57
+ lastGroup.events.push(x);
58
+ } else {
59
+ acc.push({
60
+ firstPx: x.leftPx,
61
+ lastPx: x.leftPx,
62
+ events: [x]
63
+ });
64
+ }
65
+ return acc;
66
+ }, [])
67
+ );
68
+ const children = $derived(
69
+ client.watchReport(
70
+ new ChildEntitiesAllTime({
71
+ parentType: itemType,
72
+ parentId: id
73
+ })
74
+ ).pipe(startWith([]))
75
+ );
76
+ let isInView = $state(false);
77
+ </script>
78
+
79
+ <div class="entity-history" style="min-height:{($children.length + 1) * 10}px;">
80
+ <div
81
+ class="self"
82
+ use:inview={{}}
83
+ oninview_enter={() => (isInView = true)}
84
+ oninview_leave={() => (isInView = false)}
85
+ >
86
+ <h2 style="margin-left: {level * 1}rem;">
87
+ {name}
88
+ {$children.length}
89
+ </h2>
90
+ <div class="events">
91
+ {#if isInView}
92
+ {#each eventGroups as group}
93
+ {#if group.events.length === 1}
94
+ <TransactionEvent event={group.events[0].eventContainer.event} />
95
+ {:else}
96
+ <TransactionEventGroup
97
+ firstPx={group.firstPx}
98
+ lastPx={group.lastPx}
99
+ numEvents={group.events.length}
100
+ />
101
+ {/if}
102
+ {/each}
103
+ {/if}
104
+ </div>
105
+ </div>
106
+
107
+ {#each $children as child (child.id)}
108
+ <EntityHistory id={child.id} itemType={child.itemType} level={level + 1} />
109
+ {/each}
110
+ </div>
111
+
112
+ <style>
113
+ .self {
114
+ display: flex;
115
+ align-items: center;
116
+ position: relative;
117
+ margin-bottom: 0.1rem;
118
+ }
119
+ .entity-history {
120
+ position: relative;
121
+ background-color: rgba(255, 255, 255, 0.05);
122
+ min-height: 10px;
123
+ }
124
+
125
+ h2 {
126
+ opacity: 0.5;
127
+ }
128
+
129
+ .events {
130
+ position: absolute;
131
+ display: flex;
132
+ align-items: center;
133
+ inset: 0;
134
+ }
135
+ </style>
@@ -0,0 +1,10 @@
1
+ import { type ID } from '@myko/core';
2
+ import EntityHistory from './EntityHistory.svelte';
3
+ type $$ComponentProps = {
4
+ id: ID;
5
+ itemType: string;
6
+ level?: number;
7
+ };
8
+ declare const EntityHistory: import("svelte").Component<$$ComponentProps, {}, "">;
9
+ type EntityHistory = ReturnType<typeof EntityHistory>;
10
+ export default EntityHistory;
@@ -1,28 +1,21 @@
1
- <script lang="ts">
2
- import { DateTime } from 'luxon';
3
- import { getContext } from 'svelte';
4
- import {
5
- FULL_DATE_FORMAT,
6
- TRANSACTIONS_VIEW_STATE,
7
- type TransactionsViewState
8
- } from '../state/viewstate.svelte.js';
9
- import { windbackState } from '../state/windback.svelte.js';
10
-
11
- const viewState = getContext(TRANSACTIONS_VIEW_STATE) as TransactionsViewState;
12
-
13
- const fullDuration = $derived(viewState.now.diff(viewState.timeZero));
14
-
15
- const viewLeftDuration = $derived(viewState.leftTime.diff(viewState.timeZero));
16
- const viewDuration = $derived(viewState.rightTime.diff(viewState.leftTime));
17
-
18
- const viewLeftPx = $derived(
19
- (viewLeftDuration.as('milliseconds') / fullDuration.as('milliseconds')) * viewState.width
20
- );
21
- const viewWidthPx = $derived(
22
- (viewDuration.as('milliseconds') / fullDuration.as('milliseconds')) * viewState.width
23
- );
24
-
25
- let timestampsEl: HTMLElement | null = $state(null);
1
+ <script lang="ts">import { DateTime } from "luxon";
2
+ import { getContext } from "svelte";
3
+ import {
4
+ FULL_DATE_FORMAT,
5
+ TRANSACTIONS_VIEW_STATE
6
+ } from "../state/viewstate.svelte.js";
7
+ import { windbackState } from "../state/windback.svelte.js";
8
+ const viewState = getContext(TRANSACTIONS_VIEW_STATE);
9
+ const fullDuration = $derived(viewState.now.diff(viewState.timeZero));
10
+ const viewLeftDuration = $derived(viewState.leftTime.diff(viewState.timeZero));
11
+ const viewDuration = $derived(viewState.rightTime.diff(viewState.leftTime));
12
+ const viewLeftPx = $derived(
13
+ viewLeftDuration.as("milliseconds") / fullDuration.as("milliseconds") * viewState.width
14
+ );
15
+ const viewWidthPx = $derived(
16
+ viewDuration.as("milliseconds") / fullDuration.as("milliseconds") * viewState.width
17
+ );
18
+ let timestampsEl = $state(null);
26
19
  </script>
27
20
 
28
21
  <div class="all-time">
@@ -0,0 +1,3 @@
1
+ declare const TimeStrip: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type TimeStrip = ReturnType<typeof TimeStrip>;
3
+ export default TimeStrip;
@@ -0,0 +1,24 @@
1
+ <script lang="ts">import { myko as client } from "../../services/svelte-client.svelte.js";
2
+ import { EventsForTransaction } from "@myko/core";
3
+ import { fromISOMemo, FULL_DATE_FORMAT } from "../state/viewstate.svelte.js";
4
+ const { tx } = $props();
5
+ const events = client.watchReport(new EventsForTransaction({ transactionId: tx }));
6
+ </script>
7
+
8
+ {#if $events}
9
+ {#each $events as event (event)}
10
+ <div class="div">
11
+ <p>{event.itemType}</p>
12
+ <p>{event.changeType}</p>
13
+ <p>{fromISOMemo(event.createdAt).diffNow().toHuman()}</p>
14
+ <p>{fromISOMemo(event.createdAt).toFormat(FULL_DATE_FORMAT)}</p>
15
+ </div>
16
+ {/each}
17
+ {/if}
18
+
19
+ <style>
20
+ .div {
21
+ display: flex;
22
+ gap: 1rem;
23
+ }
24
+ </style>
@@ -0,0 +1,7 @@
1
+ import { type ID } from '@myko/core';
2
+ type $$ComponentProps = {
3
+ tx: ID;
4
+ };
5
+ declare const TransactionDetails: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type TransactionDetails = ReturnType<typeof TransactionDetails>;
7
+ export default TransactionDetails;
@@ -1,35 +1,23 @@
1
- <script lang="ts">
2
- import type { MEvent } from '@myko/core';
3
- import { getContext } from 'svelte';
4
- import {
5
- fromISOMemo,
6
- FULL_DATE_FORMAT,
7
- isoToMillisMemo,
8
- TRANSACTIONS_VIEW_STATE,
9
- type TransactionsViewState
10
- } from '../state/viewstate.svelte.js';
11
-
12
- const { event }: { event: MEvent } = $props();
13
-
14
- const timeMilis = $derived(isoToMillisMemo(event.createdAt));
15
-
16
- const viewState = getContext(TRANSACTIONS_VIEW_STATE) as TransactionsViewState;
17
-
18
- const leftTimeMilis = $derived(timeMilis - viewState.leftTimeMilis);
19
-
20
- const leftPx = $derived(leftTimeMilis / viewState.durationMilisPerPx);
21
-
22
- let showDetail = $state(false);
23
-
24
- const onmouseover = () => {
25
- showDetail = true;
26
- };
27
-
28
- const onmouseleave = () => {
29
- showDetail = false;
30
- };
31
-
32
- const time = $derived(fromISOMemo(event.createdAt));
1
+ <script lang="ts">import { getContext } from "svelte";
2
+ import {
3
+ fromISOMemo,
4
+ FULL_DATE_FORMAT,
5
+ isoToMillisMemo,
6
+ TRANSACTIONS_VIEW_STATE
7
+ } from "../state/viewstate.svelte.js";
8
+ const { event } = $props();
9
+ const timeMilis = $derived(isoToMillisMemo(event.createdAt));
10
+ const viewState = getContext(TRANSACTIONS_VIEW_STATE);
11
+ const leftTimeMilis = $derived(timeMilis - viewState.leftTimeMilis);
12
+ const leftPx = $derived(leftTimeMilis / viewState.durationMilisPerPx);
13
+ let showDetail = $state(false);
14
+ const onmouseover = () => {
15
+ showDetail = true;
16
+ };
17
+ const onmouseleave = () => {
18
+ showDetail = false;
19
+ };
20
+ const time = $derived(fromISOMemo(event.createdAt));
33
21
  </script>
34
22
 
35
23
  <div class="event {event.changeType}" style="left: {leftPx}px;">
@@ -0,0 +1,7 @@
1
+ import type { MEvent } from '@myko/core';
2
+ type $$ComponentProps = {
3
+ event: MEvent;
4
+ };
5
+ declare const TransactionEvent: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type TransactionEvent = ReturnType<typeof TransactionEvent>;
7
+ export default TransactionEvent;
@@ -1,16 +1,11 @@
1
- <script lang="ts">
2
- const { firstPx, lastPx, numEvents }: { firstPx: number; lastPx: number; numEvents: number } =
3
- $props();
4
-
5
- let showDetail = $state(false);
6
-
7
- const onmouseover = () => {
8
- showDetail = true;
9
- };
10
-
11
- const onmouseleave = () => {
12
- showDetail = false;
13
- };
1
+ <script lang="ts">const { firstPx, lastPx, numEvents } = $props();
2
+ let showDetail = $state(false);
3
+ const onmouseover = () => {
4
+ showDetail = true;
5
+ };
6
+ const onmouseleave = () => {
7
+ showDetail = false;
8
+ };
14
9
  </script>
15
10
 
16
11
  <div class="event" style="left: {firstPx}px; width: {lastPx - firstPx}px;">
@@ -0,0 +1,8 @@
1
+ type $$ComponentProps = {
2
+ firstPx: number;
3
+ lastPx: number;
4
+ numEvents: number;
5
+ };
6
+ declare const TransactionEventGroup: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type TransactionEventGroup = ReturnType<typeof TransactionEventGroup>;
8
+ export default TransactionEventGroup;