@dinoreic/fez 0.2.2 → 0.3.2

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,197 @@
1
+ // Utility functions that extend Fez
2
+ export default (Fez) => {
3
+ // Script from URL
4
+ // Fez.head({ js: 'https://example.com/script.js' });
5
+ // Script with attributes
6
+ // Fez.head({ js: 'https://example.com/script.js', type: 'module', async: true });
7
+ // Script with callback
8
+ // Fez.head({ js: 'https://example.com/script.js' }, () => { console.log('loaded') });
9
+ // Module loading with auto-import to window
10
+ // Fez.head({ js: 'https://example.com/module.js', module: 'MyModule' }); // imports and sets window.MyModule
11
+ // CSS inclusion
12
+ // Fez.head({ css: 'https://example.com/styles.css' });
13
+ // CSS with additional attributes and callback
14
+ // Fez.head({ css: 'https://example.com/styles.css', media: 'print' }, () => { console.log('CSS loaded') })
15
+ // Inline script evaluation
16
+ // Fez.head({ script: 'console.log("Hello world")' })
17
+ // Extract from nodes
18
+ // Fez.head(domNode)
19
+ Fez.head = (config, callback) => {
20
+ if (config.nodeName) {
21
+ if (config.nodeName == 'SCRIPT') {
22
+ Fez.head({script: config.innerText})
23
+ config.remove()
24
+ } else {
25
+ config.querySelectorAll('script').forEach((n) => Fez.head(n) )
26
+ config.querySelectorAll('template[fez], xmp[fez], script[fez]').forEach((n) => Fez.compile(n) )
27
+ }
28
+
29
+ return
30
+ }
31
+
32
+ if (typeof config !== 'object' || config === null) {
33
+ throw new Error('head requires an object parameter');
34
+ }
35
+
36
+ let src, attributes = {}, elementType;
37
+
38
+ if (config.script) {
39
+ if (config.script.includes('import ')) {
40
+ if (callback) {
41
+ Fez.error('Fez.head callback is not supported when script with import is passed (module context).')
42
+ }
43
+
44
+ // Evaluate inline script in context in the module
45
+ const script = document.createElement('script');
46
+ script.type = 'module';
47
+ script.textContent = config.script;
48
+ document.head.appendChild(script);
49
+ setTimeout(()=>script.remove(), 100)
50
+ } else {
51
+ try {
52
+ new Function(config.script)();
53
+ if (callback) callback();
54
+ } catch (error) {
55
+ Fez.error('Error executing script:', error);
56
+ console.log(config.script);
57
+ }
58
+ }
59
+ return;
60
+ } else if (config.js) {
61
+ src = config.js;
62
+ elementType = 'script';
63
+ // Copy all properties except 'js' as attributes
64
+ for (const [key, value] of Object.entries(config)) {
65
+ if (key !== 'js' && key !== 'module') {
66
+ attributes[key] = value;
67
+ }
68
+ }
69
+ // Handle module loading
70
+ if (config.module) {
71
+ attributes.type = 'module';
72
+ }
73
+ } else if (config.css) {
74
+ src = config.css;
75
+ elementType = 'link';
76
+ attributes.rel = 'stylesheet';
77
+ // Copy all properties except 'css' as attributes
78
+ for (const [key, value] of Object.entries(config)) {
79
+ if (key !== 'css') {
80
+ attributes[key] = value;
81
+ }
82
+ }
83
+ } else {
84
+ throw new Error('head requires either "script", "js" or "css" property');
85
+ }
86
+
87
+ const existingNode = document.querySelector(`${elementType}[src="${src}"], ${elementType}[href="${src}"]`);
88
+ if (existingNode) {
89
+ if (callback) callback();
90
+ return existingNode;
91
+ }
92
+
93
+ const element = document.createElement(elementType);
94
+
95
+ if (elementType === 'link') {
96
+ element.href = src;
97
+ } else {
98
+ element.src = src;
99
+ }
100
+
101
+ for (const [key, value] of Object.entries(attributes)) {
102
+ element.setAttribute(key, value);
103
+ }
104
+
105
+ if (callback || config.module) {
106
+ element.onload = () => {
107
+ // If module name is provided, import it and assign to window
108
+ if (config.module && elementType === 'script') {
109
+ import(src).then(module => {
110
+ window[config.module] = module.default || module[config.module] || module;
111
+ }).catch(error => {
112
+ console.error(`Error importing module ${config.module}:`, error);
113
+ });
114
+ }
115
+ if (callback) callback();
116
+ };
117
+ }
118
+
119
+ document.head.appendChild(element);
120
+
121
+ return element;
122
+ }
123
+
124
+ Fez.darkenColor = (color, percent = 20) => {
125
+ // Convert hex to RGB
126
+ const num = parseInt(color.replace("#", ""), 16)
127
+ const amt = Math.round(2.55 * percent)
128
+ const R = (num >> 16) - amt
129
+ const G = (num >> 8 & 0x00FF) - amt
130
+ const B = (num & 0x0000FF) - amt
131
+ return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 + (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1)
132
+ }
133
+
134
+ Fez.lightenColor = (color, percent = 20) => {
135
+ // Convert hex to RGB
136
+ const num = parseInt(color.replace("#", ""), 16)
137
+ const amt = Math.round(2.55 * percent)
138
+ const R = (num >> 16) + amt
139
+ const G = (num >> 8 & 0x00FF) + amt
140
+ const B = (num & 0x0000FF) + amt
141
+ return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 + (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1)
142
+ }
143
+
144
+ Fez.htmlEscape = (text) => {
145
+ if (typeof text == 'string') {
146
+ text = text
147
+ // .replaceAll('&', "&amp;")
148
+ .replace(/font-family\s*:\s*(?:&[^;]+;|[^;])*?;/gi, '')
149
+ .replaceAll("&", '&amp;')
150
+ .replaceAll("'", '&apos;')
151
+ .replaceAll('"', '&quot;')
152
+ .replaceAll('<', '&lt;')
153
+ .replaceAll('>', '&gt;')
154
+ // .replaceAll('@', '&#64;') // needed for template escaping
155
+
156
+ return text
157
+ } else {
158
+ return text === undefined ? '' : text
159
+ }
160
+ }
161
+
162
+ // create dom root and return it
163
+ Fez.domRoot = (data, name = 'div') => {
164
+ if (data instanceof Node) {
165
+ return data
166
+ } else {
167
+ const root = document.createElement(name)
168
+ root.innerHTML = data
169
+ return root
170
+ }
171
+ }
172
+
173
+ // add class by name to node and remove it from siblings
174
+ Fez.activateNode = (node, klass = 'active') => {
175
+ Array.from(node.parentElement.children).forEach(child => {
176
+ child.classList.remove(klass)
177
+ })
178
+ node.classList.add(klass)
179
+ }
180
+
181
+ Fez.isTrue = (val) => {
182
+ return ['1', 'true', 'on'].includes(String(val).toLowerCase())
183
+ }
184
+
185
+ // Resolve a function from a string or function reference
186
+ Fez.getFunction = (pointer) => {
187
+ if (!pointer) {
188
+ return ()=>{}
189
+ }
190
+ else if (typeof pointer === 'function') {
191
+ return pointer;
192
+ }
193
+ else if (typeof pointer === 'string') {
194
+ return new Function(pointer);
195
+ }
196
+ }
197
+ }
@@ -1,5 +1,5 @@
1
1
  // pretty print HTML
