@t8n/ui 1.0.0 → 1.2.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/index.js +21 -33
- package/package.json +1 -1
- package/titan.json +1 -1
- package/utils/registerExtension.js +44 -0
package/index.js
CHANGED
|
@@ -7,18 +7,19 @@
|
|
|
7
7
|
* t.ui.clearCache()
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { registerExtension } from "./utils/registerExtension.js";
|
|
11
|
+
|
|
10
12
|
if (typeof Titan === "undefined") globalThis.Titan = t;
|
|
11
13
|
|
|
12
|
-
const EXT_KEY = "ui";
|
|
13
14
|
const { fs, ls } = t.core;
|
|
14
15
|
|
|
15
16
|
// --------------------------------------------------
|
|
16
|
-
// Internal cache
|
|
17
|
+
// Internal cache
|
|
17
18
|
// --------------------------------------------------
|
|
18
19
|
const memoryCache = Object.create(null);
|
|
19
20
|
|
|
20
21
|
// --------------------------------------------------
|
|
21
|
-
// Resolve paths relative to app/
|
|
22
|
+
// Resolve paths relative to app/ ✅ FIXED
|
|
22
23
|
// --------------------------------------------------
|
|
23
24
|
function resolvePath(path) {
|
|
24
25
|
const root = "../app" || "."
|
|
@@ -60,63 +61,42 @@ function renderTemplate(template, data = {}) {
|
|
|
60
61
|
function injectCSS(data, opts = {}) {
|
|
61
62
|
if (!opts.css) return data;
|
|
62
63
|
|
|
63
|
-
const
|
|
64
|
+
const files = Array.isArray(opts.css) ? opts.css : [opts.css];
|
|
64
65
|
|
|
65
|
-
const styles =
|
|
66
|
+
const styles = files
|
|
66
67
|
.map(p => {
|
|
67
68
|
const css = loadFile(resolvePath(p), "css");
|
|
68
69
|
return `<style>\n${css}\n</style>`;
|
|
69
70
|
})
|
|
70
71
|
.join("\n");
|
|
71
72
|
|
|
72
|
-
return {
|
|
73
|
-
...data,
|
|
74
|
-
css: styles
|
|
75
|
-
};
|
|
73
|
+
return { ...data, css: styles };
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
// --------------------------------------------------
|
|
79
|
-
//
|
|
77
|
+
// UI SERVICE (SAFE TO EXPORT)
|
|
80
78
|
// --------------------------------------------------
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Load HTML template once and return a reusable responder
|
|
84
|
-
*/
|
|
79
|
+
export const ui = {
|
|
85
80
|
load(htmlPath) {
|
|
86
|
-
const
|
|
87
|
-
const tpl = loadFile(fullPath, "html");
|
|
81
|
+
const tpl = loadFile(resolvePath(htmlPath), "html");
|
|
88
82
|
|
|
89
83
|
return (data = {}, opts = {}) => {
|
|
90
|
-
const
|
|
91
|
-
const html = renderTemplate(tpl, finalData);
|
|
84
|
+
const html = renderTemplate(tpl, injectCSS(data, opts));
|
|
92
85
|
return t.response.html(html);
|
|
93
86
|
};
|
|
94
87
|
},
|
|
95
88
|
|
|
96
|
-
/**
|
|
97
|
-
* One-shot render with optional CSS
|
|
98
|
-
*/
|
|
99
89
|
render(htmlPath, data = {}, opts = {}) {
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
const finalData = injectCSS(data, opts);
|
|
104
|
-
const html = renderTemplate(tpl, finalData);
|
|
105
|
-
|
|
90
|
+
const tpl = loadFile(resolvePath(htmlPath), "html");
|
|
91
|
+
const html = renderTemplate(tpl, injectCSS(data, opts));
|
|
106
92
|
return t.response.html(html);
|
|
107
93
|
},
|
|
108
94
|
|
|
109
|
-
/**
|
|
110
|
-
* Load CSS only (manual usage if needed)
|
|
111
|
-
*/
|
|
112
95
|
css(cssPath) {
|
|
113
96
|
const css = loadFile(resolvePath(cssPath), "css");
|
|
114
97
|
return `<style>\n${css}\n</style>`;
|
|
115
98
|
},
|
|
116
99
|
|
|
117
|
-
/**
|
|
118
|
-
* Clear all cached UI files
|
|
119
|
-
*/
|
|
120
100
|
clearCache() {
|
|
121
101
|
for (const k in memoryCache) delete memoryCache[k];
|
|
122
102
|
|
|
@@ -129,3 +109,11 @@ t[EXT_KEY] = {
|
|
|
129
109
|
return true;
|
|
130
110
|
}
|
|
131
111
|
};
|
|
112
|
+
|
|
113
|
+
// --------------------------------------------------
|
|
114
|
+
// REGISTER INTO TITAN (SuperLS-style) ✅ FIXED
|
|
115
|
+
// --------------------------------------------------
|
|
116
|
+
registerExtension("ui", ui);
|
|
117
|
+
|
|
118
|
+
// Optional default export (same pattern as SuperLocalStorage)
|
|
119
|
+
export default ui;
|
package/package.json
CHANGED
package/titan.json
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// utils/registerExtension.js
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Safely registers an extension in the global t object
|
|
5
|
+
* @param {string} extensionName - Unique name for the extension
|
|
6
|
+
* @param {any} extensionModule - The extension module/object to register
|
|
7
|
+
* @returns {boolean} True if registration was successful
|
|
8
|
+
*/
|
|
9
|
+
export function registerExtension(extensionName, extensionModule) {
|
|
10
|
+
// Check for global t object
|
|
11
|
+
if (typeof t === 'undefined') {
|
|
12
|
+
console.warn(`[registerExtension] Global 't' object not available. Cannot register: ${extensionName}`);
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Input validation
|
|
17
|
+
if (!extensionName || typeof extensionName !== 'string') {
|
|
18
|
+
console.error('[registerExtension] Invalid extension name provided');
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Check for naming conflicts
|
|
23
|
+
if (t[extensionName]) {
|
|
24
|
+
console.warn(`[registerExtension] '${extensionName}' already exists in global t object, overwriting`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
// Register the extension
|
|
29
|
+
t[extensionName] = extensionModule;
|
|
30
|
+
|
|
31
|
+
console.log(`[registerExtension] Successfully registered '${extensionName}'`);
|
|
32
|
+
|
|
33
|
+
return true;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
// Structured error reporting
|
|
36
|
+
console.error(`[registerExtension] Failed to register '${extensionName}':`, {
|
|
37
|
+
error: error.message,
|
|
38
|
+
extensionName,
|
|
39
|
+
moduleType: typeof extensionModule
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|