@cuekit-ai/react 1.3.3 → 1.4.0
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-ZGHSIEXZ.mjs → chunk-VQ6DNY3R.mjs} +287 -90
- package/dist/index.d.mts +40 -30
- package/dist/index.d.ts +40 -30
- package/dist/index.js +315 -120
- package/dist/index.mjs +38 -34
- package/dist/{webrtc-service-SDVOO4LS.mjs → webrtc-service-3TOBGQF7.mjs} +3 -1
- package/package.json +3 -2
|
@@ -22729,15 +22729,24 @@ var GlobalStore = {
|
|
|
22729
22729
|
var navigation;
|
|
22730
22730
|
var navigationHandler = null;
|
|
22731
22731
|
function setNavigationHandler(handler) {
|
|
22732
|
+
console.log("\u{1F9ED} setNavigationHandler called with:", !!handler);
|
|
22732
22733
|
navigationHandler = handler;
|
|
22733
22734
|
}
|
|
22734
22735
|
function navigate(path, params) {
|
|
22735
22736
|
const safeParams = params || {};
|
|
22736
22737
|
const absolutePath = path.startsWith("/") ? path : `/${path}`;
|
|
22738
|
+
console.log("\u{1F9ED} navigate() called with:", {
|
|
22739
|
+
path,
|
|
22740
|
+
absolutePath,
|
|
22741
|
+
safeParams,
|
|
22742
|
+
hasNavigationHandler: !!navigationHandler
|
|
22743
|
+
});
|
|
22737
22744
|
if (navigationHandler) {
|
|
22738
22745
|
try {
|
|
22746
|
+
console.log("\u{1F9ED} Using navigationHandler:", absolutePath, safeParams);
|
|
22739
22747
|
navigationHandler(absolutePath, safeParams);
|
|
22740
22748
|
} catch (error) {
|
|
22749
|
+
console.error("\u{1F9ED} NavigationHandler error:", error);
|
|
22741
22750
|
}
|
|
22742
22751
|
return;
|
|
22743
22752
|
}
|
|
@@ -22752,27 +22761,46 @@ function navigate(path, params) {
|
|
|
22752
22761
|
navigation.push(fullPath);
|
|
22753
22762
|
} else {
|
|
22754
22763
|
if (typeof window !== "undefined") {
|
|
22755
|
-
window.location.
|
|
22764
|
+
if (window.location.hash && window.location.hash.startsWith("#")) {
|
|
22765
|
+
window.location.hash = fullPath;
|
|
22766
|
+
} else {
|
|
22767
|
+
window.location.href = fullPath;
|
|
22768
|
+
}
|
|
22756
22769
|
}
|
|
22757
22770
|
}
|
|
22758
22771
|
}
|
|
22759
22772
|
var getCurrentPath = () => {
|
|
22760
22773
|
if (typeof window === "undefined") return "";
|
|
22774
|
+
if (window.location.hash && window.location.hash.startsWith("#")) {
|
|
22775
|
+
const hashPath = window.location.hash.substring(1);
|
|
22776
|
+
return hashPath.split("?")[0];
|
|
22777
|
+
}
|
|
22761
22778
|
return window.location.pathname;
|
|
22762
22779
|
};
|
|
22763
22780
|
var getSearchParams = () => {
|
|
22764
22781
|
if (typeof window === "undefined") return new URLSearchParams();
|
|
22782
|
+
if (window.location.hash && window.location.hash.includes("?")) {
|
|
22783
|
+
const queryString = window.location.hash.split("?")[1];
|
|
22784
|
+
return new URLSearchParams(queryString);
|
|
22785
|
+
}
|
|
22765
22786
|
return new URLSearchParams(window.location.search);
|
|
22766
22787
|
};
|
|
22767
22788
|
var safeNavigate = (name, params = {}) => {
|
|
22789
|
+
console.log("\u{1F9ED} safeNavigate called with:", { name, params });
|
|
22768
22790
|
if (name) {
|
|
22769
22791
|
navigate(name, params);
|
|
22770
22792
|
} else {
|
|
22793
|
+
console.log("\u{1F9ED} safeNavigate: no name provided, skipping navigation");
|
|
22771
22794
|
}
|
|
22772
22795
|
};
|
|
22773
22796
|
function getCurrentScreenName() {
|
|
22774
22797
|
try {
|
|
22775
22798
|
const path = getCurrentPath();
|
|
22799
|
+
const pathParams = getCurrentPathParams();
|
|
22800
|
+
if (path && Object.keys(pathParams).length > 0) {
|
|
22801
|
+
const paramString = Object.entries(pathParams).map(([key, value]) => `${key}=${value}`).join(",");
|
|
22802
|
+
return `${path}?${paramString}`;
|
|
22803
|
+
}
|
|
22776
22804
|
return path || "UnknownScreen";
|
|
22777
22805
|
} catch (e2) {
|
|
22778
22806
|
return "UnknownScreen";
|
|
@@ -22794,6 +22822,45 @@ function getCurrentRouteParams() {
|
|
|
22794
22822
|
return {};
|
|
22795
22823
|
}
|
|
22796
22824
|
}
|
|
22825
|
+
function getCurrentPathParams() {
|
|
22826
|
+
try {
|
|
22827
|
+
const currentPath = getCurrentPath();
|
|
22828
|
+
const params = {};
|
|
22829
|
+
const numericIdMatch = currentPath.match(/\/(\d+)(?:\/|$)/);
|
|
22830
|
+
if (numericIdMatch) {
|
|
22831
|
+
params.id = numericIdMatch[1];
|
|
22832
|
+
}
|
|
22833
|
+
const uuidMatch = currentPath.match(
|
|
22834
|
+
/\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:\/|$)/i
|
|
22835
|
+
);
|
|
22836
|
+
if (uuidMatch) {
|
|
22837
|
+
params.uuid = uuidMatch[1];
|
|
22838
|
+
}
|
|
22839
|
+
const slugMatch = currentPath.match(/\/([a-z0-9-]+)(?:\/|$)/i);
|
|
22840
|
+
if (slugMatch && !numericIdMatch && !uuidMatch) {
|
|
22841
|
+
params.slug = slugMatch[1];
|
|
22842
|
+
}
|
|
22843
|
+
return params;
|
|
22844
|
+
} catch (e2) {
|
|
22845
|
+
return {};
|
|
22846
|
+
}
|
|
22847
|
+
}
|
|
22848
|
+
function resolveRoutePath(routePath, params) {
|
|
22849
|
+
try {
|
|
22850
|
+
let resolvedPath = routePath;
|
|
22851
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
22852
|
+
const placeholder = `:${key}`;
|
|
22853
|
+
if (resolvedPath.includes(placeholder)) {
|
|
22854
|
+
resolvedPath = resolvedPath.replace(placeholder, value);
|
|
22855
|
+
}
|
|
22856
|
+
});
|
|
22857
|
+
resolvedPath = resolvedPath.replace(/:\w+/g, "");
|
|
22858
|
+
resolvedPath = resolvedPath.replace(/\/+/g, "/");
|
|
22859
|
+
return resolvedPath;
|
|
22860
|
+
} catch (e2) {
|
|
22861
|
+
return routePath;
|
|
22862
|
+
}
|
|
22863
|
+
}
|
|
22797
22864
|
function onStateChange() {
|
|
22798
22865
|
const routeName = getCurrentScreenName();
|
|
22799
22866
|
const params = getCurrentRouteParams();
|
|
@@ -22912,13 +22979,23 @@ function getElementPath2(element) {
|
|
|
22912
22979
|
}
|
|
22913
22980
|
|
|
22914
22981
|
// src/utils/element-service.ts
|
|
22915
|
-
var INTERACTIVE_ELEMENT_SELECTOR = 'a, button,
|
|
22982
|
+
var INTERACTIVE_ELEMENT_SELECTOR = 'a, button, select, [role="button"], [role="link"], [role="tab"], [onclick], [onmousedown], [onmouseup], [ontouchstart], [ontouchend], [onkeydown], [onkeyup], [onkeypress], [onchange], [onsubmit], [onfocus], [onblur], [data-ansyr-static], [data-ansyr-dynamic]';
|
|
22983
|
+
var elementCache = /* @__PURE__ */ new Map();
|
|
22984
|
+
var cacheTimestamp = 0;
|
|
22985
|
+
var CACHE_TTL = 5e3;
|
|
22916
22986
|
function getInteractiveElements() {
|
|
22917
22987
|
const elements = document.querySelectorAll(INTERACTIVE_ELEMENT_SELECTOR);
|
|
22918
22988
|
return Array.from(new Set(Array.from(elements)));
|
|
22919
22989
|
}
|
|
22920
22990
|
function getImmediateText(element) {
|
|
22921
22991
|
let text = "";
|
|
22992
|
+
const textAttributes = ["label", "text", "placeholder", "title", "alt", "aria-label"];
|
|
22993
|
+
for (const attr of textAttributes) {
|
|
22994
|
+
const value = element.getAttribute(attr);
|
|
22995
|
+
if (value) {
|
|
22996
|
+
text += value + " ";
|
|
22997
|
+
}
|
|
22998
|
+
}
|
|
22922
22999
|
if (element.childNodes) {
|
|
22923
23000
|
for (const node of Array.from(element.childNodes)) {
|
|
22924
23001
|
if (node.nodeType === 3) {
|
|
@@ -22928,12 +23005,30 @@ function getImmediateText(element) {
|
|
|
22928
23005
|
}
|
|
22929
23006
|
return text.trim();
|
|
22930
23007
|
}
|
|
22931
|
-
function
|
|
22932
|
-
console.log("\u{
|
|
22933
|
-
const
|
|
23008
|
+
function executeAction(action) {
|
|
23009
|
+
console.log("\u{1F3AF} Executing element action:", action);
|
|
23010
|
+
const { action_type, target_element, target } = action;
|
|
23011
|
+
switch (action_type) {
|
|
23012
|
+
case "click":
|
|
23013
|
+
return clickElement(target_element);
|
|
23014
|
+
case "navigate":
|
|
23015
|
+
return navigateToElement(target_element || target);
|
|
23016
|
+
case "input":
|
|
23017
|
+
case "focus":
|
|
23018
|
+
return focusElement(target_element);
|
|
23019
|
+
case "toggle":
|
|
23020
|
+
return toggleElement(target_element);
|
|
23021
|
+
default:
|
|
23022
|
+
console.warn(`\u26A0\uFE0F Unknown action type: ${action_type}`);
|
|
23023
|
+
return false;
|
|
23024
|
+
}
|
|
23025
|
+
}
|
|
23026
|
+
function captureAllInteractiveElements() {
|
|
23027
|
+
console.log("\u{1F333} Capturing ALL interactive elements for Cuekit...");
|
|
23028
|
+
const interactiveElements = {};
|
|
22934
23029
|
const descriptionsMap = /* @__PURE__ */ new Map();
|
|
22935
|
-
document.querySelectorAll("[data-for]").forEach((el) => {
|
|
22936
|
-
const targetId = el.getAttribute("data-for");
|
|
23030
|
+
document.querySelectorAll("[data-ansyr-for]").forEach((el) => {
|
|
23031
|
+
const targetId = el.getAttribute("data-ansyr-for");
|
|
22937
23032
|
if (!targetId) return;
|
|
22938
23033
|
const tags = [];
|
|
22939
23034
|
const description = el.getAttribute("data-ansyr-description");
|
|
@@ -22948,110 +23043,115 @@ function captureFullDOMStructure() {
|
|
|
22948
23043
|
descriptionsMap.set(targetId, [...existingTags, ...tags]);
|
|
22949
23044
|
}
|
|
22950
23045
|
});
|
|
22951
|
-
const
|
|
22952
|
-
|
|
23046
|
+
const allInteractiveElements = getInteractiveElements();
|
|
23047
|
+
console.log("\u{1F333} Found", allInteractiveElements.length, "interactive elements");
|
|
23048
|
+
allInteractiveElements.forEach((element) => {
|
|
23049
|
+
if (!(element instanceof HTMLElement)) return;
|
|
22953
23050
|
const style = getComputedStyle(element);
|
|
22954
|
-
if (element.closest("[data-cuekit-ignore]") ||
|
|
23051
|
+
if (element.closest("[data-cuekit-ignore]") || element.tagName.toLowerCase() === "script" || style.display === "none" || style.visibility === "hidden") {
|
|
22955
23052
|
return;
|
|
22956
23053
|
}
|
|
23054
|
+
let elementId = null;
|
|
22957
23055
|
const staticId = element.getAttribute("data-ansyr-static");
|
|
22958
23056
|
const dynamicId = element.getAttribute("data-ansyr-dynamic");
|
|
22959
|
-
|
|
23057
|
+
if (staticId) {
|
|
23058
|
+
elementId = staticId;
|
|
23059
|
+
console.log("\u{1F333} Using pre-assigned static ID:", elementId);
|
|
23060
|
+
} else if (dynamicId) {
|
|
23061
|
+
elementId = dynamicId;
|
|
23062
|
+
console.log("\u{1F333} Using pre-assigned dynamic ID:", elementId);
|
|
23063
|
+
} else {
|
|
23064
|
+
elementId = generateStableDOMId(element);
|
|
23065
|
+
console.log("\u{1F333} Calculated stable DOM ID:", elementId);
|
|
23066
|
+
}
|
|
23067
|
+
if (!elementId) {
|
|
23068
|
+
console.log("\u{1F333} No ID could be determined for element:", element);
|
|
23069
|
+
return;
|
|
23070
|
+
}
|
|
22960
23071
|
const tags = [];
|
|
22961
23072
|
const directDescription = element.getAttribute("data-ansyr-description");
|
|
22962
23073
|
if (directDescription) {
|
|
22963
23074
|
tags.push(directDescription);
|
|
22964
23075
|
}
|
|
22965
|
-
if (
|
|
22966
|
-
tags.push(...descriptionsMap.get(
|
|
23076
|
+
if (descriptionsMap.has(elementId)) {
|
|
23077
|
+
tags.push(...descriptionsMap.get(elementId) || []);
|
|
22967
23078
|
}
|
|
22968
|
-
const
|
|
22969
|
-
|
|
22970
|
-
|
|
22971
|
-
|
|
22972
|
-
|
|
22973
|
-
|
|
22974
|
-
|
|
23079
|
+
const textContent = getImmediateText(element) || element.textContent?.trim() || "";
|
|
23080
|
+
interactiveElements[elementId] = [textContent, ...tags];
|
|
23081
|
+
console.log("\u{1F333} Captured element:", {
|
|
23082
|
+
id: elementId,
|
|
23083
|
+
tagName: element.tagName,
|
|
23084
|
+
textContent: textContent.substring(0, 50),
|
|
23085
|
+
hasStaticId: !!staticId,
|
|
23086
|
+
hasDynamicId: !!dynamicId,
|
|
23087
|
+
isCalculated: !staticId && !dynamicId
|
|
23088
|
+
});
|
|
22975
23089
|
});
|
|
22976
23090
|
const result = {
|
|
22977
23091
|
components: interactiveElements
|
|
22978
23092
|
};
|
|
22979
|
-
console.log("\u{1F333}
|
|
23093
|
+
console.log("\u{1F333} All interactive elements captured:", result);
|
|
22980
23094
|
return result;
|
|
22981
23095
|
}
|
|
22982
|
-
function
|
|
22983
|
-
|
|
22984
|
-
|
|
22985
|
-
"a",
|
|
22986
|
-
"input",
|
|
22987
|
-
"select",
|
|
22988
|
-
"textarea",
|
|
22989
|
-
'[role="button"]',
|
|
22990
|
-
'[role="link"]',
|
|
22991
|
-
'[role="tab"]',
|
|
22992
|
-
"[data-onclick-id]",
|
|
22993
|
-
"[data-on-press-id]",
|
|
22994
|
-
"[onclick]",
|
|
22995
|
-
"[onmousedown]",
|
|
22996
|
-
"[onmouseup]",
|
|
22997
|
-
"[ontouchstart]",
|
|
22998
|
-
"[ontouchend]",
|
|
22999
|
-
"[onkeydown]",
|
|
23000
|
-
"[onkeyup]",
|
|
23001
|
-
"[onkeypress]"
|
|
23002
|
-
];
|
|
23003
|
-
for (const selector of interactiveSelectors) {
|
|
23004
|
-
if (element.matches(selector)) {
|
|
23005
|
-
return true;
|
|
23006
|
-
}
|
|
23007
|
-
}
|
|
23008
|
-
const hasClickEvents = element.onclick !== null || element.getAttribute("onclick") !== null;
|
|
23009
|
-
const hasInteractiveEvents = element.ontouchstart !== null || element.getAttribute("ontouchstart") !== null || element.ontouchend !== null || element.getAttribute("ontouchend") !== null || element.onkeydown !== null || element.getAttribute("onkeydown") !== null || element.onkeyup !== null || element.getAttribute("onkeyup") !== null || element.onkeypress !== null || element.getAttribute("onkeypress") !== null;
|
|
23010
|
-
const hasPointerCursor = element.style.cursor === "pointer" || getComputedStyle(element).cursor === "pointer";
|
|
23011
|
-
const hasTabIndex = element.hasAttribute("tabindex") && parseInt(element.getAttribute("tabindex") || "0") >= 0;
|
|
23012
|
-
const hasInteractiveDataAttrs = element.hasAttribute("data-clickable") || element.hasAttribute("data-interactive") || element.hasAttribute("data-action") || element.hasAttribute("data-handler");
|
|
23013
|
-
const hasInteractiveAria = element.hasAttribute("aria-pressed") || element.hasAttribute("aria-expanded") || element.hasAttribute("aria-selected") || element.hasAttribute("aria-checked");
|
|
23014
|
-
return hasClickEvents || hasInteractiveEvents || hasPointerCursor || hasTabIndex || hasInteractiveDataAttrs || hasInteractiveAria;
|
|
23096
|
+
function clearElementCache() {
|
|
23097
|
+
elementCache.clear();
|
|
23098
|
+
cacheTimestamp = 0;
|
|
23015
23099
|
}
|
|
23016
|
-
function
|
|
23017
|
-
|
|
23018
|
-
|
|
23019
|
-
|
|
23020
|
-
|
|
23021
|
-
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
|
|
23026
|
-
|
|
23027
|
-
|
|
23028
|
-
|
|
23029
|
-
|
|
23030
|
-
|
|
23031
|
-
|
|
23100
|
+
function validateDynamicElements() {
|
|
23101
|
+
if (false) {
|
|
23102
|
+
const elements = document.querySelectorAll("[data-ansyr-dynamic]");
|
|
23103
|
+
const ids = /* @__PURE__ */ new Set();
|
|
23104
|
+
const duplicates = [];
|
|
23105
|
+
elements.forEach((element) => {
|
|
23106
|
+
const id = element.getAttribute("data-ansyr-dynamic");
|
|
23107
|
+
if (id) {
|
|
23108
|
+
if (ids.has(id)) {
|
|
23109
|
+
duplicates.push(id);
|
|
23110
|
+
}
|
|
23111
|
+
ids.add(id);
|
|
23112
|
+
}
|
|
23113
|
+
});
|
|
23114
|
+
if (duplicates.length > 0) {
|
|
23115
|
+
console.warn("\u{1F6A8} CueKit: Duplicate dynamic IDs found:", duplicates);
|
|
23116
|
+
console.warn(
|
|
23117
|
+
"This can cause incorrect element targeting. Ensure each dynamic element has a unique identifier."
|
|
23118
|
+
);
|
|
23119
|
+
}
|
|
23032
23120
|
}
|
|
23033
23121
|
}
|
|
23034
|
-
function getFullDOMStructure() {
|
|
23035
|
-
return captureFullDOMStructure();
|
|
23036
|
-
}
|
|
23037
23122
|
function clickElement(elementId) {
|
|
23123
|
+
console.log("\u{1F5B1}\uFE0F clickElement called with:", elementId);
|
|
23038
23124
|
if (!elementId) {
|
|
23125
|
+
console.log("\u{1F5B1}\uFE0F clickElement: no elementId provided");
|
|
23039
23126
|
return false;
|
|
23040
23127
|
}
|
|
23041
23128
|
const domElement = findDOMElementById(elementId);
|
|
23129
|
+
console.log("\u{1F5B1}\uFE0F clickElement: found DOM element:", domElement);
|
|
23042
23130
|
if (domElement) {
|
|
23131
|
+
console.log("\u{1F5B1}\uFE0F clickElement: attempting to click element:", {
|
|
23132
|
+
tagName: domElement.tagName,
|
|
23133
|
+
id: domElement.id,
|
|
23134
|
+
className: domElement.className,
|
|
23135
|
+
textContent: domElement.textContent?.substring(0, 50)
|
|
23136
|
+
});
|
|
23043
23137
|
domElement.click();
|
|
23138
|
+
console.log("\u{1F5B1}\uFE0F clickElement: click() called successfully");
|
|
23044
23139
|
return true;
|
|
23045
23140
|
}
|
|
23141
|
+
console.log("\u{1F5B1}\uFE0F clickElement: element not found");
|
|
23046
23142
|
return false;
|
|
23047
23143
|
}
|
|
23048
23144
|
function navigateToElement(target) {
|
|
23145
|
+
console.log("\u{1F9ED} navigateToElement called with:", target);
|
|
23049
23146
|
if (!target) {
|
|
23147
|
+
console.log("\u{1F9ED} navigateToElement: no target provided");
|
|
23050
23148
|
return false;
|
|
23051
23149
|
}
|
|
23052
23150
|
if (target.includes("/") || target.startsWith("http")) {
|
|
23151
|
+
console.log("\u{1F9ED} navigateToElement: using safeNavigate for path:", target);
|
|
23053
23152
|
safeNavigate(target, {});
|
|
23054
23153
|
} else {
|
|
23154
|
+
console.log("\u{1F9ED} navigateToElement: using handleNavigationAndClick for element:", target);
|
|
23055
23155
|
handleNavigationAndClick(target, target);
|
|
23056
23156
|
}
|
|
23057
23157
|
return true;
|
|
@@ -23090,21 +23190,82 @@ function toggleElement(elementId) {
|
|
|
23090
23190
|
}
|
|
23091
23191
|
}
|
|
23092
23192
|
function findDOMElementById(elementId) {
|
|
23193
|
+
console.log("\u{1F50D} findDOMElementById called with:", elementId);
|
|
23093
23194
|
if (!elementId) {
|
|
23195
|
+
console.log("\u{1F50D} findDOMElementById: no elementId provided");
|
|
23094
23196
|
return null;
|
|
23095
23197
|
}
|
|
23096
|
-
const
|
|
23097
|
-
|
|
23098
|
-
|
|
23198
|
+
const now = Date.now();
|
|
23199
|
+
if (now - cacheTimestamp < CACHE_TTL && elementCache.has(elementId)) {
|
|
23200
|
+
const cachedElement = elementCache.get(elementId);
|
|
23201
|
+
console.log("\u{1F50D} findDOMElementById: found in cache:", cachedElement);
|
|
23202
|
+
if (document.contains(cachedElement)) {
|
|
23203
|
+
console.log("\u{1F50D} findDOMElementById: returning cached element");
|
|
23204
|
+
return cachedElement;
|
|
23205
|
+
} else {
|
|
23206
|
+
console.log("\u{1F50D} findDOMElementById: cached element no longer in DOM, removing from cache");
|
|
23207
|
+
elementCache.delete(elementId);
|
|
23208
|
+
}
|
|
23209
|
+
}
|
|
23210
|
+
let foundElement = null;
|
|
23211
|
+
console.log(
|
|
23212
|
+
"\u{1F50D} findDOMElementById: checking for static element with selector:",
|
|
23213
|
+
`[data-ansyr-static="${elementId}"]`
|
|
23214
|
+
);
|
|
23215
|
+
const staticElement = document.querySelector(`[data-ansyr-static="${elementId}"]`);
|
|
23216
|
+
if (staticElement instanceof HTMLElement) {
|
|
23217
|
+
console.log("\u{1F50D} findDOMElementById: found static element:", staticElement);
|
|
23218
|
+
foundElement = staticElement;
|
|
23219
|
+
} else {
|
|
23220
|
+
console.log(
|
|
23221
|
+
"\u{1F50D} findDOMElementById: checking for dynamic element with selector:",
|
|
23222
|
+
`[data-ansyr-dynamic="${elementId}"]`
|
|
23223
|
+
);
|
|
23224
|
+
const dynamicElement = document.querySelector(`[data-ansyr-dynamic="${elementId}"]`);
|
|
23225
|
+
if (dynamicElement instanceof HTMLElement) {
|
|
23226
|
+
console.log("\u{1F50D} findDOMElementById: found dynamic element:", dynamicElement);
|
|
23227
|
+
foundElement = dynamicElement;
|
|
23228
|
+
}
|
|
23229
|
+
}
|
|
23230
|
+
if (!foundElement) {
|
|
23231
|
+
console.log(
|
|
23232
|
+
"\u{1F50D} findDOMElementById: no pre-assigned element found, scanning all interactive elements"
|
|
23233
|
+
);
|
|
23234
|
+
const interactiveElements = getInteractiveElements();
|
|
23235
|
+
console.log("\u{1F50D} findDOMElementById: found", interactiveElements.length, "interactive elements");
|
|
23236
|
+
for (const element of interactiveElements) {
|
|
23237
|
+
if (!(element instanceof HTMLElement)) continue;
|
|
23099
23238
|
const staticId = element.getAttribute("data-ansyr-static");
|
|
23100
23239
|
const dynamicId = element.getAttribute("data-ansyr-dynamic");
|
|
23101
|
-
|
|
23240
|
+
let currentElementId = null;
|
|
23241
|
+
if (staticId) {
|
|
23242
|
+
currentElementId = staticId;
|
|
23243
|
+
} else if (dynamicId) {
|
|
23244
|
+
currentElementId = dynamicId;
|
|
23245
|
+
} else {
|
|
23246
|
+
currentElementId = generateStableDOMId(element);
|
|
23247
|
+
}
|
|
23102
23248
|
if (currentElementId === elementId) {
|
|
23103
|
-
|
|
23249
|
+
console.log("\u{1F50D} findDOMElementById: found element by ID match:", {
|
|
23250
|
+
element,
|
|
23251
|
+
id: currentElementId,
|
|
23252
|
+
hasStaticId: !!staticId,
|
|
23253
|
+
hasDynamicId: !!dynamicId,
|
|
23254
|
+
isCalculated: !staticId && !dynamicId
|
|
23255
|
+
});
|
|
23256
|
+
foundElement = element;
|
|
23257
|
+
break;
|
|
23104
23258
|
}
|
|
23105
23259
|
}
|
|
23260
|
+
if (!foundElement) {
|
|
23261
|
+
console.log("\u{1F50D} findDOMElementById: element not found in interactive elements scan");
|
|
23262
|
+
}
|
|
23263
|
+
}
|
|
23264
|
+
if (foundElement) {
|
|
23265
|
+
elementCache.set(elementId, foundElement);
|
|
23266
|
+
cacheTimestamp = now;
|
|
23106
23267
|
}
|
|
23107
|
-
return
|
|
23268
|
+
return foundElement;
|
|
23108
23269
|
}
|
|
23109
23270
|
|
|
23110
23271
|
// src/utils/webrtc-service.ts
|
|
@@ -23123,8 +23284,16 @@ function setAudioContainer(newAudioContainerRef) {
|
|
|
23123
23284
|
audioContainerRef = newAudioContainerRef;
|
|
23124
23285
|
}
|
|
23125
23286
|
function setWebRTCCallbacks(newCallbacks) {
|
|
23287
|
+
console.log("\u{1F4E1} setWebRTCCallbacks called with:", {
|
|
23288
|
+
hasOnNavigationCommand: !!newCallbacks.onNavigationCommand,
|
|
23289
|
+
hasOnConnectionStateChange: !!newCallbacks.onConnectionStateChange,
|
|
23290
|
+
hasOnParticipantUpdate: !!newCallbacks.onParticipantUpdate
|
|
23291
|
+
});
|
|
23126
23292
|
callbacks = newCallbacks;
|
|
23127
23293
|
}
|
|
23294
|
+
function getCurrentCallbacks() {
|
|
23295
|
+
return callbacks;
|
|
23296
|
+
}
|
|
23128
23297
|
async function authenticate(userIdentity, apiKey, appId) {
|
|
23129
23298
|
try {
|
|
23130
23299
|
const authPayload = {
|
|
@@ -23215,12 +23384,34 @@ function setupEventListeners() {
|
|
|
23215
23384
|
track.detach().forEach((element) => element.remove());
|
|
23216
23385
|
}).on(RoomEvent.DataReceived, (payload, participant) => {
|
|
23217
23386
|
const decodedPayload = new TextDecoder().decode(payload);
|
|
23218
|
-
|
|
23219
|
-
|
|
23220
|
-
|
|
23221
|
-
|
|
23222
|
-
const
|
|
23223
|
-
|
|
23387
|
+
console.log("\u{1F4E1} WebRTC DataReceived:", { decodedPayload, participant: participant?.identity });
|
|
23388
|
+
if (decodedPayload.includes("|")) {
|
|
23389
|
+
const parts = decodedPayload.split("|");
|
|
23390
|
+
const textPart = parts[0];
|
|
23391
|
+
const jsonPart = parts[1];
|
|
23392
|
+
console.log("\u{1F4E1} WebRTC Pipe-separated message:", { textPart, jsonPart });
|
|
23393
|
+
if (textPart) {
|
|
23394
|
+
callbacks.onNavigationCommand?.({ type: "speech_text", data: textPart });
|
|
23395
|
+
}
|
|
23396
|
+
if (jsonPart) {
|
|
23397
|
+
try {
|
|
23398
|
+
const message = JSON.parse(jsonPart);
|
|
23399
|
+
console.log("\u{1F4E1} WebRTC Parsed JSON message:", message);
|
|
23400
|
+
callbacks.onNavigationCommand?.(message);
|
|
23401
|
+
} catch (error) {
|
|
23402
|
+
console.log("\u{1F4E1} WebRTC JSON parse error for JSON part:", error, "JSON part:", jsonPart);
|
|
23403
|
+
}
|
|
23404
|
+
}
|
|
23405
|
+
} else {
|
|
23406
|
+
try {
|
|
23407
|
+
const message = JSON.parse(decodedPayload);
|
|
23408
|
+
console.log("\u{1F4E1} WebRTC Parsed message:", message);
|
|
23409
|
+
callbacks.onNavigationCommand?.(message);
|
|
23410
|
+
} catch (error) {
|
|
23411
|
+
console.log("\u{1F4E1} WebRTC JSON parse error:", error, "Raw payload:", decodedPayload);
|
|
23412
|
+
const message = decodedPayload;
|
|
23413
|
+
callbacks.onNavigationCommand?.({ type: "raw_text", data: message });
|
|
23414
|
+
}
|
|
23224
23415
|
}
|
|
23225
23416
|
}).on(RoomEvent.Disconnected, () => {
|
|
23226
23417
|
setWebRTCConnectionState({ isConnected: false, isConnecting: false });
|
|
@@ -23274,17 +23465,19 @@ async function sendUserCommand(command) {
|
|
|
23274
23465
|
await sendData(command);
|
|
23275
23466
|
}
|
|
23276
23467
|
async function sendRuntimeData() {
|
|
23468
|
+
console.log("\u{1F9E0} checking room:", room);
|
|
23277
23469
|
if (!room) {
|
|
23278
23470
|
return;
|
|
23279
23471
|
}
|
|
23472
|
+
console.log("\u{1F9E0} Sending runtime data", room);
|
|
23280
23473
|
try {
|
|
23281
|
-
const
|
|
23474
|
+
const allInteractiveElements = captureAllInteractiveElements();
|
|
23282
23475
|
const screenName = getCurrentScreenName();
|
|
23283
23476
|
const response = {
|
|
23284
23477
|
type: "runtime_data_response",
|
|
23285
23478
|
data: {
|
|
23286
|
-
components:
|
|
23287
|
-
|
|
23479
|
+
components: allInteractiveElements.components,
|
|
23480
|
+
currentRoute: screenName
|
|
23288
23481
|
}
|
|
23289
23482
|
};
|
|
23290
23483
|
await sendData(JSON.stringify(response));
|
|
@@ -23349,6 +23542,8 @@ export {
|
|
|
23349
23542
|
setWebRTCConfig,
|
|
23350
23543
|
GlobalStore,
|
|
23351
23544
|
setNavigationHandler,
|
|
23545
|
+
getCurrentPathParams,
|
|
23546
|
+
resolveRoutePath,
|
|
23352
23547
|
onStateChange,
|
|
23353
23548
|
WEBRTC_BACKEND_SERVER_URL,
|
|
23354
23549
|
RoomEvent,
|
|
@@ -23356,12 +23551,14 @@ export {
|
|
|
23356
23551
|
Track,
|
|
23357
23552
|
createAudioAnalyser,
|
|
23358
23553
|
ConnectionState,
|
|
23359
|
-
captureFullDOMStructure,
|
|
23360
23554
|
executeAction,
|
|
23361
|
-
|
|
23555
|
+
captureAllInteractiveElements,
|
|
23556
|
+
clearElementCache,
|
|
23557
|
+
validateDynamicElements,
|
|
23362
23558
|
setServerUrl,
|
|
23363
23559
|
setAudioContainer,
|
|
23364
23560
|
setWebRTCCallbacks,
|
|
23561
|
+
getCurrentCallbacks,
|
|
23365
23562
|
authenticate,
|
|
23366
23563
|
connectToRoom,
|
|
23367
23564
|
sendData,
|
package/dist/index.d.mts
CHANGED
|
@@ -129,25 +129,15 @@ interface ServerConfig {
|
|
|
129
129
|
token_ttl_seconds: number;
|
|
130
130
|
server_version: string;
|
|
131
131
|
}
|
|
132
|
+
interface AIIntentData {
|
|
133
|
+
actionType: 'navigate' | 'click' | 'input' | 'scroll';
|
|
134
|
+
routeName?: string;
|
|
135
|
+
elementId?: string;
|
|
136
|
+
}
|
|
132
137
|
interface NavigationCommand {
|
|
133
|
-
type: '
|
|
134
|
-
data?: {
|
|
135
|
-
app_id?: string;
|
|
136
|
-
components?: any[];
|
|
137
|
-
intents?: any[];
|
|
138
|
-
pages_count?: number;
|
|
139
|
-
elements_count?: number;
|
|
140
|
-
};
|
|
141
|
-
intent?: string;
|
|
142
|
-
actionType?: string;
|
|
143
|
-
text?: string;
|
|
144
|
-
confidence?: number;
|
|
145
|
-
target_element?: string;
|
|
146
|
-
current_page?: string;
|
|
147
|
-
user_input?: string;
|
|
148
|
-
speaker?: 'user' | 'ai';
|
|
149
|
-
duration?: number;
|
|
138
|
+
type: 'ai_intent';
|
|
150
139
|
timestamp?: number;
|
|
140
|
+
data: AIIntentData;
|
|
151
141
|
}
|
|
152
142
|
declare function sendData(data: string, reliable?: boolean): Promise<void>;
|
|
153
143
|
declare function sendScreenStatus(screenData: any): Promise<void>;
|
|
@@ -254,20 +244,13 @@ declare const initWebRTCWithDeployedBackend: (apiKey: string, customConfig?: Par
|
|
|
254
244
|
*/
|
|
255
245
|
declare const initWebRTC: (apiKey: string) => WebRTCServerConfig;
|
|
256
246
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
textContent: string;
|
|
261
|
-
tags: string[];
|
|
262
|
-
}
|
|
247
|
+
type InteractiveElement = {
|
|
248
|
+
[btnId: string]: string[];
|
|
249
|
+
};
|
|
263
250
|
interface DOMStructurePayload {
|
|
264
|
-
components:
|
|
251
|
+
components: InteractiveElement;
|
|
265
252
|
}
|
|
266
253
|
|
|
267
|
-
/**
|
|
268
|
-
* Capture the full DOM structure as a flat list of interactive elements
|
|
269
|
-
*/
|
|
270
|
-
declare function captureFullDOMStructure(): DOMStructurePayload;
|
|
271
254
|
interface ElementAction {
|
|
272
255
|
action_type: 'click' | 'navigate' | 'input' | 'focus' | 'toggle';
|
|
273
256
|
target_element?: string;
|
|
@@ -275,7 +258,23 @@ interface ElementAction {
|
|
|
275
258
|
instruction?: string;
|
|
276
259
|
}
|
|
277
260
|
declare function executeAction(action: ElementAction): boolean;
|
|
278
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Captures ALL interactive elements on the page.
|
|
263
|
+
* Uses pre-assigned IDs (data-ansyr-static, data-ansyr-dynamic) when available,
|
|
264
|
+
* otherwise calculates stable DOM IDs for elements without pre-assigned IDs.
|
|
265
|
+
*
|
|
266
|
+
* This ensures comprehensive coverage of all interactive elements for AI interaction.
|
|
267
|
+
*/
|
|
268
|
+
declare function captureAllInteractiveElements(): DOMStructurePayload;
|
|
269
|
+
/**
|
|
270
|
+
* Clears the element cache. Call this when the DOM structure changes significantly.
|
|
271
|
+
*/
|
|
272
|
+
declare function clearElementCache(): void;
|
|
273
|
+
/**
|
|
274
|
+
* Validates dynamic elements in development mode.
|
|
275
|
+
* Checks for duplicate IDs and provides warnings.
|
|
276
|
+
*/
|
|
277
|
+
declare function validateDynamicElements(): void;
|
|
279
278
|
|
|
280
279
|
/**
|
|
281
280
|
* Generates a stable, unique 8-character ID for an interactive element.
|
|
@@ -287,4 +286,15 @@ declare function getFullDOMStructure(): DOMStructurePayload;
|
|
|
287
286
|
*/
|
|
288
287
|
declare function generateDynamicId(routePath: string, elementIdentifier: string): string;
|
|
289
288
|
|
|
290
|
-
|
|
289
|
+
/**
|
|
290
|
+
* Extracts route parameters from the current URL path.
|
|
291
|
+
* For routes like /form/:id, extracts { id: "123" } from /form/123
|
|
292
|
+
*/
|
|
293
|
+
declare function getCurrentPathParams(): Record<string, string>;
|
|
294
|
+
/**
|
|
295
|
+
* Resolves a route path with parameters.
|
|
296
|
+
* Example: resolveRoutePath('/form/:id', { id: '123' }) -> '/form/123'
|
|
297
|
+
*/
|
|
298
|
+
declare function resolveRoutePath(routePath: string, params: Record<string, string>): string;
|
|
299
|
+
|
|
300
|
+
export { BorderGlow, ChatPopup, type ChatPopupProps, CuekitProvider, type DOMStructurePayload, type ElementAction, InitCuekit, type InteractiveElement, MicButton, type MicButtonProps, type MicState$1 as MicState, type NavigationCommand, type ServerConfig, type TokenRequest, type TokenResponse, VoiceIntensityVisualizer, type WebRTCServerConfig, captureAllInteractiveElements, clearElementCache, configureWebRTCServer, executeAction, generateDynamicId, getCurrentPathParams, getWebRTCServerConfig, initWebRTC, initWebRTCWithDeployedBackend, resolveRoutePath, useCuekit, useQubeContext, useWebRTC, validateDynamicElements };
|