@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/index.mjs
CHANGED
|
@@ -54,7 +54,8 @@ var DEFAULT_CAPTURE_CONFIG = {
|
|
|
54
54
|
};
|
|
55
55
|
function mergeConfig(userConfig) {
|
|
56
56
|
return {
|
|
57
|
-
enabled: userConfig?.enabled ??
|
|
57
|
+
enabled: userConfig?.enabled ?? true,
|
|
58
|
+
// Enabled by default!
|
|
58
59
|
samplingRate: userConfig?.samplingRate ?? 1,
|
|
59
60
|
privacy: { ...DEFAULT_PRIVACY_CONFIG, ...userConfig?.privacy },
|
|
60
61
|
performance: { ...DEFAULT_PERFORMANCE_CONFIG, ...userConfig?.performance },
|
|
@@ -1107,7 +1108,8 @@ async function captureElementScreenshot(element, maxSize = 200) {
|
|
|
1107
1108
|
}
|
|
1108
1109
|
function mergeConfig2(config) {
|
|
1109
1110
|
const defaults = {
|
|
1110
|
-
enabled:
|
|
1111
|
+
enabled: true,
|
|
1112
|
+
// Enabled by default!
|
|
1111
1113
|
samplingRate: 1,
|
|
1112
1114
|
events: {
|
|
1113
1115
|
clicks: true,
|
|
@@ -1232,7 +1234,15 @@ var UserFlowTracker = class {
|
|
|
1232
1234
|
console.warn("[UserFlow] Cannot track outside browser environment");
|
|
1233
1235
|
return null;
|
|
1234
1236
|
}
|
|
1237
|
+
console.log("[UserFlow] start() called", {
|
|
1238
|
+
enabled: this.config.enabled,
|
|
1239
|
+
samplingRate: this.config.samplingRate,
|
|
1240
|
+
currentState: this.state,
|
|
1241
|
+
apiUrl: this.apiUrl,
|
|
1242
|
+
hasSessionToken: !!this.sessionToken
|
|
1243
|
+
});
|
|
1235
1244
|
if (!this.config.enabled) {
|
|
1245
|
+
console.warn("[UserFlow] Tracking disabled by config");
|
|
1236
1246
|
return null;
|
|
1237
1247
|
}
|
|
1238
1248
|
if (this.state === "tracking") {
|
|
@@ -1578,16 +1588,25 @@ var UserFlowTracker = class {
|
|
|
1578
1588
|
// Link to rrweb recording session if available
|
|
1579
1589
|
linkedRecordingSessionId: this.linkedRecordingSessionId
|
|
1580
1590
|
};
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
+
try {
|
|
1592
|
+
const response = await fetch(endpoint, {
|
|
1593
|
+
method: "POST",
|
|
1594
|
+
headers: {
|
|
1595
|
+
"Content-Type": "application/json",
|
|
1596
|
+
...this.sdkKey ? { "X-SDK-Key": this.sdkKey } : {}
|
|
1597
|
+
},
|
|
1598
|
+
body: JSON.stringify(body)
|
|
1599
|
+
});
|
|
1600
|
+
if (!response.ok) {
|
|
1601
|
+
console.error("[UserFlow] Failed to start session:", response.status, response.statusText);
|
|
1602
|
+
console.error("[UserFlow] Endpoint:", endpoint);
|
|
1603
|
+
throw new Error(`Failed to start session: ${response.status}`);
|
|
1604
|
+
}
|
|
1605
|
+
console.log("[UserFlow] Session started successfully:", this.sessionId);
|
|
1606
|
+
} catch (error) {
|
|
1607
|
+
console.error("[UserFlow] Network error starting session:", error);
|
|
1608
|
+
console.error("[UserFlow] Attempted endpoint:", endpoint);
|
|
1609
|
+
throw error;
|
|
1591
1610
|
}
|
|
1592
1611
|
}
|
|
1593
1612
|
/**
|
|
@@ -1616,9 +1635,15 @@ var UserFlowTracker = class {
|
|
|
1616
1635
|
});
|
|
1617
1636
|
if (response.ok) {
|
|
1618
1637
|
this.batchesSent++;
|
|
1638
|
+
console.log(`[UserFlow] Event batch ${this.batchIndex - 1} sent (${eventsToSend.length} events)`);
|
|
1639
|
+
} else {
|
|
1640
|
+
console.error("[UserFlow] Failed to send event batch:", response.status, response.statusText);
|
|
1641
|
+
console.error("[UserFlow] Endpoint:", endpoint);
|
|
1642
|
+
this.events = [...eventsToSend, ...this.events];
|
|
1619
1643
|
}
|
|
1620
1644
|
} catch (error) {
|
|
1621
|
-
console.error("[UserFlow]
|
|
1645
|
+
console.error("[UserFlow] Network error sending event batch:", error);
|
|
1646
|
+
console.error("[UserFlow] Endpoint:", endpoint);
|
|
1622
1647
|
this.events = [...eventsToSend, ...this.events];
|
|
1623
1648
|
}
|
|
1624
1649
|
}
|
|
@@ -1739,9 +1764,32 @@ var ProduckSDK = class {
|
|
|
1739
1764
|
/** User flow tracker instance (optional, isolated module) */
|
|
1740
1765
|
this.userFlowTracker = null;
|
|
1741
1766
|
let apiUrl = config.apiUrl;
|
|
1767
|
+
let apiUrlAutoDetected = false;
|
|
1742
1768
|
if (!apiUrl) {
|
|
1769
|
+
apiUrlAutoDetected = true;
|
|
1743
1770
|
if (typeof window !== "undefined") {
|
|
1744
|
-
|
|
1771
|
+
const isLocalhost = window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1";
|
|
1772
|
+
if (isLocalhost) {
|
|
1773
|
+
apiUrl = "http://localhost:4001/api/v1";
|
|
1774
|
+
} else {
|
|
1775
|
+
apiUrl = `${window.location.protocol}//${window.location.host}/api/v1`;
|
|
1776
|
+
console.warn(
|
|
1777
|
+
"%c\u26A0\uFE0F Produck SDK Warning: apiUrl not configured!",
|
|
1778
|
+
"background: #fbbf24; color: #000; padding: 4px 8px; font-weight: bold;"
|
|
1779
|
+
);
|
|
1780
|
+
console.warn(
|
|
1781
|
+
`The SDK is auto-detecting apiUrl as: ${apiUrl}
|
|
1782
|
+
This is likely WRONG for production. Your backend is probably at a different URL.
|
|
1783
|
+
|
|
1784
|
+
To fix this, provide apiUrl in your SDK config:
|
|
1785
|
+
|
|
1786
|
+
createProduck({
|
|
1787
|
+
sdkKey: 'your_sdk_key',
|
|
1788
|
+
apiUrl: 'https://your-backend.com/api/v1', // <-- Add this!
|
|
1789
|
+
})
|
|
1790
|
+
`
|
|
1791
|
+
);
|
|
1792
|
+
}
|
|
1745
1793
|
} else {
|
|
1746
1794
|
apiUrl = "http://localhost:4001/api/v1";
|
|
1747
1795
|
}
|
|
@@ -1750,11 +1798,30 @@ var ProduckSDK = class {
|
|
|
1750
1798
|
apiUrl,
|
|
1751
1799
|
...config
|
|
1752
1800
|
};
|
|
1801
|
+
if (typeof window !== "undefined") {
|
|
1802
|
+
console.log(
|
|
1803
|
+
"%c\u{1F527} Produck SDK Config",
|
|
1804
|
+
"background: #3b82f6; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
1805
|
+
{
|
|
1806
|
+
apiUrl: this.config.apiUrl,
|
|
1807
|
+
apiUrlAutoDetected,
|
|
1808
|
+
sdkKey: this.config.sdkKey ? `${this.config.sdkKey.substring(0, 10)}...` : "not set",
|
|
1809
|
+
guiderId: this.config.guiderId || "not set"
|
|
1810
|
+
}
|
|
1811
|
+
);
|
|
1812
|
+
}
|
|
1753
1813
|
}
|
|
1754
1814
|
/**
|
|
1755
1815
|
* Initialize the SDK and create a chat session
|
|
1756
1816
|
*/
|
|
1757
1817
|
async init() {
|
|
1818
|
+
if (typeof window !== "undefined") {
|
|
1819
|
+
console.log(
|
|
1820
|
+
"%c\u{1F680} Produck SDK Initializing...",
|
|
1821
|
+
"background: #10b981; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
1822
|
+
{ endpoint: this.config.apiUrl }
|
|
1823
|
+
);
|
|
1824
|
+
}
|
|
1758
1825
|
await this.log("info", "SDK Initializing", {
|
|
1759
1826
|
apiUrl: this.config.apiUrl,
|
|
1760
1827
|
hasSDKKey: !!this.config.sdkKey,
|
|
@@ -1781,20 +1848,43 @@ var ProduckSDK = class {
|
|
|
1781
1848
|
headers
|
|
1782
1849
|
});
|
|
1783
1850
|
if (!response.ok) {
|
|
1784
|
-
|
|
1851
|
+
let errorDetail = "";
|
|
1852
|
+
try {
|
|
1853
|
+
errorDetail = await response.text();
|
|
1854
|
+
} catch {
|
|
1855
|
+
errorDetail = "Could not read response body";
|
|
1856
|
+
}
|
|
1857
|
+
console.error(
|
|
1858
|
+
"%c\u274C Produck SDK: Failed to create session",
|
|
1859
|
+
"background: #ef4444; color: #fff; padding: 2px 6px; border-radius: 3px;"
|
|
1860
|
+
);
|
|
1861
|
+
console.error(`Status: ${response.status} ${response.statusText}`);
|
|
1862
|
+
console.error(`Endpoint: ${endpoint}`);
|
|
1863
|
+
console.error(`Response: ${errorDetail}`);
|
|
1864
|
+
if (response.status === 404) {
|
|
1865
|
+
console.error(
|
|
1866
|
+
`
|
|
1867
|
+
\u{1F4A1} Tip: A 404 error usually means the apiUrl is wrong.
|
|
1868
|
+
Current apiUrl: ${this.config.apiUrl}
|
|
1869
|
+
Make sure your backend is running and the URL is correct.`
|
|
1870
|
+
);
|
|
1871
|
+
}
|
|
1872
|
+
await this.log("error", "Failed to create session", { status: response.status, errorDetail });
|
|
1785
1873
|
throw new Error(`Failed to create session: ${response.status}`);
|
|
1786
1874
|
}
|
|
1787
1875
|
const session = await response.json();
|
|
1788
1876
|
this.sessionToken = session.session_token;
|
|
1789
1877
|
this.isReady = true;
|
|
1790
1878
|
await this.log("info", "SDK initialized successfully", { hasSessionToken: !!this.sessionToken });
|
|
1791
|
-
|
|
1879
|
+
const recordingEnabled = this.config.recording?.enabled !== false;
|
|
1880
|
+
if (recordingEnabled) {
|
|
1792
1881
|
await this.initRecording();
|
|
1793
1882
|
}
|
|
1794
1883
|
if (this.config.proactive?.enabled) {
|
|
1795
1884
|
this.initProactive();
|
|
1796
1885
|
}
|
|
1797
|
-
|
|
1886
|
+
const userFlowsEnabled = this.config.userFlows?.enabled !== false;
|
|
1887
|
+
if (userFlowsEnabled) {
|
|
1798
1888
|
await this.initUserFlowTracking();
|
|
1799
1889
|
}
|
|
1800
1890
|
this.emit("ready", { sessionToken: this.sessionToken });
|
|
@@ -1802,7 +1892,27 @@ var ProduckSDK = class {
|
|
|
1802
1892
|
await this.sendInitialMessage();
|
|
1803
1893
|
}
|
|
1804
1894
|
} catch (error) {
|
|
1805
|
-
|
|
1895
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1896
|
+
const isNetworkError = errorMessage.includes("fetch") || errorMessage.includes("network") || errorMessage.includes("Failed to fetch") || errorMessage.includes("NetworkError");
|
|
1897
|
+
console.error(
|
|
1898
|
+
"%c\u274C Produck SDK initialization failed",
|
|
1899
|
+
"background: #ef4444; color: #fff; padding: 4px 8px; font-weight: bold;"
|
|
1900
|
+
);
|
|
1901
|
+
console.error(`Error: ${errorMessage}`);
|
|
1902
|
+
console.error(`API URL: ${this.config.apiUrl}`);
|
|
1903
|
+
if (isNetworkError) {
|
|
1904
|
+
console.error(
|
|
1905
|
+
`
|
|
1906
|
+
\u{1F4A1} This looks like a network error. Common causes:
|
|
1907
|
+
1. The apiUrl is incorrect or the backend is not running
|
|
1908
|
+
2. CORS is blocking the request
|
|
1909
|
+
3. The backend server is unreachable
|
|
1910
|
+
|
|
1911
|
+
Current apiUrl: ${this.config.apiUrl}
|
|
1912
|
+
Check the Network tab in DevTools for more details.`
|
|
1913
|
+
);
|
|
1914
|
+
}
|
|
1915
|
+
await this.log("error", "SDK initialization failed", { error: errorMessage });
|
|
1806
1916
|
this.emit("error", error);
|
|
1807
1917
|
throw error;
|
|
1808
1918
|
}
|
|
@@ -2486,6 +2596,15 @@ var ProduckSDK = class {
|
|
|
2486
2596
|
*/
|
|
2487
2597
|
async initUserFlowTracking() {
|
|
2488
2598
|
try {
|
|
2599
|
+
console.log(
|
|
2600
|
+
"%c\u{1F4CA} Initializing User Flow Tracking",
|
|
2601
|
+
"background: #8b5cf6; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
2602
|
+
{
|
|
2603
|
+
config: this.config.userFlows,
|
|
2604
|
+
apiUrl: this.config.apiUrl,
|
|
2605
|
+
sdkKey: this.config.sdkKey ? "present" : "missing"
|
|
2606
|
+
}
|
|
2607
|
+
);
|
|
2489
2608
|
this.userFlowTracker = new UserFlowTracker(this.config.userFlows);
|
|
2490
2609
|
this.userFlowTracker.initialize(
|
|
2491
2610
|
this.sessionToken,
|
|
@@ -2495,12 +2614,27 @@ var ProduckSDK = class {
|
|
|
2495
2614
|
const recordingSessionId = this.recorder?.getSessionId?.() || null;
|
|
2496
2615
|
const sessionId = await this.userFlowTracker.start(recordingSessionId);
|
|
2497
2616
|
if (sessionId) {
|
|
2617
|
+
console.log(
|
|
2618
|
+
"%c\u2705 User Flow Tracking Started",
|
|
2619
|
+
"background: #10b981; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
2620
|
+
{ flowSessionId: sessionId, linkedRecordingSession: recordingSessionId }
|
|
2621
|
+
);
|
|
2498
2622
|
await this.log("info", "User flow tracking started", {
|
|
2499
2623
|
flowSessionId: sessionId,
|
|
2500
2624
|
linkedRecordingSession: recordingSessionId
|
|
2501
2625
|
});
|
|
2626
|
+
} else {
|
|
2627
|
+
console.warn(
|
|
2628
|
+
"%c\u26A0\uFE0F User Flow Tracking: No session ID returned",
|
|
2629
|
+
"background: #f59e0b; color: #000; padding: 2px 6px; border-radius: 3px;"
|
|
2630
|
+
);
|
|
2502
2631
|
}
|
|
2503
2632
|
} catch (error) {
|
|
2633
|
+
console.error(
|
|
2634
|
+
"%c\u274C User Flow Tracking Failed",
|
|
2635
|
+
"background: #ef4444; color: #fff; padding: 2px 6px; border-radius: 3px;",
|
|
2636
|
+
error
|
|
2637
|
+
);
|
|
2504
2638
|
await this.log("warn", "Failed to initialize user flow tracking", {
|
|
2505
2639
|
error: error instanceof Error ? error.message : String(error)
|
|
2506
2640
|
});
|