Skip to content

Commit a7bab98

Browse files
committed
add a fe-update reason
1 parent ee13114 commit a7bab98

3 files changed

Lines changed: 54 additions & 23 deletions

File tree

tsunami/frontend/src/model/tsunami-model.tsx

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,15 @@ export class TsunamiModel {
102102
hasBackendWork: boolean = false;
103103
noPadding: jotai.PrimitiveAtom<boolean>;
104104
cachedFaviconPath: string | null = null;
105+
reason: string | null = null;
105106

106107
constructor() {
107108
this.clientId = getOrCreateClientId();
108109
this.contextActive = jotai.atom(false);
109110
this.reset();
110111
this.noPadding = jotai.atom(true);
111112
this.setupServerEventSource();
112-
this.queueUpdate(true);
113+
this.queueUpdate(true, "initial");
113114
}
114115

115116
dispose() {
@@ -129,7 +130,7 @@ export class TsunamiModel {
129130

130131
this.serverEventSource.addEventListener("asyncinitiation", (event) => {
131132
dlog("async-initiation SSE event received", event);
132-
this.queueUpdate(true);
133+
this.queueUpdate(true, "asyncinitiation");
133134
});
134135

135136
this.serverEventSource.addEventListener("error", (event) => {
@@ -165,24 +166,25 @@ export class TsunamiModel {
165166
this.refOutputStore.clear();
166167
this.globalVersion = jotai.atom(0);
167168
this.hasBackendWork = false;
169+
this.reason = null;
168170
getDefaultStore().set(this.contextActive, false);
169171
}
170172

171173
keyDownHandler(e: VDomKeyboardEvent): boolean {
172-
if (this.backendOpts?.globalkeyboardevents) {
173-
if (e.cmd || e.meta) {
174-
return false;
175-
}
176-
this.batchedEvents.push({
177-
globaleventtype: "onKeyDown",
178-
waveid: null,
179-
eventtype: "onKeyDown",
180-
keydata: e,
181-
});
182-
this.queueUpdate();
183-
return true;
174+
if (!this.backendOpts?.globalkeyboardevents) {
175+
return false;
184176
}
185-
return false;
177+
if (e.cmd || e.meta) {
178+
return false;
179+
}
180+
this.batchedEvents.push({
181+
globaleventtype: "onKeyDown",
182+
waveid: null,
183+
eventtype: "onKeyDown",
184+
keydata: e,
185+
});
186+
this.queueUpdate(false, "globalkeyboard");
187+
return true;
186188
}
187189

188190
hasRefUpdates() {
@@ -219,11 +221,29 @@ export class TsunamiModel {
219221
return updates;
220222
}
221223

222-
queueUpdate(quick: boolean = false, delay: number = 10) {
224+
mergeReasons(newReason: string): string {
225+
if (!this.reason) {
226+
return newReason;
227+
}
228+
const existingReasons = this.reason.split(",");
229+
const newReasons = newReason.split(",");
230+
for (const reason of newReasons) {
231+
if (!existingReasons.includes(reason)) {
232+
existingReasons.push(reason);
233+
}
234+
}
235+
return existingReasons.join(",");
236+
}
237+
238+
queueUpdate(quick: boolean = false, reason: string | null) {
223239
if (this.disposed) {
224240
return;
225241
}
242+
if (reason) {
243+
this.reason = this.mergeReasons(reason);
244+
}
226245
this.needsUpdate = true;
246+
let delay = 10;
227247
let nowTs = Date.now();
228248
if (delay > this.maxNormalUpdateIntervalMs) {
229249
delay = this.maxNormalUpdateIntervalMs;
@@ -312,11 +332,10 @@ export class TsunamiModel {
312332
this.hasPendingRequest = false;
313333
}
314334
if (this.needsImmediateUpdate) {
315-
this.queueUpdate(true);
335+
this.queueUpdate(true, null); // reason should already be set, dont try to add a new one
316336
}
317337
}
318338

319-
320339
getOrCreateRefContainer(vdomRef: VDomRef): RefContainer {
321340
let container = this.refs.get(vdomRef.refid);
322341
if (container == null) {
@@ -338,7 +357,6 @@ export class TsunamiModel {
338357
return container;
339358
}
340359

341-
342360
getVDomNodeVersionAtom(vdom: VDomElem) {
343361
let atom = this.vdomNodeVersion.get(vdom);
344362
if (atom == null) {
@@ -434,7 +452,6 @@ export class TsunamiModel {
434452
}
435453
}
436454

437-
438455
getRefElem(refId: string): HTMLElement {
439456
if (refId == this.rootRefId) {
440457
return this.viewRef.current;
@@ -543,9 +560,19 @@ export class TsunamiModel {
543560
renderDone(version: number) {
544561
// called when the render is done
545562
dlog("renderDone", version);
546-
if (this.hasRefUpdates() || this.hasBackendWork) {
563+
let reasons: string[] = [];
564+
let needsQueue = false;
565+
if (this.hasRefUpdates()) {
566+
reasons.push("refupdates");
567+
needsQueue = true;
568+
}
569+
if (this.hasBackendWork) {
570+
reasons.push("backendwork");
571+
needsQueue = true;
547572
this.hasBackendWork = false;
548-
this.queueUpdate(true);
573+
}
574+
if (needsQueue) {
575+
this.queueUpdate(true, reasons.join(","));
549576
}
550577
}
551578

@@ -559,7 +586,7 @@ export class TsunamiModel {
559586
}
560587
annotateEvent(vdomEvent, propName, e);
561588
this.batchedEvents.push(vdomEvent);
562-
this.queueUpdate(true);
589+
this.queueUpdate(true, "event");
563590
}
564591

565592
createFeUpdate(): VDomFrontendUpdate {
@@ -580,9 +607,11 @@ export class TsunamiModel {
580607
resync: this.needsResync,
581608
events: this.batchedEvents,
582609
refupdates: this.getRefUpdates(),
610+
reason: this.reason,
583611
};
584612
this.needsResync = false;
585613
this.batchedEvents = [];
614+
this.reason = null;
586615
if (this.shouldDispose) {
587616
this.disposed = true;
588617
}

tsunami/frontend/src/types/vdom.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type VDomFrontendUpdate = {
5252
clientid: string;
5353
forcetakeover?: boolean;
5454
correlationid?: string;
55+
reason?: string;
5556
dispose?: boolean;
5657
resync?: boolean;
5758
rendercontext: VDomRenderContext;

tsunami/rpctypes/protocoltypes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type VDomFrontendUpdate struct {
3030
ClientId string `json:"clientid"`
3131
ForceTakeover bool `json:"forcetakeover,omitempty"`
3232
CorrelationId string `json:"correlationid,omitempty"`
33+
Reason string `json:"reason,omitempty"`
3334
Dispose bool `json:"dispose,omitempty"` // the vdom context was closed
3435
Resync bool `json:"resync,omitempty"` // resync (send all backend data). useful when the FE reloads
3536
RenderContext VDomRenderContext `json:"rendercontext,omitempty"`

0 commit comments

Comments
 (0)