enigmatic 0.30.0 → 0.32.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "enigmatic",
3
- "version": "0.30.0",
3
+ "version": "0.32.0",
4
4
  "unpkg": "./public/client.js",
5
5
  "scripts": {
6
6
  "start": "bun --hot ./bun-server.js",
package/public/client.js CHANGED
@@ -1,127 +1,62 @@
1
- window.api_url = "https://localhost:3000"
2
- window.$ = document.querySelector.bind(document)
3
- window.$$ = document.querySelectorAll.bind(document)
4
- window.$c = (selector) => $0.closest(selector);
1
+ const D = document, W = window, Enc = encodeURIComponent;
5
2
 
6
- // Initialize custom elements
7
- window.initCustomElements = function() {
8
- Object.keys(window.custom || {}).forEach(tagName => {
9
- $$(tagName).forEach(async el => {
10
- const f = window.custom[tagName];
11
- if (typeof f === 'function') {
12
- el.innerHTML = await f();
13
- } else if (f && typeof f.render === 'function') {
14
- el.innerHTML = f.render();
15
- }
16
- });
17
- });
18
- }
3
+ // 1. Unified Render Logic (Handles both State & Custom Elements)
4
+ const ren = async (el, v) => {
5
+ const f = W.custom?.[el.tagName.toLowerCase()];
6
+ if (f) try { el.innerHTML = await (f.render || f)(v) } catch(e) { console.error(e) }
7
+ };
19
8
 
20
- // Make window.custom a Proxy that auto-initializes when properties are added
21
- if (!window.custom) window.custom = {};
22
- const customProxy = new Proxy(window.custom, {
23
- set(target, prop, value) {
24
- target[prop] = value;
25
- if (typeof value === 'function' || (value && typeof value.render === 'function')) {
26
- setTimeout(() => {
27
- $$(prop).forEach(async el => {
28
- if (typeof value === 'function') {
29
- el.innerHTML = await value();
30
- } else {
31
- el.innerHTML = value.render();
32
- }
33
- });
34
- }, 0);
35
- }
9
+ // 2. Proxies setup
10
+ const cProx = new Proxy({}, {
11
+ set(t, p, v) {
12
+ t[p] = v;
13
+ setTimeout(() => W.$$(p).forEach(el => ren(el)), 0);
36
14
  return true;
37
15
  }
38
16
  });
39
- Object.defineProperty(window, 'custom', {
40
- get: () => customProxy,
41
- set: (val) => {
42
- Object.assign(customProxy, val || {});
43
- },
44
- configurable: true
45
- });
17
+ Object.defineProperty(W, 'custom', { get: () => cProx, set: v => Object.assign(cProx, v) });
46
18
 
47
- window.state = new Proxy({}, {
48
- set(obj, prop, value) {
49
- obj[prop] = value
50
- $$(`[data="${prop}"]`).forEach(el => {
51
- console.log('setting', el.tagName);
52
- const f = window.custom?.[el.tagName.toLowerCase()];
53
- if (!f) return;
54
- if(typeof f === 'function') {
55
- el.innerHTML = f(value);
56
- } else if (f && typeof f.render === 'function') {
57
- el.innerHTML = f.render(value);
58
- }
59
- });
60
- return true
19
+ const sProx = new Proxy({}, {
20
+ set(o, p, v) {
21
+ o[p] = v;
22
+ W.$$(`[data="${p}"]`).forEach(el => ren(el, v));
23
+ return true;
61
24
  }
62
- })
63
- window.get = async function(key) {
64
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`)
65
- return await res.json()
66
- }
67
- window.set = async function(key, value) {
68
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, {
69
- method: 'POST', body: typeof value === 'string' ? value : JSON.stringify(value)
70
- })
71
- return await res.json()
72
- }
73
- window.delete = async function(key) {
74
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, {
75
- method: 'DELETE'
76
- })
77
- return await res.json()
78
- }
79
- window.put = async function(key, body) {
80
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, {
81
- method: 'PUT', body: body instanceof Blob ? body : typeof body === 'string' ? body : JSON.stringify(body)
82
- })
83
- return await res.json()
84
- }
85
- window.purge = async function(key) {
86
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, {
87
- method: 'PURGE'
88
- })
89
- return await res.json()
90
- }
91
- window.list = async function() {
92
- const res = await fetch(`${window.api_url}`, {
93
- method: 'PROPFIND'
94
- })
95
- return await res.json()
96
- }
97
- window.download = async function(key) {
98
- try {
99
- console.log('Downloading with method DOWNLOAD:', key);
100
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, { method: 'PATCH' });
101
- console.log('Response:', key, res.status, res.statusText);
102
- if (!res.ok) throw new Error('Download failed');
103
- const blob = await res.blob();
104
- const url = URL.createObjectURL(blob);
105
- const a = document.createElement('a');
106
- a.href = url;
107
- a.download = key;
25
+ });
26
+
27
+ // 3. API & DOM Helpers
28
+ const req = (m, k, b) => fetch(`${W.api_url}/${k ? Enc(k) : ''}`, {
29
+ method: m, body: b instanceof Blob || typeof b === 'string' ? b : JSON.stringify(b)
30
+ });
31
+
32
+ Object.assign(W, {
33
+ $: s => D.querySelector(s),
34
+ $$: s => D.querySelectorAll(s),
35
+ $c: s => $0.closest(s),
36
+ state: sProx,
37
+ get: k => req('GET', k).then(r => r.json()),
38
+ set: (k, v) => req('POST', k, v).then(r => r.json()),
39
+ put: (k, v) => req('PUT', k, v).then(r => r.json()),
40
+ delete: k => req('DELETE', k).then(r => r.json()),
41
+ purge: k => req('PURGE', k).then(r => r.json()),
42
+ list: () => req('PROPFIND').then(r => r.json()),
43
+ login: () => W.location.href = `${W.api_url}/login`,
44
+ logout: () => W.location.href = `${W.api_url}/logout`,
45
+ download: async (k) => {
46
+ const r = await req('PATCH', k);
47
+ if (!r.ok) throw new Error('Download failed');
48
+ const a = D.createElement('a');
49
+ a.href = URL.createObjectURL(await r.blob());
50
+ a.download = k;
108
51
  a.click();
109
- URL.revokeObjectURL(url);
110
- } catch (err) {
111
- console.error('Download error:', err);
112
- throw err;
113
- }
114
- }
115
- window.login = function() {
116
- window.location.href = `${window.api_url}/login`
117
- }
118
- window.logout = function() {
119
- window.location.href = `${window.api_url}/logout`
120
- }
52
+ URL.revokeObjectURL(a.href);
53
+ },
54
+ initCustomElements: () => Object.keys(W.custom).forEach(t => W.$$(t).forEach(el => ren(el)))
55
+ });
121
56
 
122
- // Auto-initialize on load
123
- if (document.readyState === 'loading') {
124
- document.addEventListener('DOMContentLoaded', window.initCustomElements);
125
- } else {
126
- window.initCustomElements();
127
- }
57
+ // 4. Initialization & Observers
58
+ const boot = () => {
59
+ W.initCustomElements();
60
+ new MutationObserver(W.initCustomElements).observe(D.body, { childList: true, subtree: true });
61
+ };
62
+ D.readyState === 'loading' ? D.addEventListener('DOMContentLoaded', boot) : boot();
@@ -0,0 +1,8 @@
1
+ <script src='https://unpkg.com/enigmatic@0.32.0/public/client.js'></script>
2
+
3
+ <script>
4
+ window.api_url = 'http://localhost:3000';
5
+ custom.hw = (data) => `Hello ${data}`;
6
+ </script>
7
+
8
+ <hw></hw>