@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 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 (per isolate)
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 cssFiles = Array.isArray(opts.css) ? opts.css : [opts.css];
64
+ const files = Array.isArray(opts.css) ? opts.css : [opts.css];
64
65
 
65
- const styles = cssFiles
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
- // EXTENSION CONTRACT (MANDATORY FOR TITANPL)
77
+ // UI SERVICE (SAFE TO EXPORT)
80
78
  // --------------------------------------------------
81
- t[EXT_KEY] = {
82
- /**
83
- * Load HTML template once and return a reusable responder
84
- */
79
+ export const ui = {
85
80
  load(htmlPath) {
86
- const fullPath = resolvePath(htmlPath);
87
- const tpl = loadFile(fullPath, "html");
81
+ const tpl = loadFile(resolvePath(htmlPath), "html");
88
82
 
89
83
  return (data = {}, opts = {}) => {
90
- const finalData = injectCSS(data, opts);
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 fullPath = resolvePath(htmlPath);
101
- const tpl = loadFile(fullPath, "html");
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t8n/ui",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "A lightweight HTML templating engine for TitanPL with file caching and variable interpolation.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/titan.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t8n/ui",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "main": "index.js",
5
5
  "description": "A lightweight HTML templating engine for TitanPL with file caching and variable interpolation.",
6
6
  "keywords": [
@@ -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
+ }