@base44-preview/sdk 0.8.57-pr.359.f19a932 → 0.8.57-pr.361.dda0ab9
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.
|
@@ -202,15 +202,15 @@ export interface AgentsModuleConfig {
|
|
|
202
202
|
*/
|
|
203
203
|
export interface AgentsModule {
|
|
204
204
|
/**
|
|
205
|
-
* Gets
|
|
205
|
+
* Gets the current user's conversations with all agents in the app.
|
|
206
206
|
*
|
|
207
|
-
* Retrieves all
|
|
207
|
+
* Retrieves every conversation the current user started, across all agents. Conversations that other users started aren't included. Use {@linkcode listConversations | listConversations()} to filter which conversations are returned, apply sorting, or paginate results. Use {@linkcode getConversation | getConversation()} to retrieve a specific conversation by ID.
|
|
208
208
|
*
|
|
209
209
|
* @returns Promise resolving to an array of conversations.
|
|
210
210
|
*
|
|
211
211
|
* @example
|
|
212
212
|
* ```typescript
|
|
213
|
-
* // Get
|
|
213
|
+
* // Get the current user's conversations
|
|
214
214
|
* const conversations = await base44.agents.getConversations();
|
|
215
215
|
* console.log(`Total conversations: ${conversations.length}`);
|
|
216
216
|
* ```
|
|
@@ -223,7 +223,7 @@ export interface AgentsModule {
|
|
|
223
223
|
* Gets a specific conversation by ID.
|
|
224
224
|
*
|
|
225
225
|
* Retrieves a single conversation using its unique identifier. To retrieve
|
|
226
|
-
* all conversations, use {@linkcode getConversations | getConversations()}. To filter, sort, or paginate conversations, use {@linkcode listConversations | listConversations()}.
|
|
226
|
+
* all of the current user's conversations, use {@linkcode getConversations | getConversations()}. To filter, sort, or paginate conversations, use {@linkcode listConversations | listConversations()}.
|
|
227
227
|
*
|
|
228
228
|
* This function returns the complete stored conversation including full tool call results, even for large responses.
|
|
229
229
|
*
|
|
@@ -246,7 +246,7 @@ export interface AgentsModule {
|
|
|
246
246
|
/**
|
|
247
247
|
* Lists conversations with filtering, sorting, and pagination.
|
|
248
248
|
*
|
|
249
|
-
* Provides querying capabilities including filtering by fields, sorting, pagination, and field selection. For cases where you need all conversations without filtering, use {@linkcode getConversations | getConversations()}. To retrieve a specific conversation by ID, use {@linkcode getConversation | getConversation()}.
|
|
249
|
+
* Provides querying capabilities including filtering by fields, sorting, pagination, and field selection. For cases where you need all of the current user's conversations without filtering, use {@linkcode getConversations | getConversations()}. To retrieve a specific conversation by ID, use {@linkcode getConversation | getConversation()}.
|
|
250
250
|
*
|
|
251
251
|
* @param filterParams - Filter parameters for querying conversations.
|
|
252
252
|
* @returns Promise resolving to an array of filtered conversations.
|
|
@@ -6,6 +6,9 @@ export declare const ANALYTICS_INITIALIZATION_EVENT_NAME = "__initialization_eve
|
|
|
6
6
|
export declare const ANALYTICS_SESSION_DURATION_EVENT_NAME = "__session_duration_event__";
|
|
7
7
|
export declare const ANALYTICS_CONFIG_ENABLE_URL_PARAM_KEY = "analytics-enable";
|
|
8
8
|
export declare const ANALYTICS_SESSION_ID_LOCAL_STORAGE_KEY = "base44_analytics_session_id";
|
|
9
|
+
export declare const ANALYTICS_MODE_META_NAME = "base44-analytics";
|
|
10
|
+
/** Whether analytics may run and store the session id on this page. */
|
|
11
|
+
export declare function isAnalyticsAllowed(): boolean;
|
|
9
12
|
export interface AnalyticsModuleArgs {
|
|
10
13
|
axiosClient: AxiosInstance;
|
|
11
14
|
serverUrl: string;
|
|
@@ -5,6 +5,25 @@ export const ANALYTICS_INITIALIZATION_EVENT_NAME = "__initialization_event__";
|
|
|
5
5
|
export const ANALYTICS_SESSION_DURATION_EVENT_NAME = "__session_duration_event__";
|
|
6
6
|
export const ANALYTICS_CONFIG_ENABLE_URL_PARAM_KEY = "analytics-enable";
|
|
7
7
|
export const ANALYTICS_SESSION_ID_LOCAL_STORAGE_KEY = "base44_analytics_session_id";
|
|
8
|
+
// Set by the Base44 server from the app owner's choice: "off" never tracks,
|
|
9
|
+
// "consent" waits for the page's Google Consent Mode `analytics_storage` grant,
|
|
10
|
+
// "on" tracks until that consent is denied. Absent: track as before.
|
|
11
|
+
export const ANALYTICS_MODE_META_NAME = "base44-analytics";
|
|
12
|
+
function readAnalyticsMode() {
|
|
13
|
+
var _a;
|
|
14
|
+
if (typeof document === "undefined")
|
|
15
|
+
return null;
|
|
16
|
+
try {
|
|
17
|
+
const content = (_a = document
|
|
18
|
+
.querySelector(`meta[name="${ANALYTICS_MODE_META_NAME}"]`)) === null || _a === void 0 ? void 0 : _a.getAttribute("content");
|
|
19
|
+
return content === "off" || content === "consent" || content === "on"
|
|
20
|
+
? content
|
|
21
|
+
: null;
|
|
22
|
+
}
|
|
23
|
+
catch (_b) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
8
27
|
const defaultConfiguration = {
|
|
9
28
|
// default to enabled //
|
|
10
29
|
enabled: true,
|
|
@@ -33,15 +52,80 @@ const analyticsSharedState = getSharedInstance(ANALYTICS_SHARED_STATE_NAME, () =
|
|
|
33
52
|
...getAnalyticsConfigFromUrlParams(),
|
|
34
53
|
},
|
|
35
54
|
}));
|
|
55
|
+
///////////////////////////////////////////////
|
|
56
|
+
//// visitor consent ////
|
|
57
|
+
///////////////////////////////////////////////
|
|
58
|
+
// Its own shared instance: an older SDK copy on the page may own "analytics".
|
|
59
|
+
const consentSharedState = getSharedInstance("analytics-consent", () => {
|
|
60
|
+
const analyticsMode = readAnalyticsMode();
|
|
61
|
+
return {
|
|
62
|
+
analyticsMode,
|
|
63
|
+
// Whether the visitor may be tracked and the session id stored.
|
|
64
|
+
consentGranted: analyticsMode !== "consent",
|
|
65
|
+
isWatchingConsent: false,
|
|
66
|
+
listeners: [],
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
/** Whether analytics may run and store the session id on this page. */
|
|
70
|
+
export function isAnalyticsAllowed() {
|
|
71
|
+
const { analyticsMode, consentGranted } = consentSharedState;
|
|
72
|
+
return analyticsMode !== "off" && consentGranted;
|
|
73
|
+
}
|
|
74
|
+
function setConsentGranted(granted) {
|
|
75
|
+
var _a;
|
|
76
|
+
if (consentSharedState.consentGranted === granted)
|
|
77
|
+
return;
|
|
78
|
+
consentSharedState.consentGranted = granted;
|
|
79
|
+
if (!granted) {
|
|
80
|
+
try {
|
|
81
|
+
const sessionId = localStorage.getItem(ANALYTICS_SESSION_ID_LOCAL_STORAGE_KEY);
|
|
82
|
+
// Same id for the rest of the tab, so an anonymous agent chat keeps its owner.
|
|
83
|
+
if (sessionId)
|
|
84
|
+
(_a = analyticsSharedState.fallbackSessionId) !== null && _a !== void 0 ? _a : (analyticsSharedState.fallbackSessionId = sessionId);
|
|
85
|
+
localStorage.removeItem(ANALYTICS_SESSION_ID_LOCAL_STORAGE_KEY);
|
|
86
|
+
}
|
|
87
|
+
catch (_b) {
|
|
88
|
+
// storage unavailable: nothing was stored
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const listener of [...consentSharedState.listeners]) {
|
|
92
|
+
listener(granted);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Subscribes once to the consent listener Base44 injects next to the meta tag.
|
|
96
|
+
// Without it (e.g. a CSP blocked the inline script) "consent" never grants.
|
|
97
|
+
function watchAnalyticsConsent() {
|
|
98
|
+
const state = consentSharedState;
|
|
99
|
+
if (state.isWatchingConsent)
|
|
100
|
+
return;
|
|
101
|
+
state.isWatchingConsent = true;
|
|
102
|
+
if (state.analyticsMode !== "consent" && state.analyticsMode !== "on")
|
|
103
|
+
return;
|
|
104
|
+
const b44Consent = typeof window !== "undefined" ? window.__b44Consent : undefined;
|
|
105
|
+
b44Consent === null || b44Consent === void 0 ? void 0 : b44Consent.on("analytics_storage", () => setConsentGranted(true), () => setConsentGranted(false));
|
|
106
|
+
}
|
|
107
|
+
function onConsentChange(listener) {
|
|
108
|
+
consentSharedState.listeners.push(listener);
|
|
109
|
+
return () => {
|
|
110
|
+
const listeners = consentSharedState.listeners;
|
|
111
|
+
const index = listeners.indexOf(listener);
|
|
112
|
+
if (index >= 0)
|
|
113
|
+
listeners.splice(index, 1);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
36
116
|
export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthModule, enabled, }) => {
|
|
37
117
|
var _a;
|
|
38
118
|
// prevent overflow of events //
|
|
39
119
|
const { maxQueueSize, throttleTime, batchSize } = analyticsSharedState.config;
|
|
120
|
+
watchAnalyticsConsent();
|
|
40
121
|
// Disable analytics on React Native. It defines `window` but not `document`,
|
|
41
122
|
// so the per-callsite `typeof window` guards below aren't enough to keep it
|
|
42
123
|
// from touching `document` (e.g. `document.referrer` on init). Node/SSR is
|
|
43
124
|
// still handled by those `window` guards, so this doesn't affect it.
|
|
44
|
-
if (!enabled ||
|
|
125
|
+
if (!enabled ||
|
|
126
|
+
!((_a = analyticsSharedState.config) === null || _a === void 0 ? void 0 : _a.enabled) ||
|
|
127
|
+
isReactNative ||
|
|
128
|
+
consentSharedState.analyticsMode === "off") {
|
|
45
129
|
return {
|
|
46
130
|
track: () => { },
|
|
47
131
|
cleanup: () => { },
|
|
@@ -70,7 +154,8 @@ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthM
|
|
|
70
154
|
}
|
|
71
155
|
};
|
|
72
156
|
const flush = async (eventsData, options = {}) => {
|
|
73
|
-
|
|
157
|
+
// Consent may have been withdrawn while these events waited.
|
|
158
|
+
if (eventsData.length === 0 || !isAnalyticsAllowed())
|
|
74
159
|
return;
|
|
75
160
|
const sessionContext_ = await getSessionContext(userAuthModule);
|
|
76
161
|
const events = eventsData.map(transformEventDataToApiRequestData(sessionContext_));
|
|
@@ -90,7 +175,8 @@ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthM
|
|
|
90
175
|
});
|
|
91
176
|
};
|
|
92
177
|
const track = (params) => {
|
|
93
|
-
if (
|
|
178
|
+
if (!isAnalyticsAllowed() ||
|
|
179
|
+
analyticsSharedState.requestsQueue.length >= maxQueueSize) {
|
|
94
180
|
return;
|
|
95
181
|
}
|
|
96
182
|
const intrinsicData = getEventIntrinsicData();
|
|
@@ -126,23 +212,45 @@ export const createAnalyticsModule = ({ axiosClient, serverUrl, appId, userAuthM
|
|
|
126
212
|
onDocVisible();
|
|
127
213
|
}
|
|
128
214
|
};
|
|
129
|
-
|
|
215
|
+
let isStarted = false;
|
|
216
|
+
const start = () => {
|
|
217
|
+
if (isStarted)
|
|
218
|
+
return;
|
|
219
|
+
isStarted = true;
|
|
220
|
+
// start the flusing process ///
|
|
221
|
+
startProcessing();
|
|
222
|
+
// start the heart beat processor //
|
|
223
|
+
clearHeartBeatProcessor = startHeartBeatProcessor(track);
|
|
224
|
+
// track the referrer event //
|
|
225
|
+
trackInitializationEvent(track);
|
|
226
|
+
// start the visibility change listener //
|
|
227
|
+
if (typeof window !== "undefined") {
|
|
228
|
+
window.addEventListener("visibilitychange", onVisibilityChange);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
const stop = () => {
|
|
232
|
+
isStarted = false;
|
|
130
233
|
stopAnalyticsProcessor();
|
|
131
234
|
clearHeartBeatProcessor === null || clearHeartBeatProcessor === void 0 ? void 0 : clearHeartBeatProcessor();
|
|
132
235
|
if (typeof window !== "undefined") {
|
|
133
236
|
window.removeEventListener("visibilitychange", onVisibilityChange);
|
|
134
237
|
}
|
|
135
238
|
};
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
239
|
+
const stopWatchingConsent = onConsentChange((granted) => {
|
|
240
|
+
if (granted) {
|
|
241
|
+
start();
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
stop();
|
|
245
|
+
analyticsSharedState.requestsQueue.splice(0);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
const cleanup = () => {
|
|
249
|
+
stopWatchingConsent();
|
|
250
|
+
stop();
|
|
251
|
+
};
|
|
252
|
+
if (isAnalyticsAllowed())
|
|
253
|
+
start();
|
|
146
254
|
return {
|
|
147
255
|
track,
|
|
148
256
|
cleanup,
|
|
@@ -338,19 +446,21 @@ function getFallbackSessionId() {
|
|
|
338
446
|
return ((_a = analyticsSharedState.fallbackSessionId) !== null && _a !== void 0 ? _a : (analyticsSharedState.fallbackSessionId = generateUuid()));
|
|
339
447
|
}
|
|
340
448
|
export function getAnalyticsSessionId() {
|
|
341
|
-
|
|
449
|
+
var _a;
|
|
450
|
+
if (typeof window === "undefined" || !isAnalyticsAllowed()) {
|
|
342
451
|
return getFallbackSessionId();
|
|
343
452
|
}
|
|
344
453
|
try {
|
|
345
454
|
const sessionId = localStorage.getItem(ANALYTICS_SESSION_ID_LOCAL_STORAGE_KEY);
|
|
346
455
|
if (!sessionId) {
|
|
347
|
-
|
|
456
|
+
// An id used before consent was granted carries on, so it is stored now.
|
|
457
|
+
const newSessionId = (_a = analyticsSharedState.fallbackSessionId) !== null && _a !== void 0 ? _a : generateUuid();
|
|
348
458
|
localStorage.setItem(ANALYTICS_SESSION_ID_LOCAL_STORAGE_KEY, newSessionId);
|
|
349
459
|
return newSessionId;
|
|
350
460
|
}
|
|
351
461
|
return sessionId;
|
|
352
462
|
}
|
|
353
|
-
catch (
|
|
463
|
+
catch (_b) {
|
|
354
464
|
return getFallbackSessionId();
|
|
355
465
|
}
|
|
356
466
|
}
|
package/dist/modules/app-logs.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isAnalyticsAllowed } from "./analytics.js";
|
|
1
2
|
/**
|
|
2
3
|
* Creates the app logs module for the Base44 SDK.
|
|
3
4
|
*
|
|
@@ -11,6 +12,9 @@ export function createAppLogsModule(axios, appId) {
|
|
|
11
12
|
return {
|
|
12
13
|
// Log user activity in the app
|
|
13
14
|
async logUserInApp(pageName) {
|
|
15
|
+
// A page visit feeds App Analytics, so it follows the same consent.
|
|
16
|
+
if (!isAnalyticsAllowed())
|
|
17
|
+
return;
|
|
14
18
|
await axios.post(`${baseURL}/log-user-in-app/${pageName}`);
|
|
15
19
|
},
|
|
16
20
|
// Fetch app logs with optional parameters
|