Rocky_Mountain_Vending/.pnpm-store/v10/files/86/8d014db3a4c9dfb02768ac8d90961ed8337feaf1e1d7eb2944e9ab3613e4d9f0076d507b5e0b33170cb7ca291ba0779dc27d75941b5546de58139f57363f97
DMleadgen 46d973904b
Initial commit: Rocky Mountain Vending website
Next.js website for Rocky Mountain Vending company featuring:
- Product catalog with Stripe integration
- Service areas and parts pages
- Admin dashboard with Clerk authentication
- SEO optimized pages with JSON-LD structured data

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 16:22:15 -07:00

149 lines
No EOL
6.5 KiB
Text

// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as Platform from '../../../core/platform/platform.js';
import * as Types from '../types/types.js';
// A flow is a logic connection between trace events. We display this
// connection as arrows between trace events belonging to the same flow.
// In the trace event format, flows are represented with pairing "flow
// phase" events. Each flow phase event corresponds to one trace event
// and indicates the role a trace event plays in a flow (start, step or
// end). For each flow, one `start` and one `end` phase events are
// included, while the amount of `step` phase events can be >= 0.
// A flow phase event is assigned to a trace event when their cat, tid,
// pid and ts are equal (see @flowPhaseBindingTokenForEvent ).
// It's possible for a single event to belong to multiple flows. In that
// case, it will have multiple corresponding flow phase events (one
// per flow).
// To parse flows, we first handle flow phase events, by creating unique
// flows with the timestamps of each phase. Then, we place trace events
// in the flows where their corresponding phase events were placed (if
// there are any corresponding flow phase events at all).
const flowDataByGroupToken = new Map();
// Given a trace event's flow binding tuple (timestamp, process id,
// thread id and category) we determine if there is any flow data bound
// to it by using this map's content. It's built when processing flow
// events in a trace.
// An alternative to having a map of four levels is having single map
// from a string token built from concatenating the binding data to the
// corresponding flow data. However, this token would be calculated for
// every event in a trace, resulting in a lot of memory overhead and
// major GC triggering. So we are trading off readability for
// performance.
const boundFlowData = new Map();
const flowsById = new Map();
const flowEvents = [];
const nonFlowEvents = [];
let flows = [];
const ID_COMPONENT_SEPARATOR = '-$-';
export function reset() {
flows = [];
flowEvents.length = 0;
nonFlowEvents.length = 0;
flowDataByGroupToken.clear();
boundFlowData.clear();
flowsById.clear();
}
export function handleEvent(event) {
if (Types.Events.isFlowPhaseEvent(event)) {
flowEvents.push(event);
return;
}
nonFlowEvents.push(event);
}
function processNonFlowEvent(event) {
const flowDataForEvent = boundFlowData.get(event.ts)?.get(event.pid)?.get(event.tid)?.get(event.cat);
if (!flowDataForEvent) {
return;
}
const { flows, bindingParsed } = flowDataForEvent;
if (bindingParsed) {
// We only consider the first event for a given flow binding tuple.
return;
}
for (const flowId of flows) {
const flow = Platform.MapUtilities.getWithDefault(flowsById, flowId, () => new Map());
flow.set(event.ts, event);
}
flowDataForEvent.bindingParsed = true;
}
/**
* Creates unique flows by tracking flow phase events. A new created
* flow whenever a flow start phase event is detected.
* Subsequent flow phase events with the same group token are added to
* this flow until a flow end phase is detected.
*/
function processFlowEvent(flowPhaseEvent) {
const flowGroup = flowGroupTokenForFlowPhaseEvent(flowPhaseEvent);
switch (flowPhaseEvent.ph) {
case (Types.Events.Phase.FLOW_START): {
const flowMetadata = { flowId: flowPhaseEvent.id, times: new Map([[flowPhaseEvent.ts, undefined]]) };
flowDataByGroupToken.set(flowGroup, flowPhaseEvent.id);
addFlowIdToEventBinding(flowPhaseEvent, flowMetadata.flowId);
return;
}
case (Types.Events.Phase.FLOW_STEP): {
const flowId = flowDataByGroupToken.get(flowGroup);
if (flowId === undefined) {
// Found non-start flow event with no corresponding start flow,
// start event. Quietly ignore the problematic event.
return;
}
addFlowIdToEventBinding(flowPhaseEvent, flowId);
return;
}
case (Types.Events.Phase.FLOW_END): {
const flowId = flowDataByGroupToken.get(flowGroup);
if (flowId === undefined) {
// Found non-start flow event with no corresponding start flow,
// start event. Quietly ignore the problematic event.
return;
}
addFlowIdToEventBinding(flowPhaseEvent, flowId);
// We don't need this data anymore as the flow has been finished,
// so we can drop it.
flowDataByGroupToken.delete(flowGroup);
}
}
}
/**
* A single trace event can belong to multiple flows. This method
* tracks which flows (flowId) an event belongs to given its flow
* binding tuple (made of its ts, pid, tid and cat).
*/
function addFlowIdToEventBinding(event, flowId) {
const flowsByPid = Platform.MapUtilities.getWithDefault(boundFlowData, event.ts, () => new Map());
const flowsByTid = Platform.MapUtilities.getWithDefault(flowsByPid, event.pid, () => new Map());
const flowsByCat = Platform.MapUtilities.getWithDefault(flowsByTid, event.tid, () => new Map());
const flowData = Platform.MapUtilities.getWithDefault(flowsByCat, event.cat, () => ({ flows: new Set(), bindingParsed: false }));
flowData.flows.add(flowId);
}
/**
* Returns a token to group flow phase events (start, step and end)
* belonging to the same flow. Flow phase events belonging to the same
* flow share category, thread id, process id and name.
*
* Note that other phase events of other flows can share these
* attributes too. For this reason, we group flow phase events in
* cycles. A cycle starts on a flow start phase event and finishes on a
* flow end phase event. For this reason, flow phase events need to be
* handled in timestamp order.
*/
function flowGroupTokenForFlowPhaseEvent(event) {
return `${event.cat}${ID_COMPONENT_SEPARATOR}${event.name}${ID_COMPONENT_SEPARATOR}${event.id}`;
}
export async function finalize() {
// Order is important: flow events need to be handled first.
flowEvents.forEach(processFlowEvent);
nonFlowEvents.forEach(processNonFlowEvent);
flows = [...flowsById.values()]
.map(flowMapping => [...flowMapping.values()])
.map(flow => flow.filter(event => event !== undefined))
.filter(flow => flow.length > 1);
}
export function data() {
return {
flows,
};
}
//# sourceMappingURL=FlowsHandler.js.map