beanbagdb-components 0.2.6 → 0.2.8
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/main.js +9065 -8655
- package/dist/main.js.map +1 -1
- package/dist/main.umd.cjs +47 -36
- package/dist/main.umd.cjs.map +1 -1
- package/package.json +2 -2
- package/dist/app.js +0 -131
- package/dist/app.style.css +0 -51
- package/dist/data.html +0 -1086
- package/dist/doc.html +0 -61
- package/dist/index.html +0 -28
- package/dist/local_cache.js +0 -210
- package/dist/settings.html +0 -39
- package/dist/test.html +0 -34
package/dist/doc.html
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en" data-bs-theme="dark">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<!-- <script type="module" src="../dist/main.js"></script> -->
|
|
7
|
-
|
|
8
|
-
<title>BBDB-Database</title>
|
|
9
|
-
<link
|
|
10
|
-
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
|
|
11
|
-
rel="stylesheet"
|
|
12
|
-
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
|
|
13
|
-
crossorigin="anonymous"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
<link rel="stylesheet" href="app.style.css" />
|
|
17
|
-
<script src="app.js"></script>
|
|
18
|
-
|
|
19
|
-
<script type="module">
|
|
20
|
-
import { BBDB } from "../dist/main.js";
|
|
21
|
-
let DB;
|
|
22
|
-
let DB_cache;
|
|
23
|
-
|
|
24
|
-
document.addEventListener("DOMContentLoaded", async () => {
|
|
25
|
-
try {
|
|
26
|
-
const db_details = await initPage("doc");
|
|
27
|
-
console.log(db_details);
|
|
28
|
-
DB = await BBDB(db_details.dbObj);
|
|
29
|
-
await DB.ready();
|
|
30
|
-
|
|
31
|
-
const doc_element = document.createElement("bbdb-doc");
|
|
32
|
-
doc_element.BBDB = DB;
|
|
33
|
-
doc_element.new_doc = db_details.new_record
|
|
34
|
-
if(db_details.single_record){
|
|
35
|
-
doc_element.search_criteria = db_details.parsedDocCriteria
|
|
36
|
-
}
|
|
37
|
-
console.log(doc_element);
|
|
38
|
-
doc_element.addEventListener("action",handle_bbdb_action);
|
|
39
|
-
|
|
40
|
-
document.getElementById("pane_doc_editor").appendChild(doc_element);
|
|
41
|
-
} catch (error) {
|
|
42
|
-
showMessage("error", error.message);
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
</script>
|
|
46
|
-
</head>
|
|
47
|
-
<body>
|
|
48
|
-
<div class="container-fluid">
|
|
49
|
-
<div class="row">
|
|
50
|
-
<div class="col-12">
|
|
51
|
-
<div id="pane_doc_editor"></div>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
<script
|
|
56
|
-
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
|
|
57
|
-
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
|
|
58
|
-
crossorigin="anonymous"
|
|
59
|
-
></script>
|
|
60
|
-
</body>
|
|
61
|
-
</html>
|
package/dist/index.html
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en" data-bs-theme="dark">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<!-- <script type="module" src="../dist/main.js"></script> -->
|
|
7
|
-
|
|
8
|
-
<title>BBDB Home </title>
|
|
9
|
-
<link
|
|
10
|
-
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
|
|
11
|
-
rel="stylesheet"
|
|
12
|
-
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
|
|
13
|
-
crossorigin="anonymous"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
<link rel="stylesheet" href="app.style.css" />
|
|
17
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/split.js/1.6.0/split.min.js"></script>
|
|
18
|
-
<script src="app.js"></script>
|
|
19
|
-
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
|
|
20
|
-
|
|
21
|
-
</head>
|
|
22
|
-
<body>
|
|
23
|
-
<div id="app" class="d-flex h-100 overflow-hidden">
|
|
24
|
-
|
|
25
|
-
</div>
|
|
26
|
-
|
|
27
|
-
</body>
|
|
28
|
-
</html>
|
package/dist/local_cache.js
DELETED
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CacheManager provides instant cache-first loading with automatic background refresh.
|
|
3
|
-
*
|
|
4
|
-
*/
|
|
5
|
-
class CacheManager {
|
|
6
|
-
/**
|
|
7
|
-
* @param {number} [defaultTTL=1800000] - Default TTL in ms (30 minutes)
|
|
8
|
-
*/
|
|
9
|
-
constructor(defaultTTL = 1000 * 60 * 30) {
|
|
10
|
-
/** @private */
|
|
11
|
-
this.defaultTTL = defaultTTL;
|
|
12
|
-
/** @private */
|
|
13
|
-
this.db = null;
|
|
14
|
-
/** @private */
|
|
15
|
-
this.dbName = 'appCache';
|
|
16
|
-
/** @private */
|
|
17
|
-
this.version = 1;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Initialize IndexedDB connection (called automatically)
|
|
22
|
-
* @private
|
|
23
|
-
* @returns {Promise<IDBDatabase>}
|
|
24
|
-
*/
|
|
25
|
-
async initDB() {
|
|
26
|
-
if (this.db) return this.db;
|
|
27
|
-
return new Promise((resolve, reject) => {
|
|
28
|
-
const req = indexedDB.open(this.dbName, this.version);
|
|
29
|
-
req.onupgradeneeded = () => {
|
|
30
|
-
const db = req.result;
|
|
31
|
-
if (!db.objectStoreNames.contains('kv')) {
|
|
32
|
-
db.createObjectStore('kv', { keyPath: 'id' });
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
req.onsuccess = () => {
|
|
36
|
-
this.db = req.result;
|
|
37
|
-
resolve(this.db);
|
|
38
|
-
};
|
|
39
|
-
req.onerror = () => reject(req.error);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* MAGIC METHOD: Load data with instant cache-first + background refresh
|
|
45
|
-
* 1. Returns cached data IMMEDIATELY (never blocks UI)
|
|
46
|
-
* 2. If stale/missing, fetches fresh data in BACKGROUND
|
|
47
|
-
* 3. Silently updates cache + UI when done
|
|
48
|
-
*
|
|
49
|
-
* @param {string} resourceKey - Unique key ('tags', 'users', 'stats')
|
|
50
|
-
* @param {Function} fetchFn - Function that returns Promise<JSON>
|
|
51
|
-
* @param {number} [ttlMs] - Override default TTL
|
|
52
|
-
* @returns {Promise<any|null>} Cached data (or null if none)
|
|
53
|
-
*/
|
|
54
|
-
async load(resourceKey, fetchFn, ttlMs = null) {
|
|
55
|
-
const ttl = ttlMs || this.defaultTTL;
|
|
56
|
-
let cached = await this.getWithRaw(resourceKey);
|
|
57
|
-
|
|
58
|
-
// IMMEDIATE RETURN - never block!
|
|
59
|
-
if (cached && Date.now() - cached.timestamp <= ttl) {
|
|
60
|
-
return cached.value;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// BACKGROUND refresh (non-blocking)
|
|
64
|
-
this.refresh(resourceKey, fetchFn, ttl).catch(console.error);
|
|
65
|
-
return cached?.value || null;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Force refresh: fetch fresh data + update cache
|
|
70
|
-
* @param {string} resourceKey
|
|
71
|
-
* @param {Function} fetchFn
|
|
72
|
-
* @param {number} [ttlMs]
|
|
73
|
-
* @returns {Promise<any>}
|
|
74
|
-
*/
|
|
75
|
-
async refresh(resourceKey, fetchFn, ttlMs = null) {
|
|
76
|
-
const ttl = ttlMs || this.defaultTTL;
|
|
77
|
-
try {
|
|
78
|
-
const data = await fetchFn();
|
|
79
|
-
await this.set(resourceKey, data, ttl);
|
|
80
|
-
return data;
|
|
81
|
-
} catch (err) {
|
|
82
|
-
console.error(`Refresh failed for ${resourceKey}:`, err);
|
|
83
|
-
throw err;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Manual set with TTL
|
|
89
|
-
* @param {string} resourceKey
|
|
90
|
-
* @param {any} value - Any JSON-serializable value
|
|
91
|
-
* @param {number} [ttlMs]
|
|
92
|
-
*/
|
|
93
|
-
async set(resourceKey, value, ttlMs = null) {
|
|
94
|
-
const ttl = ttlMs || this.defaultTTL;
|
|
95
|
-
await this.initDB();
|
|
96
|
-
|
|
97
|
-
const record = {
|
|
98
|
-
id: resourceKey,
|
|
99
|
-
value,
|
|
100
|
-
timestamp: Date.now(),
|
|
101
|
-
ttl
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
return new Promise((resolve, reject) => {
|
|
105
|
-
const tx = this.db.transaction('kv', 'readwrite');
|
|
106
|
-
const store = tx.objectStore('kv');
|
|
107
|
-
const req = store.put(record);
|
|
108
|
-
req.onsuccess = () => resolve(value);
|
|
109
|
-
req.onerror = () => reject(req.error);
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Get with automatic TTL validation + stale eviction
|
|
115
|
-
* @param {string} resourceKey
|
|
116
|
-
* @returns {Promise<any|null>}
|
|
117
|
-
*/
|
|
118
|
-
async get(resourceKey) {
|
|
119
|
-
const data = await this.getWithRaw(resourceKey);
|
|
120
|
-
if (!data) return null;
|
|
121
|
-
|
|
122
|
-
if (Date.now() - data.timestamp > data.ttl) {
|
|
123
|
-
await this.delete(resourceKey); // Auto-evict stale
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
return data.value;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Raw get (no TTL check) - for internal use
|
|
131
|
-
* @private
|
|
132
|
-
*/
|
|
133
|
-
async getWithRaw(resourceKey) {
|
|
134
|
-
await this.initDB();
|
|
135
|
-
return new Promise((resolve, reject) => {
|
|
136
|
-
const tx = this.db.transaction('kv', 'readonly');
|
|
137
|
-
const store = tx.objectStore('kv');
|
|
138
|
-
const req = store.get(resourceKey);
|
|
139
|
-
req.onsuccess = () => resolve(req.result);
|
|
140
|
-
req.onerror = () => reject(req.error);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/** Check if key exists and is fresh */
|
|
145
|
-
async has(resourceKey) {
|
|
146
|
-
return !!(await this.get(resourceKey));
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/** Delete specific key */
|
|
150
|
-
async delete(resourceKey) {
|
|
151
|
-
await this.initDB();
|
|
152
|
-
return new Promise((resolve, reject) => {
|
|
153
|
-
const tx = this.db.transaction('kv', 'readwrite');
|
|
154
|
-
const store = tx.objectStore('kv');
|
|
155
|
-
store.delete(resourceKey);
|
|
156
|
-
tx.oncomplete = resolve;
|
|
157
|
-
tx.onerror = () => reject(tx.error);
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/** Clear ALL cached data */
|
|
162
|
-
async clear() {
|
|
163
|
-
await this.initDB();
|
|
164
|
-
return new Promise((resolve, reject) => {
|
|
165
|
-
const tx = this.db.transaction('kv', 'readwrite');
|
|
166
|
-
const store = tx.objectStore('kv');
|
|
167
|
-
store.clear();
|
|
168
|
-
tx.oncomplete = resolve;
|
|
169
|
-
tx.onerror = () => reject(tx.error);
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// SINGLE GLOBAL INSTANCE - import anywhere
|
|
175
|
-
const APP_CACHE = new CacheManager();
|
|
176
|
-
|
|
177
|
-
/*
|
|
178
|
-
USAGE EXAMPLES:
|
|
179
|
-
|
|
180
|
-
// ===== 1. COUCHDB TAGS (your original use case) =====
|
|
181
|
-
async function loadTagsPage(dbUrl) {
|
|
182
|
-
const tags = await cache.load('tags', () => fetchAllTags(dbUrl));
|
|
183
|
-
renderTags(tags || []); // INSTANT - never blocks!
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// ===== 2. USERS LIST =====
|
|
187
|
-
async function loadUsersPage() {
|
|
188
|
-
const users = await cache.load('users', () => fetch('/api/users'));
|
|
189
|
-
renderUsers(users || []);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// ===== 3. STATS DASHBOARD =====
|
|
193
|
-
async function loadStats() {
|
|
194
|
-
const stats = await cache.load('stats', () => fetchStats(dbUrl), 5 * 60 * 1000); // 5min TTL
|
|
195
|
-
renderStats(stats);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// ===== 4. REFRESH BUTTONS =====
|
|
199
|
-
$('#refresh-tags').click(async () => {
|
|
200
|
-
await cache.refresh('tags', () => fetchAllTags(dbUrl));
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
// ===== 5. MANUAL CONTROL =====
|
|
204
|
-
const tags = await cache.get('tags'); // TTL-aware get
|
|
205
|
-
await cache.set('config', configData); // Manual set
|
|
206
|
-
await cache.delete('tags'); // Invalidate
|
|
207
|
-
await cache.clear(); // Nuke everything
|
|
208
|
-
|
|
209
|
-
// PERFECT FOR: tags, users, categories, search results, stats, config
|
|
210
|
-
*/
|
package/dist/settings.html
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<script type="module" src="../dist/main.js"></script>
|
|
7
|
-
<script src="app.js"></script>
|
|
8
|
-
<title>BBDB-Local settings</title>
|
|
9
|
-
<link
|
|
10
|
-
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
|
|
11
|
-
rel="stylesheet"
|
|
12
|
-
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
|
|
13
|
-
crossorigin="anonymous"
|
|
14
|
-
/>
|
|
15
|
-
</head>
|
|
16
|
-
<body>
|
|
17
|
-
<script>
|
|
18
|
-
// Call the function to load the header
|
|
19
|
-
// document.addEventListener("DOMContentLoaded", loadHeader);
|
|
20
|
-
|
|
21
|
-
// Usage examples:
|
|
22
|
-
document.addEventListener("DOMContentLoaded", async () => {
|
|
23
|
-
// try {
|
|
24
|
-
// const db = await initPage();
|
|
25
|
-
// showMessage("success", `Loaded database: ${db.name}`);
|
|
26
|
-
// } catch (error) {
|
|
27
|
-
// showMessage("error", error.message);
|
|
28
|
-
// }
|
|
29
|
-
});
|
|
30
|
-
</script>
|
|
31
|
-
<div class="container">
|
|
32
|
-
<h3>List of database</h3>
|
|
33
|
-
<hr>
|
|
34
|
-
<db-list></db-list>
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</body>
|
|
39
|
-
</html>
|
package/dist/test.html
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<script type="module" src="../dist/main.js"></script>
|
|
7
|
-
<script src="app.js"></script>
|
|
8
|
-
<title>BBDB Web Components</title>
|
|
9
|
-
<link
|
|
10
|
-
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
|
|
11
|
-
rel="stylesheet"
|
|
12
|
-
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
|
|
13
|
-
crossorigin="anonymous"
|
|
14
|
-
/>
|
|
15
|
-
</head>
|
|
16
|
-
<body>
|
|
17
|
-
<script>
|
|
18
|
-
// Call the function to load the header
|
|
19
|
-
// document.addEventListener("DOMContentLoaded", loadHeader);
|
|
20
|
-
|
|
21
|
-
// Usage examples:
|
|
22
|
-
document.addEventListener("DOMContentLoaded", async () => {
|
|
23
|
-
try {
|
|
24
|
-
const db = await initPage();
|
|
25
|
-
console.log("Loaded DB:", db);
|
|
26
|
-
} catch (error) {
|
|
27
|
-
console.error("Init failed:", error.message);
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
</script>
|
|
31
|
-
|
|
32
|
-
<db-list></db-list>
|
|
33
|
-
</body>
|
|
34
|
-
</html>
|