2
- const LOG_PP = (html) => {
2
+ const log_pretty_print = (html) => {
3
3
  const parts = html
4
4
  .split(/(<\/?[^>]+>)/g)
5
5
  .map(p => p.trim())
@@ -55,50 +55,58 @@ const LOG = (() => {
55
55
  const logTypes = []; // Track the original type of each log
56
56
  let currentIndex = 0;
57
57
 
58
- return o => {
59
- if (!document.body) {
60
- window.requestAnimationFrame( () => LOG(o) )
61
- return
62
- }
63
-
64
- if (o instanceof Node) {
65
- o = LOG_PP(o.outerHTML)
66
- }
67
-
68
- // Store the original type
69
- let originalType = typeof o;
70
-
71
- if (o === undefined) { o = 'undefined' }
72
- if (o === null) { o = 'null' }
73
-
74
- if (Array.isArray(o)) {
75
- originalType = 'array';
76
- } else if (typeof o === 'object' && o !== null) {
77
- originalType = 'object';
58
+ // Add ESC key handler
59
+ document.addEventListener('keydown', (e) => {
60
+ if (e.key === 'Escape') {
61
+ e.preventDefault();
62
+ const dialog = document.getElementById('dump-dialog');
63
+ const button = document.getElementById('log-reopen-button');
64
+
65
+ if (dialog) {
66
+ // Close dialog
67
+ dialog.remove();
68
+ localStorage.setItem('_LOG_CLOSED', 'true');
69
+ createLogButton();
70
+ } else if (button) {
71
+ // Open dialog
72
+ button.remove();
73
+ localStorage.setItem('_LOG_CLOSED', 'false');
74
+ showLogDialog();
75
+ }
78
76
  }
79
-
80
- if (typeof o != 'string') {
81
- o = JSON.stringify(o, (key, value) => {
82
- if (typeof value === 'function') {
83
- return String(value);
84
- }
85
- return value;
86
- }, 2).replaceAll('<', '&lt;')
77
+ });
78
+
79
+ const createLogButton = () => {
80
+ let btn = document.getElementById('log-reopen-button');
81
+ if (!btn) {
82
+ btn = document.body.appendChild(document.createElement('button'));
83
+ btn.id = 'log-reopen-button';
84
+ btn.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:4px"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>LOG';
85
+ btn.style.cssText =
86
+ 'position:fixed; top: 10px; right: 10px;' +
87
+ 'padding:10px 20px;background:#ff3333;color:#fff;border:none;' +
88
+ 'cursor:pointer;font:14px/1.4 monospace;z-index:2147483647;' +
89
+ 'border-radius:8px;display:flex;align-items:center;' +
90
+ 'opacity:1;visibility:visible;box-shadow:0 4px 12px rgba(255,51,51,0.3)';
91
+ btn.onclick = () => {
92
+ btn.remove();
93
+ localStorage.setItem('_LOG_CLOSED', 'false');
94
+ showLogDialog();
95
+ };
87
96
  }
97
+ };
88
98
 
89
- o = o.trim()
90
-
91
- logs.push(o + `\n\ntype: ${originalType}`);
92
- logTypes.push(originalType);
93
-
99
+ const showLogDialog = () => {
94
100
  let d = document.getElementById('dump-dialog');
95
101
  if (!d) {
96
102
  d = document.body.appendChild(document.createElement('div'));
97
103
  d.id = 'dump-dialog';
104
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
98
105
  d.style.cssText =
99
- 'position:fixed;top:30px;left:30px;right:50px;bottom:50px;' +
100
- 'background:#fff;border:1px solid#333;box-shadow:0 0 10px rgba(0,0,0,0.5);' +
101
- 'padding:20px;overflow:auto;z-index:9999;font:13px/1.4 monospace;white-space:pre';
106
+ 'position:absolute; top:' + (scrollTop + 20) + 'px; left: 20px; right:20px;' +
107
+ 'background:#fff; border:1px solid #333; box-shadow:0 0 10px rgba(0,0,0,0.5);' +
108
+ 'padding:20px; overflow:auto; z-index:2147483646; font:13px/1.4 monospace;' +
109
+ 'white-space:pre; display:block; opacity:1; visibility:visible';
102
110
  }
103
111
 
104
112
  // Check if we have a saved index and it's still valid
@@ -119,7 +127,7 @@ const LOG = (() => {
119
127
  bgColor = '#d8d5ef'; // super light indigo
120
128
  }
121
129
  }
122
- return `<button style="padding:4px 8px;margin:0;cursor:pointer;background:${i === currentIndex ? '#333' : bgColor};color:${i === currentIndex ? '#fff' : '#000'}" data-index="${i}">${i + 1}</button>`
130
+ return `<button style="font-size: 14px; font-weight: 400; padding:2px 6px; margin: 0 2px 2px 0;cursor:pointer;background:${i === currentIndex ? '#333' : bgColor};color:${i === currentIndex ? '#fff' : '#000'}" data-index="${i}">${i + 1}</button>`
123
131
  }).join('');
124
132
 
125
133
  d.innerHTML =
@@ -128,10 +136,14 @@ const LOG = (() => {
128
136
  '<div style="display:flex;flex-wrap:wrap;gap:4px;flex:1;margin-right:10px">' + buttons + '</div>' +
129
137
  '<button style="padding:4px 8px;cursor:pointer;flex-shrink:0">&times;</button>' +
130
138
  '</div>' +
131
- '<xmp style="flex:1;overflow:auto;margin:0;padding:0;color:#000;background:#fff;font-size:14px;line-height:22px">' + logs[currentIndex] + '</xmp>' +
139
+ '<xmp style="font-family:monospace;flex:1;overflow:auto;margin:0;padding:0;color:#000;background:#fff;font-size:14px;line-height:22px">' + logs[currentIndex] + '</xmp>' +
132
140
  '</div>';
133
141
 
134
- d.querySelector('button[style*="flex-shrink:0"]').onclick = () => d.remove();
142
+ d.querySelector('button[style*="flex-shrink:0"]').onclick = () => {
143
+ d.remove();
144
+ localStorage.setItem('_LOG_CLOSED', 'true');
145
+ createLogButton();
146
+ };
135
147
 
136
148
  d.querySelectorAll('button[data-index]').forEach(btn => {
137
149
  btn.onclick = () => {
@@ -144,11 +156,56 @@ const LOG = (() => {
144
156
 
145
157
  renderContent();
146
158
  };
159
+
160
+ return o => {
161
+ if (!document.body) {
162
+ window.requestAnimationFrame( () => LOG(o) )
163
+ return
164
+ }
165
+
166
+ if (o instanceof Node) {
167
+ o = log_pretty_print(o.outerHTML)
168
+ }
169
+
170
+ // Store the original type
171
+ let originalType = typeof o;
172
+
173
+ if (o === undefined) { o = 'undefined' }
174
+ if (o === null) { o = 'null' }
175
+
176
+ if (Array.isArray(o)) {
177
+ originalType = 'array';
178
+ } else if (typeof o === 'object' && o !== null) {
179
+ originalType = 'object';
180
+ }
181
+
182
+ if (typeof o != 'string') {
183
+ o = JSON.stringify(o, (key, value) => {
184
+ if (typeof value === 'function') {
185
+ return String(value);
186
+ }
187
+ return value;
188
+ }, 2).replaceAll('<', '&lt;')
189
+ }
190
+
191
+ o = o.trim()
192
+
193
+ logs.push(o + `\n\ntype: ${originalType}`);
194
+ logTypes.push(originalType);
195
+
196
+ // Check if log was previously closed
197
+ const isClosed = localStorage.getItem('_LOG_CLOSED') === 'true';
198
+
199
+ if (isClosed) {
200
+ createLogButton();
201
+ } else {
202
+ showLogDialog();
203
+ }
204
+ };
147
205
  })();
148
206
 
149
- if (typeof window !== 'undefined') {
207
+ if (typeof window !== 'undefined' && !window.LOG) {
150
208
  window.LOG = LOG
151
- window.LOG_PP = LOG_PP
152
209
  }
153
210
 
154
211
  export default LOG
package/src/fez.js CHANGED
@@ -14,7 +14,7 @@ setInterval(() => {
14
14
  for (const [key, el] of Fez.instances) {
15
15
  if (!el?.isConnected) {
16
16
  // Fez.error(`Found junk instance that is not connected ${el.fezName}`)
17
- el.fez?.fezRemoveSelf()
17
+ el.fez?.fezOnDestroy()
18
18
  Fez.instances.delete(key)
19
19
  }
20
20
  }
@@ -47,7 +47,7 @@ const observer = new MutationObserver((mutations) => {
47
47
  .forEach(el => {
48
48
  if (el.fez && el.root) {
49
49
  Fez.instances.delete(el.fez.UID)
50
- el.fez.fezRemoveSelf()
50
+ el.fez.fezOnDestroy()
51
51
  }
52
52
  });
53
53
  }
package/src/rollup.js CHANGED
@@ -1,25 +1,82 @@
1
- function fezPlugin() {
2
- return {
3
- name: 'fez-plugin',
1
+ // import .fez files and import globing via fezImport(./foo/bar/*)
2
+ // svelte is transformed to component import, all other files are copied
3
+ //
4
+ // rollup.config.js
5
+ // import fezImport from '@dinoreic/fez/rollup';
6
+ // plugins: [fezImport(), ...]
7
+
8
+ import { glob } from 'glob';
9
+ import path from 'path';
4
10
 
5
- transform(code, filePath) {
6
- const baseName = filePath.split('/').pop().split('.');
11
+ // compile fez files
12
+ const transformFez = (code, filePath) => {
13
+ const baseName = filePath.split('/').pop().split('.');
14
+
15
+ if (baseName[1] === 'fez') {
16
+ code = code.replace(/`/g, '\\`').replace(/\$/g, '\\$');
17
+ return `Fez.compile('${baseName[0]}', \`\n${code}\`)`;
18
+ }
19
+ }
7
20
 
8
- if (baseName[1] === 'fez') {
9
- code = code.replace(/`/g, '\\`').replace(/\$/g, '\\$');
10
- const transformedCode = `Fez.compile('${baseName[0]}', \`\n${code}\`)`;
21
+ // glob import files
22
+ const transformGlob = async (code, filePath) => {
23
+ // Only process .js files containing glob statements
24
+ if (!filePath.endsWith('.js')) {
25
+ return null;
26
+ }
11
27
 
12
- // if (baseName[0] === 'admin-menu') {
13
- // console.log('Transformed code:', baseName, transformedCode);
14
- // }
28
+ // Check for fezImport() function calls
29
+ const globImportMatch = code.match(/fezImport\(['"`]([^'"`]+)['"`]\)/);
30
+ if (globImportMatch) {
31
+ const globPattern = globImportMatch[1];
15
32
 
16
- return {
17
- code: transformedCode,
18
- map: null,
19
- };
33
+ // Resolve relative path from the file's directory
34
+ const fileDir = path.dirname(filePath);
35
+ const resolvedPattern = path.resolve(fileDir, globPattern);
36
+
37
+ const files = await glob(resolvedPattern, { absolute: true });
38
+ const imports = [];
39
+ const bindings = [];
40
+
41
+ console.log('fezGlob(', globPattern, '), files:', files.length);
42
+
43
+ for (const file of files.sort()) {
44
+ if (file.endsWith('.svelte')) {
45
+ // Transform Svelte files with bindings
46
+ const name = path.basename(file, '.svelte').replace(/-/g, '_');
47
+ imports.push(`import Svelte_${name} from '${file}';`);
48
+ bindings.push(`Svelte.connect('s-${name.replace(/_/g, '-')}', Svelte_${name});`);
49
+ } else {
50
+ // Regular import for all other files
51
+ const name = path.basename(file, path.extname(file)).replace(/-/g, '_');
52
+ imports.push(`import ${name} from '${file}';`);
20
53
  }
54
+ }
55
+
56
+ const replacement = [...imports, '', ...bindings].join('\n');
57
+ return code.replace(globImportMatch[0], replacement);
58
+ }
59
+
60
+ return null;
61
+ }
62
+
63
+ export default function fezImport() {
64
+ return {
65
+ name: 'fez-plugin',
66
+
67
+ async transform(code, filePath) {
68
+ for (const func of [transformFez, transformGlob]) {
69
+ const result = await func(code, filePath);
70
+ if (result) {
71
+ return {
72
+ code: result,
73
+ map: null,
74
+ };
75
+ }
76
+ }
77
+
78
+ return null;
21
79
  },
22
80
  };
23
81
  }
24
82
 
25
- export default fezPlugin;
package/dist/log.js DELETED
@@ -1,5 +0,0 @@
1
- (()=>{var u=o=>{let a=o.split(/(<\/?[^>]+>)/g).map(i=>i.trim()).filter(i=>i),n=0,t=[];for(let i=0;i<a.length;i++){let e=a[i],s=a[i+1],p=a[i+2];if(e.startsWith("<"))if(!e.startsWith("</")&&!e.endsWith("/>")&&s&&!s.startsWith("<")&&p&&p.startsWith("</")){let r=Math.max(0,n);t.push(" ".repeat(r)+e+s+p),i+=2}else if(e.startsWith("</")){n--;let r=Math.max(0,n);t.push(" ".repeat(r)+e)}else if(e.endsWith("/>")||e.includes(" />")){let r=Math.max(0,n);t.push(" ".repeat(r)+e)}else{let r=Math.max(0,n);t.push(" ".repeat(r)+e),n++}else if(e){let r=Math.max(0,n);t.push(" ".repeat(r)+e)}}return t.join(`
2
- `)},c=(()=>{let o=[],a=[],n=0;return t=>{if(!document.body){window.requestAnimationFrame(()=>c(t));return}t instanceof Node&&(t=u(t.outerHTML));let i=typeof t;t===void 0&&(t="undefined"),t===null&&(t="null"),Array.isArray(t)?i="array":typeof t=="object"&&t!==null&&(i="object"),typeof t!="string"&&(t=JSON.stringify(t,(r,l)=>typeof l=="function"?String(l):l,2).replaceAll("<","&lt;")),t=t.trim(),o.push(t+`
3
-
4
- type: ${i}`),a.push(i);let e=document.getElementById("dump-dialog");e||(e=document.body.appendChild(document.createElement("div")),e.id="dump-dialog",e.style.cssText="position:fixed;top:30px;left:30px;right:50px;bottom:50px;background:#fff;border:1px solid#333;box-shadow:0 0 10px rgba(0,0,0,0.5);padding:20px;overflow:auto;z-index:9999;font:13px/1.4 monospace;white-space:pre");let s=parseInt(localStorage.getItem("_LOG_INDEX"));!isNaN(s)&&s>=0&&s<o.length?n=s:n=o.length-1;let p=()=>{let r=o.map((l,d)=>{let f="#f0f0f0";return d!==n&&(a[d]==="object"?f="#d6e3ef":a[d]==="array"&&(f="#d8d5ef")),`<button style="padding:4px 8px;margin:0;cursor:pointer;background:${d===n?"#333":f};color:${d===n?"#fff":"#000"}" data-index="${d}">${d+1}</button>`}).join("");e.innerHTML='<div style="display:flex;flex-direction:column;height:100%"><div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:10px"><div style="display:flex;flex-wrap:wrap;gap:4px;flex:1;margin-right:10px">'+r+'</div><button style="padding:4px 8px;cursor:pointer;flex-shrink:0">&times;</button></div><xmp style="flex:1;overflow:auto;margin:0;padding:0;color:#000;background:#fff;font-size:14px;line-height:22px">'+o[n]+"</xmp></div>",e.querySelector('button[style*="flex-shrink:0"]').onclick=()=>e.remove(),e.querySelectorAll("button[data-index]").forEach(l=>{l.onclick=()=>{n=parseInt(l.dataset.index),localStorage.setItem("_LOG_INDEX",n),p()}})};p()}})();typeof window<"u"&&(window.LOG=c,window.LOG_PP=u);var x=c;})();
5
- //# sourceMappingURL=log.js.map
package/dist/log.js.map DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/log.js"],
4
- "sourcesContent": ["// pretty print HTML\nconst LOG_PP = (html) => {\n const parts = html\n .split(/(<\\/?[^>]+>)/g)\n .map(p => p.trim())\n .filter(p => p);\n\n let indent = 0;\n const lines = [];\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const nextPart = parts[i + 1];\n const nextNextPart = parts[i + 2];\n\n // Check if it's a tag\n if (part.startsWith('<')) {\n // Check if this is an opening tag followed by text and then its closing tag\n if (!part.startsWith('</') && !part.endsWith('/>') && nextPart && !nextPart.startsWith('<') && nextNextPart && nextNextPart.startsWith('</')) {\n // Combine them on one line\n const actualIndent = Math.max(0, indent);\n lines.push(' '.repeat(actualIndent) + part + nextPart + nextNextPart);\n i += 2; // Skip the next two parts\n }\n // Closing tag\n else if (part.startsWith('</')) {\n indent--;\n const actualIndent = Math.max(0, indent);\n lines.push(' '.repeat(actualIndent) + part);\n }\n // Self-closing tag\n else if (part.endsWith('/>') || part.includes(' />')) {\n const actualIndent = Math.max(0, indent);\n lines.push(' '.repeat(actualIndent) + part);\n }\n // Opening tag\n else {\n const actualIndent = Math.max(0, indent);\n lines.push(' '.repeat(actualIndent) + part);\n indent++;\n }\n }\n // Text node\n else if (part) {\n const actualIndent = Math.max(0, indent);\n lines.push(' '.repeat(actualIndent) + part);\n }\n }\n\n return lines.join('\\n');\n}\n\nconst LOG = (() => {\n const logs = [];\n const logTypes = []; // Track the original type of each log\n let currentIndex = 0;\n\n return o => {\n if (!document.body) {\n window.requestAnimationFrame( () => LOG(o) )\n return\n }\n\n if (o instanceof Node) {\n o = LOG_PP(o.outerHTML)\n }\n\n // Store the original type\n let originalType = typeof o;\n\n if (o === undefined) { o = 'undefined' }\n if (o === null) { o = 'null' }\n\n if (Array.isArray(o)) {\n originalType = 'array';\n } else if (typeof o === 'object' && o !== null) {\n originalType = 'object';\n }\n\n if (typeof o != 'string') {\n o = JSON.stringify(o, (key, value) => {\n if (typeof value === 'function') {\n return String(value);\n }\n return value;\n }, 2).replaceAll('<', '&lt;')\n }\n\n o = o.trim()\n\n logs.push(o + `\\n\\ntype: ${originalType}`);\n logTypes.push(originalType);\n\n let d = document.getElementById('dump-dialog');\n if (!d) {\n d = document.body.appendChild(document.createElement('div'));\n d.id = 'dump-dialog';\n d.style.cssText =\n 'position:fixed;top:30px;left:30px;right:50px;bottom:50px;' +\n 'background:#fff;border:1px solid#333;box-shadow:0 0 10px rgba(0,0,0,0.5);' +\n 'padding:20px;overflow:auto;z-index:9999;font:13px/1.4 monospace;white-space:pre';\n }\n\n // Check if we have a saved index and it's still valid\n const savedIndex = parseInt(localStorage.getItem('_LOG_INDEX'));\n if (!isNaN(savedIndex) && savedIndex >= 0 && savedIndex < logs.length) {\n currentIndex = savedIndex;\n } else {\n currentIndex = logs.length - 1;\n }\n\n const renderContent = () => {\n const buttons = logs.map((_, i) => {\n let bgColor = '#f0f0f0'; // default\n if (i !== currentIndex) {\n if (logTypes[i] === 'object') {\n bgColor = '#d6e3ef'; // super light blue\n } else if (logTypes[i] === 'array') {\n bgColor = '#d8d5ef'; // super light indigo\n }\n }\n return `<button style=\"padding:4px 8px;margin:0;cursor:pointer;background:${i === currentIndex ? '#333' : bgColor};color:${i === currentIndex ? '#fff' : '#000'}\" data-index=\"${i}\">${i + 1}</button>`\n }).join('');\n\n d.innerHTML =\n '<div style=\"display:flex;flex-direction:column;height:100%\">' +\n '<div style=\"display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:10px\">' +\n '<div style=\"display:flex;flex-wrap:wrap;gap:4px;flex:1;margin-right:10px\">' + buttons + '</div>' +\n '<button style=\"padding:4px 8px;cursor:pointer;flex-shrink:0\">&times;</button>' +\n '</div>' +\n '<xmp style=\"flex:1;overflow:auto;margin:0;padding:0;color:#000;background:#fff;font-size:14px;line-height:22px\">' + logs[currentIndex] + '</xmp>' +\n '</div>';\n\n d.querySelector('button[style*=\"flex-shrink:0\"]').onclick = () => d.remove();\n\n d.querySelectorAll('button[data-index]').forEach(btn => {\n btn.onclick = () => {\n currentIndex = parseInt(btn.dataset.index);\n localStorage.setItem('_LOG_INDEX', currentIndex);\n renderContent();\n };\n });\n };\n\n renderContent();\n };\n})();\n\nif (typeof window !== 'undefined') {\n window.LOG = LOG\n window.LOG_PP = LOG_PP\n}\n\nexport default LOG\n"],
5
- "mappings": "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",
6
- "names": ["LOG_PP", "html", "parts", "p", "indent", "lines", "part", "nextPart", "nextNextPart", "actualIndent", "LOG", "logs", "logTypes", "currentIndex", "o", "originalType", "key", "value", "d", "savedIndex", "renderContent", "buttons", "_", "i", "bgColor", "btn", "log_default"]
7
- }
package/dist/rollup.js DELETED
@@ -1,3 +0,0 @@
1
- (()=>{function t(){return{name:"fez-plugin",transform(e,r){let n=r.split("/").pop().split(".");if(n[1]==="fez")return e=e.replace(/`/g,"\\`").replace(/\$/g,"\\$"),{code:`Fez.compile('${n[0]}', \`
2
- ${e}\`)`,map:null}}}}var l=t;})();
3
- //# sourceMappingURL=rollup.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/rollup.js"],
4
- "sourcesContent": ["function fezPlugin() {\n return {\n name: 'fez-plugin',\n\n transform(code, filePath) {\n const baseName = filePath.split('/').pop().split('.');\n\n if (baseName[1] === 'fez') {\n code = code.replace(/`/g, '\\\\`').replace(/\\$/g, '\\\\$');\n const transformedCode = `Fez.compile('${baseName[0]}', \\`\\n${code}\\`)`;\n\n // if (baseName[0] === 'admin-menu') {\n // console.log('Transformed code:', baseName, transformedCode);\n // }\n\n return {\n code: transformedCode,\n map: null,\n };\n }\n },\n };\n}\n\nexport default fezPlugin;\n"],
5
- "mappings": "MAAA,SAASA,GAAY,CACnB,MAAO,CACL,KAAM,aAEN,UAAUC,EAAMC,EAAU,CACxB,IAAMC,EAAWD,EAAS,MAAM,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,EAEpD,GAAIC,EAAS,CAAC,IAAM,MAClB,OAAAF,EAAOA,EAAK,QAAQ,KAAM,KAAK,EAAE,QAAQ,MAAO,KAAK,EAO9C,CACL,KAPsB,gBAAgBE,EAAS,CAAC,CAAC;AAAA,EAAUF,CAAI,MAQ/D,IAAK,IACP,CAEJ,CACF,CACF,CAEA,IAAOG,EAAQJ",
6
- "names": ["fezPlugin", "code", "filePath", "baseName", "rollup_default"]
7
- }