estreui 1.2.3 → 1.2.5

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.
@@ -0,0 +1,596 @@
1
+ /*
2
+ EstreUI rimwork — Notation & Storage
3
+ Part of the split from estreUi.js (roadmap #002 phase 2).
4
+
5
+ This file is loaded as a plain <script> tag and shares the global scope
6
+ with the other estreUi-*.js files. Load order matters: see index.html.
7
+ */
8
+
9
+ // MODULE: Notation & Storage -- EstreNotationManager, AsyncStorage,
10
+ // NativeStorage, ES/EAS/EJS/EAJS, EstreUiParameterManager
11
+ // ======================================================================
12
+
13
+ class EstreNotationManager {
14
+
15
+ // static
16
+ static #page = "popNote";
17
+
18
+ static #queue = [];
19
+ static current = null;
20
+
21
+ static postHandle = null;
22
+
23
+ static get noInteraction() { return (intent) => {}; }
24
+
25
+ static post(message, showTime = 3000, onTakeInteraction = this.noInteraction, options = {}) {
26
+ if (message != null && !isNaN(showTime) && showTime > 0) {
27
+ return new Promise((resolve) => {
28
+ const it = new EstreNotationManager(message, showTime, onTakeInteraction, options, resolve);
29
+ this.#queue.push(it);
30
+ if (window.isDebug) console.log(this.#page + " posted: ", it);
31
+ postQueue(_ => this.postHandler());
32
+ });
33
+ }
34
+ }
35
+
36
+ static postHandler() {
37
+ if (window.isDebug) console.log("queue: ", this.#queue);
38
+ if (this.postHandle == null && this.current == null && this.#queue.length > 0) {
39
+ const handle = Date.now();
40
+ this.postHandle = handle;
41
+ const current = this.#queue.splice(0, 1)[0];
42
+ current.data.posted = handle;
43
+ if (window.isDebug) console.log(this.#page + " bring: ", current);
44
+ return pageManager.bringPage("!" + this.#page, current, handle);
45
+ }
46
+ }
47
+
48
+ static checkOut(intent) {
49
+ if (intent.data.posted != null && this.postHandle == intent.data.posted) {
50
+ if (this.current == intent) {
51
+ this.current = null;
52
+ }
53
+ this.postHandle = null;
54
+ if (window.isDebug) console.log(this.#page + " checked out: ", intent);
55
+ postQueue(_ => this.postHandler());
56
+ }
57
+ intent.resolver?.(intent);
58
+ }
59
+
60
+ // instance property
61
+ data = {
62
+ posted: undefined,
63
+ content: undefined,
64
+ showTime: undefined,
65
+ interactive: undefined,
66
+ resolver: undefined,
67
+
68
+ //options
69
+ iconSrc: undefined,
70
+ textSize: undefined,
71
+ textWeight: undefined,
72
+ textColor: undefined,
73
+ bgColor: undefined,
74
+ };
75
+
76
+ onTakeInteraction = undefined;
77
+
78
+ constructor(message, showTime = 3000, onTakeInteraction = EstreNotationManager.noInteraction, options = {}, resolver) {
79
+ for (const item in options) this.data[item] = options[item];
80
+ this.data.content = message;
81
+ this.data.showTime = showTime;
82
+ this.onTakeInteraction = onTakeInteraction;
83
+ if (onTakeInteraction != EstreNotationManager.noInteraction) this.data.interactive = "";
84
+ this.resolver = resolver;
85
+ }
86
+ }
87
+
88
+ const note = function (message, showTime = 3000, onTakeInteraction = EstreNotationManager.noInteraction, options = {}) {
89
+ return EstreNotationManager.post(...arguments);
90
+ }
91
+
92
+
93
+
94
+ // For Native storage
95
+ class AsyncStorage {}
96
+ class NativeStorage extends AsyncStorage {
97
+
98
+ constructor() {
99
+ super();
100
+
101
+ this.#getLength();
102
+ }
103
+
104
+ #length = 0;
105
+
106
+ get length() {
107
+ return this.#length;
108
+ }
109
+
110
+ async #getLength() {
111
+ this.#length = await window.app?.request?.("getLengthOfNativeStorage") ?? 0;
112
+ return this.#length;
113
+ }
114
+
115
+ async key(index) {
116
+ return await window.app?.request?.("getFromNativeStorageAt", index);
117
+ }
118
+
119
+ async getItem(keyName) {
120
+ return await window.app?.request?.("getFromNativeStorage", keyName);
121
+ }
122
+
123
+ async setItem(keyName, keyValue) {
124
+ const returns = await window.app?.request?.("setToNativeStorage", keyName, keyValue);
125
+ await this.#getLength();
126
+ return returns;
127
+ }
128
+
129
+ async removeItem(keyName) {
130
+ const returns = await window.app?.request?.("removeFromNativeStorage", keyName);
131
+ await this.#getLength();
132
+ return returns;
133
+ }
134
+
135
+ async clear() {
136
+ const returns = await window.app?.request?.("clearNativeStorage");
137
+ await this.#getLength();
138
+ return returns;
139
+ }
140
+
141
+ }
142
+ window.nativeStorage = new NativeStorage();
143
+
144
+ // Storage handler
145
+ const ES_PREFIX = "ESAF_";//Estre Syncretic Applicate Framework
146
+
147
+ /**
148
+ * Estre Storage access handler
149
+ */
150
+ class ES {
151
+
152
+ _storage = null;
153
+ _storagePrefix = null;
154
+
155
+ get _prefix() { return ES_PREFIX + this._storagePrefix + "RAW_"; }
156
+
157
+
158
+ _getFullKey(key) { return this._prefix + key; }
159
+
160
+
161
+
162
+ constructor(storage, storagePrefix) {
163
+ this._storage = storage;
164
+ this._storagePrefix = storagePrefix;
165
+ }
166
+
167
+
168
+ #get(key, type = "string", def) {
169
+ if (key == null | key == "") return;
170
+ const value = this._storage.getItem(this._getFullKey(key));
171
+ return this._getBy(type, value, def);
172
+ }
173
+
174
+ _getBy(type, value, def) {
175
+ switch (type) {
176
+
177
+ case "boolean":
178
+ if (value == "true") return true;
179
+ else if (value == "false") return false;
180
+ else if (value == "null") return null;
181
+ else return def;
182
+
183
+ case "int":
184
+ if (isNaN(value)) return def;
185
+ else return parseInt(value);
186
+
187
+ case "float":
188
+ if (isNaN(value)) return def;
189
+ else return parseFloat(value);
190
+
191
+ case "object":
192
+ if (value == null || value == "") return def;
193
+ else try {
194
+ return JSON.parse(value);
195
+ } catch (ex) {
196
+ if (window.isLogging) console.error("[" + ex.name + "]" + ex.message);
197
+ if (window.isDebug) console.error(value);
198
+ return def;
199
+ }
200
+
201
+ case "binary":
202
+ if (value == null || value == "") return def;
203
+ else try {
204
+ return atob(value);
205
+ } catch (ex) {
206
+ if (window.isLogging) console.error("[" + ex.name + "]" + ex.message);
207
+ if (window.isDebug) console.error(value);
208
+ return def;
209
+ }
210
+
211
+ case "bytes":
212
+ if (value == null || value == "") return def;
213
+ else try {
214
+ return Uint8Array.from(atob(value), (m) => m.codePointAt(0));
215
+ } catch (ex) {
216
+ if (window.isLogging) console.error("[" + ex.name + "]" + ex.message);
217
+ if (window.isDebug) console.error(value);
218
+ return def;
219
+ }
220
+
221
+ case "string":
222
+ default:
223
+ return value == null ? def : value;
224
+ }
225
+ }
226
+
227
+ getBoolean(key, def) { return this.#get(key, "boolean", def); }
228
+ getInt(key, def) { return this.#get(key, "int", def); }
229
+ getFloat(key, def) { return this.#get(key, "float", def); }
230
+ getString(key, def) { return this.#get(key, "string", def); }
231
+ getBinary(key, def) { return this.#get(key, "binary", def); }
232
+ getBytes(key, def) { return this.#get(key, "bytes", def); }
233
+ getObject(key, def) { return this.#get(key, "object", def); }
234
+
235
+ get(key, def) { return this.getString(key, def); }
236
+
237
+
238
+ #set(key, type = "string", value) {
239
+ if (key == null | key == "") return undefined;
240
+ let valueString = this._stringifyBy(type, value);
241
+ if (valueString === false) return false;
242
+
243
+ return this._storage.setItem(this._getFullKey(key), valueString == null ? "" : valueString);
244
+ }
245
+
246
+ _stringifyBy(type, value) {
247
+ let valueString = null;
248
+ switch (type) {
249
+
250
+ case "object":
251
+ try {
252
+ valueString = JSON.stringify(value);
253
+ } catch (ex) {
254
+ if (window.isLogging) console.error("[" + ex.name + "]" + ex.message);
255
+ if (window.isDebug) console.error(value);
256
+ return false;
257
+ }
258
+ break;
259
+
260
+ case "binary":
261
+ try {
262
+ valueString = btoa(value);
263
+ } catch (ex) {
264
+ if (window.isLogging) console.error("[" + ex.name + "]" + ex.message);
265
+ if (window.isDebug) console.error(value);
266
+ return false;
267
+ }
268
+ break;
269
+
270
+ case "bytes":
271
+ try {
272
+ valueString = btoa(Array.from(value, (x) => String.fromCodePoint(x)).join(""));
273
+ } catch (ex) {
274
+ if (window.isLogging) console.error("[" + ex.name + "]" + ex.message);
275
+ if (window.isDebug) console.error(value);
276
+ return false;
277
+ }
278
+ break;
279
+
280
+ case "string":
281
+ valueString = value;
282
+ break;
283
+
284
+ case "boolean":
285
+ case "int":
286
+ case "float":
287
+ default:
288
+ valueString = "" + value;
289
+ break;
290
+ }
291
+
292
+ return valueString;
293
+ }
294
+
295
+ setBoolean(key, value) { return this.#set(key, "boolean", value); }
296
+ setInt(key, value) { return this.#set(key, "int", value); }
297
+ setFloat(key, value) { return this.#set(key, "float", value); }
298
+ setString(key, value) { return this.#set(key, "string", value); }
299
+ setBinary(key, value) { return this.#set(key, "binary", value); }
300
+ setBytes(key, value) { return this.#set(key, "bytes", value); }
301
+ setObject(key, value) { return this.#set(key, "object", value); }
302
+
303
+ set(key, value) { return this.setString(key, value); }
304
+
305
+
306
+ #remove(key) {
307
+ if (key == null | key == "") return undefined;
308
+ return this._storage.removeItem(this._getFullKey(key));
309
+ }
310
+
311
+ remove(key) { return this.#remove(key); }
312
+ }
313
+
314
+ /**
315
+ * Estre Async Storage access handler
316
+ */
317
+ class EAS extends ES {
318
+
319
+ constructor(storage, storagePrefix) {
320
+ super(storage, storagePrefix);
321
+ }
322
+
323
+ async #get(key, type = "string", def) {
324
+ if (key == null | key == "") return;
325
+ const value = await this._storage.getItem(this._getFullKey(key));
326
+ return this._getBy(type, value, def);
327
+ }
328
+
329
+ async getBoolean(key, def) { return await this.#get(key, "boolean", def); }
330
+ async getInt(key, def) { return await this.#get(key, "int", def); }
331
+ async getFloat(key, def) { return await this.#get(key, "float", def); }
332
+ async getString(key, def) { return await this.#get(key, "string", def); }
333
+ async getBinary(key, def) { return await this.#get(key, "binary", def); }
334
+ async getBytes(key, def) { return await this.#get(key, "bytes", def); }
335
+ async getObject(key, def) { return await this.#get(key, "object", def); }
336
+
337
+ async get(key, def) { return await this.getString(key, def); }
338
+
339
+
340
+ async #set(key, type = "string", value) {
341
+ if (key == null | key == "") return undefined;
342
+ let valueString = this._stringifyBy(type, value);
343
+ if (valueString === false) return false;
344
+
345
+ return await this._storage.setItem(this._getFullKey(key), valueString == null ? "" : valueString);
346
+ }
347
+
348
+ async setBoolean(key, value) { return await this.#set(key, "boolean", value); }
349
+ async setInt(key, value) { return await this.#set(key, "int", value); }
350
+ async setFloat(key, value) { return await this.#set(key, "float", value); }
351
+ async setString(key, value) { return await this.#set(key, "string", value); }
352
+ async setBinary(key, value) { return await this.#set(key, "binary", value); }
353
+ async setBytes(key, value) { return await this.#set(key, "bytes", value); }
354
+ async setObject(key, value) { return await this.#set(key, "object", value); }
355
+
356
+ async set(key, value) { return await this.setString(key, value); }
357
+
358
+
359
+ async #remove(key) {
360
+ if (key == null | key == "") return undefined;
361
+ return await this._storage.removeItem(this._getFullKey(key));
362
+ }
363
+
364
+ async remove(key) { return await this.#remove(key); }
365
+
366
+ }
367
+
368
+
369
+ /**
370
+ * Estre JSON/JCODD Storage access handler
371
+ */
372
+ class EJS {
373
+
374
+ get _typePrefix() { return equalCase(this._codeType, {
375
+ json: "JSON_",
376
+ jcodd: "JCODD_",
377
+ }); }
378
+
379
+ _storage = null;
380
+ _storagePrefix = null;
381
+
382
+ _codeType;
383
+
384
+ get _prefix() { return ES_PREFIX + this._storagePrefix + this._typePrefix; }
385
+
386
+
387
+ _getFullKey(key) { return this._prefix + key; }
388
+
389
+ constructor(storage, storagePrefix, codeType = "jcodd") {
390
+ this._storage = storage;
391
+ this._storagePrefix = storagePrefix;
392
+ this._codeType = codeType.toLowerCase();
393
+ }
394
+
395
+ get(key, def) {
396
+ if (key == null | key == "") return;
397
+ const value = this._storage.getItem(this._getFullKey(key));
398
+ return value == null ? def : equalCase(this._codeType, {
399
+ json: _ => JSON.parse(value),
400
+ jcodd: _ => Jcodd.parse(value),
401
+ });
402
+ }
403
+
404
+ set(key, value) {
405
+ if (key == null | key == "") return undefined;
406
+ let valueString
407
+ try {
408
+ valueString = equalCase(this._codeType, {
409
+ json: _ => JSON.stringify(value),
410
+ jcodd: _ => Jcodd.coddify(value),
411
+ });
412
+ } catch (ex) {
413
+ if (window.isLogging) console.error(ex);
414
+ }
415
+ return this._storage.setItem(this._getFullKey(key), valueString == null ? "" : valueString);
416
+ }
417
+
418
+ }
419
+
420
+ /**
421
+ * Estre Async JSON/JCODD Storage access handler
422
+ */
423
+ class EAJS extends EJS {
424
+
425
+ constructor(storage, storagePrefix, codeType) {
426
+ super(storage, storagePrefix, codeType);
427
+ }
428
+
429
+ async get(key, def) {
430
+ if (key == null | key == "") return;
431
+ const value = await this._storage.getItem(this._getFullKey(key));
432
+ return value == null ? def : equalCase(this._codeType, {
433
+ json: _ => JSON.parse(value),
434
+ jcodd: _ => Jcodd.parse(value),
435
+ });
436
+ }
437
+
438
+ async set(key, value) {
439
+ if (key == null | key == "") return undefined;
440
+ let valueString
441
+ try {
442
+ valueString = equalCase(this._codeType, {
443
+ json: _ => JSON.stringify(value),
444
+ jcodd: _ => Jcodd.coddify(value),
445
+ });
446
+ } catch (ex) {
447
+ if (window.isLogging) console.error(ex);
448
+ }
449
+ return await this._storage.setItem(this._getFullKey(key), valueString == null ? "" : valueString);
450
+ }
451
+
452
+ }
453
+
454
+
455
+
456
+ /**
457
+ * Session storage handler
458
+ */
459
+ const ESS = new ES(sessionStorage, "SS_");
460
+
461
+ /**
462
+ * Local storage handler
463
+ */
464
+ const ELS = new ES(localStorage, "LS_");
465
+
466
+ /**
467
+ * Native storage handler
468
+ */
469
+ const ENS = new EAS(nativeStorage, "NS_");
470
+
471
+
472
+
473
+
474
+ /**
475
+ * Codded Session storage handler
476
+ */
477
+ const ECSS = new EJS(sessionStorage, "SS_");
478
+
479
+ /**
480
+ * Codded Local storage handler
481
+ */
482
+ const ECLS = new EJS(localStorage, "LS_");
483
+
484
+ /**
485
+ * Codded Native storage handler
486
+ */
487
+ const ECNS = new EAJS(nativeStorage, "NS_");
488
+
489
+
490
+
491
+
492
+
493
+ /***
494
+ * Parameter manager
495
+ */
496
+ class EstreUiParameterManager {
497
+
498
+ get ssPrefix() { return this.#prefix + "PARAMETER_MANAGER_"; }
499
+
500
+ get forLS() { return {
501
+
502
+ }; }
503
+
504
+ get forSS() { return {
505
+ get page() { return "requestPage"; },
506
+ get origin() { return "requestOrigin"; },
507
+ }; }
508
+
509
+ // class property
510
+ #prefix;
511
+ #params;
512
+
513
+ #lsMatch = {};
514
+ #ssMatch = {};
515
+
516
+ constructor(prefix = "", lsMatch = {}, ssMatch = {}, search = location.search) {
517
+ this.#prefix = prefix ?? "";
518
+ this.#params = new URLSearchParams(search);
519
+ this.#lsMatch = lsMatch ?? {};
520
+ this.#ssMatch = ssMatch ?? {};
521
+ }
522
+
523
+
524
+ init() {
525
+ for (const [key, value] of this.#params) {
526
+ let keyName = this.#lsMatch[key] ?? this.forLS[key];
527
+ if (keyName != null) {
528
+ ELS.setString(keyName.length > 0 ? keyName : this.ssPrefix + key, value);
529
+ } else {
530
+ keyName = this.#ssMatch[key] ?? this.forSS[key];
531
+ ESS.setString(keyName != null && keyName.length > 0 ? keyName : this.ssPrefix + key, value);
532
+ }
533
+ }
534
+
535
+ return this;
536
+ }
537
+
538
+ get(key) {
539
+ let keyName = this.#lsMatch[key] ?? this.forLS[key];
540
+ if (keyName != null) {
541
+ return ELS.getString(keyName.length > 0 ? keyName : this.ssPrefix + key);
542
+ } else {
543
+ keyName = this.#ssMatch[key] ?? this.forSS[key];
544
+ return ESS.getString(keyName != null && keyName.length > 0 ? keyName : this.ssPrefix + key);
545
+ }
546
+ }
547
+ }
548
+
549
+
550
+ /**
551
+ * Async works manager
552
+ */
553
+ class EstreAsyncManager {
554
+
555
+ static works = new Set();
556
+ static onClears = new Set();
557
+
558
+ static get workIs() { return Array.from(this.works).length; }
559
+
560
+ static beginWork(specifier, host, just = Date.now()) {
561
+ const id = just + "@" + host + "#" + specifier;
562
+
563
+ this.works.add(id);
564
+
565
+ return id;
566
+ }
567
+
568
+ static endOfWork(id) {
569
+ this.works.delete(id);
570
+
571
+ const lefts = this.workIs
572
+ if (lefts < 1) this.bringFinishCallback();
573
+
574
+ return lefts;
575
+ }
576
+
577
+ static setOnFinishedCurrentWorks(callback) {
578
+ if (this.workIs < 1) callback(0);
579
+ else this.onClears.add(callback);
580
+ }
581
+
582
+ static removeOnFinishedCurrentWorks(callback) {
583
+ this.onClears.delete(callback);
584
+ }
585
+
586
+ static bringFinishCallback() {
587
+ const callbacks = Array.from(this.onClears);
588
+ const lefts = this.workIs;
589
+
590
+ for (var callback of callbacks) callback(lefts);
591
+ }
592
+ }
593
+
594
+
595
+
596
+ // ======================================================================