aprog 1.1.3 → 1.2.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/README.md CHANGED
@@ -33,8 +33,8 @@ import Unauthorized from "./pages/Unauthorized";
33
33
 
34
34
  const routes = [
35
35
  {
36
- path: "/categories",
37
- component: Categories,
36
+ path: "/",
37
+ component: NamePage,
38
38
  },
39
39
  {
40
40
  path: "/access/denied",
@@ -48,8 +48,8 @@ const routes = [
48
48
 
49
49
  document.addEventListener("DOMContentLoaded", async function() {
50
50
  // router
51
- const body = document.body;
52
- await router({ routes, body, "Page Not Found" });
51
+ const main = document.getElementById('main');
52
+ await router({ routes, main, "Page Not Found" });
53
53
  });
54
54
 
55
55
  ```
@@ -114,20 +114,33 @@ dd(int, array, boolean);
114
114
 
115
115
  ```
116
116
 
117
+ Приклад використання gemini:
118
+
119
+ у файл __.env__ потрібно додати api-ключ *__VITE_GEMINI_KEY=you_api_gemini_key__*
120
+ ```shell
121
+
122
+ const message = await gemini("Розкажи жарт про програміста!");
123
+ console.log(message);
124
+
125
+ ```
126
+
117
127
  Загальний список методів:
118
128
 
119
129
  - *dump(...args), dd(...args)*
120
130
  - *redirect(url, { newTab: bool, replace: bool })*
121
131
  - *encrypt(str), decrypt(encryptedStr)*
122
132
 
123
-
124
133
  - *div, span, button, a, img, meta, label, input, select, option, options, form, hr, textarea, table, thead, tbody, tr, th, td, pre*
125
134
  - *_get, GUID, apState, cookie, date, pause, apFetch, chars, elementToObject, copyText, scrollToTop, scrollToBottom, firstKey, checkArrays, ucfirst, deepEqual, nodeListToObject*
126
135
  - *isEmpty, isNull, isFloat, isNumeric, isObject, isArray, isNumber, isString, isPromise, isNull, isFloat, isNumeric, isObject*
127
136
 
137
+ - *router({ routes, main, "Page Not Found" })*
138
+
139
+ - *gemini(message)*
128
140
 
129
141
  ### Info
130
142
 
143
+ - Додано безплатний чат із Gemini
131
144
  - З часом будуть додаватися можливості створення додаткових інструментів
132
145
 
133
146
 
package/index.js CHANGED
@@ -7,4 +7,5 @@ export {
7
7
  export { dump, dd } from './src/debugger.js';
8
8
  export { redirect } from './src/redirect.js';
9
9
  export { router, navigateTo } from './src/router.js';
10
- export { encrypt, decrypt } from './src/shifrator.js';
10
+ export { encrypt, decrypt } from './src/shifrator.js';
11
+ export { gemini } from './src/OpenAI.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aprog",
3
- "version": "1.1.3",
3
+ "version": "1.2.1",
4
4
  "description": "Допоміжна бібліотека js",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/OpenAI.js ADDED
@@ -0,0 +1,50 @@
1
+ import {loadCacheDB, saveCacheDB} from "./indexDB.js";
2
+
3
+ const empty = (variable) => {
4
+ if (typeof variable === 'object' && !Array.isArray(variable) && Object.keys(variable).length === 0) {
5
+ return true;
6
+ }
7
+ return !variable;
8
+ }
9
+
10
+ const loadCache = async () => {
11
+ const data = await loadCacheDB();
12
+ return !empty(data) ? data : { messages: {} };
13
+ }
14
+
15
+ export const gemini = async (content) => {
16
+ let cache = await loadCache();
17
+
18
+ if (cache.messages[content]) {
19
+ console.warn("Відповідь знайдена у кеші");
20
+ return cache.messages[content];
21
+ }
22
+
23
+ const apiKey = import.meta.env.VITE_GEMINI_KEY;
24
+ const url = `https://generativelanguage.googleapis.com/v1/models/gemini-2.0-flash:generateContent?key=${apiKey}`;
25
+
26
+ const response = await fetch(url, {
27
+ method: "POST",
28
+ headers: { "Content-Type": "application/json" },
29
+ body: JSON.stringify({
30
+ contents: [{ parts: [{ text: content }] }]
31
+ })
32
+ });
33
+
34
+ const data = await response.json();
35
+ if (data.error) {
36
+ console.error(data.error.message)
37
+ cache.messages[content] = data.error.message;
38
+ await saveCacheDB(cache);
39
+ return data.error.message;
40
+ }
41
+
42
+ const answer = data.candidates?.[0]?.content?.parts?.[0]?.text || null;
43
+
44
+ if (answer) {
45
+ cache.messages[content] = answer;
46
+ await saveCacheDB(cache);
47
+ }
48
+
49
+ return answer;
50
+ };
package/src/indexDB.js ADDED
@@ -0,0 +1,55 @@
1
+ const dbName = "aprogDB";
2
+ const storeName = "cacheGemini";
3
+
4
+ /**
5
+ * Відкриття або створення IndexedDB
6
+ */
7
+ const openDB = () => {
8
+ return new Promise((resolve, reject) => {
9
+ const request = indexedDB.open(dbName, 1);
10
+
11
+ request.onupgradeneeded = (event) => {
12
+ const db = event.target.result;
13
+ if (!db.objectStoreNames.contains(storeName)) {
14
+ db.createObjectStore(storeName, { keyPath: "id" });
15
+ }
16
+ };
17
+
18
+ request.onsuccess = () => resolve(request.result);
19
+ request.onerror = () => reject(request.error);
20
+ });
21
+ };
22
+
23
+ /**
24
+ * Завантаження кешу (аналог sessionStorage.getItem)
25
+ */
26
+ const loadCacheDB = async (name = "gemini") => {
27
+ const db = await openDB();
28
+ return new Promise((resolve, reject) => {
29
+ const tx = db.transaction(storeName, "readonly");
30
+ const store = tx.objectStore(storeName);
31
+ const request = store.get(name);
32
+
33
+ request.onsuccess = () => resolve(request.result ? request.result.data : {});
34
+ request.onerror = () => reject(request.error);
35
+ });
36
+ };
37
+
38
+ /**
39
+ * Збереження кешу (аналог sessionStorage.setItem)
40
+ */
41
+ const saveCacheDB = async (cache, id = "gemini") => {
42
+ try {
43
+ const resolvedCache = await Promise.resolve(cache);
44
+ const db = await openDB();
45
+ const tx = db.transaction(storeName, "readwrite");
46
+ const store = tx.objectStore(storeName);
47
+
48
+ await store.put({ id: id, data: resolvedCache });
49
+ await tx.complete;
50
+ } catch (err) {
51
+ console.error("Failed to save cache:", err);
52
+ }
53
+ };
54
+
55
+ export {loadCacheDB, saveCacheDB};