enigmatic 0.31.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.31.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,137 +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
- try {
29
- if (typeof value === 'function') {
30
- el.innerHTML = await value();
31
- } else if (value && typeof value.render === 'function') {
32
- el.innerHTML = value.render();
33
- }
34
- } catch (e) {
35
- console.error('Custom element error:', e);
36
- }
37
- });
38
- }, 0);
39
- }
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);
40
14
  return true;
41
15
  }
42
16
  });
43
- Object.defineProperty(window, 'custom', {
44
- get: () => customProxy,
45
- set: (val) => {
46
- Object.keys(val || {}).forEach(key => customProxy[key] = val[key]);
47
- window.initCustomElements();
48
- },
49
- configurable: true
50
- });
17
+ Object.defineProperty(W, 'custom', { get: () => cProx, set: v => Object.assign(cProx, v) });
51
18
 
52
- window.state = new Proxy({}, {
53
- set(obj, prop, value) {
54
- obj[prop] = value
55
- $$(`[data="${prop}"]`).forEach(el => {
56
- console.log('setting', el.tagName);
57
- const f = window.custom?.[el.tagName.toLowerCase()];
58
- if (!f) return;
59
- if(typeof f === 'function') {
60
- el.innerHTML = f(value);
61
- } else if (f && typeof f.render === 'function') {
62
- el.innerHTML = f.render(value);
63
- }
64
- });
65
- 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;
66
24
  }
67
- })
68
- window.get = async function(key) {
69
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`)
70
- return await res.json()
71
- }
72
- window.set = async function(key, value) {
73
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, {
74
- method: 'POST', body: typeof value === 'string' ? value : JSON.stringify(value)
75
- })
76
- return await res.json()
77
- }
78
- window.delete = async function(key) {
79
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, {
80
- method: 'DELETE'
81
- })
82
- return await res.json()
83
- }
84
- window.put = async function(key, body) {
85
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, {
86
- method: 'PUT', body: body instanceof Blob ? body : typeof body === 'string' ? body : JSON.stringify(body)
87
- })
88
- return await res.json()
89
- }
90
- window.purge = async function(key) {
91
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, {
92
- method: 'PURGE'
93
- })
94
- return await res.json()
95
- }
96
- window.list = async function() {
97
- const res = await fetch(`${window.api_url}`, {
98
- method: 'PROPFIND'
99
- })
100
- return await res.json()
101
- }
102
- window.download = async function(key) {
103
- try {
104
- console.log('Downloading with method DOWNLOAD:', key);
105
- const res = await fetch(`${window.api_url}/${encodeURIComponent(key)}`, { method: 'PATCH' });
106
- console.log('Response:', key, res.status, res.statusText);
107
- if (!res.ok) throw new Error('Download failed');
108
- const blob = await res.blob();
109
- const url = URL.createObjectURL(blob);
110
- const a = document.createElement('a');
111
- a.href = url;
112
- 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;
113
51
  a.click();
114
- URL.revokeObjectURL(url);
115
- } catch (err) {
116
- console.error('Download error:', err);
117
- throw err;
118
- }
119
- }
120
- window.login = function() {
121
- window.location.href = `${window.api_url}/login`
122
- }
123
- window.logout = function() {
124
- window.location.href = `${window.api_url}/logout`
125
- }
52
+ URL.revokeObjectURL(a.href);
53
+ },
54
+ initCustomElements: () => Object.keys(W.custom).forEach(t => W.$$(t).forEach(el => ren(el)))
55
+ });
126
56
 
127
- // Auto-initialize on load and watch for new elements
128
- if (document.readyState === 'loading') {
129
- document.addEventListener('DOMContentLoaded', () => {
130
- window.initCustomElements();
131
- // Watch for new custom elements added to DOM
132
- new MutationObserver(() => window.initCustomElements()).observe(document.body, { childList: true, subtree: true });
133
- });
134
- } else {
135
- window.initCustomElements();
136
- new MutationObserver(() => window.initCustomElements()).observe(document.body, { childList: true, subtree: true });
137
- }
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();
@@ -1,3 +1,8 @@
1
- <script src='https://unpkg.com/enigmatic@0.30.0/public/client.js'></script>
1
+ <script src='https://unpkg.com/enigmatic@0.32.0/public/client.js'></script>
2
2
 
3
- <hello-world></hello-world>
3
+ <script>
4
+ window.api_url = 'http://localhost:3000';
5
+ custom.hw = (data) => `Hello ${data}`;
6
+ </script>
7
+
8
+ <hw></hw>