@txstate-mws/sveltekit-utils 1.2.7 → 1.2.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/api.d.ts CHANGED
@@ -47,6 +47,7 @@ export declare class APIBase {
47
47
  body?: any;
48
48
  query?: APIBaseQueryPayload;
49
49
  inlineValidation?: boolean;
50
+ keepalive?: boolean;
50
51
  }): Promise<ReturnType>;
51
52
  uploadWithProgress(path: string, formData: FormData, progress: APIBaseProgressFn): Promise<any>;
52
53
  get<ReturnType = any>(path: string, query?: APIBaseQueryPayload): Promise<ReturnType>;
@@ -109,8 +110,11 @@ export declare class APIBase {
109
110
  */
110
111
  progress?: APIBaseProgressFn;
111
112
  }): Promise<ReturnType>;
113
+ protected lastAnalyticsSent: number;
112
114
  protected analyticsQueue: InteractionEvent[];
115
+ protected analyticsTimer: ReturnType<typeof setTimeout> | undefined;
113
116
  recordInteraction(evt: Optional<InteractionEvent, 'screen'>): void;
117
+ sendBatchedAnalytics(): Promise<void>;
114
118
  /**
115
119
  * Due to the mechanics of sveltekit, this function cannot be fully automatic and must
116
120
  * be called in your global +layout.svelte
package/dist/api.js CHANGED
@@ -76,6 +76,13 @@ export class APIBase {
76
76
  else {
77
77
  this.token ??= sessionStorage.getItem('token') ?? undefined;
78
78
  }
79
+ if (typeof document !== 'undefined') {
80
+ document.addEventListener("visibilitychange", () => {
81
+ if (document.visibilityState === "hidden") {
82
+ this.sendBatchedAnalytics().catch(console.error);
83
+ }
84
+ });
85
+ }
79
86
  this.ready();
80
87
  }
81
88
  stringifyQuery(query) {
@@ -95,6 +102,7 @@ export class APIBase {
95
102
  try {
96
103
  const resp = await this.fetch(this.apiBase + path + this.stringifyQuery(opts?.query), {
97
104
  method,
105
+ keepalive: opts?.keepalive,
98
106
  headers: {
99
107
  Authorization: `Bearer ${this.token ?? ''}`,
100
108
  Accept: 'application/json',
@@ -261,16 +269,28 @@ export class APIBase {
261
269
  }
262
270
  return gqlresponse.data;
263
271
  }
272
+ lastAnalyticsSent = new Date().getTime();
264
273
  analyticsQueue = [];
274
+ analyticsTimer;
265
275
  recordInteraction(evt) {
266
276
  evt.screen ??= get(page).route.id;
267
277
  this.analyticsQueue.push(evt);
268
- setTimeout(() => {
269
- const events = [...this.analyticsQueue];
270
- this.analyticsQueue.length = 0;
271
- if (events.length)
272
- this.post('/analytics', events).catch((e) => console.error(e));
273
- }, 2000);
278
+ clearTimeout(this.analyticsTimer);
279
+ // If the last analytics was sent more than 2 seconds ago, send immediately
280
+ if (new Date().getTime() - this.lastAnalyticsSent > 2000)
281
+ this.sendBatchedAnalytics().catch(console.error);
282
+ // Otherwise, collect more analytics for up to 2 seconds
283
+ else
284
+ this.analyticsTimer = setTimeout(() => this.sendBatchedAnalytics().catch(console.error), 2000);
285
+ }
286
+ async sendBatchedAnalytics() {
287
+ const events = [...this.analyticsQueue];
288
+ this.analyticsQueue.length = 0;
289
+ if (events.length) {
290
+ this.lastAnalyticsSent = new Date().getTime();
291
+ // keepalive true means the request will not be cancelled even if the user navigates away
292
+ await this.request('/analytics', 'POST', { body: events, keepalive: true });
293
+ }
274
294
  }
275
295
  /**
276
296
  * Due to the mechanics of sveltekit, this function cannot be fully automatic and must
@@ -33,7 +33,7 @@ export const unifiedAuth = {
33
33
  if (isBlank(api.token))
34
34
  return;
35
35
  const authRedirect = new URL(api.authRedirect);
36
- authRedirect.pathname = '/logout';
36
+ authRedirect.pathname = [...authRedirect.pathname.split('/').slice(0, -1), 'logout'].join('/');
37
37
  authRedirect.searchParams.set('unifiedJwt', api.token);
38
38
  api.token = undefined;
39
39
  sessionStorage.removeItem('token');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@txstate-mws/sveltekit-utils",
3
- "version": "1.2.7",
3
+ "version": "1.2.9",
4
4
  "description": "Shared library for code that is specifically tied to sveltekit in addition to svelte.",
5
5
  "type": "module",
6
6
  "exports": {