@ddwang/magnitude-core 0.3.1-ddwang.1

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 (142) hide show
  1. package/dist/actions/desktopActions.d.ts +58 -0
  2. package/dist/actions/desktopActions.js +154 -0
  3. package/dist/actions/index.d.ts +26 -0
  4. package/dist/actions/index.js +11 -0
  5. package/dist/actions/taskActions.d.ts +8 -0
  6. package/dist/actions/taskActions.js +27 -0
  7. package/dist/actions/types.d.ts +31 -0
  8. package/dist/actions/types.js +5 -0
  9. package/dist/actions/util.d.ts +20 -0
  10. package/dist/actions/util.js +297 -0
  11. package/dist/actions/webActions.d.ts +79 -0
  12. package/dist/actions/webActions.js +190 -0
  13. package/dist/agent/browserAgent.d.ts +29 -0
  14. package/dist/agent/browserAgent.js +122 -0
  15. package/dist/agent/errors.d.ts +8 -0
  16. package/dist/agent/errors.js +68 -0
  17. package/dist/agent/index.d.ts +53 -0
  18. package/dist/agent/index.js +377 -0
  19. package/dist/agent/narrator.d.ts +4 -0
  20. package/dist/agent/narrator.js +63 -0
  21. package/dist/agent/pause.test.d.ts +1 -0
  22. package/dist/agent/pause.test.js +194 -0
  23. package/dist/ai/baml_client/async_client.d.ts +73 -0
  24. package/dist/ai/baml_client/async_client.js +152 -0
  25. package/dist/ai/baml_client/async_request.d.ts +35 -0
  26. package/dist/ai/baml_client/async_request.js +98 -0
  27. package/dist/ai/baml_client/config.d.ts +11 -0
  28. package/dist/ai/baml_client/config.js +20 -0
  29. package/dist/ai/baml_client/globals.d.ts +16 -0
  30. package/dist/ai/baml_client/globals.js +37 -0
  31. package/dist/ai/baml_client/index.d.ts +16 -0
  32. package/dist/ai/baml_client/index.js +41 -0
  33. package/dist/ai/baml_client/inlinedbaml.d.ts +19 -0
  34. package/dist/ai/baml_client/inlinedbaml.js +31 -0
  35. package/dist/ai/baml_client/parser.d.ts +53 -0
  36. package/dist/ai/baml_client/parser.js +86 -0
  37. package/dist/ai/baml_client/partial_types.d.ts +61 -0
  38. package/dist/ai/baml_client/partial_types.js +10 -0
  39. package/dist/ai/baml_client/sync_client.d.ts +50 -0
  40. package/dist/ai/baml_client/sync_client.js +100 -0
  41. package/dist/ai/baml_client/sync_request.d.ts +35 -0
  42. package/dist/ai/baml_client/sync_request.js +98 -0
  43. package/dist/ai/baml_client/tracing.d.ts +16 -0
  44. package/dist/ai/baml_client/tracing.js +18 -0
  45. package/dist/ai/baml_client/type_builder.d.ts +38 -0
  46. package/dist/ai/baml_client/type_builder.js +96 -0
  47. package/dist/ai/baml_client/types.d.ts +69 -0
  48. package/dist/ai/baml_client/types.js +15 -0
  49. package/dist/ai/claudeCode.d.ts +1 -0
  50. package/dist/ai/claudeCode.js +186 -0
  51. package/dist/ai/modelHarness.d.ts +39 -0
  52. package/dist/ai/modelHarness.js +189 -0
  53. package/dist/ai/multiModelHarness.d.ts +27 -0
  54. package/dist/ai/multiModelHarness.js +52 -0
  55. package/dist/ai/types.d.ts +90 -0
  56. package/dist/ai/types.js +5 -0
  57. package/dist/ai/util.d.ts +13 -0
  58. package/dist/ai/util.js +165 -0
  59. package/dist/cli.d.ts +0 -0
  60. package/dist/cli.js +3 -0
  61. package/dist/common/actions.d.ts +0 -0
  62. package/dist/common/actions.js +14 -0
  63. package/dist/common/events.d.ts +15 -0
  64. package/dist/common/events.js +3 -0
  65. package/dist/common/failure.d.ts +68 -0
  66. package/dist/common/failure.js +1 -0
  67. package/dist/common/index.d.ts +3 -0
  68. package/dist/common/index.js +3 -0
  69. package/dist/common/retry.d.ts +16 -0
  70. package/dist/common/retry.js +30 -0
  71. package/dist/common/util.d.ts +23 -0
  72. package/dist/common/util.js +132 -0
  73. package/dist/connectors/browserConnector.d.ts +40 -0
  74. package/dist/connectors/browserConnector.js +127 -0
  75. package/dist/connectors/desktopConnector.d.ts +58 -0
  76. package/dist/connectors/desktopConnector.js +68 -0
  77. package/dist/connectors/index.d.ts +10 -0
  78. package/dist/connectors/index.js +2 -0
  79. package/dist/index.cjs +6143 -0
  80. package/dist/index.d.cts +825 -0
  81. package/dist/index.d.ts +20 -0
  82. package/dist/index.js +26 -0
  83. package/dist/index.mjs +6097 -0
  84. package/dist/logger.d.ts +3 -0
  85. package/dist/logger.js +15 -0
  86. package/dist/memory/agentMemory.d.ts +37 -0
  87. package/dist/memory/agentMemory.js +121 -0
  88. package/dist/memory/image.d.ts +26 -0
  89. package/dist/memory/image.js +106 -0
  90. package/dist/memory/index.d.ts +3 -0
  91. package/dist/memory/index.js +3 -0
  92. package/dist/memory/masking.d.ts +7 -0
  93. package/dist/memory/masking.js +141 -0
  94. package/dist/memory/masking.test.d.ts +1 -0
  95. package/dist/memory/masking.test.js +117 -0
  96. package/dist/memory/observation.d.ts +38 -0
  97. package/dist/memory/observation.js +79 -0
  98. package/dist/memory/rendering/index.d.ts +10 -0
  99. package/dist/memory/rendering/index.js +13 -0
  100. package/dist/memory/rendering/renderJsonParts.d.ts +3 -0
  101. package/dist/memory/rendering/renderJsonParts.js +115 -0
  102. package/dist/memory/rendering/renderJsonParts.test.d.ts +1 -0
  103. package/dist/memory/rendering/renderJsonParts.test.js +217 -0
  104. package/dist/memory/rendering/renderXmlParts.d.ts +7 -0
  105. package/dist/memory/rendering/renderXmlParts.js +127 -0
  106. package/dist/memory/serde.d.ts +20 -0
  107. package/dist/memory/serde.js +81 -0
  108. package/dist/memory/util.d.ts +2 -0
  109. package/dist/memory/util.js +17 -0
  110. package/dist/telemetry/events.d.ts +9 -0
  111. package/dist/telemetry/events.js +80 -0
  112. package/dist/telemetry/index.d.ts +6 -0
  113. package/dist/telemetry/index.js +91 -0
  114. package/dist/types.d.ts +30 -0
  115. package/dist/types.js +1 -0
  116. package/dist/util.d.ts +1 -0
  117. package/dist/util.js +12 -0
  118. package/dist/version.d.ts +1 -0
  119. package/dist/version.js +3 -0
  120. package/dist/web/browserProvider.d.ts +23 -0
  121. package/dist/web/browserProvider.js +153 -0
  122. package/dist/web/harness.d.ts +102 -0
  123. package/dist/web/harness.js +340 -0
  124. package/dist/web/stability.d.ts +57 -0
  125. package/dist/web/stability.js +316 -0
  126. package/dist/web/tabs.d.ts +58 -0
  127. package/dist/web/tabs.js +293 -0
  128. package/dist/web/transformer.d.ts +7 -0
  129. package/dist/web/transformer.js +41 -0
  130. package/dist/web/types.d.ts +32 -0
  131. package/dist/web/types.js +2 -0
  132. package/dist/web/util.d.ts +3 -0
  133. package/dist/web/util.js +81 -0
  134. package/dist/web/visualizer/cursor.d.ts +16 -0
  135. package/dist/web/visualizer/cursor.js +152 -0
  136. package/dist/web/visualizer/index.d.ts +22 -0
  137. package/dist/web/visualizer/index.js +47 -0
  138. package/dist/web/visualizer/mouseEffects.d.ts +18 -0
  139. package/dist/web/visualizer/mouseEffects.js +287 -0
  140. package/dist/web/visualizer/typeEffects.d.ts +10 -0
  141. package/dist/web/visualizer/typeEffects.js +190 -0
  142. package/package.json +71 -0
