aprog 2.1.3 → 2.1.4
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/README.md +2 -0
- package/index.js +2 -1
- package/package.json +5 -2
- package/src/general.js +7 -7
- package/src/pages.js +61 -0
- package/src/storage.js +99 -19
package/README.md
CHANGED
|
@@ -173,6 +173,8 @@ node node_modules/aprog/publish.js --force
|
|
|
173
173
|
|
|
174
174
|
- *saveItem("id", data), loadItem("id")*
|
|
175
175
|
|
|
176
|
+
- *uniquePage({key: "default", callbackTrue: () => {"empty"}, callbackFalse: () => {"empty"}, timer: "default")*
|
|
177
|
+
|
|
176
178
|
### Info
|
|
177
179
|
|
|
178
180
|
- Додано безплатний чат із `Gemini`
|
package/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export { router, navigateTo, navi } from './src/router.js';
|
|
|
11
11
|
export { encrypt, decrypt } from './src/shifrator.js';
|
|
12
12
|
export { gemini } from './src/OpenAI.js';
|
|
13
13
|
export { mathInput, autoPPI } from './src/math.js';
|
|
14
|
-
export { cookie, storage, cacheKey, downloadFile } from './src/storage.js';
|
|
14
|
+
export { cookie, storage, session, cacheKey, downloadFile } from './src/storage.js';
|
|
15
15
|
export { paginate, parseData, __paginate, __counter } from './src/paginate.js';
|
|
16
16
|
export { saveItem, loadItem, setSecretKey } from './src/secretStorage.js';
|
|
17
17
|
export {
|
|
@@ -21,3 +21,4 @@ export {
|
|
|
21
21
|
repeatHTMLElementPrototype
|
|
22
22
|
} from './src/html.js';
|
|
23
23
|
export { prism } from "./src/prism.js";
|
|
24
|
+
export { uniquePage } from "./src/pages.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aprog",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
4
4
|
"description": "Допоміжна JavaScript-бібліотека для проєктів",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"exports": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
|
-
"url": "https://github.com/uaproger/aprog-js.git"
|
|
20
|
+
"url": "git+https://github.com/uaproger/aprog-js.git"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"aprog",
|
|
@@ -44,5 +44,8 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"crypto-js": "^4.2.0"
|
|
47
|
+
},
|
|
48
|
+
"bin": {
|
|
49
|
+
"aprog": "bin/cli.js"
|
|
47
50
|
}
|
|
48
51
|
}
|
package/src/general.js
CHANGED
|
@@ -98,7 +98,7 @@ const isHtmlElement = (value) => {
|
|
|
98
98
|
});
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
export const isEmpty = (variable) => {
|
|
101
|
+
export const isEmpty = (variable): boolean => {
|
|
102
102
|
if (variable === undefined || variable === null) {
|
|
103
103
|
return true;
|
|
104
104
|
}
|
|
@@ -1261,7 +1261,7 @@ export const td = (attributes = {}) => {
|
|
|
1261
1261
|
return td;
|
|
1262
1262
|
};
|
|
1263
1263
|
|
|
1264
|
-
export const img = (attributes = {}) => {
|
|
1264
|
+
export const img = (attributes: Record<string, any> = {}): HTMLImageElement => {
|
|
1265
1265
|
let img = document.createElement("img");
|
|
1266
1266
|
img.alt = "img...";
|
|
1267
1267
|
if (attributes) {
|
|
@@ -1350,21 +1350,21 @@ export const apFetch = async (url, params = {}) => {
|
|
|
1350
1350
|
return [data, error, isLoading];
|
|
1351
1351
|
};
|
|
1352
1352
|
|
|
1353
|
-
export const scrollToTop = () => {
|
|
1353
|
+
export const scrollToTop = (): void => {
|
|
1354
1354
|
window.scrollTo({
|
|
1355
1355
|
top: 0,
|
|
1356
1356
|
behavior: "smooth",
|
|
1357
1357
|
});
|
|
1358
1358
|
};
|
|
1359
1359
|
|
|
1360
|
-
export const scrollToBottom = () => {
|
|
1360
|
+
export const scrollToBottom = (): void => {
|
|
1361
1361
|
window.scrollTo({
|
|
1362
1362
|
top: document.documentElement.scrollHeight,
|
|
1363
1363
|
behavior: "smooth",
|
|
1364
1364
|
});
|
|
1365
1365
|
};
|
|
1366
1366
|
|
|
1367
|
-
export const _get = (name, defaulting = null) => {
|
|
1367
|
+
export const _get = (name: string, defaulting: any = null): string|number|null => {
|
|
1368
1368
|
let url = new URL(window.location.href);
|
|
1369
1369
|
let searchParams = new URLSearchParams(url.search);
|
|
1370
1370
|
if (searchParams.has(name)) {
|
|
@@ -1375,7 +1375,7 @@ export const _get = (name, defaulting = null) => {
|
|
|
1375
1375
|
return defaulting;
|
|
1376
1376
|
};
|
|
1377
1377
|
|
|
1378
|
-
export const _getAll = () => {
|
|
1378
|
+
export const _getAll = (): Record<string, string> => {
|
|
1379
1379
|
let url = new URL(window.location.href);
|
|
1380
1380
|
let searchParams = new URLSearchParams(url.search);
|
|
1381
1381
|
let params = {};
|
|
@@ -1385,7 +1385,7 @@ export const _getAll = () => {
|
|
|
1385
1385
|
return params;
|
|
1386
1386
|
};
|
|
1387
1387
|
|
|
1388
|
-
export const GUID = () => {
|
|
1388
|
+
export const GUID = (): string => {
|
|
1389
1389
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (char) {
|
|
1390
1390
|
const random = Math.random() * 16 | 0;
|
|
1391
1391
|
const value = char === 'x' ? random : (random & 0x3 | 0x8);
|
package/src/pages.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {GUID} from "./general.js";
|
|
2
|
+
import {session, storage} from "./storage.js";
|
|
3
|
+
|
|
4
|
+
export const uniquePage = ({
|
|
5
|
+
key = "guid",
|
|
6
|
+
callbackTrue = () => {},
|
|
7
|
+
callbackFalse = () => {},
|
|
8
|
+
timer = 60000 // таймер 1 хвилина
|
|
9
|
+
}): void => {
|
|
10
|
+
const setSession = () => {
|
|
11
|
+
// Якщо немає ні сесії, ні лс, то додаємо
|
|
12
|
+
if (!session.check(key) && !storage.check(key)) {
|
|
13
|
+
const id = GUID();
|
|
14
|
+
session.set(key, id);
|
|
15
|
+
storage.set(key, id);
|
|
16
|
+
callbackTrue();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
setTimeout(() => {
|
|
20
|
+
console.log("session: ", session.get(key));
|
|
21
|
+
console.log("local: ", storage.get(key));
|
|
22
|
+
}, 0);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const checkingLocalStorage = () => {
|
|
26
|
+
// Якщо сесія є, але немає лс, то в лс додаємо значення сесії
|
|
27
|
+
if (session.check(key) && !storage.check(key)) {
|
|
28
|
+
storage.set(key, session.get(key));
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Запускаємо сесію
|
|
33
|
+
setSession();
|
|
34
|
+
// Запускаємо першу перевірку на наявність лс
|
|
35
|
+
checkingLocalStorage();
|
|
36
|
+
|
|
37
|
+
// Встановлюємо перевірку наявності лс за таймером
|
|
38
|
+
setInterval(() => {
|
|
39
|
+
checkingLocalStorage();
|
|
40
|
+
}, timer);
|
|
41
|
+
|
|
42
|
+
// Якщо немає сесії, або сесія не дорівнює лс, то виконуємо callback
|
|
43
|
+
if (!session.check(key) || session.get(key) !== storage.get(key)) {
|
|
44
|
+
const isTimer = setInterval(() => {
|
|
45
|
+
if (!storage.check(key)) {
|
|
46
|
+
// Попередня вкладка була закрита — перехоплюємо керування
|
|
47
|
+
setSession();
|
|
48
|
+
clearInterval(isTimer); // зупиняємо таймер
|
|
49
|
+
}
|
|
50
|
+
}, timer);
|
|
51
|
+
|
|
52
|
+
setTimeout(callbackFalse, 0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Якщо вкладка оновлюється, або закривається і сесія дорівнює лс, видаляємо лс
|
|
56
|
+
window.addEventListener('beforeunload', () => {
|
|
57
|
+
if (session.get(key) === storage.get(key)) {
|
|
58
|
+
storage.delete(key);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
};
|
package/src/storage.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {GUID} from "./general.js";
|
|
1
|
+
import {GUID, isEmpty} from "./general.js";
|
|
2
2
|
|
|
3
3
|
export const cookie = {
|
|
4
4
|
/**
|
|
5
|
-
* Отримати значення cookie за ім'ям
|
|
5
|
+
* --- Отримати значення cookie за ім'ям ---
|
|
6
6
|
* @param {string} name
|
|
7
|
-
* @param defaulting
|
|
7
|
+
* @param {any|null} defaulting
|
|
8
8
|
* @returns {string|null}
|
|
9
9
|
*/
|
|
10
|
-
get(name, defaulting = null) {
|
|
10
|
+
get(name: string, defaulting: any = null): string|null {
|
|
11
11
|
const cookies = document.cookie.split('; ');
|
|
12
12
|
for (let cookie of cookies) {
|
|
13
13
|
const index = cookie.indexOf('=');
|
|
@@ -24,10 +24,10 @@ export const cookie = {
|
|
|
24
24
|
},
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Отримати всі cookie
|
|
27
|
+
* --- Отримати всі cookie ---
|
|
28
28
|
* @return {{}}
|
|
29
29
|
*/
|
|
30
|
-
getAll() {
|
|
30
|
+
getAll(): Record<string, string> {
|
|
31
31
|
return document.cookie.split('; ').reduce((acc, cookie) => {
|
|
32
32
|
const [key, ...val] = cookie.split('=');
|
|
33
33
|
acc[key] = decodeURIComponent(val.join('='));
|
|
@@ -36,12 +36,12 @@ export const cookie = {
|
|
|
36
36
|
},
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* Встановити cookie
|
|
39
|
+
* --- Встановити cookie ---
|
|
40
40
|
* @param {string} name
|
|
41
41
|
* @param {string} value
|
|
42
42
|
* @param {number} days
|
|
43
43
|
*/
|
|
44
|
-
set(name, value, days = 7) {
|
|
44
|
+
set(name: string, value: string, days: number = 7): void {
|
|
45
45
|
let expires = "";
|
|
46
46
|
if (days) {
|
|
47
47
|
const date = new Date();
|
|
@@ -56,32 +56,112 @@ export const cookie = {
|
|
|
56
56
|
* Видалити cookie
|
|
57
57
|
* @param {string} name
|
|
58
58
|
*/
|
|
59
|
-
delete(name) {
|
|
59
|
+
delete(name: string): void {
|
|
60
60
|
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* --- Локальне сховище ---
|
|
66
|
+
*/
|
|
64
67
|
export const storage = {
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
/**
|
|
69
|
+
* --- Отримати елемент зі сховища ---
|
|
70
|
+
* @param {string} key
|
|
71
|
+
* @param {any|null} defaulting
|
|
72
|
+
* @return {any|null}
|
|
73
|
+
*/
|
|
74
|
+
get(key: string, defaulting: any = null): any|null {
|
|
75
|
+
try {
|
|
76
|
+
const item = localStorage.getItem(key);
|
|
77
|
+
return item ? JSON.parse(item) : defaulting;
|
|
78
|
+
} catch (e) {
|
|
79
|
+
console.warn(`storage.get: invalid JSON for key "${key}"`, e);
|
|
80
|
+
return defaulting;
|
|
81
|
+
}
|
|
67
82
|
},
|
|
68
83
|
|
|
69
|
-
|
|
84
|
+
/**
|
|
85
|
+
* --- Додати елемент у сховище ---
|
|
86
|
+
* @param {string} key
|
|
87
|
+
* @param {any} data
|
|
88
|
+
*/
|
|
89
|
+
set(key: string, data: any): void {
|
|
70
90
|
localStorage.setItem(key, JSON.stringify(data));
|
|
71
91
|
},
|
|
72
92
|
|
|
73
|
-
|
|
93
|
+
/**
|
|
94
|
+
* --- Перевірка на існування елемента у сховищі ---
|
|
95
|
+
* @param {string} key
|
|
96
|
+
* @return {boolean}
|
|
97
|
+
*/
|
|
98
|
+
check(key: string): boolean {
|
|
99
|
+
return !isEmpty(localStorage.getItem(key));
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* --- Видалити елемент зі сховища ---
|
|
104
|
+
* @param {string} key
|
|
105
|
+
*/
|
|
106
|
+
delete(key: string): void {
|
|
74
107
|
localStorage.removeItem(key);
|
|
75
108
|
}
|
|
76
109
|
};
|
|
77
110
|
|
|
111
|
+
/**
|
|
112
|
+
* --- Сховище сесії ---
|
|
113
|
+
*/
|
|
114
|
+
export const session = {
|
|
115
|
+
/**
|
|
116
|
+
* --- Отримати елемент з сесії ---
|
|
117
|
+
* @param {string} key
|
|
118
|
+
* @param {any|null} defaulting
|
|
119
|
+
* @return {any|null}
|
|
120
|
+
*/
|
|
121
|
+
get(key: string, defaulting: any = null): any|null {
|
|
122
|
+
try {
|
|
123
|
+
const item = sessionStorage.getItem(key);
|
|
124
|
+
return item ? JSON.parse(item) : defaulting;
|
|
125
|
+
} catch (e) {
|
|
126
|
+
console.warn(`session.get: invalid JSON for key "${key}"`, e);
|
|
127
|
+
return defaulting;
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* --- Додати елемент до сесії ---
|
|
133
|
+
* @param {string} key
|
|
134
|
+
* @param {any} data
|
|
135
|
+
*/
|
|
136
|
+
set(key: string, data: any): void {
|
|
137
|
+
sessionStorage.setItem(key, JSON.stringify(data));
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* --- Перевірка на існування елемента у сесії ---
|
|
142
|
+
* @param {string} key
|
|
143
|
+
* @return {boolean}
|
|
144
|
+
*/
|
|
145
|
+
check(key: string): boolean {
|
|
146
|
+
return !isEmpty(sessionStorage.getItem(key));
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* --- Видалити елемент з сесії ---
|
|
151
|
+
* @param {string} key
|
|
152
|
+
*/
|
|
153
|
+
delete(key: string): void {
|
|
154
|
+
sessionStorage.removeItem(key);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
78
158
|
/**
|
|
79
159
|
* --- Ключ для кешу на бекенді ---
|
|
80
160
|
* @param {string} name - вводиться як абревіатура у верхньому регістрі
|
|
81
161
|
* @param {boolean} create
|
|
82
162
|
* @return {string}
|
|
83
163
|
*/
|
|
84
|
-
export const cacheKey = (name, create = true) => {
|
|
164
|
+
export const cacheKey = (name: string, create: boolean = true): string => {
|
|
85
165
|
let key = cookie.get(`_key_${name}`);
|
|
86
166
|
|
|
87
167
|
if (!create) return key;
|
|
@@ -90,19 +170,19 @@ export const cacheKey = (name, create = true) => {
|
|
|
90
170
|
key = GUID();
|
|
91
171
|
cookie.set(`_key_${name}`, key, 30);
|
|
92
172
|
} else {
|
|
93
|
-
console.warn("
|
|
173
|
+
console.warn("load by cache");
|
|
94
174
|
}
|
|
95
175
|
return key;
|
|
96
|
-
}
|
|
176
|
+
};
|
|
97
177
|
|
|
98
178
|
/**
|
|
99
179
|
* --- Функція завантаження файлів ---
|
|
100
180
|
* @param content
|
|
101
181
|
* @param filename
|
|
102
182
|
*/
|
|
103
|
-
export const downloadFile = (content, filename = "file.txt") => {
|
|
183
|
+
export const downloadFile = (content: string | Blob | Uint8Array, filename = "file.txt"): void => {
|
|
104
184
|
/** Мапа: розширення -> MIME-тип */
|
|
105
|
-
const extensionToMime = {
|
|
185
|
+
const extensionToMime: Record<string, string> = {
|
|
106
186
|
"txt": "text/plain",
|
|
107
187
|
"json": "application/json",
|
|
108
188
|
"xml": "text/xml",
|
|
@@ -137,4 +217,4 @@ export const downloadFile = (content, filename = "file.txt") => {
|
|
|
137
217
|
URL.revokeObjectURL(url);
|
|
138
218
|
|
|
139
219
|
console.log(`✅ Файл "${filename}" (${mimeType}) завантажено.`);
|
|
140
|
-
}
|
|
220
|
+
};
|