@modelnex/sdk 0.5.29 → 0.5.30
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/README.md +11 -5
- package/dist/dom-sync-L5KIP45X.mjs +55 -0
- package/dist/index.d.mts +0 -9
- package/dist/index.d.ts +0 -9
- package/dist/index.js +3 -7
- package/dist/index.mjs +3 -7
- package/package.json +12 -11
package/README.md
CHANGED
|
@@ -86,7 +86,6 @@ Current behavior:
|
|
|
86
86
|
| `serverUrl` | Backend base URL for chat, tags, tours, voice, and recording APIs |
|
|
87
87
|
| `websiteId` | Tenant/integration identifier |
|
|
88
88
|
| `userProfile` | End-user targeting data for tours/workflows |
|
|
89
|
-
| `devMode` | Enables recording/studio tooling for your internal users |
|
|
90
89
|
|
|
91
90
|
## Chat Bubble Props
|
|
92
91
|
|
|
@@ -115,10 +114,7 @@ export function AppShell({ children, currentUser }) {
|
|
|
115
114
|
return (
|
|
116
115
|
<ModelNexProvider
|
|
117
116
|
websiteId="prod_site_123"
|
|
118
|
-
|
|
119
|
-
// Development setup
|
|
120
|
-
devMode={process.env.NODE_ENV === 'development'}
|
|
121
|
-
|
|
117
|
+
|
|
122
118
|
// User Targeting for Tours & Workflows
|
|
123
119
|
userProfile={{
|
|
124
120
|
userId: currentUser.id,
|
|
@@ -132,6 +128,16 @@ export function AppShell({ children, currentUser }) {
|
|
|
132
128
|
}
|
|
133
129
|
```
|
|
134
130
|
|
|
131
|
+
### Browser-Injected Dev Mode
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<script>
|
|
135
|
+
window.__MODELNEX_DEV_MODE_KEY__ = 'dmk_live_xxxxxxxxx';
|
|
136
|
+
</script>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The SDK now enables dev tooling only after it finds a browser-injected dev mode key and validates it with the backend for the current `websiteId`.
|
|
140
|
+
|
|
135
141
|
### Themed Chat Bubble
|
|
136
142
|
|
|
137
143
|
```tsx
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// src/utils/dom-sync.ts
|
|
2
|
+
function waitForDomSettle(options = {}) {
|
|
3
|
+
const { timeoutMs = 5e3, debounceMs = 400, minWaitMs = 100 } = options;
|
|
4
|
+
return new Promise((resolve) => {
|
|
5
|
+
let debounceTimer = null;
|
|
6
|
+
let resolved = false;
|
|
7
|
+
const maxTimer = setTimeout(() => {
|
|
8
|
+
if (!resolved) {
|
|
9
|
+
resolved = true;
|
|
10
|
+
cleanup();
|
|
11
|
+
console.log("[DOM Sync] Forced resolution by max timeout");
|
|
12
|
+
resolve();
|
|
13
|
+
}
|
|
14
|
+
}, Math.max(timeoutMs, minWaitMs));
|
|
15
|
+
const finish = () => {
|
|
16
|
+
if (!resolved) {
|
|
17
|
+
resolved = true;
|
|
18
|
+
cleanup();
|
|
19
|
+
resolve();
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const observer = new MutationObserver((mutations) => {
|
|
23
|
+
const hasSignificantMutations = mutations.some((m) => {
|
|
24
|
+
if (m.target instanceof HTMLElement) {
|
|
25
|
+
if (m.target.hasAttribute("data-modelnex-tour-highlight")) return false;
|
|
26
|
+
if (m.target.hasAttribute("data-modelnex-caption")) return false;
|
|
27
|
+
if (m.target.closest("#modelnex-studio-root")) return false;
|
|
28
|
+
if (m.target.closest("#modelnex-active-agent-root")) return false;
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
});
|
|
32
|
+
if (!hasSignificantMutations) return;
|
|
33
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
34
|
+
debounceTimer = setTimeout(finish, debounceMs);
|
|
35
|
+
});
|
|
36
|
+
const cleanup = () => {
|
|
37
|
+
observer.disconnect();
|
|
38
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
39
|
+
clearTimeout(maxTimer);
|
|
40
|
+
};
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
if (resolved) return;
|
|
43
|
+
observer.observe(document.body, {
|
|
44
|
+
childList: true,
|
|
45
|
+
subtree: true,
|
|
46
|
+
attributes: true,
|
|
47
|
+
characterData: true
|
|
48
|
+
});
|
|
49
|
+
debounceTimer = setTimeout(finish, debounceMs);
|
|
50
|
+
}, minWaitMs);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
waitForDomSettle
|
|
55
|
+
};
|
package/dist/index.d.mts
CHANGED
|
@@ -845,15 +845,6 @@ interface ModelNexProviderProps {
|
|
|
845
845
|
* Same-origin base for tour API (avoids CORS for ?modelnex_test_tour=)
|
|
846
846
|
*/
|
|
847
847
|
toursApiBase?: string;
|
|
848
|
-
/**
|
|
849
|
-
* Enable SDK dev tools unconditionally (tour recording, studio mode)
|
|
850
|
-
*/
|
|
851
|
-
devMode?: boolean;
|
|
852
|
-
/**
|
|
853
|
-
* Optional dev mode key. When present, the SDK validates it with the backend
|
|
854
|
-
* and enables dev tooling when the key matches the project configuration.
|
|
855
|
-
*/
|
|
856
|
-
devModeKey?: string;
|
|
857
848
|
}
|
|
858
849
|
declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
|
|
859
850
|
|
package/dist/index.d.ts
CHANGED
|
@@ -845,15 +845,6 @@ interface ModelNexProviderProps {
|
|
|
845
845
|
* Same-origin base for tour API (avoids CORS for ?modelnex_test_tour=)
|
|
846
846
|
*/
|
|
847
847
|
toursApiBase?: string;
|
|
848
|
-
/**
|
|
849
|
-
* Enable SDK dev tools unconditionally (tour recording, studio mode)
|
|
850
|
-
*/
|
|
851
|
-
devMode?: boolean;
|
|
852
|
-
/**
|
|
853
|
-
* Optional dev mode key. When present, the SDK validates it with the backend
|
|
854
|
-
* and enables dev tooling when the key matches the project configuration.
|
|
855
|
-
*/
|
|
856
|
-
devModeKey?: string;
|
|
857
848
|
}
|
|
858
849
|
declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
|
|
859
850
|
|
package/dist/index.js
CHANGED
|
@@ -2766,9 +2766,7 @@ function normalizeDevModeKey(value) {
|
|
|
2766
2766
|
const normalized = value.trim();
|
|
2767
2767
|
return normalized || void 0;
|
|
2768
2768
|
}
|
|
2769
|
-
function resolveInjectedDevModeKey(
|
|
2770
|
-
const normalizedExplicitKey = normalizeDevModeKey(explicitDevModeKey);
|
|
2771
|
-
if (normalizedExplicitKey) return normalizedExplicitKey;
|
|
2769
|
+
function resolveInjectedDevModeKey() {
|
|
2772
2770
|
if (typeof window === "undefined") return void 0;
|
|
2773
2771
|
const browserWindow = window;
|
|
2774
2772
|
for (const globalName of DEV_MODE_KEY_GLOBAL_NAMES) {
|
|
@@ -11741,8 +11739,6 @@ var ModelNexProvider = ({
|
|
|
11741
11739
|
websiteId,
|
|
11742
11740
|
userProfile,
|
|
11743
11741
|
toursApiBase,
|
|
11744
|
-
devMode,
|
|
11745
|
-
devModeKey,
|
|
11746
11742
|
serverUrl: serverUrlProp
|
|
11747
11743
|
}) => {
|
|
11748
11744
|
const serverUrl = serverUrlProp ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
@@ -11766,7 +11762,7 @@ var ModelNexProvider = ({
|
|
|
11766
11762
|
const [socketId, setSocketId] = (0, import_react21.useState)(null);
|
|
11767
11763
|
const [actions, setActions] = (0, import_react21.useState)(/* @__PURE__ */ new Map());
|
|
11768
11764
|
const [validatedBrowserDevMode, setValidatedBrowserDevMode] = (0, import_react21.useState)(false);
|
|
11769
|
-
const resolvedDevModeKey = (0, import_react21.useMemo)(() => resolveInjectedDevModeKey(
|
|
11765
|
+
const resolvedDevModeKey = (0, import_react21.useMemo)(() => resolveInjectedDevModeKey(), []);
|
|
11770
11766
|
(0, import_react21.useEffect)(() => {
|
|
11771
11767
|
let cancelled = false;
|
|
11772
11768
|
if (!websiteId || !resolvedDevModeKey) {
|
|
@@ -11783,7 +11779,7 @@ var ModelNexProvider = ({
|
|
|
11783
11779
|
cancelled = true;
|
|
11784
11780
|
};
|
|
11785
11781
|
}, [resolvedDevModeKey, serverUrl, websiteId]);
|
|
11786
|
-
const effectiveDevMode =
|
|
11782
|
+
const effectiveDevMode = validatedBrowserDevMode;
|
|
11787
11783
|
const registerAction = (0, import_react21.useCallback)((action) => {
|
|
11788
11784
|
setActions((prev) => {
|
|
11789
11785
|
const next = new Map(prev);
|
package/dist/index.mjs
CHANGED
|
@@ -2557,9 +2557,7 @@ function normalizeDevModeKey(value) {
|
|
|
2557
2557
|
const normalized = value.trim();
|
|
2558
2558
|
return normalized || void 0;
|
|
2559
2559
|
}
|
|
2560
|
-
function resolveInjectedDevModeKey(
|
|
2561
|
-
const normalizedExplicitKey = normalizeDevModeKey(explicitDevModeKey);
|
|
2562
|
-
if (normalizedExplicitKey) return normalizedExplicitKey;
|
|
2560
|
+
function resolveInjectedDevModeKey() {
|
|
2563
2561
|
if (typeof window === "undefined") return void 0;
|
|
2564
2562
|
const browserWindow = window;
|
|
2565
2563
|
for (const globalName of DEV_MODE_KEY_GLOBAL_NAMES) {
|
|
@@ -11531,8 +11529,6 @@ var ModelNexProvider = ({
|
|
|
11531
11529
|
websiteId,
|
|
11532
11530
|
userProfile,
|
|
11533
11531
|
toursApiBase,
|
|
11534
|
-
devMode,
|
|
11535
|
-
devModeKey,
|
|
11536
11532
|
serverUrl: serverUrlProp
|
|
11537
11533
|
}) => {
|
|
11538
11534
|
const serverUrl = serverUrlProp ?? DEFAULT_MODELNEX_SERVER_URL;
|
|
@@ -11556,7 +11552,7 @@ var ModelNexProvider = ({
|
|
|
11556
11552
|
const [socketId, setSocketId] = useState15(null);
|
|
11557
11553
|
const [actions, setActions] = useState15(/* @__PURE__ */ new Map());
|
|
11558
11554
|
const [validatedBrowserDevMode, setValidatedBrowserDevMode] = useState15(false);
|
|
11559
|
-
const resolvedDevModeKey = useMemo5(() => resolveInjectedDevModeKey(
|
|
11555
|
+
const resolvedDevModeKey = useMemo5(() => resolveInjectedDevModeKey(), []);
|
|
11560
11556
|
useEffect19(() => {
|
|
11561
11557
|
let cancelled = false;
|
|
11562
11558
|
if (!websiteId || !resolvedDevModeKey) {
|
|
@@ -11573,7 +11569,7 @@ var ModelNexProvider = ({
|
|
|
11573
11569
|
cancelled = true;
|
|
11574
11570
|
};
|
|
11575
11571
|
}, [resolvedDevModeKey, serverUrl, websiteId]);
|
|
11576
|
-
const effectiveDevMode =
|
|
11572
|
+
const effectiveDevMode = validatedBrowserDevMode;
|
|
11577
11573
|
const registerAction = useCallback14((action) => {
|
|
11578
11574
|
setActions((prev) => {
|
|
11579
11575
|
const next = new Map(prev);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelnex/sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.30",
|
|
4
4
|
"description": "React SDK for natural language control of web apps via AI agents",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -20,6 +20,15 @@
|
|
|
20
20
|
"dist",
|
|
21
21
|
"README.md"
|
|
22
22
|
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"prepublishOnly": "npm run build",
|
|
25
|
+
"build": "npm exec -- tsup src/index.ts --format cjs,esm --dts",
|
|
26
|
+
"dev": "npm exec -- tsup src/index.ts --format cjs,esm --watch --dts",
|
|
27
|
+
"lint": "eslint src/",
|
|
28
|
+
"test": "npm run build && node --test tests/*.test.js",
|
|
29
|
+
"test:ci": "npm run test && npm run test:unit",
|
|
30
|
+
"test:unit": "node --import tsx --test tests/*.test.ts"
|
|
31
|
+
},
|
|
23
32
|
"peerDependencies": {
|
|
24
33
|
"react": ">=17.0.0",
|
|
25
34
|
"react-dom": ">=17.0.0",
|
|
@@ -58,13 +67,5 @@
|
|
|
58
67
|
"bugs": {
|
|
59
68
|
"url": "https://github.com/sharunaraksha/modelnex-sdk/issues"
|
|
60
69
|
},
|
|
61
|
-
"homepage": "https://github.com/sharunaraksha/modelnex-sdk#readme"
|
|
62
|
-
|
|
63
|
-
"build": "npm exec -- tsup src/index.ts --format cjs,esm --dts",
|
|
64
|
-
"dev": "npm exec -- tsup src/index.ts --format cjs,esm --watch --dts",
|
|
65
|
-
"lint": "eslint src/",
|
|
66
|
-
"test": "npm run build && node --test tests/*.test.js",
|
|
67
|
-
"test:ci": "npm run test && npm run test:unit",
|
|
68
|
-
"test:unit": "node --import tsx --test tests/*.test.ts"
|
|
69
|
-
}
|
|
70
|
-
}
|
|
70
|
+
"homepage": "https://github.com/sharunaraksha/modelnex-sdk#readme"
|
|
71
|
+
}
|