@zerotal/flow 1.6.3 → 1.7.2

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.
@@ -44,8 +44,15 @@ interface DevtoolsSink {
44
44
  meta?: string[];
45
45
  warn?: string;
46
46
  order?: number;
47
+ hidden?: boolean;
47
48
  }): void;
48
49
  record(ctx: object, channel: string, entry: Record<string, unknown>): void;
50
+ /**
51
+ * Optional because it postdates the sink: a project can pin a devtools older
52
+ * than this Flow, and an action that goes untraced is a worse panel, not a
53
+ * crashed one.
54
+ */
55
+ finalise?(ctx: object, meta: { startMs: number; durationMs: number; method?: string }): void;
49
56
  }
50
57
 
51
58
  // Framework/asset noise the panel shouldn't chart as realtime traffic.
@@ -134,6 +141,12 @@ export function installFlowObservability(app: Application): () => void {
134
141
 
135
142
  const trace = _observer<DevtoolsSink>(app, "devtools.trace");
136
143
  if (trace) {
144
+ // Recorded on the trace, but with no tab of its own: Flow's client panel is
145
+ // the better home for it. A time-travel frame already names the component,
146
+ // the action and the fields it changed, so a separate tab could only repeat
147
+ // that beside a duration the trace header already shows — and the frames and
148
+ // the actions are the same clicks seen from the two ends. The panel reads
149
+ // these entries off the trace and prints them on the frame they belong to.
137
150
  trace.channel({
138
151
  id: "flow",
139
152
  label: "Flow",
@@ -142,12 +155,18 @@ export function installFlowObservability(app: Application): () => void {
142
155
  meta: ["durationMs", "ip"],
143
156
  warn: "failed",
144
157
  order: 20,
158
+ hidden: true,
145
159
  });
146
160
 
147
161
  unsubs.push(
148
162
  FrameworkEvents.on(FlowActionHandled, (e) => {
149
163
  // An action round-trips over the WebSocket against its own HttpContext,
150
- // so it buffers against that context and lands on that action's trace.
164
+ // so it buffers against that context — and then has to finalise that
165
+ // context itself. Devtools builds traces from core's request lifecycle,
166
+ // and a WebSocket action fires none of it, so for as long as this call
167
+ // was missing every action buffered its evidence and dropped it: the Flow
168
+ // tab reported "no flow activity" for apps whose every interaction is a
169
+ // Flow action, and the queries those actions ran showed up nowhere.
151
170
  if (!e.ctx) return;
152
171
  if (IGNORE_PREFIXES.some((p) => _rawPath(e.ctx as object).startsWith(p))) return;
153
172
  trace.record(e.ctx as object, "flow", {
@@ -157,6 +176,14 @@ export function installFlowObservability(app: Application): () => void {
157
176
  ip: e.ip,
158
177
  ...(e.ok ? {} : { failed: true }),
159
178
  });
179
+ // The synthetic request behind an action is a GET of the page the action
180
+ // ran on, so labelling it `FLOW` is what keeps it from reading as a second
181
+ // page load in the request list.
182
+ trace.finalise?.(e.ctx as object, {
183
+ startMs: Date.now() - e.durationMs,
184
+ durationMs: e.durationMs,
185
+ method: "FLOW",
186
+ });
160
187
  }),
161
188
  );
162
189
  }