@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.
- package/dist/esm/af.common.js +131 -146
- package/dist/esm/af.common.legacy.js +137 -152
- package/dist/esm/af.common.legacy.min.js +1 -1
- package/dist/esm/af.common.legacy.min.js.map +4 -4
- package/dist/esm/af.common.min.js +2 -2
- package/dist/esm/af.common.min.js.map +4 -4
- package/dist/iife/af.common.js +131 -146
- package/dist/iife/af.common.legacy.js +137 -152
- package/dist/iife/af.common.legacy.min.js +1 -1
- package/dist/iife/af.common.legacy.min.js.map +4 -4
- package/dist/iife/af.common.min.js +2 -2
- package/dist/iife/af.common.min.js.map +4 -4
- package/es/SessionHandler.js +1 -3
- package/es/UserSession.js +33 -29
- package/es/date.d.ts +16 -0
- package/es/date.js +15 -3
- package/es/date.test.d.ts +1 -0
- package/es/date.test.js +23 -0
- package/es/downloadRequest.js +6 -11
- package/es/errorHandler.d.ts +1 -0
- package/es/errorHandler.js +5 -21
- package/es/expose.d.ts +1 -1
- package/es/expose.test.d.ts +10 -0
- package/es/expose.test.js +36 -0
- package/es/getUserImage.test.d.ts +1 -0
- package/es/getUserImage.test.js +30 -0
- package/es/index.d.ts +1 -1
- package/es/index.js +2 -2
- package/es/invariant.test.d.ts +1 -0
- package/es/invariant.test.js +19 -0
- package/es/localStorage.js +1 -3
- package/es/parseFunc.js +1 -1
- package/es/parseFunc.test.d.ts +1 -0
- package/es/parseFunc.test.js +14 -0
- package/package.json +5 -3
- package/src/date.test.ts +27 -0
- package/src/date.ts +22 -3
- package/src/downloadRequest.ts +6 -12
- package/src/errorHandler.ts +6 -21
- package/src/expose.test.ts +59 -0
- package/src/expose.ts +1 -1
- package/src/getUserImage.test.ts +50 -0
- package/src/index.ts +1 -1
- package/src/invariant.test.ts +23 -0
- package/src/parseFunc.test.ts +17 -0
- package/src/parseFunc.ts +1 -1
package/dist/esm/af.common.js
CHANGED
|
@@ -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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
356
|
+
onProgress?.({ bytesReceived, status: "downloaded" });
|
|
261
357
|
await downloadBlob(blob, fileName);
|
|
262
|
-
|
|
358
|
+
onProgress?.({ bytesReceived, status: "completed" });
|
|
263
359
|
} catch (err) {
|
|
264
360
|
if (signal?.aborted) {
|
|
265
|
-
|
|
361
|
+
onProgress?.({ status: "cancelled" });
|
|
266
362
|
} else {
|
|
267
|
-
|
|
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.
|
|
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,
|