@olenbetong/appframe-core 2.10.2 → 2.11.1

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.
Files changed (46) hide show
  1. package/dist/esm/af.common.js +131 -146
  2. package/dist/esm/af.common.legacy.js +137 -152
  3. package/dist/esm/af.common.legacy.min.js +1 -1
  4. package/dist/esm/af.common.legacy.min.js.map +4 -4
  5. package/dist/esm/af.common.min.js +2 -2
  6. package/dist/esm/af.common.min.js.map +4 -4
  7. package/dist/iife/af.common.js +131 -146
  8. package/dist/iife/af.common.legacy.js +137 -152
  9. package/dist/iife/af.common.legacy.min.js +1 -1
  10. package/dist/iife/af.common.legacy.min.js.map +4 -4
  11. package/dist/iife/af.common.min.js +2 -2
  12. package/dist/iife/af.common.min.js.map +4 -4
  13. package/es/SessionHandler.js +1 -3
  14. package/es/UserSession.js +33 -29
  15. package/es/date.d.ts +16 -0
  16. package/es/date.js +15 -3
  17. package/es/date.test.d.ts +1 -0
  18. package/es/date.test.js +23 -0
  19. package/es/downloadRequest.js +6 -11
  20. package/es/errorHandler.d.ts +1 -0
  21. package/es/errorHandler.js +5 -21
  22. package/es/expose.d.ts +1 -1
  23. package/es/expose.test.d.ts +10 -0
  24. package/es/expose.test.js +36 -0
  25. package/es/getUserImage.test.d.ts +1 -0
  26. package/es/getUserImage.test.js +30 -0
  27. package/es/index.d.ts +1 -1
  28. package/es/index.js +2 -2
  29. package/es/invariant.test.d.ts +1 -0
  30. package/es/invariant.test.js +19 -0
  31. package/es/localStorage.js +1 -3
  32. package/es/parseFunc.js +1 -1
  33. package/es/parseFunc.test.d.ts +1 -0
  34. package/es/parseFunc.test.js +14 -0
  35. package/package.json +5 -3
  36. package/src/date.test.ts +27 -0
  37. package/src/date.ts +22 -3
  38. package/src/downloadRequest.ts +6 -12
  39. package/src/errorHandler.ts +6 -21
  40. package/src/expose.test.ts +59 -0
  41. package/src/expose.ts +1 -1
  42. package/src/getUserImage.test.ts +50 -0
  43. package/src/index.ts +1 -1
  44. package/src/invariant.test.ts +23 -0
  45. package/src/parseFunc.test.ts +17 -0
  46. package/src/parseFunc.ts +1 -1
@@ -110,27 +110,125 @@ var UserSession = class extends SessionHandler {
110
110
  }
111
111
  };
112
112
 