@@ -0,0 +1,41 @@
1
+ import getShadowDOMInputAdapterScript from './scripts/shadowDOMInputAdapter';
2
+ import logger from '@/logger';
3
+ export class DOMTransformer {
4
+ initializedPages = new WeakSet(); // Track pages for which 'load' listener is set
5
+ constructor() { }
6
+ setActivePage(newPage) {
7
+ // Only add the 'load' listener if we haven't done so for this specific Page object instance.
8
+ if (!this.initializedPages.has(newPage)) {
9
+ newPage.on('load', async () => {
10
+ // Pass 'newPage' (the page that triggered the 'load' event) to setupScriptForPage.
11
+ await this.setupScriptForPage(newPage);
12
+ });
13
+ this.initializedPages.add(newPage); // Mark this Page object as having its 'load' listener set up.
14
+ }
15
+ }
16
+ async setupScriptForPage(targetPage) {
17
+ try {
18
+ // Check if a marker for the script already exists on the page for this load cycle.
19
+ const scriptAlreadyInjected = await targetPage.evaluate(() => {
20
+ return window.__magnitudeShadowDOMAdapterInjected === true;
21
+ }).catch(() => false); // If evaluate fails (e.g., page closed), assume not injected.
22
+ if (scriptAlreadyInjected) {
23
+ logger.trace('Select manager script already present on this page load.');
24
+ return;
25
+ }
26
+ // Get the script as a string from the separate file
27
+ const scriptFnString = getShadowDOMInputAdapterScript();
28
+ // Evaluate the script function in the browser and set the marker.
29
+ // We need to wrap it in a self-executing function
30
+ await targetPage.evaluate(`
31
+ (${scriptFnString})();
32
+ window.__magnitudeShadowDOMAdapterInjected = true;
33
+ `);
34
+ logger.trace(`Script injected into page: ${targetPage.url()}`);
35
+ }
36
+ catch (error) {
37
+ const url = targetPage.isClosed() ? '[closed page]' : targetPage.url();
38
+ logger.warn(`Error injecting script into ${url}: ${error.message}`);
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,32 @@
1
+ export type Base64Image = `data:image/${'jpeg' | 'png' | 'gif'};base64,${string}`;
2
+ export type WebAction = NavigateWebAction | ClickWebAction | TypeWebAction | ScrollWebAction | SwitchTabWebAction;
3
+ export interface NavigateWebAction {
4
+ variant: 'load';
5
+ url: string;
6
+ }
7
+ export interface ClickWebAction {
8
+ variant: 'click';
9
+ x: number;
10
+ y: number;
11
+ }
12
+ export interface TypeWebAction {
13
+ variant: 'type';
14
+ x: number;
15
+ y: number;
16
+ content: string;
17
+ }
18
+ export interface ScrollWebAction {
19
+ variant: 'scroll';
20
+ x: number;
21
+ y: number;
22
+ deltaX: number;
23
+ deltaY: number;
24
+ }
25
+ export type SwitchTabWebAction = {
26
+ variant: 'tab';
27
+ index: number;
28
+ };
29
+ export interface PixelCoordinate {
30
+ x: number;
31
+ y: number;
32
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ // for back-compat, not all implemented yet
@@ -0,0 +1,3 @@
1
+ export type KeypressIndicator = '<enter>' | '<tab>';
2
+ export declare function parseTypeContent(content: string): (string | KeypressIndicator)[];
3
+ export declare function renderMinimalAccessibilityTree(node: any): string;
@@ -0,0 +1,81 @@
1
+ export function parseTypeContent(content) {
2
+ // Parse content sequence potentially with special indicators <enter> or <tab> into components
3
+ const regex = /<enter>|<tab>/g;
4
+ const result = [];
5
+ let lastIndex = 0;
6
+ content.replace(regex, (match, offset) => {
7
+ // Grab the text before the match and trim surrounding whitespace
8
+ const text = content.slice(lastIndex, offset).trim();
9
+ if (text)
10
+ result.push(text);
11
+ // Add the matched special indicator
12
+ result.push(match);
13
+ lastIndex = offset + match.length;
14
+ return match;
15
+ });
16
+ // Add any remaining text after the last match
17
+ const remaining = content.slice(lastIndex).trim();
18
+ if (remaining)
19
+ result.push(remaining);
20
+ return result;
21
+ }
22
+ export function renderMinimalAccessibilityTree(node) {
23
+ // Escapes newlines for safe inline printing, and trims whitespace.
24
+ const sanitize = (text) => {
25
+ return String(text).trim().replace(/\n/g, '\\n');
26
+ };
27
+ // Inner recursive function to handle state like indentation
28
+ function recursiveFlatten(node, indent) {
29
+ const isTextLike = (n) => n && (n.role === 'StaticText' || n.role === 'text') && n.name && n.name.trim();
30
+ let childrenOutput = '';
31
+ if (node.children) {
32
+ const newChildren = [];
33
+ let currentTextBuffer = [];
34
+ for (const child of node.children) {
35
+ if (isTextLike(child)) {
36
+ currentTextBuffer.push(sanitize(child.name));
37
+ }
38
+ else {
39
+ if (currentTextBuffer.length > 0) {
40
+ newChildren.push({ role: 'coalesced-text', name: currentTextBuffer.join(' ') });
41
+ currentTextBuffer = [];
42
+ }
43
+ newChildren.push(child);
44
+ }
45
+ }
46
+ if (currentTextBuffer.length > 0) {
47
+ newChildren.push({ role: 'coalesced-text', name: currentTextBuffer.join(' ') });
48
+ }
49
+ for (const child of newChildren) {
50
+ if (child.role === 'coalesced-text') {
51
+ childrenOutput += `${indent} ${child.name}\n`;
52
+ }
53
+ else {
54
+ childrenOutput += recursiveFlatten(child, indent + ' ');
55
+ }
56
+ }
57
+ }
58
+ const isBoringContainer = (node.role === 'generic' || node.role === 'div') && !node.name;
59
+ if (isBoringContainer) {
60
+ return childrenOutput;
61
+ }
62
+ let line = '';
63
+ if (node.role && !['StaticText', 'text', 'RootWebArea'].includes(node.role)) {
64
+ line = `${indent}[${node.role}]`;
65
+ if (node.name && sanitize(node.name)) {
66
+ line += ` ${sanitize(node.name)}`;
67
+ }
68
+ if (node.value !== undefined && sanitize(node.value)) {
69
+ line += ` (value: ${sanitize(node.value)})`;
70
+ }
71
+ if (node.checked !== undefined)
72
+ line += ` (checked: ${node.checked})`;
73
+ if (node.disabled)
74
+ line += ` (disabled)`;
75
+ line += '\n';
76
+ }
77
+ return line + childrenOutput;
78
+ }
79
+ const rawFlattened = recursiveFlatten(node, '');
80
+ return rawFlattened.split('\n').filter(line => line.trim() !== '').join('\n');
81
+ }
@@ -0,0 +1,16 @@
1
+ import { Page } from "playwright";
2
+ export declare class CursorVisual {
3
+ /**
4
+ * Manages the visual indicator for actions on a page
5
+ */
6
+ private page;
7
+ private visualElementId;
8
+ private lastPosition;
9
+ constructor();
10
+ setActivePage(page: Page): Promise<void>;
11
+ move(x: number, y: number): Promise<void>;
12
+ setupOnPage(): Promise<void>;
13
+ private _drawVisual;
14
+ hide(): Promise<void>;
15
+ show(): Promise<void>;
16
+ }
@@ -0,0 +1,152 @@
1
+ import { retryOnErrorIsSuccess } from "@/common";
2
+ import logger from "@/logger";
3
+ export class CursorVisual {
4
+ /**
5
+ * Manages the visual indicator for actions on a page
6
+ */
7
+ page;
8
+ visualElementId = 'action-visual-indicator';
9
+ lastPosition = null;
10
+ constructor() {
11
+ //this.page = page;
12
+ }
13
+ async setActivePage(page) {
14
+ this.page = page;
15
+ page.on('load', async () => {
16
+ await retryOnErrorIsSuccess(this.setupOnPage.bind(this), { mode: 'retry_all', delayMs: 200, retryLimit: 10 });
17
+ });
18
+ await retryOnErrorIsSuccess(this.setupOnPage.bind(this), { mode: 'retry_all', delayMs: 200, retryLimit: 5 });
19
+ }
20
+ async move(x, y) {
21
+ // Store the position
22
+ this.lastPosition = { x, y };
23
+ // Create or update the mouse pointer visual, showing the click effect
24
+ await this._drawVisual(x, y, false);
25
+ // The pointer visual takes 0.3s on the transition, but awaiting script evaluation does not wait for this to complete.
26
+ // So we wait 300ms manually.
27
+ await this.page.waitForTimeout(300);
28
+ }
29
+ async setupOnPage() {
30
+ if (this.lastPosition) {
31
+ // Redraw the visual without the click effect
32
+ await this._drawVisual(this.lastPosition.x, this.lastPosition.y, false);
33
+ }
34
+ }
35
+ // Internal method to handle the actual drawing logic
36
+ async _drawVisual(x, y, showClickEffect) {
37
+ try {
38
+ await this.page.evaluate(({ x, y, id, showClickEffect }) => {
39
+ // Use viewport coordinates directly (no scroll adjustment for fixed positioning)
40
+ const viewportX = x;
41
+ const viewportY = y;
42
+ // Document coordinates for the click effect circle (which uses absolute positioning)
43
+ const docX = x + window.scrollX;
44
+ const docY = y + window.scrollY;
45
+ // --- Create Expanding/Fading Circle (Optional) ---
46
+ if (showClickEffect) {
47
+ const circle = document.createElement('div');
48
+ circle.style.position = 'absolute';
49
+ circle.style.left = `${docX}px`;
50
+ circle.style.top = `${docY}px`;
51
+ circle.style.borderRadius = '50%';
52
+ circle.style.backgroundColor = '#026aa1'; // Blue color
53
+ circle.style.width = '0px';
54
+ circle.style.height = '0px';
55
+ circle.style.transform = 'translate(-50%, -50%)'; // Center on (x, y)
56
+ circle.style.pointerEvents = 'none';
57
+ circle.style.zIndex = '9998'; // Below the pointer
58
+ circle.style.opacity = '0.7'; // Initial opacity
59
+ document.body.appendChild(circle);
60
+ // Animate the circle
61
+ const animation = circle.animate([
62
+ { width: '0px', height: '0px', opacity: 0.7 }, // Start state
63
+ { width: '50px', height: '50px', opacity: 0 } // End state
64
+ ], {
65
+ duration: 500, // 500ms duration
66
+ easing: 'ease-out'
67
+ });
68
+ // Remove circle after animation
69
+ animation.onfinish = () => {
70
+ circle.remove();
71
+ };
72
+ }
73
+ // --- Pointer Logic (Always runs) ---
74
+ // Check if the visual indicator already exists
75
+ let pointerElement = document.getElementById(id);
76
+ // If it doesn't exist, create it with all necessary styling
77
+ if (!pointerElement) {
78
+ pointerElement = document.createElement('div');
79
+ pointerElement.id = id;
80
+ pointerElement.style.position = 'fixed'; // Use fixed positioning for viewport-relative
81
+ pointerElement.style.width = '32px';
82
+ pointerElement.style.height = '32px';
83
+ pointerElement.style.zIndex = '2147483647'; // Max z-index
84
+ pointerElement.style.pointerEvents = 'none'; // Don't interfere with actual clicks
85
+ // Notice that transition is 300ms
86
+ pointerElement.style.transition = 'left 0.3s cubic-bezier(0.25, 0.1, 0.25, 1), top 0.3s cubic-bezier(0.25, 0.1, 0.25, 1)';
87
+ // Create SVG using DOM methods to avoid Trusted Types issues
88
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
89
+ svg.setAttribute('width', '32');
90
+ svg.setAttribute('height', '32');
91
+ svg.setAttribute('viewBox', '0 0 113.50408 99.837555');
92
+ const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
93
+ g.setAttribute('transform', 'translate(-413.10686,-501.19661)');
94
+ const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
95
+ path1.setAttribute('style', 'fill:#026aa1;fill-opacity:1;stroke:#000000;stroke-width:0');
96
+ path1.setAttribute('d', 'm 416.1069,504.1966 52.47697,93.83813 8.33253,-57.61019 z');
97
+ const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
98
+ path2.setAttribute('style', 'fill:#0384c7;fill-opacity:1;stroke:#000000;stroke-width:0');
99
+ path2.setAttribute('d', 'm 416.1069,504.1966 60.8095,36.22794 46.69517,-34.75524 z');
100
+ const path3 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
101
+ path3.setAttribute('style', 'fill:#0384c7;fill-opacity:0;stroke:#000000;stroke-width:6;stroke-linecap:round;stroke-linejoin:round');
102
+ path3.setAttribute('d', 'm 416.1069,504.19658 52.47698,93.83813 8.33252,-57.61019 46.69517,-34.75521 -107.50467,-1.47273');
103
+ g.appendChild(path1);
104
+ g.appendChild(path2);
105
+ g.appendChild(path3);
106
+ svg.appendChild(g);
107
+ pointerElement.appendChild(svg);
108
+ document.body.appendChild(pointerElement);
109
+ }
110
+ //pointerElement.style.display = 'none';
111
+ // Update position - use viewport coordinates for fixed positioning
112
+ // Set the top-left corner to (viewportX, viewportY) and then translate by (-1px, -3px)
113
+ // to align the pointer tip (approx. at 1.27, 4.17 within the SVG) with the click point.
114
+ pointerElement.style.left = `${viewportX}px`;
115
+ pointerElement.style.top = `${viewportY}px`;
116
+ pointerElement.style.transform = 'translate(-1px, -3px)';
117
+ }, { x, y, id: this.visualElementId, showClickEffect });
118
+ }
119
+ catch (error) {
120
+ // For example when:
121
+ // TypeError: Failed to set the 'innerHTML' property on 'Element': This document requires 'TrustedHTML' assignment.
122
+ logger.trace(`Failed to draw visual: ${error.message}`);
123
+ }
124
+ }
125
+ async hide() {
126
+ try {
127
+ await this.page.evaluate((id) => {
128
+ const element = document.getElementById(id);
129
+ if (element) {
130
+ element.style.display = 'none';
131
+ }
132
+ }, this.visualElementId);
133
+ }
134
+ catch {
135
+ logger.trace(`Failed to hide pointer`);
136
+ }
137
+ }
138
+ async show() {
139
+ try {
140
+ await this.page.evaluate((id) => {
141
+ const element = document.getElementById(id);
142
+ if (element) {
143
+ // Revert to the default display value (usually 'block' for a div)
144
+ element.style.display = '';
145
+ }
146
+ }, this.visualElementId);
147
+ }
148
+ catch {
149
+ logger.trace(`Failed to show pointer`);
150
+ }
151
+ }
152
+ }
@@ -0,0 +1,22 @@
1
+ import { BrowserContext, Page } from "playwright";
2
+ export interface ActionVisualizerOptions {
3
+ showCursor?: boolean;
4
+ showHoverCircle?: boolean;
5
+ showClickRipple?: boolean;
6
+ showDragLine?: boolean;
7
+ showTypeEffects?: boolean;
8
+ }
9
+ export declare class ActionVisualizer {
10
+ private options;
11
+ private context;
12
+ private page;
13
+ private cursor;
14
+ private mouseEffects;
15
+ private typeEffects;
16
+ constructor(context: BrowserContext, options: ActionVisualizerOptions);
17
+ setup(): Promise<void>;
18
+ setActivePage(page: Page): Promise<void>;
19
+ moveVirtualCursor(x: number, y: number): Promise<void>;
20
+ hideAll(): Promise<void>;
21
+ showAll(): Promise<void>;
22
+ }
@@ -0,0 +1,47 @@
1
+ import { CursorVisual } from "./cursor";
2
+ import { MouseEffectVisual } from "./mouseEffects";
3
+ import { TypeEffectVisual } from "./typeEffects";
4
+ export class ActionVisualizer {
5
+ options;
6
+ context;
7
+ page;
8
+ cursor;
9
+ mouseEffects;
10
+ typeEffects;
11
+ constructor(context, options) {
12
+ this.context = context;
13
+ this.options = {
14
+ showCursor: options.showCursor ?? true,
15
+ showHoverCircle: options.showHoverCircle ?? false,
16
+ showClickRipple: options.showClickRipple ?? true,
17
+ showDragLine: options.showDragLine ?? false,
18
+ showTypeEffects: options.showTypeEffects ?? true
19
+ };
20
+ this.cursor = new CursorVisual();
21
+ this.mouseEffects = new MouseEffectVisual(this.options);
22
+ this.typeEffects = new TypeEffectVisual();
23
+ }
24
+ async setup() {
25
+ // await this.mouseEffects.setContext(this.context);
26
+ // if (this.options.showTypeEffects) {
27
+ // await this.typeEffects.setContext(this.context);
28
+ // }
29
+ //this.showAll();
30
+ }
31
+ async setActivePage(page) {
32
+ this.page = page;
33
+ await this.cursor.setActivePage(page);
34
+ await this.mouseEffects.setActivePage(page);
35
+ await this.typeEffects.setActivePage(page);
36
+ }
37
+ async moveVirtualCursor(x, y) {
38
+ // Takes like 300ms for smooth anim
39
+ await this.cursor.move(x, y);
40
+ }
41
+ async hideAll() {
42
+ await this.cursor.hide();
43
+ }
44
+ async showAll() {
45
+ await this.cursor.show();
46
+ }
47
+ }
@@ -0,0 +1,18 @@
1
+ import { Page } from "playwright";
2
+ interface MouseEffectOptions {
3
+ baseOpacity?: number;
4
+ showHoverCircle?: boolean;
5
+ showClickRipple?: boolean;
6
+ showDragLine?: boolean;
7
+ }
8
+ export declare class MouseEffectVisual {
9
+ private baseOpacity;
10
+ private showHoverCircle;
11
+ private showClickRipple;
12
+ private showDragLine;
13
+ private page;
14
+ constructor(options?: MouseEffectOptions);
15
+ setActivePage(page: Page): Promise<void>;
16
+ setupOnPage(): Promise<void>;
17
+ }
18
+ export {};