@t8n/ui 1.0.0 → 1.1.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,22 +7,22 @@
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
- const root = "../app" || "."
25
- return root + `/${path.replace(/^\/+/, "")}`;
25
+ return `app/${path.replace(/^\/+/, "")}`;
26
26
  }
27
27
 
28
28
  // --------------------------------------------------
@@ -60,63 +60,42 @@ function renderTemplate(template, data = {}) {
60
60
  function injectCSS(data, opts = {}) {
61
61
  if (!opts.css) return data;
62
62
 
63
- const cssFiles = Array.isArray(opts.css) ? opts.css : [opts.css];
63
+ const files = Array.isArray(opts.css) ? opts.css : [opts.css];
64
64
 
65
- const styles = cssFiles
65
+ const styles = files
66
66
  .map(p => {
67
67
  const css = loadFile(resolvePath(p), "css");
68
68
  return `<style>\n${css}\n</style>`;
69
69
  })
70
70
  .join("\n");
71
71
 
72
- return {
73
- ...data,
74
- css: styles
75
- };
72
+ return { ...data, css: styles };
76
73
  }
77
74
 
78
75
  // --------------------------------------------------
79
- // EXTENSION CONTRACT (MANDATORY FOR TITANPL)
76
+ // UI SERVICE (SAFE TO EXPORT)
80
77
  // --------------------------------------------------
81
- t[EXT_KEY] = {
82
- /**
83
- * Load HTML template once and return a reusable responder
84
- */
78
+ export const ui = {
85
79
  load(htmlPath) {
86
- const fullPath = resolvePath(htmlPath);
87
- const tpl = loadFile(fullPath, "html");
80
+ const tpl = loadFile(resolvePath(htmlPath), "html");
88
81
 
89
82
  return (data = {}, opts = {}) => {
90
- const finalData = injectCSS(data, opts);
91
- const html = renderTemplate(tpl, finalData);
83
+ const html = renderTemplate(tpl, injectCSS(data, opts));
92
84
  return t.response.html(html);
93
85
  };
94
86
  },
95
87
 
96
- /**
97
- * One-shot render with optional CSS
98
- */
99
88
  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
-
89
+ const tpl = loadFile(resolvePath(htmlPath), "html");
90
+ const html = renderTemplate(tpl, injectCSS(data, opts));
106
91
  return t.response.html(html);
107
92
  },
108
93
 
109
- /**
110
- * Load CSS only (manual usage if needed)
111
- */
112
94
  css(cssPath) {
113
95
  const css = loadFile(resolvePath(cssPath), "css");
114
96
  return `<style>\n${css}\n</style>`;
115
97
  },
116
98
 
117
- /**
118
- * Clear all cached UI files
119
- */
120
99
  clearCache() {
121
100
  for (const k in memoryCache) delete memoryCache[k];
122
101
 
@@ -129,3 +108,11 @@ t[EXT_KEY] = {
129
108
  return true;
130
109
  }
131
110
  };
111
+
112
+ // --------------------------------------------------
113
+ // REGISTER INTO TITAN (SuperLS-style) ✅ FIXED
114
+ // --------------------------------------------------
115
+ registerExtension("ui", ui);
116
+
117
+ // Optional default export (same pattern as SuperLocalStorage)
118
+ 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.1.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.1.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
+ }