113
+ // src/log.ts
114
+ async function logActivity(activity, parameters = {}, timeElapsed = 0) {
115
+ try {
116
+ let response = await fetch("/api/logging/log-activity", {
117
+ method: "POST",
118
+ body: JSON.stringify({
119
+ article: af.article.id,
120
+ timeElapsed,
121
+ action: activity,
122
+ parameters: {
123
+ ...parameters,
124
+ _session: getSessionData()
125
+ }
126
+ }),
127
+ headers: { "Content-Type": "application/json", Accept: "application/json" }
128
+ });
129
+ if (!response.ok) {
130
+ if (response.headers.get("Content-Type")?.includes("application/json")) {
131
+ let data = await response.json();
132
+ console.error(data.error);
133
+ } else {
134
+ console.error(`${response.status} ${response.statusText}`);
135
+ }
136
+ }
137
+ } catch (error) {
138
+ }
139
+ }
140
+ function startActivity(activity, startParameters = {}) {
141
+ let start = performance.now();
142
+ return (endParameters = {}) => logActivity(activity, { ...startParameters, ...endParameters }, performance.now() - start);
143
+ }
144
+ async function time(callback) {
145
+ let start = performance.now();
146
+ let returnValue = await callback();
147
+ return [returnValue, performance.now() - start];
148
+ }
149
+ async function logError(error) {
150
+ try {
151
+ if (!error)
152
+ return;
153
+ let data = typeof error === "string" ? { error } : typeof error === "object" ? "message" in error ? {
154
+ error: error.message,
155
+ stack: error.stack ?? null
156
+ } : { error: error.toString() } : { error: "Unspecified error" };
157
+ console.error(error);
158
+ let result = await fetch("/data/Logger/LogError", {
159
+ method: "POST",
160
+ body: JSON.stringify(data),
161
+ headers: {
162
+ "Content-Type": "application/json; charset=utf-8"
163
+ }
164
+ });
165
+ if (result.ok) {
166
+ return await result.json();
167
+ }
168
+ console.error(Error("Failed to log error"));
169
+ } catch {
170
+ }
171
+ }
172
+ function getSessionId() {
173
+ return crypto.randomUUID?.();
174
+ }
175
+ var sessionStart = Date.now();
176
+ var sessionId = getSessionId();
177
+ var deviceId = "";
178
+ var browserSessionId = "";
179
+ if ("document" in window) {
180
+ let startSession = () => logActivity("AfSessionInit", {
181
+ "appframe-core": af.common.version,
182
+ "appframe-data": af.data?.version,
183
+ "app-version": af.article.version
184
+ });
185
+ document.addEventListener("DOMContentLoaded", () => {
186
+ deviceId = localStorage.getItem("_afDeviceId");
187
+ browserSessionId = sessionStorage.getItem("_afSessionId");
188
+ if (!deviceId) {
189
+ deviceId = getSessionId();
190
+ localStorage.setItem("_afDeviceId", deviceId);
191
+ }
192
+ if (!browserSessionId) {
193
+ browserSessionId = sessionId;
194
+ sessionStorage.setItem("_afSessionId", browserSessionId);
195
+ }
196
+ startSession();
197
+ });
198
+ document.addEventListener("visibilitychange", function logData() {
199
+ if (document.visibilityState === "hidden") {
200
+ navigator.sendBeacon(
201
+ "/api/logging/log-activity",
202
+ JSON.stringify({
203
+ article: af.article.id,
204
+ action: "AfSessionEnd",
205
+ parameters: {
206
+ _session: getSessionData()
207
+ }
208
+ })
209
+ );
210
+ } else {
211
+ startSession();
212
+ }
213
+ });
214
+ }
215
+ function getSessionData() {
216
+ return {
217
+ browserSessionId,
218
+ sessionStart,
219
+ sessionLength: Date.now() - sessionStart,
220
+ sessionId,
221
+ deviceId
222
+ };
223
+ }
224
+
113
225
  // src/errorHandler.ts
