@agg-build/ui 1.2.6 → 1.2.8
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.
- package/dist/{chunk-2HI6K7JF.mjs → chunk-2YVW6J5N.mjs} +12 -6
- package/dist/{chunk-5FXMHTVR.mjs → chunk-BW4DQYWM.mjs} +1 -1
- package/dist/{chunk-34L7ZKJW.mjs → chunk-HQRT3B3L.mjs} +3 -2
- package/dist/{chunk-WPF47BQQ.mjs → chunk-IIEE4FVO.mjs} +9 -2
- package/dist/{chunk-TBKDLNOE.mjs → chunk-RPIYL7EA.mjs} +29 -8
- package/dist/{chunk-E45WOOMN.mjs → chunk-SMGKYWEP.mjs} +22 -8
- package/dist/{chunk-FS3FGVAG.mjs → chunk-U6YU5OE7.mjs} +671 -152
- package/dist/events.js +51 -15
- package/dist/events.mjs +3 -3
- package/dist/index.js +771 -196
- package/dist/index.mjs +27 -20
- package/dist/modals.js +8 -1
- package/dist/modals.mjs +3 -3
- package/dist/pages.js +735 -174
- package/dist/pages.mjs +6 -6
- package/dist/primitives.js +3 -2
- package/dist/primitives.mjs +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +1 -1
- package/dist/trading.js +670 -150
- package/dist/trading.mjs +4 -4
- package/dist/types/primitives/switch-button/switch-button.constants.d.mts +1 -1
- package/dist/types/primitives/switch-button/switch-button.constants.d.ts +1 -1
- package/dist/types/primitives/tooltip/index.d.mts +1 -1
- package/dist/types/primitives/tooltip/index.d.ts +1 -1
- package/dist/types/primitives/tooltip/tooltip.types.d.mts +2 -0
- package/dist/types/primitives/tooltip/tooltip.types.d.ts +2 -0
- package/dist/types/trading/place-order/index.place-order.execution-debug.d.mts +183 -0
- package/dist/types/trading/place-order/index.place-order.execution-debug.d.ts +183 -0
- package/dist/types/trading/place-order/index.place-order.execution-steps.d.mts +72 -0
- package/dist/types/trading/place-order/index.place-order.execution-steps.d.ts +72 -0
- package/package.json +1 -1
package/dist/trading.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
SettlementDetails,
|
|
7
7
|
parseAmount,
|
|
8
8
|
parseVenue
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-U6YU5OE7.mjs";
|
|
10
10
|
import {
|
|
11
11
|
SETTLEMENT_SECTION_ID,
|
|
12
12
|
Settlement,
|
|
@@ -21,9 +21,9 @@ import {
|
|
|
21
21
|
getTradingValueLabel,
|
|
22
22
|
getTradingVenueLabel,
|
|
23
23
|
useEventTradingContext
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
26
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-RPIYL7EA.mjs";
|
|
25
|
+
import "./chunk-BW4DQYWM.mjs";
|
|
26
|
+
import "./chunk-HQRT3B3L.mjs";
|
|
27
27
|
export {
|
|
28
28
|
PlaceOrder,
|
|
29
29
|
PlaceOrderFailureView,
|
|
@@ -2,4 +2,4 @@ export declare const SWITCH_BUTTON_ANIMATION_DURATION_MS = 350;
|
|
|
2
2
|
export declare const SWITCH_BUTTON_CONTAINER_CLASS_NAME = "group/agg-switch-button min-w-fit inline-flex min-w-0 rounded-agg-full bg-agg-secondary-hover font-agg-sans cursor-pointer hover:bg-agg-tertiary";
|
|
3
3
|
export declare const SWITCH_BUTTON_TRACK_CLASS_NAME = "agg-switch-button-track relative grid min-w-0 flex-1 items-center";
|
|
4
4
|
export declare const SWITCH_BUTTON_TRACK_HIGHLIGHT_CLASS_NAME = "pointer-events-none absolute inset-y-0 left-0 rounded-agg-full border border-agg-primary bg-agg-secondary";
|
|
5
|
-
export declare const SWITCH_BUTTON_OPTION_BASE_CLASS_NAME = "agg-switch-button-option whitespace-nowrap relative z-10 min-w-0 rounded-agg-full px-5 py-1.5 font-agg-sans text-agg-base leading-agg-6 text-agg-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-agg-primary focus-visible:ring-offset-0 focus-visible:ring-offset-agg-secondary-hover cursor-pointer disabled:cursor-not-allowed disabled:text-agg-muted-foreground";
|
|
5
|
+
export declare const SWITCH_BUTTON_OPTION_BASE_CLASS_NAME = "agg-switch-button-option whitespace-nowrap relative z-10 min-w-0 rounded-agg-full px-5 py-1.5 font-agg-sans text-agg-sm leading-agg-5 md:text-agg-base md:leading-agg-6 text-agg-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-agg-primary focus-visible:ring-offset-0 focus-visible:ring-offset-agg-secondary-hover cursor-pointer disabled:cursor-not-allowed disabled:text-agg-muted-foreground";
|
|
@@ -2,4 +2,4 @@ export declare const SWITCH_BUTTON_ANIMATION_DURATION_MS = 350;
|
|
|
2
2
|
export declare const SWITCH_BUTTON_CONTAINER_CLASS_NAME = "group/agg-switch-button min-w-fit inline-flex min-w-0 rounded-agg-full bg-agg-secondary-hover font-agg-sans cursor-pointer hover:bg-agg-tertiary";
|
|
3
3
|
export declare const SWITCH_BUTTON_TRACK_CLASS_NAME = "agg-switch-button-track relative grid min-w-0 flex-1 items-center";
|
|
4
4
|
export declare const SWITCH_BUTTON_TRACK_HIGHLIGHT_CLASS_NAME = "pointer-events-none absolute inset-y-0 left-0 rounded-agg-full border border-agg-primary bg-agg-secondary";
|
|
5
|
-
export declare const SWITCH_BUTTON_OPTION_BASE_CLASS_NAME = "agg-switch-button-option whitespace-nowrap relative z-10 min-w-0 rounded-agg-full px-5 py-1.5 font-agg-sans text-agg-base leading-agg-6 text-agg-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-agg-primary focus-visible:ring-offset-0 focus-visible:ring-offset-agg-secondary-hover cursor-pointer disabled:cursor-not-allowed disabled:text-agg-muted-foreground";
|
|
5
|
+
export declare const SWITCH_BUTTON_OPTION_BASE_CLASS_NAME = "agg-switch-button-option whitespace-nowrap relative z-10 min-w-0 rounded-agg-full px-5 py-1.5 font-agg-sans text-agg-sm leading-agg-5 md:text-agg-base md:leading-agg-6 text-agg-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-agg-primary focus-visible:ring-offset-0 focus-visible:ring-offset-agg-secondary-hover cursor-pointer disabled:cursor-not-allowed disabled:text-agg-muted-foreground";
|
|
@@ -2,6 +2,6 @@ import type { TooltipProps } from "./tooltip.types";
|
|
|
2
2
|
export type { TooltipProps } from "./tooltip.types";
|
|
3
3
|
/** Renders a tooltip with an optional custom trigger and animated floating content. */
|
|
4
4
|
export declare const Tooltip: {
|
|
5
|
-
({ content, children, size, side, delayDuration, collisionPadding, classNames, "aria-label": ariaLabel, }: TooltipProps): JSX.Element;
|
|
5
|
+
({ content, children, size, side, delayDuration, collisionPadding, sideOffset, classNames, "aria-label": ariaLabel, }: TooltipProps): JSX.Element;
|
|
6
6
|
displayName: string;
|
|
7
7
|
};
|
|
@@ -2,6 +2,6 @@ import type { TooltipProps } from "./tooltip.types";
|
|
|
2
2
|
export type { TooltipProps } from "./tooltip.types";
|
|
3
3
|
/** Renders a tooltip with an optional custom trigger and animated floating content. */
|
|
4
4
|
export declare const Tooltip: {
|
|
5
|
-
({ content, children, size, side, delayDuration, collisionPadding, classNames, "aria-label": ariaLabel, }: TooltipProps): JSX.Element;
|
|
5
|
+
({ content, children, size, side, delayDuration, collisionPadding, sideOffset, classNames, "aria-label": ariaLabel, }: TooltipProps): JSX.Element;
|
|
6
6
|
displayName: string;
|
|
7
7
|
};
|
|
@@ -19,6 +19,8 @@ export interface TooltipProps {
|
|
|
19
19
|
delayDuration?: number;
|
|
20
20
|
/** Collision padding for viewport/surface boundaries. */
|
|
21
21
|
collisionPadding?: number;
|
|
22
|
+
/** Distance in px between the tooltip and its trigger. */
|
|
23
|
+
sideOffset?: number;
|
|
22
24
|
/** Optional className overrides for internal parts. */
|
|
23
25
|
classNames?: TooltipClassNames;
|
|
24
26
|
/** Accessible label for the default icon trigger. Ignored when a custom trigger is provided. */
|
|
@@ -19,6 +19,8 @@ export interface TooltipProps {
|
|
|
19
19
|
delayDuration?: number;
|
|
20
20
|
/** Collision padding for viewport/surface boundaries. */
|
|
21
21
|
collisionPadding?: number;
|
|
22
|
+
/** Distance in px between the tooltip and its trigger. */
|
|
23
|
+
sideOffset?: number;
|
|
22
24
|
/** Optional className overrides for internal parts. */
|
|
23
25
|
classNames?: TooltipClassNames;
|
|
24
26
|
/** Accessible label for the default icon trigger. Ignored when a custom trigger is provided. */
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Developer-only debug collector for the Place Order / quote-execution flow.
|
|
3
|
+
*
|
|
4
|
+
* When enabled, the surrounding component pushes structured snapshots of every
|
|
5
|
+
* meaningful step into a global store and exposes a small set of helpers on
|
|
6
|
+
* `window` so a developer (or designer reporting a bug) can do this in the
|
|
7
|
+
* browser console after a failed order:
|
|
8
|
+
*
|
|
9
|
+
* window.getFailedExecutionData() // copies sanitized JSON to clipboard
|
|
10
|
+
* window.getExecutionData() // full store, sanitized + copied
|
|
11
|
+
* window.clearExecutionData() // wipe the store and start fresh
|
|
12
|
+
*
|
|
13
|
+
* Enablement
|
|
14
|
+
* ----------
|
|
15
|
+
* Off by default. Partner apps opt in by setting `enableDebug: true` on
|
|
16
|
+
* `AggUiConfig` (typically gated on a `NEXT_PUBLIC_AGG_ENABLE_DEBUG` env var
|
|
17
|
+
* in the host app). When `enableDebug` is `false` the place-order component
|
|
18
|
+
* never invokes `enableExecutionDebugInBrowser`, so this module installs no
|
|
19
|
+
* window helpers and performs no side effects.
|
|
20
|
+
*
|
|
21
|
+
* What gets captured per attempt
|
|
22
|
+
* ------------------------------
|
|
23
|
+
* - Quote request input + the selected route summary.
|
|
24
|
+
* - Order side (buy/sell), market/event identifiers, venue identifiers.
|
|
25
|
+
* - Normalized display steps and the raw DAG / websocket events that
|
|
26
|
+
* produced them.
|
|
27
|
+
* - Wallet-confirmation transitions.
|
|
28
|
+
* - Bridge / venue-execution metadata when present in the route.
|
|
29
|
+
* - Terminal status (`succeeded` / `failed` / `cancelled` / ...).
|
|
30
|
+
* - Errors, including the failed step / message / code when available.
|
|
31
|
+
* - Environment info: app + package versions if known, URL, user agent,
|
|
32
|
+
* capture timestamp.
|
|
33
|
+
*
|
|
34
|
+
* What is intentionally redacted
|
|
35
|
+
* ------------------------------
|
|
36
|
+
* - JWTs, access/refresh tokens, raw `Authorization` headers, cookies.
|
|
37
|
+
* - Wallet signatures and private keys.
|
|
38
|
+
* - Passwords, API keys, generic `secret` values.
|
|
39
|
+
* - Email addresses (and any field whose name *contains* `email`).
|
|
40
|
+
* - Raw HTTP `headers` blobs (the Authorization line is never useful in a
|
|
41
|
+
* bug report and may carry session material).
|
|
42
|
+
* Any field name containing one of the patterns in `SENSITIVE_FIELD_PATTERNS`
|
|
43
|
+
* is replaced with the literal string `[redacted]` in the output. Cycles in
|
|
44
|
+
* the captured object graph are broken with `[circular]`.
|
|
45
|
+
*
|
|
46
|
+
* Example workflow for designers / testers reporting a bug
|
|
47
|
+
* --------------------------------------------------------
|
|
48
|
+
* 1. Reproduce the failed order in dev/staging/preview.
|
|
49
|
+
* 2. Open DevTools → Console.
|
|
50
|
+
* 3. Run: `window.getFailedExecutionData()`
|
|
51
|
+
* 4. Paste the clipboard contents into the bug report (Linear / Slack).
|
|
52
|
+
* 5. Optionally `window.clearExecutionData()` before the next reproduction
|
|
53
|
+
* so subsequent attempts start with an empty timeline.
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Recursively redact known-sensitive fields. The output is a structurally
|
|
57
|
+
* identical clone of the input where any sensitive value has been replaced
|
|
58
|
+
* with the literal `[redacted]` marker. Non-sensitive fields pass through
|
|
59
|
+
* unchanged.
|
|
60
|
+
*
|
|
61
|
+
* Cycle detection tracks only the current DFS path (parents of the node
|
|
62
|
+
* currently being walked), not every node ever seen. That distinction
|
|
63
|
+
* matters: shared references — e.g. the same `orderIds` array stored on
|
|
64
|
+
* multiple `state_change` events, or the same selected-route object
|
|
65
|
+
* referenced in two sibling fields — are NOT cycles and must serialize fully
|
|
66
|
+
* each time. Only true ancestor self-references (`a.self = a`) are
|
|
67
|
+
* collapsed to the literal `[circular]` marker.
|
|
68
|
+
*/
|
|
69
|
+
export declare const sanitizeExecutionDebugValue: <T>(input: T) => T;
|
|
70
|
+
export type ExecutionDebugStatus = "idle" | "quoting" | "executing" | "wallet_confirmation_required" | "succeeded" | "failed" | "cancelled";
|
|
71
|
+
export type ExecutionDebugQuoteSnapshot = {
|
|
72
|
+
request?: unknown;
|
|
73
|
+
response?: unknown;
|
|
74
|
+
selectedRoute?: unknown;
|
|
75
|
+
side?: "buy" | "sell";
|
|
76
|
+
marketId?: string;
|
|
77
|
+
eventId?: string;
|
|
78
|
+
outcomeId?: string;
|
|
79
|
+
venues?: string[];
|
|
80
|
+
capturedAt: number;
|
|
81
|
+
};
|
|
82
|
+
export type ExecutionDebugEvent = {
|
|
83
|
+
/** Stable category — useful for filtering. */
|
|
84
|
+
kind: "quote_request" | "quote_response" | "execute_request" | "execute_response" | "state_change" | "ws_update" | "normalized_steps" | "wallet_confirmation" | "terminal_event" | "error";
|
|
85
|
+
/** Free-form label distinguishing events of the same `kind`. */
|
|
86
|
+
label?: string;
|
|
87
|
+
data?: unknown;
|
|
88
|
+
timestamp: number;
|
|
89
|
+
};
|
|
90
|
+
export type ExecutionDebugError = {
|
|
91
|
+
message: string;
|
|
92
|
+
name?: string;
|
|
93
|
+
code?: string;
|
|
94
|
+
stack?: string;
|
|
95
|
+
failedStep?: string;
|
|
96
|
+
data?: unknown;
|
|
97
|
+
timestamp: number;
|
|
98
|
+
};
|
|
99
|
+
export type ExecutionDebugAttempt = {
|
|
100
|
+
attemptId: string;
|
|
101
|
+
startedAt: number;
|
|
102
|
+
updatedAt: number;
|
|
103
|
+
status: ExecutionDebugStatus;
|
|
104
|
+
/** Promoted to top level for at-a-glance triage when scrolling failed attempts. */
|
|
105
|
+
quoteId?: string;
|
|
106
|
+
/** First / primary order ID once `executeManaged` returns. */
|
|
107
|
+
orderId?: string;
|
|
108
|
+
/** All order IDs in the executed route (for split orders). */
|
|
109
|
+
orderIds?: string[];
|
|
110
|
+
quote?: ExecutionDebugQuoteSnapshot;
|
|
111
|
+
selectedRoute?: unknown;
|
|
112
|
+
bridge?: unknown;
|
|
113
|
+
venueExecution?: unknown;
|
|
114
|
+
rawEvents: ExecutionDebugEvent[];
|
|
115
|
+
normalizedSteps: unknown[];
|
|
116
|
+
errors: ExecutionDebugError[];
|
|
117
|
+
finalStatus?: ExecutionDebugStatus;
|
|
118
|
+
};
|
|
119
|
+
export type ExecutionDebugEnvironment = {
|
|
120
|
+
appVersion?: string;
|
|
121
|
+
packageVersions?: Record<string, string>;
|
|
122
|
+
url?: string;
|
|
123
|
+
userAgent?: string;
|
|
124
|
+
capturedAt: number;
|
|
125
|
+
};
|
|
126
|
+
export type ExecutionDebugStore = {
|
|
127
|
+
attempts: ExecutionDebugAttempt[];
|
|
128
|
+
environment: ExecutionDebugEnvironment;
|
|
129
|
+
};
|
|
130
|
+
export type AppendExecutionDebugAttemptInput = Partial<Pick<ExecutionDebugAttempt, "status" | "quoteId" | "orderId" | "orderIds" | "quote" | "selectedRoute" | "bridge" | "venueExecution">> & {
|
|
131
|
+
attemptId?: string;
|
|
132
|
+
};
|
|
133
|
+
export type UpdateExecutionDebugAttemptInput = Partial<Pick<ExecutionDebugAttempt, "status" | "quoteId" | "orderId" | "orderIds" | "quote" | "selectedRoute" | "bridge" | "venueExecution" | "finalStatus">>;
|
|
134
|
+
/**
|
|
135
|
+
* Pure debug store. The window-scoped collector below is a thin wrapper around
|
|
136
|
+
* an instance of this — but the store itself is environment-agnostic and fully
|
|
137
|
+
* testable in isolation.
|
|
138
|
+
*/
|
|
139
|
+
export declare const createExecutionDebugStore: (initial?: Partial<Omit<ExecutionDebugEnvironment, "capturedAt">>) => {
|
|
140
|
+
appendAttempt: (input?: AppendExecutionDebugAttemptInput) => ExecutionDebugAttempt;
|
|
141
|
+
updateAttempt: (attemptId: string, patch: UpdateExecutionDebugAttemptInput) => void;
|
|
142
|
+
appendEvent: (attemptId: string, event: Omit<ExecutionDebugEvent, "timestamp"> & {
|
|
143
|
+
timestamp?: number;
|
|
144
|
+
}) => void;
|
|
145
|
+
appendError: (attemptId: string, error: Omit<ExecutionDebugError, "timestamp"> & {
|
|
146
|
+
timestamp?: number;
|
|
147
|
+
}) => void;
|
|
148
|
+
setNormalizedSteps: (attemptId: string, steps: unknown[]) => void;
|
|
149
|
+
getSnapshot: () => ExecutionDebugStore;
|
|
150
|
+
getFailedAttempts: () => ExecutionDebugAttempt[];
|
|
151
|
+
clear: () => void;
|
|
152
|
+
};
|
|
153
|
+
export type ExecutionDebugStoreInstance = ReturnType<typeof createExecutionDebugStore>;
|
|
154
|
+
declare global {
|
|
155
|
+
interface Window {
|
|
156
|
+
executionData?: ExecutionDebugStore;
|
|
157
|
+
getExecutionData?: () => ExecutionDebugStore;
|
|
158
|
+
getFailedExecutionData?: () => {
|
|
159
|
+
attempts: ExecutionDebugAttempt[];
|
|
160
|
+
};
|
|
161
|
+
clearExecutionData?: () => void;
|
|
162
|
+
__aggExecutionDebugStore?: ExecutionDebugStoreInstance;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export type InstallExecutionDebugWindowOptions = {
|
|
166
|
+
store: ExecutionDebugStoreInstance;
|
|
167
|
+
/** Override `console` for testing the activation banner and copy logs. */
|
|
168
|
+
consoleImpl?: Pick<Console, "info" | "warn" | "log">;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Install the `window.executionData` / `window.getExecutionData()` /
|
|
172
|
+
* `window.getFailedExecutionData()` / `window.clearExecutionData()` helpers
|
|
173
|
+
* in the current document. Returns an `uninstall` callback that restores the
|
|
174
|
+
* previous values — handy for cleanup in tests and React effects.
|
|
175
|
+
*/
|
|
176
|
+
export declare const installExecutionDebugWindow: ({ store, consoleImpl, }: InstallExecutionDebugWindowOptions) => (() => void);
|
|
177
|
+
/**
|
|
178
|
+
* Convenience: shared singleton + window-installer used by the React layer.
|
|
179
|
+
* Returns `null` when there is no `window` (SSR). Callers gate this on the
|
|
180
|
+
* `enableDebug` flag from `AggUiConfig` — when that flag is off, this is
|
|
181
|
+
* never invoked and the module has no runtime footprint.
|
|
182
|
+
*/
|
|
183
|
+
export declare const enableExecutionDebugInBrowser: (initial?: Partial<Omit<ExecutionDebugEnvironment, "capturedAt">>) => ExecutionDebugStoreInstance | null;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Developer-only debug collector for the Place Order / quote-execution flow.
|
|
3
|
+
*
|
|
4
|
+
* When enabled, the surrounding component pushes structured snapshots of every
|
|
5
|
+
* meaningful step into a global store and exposes a small set of helpers on
|
|
6
|
+
* `window` so a developer (or designer reporting a bug) can do this in the
|
|
7
|
+
* browser console after a failed order:
|
|
8
|
+
*
|
|
9
|
+
* window.getFailedExecutionData() // copies sanitized JSON to clipboard
|
|
10
|
+
* window.getExecutionData() // full store, sanitized + copied
|
|
11
|
+
* window.clearExecutionData() // wipe the store and start fresh
|
|
12
|
+
*
|
|
13
|
+
* Enablement
|
|
14
|
+
* ----------
|
|
15
|
+
* Off by default. Partner apps opt in by setting `enableDebug: true` on
|
|
16
|
+
* `AggUiConfig` (typically gated on a `NEXT_PUBLIC_AGG_ENABLE_DEBUG` env var
|
|
17
|
+
* in the host app). When `enableDebug` is `false` the place-order component
|
|
18
|
+
* never invokes `enableExecutionDebugInBrowser`, so this module installs no
|
|
19
|
+
* window helpers and performs no side effects.
|
|
20
|
+
*
|
|
21
|
+
* What gets captured per attempt
|
|
22
|
+
* ------------------------------
|
|
23
|
+
* - Quote request input + the selected route summary.
|
|
24
|
+
* - Order side (buy/sell), market/event identifiers, venue identifiers.
|
|
25
|
+
* - Normalized display steps and the raw DAG / websocket events that
|
|
26
|
+
* produced them.
|
|
27
|
+
* - Wallet-confirmation transitions.
|
|
28
|
+
* - Bridge / venue-execution metadata when present in the route.
|
|
29
|
+
* - Terminal status (`succeeded` / `failed` / `cancelled` / ...).
|
|
30
|
+
* - Errors, including the failed step / message / code when available.
|
|
31
|
+
* - Environment info: app + package versions if known, URL, user agent,
|
|
32
|
+
* capture timestamp.
|
|
33
|
+
*
|
|
34
|
+
* What is intentionally redacted
|
|
35
|
+
* ------------------------------
|
|
36
|
+
* - JWTs, access/refresh tokens, raw `Authorization` headers, cookies.
|
|
37
|
+
* - Wallet signatures and private keys.
|
|
38
|
+
* - Passwords, API keys, generic `secret` values.
|
|
39
|
+
* - Email addresses (and any field whose name *contains* `email`).
|
|
40
|
+
* - Raw HTTP `headers` blobs (the Authorization line is never useful in a
|
|
41
|
+
* bug report and may carry session material).
|
|
42
|
+
* Any field name containing one of the patterns in `SENSITIVE_FIELD_PATTERNS`
|
|
43
|
+
* is replaced with the literal string `[redacted]` in the output. Cycles in
|
|
44
|
+
* the captured object graph are broken with `[circular]`.
|
|
45
|
+
*
|
|
46
|
+
* Example workflow for designers / testers reporting a bug
|
|
47
|
+
* --------------------------------------------------------
|
|
48
|
+
* 1. Reproduce the failed order in dev/staging/preview.
|
|
49
|
+
* 2. Open DevTools → Console.
|
|
50
|
+
* 3. Run: `window.getFailedExecutionData()`
|
|
51
|
+
* 4. Paste the clipboard contents into the bug report (Linear / Slack).
|
|
52
|
+
* 5. Optionally `window.clearExecutionData()` before the next reproduction
|
|
53
|
+
* so subsequent attempts start with an empty timeline.
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Recursively redact known-sensitive fields. The output is a structurally
|
|
57
|
+
* identical clone of the input where any sensitive value has been replaced
|
|
58
|
+
* with the literal `[redacted]` marker. Non-sensitive fields pass through
|
|
59
|
+
* unchanged.
|
|
60
|
+
*
|
|
61
|
+
* Cycle detection tracks only the current DFS path (parents of the node
|
|
62
|
+
* currently being walked), not every node ever seen. That distinction
|
|
63
|
+
* matters: shared references — e.g. the same `orderIds` array stored on
|
|
64
|
+
* multiple `state_change` events, or the same selected-route object
|
|
65
|
+
* referenced in two sibling fields — are NOT cycles and must serialize fully
|
|
66
|
+
* each time. Only true ancestor self-references (`a.self = a`) are
|
|
67
|
+
* collapsed to the literal `[circular]` marker.
|
|
68
|
+
*/
|
|
69
|
+
export declare const sanitizeExecutionDebugValue: <T>(input: T) => T;
|
|
70
|
+
export type ExecutionDebugStatus = "idle" | "quoting" | "executing" | "wallet_confirmation_required" | "succeeded" | "failed" | "cancelled";
|
|
71
|
+
export type ExecutionDebugQuoteSnapshot = {
|
|
72
|
+
request?: unknown;
|
|
73
|
+
response?: unknown;
|
|
74
|
+
selectedRoute?: unknown;
|
|
75
|
+
side?: "buy" | "sell";
|
|
76
|
+
marketId?: string;
|
|
77
|
+
eventId?: string;
|
|
78
|
+
outcomeId?: string;
|
|
79
|
+
venues?: string[];
|
|
80
|
+
capturedAt: number;
|
|
81
|
+
};
|
|
82
|
+
export type ExecutionDebugEvent = {
|
|
83
|
+
/** Stable category — useful for filtering. */
|
|
84
|
+
kind: "quote_request" | "quote_response" | "execute_request" | "execute_response" | "state_change" | "ws_update" | "normalized_steps" | "wallet_confirmation" | "terminal_event" | "error";
|
|
85
|
+
/** Free-form label distinguishing events of the same `kind`. */
|
|
86
|
+
label?: string;
|
|
87
|
+
data?: unknown;
|
|
88
|
+
timestamp: number;
|
|
89
|
+
};
|
|
90
|
+
export type ExecutionDebugError = {
|
|
91
|
+
message: string;
|
|
92
|
+
name?: string;
|
|
93
|
+
code?: string;
|
|
94
|
+
stack?: string;
|
|
95
|
+
failedStep?: string;
|
|
96
|
+
data?: unknown;
|
|
97
|
+
timestamp: number;
|
|
98
|
+
};
|
|
99
|
+
export type ExecutionDebugAttempt = {
|
|
100
|
+
attemptId: string;
|
|
101
|
+
startedAt: number;
|
|
102
|
+
updatedAt: number;
|
|
103
|
+
status: ExecutionDebugStatus;
|
|
104
|
+
/** Promoted to top level for at-a-glance triage when scrolling failed attempts. */
|
|
105
|
+
quoteId?: string;
|
|
106
|
+
/** First / primary order ID once `executeManaged` returns. */
|
|
107
|
+
orderId?: string;
|
|
108
|
+
/** All order IDs in the executed route (for split orders). */
|
|
109
|
+
orderIds?: string[];
|
|
110
|
+
quote?: ExecutionDebugQuoteSnapshot;
|
|
111
|
+
selectedRoute?: unknown;
|
|
112
|
+
bridge?: unknown;
|
|
113
|
+
venueExecution?: unknown;
|
|
114
|
+
rawEvents: ExecutionDebugEvent[];
|
|
115
|
+
normalizedSteps: unknown[];
|
|
116
|
+
errors: ExecutionDebugError[];
|
|
117
|
+
finalStatus?: ExecutionDebugStatus;
|
|
118
|
+
};
|
|
119
|
+
export type ExecutionDebugEnvironment = {
|
|
120
|
+
appVersion?: string;
|
|
121
|
+
packageVersions?: Record<string, string>;
|
|
122
|
+
url?: string;
|
|
123
|
+
userAgent?: string;
|
|
124
|
+
capturedAt: number;
|
|
125
|
+
};
|
|
126
|
+
export type ExecutionDebugStore = {
|
|
127
|
+
attempts: ExecutionDebugAttempt[];
|
|
128
|
+
environment: ExecutionDebugEnvironment;
|
|
129
|
+
};
|
|
130
|
+
export type AppendExecutionDebugAttemptInput = Partial<Pick<ExecutionDebugAttempt, "status" | "quoteId" | "orderId" | "orderIds" | "quote" | "selectedRoute" | "bridge" | "venueExecution">> & {
|
|
131
|
+
attemptId?: string;
|
|
132
|
+
};
|
|
133
|
+
export type UpdateExecutionDebugAttemptInput = Partial<Pick<ExecutionDebugAttempt, "status" | "quoteId" | "orderId" | "orderIds" | "quote" | "selectedRoute" | "bridge" | "venueExecution" | "finalStatus">>;
|
|
134
|
+
/**
|
|
135
|
+
* Pure debug store. The window-scoped collector below is a thin wrapper around
|
|
136
|
+
* an instance of this — but the store itself is environment-agnostic and fully
|
|
137
|
+
* testable in isolation.
|
|
138
|
+
*/
|
|
139
|
+
export declare const createExecutionDebugStore: (initial?: Partial<Omit<ExecutionDebugEnvironment, "capturedAt">>) => {
|
|
140
|
+
appendAttempt: (input?: AppendExecutionDebugAttemptInput) => ExecutionDebugAttempt;
|
|
141
|
+
updateAttempt: (attemptId: string, patch: UpdateExecutionDebugAttemptInput) => void;
|
|
142
|
+
appendEvent: (attemptId: string, event: Omit<ExecutionDebugEvent, "timestamp"> & {
|
|
143
|
+
timestamp?: number;
|
|
144
|
+
}) => void;
|
|
145
|
+
appendError: (attemptId: string, error: Omit<ExecutionDebugError, "timestamp"> & {
|
|
146
|
+
timestamp?: number;
|
|
147
|
+
}) => void;
|
|
148
|
+
setNormalizedSteps: (attemptId: string, steps: unknown[]) => void;
|
|
149
|
+
getSnapshot: () => ExecutionDebugStore;
|
|
150
|
+
getFailedAttempts: () => ExecutionDebugAttempt[];
|
|
151
|
+
clear: () => void;
|
|
152
|
+
};
|
|
153
|
+
export type ExecutionDebugStoreInstance = ReturnType<typeof createExecutionDebugStore>;
|
|
154
|
+
declare global {
|
|
155
|
+
interface Window {
|
|
156
|
+
executionData?: ExecutionDebugStore;
|
|
157
|
+
getExecutionData?: () => ExecutionDebugStore;
|
|
158
|
+
getFailedExecutionData?: () => {
|
|
159
|
+
attempts: ExecutionDebugAttempt[];
|
|
160
|
+
};
|
|
161
|
+
clearExecutionData?: () => void;
|
|
162
|
+
__aggExecutionDebugStore?: ExecutionDebugStoreInstance;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export type InstallExecutionDebugWindowOptions = {
|
|
166
|
+
store: ExecutionDebugStoreInstance;
|
|
167
|
+
/** Override `console` for testing the activation banner and copy logs. */
|
|
168
|
+
consoleImpl?: Pick<Console, "info" | "warn" | "log">;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Install the `window.executionData` / `window.getExecutionData()` /
|
|
172
|
+
* `window.getFailedExecutionData()` / `window.clearExecutionData()` helpers
|
|
173
|
+
* in the current document. Returns an `uninstall` callback that restores the
|
|
174
|
+
* previous values — handy for cleanup in tests and React effects.
|
|
175
|
+
*/
|
|
176
|
+
export declare const installExecutionDebugWindow: ({ store, consoleImpl, }: InstallExecutionDebugWindowOptions) => (() => void);
|
|
177
|
+
/**
|
|
178
|
+
* Convenience: shared singleton + window-installer used by the React layer.
|
|
179
|
+
* Returns `null` when there is no `window` (SSR). Callers gate this on the
|
|
180
|
+
* `enableDebug` flag from `AggUiConfig` — when that flag is off, this is
|
|
181
|
+
* never invoked and the module has no runtime footprint.
|
|
182
|
+
*/
|
|
183
|
+
export declare const enableExecutionDebugInBrowser: (initial?: Partial<Omit<ExecutionDebugEnvironment, "capturedAt">>) => ExecutionDebugStoreInstance | null;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { DagStepProgress } from "@agg-build/hooks";
|
|
2
|
+
import type { TradingVenue } from "../types";
|
|
3
|
+
import type { PlaceOrderSubmissionProgressPhase, PlaceOrderTradingLabels } from "./index.place-order.types";
|
|
4
|
+
/**
|
|
5
|
+
* Stable, user-facing phases for the in-flight Place Order submission UI.
|
|
6
|
+
*
|
|
7
|
+
* The DAG executor emits many granular step types (`bridge-fetch-quote`,
|
|
8
|
+
* `polymarket-setup-resolve-need`, `submit-verify-order-status`, etc.) that
|
|
9
|
+
* are an implementation detail of how a route is fulfilled. Surfacing them
|
|
10
|
+
* directly produces noisy, confusing progress and leaks internal architecture
|
|
11
|
+
* to partners. We collapse every raw step into one of a small, fixed set of
|
|
12
|
+
* normalized phases here, then drive rendering off the normalized model.
|
|
13
|
+
*
|
|
14
|
+
* Anything not in this list (bridge, ata, approve, swap, transfer, position,
|
|
15
|
+
* polymarket-setup, hl-fund, wait sentinels) maps to either `checking-balance`
|
|
16
|
+
* (read-only probes) or `submitting`.
|
|
17
|
+
*/
|
|
18
|
+
export type NormalizedExecutionPhaseKind = "finding-route" | "checking-balance" | "submitting" | "wallet-confirm" | "executing-venue" | "filled" | "failed";
|
|
19
|
+
export type NormalizedExecutionPhase = {
|
|
20
|
+
kind: NormalizedExecutionPhaseKind;
|
|
21
|
+
/** Set when the phase is venue-scoped — `executing-venue` and finalize legs. */
|
|
22
|
+
venue?: TradingVenue;
|
|
23
|
+
};
|
|
24
|
+
export type SubmissionDisplayRow = {
|
|
25
|
+
id: string;
|
|
26
|
+
label: string;
|
|
27
|
+
status: "pending" | "complete";
|
|
28
|
+
venue?: TradingVenue;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Classify a raw DAG step type into the normalized phase it represents.
|
|
32
|
+
*
|
|
33
|
+
* Returns `null` for wait sentinels and unrecognized step types — the caller
|
|
34
|
+
* should skip these so they don't introduce a fake "Wait" or `Step N of M`
|
|
35
|
+
* row in the UI.
|
|
36
|
+
*/
|
|
37
|
+
export declare const classifyExecutionStepType: (stepType: string) => NormalizedExecutionPhase | null;
|
|
38
|
+
type PhaseTimelineEntry = NormalizedExecutionPhase & {
|
|
39
|
+
firstSeq: number;
|
|
40
|
+
lastSeq: number;
|
|
41
|
+
allCompleted: boolean;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Walk the DAG sequences in order, classify each, and merge consecutive
|
|
45
|
+
* entries that share the same kind+venue. The result is the
|
|
46
|
+
* presentation-layer timeline of high-level phases.
|
|
47
|
+
*
|
|
48
|
+
* A merged entry is `allCompleted` only when every underlying sequence has
|
|
49
|
+
* finished — so a single in-flight `bridge-submit` keeps the merged
|
|
50
|
+
* "submitting" row pending even if `bridge-fetch-quote` already completed.
|
|
51
|
+
*/
|
|
52
|
+
export declare const buildPhaseTimeline: (dag: DagStepProgress) => PhaseTimelineEntry[];
|
|
53
|
+
export type BuildSubmissionDisplayRowsArgs = {
|
|
54
|
+
phase: PlaceOrderSubmissionProgressPhase;
|
|
55
|
+
dagProgress: DagStepProgress | null | undefined;
|
|
56
|
+
executionVenue?: TradingVenue;
|
|
57
|
+
/** Whether the active submitting beat is waiting on a wallet signature. */
|
|
58
|
+
isAwaitingWalletConfirmation?: boolean;
|
|
59
|
+
labels: PlaceOrderTradingLabels;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Produce the rows the in-flight Place Order surface should render.
|
|
63
|
+
*
|
|
64
|
+
* Invariants:
|
|
65
|
+
* - At most one row has status `pending`.
|
|
66
|
+
* - Completed rows are kept only when they correspond to a meaningful
|
|
67
|
+
* user-facing milestone (the normalized phases above).
|
|
68
|
+
* - The same kind+venue never appears twice — repeated `step_started` /
|
|
69
|
+
* `step_waiting` events on the same phase don't duplicate rows.
|
|
70
|
+
*/
|
|
71
|
+
export declare const buildSubmissionDisplayRows: ({ phase, dagProgress, executionVenue, isAwaitingWalletConfirmation, labels, }: BuildSubmissionDisplayRowsArgs) => SubmissionDisplayRow[];
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { DagStepProgress } from "@agg-build/hooks";
|
|
2
|
+
import type { TradingVenue } from "../types";
|
|
3
|
+
import type { PlaceOrderSubmissionProgressPhase, PlaceOrderTradingLabels } from "./index.place-order.types";
|
|
4
|
+
/**
|
|
5
|
+
* Stable, user-facing phases for the in-flight Place Order submission UI.
|
|
6
|
+
*
|
|
7
|
+
* The DAG executor emits many granular step types (`bridge-fetch-quote`,
|
|
8
|
+
* `polymarket-setup-resolve-need`, `submit-verify-order-status`, etc.) that
|
|
9
|
+
* are an implementation detail of how a route is fulfilled. Surfacing them
|
|
10
|
+
* directly produces noisy, confusing progress and leaks internal architecture
|
|
11
|
+
* to partners. We collapse every raw step into one of a small, fixed set of
|
|
12
|
+
* normalized phases here, then drive rendering off the normalized model.
|
|
13
|
+
*
|
|
14
|
+
* Anything not in this list (bridge, ata, approve, swap, transfer, position,
|
|
15
|
+
* polymarket-setup, hl-fund, wait sentinels) maps to either `checking-balance`
|
|
16
|
+
* (read-only probes) or `submitting`.
|
|
17
|
+
*/
|
|
18
|
+
export type NormalizedExecutionPhaseKind = "finding-route" | "checking-balance" | "submitting" | "wallet-confirm" | "executing-venue" | "filled" | "failed";
|
|
19
|
+
export type NormalizedExecutionPhase = {
|
|
20
|
+
kind: NormalizedExecutionPhaseKind;
|
|
21
|
+
/** Set when the phase is venue-scoped — `executing-venue` and finalize legs. */
|
|
22
|
+
venue?: TradingVenue;
|
|
23
|
+
};
|
|
24
|
+
export type SubmissionDisplayRow = {
|
|
25
|
+
id: string;
|
|
26
|
+
label: string;
|
|
27
|
+
status: "pending" | "complete";
|
|
28
|
+
venue?: TradingVenue;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Classify a raw DAG step type into the normalized phase it represents.
|
|
32
|
+
*
|
|
33
|
+
* Returns `null` for wait sentinels and unrecognized step types — the caller
|
|
34
|
+
* should skip these so they don't introduce a fake "Wait" or `Step N of M`
|
|
35
|
+
* row in the UI.
|
|
36
|
+
*/
|
|
37
|
+
export declare const classifyExecutionStepType: (stepType: string) => NormalizedExecutionPhase | null;
|
|
38
|
+
type PhaseTimelineEntry = NormalizedExecutionPhase & {
|
|
39
|
+
firstSeq: number;
|
|
40
|
+
lastSeq: number;
|
|
41
|
+
allCompleted: boolean;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Walk the DAG sequences in order, classify each, and merge consecutive
|
|
45
|
+
* entries that share the same kind+venue. The result is the
|
|
46
|
+
* presentation-layer timeline of high-level phases.
|
|
47
|
+
*
|
|
48
|
+
* A merged entry is `allCompleted` only when every underlying sequence has
|
|
49
|
+
* finished — so a single in-flight `bridge-submit` keeps the merged
|
|
50
|
+
* "submitting" row pending even if `bridge-fetch-quote` already completed.
|
|
51
|
+
*/
|
|
52
|
+
export declare const buildPhaseTimeline: (dag: DagStepProgress) => PhaseTimelineEntry[];
|
|
53
|
+
export type BuildSubmissionDisplayRowsArgs = {
|
|
54
|
+
phase: PlaceOrderSubmissionProgressPhase;
|
|
55
|
+
dagProgress: DagStepProgress | null | undefined;
|
|
56
|
+
executionVenue?: TradingVenue;
|
|
57
|
+
/** Whether the active submitting beat is waiting on a wallet signature. */
|
|
58
|
+
isAwaitingWalletConfirmation?: boolean;
|
|
59
|
+
labels: PlaceOrderTradingLabels;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Produce the rows the in-flight Place Order surface should render.
|
|
63
|
+
*
|
|
64
|
+
* Invariants:
|
|
65
|
+
* - At most one row has status `pending`.
|
|
66
|
+
* - Completed rows are kept only when they correspond to a meaningful
|
|
67
|
+
* user-facing milestone (the normalized phases above).
|
|
68
|
+
* - The same kind+venue never appears twice — repeated `step_started` /
|
|
69
|
+
* `step_waiting` events on the same phase don't duplicate rows.
|
|
70
|
+
*/
|
|
71
|
+
export declare const buildSubmissionDisplayRows: ({ phase, dagProgress, executionVenue, isAwaitingWalletConfirmation, labels, }: BuildSubmissionDisplayRowsArgs) => SubmissionDisplayRow[];
|
|
72
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agg-build/ui",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.8",
|
|
4
4
|
"description": "Pre-built React component library for the AGG prediction market aggregator. Tailwind-based, themeable, with primitives, event surfaces, trading flows, full pages, and modals.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|