@taybart/corvid 0.1.1 → 0.1.3
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 +113 -1
- package/dist/dom.d.ts +16 -2
- package/dist/dom.test.d.ts +1 -0
- package/dist/index.js +162 -52
- package/dist/local_storage.d.ts +5 -2
- package/dist/network.d.ts +2 -0
- package/dist/qr.d.ts +22 -0
- package/dist/renderer.d.ts +0 -0
- package/dist/style.d.ts +5 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -2,5 +2,117 @@
|
|
|
2
2
|
|
|
3
3
|
fear the crow
|
|
4
4
|
|
|
5
|
+

|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
Non-exhastive list of features
|
|
10
|
+
|
|
11
|
+
### DOM
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import { dom } from '@taybart/corvid'
|
|
15
|
+
|
|
16
|
+
dom.ready(() => {
|
|
17
|
+
// query for existing element
|
|
18
|
+
const username = new dom.el('#username')
|
|
19
|
+
// listen for events
|
|
20
|
+
username.on('click', () => {
|
|
21
|
+
// set style, will kebab keys backgroundColor -> background-color
|
|
22
|
+
username.style({ color: 'red', backgroundColor: 'yellow' })
|
|
23
|
+
// set/get content
|
|
24
|
+
username.content(`evil: ${username.value()}`)
|
|
25
|
+
}))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
// create new elements
|
|
29
|
+
new dom.el({
|
|
30
|
+
type: 'div',
|
|
31
|
+
id: 'hair-color',
|
|
32
|
+
class: 'hair user-info',
|
|
33
|
+
content: 'blue',
|
|
34
|
+
// will append element to username
|
|
35
|
+
parent: username,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
// listen for keys and check for modifiers
|
|
39
|
+
dom.onKey('E', ({ ctrl, alt, meta, shift }) => {
|
|
40
|
+
console.log('E pressed')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
/*
|
|
44
|
+
* Given a template:
|
|
45
|
+
* <template id="tmpl-test">
|
|
46
|
+
* <div> hello ${name} </div>
|
|
47
|
+
* </template>
|
|
48
|
+
*/
|
|
49
|
+
const tmpl = new dom.el('#tmpl-test')
|
|
50
|
+
// append template to el
|
|
51
|
+
username.appendTemplate(tmpl, { name: 'corvid' })
|
|
52
|
+
// or just set content
|
|
53
|
+
document.body.innerHTML = tmpl.render({ name: 'corvid' })
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### LocalStorage
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
import { ls, dom } from '@taybart/corvid'
|
|
61
|
+
|
|
62
|
+
dom.ready(() => {
|
|
63
|
+
const hpStat = new dom.el({ query: '#stat-hp', content: ls.get('stats.hp') })
|
|
64
|
+
// set element content when localstorage changes
|
|
65
|
+
ls.listen('stats.hp', hpStat)
|
|
66
|
+
// or just a callback
|
|
67
|
+
ls.listen('stats.hp', ({ key, value }) => {
|
|
68
|
+
console.log(`health is now ${value}`)
|
|
69
|
+
})
|
|
70
|
+
// set a value (required if listening for events)
|
|
71
|
+
ls.set('stats.hp', ls.get('stats.hp') - 1))
|
|
72
|
+
// set a flattened object, will update "stats.hp" and "stats.attack"
|
|
73
|
+
ls.set({ stats: { hp: 100, attack: 10 } })
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Network
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
import { network } '@taybart/corvid'
|
|
81
|
+
|
|
82
|
+
// create an api client
|
|
83
|
+
const api = network.create({
|
|
84
|
+
url: 'https://api.example.com',
|
|
85
|
+
credentials: 'include',
|
|
86
|
+
success: 250, // odd success code
|
|
87
|
+
// corvid params, string, or custom object that has .toString() and renders url safe params
|
|
88
|
+
params: new network.params({hello: 'corvid'})
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// make a request
|
|
92
|
+
const { username } = await api.do({
|
|
93
|
+
path: '/users/1',
|
|
94
|
+
override: {
|
|
95
|
+
params: network.params.render({hello: 'world!'}) , // only for this request
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Styles
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
import { style } '@taybart/corvid'
|
|
106
|
+
|
|
107
|
+
// query css media prefers-color-scheme
|
|
108
|
+
if (style.isDarkMode()) {
|
|
109
|
+
console.log('dark mode')
|
|
110
|
+
}
|
|
111
|
+
// listen for theme switch
|
|
112
|
+
style.onDarkMode((isDark) => {
|
|
113
|
+
// set document attribute 'data-theme'
|
|
114
|
+
style.switchTheme(isDark ? 'light' : 'dark')
|
|
115
|
+
// get css variables
|
|
116
|
+
console.log(`is dark mode: ${isDark} and background is ${style.cssVar('--color-bg')`)
|
|
117
|
+
})
|
|
118
|
+
```
|
package/dist/dom.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export declare function onKey(key: string, cb: (ev: {
|
|
|
13
13
|
meta: boolean;
|
|
14
14
|
shift: boolean;
|
|
15
15
|
}) => void): void;
|
|
16
|
+
export declare function els(query: string, verbose?: boolean): el[];
|
|
16
17
|
/*** element ***/
|
|
17
18
|
type elOpts = {
|
|
18
19
|
element?: HTMLElement;
|
|
@@ -28,6 +29,7 @@ export declare class el {
|
|
|
28
29
|
el: HTMLElement | null;
|
|
29
30
|
query: string;
|
|
30
31
|
log: logger;
|
|
32
|
+
listeners: Record<string, Array<(ev: Event) => void>>;
|
|
31
33
|
constructor(opts: HTMLElement | string | elOpts, verbose?: boolean);
|
|
32
34
|
/*** dom manipulation ***/
|
|
33
35
|
value(update?: string): string | el;
|
|
@@ -40,12 +42,24 @@ export declare class el {
|
|
|
40
42
|
}): this;
|
|
41
43
|
src(url: string): this;
|
|
42
44
|
/*** Style ***/
|
|
43
|
-
style(
|
|
45
|
+
style(update: Object | string, stringify?: boolean): this | undefined;
|
|
46
|
+
hasClass(className: string): boolean;
|
|
44
47
|
addClass(className: string): this;
|
|
45
48
|
removeClass(className: string): this;
|
|
49
|
+
/*** Templates ***/
|
|
50
|
+
render(vars?: {}): string;
|
|
51
|
+
appendTemplate(template: el, vars: any): void;
|
|
46
52
|
/*** Events ***/
|
|
47
53
|
on(event: string, cb: (ev: Event) => void): this;
|
|
48
54
|
listen(event: string, cb: (ev: Event) => void): this;
|
|
49
|
-
|
|
55
|
+
removeListeners(event: string): this;
|
|
50
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Get a template from a string
|
|
59
|
+
* https://stackoverflow.com/a/41015840
|
|
60
|
+
* @param str The string to interpolate
|
|
61
|
+
* @param params The parameters
|
|
62
|
+
* @return The interpolated string
|
|
63
|
+
*/
|
|
64
|
+
export declare function interpolate(str: string, params: Object): string;
|
|
51
65
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -26,22 +26,26 @@ __webpack_require__.d(strings_namespaceObject, {
|
|
|
26
26
|
bytesToHuman: ()=>bytesToHuman,
|
|
27
27
|
toKebab: ()=>toKebab
|
|
28
28
|
});
|
|
29
|
-
var dom_namespaceObject = {};
|
|
30
|
-
__webpack_require__.r(dom_namespaceObject);
|
|
31
|
-
__webpack_require__.d(dom_namespaceObject, {
|
|
32
|
-
el: ()=>dom_el,
|
|
33
|
-
onKey: ()=>onKey,
|
|
34
|
-
ready: ()=>ready
|
|
35
|
-
});
|
|
36
29
|
var style_namespaceObject = {};
|
|
37
30
|
__webpack_require__.r(style_namespaceObject);
|
|
38
31
|
__webpack_require__.d(style_namespaceObject, {
|
|
39
32
|
cssVar: ()=>cssVar,
|
|
40
33
|
gradient: ()=>gradient,
|
|
34
|
+
handleThemeSwitch: ()=>handleThemeSwitch,
|
|
41
35
|
isDarkMode: ()=>isDarkMode,
|
|
42
36
|
onDarkMode: ()=>onDarkMode,
|
|
37
|
+
render: ()=>render,
|
|
43
38
|
switchTheme: ()=>switchTheme
|
|
44
39
|
});
|
|
40
|
+
var dom_namespaceObject = {};
|
|
41
|
+
__webpack_require__.r(dom_namespaceObject);
|
|
42
|
+
__webpack_require__.d(dom_namespaceObject, {
|
|
43
|
+
el: ()=>dom_el,
|
|
44
|
+
els: ()=>els,
|
|
45
|
+
interpolate: ()=>interpolate,
|
|
46
|
+
onKey: ()=>onKey,
|
|
47
|
+
ready: ()=>ready
|
|
48
|
+
});
|
|
45
49
|
var network_namespaceObject = {};
|
|
46
50
|
__webpack_require__.r(network_namespaceObject);
|
|
47
51
|
__webpack_require__.d(network_namespaceObject, {
|
|
@@ -53,9 +57,12 @@ __webpack_require__.d(network_namespaceObject, {
|
|
|
53
57
|
var local_storage_namespaceObject = {};
|
|
54
58
|
__webpack_require__.r(local_storage_namespaceObject);
|
|
55
59
|
__webpack_require__.d(local_storage_namespaceObject, {
|
|
60
|
+
clear: ()=>clear,
|
|
56
61
|
get: ()=>get,
|
|
57
62
|
listen: ()=>listen,
|
|
58
|
-
set: ()=>set
|
|
63
|
+
set: ()=>set,
|
|
64
|
+
setObj: ()=>setObj,
|
|
65
|
+
update: ()=>local_storage_update
|
|
59
66
|
});
|
|
60
67
|
function bytesToHuman(bytes, options = {}) {
|
|
61
68
|
const { useSI = false, decimals = 2, includeUnits = true, targetUnit = null } = options;
|
|
@@ -102,6 +109,39 @@ function bytesToHuman(bytes, options = {}) {
|
|
|
102
109
|
function toKebab(str) {
|
|
103
110
|
return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, (s, ofs)=>(ofs ? '-' : '') + s.toLowerCase());
|
|
104
111
|
}
|
|
112
|
+
function cssVar(name) {
|
|
113
|
+
const style = window.getComputedStyle(document.body);
|
|
114
|
+
return style.getPropertyValue(name);
|
|
115
|
+
}
|
|
116
|
+
function render(style) {
|
|
117
|
+
let s = '';
|
|
118
|
+
Object.entries(style).forEach(([k, v])=>s += `${toKebab(k)}:${v};`);
|
|
119
|
+
return s;
|
|
120
|
+
}
|
|
121
|
+
function isDarkMode() {
|
|
122
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
123
|
+
}
|
|
124
|
+
function onDarkMode(cb) {
|
|
125
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (ev)=>{
|
|
126
|
+
cb(ev.matches);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function switchTheme(theme) {
|
|
130
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
131
|
+
}
|
|
132
|
+
function handleThemeSwitch() {
|
|
133
|
+
switchTheme(isDarkMode() ? 'dark' : 'light');
|
|
134
|
+
onDarkMode((dark)=>{
|
|
135
|
+
switchTheme(dark ? 'dark' : 'light');
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function gradient(start, end, value) {
|
|
139
|
+
value = Math.max(0, Math.min(100, value));
|
|
140
|
+
const red = Math.round(start.red + (end.red - start.red) * value / 100);
|
|
141
|
+
const green = Math.round(start.green + (end.green - start.green) * value / 100);
|
|
142
|
+
const blue = Math.round(start.blue + (end.blue - start.blue) * value / 100);
|
|
143
|
+
return `rgb(${red}, ${green}, ${blue})`;
|
|
144
|
+
}
|
|
105
145
|
function _define_property(obj, key, value) {
|
|
106
146
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
107
147
|
value: value,
|
|
@@ -212,15 +252,20 @@ function onKey(key, cb) {
|
|
|
212
252
|
});
|
|
213
253
|
});
|
|
214
254
|
}
|
|
255
|
+
function els(query, verbose = false) {
|
|
256
|
+
return Array.from(document.querySelectorAll(query)).map((n)=>new dom_el(n, verbose));
|
|
257
|
+
}
|
|
215
258
|
class dom_el {
|
|
216
259
|
value(update) {
|
|
217
260
|
if (!this.el) throw new Error(`no element from query: ${this.query}`);
|
|
218
|
-
if (update) {
|
|
261
|
+
if (void 0 !== update) {
|
|
219
262
|
if ('value' in this.el) this.el.value = update;
|
|
220
263
|
if ('src' in this.el) this.el.src = update;
|
|
221
264
|
return this;
|
|
222
265
|
}
|
|
223
266
|
if ('value' in this.el) return this.el.value;
|
|
267
|
+
if ('innerText' in this.el) return this.el.innerText;
|
|
268
|
+
if ('innerHTML' in this.el) return this.el.innerHTML;
|
|
224
269
|
this.log.warn(`element (${this.query}) does not contain value, returning empty string`);
|
|
225
270
|
return '';
|
|
226
271
|
}
|
|
@@ -252,17 +297,25 @@ class dom_el {
|
|
|
252
297
|
if (this.el && 'src' in this.el) this.el.src = url;
|
|
253
298
|
return this;
|
|
254
299
|
}
|
|
255
|
-
style(
|
|
300
|
+
style(update, stringify = false) {
|
|
256
301
|
if (this.el) {
|
|
257
|
-
if ('string' == typeof
|
|
258
|
-
else if ('object' == typeof
|
|
259
|
-
|
|
260
|
-
|
|
302
|
+
if ('string' == typeof update) this.el.style = update;
|
|
303
|
+
else if ('object' == typeof update) {
|
|
304
|
+
if (!stringify) {
|
|
305
|
+
for (const [k, v] of Object.entries(update))this.el.style[k] = v;
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const s = render(update);
|
|
309
|
+
this.log.debug(`set style: ${this.el.style} -> ${s}`);
|
|
261
310
|
this.el.style = s;
|
|
262
311
|
}
|
|
263
312
|
}
|
|
264
313
|
return this;
|
|
265
314
|
}
|
|
315
|
+
hasClass(className) {
|
|
316
|
+
if (!this.el) throw new Error(`no element from query: ${this.query}`);
|
|
317
|
+
return this.el.classList.contains(className);
|
|
318
|
+
}
|
|
266
319
|
addClass(className) {
|
|
267
320
|
if (!this.el) throw new Error(`no element from query: ${this.query}`);
|
|
268
321
|
this.el.classList.add(className);
|
|
@@ -273,27 +326,52 @@ class dom_el {
|
|
|
273
326
|
this.el.classList.remove(className);
|
|
274
327
|
return this;
|
|
275
328
|
}
|
|
329
|
+
render(vars = {}) {
|
|
330
|
+
if (!this.el) throw new Error(`no element from query: ${this.query}`);
|
|
331
|
+
try {
|
|
332
|
+
return interpolate(this.el.innerHTML, vars);
|
|
333
|
+
} catch (e) {
|
|
334
|
+
throw new Error(`could not render template ${this.query}: ${e}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
appendTemplate(template, vars) {
|
|
338
|
+
if (!this.el) throw new Error(`no element from query: ${this.query}`);
|
|
339
|
+
if (!template.el) throw new Error("template does not contain element");
|
|
340
|
+
const tmpl = template.render(vars);
|
|
341
|
+
this.el.insertAdjacentHTML('beforeend', tmpl);
|
|
342
|
+
}
|
|
276
343
|
on(event, cb) {
|
|
277
344
|
if (!this.el) throw new Error(`no element from query: ${this.query}`);
|
|
345
|
+
if (!this.listeners[event]) this.listeners[event] = [];
|
|
346
|
+
this.listeners[event].push(cb);
|
|
278
347
|
this.el.addEventListener(event, cb);
|
|
279
348
|
return this;
|
|
280
349
|
}
|
|
281
350
|
listen(event, cb) {
|
|
282
351
|
return this.on(event, cb);
|
|
283
352
|
}
|
|
284
|
-
|
|
285
|
-
|
|
353
|
+
removeListeners(event) {
|
|
354
|
+
if (!this.el) throw new Error(`no element from query: ${this.query}`);
|
|
355
|
+
for (const cb of this.listeners[event])this.el.removeEventListener(event, cb);
|
|
356
|
+
this.listeners[event] = [];
|
|
357
|
+
return this;
|
|
286
358
|
}
|
|
287
359
|
constructor(opts, verbose = false){
|
|
288
360
|
dom_define_property(this, "el", void 0);
|
|
289
361
|
dom_define_property(this, "query", '');
|
|
290
362
|
dom_define_property(this, "log", void 0);
|
|
363
|
+
dom_define_property(this, "listeners", {});
|
|
291
364
|
this.log = new logger(verbose ? utils_logLevel.debug : utils_logLevel.none, 'element');
|
|
292
365
|
if ('string' == typeof opts) {
|
|
293
366
|
this.query = opts;
|
|
294
367
|
this.el = document.querySelector(opts);
|
|
295
368
|
return;
|
|
296
369
|
}
|
|
370
|
+
if (opts instanceof HTMLElement) {
|
|
371
|
+
this.log.debug(`using existing element: ${opts}`);
|
|
372
|
+
this.el = opts;
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
297
375
|
const { query, element, type, class: styleClass, style, id, content, parent } = opts;
|
|
298
376
|
if (query) {
|
|
299
377
|
this.log.debug(`using query: ${query}`);
|
|
@@ -304,6 +382,7 @@ class dom_el {
|
|
|
304
382
|
this.log.debug(`using existing element: ${element}`);
|
|
305
383
|
this.el = element;
|
|
306
384
|
} else if (type) {
|
|
385
|
+
this.query = type;
|
|
307
386
|
this.log.debug(`creating element: ${type}`);
|
|
308
387
|
this.el = document.createElement(type);
|
|
309
388
|
} else throw new Error('no query or type provided');
|
|
@@ -325,27 +404,10 @@ class dom_el {
|
|
|
325
404
|
}
|
|
326
405
|
}
|
|
327
406
|
}
|
|
328
|
-
function
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}
|
|
332
|
-
function isDarkMode() {
|
|
333
|
-
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
334
|
-
}
|
|
335
|
-
function onDarkMode(cb) {
|
|
336
|
-
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (ev)=>{
|
|
337
|
-
cb(ev.matches);
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
function switchTheme(theme) {
|
|
341
|
-
document.documentElement.setAttribute('data-theme', theme);
|
|
342
|
-
}
|
|
343
|
-
function gradient(start, end, value) {
|
|
344
|
-
value = Math.max(0, Math.min(100, value));
|
|
345
|
-
const red = Math.round(start.red + (end.red - start.red) * value / 100);
|
|
346
|
-
const green = Math.round(start.green + (end.green - start.green) * value / 100);
|
|
347
|
-
const blue = Math.round(start.blue + (end.blue - start.blue) * value / 100);
|
|
348
|
-
return `rgb(${red}, ${green}, ${blue})`;
|
|
407
|
+
function interpolate(str, params) {
|
|
408
|
+
let names = Object.keys(params).map((k)=>`_${k}`);
|
|
409
|
+
let vals = Object.values(params);
|
|
410
|
+
return new Function(...names, `return \`${str.replace(/\$\{(\w*)\}/g, '${_$1}')}\`;`)(...vals);
|
|
349
411
|
}
|
|
350
412
|
function network_define_property(obj, key, value) {
|
|
351
413
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
@@ -437,47 +499,54 @@ class request {
|
|
|
437
499
|
class ws {
|
|
438
500
|
setup() {
|
|
439
501
|
this.recursion_level += 1;
|
|
502
|
+
if (this.ws) for(let key in this.event_listeners)this.event_listeners[key].forEach((cb)=>{
|
|
503
|
+
this.ws.removeEventListener(key, cb);
|
|
504
|
+
});
|
|
440
505
|
this.ws = new WebSocket(this.url);
|
|
441
506
|
this.backoff = 100;
|
|
442
507
|
this.ws.addEventListener('open', ()=>{
|
|
443
508
|
const rl = this.recursion_level;
|
|
444
509
|
this.log.debug(`on open: reconnected (${rl})`);
|
|
445
510
|
this.is_connected = true;
|
|
511
|
+
if (!this.ws) return;
|
|
446
512
|
for(let key in this.event_listeners)this.event_listeners[key].forEach((cb)=>{
|
|
447
|
-
this.
|
|
448
|
-
|
|
513
|
+
if (this.ws) {
|
|
514
|
+
this.log.debug(`adding listener (${rl}): ${key}`);
|
|
515
|
+
this.ws.addEventListener(key, cb);
|
|
516
|
+
}
|
|
449
517
|
});
|
|
450
518
|
});
|
|
451
519
|
this.ws.addEventListener('close', ()=>{
|
|
452
520
|
this.log.debug('connection closed');
|
|
453
521
|
this.is_connected = false;
|
|
454
522
|
this.backoff = Math.min(2 * this.backoff, this.max_timeout);
|
|
455
|
-
this.log.debug(
|
|
456
|
-
setTimeout(()=>{
|
|
523
|
+
this.log.debug(`backoff: ${this.backoff}`);
|
|
524
|
+
this.reconnect_timer = window.setTimeout(()=>{
|
|
457
525
|
if (this.should_reconnect) {
|
|
458
526
|
this.ws = null;
|
|
459
527
|
this.setup();
|
|
460
528
|
}
|
|
461
529
|
}, this.backoff + 50 * Math.random());
|
|
462
530
|
});
|
|
531
|
+
this.ws.addEventListener('error', this.log.error);
|
|
463
532
|
}
|
|
464
533
|
send(data) {
|
|
465
534
|
if (!this.is_connected || !this.ws) throw new Error('not connected');
|
|
466
|
-
this.ws.send(data);
|
|
535
|
+
this.ws.send(JSON.stringify(data));
|
|
467
536
|
}
|
|
468
537
|
onMessage(cb) {
|
|
469
538
|
if (!this.ws) throw new Error('ws is null');
|
|
470
539
|
if (!this.event_listeners.message) this.event_listeners.message = [];
|
|
471
|
-
|
|
472
|
-
const rl = this.recursion_level;
|
|
473
|
-
this.log.debug(`message(${rl}): ${e.data}`);
|
|
474
|
-
cb(e.data);
|
|
475
|
-
});
|
|
476
|
-
this.ws.addEventListener('message', (e)=>{
|
|
540
|
+
const handler = (e)=>{
|
|
477
541
|
const rl = this.recursion_level;
|
|
478
542
|
this.log.debug(`message(${rl}): ${e.data}`);
|
|
479
543
|
cb(e.data);
|
|
480
|
-
}
|
|
544
|
+
};
|
|
545
|
+
this.event_listeners.message.push(handler);
|
|
546
|
+
this.ws.addEventListener('message', handler);
|
|
547
|
+
}
|
|
548
|
+
onJSON(cb) {
|
|
549
|
+
this.onMessage((d)=>cb(JSON.parse(d)));
|
|
481
550
|
}
|
|
482
551
|
on(event, cb) {
|
|
483
552
|
if (!this.ws) throw new Error('ws is null');
|
|
@@ -486,6 +555,7 @@ class ws {
|
|
|
486
555
|
this.ws.addEventListener(event, cb);
|
|
487
556
|
}
|
|
488
557
|
close() {
|
|
558
|
+
if (this.reconnect_timer) clearTimeout(this.reconnect_timer);
|
|
489
559
|
if (!this.is_connected || !this.ws) return;
|
|
490
560
|
this.should_reconnect = false;
|
|
491
561
|
this.ws.close();
|
|
@@ -493,11 +563,12 @@ class ws {
|
|
|
493
563
|
constructor(url, verbose = false){
|
|
494
564
|
network_define_property(this, "url", void 0);
|
|
495
565
|
network_define_property(this, "ws", void 0);
|
|
496
|
-
network_define_property(this, "backoff",
|
|
566
|
+
network_define_property(this, "backoff", 100);
|
|
497
567
|
network_define_property(this, "max_timeout", 10000);
|
|
498
568
|
network_define_property(this, "should_reconnect", true);
|
|
499
569
|
network_define_property(this, "is_connected", false);
|
|
500
570
|
network_define_property(this, "recursion_level", 0);
|
|
571
|
+
network_define_property(this, "reconnect_timer", null);
|
|
501
572
|
network_define_property(this, "log", void 0);
|
|
502
573
|
network_define_property(this, "event_listeners", {});
|
|
503
574
|
this.url = url;
|
|
@@ -525,10 +596,31 @@ class refresh {
|
|
|
525
596
|
this.url = url;
|
|
526
597
|
}
|
|
527
598
|
}
|
|
528
|
-
function get(key) {
|
|
529
|
-
|
|
599
|
+
function get(key, _default) {
|
|
600
|
+
let ret = localStorage.getItem(key);
|
|
601
|
+
if (!ret && _default) {
|
|
602
|
+
ret = _default;
|
|
603
|
+
if ('function' == typeof _default) ret = _default();
|
|
604
|
+
set(key, ret);
|
|
605
|
+
}
|
|
606
|
+
return ret;
|
|
607
|
+
}
|
|
608
|
+
function local_storage_update(key, update1, broadcast = false) {
|
|
609
|
+
const prev = get(key);
|
|
610
|
+
const value = update1(prev);
|
|
611
|
+
if (prev !== value || broadcast) {
|
|
612
|
+
const event = new CustomEvent('@corvid/ls-update', {
|
|
613
|
+
detail: {
|
|
614
|
+
key,
|
|
615
|
+
value
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
document.dispatchEvent(event);
|
|
619
|
+
}
|
|
620
|
+
localStorage.setItem(key, value);
|
|
530
621
|
}
|
|
531
622
|
function set(key, value, broadcast = false) {
|
|
623
|
+
if ('object' == typeof key) return void setObj(key, value, broadcast);
|
|
532
624
|
const prev = get(key);
|
|
533
625
|
if (prev !== value || broadcast) {
|
|
534
626
|
const event = new CustomEvent('@corvid/ls-update', {
|
|
@@ -541,6 +633,21 @@ function set(key, value, broadcast = false) {
|
|
|
541
633
|
}
|
|
542
634
|
localStorage.setItem(key, value);
|
|
543
635
|
}
|
|
636
|
+
function setObj(update, prefix, broadcast = false) {
|
|
637
|
+
const flatten = (ob)=>{
|
|
638
|
+
const ret = {};
|
|
639
|
+
for(let i in ob)if (ob.hasOwnProperty(i)) if ('object' == typeof ob[i] && null !== ob[i]) {
|
|
640
|
+
const flat = flatten(ob[i]);
|
|
641
|
+
for(let x in flat)if (flat.hasOwnProperty(x)) ret[`${i}.${x}`] = flat[x];
|
|
642
|
+
} else ret[i] = ob[i];
|
|
643
|
+
return ret;
|
|
644
|
+
};
|
|
645
|
+
for (let [k, v] of Object.entries(flatten(update))){
|
|
646
|
+
let key = k;
|
|
647
|
+
if (prefix) key = `${prefix}.${k}`;
|
|
648
|
+
set(key, v, broadcast);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
544
651
|
function listen(key, cb) {
|
|
545
652
|
document.addEventListener('@corvid/ls-update', (ev)=>{
|
|
546
653
|
if (ev.detail.key === key || '*' === key) {
|
|
@@ -555,4 +662,7 @@ function listen(key, cb) {
|
|
|
555
662
|
}
|
|
556
663
|
});
|
|
557
664
|
}
|
|
665
|
+
function clear(key) {
|
|
666
|
+
localStorage.removeItem(key);
|
|
667
|
+
}
|
|
558
668
|
export { clipboard, dom_namespaceObject as dom, genID, utils_logLevel as logLevel, logger, local_storage_namespaceObject as ls, network_namespaceObject as network, strings_namespaceObject as strings, style_namespaceObject as style };
|
package/dist/local_storage.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { el } from './dom';
|
|
2
|
-
export declare function get(key: string): any;
|
|
3
|
-
export declare function
|
|
2
|
+
export declare function get(key: string, _default?: any): any;
|
|
3
|
+
export declare function update(key: string, update: (current: any) => any, broadcast?: boolean): void;
|
|
4
|
+
export declare function set(key: string | object, value: any, broadcast?: boolean): void;
|
|
5
|
+
export declare function setObj(update: object, prefix?: string, broadcast?: boolean): void;
|
|
4
6
|
export declare function listen(key: string, cb: (update: {
|
|
5
7
|
key: string;
|
|
6
8
|
value: any;
|
|
7
9
|
}) => void | el): void;
|
|
10
|
+
export declare function clear(key: string): void;
|
package/dist/network.d.ts
CHANGED
|
@@ -44,12 +44,14 @@ export declare class ws {
|
|
|
44
44
|
should_reconnect: boolean;
|
|
45
45
|
is_connected: boolean;
|
|
46
46
|
recursion_level: number;
|
|
47
|
+
reconnect_timer: number | null;
|
|
47
48
|
log: logger;
|
|
48
49
|
event_listeners: Record<string, Array<(data: any) => void>>;
|
|
49
50
|
constructor(url: string, verbose?: boolean);
|
|
50
51
|
setup(): void;
|
|
51
52
|
send(data: any): void;
|
|
52
53
|
onMessage(cb: (data: any) => void): void;
|
|
54
|
+
onJSON(cb: (data: any) => void): void;
|
|
53
55
|
on(event: string, cb: (data: any) => void): void;
|
|
54
56
|
close(): void;
|
|
55
57
|
}
|
package/dist/qr.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface QRCodeConfig {
|
|
2
|
+
text: string;
|
|
3
|
+
size?: number;
|
|
4
|
+
ecLevel?: 'L' | 'M' | 'Q' | 'H';
|
|
5
|
+
minVersion?: number;
|
|
6
|
+
maxVersion?: number;
|
|
7
|
+
quiet?: number;
|
|
8
|
+
radius?: number;
|
|
9
|
+
background?: string | null;
|
|
10
|
+
fill?: string | GradientFill;
|
|
11
|
+
left?: number;
|
|
12
|
+
top?: number;
|
|
13
|
+
}
|
|
14
|
+
interface GradientFill {
|
|
15
|
+
type: 'linear-gradient' | 'radial-gradient';
|
|
16
|
+
position: number[];
|
|
17
|
+
colorStops: Array<[number, string]>;
|
|
18
|
+
}
|
|
19
|
+
export default class QrCreator {
|
|
20
|
+
static render(config: QRCodeConfig, element: HTMLElement | HTMLCanvasElement): void;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
File without changes
|
package/dist/style.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Style *
|
|
3
3
|
**************/
|
|
4
4
|
export declare function cssVar(name: string): string;
|
|
5
|
+
export declare function render(style: Object): string;
|
|
5
6
|
/**
|
|
6
7
|
* Check if the current theme is dark
|
|
7
8
|
*/
|
|
@@ -16,6 +17,10 @@ export declare function onDarkMode(cb: (isDark: boolean) => void): void;
|
|
|
16
17
|
* @param theme - 'light' or 'dark'
|
|
17
18
|
*/
|
|
18
19
|
export declare function switchTheme(theme: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Listen for changes in the dark mode preference
|
|
22
|
+
*/
|
|
23
|
+
export declare function handleThemeSwitch(): void;
|
|
19
24
|
/**
|
|
20
25
|
* Calculate a color gradient
|
|
21
26
|
* @param start - The starting color
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taybart/corvid",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -15,7 +15,12 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"devDependencies": {
|
|
18
|
+
"@happy-dom/global-registrator": "^17.4.7",
|
|
18
19
|
"@rslib/core": "^0.6.2",
|
|
20
|
+
"@testing-library/dom": "^10.4.0",
|
|
21
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
22
|
+
"@types/bun": "^1.2.13",
|
|
23
|
+
"@types/jsdom": "^21.1.7",
|
|
19
24
|
"@types/node": "^22.8.1",
|
|
20
25
|
"typescript": "^5.8.3"
|
|
21
26
|
},
|