114
226
  if (true) {
115
227
  window.window?.addEventListener("error", (event) => {
116
- try {
117
- const data = {
118
- error: event.error?.message ?? event.message ?? null,
119
- file: event.filename,
120
- line: event.lineno ?? 0,
121
- column: event.colno ?? 0,
122
- stack: event.error?.stack ?? null
123
- };
124
- fetch("/data/Logger/LogError", {
125
- body: JSON.stringify(data),
126
- headers: {
127
- Accept: "application/json",
128
- "Content-Type": "application/json; charset=utf-8",
129
- "X-Requested-With": "XMLHttpRequest"
130
- },
131
- method: "POST"
132
- });
133
- } catch (ex) {
228
+ if (typeof event === "object" && "error" in event) {
229
+ logError(event.error);
230
+ } else if (typeof event === "object" && "message" in event) {
231
+ logError(event);
134
232
  }
135
233
  });
136
234
  }
@@ -176,13 +274,16 @@ var localStorage_default = new LocalStorage();
176
274
  function toLocalISODate(date) {
177
275
  return date ? toLocalISODateTime(date).substring(0, 10) : null;
178
276
  }
179
- function pad(num) {
180
- return String(num).padStart(2, "0");
277
+ function pad(num, digits = 2) {
278
+ return String(num).padStart(digits, "0");
181
279
  }
182
280
  function toLocalISODateTime(date) {
183
281
  return date ? `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(
184
282
  date.getMinutes()
185
- )}:${pad(date.getSeconds())}.${pad(date.getMilliseconds())}` : null;
283
+ )}:${pad(date.getSeconds())}.${pad(date.getMilliseconds(), 3)}` : null;
284
+ }
285
+ function toLocalDateTime(date) {
286
+ return date ? date.toISOString().substring(0, 16) : "";
186
287
  }
187
288
 
188
289
  // src/downloadBlob.ts
@@ -218,13 +319,8 @@ function invariant(condition, message) {
218
319
 
219
320
  // src/downloadRequest.ts
220
321
  async function downloadRequest(request, { fileName, signal, onProgress }) {
221
- function reportProgress(progress) {
222
- if (typeof onProgress === "function") {
223
- onProgress({ ...progress });
224
- }
225
- }
226
322
  let bytesReceived = 0;
227
- reportProgress({ status: "requested" });
323
+ onProgress?.({ status: "requested" });
228
324
  try {
229
325
  let response = await fetch(request);
230
326
  if (!response.ok || !response.body) {
@@ -245,7 +341,7 @@ async function downloadRequest(request, { fileName, signal, onProgress }) {
245
341
  return;
246
342
  }
247
343
  bytesReceived += read.value.length;
248
- reportProgress({ bytesReceived, status: "downloading" });
344
+ onProgress?.({ bytesReceived, status: "downloading" });
249
345
  controller.enqueue(read.value);
250
346
  return pump();
251
347
  });
@@ -257,14 +353,14 @@ async function downloadRequest(request, { fileName, signal, onProgress }) {
257
353
  } catch (error) {
258
354
  }
259
355
  const blob = await response.blob();
260
- reportProgress({ bytesReceived, status: "downloaded" });
356
+ onProgress?.({ bytesReceived, status: "downloaded" });
261
357
  await downloadBlob(blob, fileName);
262
- reportProgress({ bytesReceived, status: "completed" });
358
+ onProgress?.({ bytesReceived, status: "completed" });
263
359
  } catch (err) {
264
360
  if (signal?.aborted) {
265
- reportProgress({ status: "cancelled" });
361
+ onProgress?.({ status: "cancelled" });
266
362
  } else {
267
- reportProgress({ error: err.message, status: "error" });
363
+ onProgress?.({ error: err.message, status: "error" });
268
364
  }
269
365
  }
270
366
  }
@@ -279,7 +375,7 @@ var funcRegex = /^function(?:\s+([a-zA-Z$_][a-zA-Z0-9$_]*))?\s*\(((?:(?:\s*[a-zA
279
375
  function parseFunc(func) {
280
376
  var match = func.toString().match(funcRegex);
281
377
  invariant(match, "Unable to parse function!");
282
- return { name: match[1], args: match[2].split(","), body: match[3] };
378
+ return { name: func.name ?? match[1], args: match[2].split(",").map((a) => a.trim()), body: match[3] };
283
379
  }
284
380
 
285
381
  // src/Namespace.ts
@@ -417,118 +513,6 @@ function localize(stringParts, ...args) {
417
513
  return localized;
418
514
  }
419
515
 
420
- // src/log.ts
421
- async function logActivity(activity, parameters = {}, timeElapsed = 0) {
422
- try {
423
- let response = await fetch("/api/logging/log-activity", {
424
- method: "POST",
425
- body: JSON.stringify({
426
- article: af.article.id,
427
- timeElapsed,
428
- action: activity,
429
- parameters: {
430
- ...parameters,
431
- _session: getSessionData()
432
- }
433
- }),
434
- headers: { "Content-Type": "application/json", Accept: "application/json" }
435
- });
436
- if (!response.ok) {
437
- if (response.headers.get("Content-Type")?.includes("application/json")) {
438
- let data = await response.json();
439
- console.error(data.error);
440
- } else {
441
- console.error(`${response.status} ${response.statusText}`);
442
- }
443
- }
444
- } catch (error) {
445
- }
446
- }
447
- function startActivity(activity, startParameters = {}) {
448
- let start = performance.now();
449
- return (endParameters = {}) => logActivity(activity, { ...startParameters, ...endParameters }, performance.now() - start);
450
- }
451
- async function time(callback) {
452
- let start = performance.now();
453
- let returnValue = await callback();
454
- return [returnValue, performance.now() - start];
455
- }
456
- async function logError(error) {
457
- try {
458
- if (!error)
459
- return;
460
- let data = typeof error === "string" ? { error } : typeof error === "object" ? "message" in error ? {
461
- error: error.message,
462
- stack: error.stack ?? null
463
- } : { error: error.toString() } : { error: "Unspecified error" };
464
- console.error(error);
465
- let result = await fetch("/data/Logger/LogError", {
466
- method: "POST",
467
- body: JSON.stringify(data),
468
- headers: {
469
- "Content-Type": "application/json; charset=utf-8"
470
- }
471
- });
472
- if (result.ok) {
473
- return await result.json();
474
- }
475
- console.error(Error("Failed to log error"));
476
- } catch {
477
- }
478
- }
479
- function getSessionId() {
480
- return crypto.randomUUID?.();
481
- }
482
- var sessionStart = Date.now();
483
- var sessionId = getSessionId();
484
- var deviceId = "";
485
- var browserSessionId = "";
486
- if ("document" in window) {
487
- let startSession = () => logActivity("AfSessionInit", {
488
- "appframe-core": af.common.version,
489
- "appframe-data": af.data?.version,
490
- "app-version": af.article.version
491
- });
492
- document.addEventListener("DOMContentLoaded", () => {
493
- deviceId = localStorage.getItem("_afDeviceId");
494
- browserSessionId = sessionStorage.getItem("_afSessionId");
495
- if (!deviceId) {
496
- deviceId = getSessionId();
497
- localStorage.setItem("_afDeviceId", deviceId);
498
- }
499
- if (!browserSessionId) {
500
- browserSessionId = sessionId;
501
- sessionStorage.setItem("_afSessionId", browserSessionId);
502
- }
503
- startSession();
504
- });
505
- document.addEventListener("visibilitychange", function logData() {
506
- if (document.visibilityState === "hidden") {
507
- navigator.sendBeacon(
508
- "/api/logging/log-activity",
509
- JSON.stringify({
510
- article: af.article.id,
511
- action: "AfSessionEnd",
512
- parameters: {
513
- _session: getSessionData()
514
- }
515
- })
516
- );
517
- } else {
518
- startSession();
519
- }
520
- });
521
- }
522
- function getSessionData() {
523
- return {
524
- browserSessionId,
525
- sessionStart,
526
- sessionLength: Date.now() - sessionStart,
527
- sessionId,
528
- deviceId
529
- };
530
- }
531
-
532
516
  // src/settings.ts
533
517
  function getKey(article) {
534
518
  const articleKey = article || af.article.id;
@@ -670,7 +654,7 @@ async function alert(prompt, options = {}) {
670
654
  }
671
655
 
672
656
  // src/index.ts
673
- var version = "2.10.2";
657
+ var version = "2.11.1";
674
658
  export {
675
659
  ConfirmButtons,
676
660
  SessionHandler,
@@ -695,6 +679,7 @@ export {
695
679
  saveSettings,
696
680
  startActivity,
697
681
  time,
682
+ toLocalDateTime,
698
683
  toLocalISODate,
699
684
  toLocalISODateTime,
700
685
  version,