@prodact.ai/sdk 0.0.7 → 0.0.9
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/cdn/sdk.global.js +81 -62
- package/dist/cdn/sdk.global.js.map +1 -1
- package/dist/index.js +152 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +152 -18
- package/dist/index.mjs.map +1 -1
- package/dist/react.js +152 -18
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +152 -18
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -103,7 +103,8 @@ var DEFAULT_CAPTURE_CONFIG = {
|
|
|
103
103
|
};
|
|
104
104
|
function mergeConfig(userConfig) {
|
|
105
105
|
return {
|
|
106
|
-
enabled: userConfig?.enabled ??
|
|
106
|
+
enabled: userConfig?.enabled ?? true,
|
|
107
|
+
// Enabled by default!
|
|
107
108
|
samplingRate: userConfig?.samplingRate ?? 1,
|
|
108
109
|
privacy: { ...DEFAULT_PRIVACY_CONFIG, ...userConfig?.privacy },
|
|
109
110
|
performance: { ...DEFAULT_PERFORMANCE_CONFIG, ...userConfig?.performance },
|
|
@@ -1115,7 +1116,8 @@ async function captureElementScreenshot(element, maxSize = 200) {
|
|
|
1115
1116
|
}
|
|
1116
1117
|
function mergeConfig2(config) {
|
|
1117
1118
|
const defaults = {
|
|
1118
|
-
enabled:
|
|
1119
|
+
enabled: true,
|
|
1120
|
+
// Enabled by default!
|
|
1119
1121
|
samplingRate: 1,
|
|
1120
1122
|
events: {
|
|
1121
1123
|
clicks: true,
|
|
@@ -1240,7 +1242,15 @@ var UserFlowTracker = class {
|
|
|
1240
1242
|
console.warn("[UserFlow] Cannot track outside browser environment");
|
|
1241
1243
|
return null;
|
|
1242
1244
|
}
|
|
1245
|
+
console.log("[UserFlow] start() called", {
|
|
1246
|
+
enabled: this.config.enabled,
|
|
1247
|
+
samplingRate: this.config.samplingRate,
|
|
1248
|
+
currentState: this.state,
|
|
1249
|
+
apiUrl: this.apiUrl,
|
|
1250
|
+
hasSessionToken: !!this.sessionToken
|
|
1251
|
+
});
|
|
1243
1252
|
if (!this.config.enabled) {
|
|
1253
|
+
console.warn("[UserFlow] Tracking disabled by config");
|
|
1244
1254
|
return null;
|
|
1245
1255
|
}
|
|
1246
1256
|
if (this.state === "tracking") {
|
|
@@ -1586,16 +1596,25 @@ var UserFlowTracker = class {
|
|
|
1586
1596
|
// Link to rrweb recording session if available
|
|
1587
1597
|
linkedRecordingSessionId: this.linkedRecordingSessionId
|
|
1588
1598
|
};
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
+
try {
|
|
1600
|
+
const response = await fetch(endpoint, {
|
|
1601
|
+
method: "POST",
|
|
1602
|
+
headers: {
|
|
1603
|
+
"Content-Type": "application/json",
|
|
1604
|
+
...this.sdkKey ? { "X-SDK-Key": this.sdkKey } : {}
|
|
1605
|
+
},
|
|
1606
|
+
body: JSON.stringify(body)
|
|
1607
|
+
});
|
|
1608
|
+
if (!response.ok) {
|
|
1609
|
+
console.error("[UserFlow] Failed to start session:", response.status, response.statusText);
|
|
1610
|
+
console.error("[UserFlow] Endpoint:", endpoint);
|
|
1611
|
+
throw new Error(`Failed to start session: ${response.status}`);
|
|
1612
|
+
}
|
|
1613
|
+
console.log("[UserFlow] Session started successfully:", this.sessionId);
|
|
1614
|
+
} catch (error) {
|
|
1615
|
+
console.error("[UserFlow] Network error starting session:", error);
|
|
1616
|
+
console.error("[UserFlow] Attempted endpoint:", endpoint);
|
|
1617
|
+
throw error;
|
|
1599
1618
|
}
|
|
1600
1619
|
}
|
|
1601
1620
|
/**
|
|
@@ -1624,9 +1643,15 @@ var UserFlowTracker = class {
|
|
|
1624
1643
|
});
|
|
1625
1644
|
if (response.ok) {
|
|
1626
1645
|
this.batchesSent++;
|
|
1646
|
+
console.log(`[UserFlow] Event batch ${this.batchIndex - 1} sent (${eventsToSend.length} events)`);
|
|
1647
|
+
} else {
|
|
1648
|
+
console.error("[UserFlow] Failed to send event batch:", response.status, response.statusText);
|
|
1649
|
+
console.error("[UserFlow] Endpoint:", endpoint);
|
|
1650
|
+
this.events = [...eventsToSend, ...this.events];
|
|
1627
1651
|
}
|
|
1628
1652
|
} catch (error) {
|
|
1629
|
-
console.error("[UserFlow]
|
|
1653
|
+
console.error("[UserFlow] Network error sending event batch:", error);
|
|
1654
|
+
console.error("[UserFlow] Endpoint:", endpoint);
|
|
1630
1655
|
this.events = [...eventsToSend, ...this.events];
|
|
1631
1656
|
}
|
|
1632
1657
|
}
|
|
@@ -1744,9 +1769,32 @@ var ProduckSDK = class {
|
|
|
1744
1769
|
/** User flow tracker instance (optional, isolated module) */
|
|
1745
1770
|
this.userFlowTracker = null;
|
|
1746
1771
|
let apiUrl = config.apiUrl;
|
|
1772
|
+
let apiUrlAutoDetected = false;
|
|
1747
1773
|
if (!apiUrl) {
|
|
1774
|
+
apiUrlAutoDetected = true;
|
|
1748
1775
|
if (typeof window !== "undefined") {
|
|
1749
|
-
|
|
1776
|
+
const isLocalhost = window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1";
|
|
1777
|
+
if (isLocalhost) {
|
|
1778
|
+
apiUrl = "http://localhost:4001/api/v1";
|
|
1779
|
+
} else {
|
|
1780
|
+
apiUrl = `${window.location.protocol}//${window.location.host}/api/v1`;
|
|
1781
|
+
console.warn(
|
|
1782
|
+
"%c\u26A0\uFE0F Produck SDK Warning: apiUrl not configured!",
|
|
1783
|
+
"background: #fbbf24; color: #000; padding: 4px 8px; font-weight: bold;"
|
|
1784
|
+
);
|
|
1785
|
+
console.warn(
|
|
1786
|
+
`The SDK is auto-detecting apiUrl as: ${apiUrl}
|
|
1787
|
+
This is likely WRONG for production. Your backend is probably at a different URL.
|
|
1788
|
+
|
|
1789
|
+
To fix this, provide apiUrl in your SDK config:
|
|
1790
|
+
|
|
1791
|
+
createProduck({
|
|
1792
|
+
sdkKey: 'your_sdk_key',
|
|
1793
|
+
apiUrl: 'https://your-backend.com/api/v1', // <-- Add this!
|
|
1794
|
+
})
|
|
1795
|
+
`
|
|
1796
|
+
);
|
|
1797
|
+
}
|
|
1750
1798
|
} else {
|
|
1751
1799
|
apiUrl = "http://localhost:4001/api/v1";
|
|
1752
1800
|
}
|
|
@@ -1755,11 +1803,30 @@ var ProduckSDK = class {
|
|
|
1755
1803
|
apiUrl,
|
|
1756
1804
|
...config
|
|
1757
1805
|
};
|
|
1806
|
+
if (typeof window !== "undefined") {
|
|
1807
|
+
console.log(
|
|
1808
|
+
"%c\u{1F527} Produck SDK Config",
|
|
1809
|
+
"background: #3b82f6; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
1810
|
+
{
|
|
1811
|
+
apiUrl: this.config.apiUrl,
|
|
1812
|
+
apiUrlAutoDetected,
|
|
1813
|
+
sdkKey: this.config.sdkKey ? `${this.config.sdkKey.substring(0, 10)}...` : "not set",
|
|
1814
|
+
guiderId: this.config.guiderId || "not set"
|
|
1815
|
+
}
|
|
1816
|
+
);
|
|
1817
|
+
}
|
|
1758
1818
|
}
|
|
1759
1819
|
/**
|
|
1760
1820
|
* Initialize the SDK and create a chat session
|
|
1761
1821
|
*/
|
|
1762
1822
|
async init() {
|
|
1823
|
+
if (typeof window !== "undefined") {
|
|
1824
|
+
console.log(
|
|
1825
|
+
"%c\u{1F680} Produck SDK Initializing...",
|
|
1826
|
+
"background: #10b981; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
1827
|
+
{ endpoint: this.config.apiUrl }
|
|
1828
|
+
);
|
|
1829
|
+
}
|
|
1763
1830
|
await this.log("info", "SDK Initializing", {
|
|
1764
1831
|
apiUrl: this.config.apiUrl,
|
|
1765
1832
|
hasSDKKey: !!this.config.sdkKey,
|
|
@@ -1786,20 +1853,43 @@ var ProduckSDK = class {
|
|
|
1786
1853
|
headers
|
|
1787
1854
|
});
|
|
1788
1855
|
if (!response.ok) {
|
|
1789
|
-
|
|
1856
|
+
let errorDetail = "";
|
|
1857
|
+
try {
|
|
1858
|
+
errorDetail = await response.text();
|
|
1859
|
+
} catch {
|
|
1860
|
+
errorDetail = "Could not read response body";
|
|
1861
|
+
}
|
|
1862
|
+
console.error(
|
|
1863
|
+
"%c\u274C Produck SDK: Failed to create session",
|
|
1864
|
+
"background: #ef4444; color: #fff; padding: 2px 6px; border-radius: 3px;"
|
|
1865
|
+
);
|
|
1866
|
+
console.error(`Status: ${response.status} ${response.statusText}`);
|
|
1867
|
+
console.error(`Endpoint: ${endpoint}`);
|
|
1868
|
+
console.error(`Response: ${errorDetail}`);
|
|
1869
|
+
if (response.status === 404) {
|
|
1870
|
+
console.error(
|
|
1871
|
+
`
|
|
1872
|
+
\u{1F4A1} Tip: A 404 error usually means the apiUrl is wrong.
|
|
1873
|
+
Current apiUrl: ${this.config.apiUrl}
|
|
1874
|
+
Make sure your backend is running and the URL is correct.`
|
|
1875
|
+
);
|
|
1876
|
+
}
|
|
1877
|
+
await this.log("error", "Failed to create session", { status: response.status, errorDetail });
|
|
1790
1878
|
throw new Error(`Failed to create session: ${response.status}`);
|
|
1791
1879
|
}
|
|
1792
1880
|
const session = await response.json();
|
|
1793
1881
|
this.sessionToken = session.session_token;
|
|
1794
1882
|
this.isReady = true;
|
|
1795
1883
|
await this.log("info", "SDK initialized successfully", { hasSessionToken: !!this.sessionToken });
|
|
1796
|
-
|
|
1884
|
+
const recordingEnabled = this.config.recording?.enabled !== false;
|
|
1885
|
+
if (recordingEnabled) {
|
|
1797
1886
|
await this.initRecording();
|
|
1798
1887
|
}
|
|
1799
1888
|
if (this.config.proactive?.enabled) {
|
|
1800
1889
|
this.initProactive();
|
|
1801
1890
|
}
|
|
1802
|
-
|
|
1891
|
+
const userFlowsEnabled = this.config.userFlows?.enabled !== false;
|
|
1892
|
+
if (userFlowsEnabled) {
|
|
1803
1893
|
await this.initUserFlowTracking();
|
|
1804
1894
|
}
|
|
1805
1895
|
this.emit("ready", { sessionToken: this.sessionToken });
|
|
@@ -1807,7 +1897,27 @@ var ProduckSDK = class {
|
|
|
1807
1897
|
await this.sendInitialMessage();
|
|
1808
1898
|
}
|
|
1809
1899
|
} catch (error) {
|
|
1810
|
-
|
|
1900
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1901
|
+
const isNetworkError = errorMessage.includes("fetch") || errorMessage.includes("network") || errorMessage.includes("Failed to fetch") || errorMessage.includes("NetworkError");
|
|
1902
|
+
console.error(
|
|
1903
|
+
"%c\u274C Produck SDK initialization failed",
|
|
1904
|
+
"background: #ef4444; color: #fff; padding: 4px 8px; font-weight: bold;"
|
|
1905
|
+
);
|
|
1906
|
+
console.error(`Error: ${errorMessage}`);
|
|
1907
|
+
console.error(`API URL: ${this.config.apiUrl}`);
|
|
1908
|
+
if (isNetworkError) {
|
|
1909
|
+
console.error(
|
|
1910
|
+
`
|
|
1911
|
+
\u{1F4A1} This looks like a network error. Common causes:
|
|
1912
|
+
1. The apiUrl is incorrect or the backend is not running
|
|
1913
|
+
2. CORS is blocking the request
|
|
1914
|
+
3. The backend server is unreachable
|
|
1915
|
+
|
|
1916
|
+
Current apiUrl: ${this.config.apiUrl}
|
|
1917
|
+
Check the Network tab in DevTools for more details.`
|
|
1918
|
+
);
|
|
1919
|
+
}
|
|
1920
|
+
await this.log("error", "SDK initialization failed", { error: errorMessage });
|
|
1811
1921
|
this.emit("error", error);
|
|
1812
1922
|
throw error;
|
|
1813
1923
|
}
|
|
@@ -2491,6 +2601,15 @@ var ProduckSDK = class {
|
|
|
2491
2601
|
*/
|
|
2492
2602
|
async initUserFlowTracking() {
|
|
2493
2603
|
try {
|
|
2604
|
+
console.log(
|
|
2605
|
+
"%c\u{1F4CA} Initializing User Flow Tracking",
|
|
2606
|
+
"background: #8b5cf6; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
2607
|
+
{
|
|
2608
|
+
config: this.config.userFlows,
|
|
2609
|
+
apiUrl: this.config.apiUrl,
|
|
2610
|
+
sdkKey: this.config.sdkKey ? "present" : "missing"
|
|
2611
|
+
}
|
|
2612
|
+
);
|
|
2494
2613
|
this.userFlowTracker = new UserFlowTracker(this.config.userFlows);
|
|
2495
2614
|
this.userFlowTracker.initialize(
|
|
2496
2615
|
this.sessionToken,
|
|
@@ -2500,12 +2619,27 @@ var ProduckSDK = class {
|
|
|
2500
2619
|
const recordingSessionId = this.recorder?.getSessionId?.() || null;
|
|
2501
2620
|
const sessionId = await this.userFlowTracker.start(recordingSessionId);
|
|
2502
2621
|
if (sessionId) {
|
|
2622
|
+
console.log(
|
|
2623
|
+
"%c\u2705 User Flow Tracking Started",
|
|
2624
|
+
"background: #10b981; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
2625
|
+
{ flowSessionId: sessionId, linkedRecordingSession: recordingSessionId }
|
|
2626
|
+
);
|
|
2503
2627
|
await this.log("info", "User flow tracking started", {
|
|
2504
2628
|
flowSessionId: sessionId,
|
|
2505
2629
|
linkedRecordingSession: recordingSessionId
|
|
2506
2630
|
});
|
|
2631
|
+
} else {
|
|
2632
|
+
console.warn(
|
|
2633
|
+
"%c\u26A0\uFE0F User Flow Tracking: No session ID returned",
|
|
2634
|
+
"background: #f59e0b; color: #000; padding: 2px 6px; border-radius: 3px;"
|
|
2635
|
+
);
|
|
2507
2636
|
}
|
|
2508
2637
|
} catch (error) {
|
|
2638
|
+
console.error(
|
|
2639
|
+
"%c\u274C User Flow Tracking Failed",
|
|
2640
|
+
"background: #ef4444; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
2641
|
+
error
|
|
2642
|
+
);
|
|
2509
2643
|
await this.log("warn", "Failed to initialize user flow tracking", {
|
|
2510
2644
|
error: error instanceof Error ? error.message : String(error)
|
|
2511
2645
|
});
|