@taybart/corvid 0.1.10 → 0.1.12

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/dom.d.ts CHANGED
@@ -32,6 +32,7 @@ export declare class el {
32
32
  log: logger;
33
33
  listeners: Record<string, Array<(ev: Event) => void>>;
34
34
  constructor(opts: HTMLElement | string | elOpts, verbose?: boolean);
35
+ static query(query: string, verbose?: boolean): el;
35
36
  /*** dom manipulation ***/
36
37
  value(update?: string): string | el;
37
38
  parent(parent: HTMLElement | el): this;
@@ -49,6 +50,7 @@ export declare class el {
49
50
  addClass(className: string | string[]): this;
50
51
  removeClass(className: string | string[]): this;
51
52
  /*** Templates ***/
53
+ html(content: string): void;
52
54
  render(vars?: {}): string;
53
55
  appendTemplate(template: el, vars: any): void;
54
56
  /*** Events ***/
@@ -64,4 +66,11 @@ export declare class el {
64
66
  * @return The interpolated string
65
67
  */
66
68
  export declare function interpolate(str: string, params: Object): string;
67
- export {};
69
+ declare const _default: {
70
+ el: typeof el;
71
+ els: typeof els;
72
+ ready: typeof ready;
73
+ on: typeof on;
74
+ onKey: typeof onKey;
75
+ };
76
+ export default _default;
package/dist/dom.js ADDED
@@ -0,0 +1,281 @@
1
+ function toKebab(str) {
2
+ return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, (s, ofs)=>(ofs ? '-' : '') + s.toLowerCase());
3
+ }
4
+ function render(style) {
5
+ let s = '';
6
+ Object.entries(style).forEach(([k, v])=>s += `${toKebab(k)}:${v};`);
7
+ return s;
8
+ }
9
+ function _define_property(obj, key, value) {
10
+ if (key in obj) Object.defineProperty(obj, key, {
11
+ value: value,
12
+ enumerable: true,
13
+ configurable: true,
14
+ writable: true
15
+ });
16
+ else obj[key] = value;
17
+ return obj;
18
+ }
19
+ var utils_logLevel = /*#__PURE__*/ function(logLevel) {
20
+ logLevel[logLevel["none"] = -1] = "none";
21
+ logLevel[logLevel["error"] = 0] = "error";
22
+ logLevel[logLevel["warn"] = 1] = "warn";
23
+ logLevel[logLevel["info"] = 2] = "info";
24
+ logLevel[logLevel["debug"] = 3] = "debug";
25
+ logLevel[logLevel["trace"] = 4] = "trace";
26
+ return logLevel;
27
+ }({});
28
+ class logger {
29
+ error(...args) {
30
+ if (this.level >= 0) console.error(`[corvid] ${this.prefix}`, ...args);
31
+ }
32
+ warn(...args) {
33
+ if (this.level >= 1) console.warn(`[corvid] ${this.prefix}`, ...args);
34
+ }
35
+ info(...args) {
36
+ if (this.level >= 2) console.info(`[corvid] ${this.prefix}`, ...args);
37
+ }
38
+ debug(...args) {
39
+ if (this.level >= 3) console.debug(`[corvid] ${this.prefix}`, ...args);
40
+ }
41
+ trace(...args) {
42
+ if (this.level >= 4) console.trace(`[corvid] ${this.prefix}`, ...args);
43
+ }
44
+ log(...args) {
45
+ console.log(`[corvid] ${this.prefix}`, ...args);
46
+ }
47
+ constructor(level = 2, prefix){
48
+ _define_property(this, "level", void 0);
49
+ _define_property(this, "prefix", void 0);
50
+ this.level = level;
51
+ this.prefix = prefix ? `(${prefix}):` : ':';
52
+ if (-1 === this.level) [
53
+ 'error',
54
+ 'warn',
55
+ 'info',
56
+ 'debug',
57
+ 'trace',
58
+ 'log'
59
+ ].forEach((methodName)=>{
60
+ this[methodName] = ()=>{};
61
+ });
62
+ }
63
+ }
64
+ function dom_define_property(obj, key, value) {
65
+ if (key in obj) Object.defineProperty(obj, key, {
66
+ value: value,
67
+ enumerable: true,
68
+ configurable: true,
69
+ writable: true
70
+ });
71
+ else obj[key] = value;
72
+ return obj;
73
+ }
74
+ function ready(cb) {
75
+ window.addEventListener('DOMContentLoaded', cb);
76
+ }
77
+ function on(event, cb) {
78
+ document.addEventListener(event, cb);
79
+ return ()=>{
80
+ document.removeEventListener(event, cb);
81
+ };
82
+ }
83
+ function onKey(key, cb, verbose = false) {
84
+ const log = new logger(verbose ? utils_logLevel.debug : utils_logLevel.none, 'onKey');
85
+ log.debug(`adding ${key} keydown listener`);
86
+ const handler = (ev)=>{
87
+ if (ev.key === key) cb({
88
+ ctrl: ev.ctrlKey,
89
+ alt: ev.altKey,
90
+ meta: ev.metaKey,
91
+ shift: ev.shiftKey
92
+ });
93
+ };
94
+ window.addEventListener('keydown', handler);
95
+ return ()=>{
96
+ log.debug(`removing ${key} listener`);
97
+ window.removeEventListener('keydown', handler);
98
+ };
99
+ }
100
+ function els(query, verbose = false) {
101
+ return Array.from(document.querySelectorAll(query)).map((n)=>new dom_el(n, verbose));
102
+ }
103
+ class dom_el {
104
+ static query(query, verbose = false) {
105
+ return new dom_el(query, verbose);
106
+ }
107
+ value(update) {
108
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
109
+ if (void 0 !== update) {
110
+ if ('value' in this.el) this.el.value = update;
111
+ if ('src' in this.el) this.el.src = update;
112
+ return this;
113
+ }
114
+ if ('value' in this.el) return this.el.value;
115
+ if ('innerText' in this.el) return this.el.innerText;
116
+ if ('innerHTML' in this.el) return this.el.innerHTML;
117
+ this.log.warn(`element (${this.query}) does not contain value, returning empty string`);
118
+ return '';
119
+ }
120
+ parent(parent) {
121
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
122
+ parent.appendChild(this.el);
123
+ return this;
124
+ }
125
+ appendChild(ch) {
126
+ return this.child(ch);
127
+ }
128
+ child(ch) {
129
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
130
+ if (ch instanceof dom_el) this.el.appendChild(ch.el);
131
+ else this.el.appendChild(ch);
132
+ return this;
133
+ }
134
+ prependChild(ch) {
135
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
136
+ if (ch instanceof dom_el) this.el.prepend(ch.el);
137
+ else this.el.prepend(ch);
138
+ return this;
139
+ }
140
+ empty() {
141
+ if (this.el) this.el.innerHTML = '';
142
+ return this;
143
+ }
144
+ content(content, { text = false } = {}) {
145
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
146
+ if (text) this.el.textContent = content;
147
+ else this.el.innerHTML = content;
148
+ return this;
149
+ }
150
+ src(url) {
151
+ if (this.el && 'src' in this.el) this.el.src = url;
152
+ return this;
153
+ }
154
+ style(update, stringify = false) {
155
+ if (this.el) {
156
+ if ('string' == typeof update) this.el.style = update;
157
+ else if ('object' == typeof update) {
158
+ if (!stringify) {
159
+ for (const [k, v] of Object.entries(update))this.el.style[k] = v;
160
+ return;
161
+ }
162
+ const s = render(update);
163
+ this.log.debug(`set style: ${this.el.style} -> ${s}`);
164
+ this.el.style = s;
165
+ }
166
+ }
167
+ return this;
168
+ }
169
+ hasClass(className) {
170
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
171
+ return this.el.classList.contains(className);
172
+ }
173
+ addClass(className) {
174
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
175
+ if ('string' == typeof className) this.el.classList.add(className);
176
+ else for (const sc of className)this.el.classList.add(sc);
177
+ return this;
178
+ }
179
+ removeClass(className) {
180
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
181
+ if ('string' == typeof className) this.el.classList.remove(className);
182
+ else for (const sc of className)this.el.classList.remove(sc);
183
+ return this;
184
+ }
185
+ html(content) {
186
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
187
+ this.el.innerHTML = content;
188
+ }
189
+ render(vars = {}) {
190
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
191
+ try {
192
+ return interpolate(this.el.innerHTML, vars);
193
+ } catch (e) {
194
+ throw new Error(`could not render template ${this.query}: ${e}`);
195
+ }
196
+ }
197
+ appendTemplate(template, vars) {
198
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
199
+ if (!template.el) throw new Error("template does not contain element");
200
+ const tmpl = template.render(vars);
201
+ this.el.insertAdjacentHTML('beforeend', tmpl);
202
+ }
203
+ on(event, cb) {
204
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
205
+ if (!this.listeners[event]) this.listeners[event] = [];
206
+ this.listeners[event].push(cb);
207
+ this.el.addEventListener(event, cb);
208
+ return this;
209
+ }
210
+ listen(event, cb) {
211
+ return this.on(event, cb);
212
+ }
213
+ removeListeners(event) {
214
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
215
+ if (!this.listeners[event]) return this;
216
+ for (const cb of this.listeners[event])this.el.removeEventListener(event, cb);
217
+ this.listeners[event] = [];
218
+ return this;
219
+ }
220
+ constructor(opts, verbose = false){
221
+ dom_define_property(this, "el", void 0);
222
+ dom_define_property(this, "query", '');
223
+ dom_define_property(this, "log", void 0);
224
+ dom_define_property(this, "listeners", {});
225
+ this.log = new logger(verbose ? utils_logLevel.debug : utils_logLevel.none, 'element');
226
+ if ('string' == typeof opts) {
227
+ this.query = opts;
228
+ this.el = document.querySelector(opts);
229
+ return;
230
+ }
231
+ if (opts instanceof HTMLElement) {
232
+ this.log.debug(`using existing element: ${opts}`);
233
+ this.el = opts;
234
+ return;
235
+ }
236
+ const { query, element, type, class: styleClass, style, id, content, parent } = opts;
237
+ if (query) {
238
+ this.log.debug(`using query: ${query}`);
239
+ this.query = query;
240
+ this.el = document.querySelector(query);
241
+ if (!this.el) throw new Error(`no element from query: ${query}`);
242
+ } else if (element) {
243
+ this.log.debug(`using existing element: ${element}`);
244
+ this.el = element;
245
+ } else if (type) {
246
+ this.query = type;
247
+ this.log.debug(`creating element: ${type}`);
248
+ this.el = document.createElement(type);
249
+ } else throw new Error('no query or type provided');
250
+ if (this.el) {
251
+ if (id) {
252
+ this.log.debug(`setting id: ${id}`);
253
+ this.el.id = id;
254
+ }
255
+ if (styleClass) if ('string' == typeof styleClass) this.el.classList.add(styleClass);
256
+ else for (const sc of styleClass)this.el.classList.add(sc);
257
+ if (style) this.style(style);
258
+ if (content) {
259
+ this.log.debug(`setting content: ${content}`);
260
+ this.el.innerHTML = content;
261
+ }
262
+ if (parent) {
263
+ this.log.debug("adding to parent");
264
+ parent.appendChild(this.el);
265
+ }
266
+ }
267
+ }
268
+ }
269
+ function interpolate(str, params) {
270
+ let names = Object.keys(params).map((k)=>`_${k}`);
271
+ let vals = Object.values(params);
272
+ return new Function(...names, `return \`${str.replace(/\$\{(\w*)\}/g, '${_$1}')}\`;`)(...vals);
273
+ }
274
+ const dom = {
275
+ el: dom_el,
276
+ els,
277
+ ready,
278
+ on,
279
+ onKey
280
+ };
281
+ export { dom as default, dom_el as el, els, interpolate, on, onKey, ready };
package/dist/index.js CHANGED
@@ -40,6 +40,7 @@ __webpack_require__.d(style_namespaceObject, {
40
40
  var dom_namespaceObject = {};
41
41
  __webpack_require__.r(dom_namespaceObject);
42
42
  __webpack_require__.d(dom_namespaceObject, {
43
+ default: ()=>dom,
43
44
  el: ()=>dom_el,
44
45
  els: ()=>els,
45
46
  interpolate: ()=>interpolate,
@@ -50,6 +51,7 @@ __webpack_require__.d(dom_namespaceObject, {
50
51
  var network_namespaceObject = {};
51
52
  __webpack_require__.r(network_namespaceObject);
52
53
  __webpack_require__.d(network_namespaceObject, {
54
+ default: ()=>network,
53
55
  params: ()=>network_params,
54
56
  refresh: ()=>refresh,
55
57
  request: ()=>request,
@@ -277,6 +279,9 @@ function els(query, verbose = false) {
277
279
  return Array.from(document.querySelectorAll(query)).map((n)=>new dom_el(n, verbose));
278
280
  }
279
281
  class dom_el {
282
+ static query(query, verbose = false) {
283
+ return new dom_el(query, verbose);
284
+ }
280
285
  value(update) {
281
286
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
282
287
  if (void 0 !== update) {
@@ -355,6 +360,10 @@ class dom_el {
355
360
  else for (const sc of className)this.el.classList.remove(sc);
356
361
  return this;
357
362
  }
363
+ html(content) {
364
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
365
+ this.el.innerHTML = content;
366
+ }
358
367
  render(vars = {}) {
359
368
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
360
369
  try {
@@ -440,6 +449,13 @@ function interpolate(str, params) {
440
449
  let vals = Object.values(params);
441
450
  return new Function(...names, `return \`${str.replace(/\$\{(\w*)\}/g, '${_$1}')}\`;`)(...vals);
442
451
  }
452
+ const dom = {
453
+ el: dom_el,
454
+ els,
455
+ ready,
456
+ on,
457
+ onKey
458
+ };
443
459
  function network_define_property(obj, key, value) {
444
460
  if (key in obj) Object.defineProperty(obj, key, {
445
461
  value: value,
@@ -487,8 +503,9 @@ class request {
487
503
  this.opts.body = body;
488
504
  return this;
489
505
  }
490
- async do({ path, params: passedParams, override } = {}) {
491
- if (this.opts.auth) this.opts.headers.Authorization = `Bearer ${this.opts.auth}`;
506
+ build({ path, params: passedParams, override } = {}) {
507
+ if (this.opts.auth && !this.opts.headers.Authorization) if ('string' == typeof this.opts.auth) this.opts.headers.Authorization = `Bearer ${this.opts.auth}`;
508
+ else this.opts.headers.Authorization = `Basic ${btoa(`${this.opts.auth.username}:${this.opts.auth.password}`)}`;
492
509
  if (!override) override = {};
493
510
  const body = override.body || this.opts.body;
494
511
  let url = this.opts.url;
@@ -501,17 +518,29 @@ class request {
501
518
  this.log.debug(`params: ${reqParams.toString()}`);
502
519
  url = `${url}?${reqParams.toString()}`;
503
520
  }
521
+ override.headers = override.headers || {};
504
522
  this.log.debug(`${this.opts.method} ${url}`);
505
- const res = await fetch(url, {
506
- method: this.opts.method,
507
- credentials: this.opts.credentials,
508
- headers: {
509
- accept: 'application/json',
510
- 'content-type': 'application/json',
511
- ...this.opts.headers
512
- },
513
- body: JSON.stringify(body)
523
+ return {
524
+ url,
525
+ options: {
526
+ method: override.method || this.opts.method,
527
+ credentials: this.opts.credentials,
528
+ headers: {
529
+ ...this.opts.headers,
530
+ ...override.headers
531
+ },
532
+ body: JSON.stringify(body)
533
+ }
534
+ };
535
+ }
536
+ async do({ path, params: passedParams, override = {} } = {}) {
537
+ const { url, options } = this.build({
538
+ path,
539
+ params: passedParams,
540
+ override
514
541
  });
542
+ this.log.debug(`${this.opts.method} ${url}`);
543
+ const res = await fetch(url, options);
515
544
  const success = override.success || this.opts.success;
516
545
  if (res.status !== success) {
517
546
  const body = await res.json();
@@ -637,6 +666,12 @@ class refresh {
637
666
  this.url = url;
638
667
  }
639
668
  }
669
+ const network = {
670
+ params: network_params,
671
+ request,
672
+ ws,
673
+ refresh
674
+ };
640
675
  function get(key, _default) {
641
676
  let ret = localStorage.getItem(key);
642
677
  if (!ret && _default) {
package/dist/network.d.ts CHANGED
@@ -11,27 +11,62 @@ export declare class params {
11
11
  export type requestOpts = {
12
12
  url?: string;
13
13
  type?: 'json';
14
- method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
14
+ method?: 'HEAD' | 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS';
15
15
  params?: Object | params;
16
16
  headers?: Record<string, string>;
17
- auth?: string;
17
+ auth?: string | {
18
+ username: string;
19
+ password: string;
20
+ };
18
21
  body?: Object;
19
22
  success?: number;
20
23
  credentials?: RequestCredentials;
24
+ insecureNoVerify?: boolean;
21
25
  };
22
26
  export declare class request {
23
27
  opts: requestOpts;
24
28
  log: logger;
25
29
  constructor(opts?: requestOpts, verbose?: boolean);
26
- auth(token: string): this;
30
+ auth(token: string | {
31
+ username: string;
32
+ password: string;
33
+ }): this;
27
34
  basicAuth(username: string, password: string): this;
28
35
  body(body: Object): this;
36
+ build({ path, params: passedParams, override, }?: {
37
+ path?: string;
38
+ params?: Object;
39
+ override?: {
40
+ success?: number;
41
+ params?: Object;
42
+ body?: Object;
43
+ headers?: Object;
44
+ method?: string;
45
+ };
46
+ }): {
47
+ url: string;
48
+ options: {
49
+ method: string | undefined;
50
+ credentials: RequestCredentials | undefined;
51
+ headers: {
52
+ constructor: Function;
53
+ toString(): string;
54
+ toLocaleString(): string;
55
+ valueOf(): Object;
56
+ hasOwnProperty(v: PropertyKey): boolean;
57
+ isPrototypeOf(v: Object): boolean;
58
+ propertyIsEnumerable(v: PropertyKey): boolean;
59
+ };
60
+ body: string;
61
+ };
62
+ };
29
63
  do({ path, params: passedParams, override, }?: {
30
64
  path?: string;
31
65
  params?: Object;
32
66
  override?: {
33
67
  success?: number;
34
68
  params?: Object;
69
+ headers?: Object;
35
70
  body?: Object;
36
71
  };
37
72
  }): Promise<any>;
@@ -64,3 +99,10 @@ export declare class refresh {
64
99
  listen(): void;
65
100
  }
66
101
  /*** server sent events ***/
102
+ declare const _default: {
103
+ params: typeof params;
104
+ request: typeof request;
105
+ ws: typeof ws;
106
+ refresh: typeof refresh;
107
+ };
108
+ export default _default;
@@ -0,0 +1,272 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) Object.defineProperty(obj, key, {
3
+ value: value,
4
+ enumerable: true,
5
+ configurable: true,
6
+ writable: true
7
+ });
8
+ else obj[key] = value;
9
+ return obj;
10
+ }
11
+ var utils_logLevel = /*#__PURE__*/ function(logLevel) {
12
+ logLevel[logLevel["none"] = -1] = "none";
13
+ logLevel[logLevel["error"] = 0] = "error";
14
+ logLevel[logLevel["warn"] = 1] = "warn";
15
+ logLevel[logLevel["info"] = 2] = "info";
16
+ logLevel[logLevel["debug"] = 3] = "debug";
17
+ logLevel[logLevel["trace"] = 4] = "trace";
18
+ return logLevel;
19
+ }({});
20
+ class logger {
21
+ error(...args) {
22
+ if (this.level >= 0) console.error(`[corvid] ${this.prefix}`, ...args);
23
+ }
24
+ warn(...args) {
25
+ if (this.level >= 1) console.warn(`[corvid] ${this.prefix}`, ...args);
26
+ }
27
+ info(...args) {
28
+ if (this.level >= 2) console.info(`[corvid] ${this.prefix}`, ...args);
29
+ }
30
+ debug(...args) {
31
+ if (this.level >= 3) console.debug(`[corvid] ${this.prefix}`, ...args);
32
+ }
33
+ trace(...args) {
34
+ if (this.level >= 4) console.trace(`[corvid] ${this.prefix}`, ...args);
35
+ }
36
+ log(...args) {
37
+ console.log(`[corvid] ${this.prefix}`, ...args);
38
+ }
39
+ constructor(level = 2, prefix){
40
+ _define_property(this, "level", void 0);
41
+ _define_property(this, "prefix", void 0);
42
+ this.level = level;
43
+ this.prefix = prefix ? `(${prefix}):` : ':';
44
+ if (-1 === this.level) [
45
+ 'error',
46
+ 'warn',
47
+ 'info',
48
+ 'debug',
49
+ 'trace',
50
+ 'log'
51
+ ].forEach((methodName)=>{
52
+ this[methodName] = ()=>{};
53
+ });
54
+ }
55
+ }
56
+ function network_define_property(obj, key, value) {
57
+ if (key in obj) Object.defineProperty(obj, key, {
58
+ value: value,
59
+ enumerable: true,
60
+ configurable: true,
61
+ writable: true
62
+ });
63
+ else obj[key] = value;
64
+ return obj;
65
+ }
66
+ class network_params {
67
+ set(p) {
68
+ for (let [k, v] of Object.entries(p))this.params.set(k, v);
69
+ return this;
70
+ }
71
+ toString() {
72
+ return this.params.toString();
73
+ }
74
+ static render(p) {
75
+ const params = new URLSearchParams();
76
+ if (p) for (let [k, v] of Object.entries(p))params.set(k, v);
77
+ return params.toString();
78
+ }
79
+ constructor(p){
80
+ network_define_property(this, "params", void 0);
81
+ this.params = new URLSearchParams();
82
+ if (p) for (let [k, v] of Object.entries(p))this.params.set(k, v);
83
+ return this;
84
+ }
85
+ }
86
+ class request {
87
+ auth(token) {
88
+ const header = `Bearer ${token}`;
89
+ this.log.debug(`adding auth token header ${header}`);
90
+ this.opts.headers.Authorization = header;
91
+ return this;
92
+ }
93
+ basicAuth(username, password) {
94
+ const header = `Basic ${btoa(`${username}:${password}`)}`;
95
+ this.log.debug(`adding basic auth header ${header}`);
96
+ this.opts.headers.Authorization = header;
97
+ return this;
98
+ }
99
+ body(body) {
100
+ this.opts.body = body;
101
+ return this;
102
+ }
103
+ build({ path, params: passedParams, override } = {}) {
104
+ if (this.opts.auth && !this.opts.headers.Authorization) if ('string' == typeof this.opts.auth) this.opts.headers.Authorization = `Bearer ${this.opts.auth}`;
105
+ else this.opts.headers.Authorization = `Basic ${btoa(`${this.opts.auth.username}:${this.opts.auth.password}`)}`;
106
+ if (!override) override = {};
107
+ const body = override.body || this.opts.body;
108
+ let url = this.opts.url;
109
+ if (path) url = `${this.opts.url}${path}`;
110
+ let reqParams = this.opts.params;
111
+ if (override.params) reqParams = new network_params(override.params);
112
+ if (passedParams) if (reqParams) reqParams.set(passedParams);
113
+ else reqParams = new network_params(passedParams);
114
+ if (reqParams) {
115
+ this.log.debug(`params: ${reqParams.toString()}`);
116
+ url = `${url}?${reqParams.toString()}`;
117
+ }
118
+ override.headers = override.headers || {};
119
+ this.log.debug(`${this.opts.method} ${url}`);
120
+ return {
121
+ url,
122
+ options: {
123
+ method: override.method || this.opts.method,
124
+ credentials: this.opts.credentials,
125
+ headers: {
126
+ ...this.opts.headers,
127
+ ...override.headers
128
+ },
129
+ body: JSON.stringify(body)
130
+ }
131
+ };
132
+ }
133
+ async do({ path, params: passedParams, override = {} } = {}) {
134
+ const { url, options } = this.build({
135
+ path,
136
+ params: passedParams,
137
+ override
138
+ });
139
+ this.log.debug(`${this.opts.method} ${url}`);
140
+ const res = await fetch(url, options);
141
+ const success = override.success || this.opts.success;
142
+ if (res.status !== success) {
143
+ const body = await res.json();
144
+ throw new Error(`bad response ${res.status} !== ${success}, body: ${body}`);
145
+ }
146
+ return await res.json();
147
+ }
148
+ constructor(opts = {}, verbose = false){
149
+ network_define_property(this, "opts", void 0);
150
+ network_define_property(this, "log", void 0);
151
+ this.log = new logger(verbose ? utils_logLevel.debug : utils_logLevel.none, 'request');
152
+ if (opts.type && 'json' !== opts.type) throw new Error('this class only provides json requests');
153
+ if (!opts.url) throw new Error('must provide url');
154
+ this.opts = opts;
155
+ if (!this.opts.success) this.opts.success = 200;
156
+ if (!this.opts.method) this.opts.method = 'GET';
157
+ if (!this.opts.headers) this.opts.headers = {};
158
+ if (!this.opts.credentials) this.opts.credentials = 'omit';
159
+ if (this.opts.params && !(this.opts.params instanceof network_params)) {
160
+ this.log.debug("converting object params to class");
161
+ this.opts.params = new network_params(this.opts.params);
162
+ }
163
+ this.log.debug(`with options: ${JSON.stringify(this.opts)}`);
164
+ }
165
+ }
166
+ class ws {
167
+ setup() {
168
+ this.recursion_level += 1;
169
+ if (this.ws) for(let key in this.event_listeners)this.event_listeners[key].forEach((cb)=>{
170
+ this.ws.removeEventListener(key, cb);
171
+ });
172
+ this.ws = new WebSocket(this.url);
173
+ this.backoff = 100;
174
+ this.ws.addEventListener('open', ()=>{
175
+ const rl = this.recursion_level;
176
+ this.log.debug(`on open: reconnected (${rl})`);
177
+ this.is_connected = true;
178
+ if (!this.ws) return;
179
+ for(let key in this.event_listeners)this.event_listeners[key].forEach((cb)=>{
180
+ if (this.ws) {
181
+ this.log.debug(`adding listener (${rl}): ${key}`);
182
+ this.ws.addEventListener(key, cb);
183
+ }
184
+ });
185
+ });
186
+ this.ws.addEventListener('close', ()=>{
187
+ this.log.debug('connection closed');
188
+ this.is_connected = false;
189
+ this.backoff = Math.min(2 * this.backoff, this.max_timeout);
190
+ this.log.debug(`backoff: ${this.backoff}`);
191
+ this.reconnect_timer = window.setTimeout(()=>{
192
+ if (this.should_reconnect) {
193
+ this.ws = null;
194
+ this.setup();
195
+ }
196
+ }, this.backoff + 50 * Math.random());
197
+ });
198
+ this.ws.addEventListener('error', this.log.error);
199
+ }
200
+ send(data) {
201
+ if (!this.is_connected || !this.ws) throw new Error('not connected');
202
+ this.ws.send(JSON.stringify(data));
203
+ }
204
+ onMessage(cb) {
205
+ if (!this.ws) throw new Error('ws is null');
206
+ if (!this.event_listeners.message) this.event_listeners.message = [];
207
+ const handler = (e)=>{
208
+ const rl = this.recursion_level;
209
+ this.log.debug(`message(${rl}): ${e.data}`);
210
+ cb(e.data);
211
+ };
212
+ this.event_listeners.message.push(handler);
213
+ this.ws.addEventListener('message', handler);
214
+ }
215
+ onJSON(cb) {
216
+ this.onMessage((d)=>cb(JSON.parse(d)));
217
+ }
218
+ on(event, cb) {
219
+ if (!this.ws) throw new Error('ws is null');
220
+ if (!this.event_listeners[event]) this.event_listeners[event] = [];
221
+ this.event_listeners[event].push(cb);
222
+ this.ws.addEventListener(event, cb);
223
+ }
224
+ close() {
225
+ if (this.reconnect_timer) clearTimeout(this.reconnect_timer);
226
+ if (!this.is_connected || !this.ws) return;
227
+ this.should_reconnect = false;
228
+ this.ws.close();
229
+ }
230
+ constructor(url, verbose = false){
231
+ network_define_property(this, "url", void 0);
232
+ network_define_property(this, "ws", void 0);
233
+ network_define_property(this, "backoff", 100);
234
+ network_define_property(this, "max_timeout", 10000);
235
+ network_define_property(this, "should_reconnect", true);
236
+ network_define_property(this, "is_connected", false);
237
+ network_define_property(this, "recursion_level", 0);
238
+ network_define_property(this, "reconnect_timer", null);
239
+ network_define_property(this, "log", void 0);
240
+ network_define_property(this, "event_listeners", {});
241
+ this.url = url;
242
+ this.ws = null;
243
+ this.log = new logger(verbose ? utils_logLevel.debug : utils_logLevel.none, 'websocket');
244
+ this.setup();
245
+ }
246
+ }
247
+ class refresh {
248
+ listen() {
249
+ const socket = new ws(this.url);
250
+ if (socket) {
251
+ socket.on('open', ()=>{
252
+ if (this.should_reload) location.reload();
253
+ });
254
+ socket.on('close', ()=>{
255
+ this.should_reload = true;
256
+ setTimeout(this.listen, 500);
257
+ });
258
+ }
259
+ }
260
+ constructor(url){
261
+ network_define_property(this, "url", void 0);
262
+ network_define_property(this, "should_reload", false);
263
+ this.url = url;
264
+ }
265
+ }
266
+ const network = {
267
+ params: network_params,
268
+ request,
269
+ ws,
270
+ refresh
271
+ };
272
+ export { network as default, network_params as params, refresh, request, ws };
@@ -1,3 +1,4 @@
1
+ import { el } from '../dom.ts';
1
2
  export interface QRCodeConfig {
2
3
  text: string;
3
4
  size?: number;
@@ -24,7 +25,7 @@ export interface QRCode {
24
25
  isDark: (row: number, col: number) => boolean;
25
26
  }
26
27
  export declare class QR {
27
- static render(config: QRCodeConfig, element: HTMLElement | HTMLCanvasElement): void;
28
+ static render(config: QRCodeConfig, element: el | HTMLElement | HTMLCanvasElement): void;
28
29
  private static getDefaultSettings;
29
30
  private static createQRCode;
30
31
  private static createMinQRCode;
package/dist/qr.js CHANGED
@@ -1904,11 +1904,256 @@ const QRErrorCorrectLevel = {
1904
1904
  Q: 3,
1905
1905
  H: 2
1906
1906
  };
1907
+ function toKebab(str) {
1908
+ return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, (s, ofs)=>(ofs ? '-' : '') + s.toLowerCase());
1909
+ }
1910
+ function render(style) {
1911
+ let s = '';
1912
+ Object.entries(style).forEach(([k, v])=>s += `${toKebab(k)}:${v};`);
1913
+ return s;
1914
+ }
1915
+ function utils_define_property(obj, key, value) {
1916
+ if (key in obj) Object.defineProperty(obj, key, {
1917
+ value: value,
1918
+ enumerable: true,
1919
+ configurable: true,
1920
+ writable: true
1921
+ });
1922
+ else obj[key] = value;
1923
+ return obj;
1924
+ }
1925
+ var utils_logLevel = /*#__PURE__*/ function(logLevel) {
1926
+ logLevel[logLevel["none"] = -1] = "none";
1927
+ logLevel[logLevel["error"] = 0] = "error";
1928
+ logLevel[logLevel["warn"] = 1] = "warn";
1929
+ logLevel[logLevel["info"] = 2] = "info";
1930
+ logLevel[logLevel["debug"] = 3] = "debug";
1931
+ logLevel[logLevel["trace"] = 4] = "trace";
1932
+ return logLevel;
1933
+ }({});
1934
+ class utils_logger {
1935
+ error(...args) {
1936
+ if (this.level >= 0) console.error(`[corvid] ${this.prefix}`, ...args);
1937
+ }
1938
+ warn(...args) {
1939
+ if (this.level >= 1) console.warn(`[corvid] ${this.prefix}`, ...args);
1940
+ }
1941
+ info(...args) {
1942
+ if (this.level >= 2) console.info(`[corvid] ${this.prefix}`, ...args);
1943
+ }
1944
+ debug(...args) {
1945
+ if (this.level >= 3) console.debug(`[corvid] ${this.prefix}`, ...args);
1946
+ }
1947
+ trace(...args) {
1948
+ if (this.level >= 4) console.trace(`[corvid] ${this.prefix}`, ...args);
1949
+ }
1950
+ log(...args) {
1951
+ console.log(`[corvid] ${this.prefix}`, ...args);
1952
+ }
1953
+ constructor(level = 2, prefix){
1954
+ utils_define_property(this, "level", void 0);
1955
+ utils_define_property(this, "prefix", void 0);
1956
+ this.level = level;
1957
+ this.prefix = prefix ? `(${prefix}):` : ':';
1958
+ if (-1 === this.level) [
1959
+ 'error',
1960
+ 'warn',
1961
+ 'info',
1962
+ 'debug',
1963
+ 'trace',
1964
+ 'log'
1965
+ ].forEach((methodName)=>{
1966
+ this[methodName] = ()=>{};
1967
+ });
1968
+ }
1969
+ }
1970
+ function dom_define_property(obj, key, value) {
1971
+ if (key in obj) Object.defineProperty(obj, key, {
1972
+ value: value,
1973
+ enumerable: true,
1974
+ configurable: true,
1975
+ writable: true
1976
+ });
1977
+ else obj[key] = value;
1978
+ return obj;
1979
+ }
1980
+ class dom_el {
1981
+ static query(query, verbose = false) {
1982
+ return new dom_el(query, verbose);
1983
+ }
1984
+ value(update) {
1985
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
1986
+ if (void 0 !== update) {
1987
+ if ('value' in this.el) this.el.value = update;
1988
+ if ('src' in this.el) this.el.src = update;
1989
+ return this;
1990
+ }
1991
+ if ('value' in this.el) return this.el.value;
1992
+ if ('innerText' in this.el) return this.el.innerText;
1993
+ if ('innerHTML' in this.el) return this.el.innerHTML;
1994
+ this.log.warn(`element (${this.query}) does not contain value, returning empty string`);
1995
+ return '';
1996
+ }
1997
+ parent(parent) {
1998
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
1999
+ parent.appendChild(this.el);
2000
+ return this;
2001
+ }
2002
+ appendChild(ch) {
2003
+ return this.child(ch);
2004
+ }
2005
+ child(ch) {
2006
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2007
+ if (ch instanceof dom_el) this.el.appendChild(ch.el);
2008
+ else this.el.appendChild(ch);
2009
+ return this;
2010
+ }
2011
+ prependChild(ch) {
2012
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2013
+ if (ch instanceof dom_el) this.el.prepend(ch.el);
2014
+ else this.el.prepend(ch);
2015
+ return this;
2016
+ }
2017
+ empty() {
2018
+ if (this.el) this.el.innerHTML = '';
2019
+ return this;
2020
+ }
2021
+ content(content, { text = false } = {}) {
2022
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2023
+ if (text) this.el.textContent = content;
2024
+ else this.el.innerHTML = content;
2025
+ return this;
2026
+ }
2027
+ src(url) {
2028
+ if (this.el && 'src' in this.el) this.el.src = url;
2029
+ return this;
2030
+ }
2031
+ style(update, stringify = false) {
2032
+ if (this.el) {
2033
+ if ('string' == typeof update) this.el.style = update;
2034
+ else if ('object' == typeof update) {
2035
+ if (!stringify) {
2036
+ for (const [k, v] of Object.entries(update))this.el.style[k] = v;
2037
+ return;
2038
+ }
2039
+ const s = render(update);
2040
+ this.log.debug(`set style: ${this.el.style} -> ${s}`);
2041
+ this.el.style = s;
2042
+ }
2043
+ }
2044
+ return this;
2045
+ }
2046
+ hasClass(className) {
2047
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2048
+ return this.el.classList.contains(className);
2049
+ }
2050
+ addClass(className) {
2051
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2052
+ if ('string' == typeof className) this.el.classList.add(className);
2053
+ else for (const sc of className)this.el.classList.add(sc);
2054
+ return this;
2055
+ }
2056
+ removeClass(className) {
2057
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2058
+ if ('string' == typeof className) this.el.classList.remove(className);
2059
+ else for (const sc of className)this.el.classList.remove(sc);
2060
+ return this;
2061
+ }
2062
+ html(content) {
2063
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2064
+ this.el.innerHTML = content;
2065
+ }
2066
+ render(vars = {}) {
2067
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2068
+ try {
2069
+ return interpolate(this.el.innerHTML, vars);
2070
+ } catch (e) {
2071
+ throw new Error(`could not render template ${this.query}: ${e}`);
2072
+ }
2073
+ }
2074
+ appendTemplate(template, vars) {
2075
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2076
+ if (!template.el) throw new Error("template does not contain element");
2077
+ const tmpl = template.render(vars);
2078
+ this.el.insertAdjacentHTML('beforeend', tmpl);
2079
+ }
2080
+ on(event, cb) {
2081
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2082
+ if (!this.listeners[event]) this.listeners[event] = [];
2083
+ this.listeners[event].push(cb);
2084
+ this.el.addEventListener(event, cb);
2085
+ return this;
2086
+ }
2087
+ listen(event, cb) {
2088
+ return this.on(event, cb);
2089
+ }
2090
+ removeListeners(event) {
2091
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2092
+ if (!this.listeners[event]) return this;
2093
+ for (const cb of this.listeners[event])this.el.removeEventListener(event, cb);
2094
+ this.listeners[event] = [];
2095
+ return this;
2096
+ }
2097
+ constructor(opts, verbose = false){
2098
+ dom_define_property(this, "el", void 0);
2099
+ dom_define_property(this, "query", '');
2100
+ dom_define_property(this, "log", void 0);
2101
+ dom_define_property(this, "listeners", {});
2102
+ this.log = new utils_logger(verbose ? utils_logLevel.debug : utils_logLevel.none, 'element');
2103
+ if ('string' == typeof opts) {
2104
+ this.query = opts;
2105
+ this.el = document.querySelector(opts);
2106
+ return;
2107
+ }
2108
+ if (opts instanceof HTMLElement) {
2109
+ this.log.debug(`using existing element: ${opts}`);
2110
+ this.el = opts;
2111
+ return;
2112
+ }
2113
+ const { query, element, type, class: styleClass, style, id, content, parent } = opts;
2114
+ if (query) {
2115
+ this.log.debug(`using query: ${query}`);
2116
+ this.query = query;
2117
+ this.el = document.querySelector(query);
2118
+ if (!this.el) throw new Error(`no element from query: ${query}`);
2119
+ } else if (element) {
2120
+ this.log.debug(`using existing element: ${element}`);
2121
+ this.el = element;
2122
+ } else if (type) {
2123
+ this.query = type;
2124
+ this.log.debug(`creating element: ${type}`);
2125
+ this.el = document.createElement(type);
2126
+ } else throw new Error('no query or type provided');
2127
+ if (this.el) {
2128
+ if (id) {
2129
+ this.log.debug(`setting id: ${id}`);
2130
+ this.el.id = id;
2131
+ }
2132
+ if (styleClass) if ('string' == typeof styleClass) this.el.classList.add(styleClass);
2133
+ else for (const sc of styleClass)this.el.classList.add(sc);
2134
+ if (style) this.style(style);
2135
+ if (content) {
2136
+ this.log.debug(`setting content: ${content}`);
2137
+ this.el.innerHTML = content;
2138
+ }
2139
+ if (parent) {
2140
+ this.log.debug("adding to parent");
2141
+ parent.appendChild(this.el);
2142
+ }
2143
+ }
2144
+ }
2145
+ }
2146
+ function interpolate(str, params) {
2147
+ let names = Object.keys(params).map((k)=>`_${k}`);
2148
+ let vals = Object.values(params);
2149
+ return new Function(...names, `return \`${str.replace(/\$\{(\w*)\}/g, '${_$1}')}\`;`)(...vals);
2150
+ }
1907
2151
  class QR {
1908
2152
  static render(config, element) {
1909
2153
  const settings = this.getDefaultSettings(config);
1910
2154
  if (element instanceof HTMLCanvasElement) this.renderToCanvas(element, settings);
1911
2155
  else {
2156
+ if (element instanceof dom_el) element = element.el;
1912
2157
  const canvas = this.createCanvas(settings);
1913
2158
  element.appendChild(canvas);
1914
2159
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taybart/corvid",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
@@ -8,6 +8,14 @@
8
8
  "types": "./dist/index.d.ts",
9
9
  "import": "./dist/index.js"
10
10
  },
11
+ "./dom": {
12
+ "types": "./dist/dom.d.ts",
13
+ "import": "./dist/dom.js"
14
+ },
15
+ "./network": {
16
+ "types": "./dist/network.d.ts",
17
+ "import": "./dist/network.js"
18
+ },
11
19
  "./qr": {
12
20
  "types": "./dist/qr.d.ts",
13
21
  "import": "./dist/qr.js"