@arikajs/view 0.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.

Potentially problematic release.


This version of @arikajs/view might be problematic. Click here for more details.

package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ArikaJs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,246 @@
1
+ ## Arika View
2
+
3
+ `@arikajs/view` is the server-side rendering (SSR) and template engine for the ArikaJS framework.
4
+
5
+ It allows developers to render dynamic HTML using a clean, expressive template syntax inspired by modern server frameworks — while remaining lightweight, secure, and framework-agnostic.
6
+
7
+ ```ts
8
+ import { View } from '@arikajs/view';
9
+
10
+ const view = new View({
11
+ viewsPath: './views',
12
+ cachePath: './storage/views',
13
+ });
14
+
15
+ const html = await view.render('home', {
16
+ title: 'Welcome to ArikaJS',
17
+ });
18
+ ```
19
+
20
+ The View package enables presentation logic in ArikaJS, transforming templates into clean HTML output with safe escaping and high performance.
21
+
22
+ ---
23
+
24
+ ### Status
25
+
26
+ - **Stage**: Experimental / v0.x
27
+ - **Scope (v0.x)**:
28
+ - Template compilation & rendering
29
+ - Layout & section management
30
+ - Basic control structures (`@if`, `@for`)
31
+ - Safe output escaping
32
+ - Template caching
33
+ - **Out of scope (for this package)**:
34
+ - HTTP request/response handling (see `@arikajs/http`)
35
+ - Route matching (see `@arikajs/router`)
36
+ - Authentication logic
37
+
38
+ ---
39
+
40
+ ## 🎯 Purpose
41
+
42
+ The View package is the presentation layer of the ArikaJS ecosystem. It is responsible for:
43
+ - Rendering templates into HTML
44
+ - Managing layouts and partials
45
+ - Escaping output safely
46
+ - Supporting control structures
47
+ - Providing a foundation for Web views, Email templates, and Error pages.
48
+
49
+ ---
50
+
51
+ ## 🧠 Responsibilities
52
+
53
+ ### ✅ What Arika View Does
54
+ - Compile templates into renderable functions
55
+ - Render templates with dynamic data
56
+ - Support layouts, sections, and includes
57
+ - Provide basic control structures (`if`, `for`)
58
+ - Escape output by default
59
+ - Cache compiled templates for performance
60
+
61
+ ### ❌ What Arika View Does NOT Do
62
+ - Handle HTTP requests or responses
63
+ - Match routes
64
+ - Manage authentication
65
+ - Execute business logic
66
+
67
+ ---
68
+
69
+ ## 🧬 Rendering Flow
70
+
71
+ ```
72
+ Controller
73
+
74
+ View.render()
75
+
76
+ Template Compiler
77
+
78
+ Compiled Template
79
+
80
+ HTML Output
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Features
86
+
87
+ - **Simple, expressive template syntax**
88
+ - Clean tags for logic and output.
89
+ - **Layout & section support**
90
+ - Powerful inheritance model for UI consistency.
91
+ - **Partial / include support**
92
+ - Modularize your templates into reusable components.
93
+ - **Safe output escaping**
94
+ - Protection against XSS by default.
95
+ - **Custom directives**
96
+ - Extend the engine with your own syntax.
97
+ - **Template caching**
98
+ - High-performance rendering via pre-compiled templates.
99
+
100
+ ---
101
+
102
+ ## Installation
103
+
104
+ ```bash
105
+ npm install @arikajs/view
106
+ # or
107
+ yarn add @arikajs/view
108
+ # or
109
+ pnpm add @arikajs/view
110
+ ```
111
+
112
+ ---
113
+
114
+ ## 🧩 Template Syntax
115
+
116
+ ### Variable Output
117
+ ```html
118
+ <h1>{{ title }}</h1>
119
+ ```
120
+ *Escaped by default.*
121
+
122
+ ### Raw Output
123
+ ```html
124
+ {!! html !!}
125
+ ```
126
+
127
+ ### Conditionals
128
+ ```html
129
+ @if (user)
130
+ <p>Welcome, {{ user.name }}</p>
131
+ @endif
132
+ ```
133
+
134
+ ### Loops
135
+ ```html
136
+ @for (item in items)
137
+ <li>{{ item }}</li>
138
+ @endfor
139
+ ```
140
+
141
+ ### Includes
142
+ ```html
143
+ @include('partials.header')
144
+ ```
145
+
146
+ ### Layouts & Sections
147
+
148
+ **layout.html**
149
+ ```html
150
+ <html>
151
+ <body>
152
+ @yield('content')
153
+ </body>
154
+ </html>
155
+ ```
156
+
157
+ **page.html**
158
+ ```html
159
+ @extends('layout')
160
+
161
+ @section('content')
162
+ <h1>Hello World</h1>
163
+ @endsection
164
+ ```
165
+
166
+ ---
167
+
168
+ ## 🔌 Usage
169
+
170
+ ### Basic Rendering
171
+ ```ts
172
+ import { View } from '@arikajs/view';
173
+
174
+ const view = new View({
175
+ viewsPath: './views',
176
+ cachePath: './storage/views',
177
+ });
178
+
179
+ const html = await view.render('home', {
180
+ title: 'Welcome to ArikaJS',
181
+ });
182
+ ```
183
+
184
+ ### Controller Integration
185
+ *(Typically provided by the HTTP Kernel)*
186
+ ```ts
187
+ return view('dashboard', {
188
+ user,
189
+ });
190
+ ```
191
+
192
+ ---
193
+
194
+ ## ⚙️ Configuration Options
195
+
196
+ ```ts
197
+ {
198
+ viewsPath: string; // Directory containing templates
199
+ cachePath?: string; // Directory for compiled templates
200
+ extension?: '.html' | '.ark'; // Template file extension
201
+ cache?: boolean; // Enable/disable caching
202
+ }
203
+ ```
204
+
205
+ ---
206
+
207
+ ## 🧱 Project Structure
208
+
209
+ - `src/`
210
+ - `View.ts` – Main entry point
211
+ - `Engine.ts` – Execution context
212
+ - `Compiler.ts` – Template string to JS compiler
213
+ - `Template.ts` – Template resolution and state
214
+ - `Directives/` – Built-in controls
215
+ - `If.ts`, `For.ts`, `Include.ts`, `Section.ts`
216
+ - `index.ts` – Public exports
217
+ - `tests/` – Unit and integration tests
218
+ - `package.json`
219
+ - `tsconfig.json`
220
+ - `README.md`
221
+ - `LICENSE`
222
+
223
+ ---
224
+
225
+ ## Versioning & Stability
226
+
227
+ - While in **v0.x**, the API may change between minor versions.
228
+ - Once the API stabilizes, `@arikajs/view` will move to **v1.0** and follow **semver** strictly.
229
+
230
+ ---
231
+
232
+ ## Contributing
233
+
234
+ Contributions are welcome! Please ensure all pull requests include tests and follow the project's coding standards.
235
+
236
+ ---
237
+
238
+ ## License
239
+
240
+ `@arikajs/view` is open-sourced software licensed under the **MIT license**.
241
+
242
+ ---
243
+
244
+ ## 🧠 Philosophy
245
+
246
+ > “Presentation is a reflection of logic, not a home for it.”
@@ -0,0 +1,13 @@
1
+ import { Directive } from './Directives/If';
2
+ export declare class Compiler {
3
+ private directives;
4
+ /**
5
+ * Add a custom directive to the compiler.
6
+ */
7
+ addDirective(directive: Directive): void;
8
+ /**
9
+ * Compile a template string into a executable JavaScript function body.
10
+ */
11
+ compile(content: string): string;
12
+ }
13
+ //# sourceMappingURL=Compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Compiler.d.ts","sourceRoot":"","sources":["../src/Compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,iBAAiB,CAAC;AAKzD,qBAAa,QAAQ;IACjB,OAAO,CAAC,UAAU,CAKhB;IAEF;;OAEG;IACI,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAI/C;;OAEG;IACI,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAyD1C"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Compiler = void 0;
4
+ const If_1 = require("./Directives/If");
5
+ const For_1 = require("./Directives/For");
6
+ const Include_1 = require("./Directives/Include");
7
+ const Section_1 = require("./Directives/Section");
8
+ class Compiler {
9
+ constructor() {
10
+ this.directives = [
11
+ If_1.IfDirective,
12
+ For_1.ForDirective,
13
+ Include_1.IncludeDirective,
14
+ Section_1.SectionDirective
15
+ ];
16
+ }
17
+ /**
18
+ * Add a custom directive to the compiler.
19
+ */
20
+ addDirective(directive) {
21
+ this.directives.unshift(directive);
22
+ }
23
+ /**
24
+ * Compile a template string into a executable JavaScript function body.
25
+ */
26
+ compile(content) {
27
+ let jsCode = 'let _output = "";\n';
28
+ jsCode += 'const _escape = (val) => String(val ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/\'/g, "&#39;");\n';
29
+ jsCode += 'with (_data) {\n';
30
+ const escapedContent = content
31
+ .replace(/\\/g, '\\\\')
32
+ .replace(/`/g, '\\`')
33
+ .replace(/\$\{/g, '\\${');
34
+ const regex = /(@\w+\s*\(.*?\)|@\w+|\{\{.*?\}\}|\{!!.*?!!\})/sg;
35
+ let lastIndex = 0;
36
+ let match;
37
+ while ((match = regex.exec(escapedContent)) !== null) {
38
+ const text = escapedContent.substring(lastIndex, match.index);
39
+ if (text) {
40
+ jsCode += `_output += \`${text}\`;\n`;
41
+ }
42
+ const tag = match[0];
43
+ if (tag.startsWith('{!!')) {
44
+ const expr = tag.substring(3, tag.length - 3).trim().replace(/\\\\/g, '\\');
45
+ jsCode += `_output += (${expr});\n`;
46
+ }
47
+ else if (tag.startsWith('{{')) {
48
+ const expr = tag.substring(2, tag.length - 2).trim().replace(/\\\\/g, '\\');
49
+ jsCode += `_output += _escape(${expr});\n`;
50
+ }
51
+ else if (tag.startsWith('@')) {
52
+ let processed = false;
53
+ for (const directive of this.directives) {
54
+ const result = directive.handle(tag);
55
+ if (result) {
56
+ jsCode += result;
57
+ processed = true;
58
+ break;
59
+ }
60
+ }
61
+ if (!processed) {
62
+ // If no directive handled it, treat as literal (escaping the @)
63
+ jsCode += `_output += \`@\`;\n`;
64
+ regex.lastIndex = match.index + 1;
65
+ }
66
+ }
67
+ lastIndex = regex.lastIndex;
68
+ }
69
+ const remaining = escapedContent.substring(lastIndex);
70
+ if (remaining) {
71
+ jsCode += `_output += \`${remaining}\`;\n`;
72
+ }
73
+ jsCode += '}\nreturn _output;';
74
+ return jsCode;
75
+ }
76
+ }
77
+ exports.Compiler = Compiler;
78
+ //# sourceMappingURL=Compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Compiler.js","sourceRoot":"","sources":["../src/Compiler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const ForDirective: {
2
+ name: string;
3
+ handle(content: string): string;
4
+ };
5
+ //# sourceMappingURL=For.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"For.d.ts","sourceRoot":"","sources":["../../src/Directives/For.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;oBAEL,MAAM,GAAG,MAAM;CAWlC,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ForDirective = void 0;
4
+ exports.ForDirective = {
5
+ name: 'for',
6
+ handle(content) {
7
+ if (content.startsWith('@for')) {
8
+ const match = content.match(/@for\s*\((.*)\)/);
9
+ const loop = match && match[1] ? match[1] : '';
10
+ return `for (let ${loop}) {\n`;
11
+ }
12
+ if (content === '@endfor') {
13
+ return `}\n`;
14
+ }
15
+ return '';
16
+ }
17
+ };
18
+ //# sourceMappingURL=For.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"For.js","sourceRoot":"","sources":["../../src/Directives/For.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG;IACxB,IAAI,EAAE,KAAK;IACX,MAAM,CAAC,OAAe;QAClB,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,OAAO,YAAY,IAAI,OAAO,CAAC;QACnC,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface Directive {
2
+ name: string;
3
+ handle(content: string): string;
4
+ }
5
+ export declare const IfDirective: Directive;
6
+ //# sourceMappingURL=If.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"If.d.ts","sourceRoot":"","sources":["../../src/Directives/If.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CACnC;AAED,eAAO,MAAM,WAAW,EAAE,SAqBzB,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IfDirective = void 0;
4
+ exports.IfDirective = {
5
+ name: 'if',
6
+ handle(content) {
7
+ if (content.startsWith('@if')) {
8
+ const match = content.match(/@if\s*\((.*)\)/);
9
+ const condition = match && match[1] ? match[1] : 'true';
10
+ return `if (${condition}) {\n`;
11
+ }
12
+ if (content === '@else') {
13
+ return `} else {\n`;
14
+ }
15
+ if (content.startsWith('@elseif')) {
16
+ const match = content.match(/@elseif\s*\((.*)\)/);
17
+ const condition = match && match[1] ? match[1] : 'true';
18
+ return `} else if (${condition}) {\n`;
19
+ }
20
+ if (content === '@endif') {
21
+ return `}\n`;
22
+ }
23
+ return '';
24
+ }
25
+ };
26
+ //# sourceMappingURL=If.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"If.js","sourceRoot":"","sources":["../../src/Directives/If.ts"],"names":[],"mappings":";;;AAKa,QAAA,WAAW,GAAc;IAClC,IAAI,EAAE,IAAI;IACV,MAAM,CAAC,OAAe;QAClB,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAC9C,MAAM,SAAS,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACxD,OAAO,OAAO,SAAS,OAAO,CAAC;QACnC,CAAC;QACD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACtB,OAAO,YAAY,CAAC;QACxB,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACxD,OAAO,cAAc,SAAS,OAAO,CAAC;QAC1C,CAAC;QACD,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const IncludeDirective: {
2
+ name: string;
3
+ handle(content: string): string;
4
+ };
5
+ //# sourceMappingURL=Include.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Include.d.ts","sourceRoot":"","sources":["../../src/Directives/Include.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;oBAET,MAAM,GAAG,MAAM;CAQlC,CAAC"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IncludeDirective = void 0;
4
+ exports.IncludeDirective = {
5
+ name: 'include',
6
+ handle(content) {
7
+ if (!content.startsWith('@include')) {
8
+ return '';
9
+ }
10
+ const match = content.match(/@include\s*\((.*)\)/);
11
+ const template = match && match[1] ? match[1] : '""';
12
+ return `_output += await _engine.render(${template}, _data);\n`;
13
+ }
14
+ };
15
+ //# sourceMappingURL=Include.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Include.js","sourceRoot":"","sources":["../../src/Directives/Include.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG;IAC5B,IAAI,EAAE,SAAS;IACf,MAAM,CAAC,OAAe;QAClB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,CAAC;QACd,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,OAAO,mCAAmC,QAAQ,aAAa,CAAC;IACpE,CAAC;CACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const SectionDirective: {
2
+ name: string;
3
+ handle(content: string): string;
4
+ };
5
+ //# sourceMappingURL=Section.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Section.d.ts","sourceRoot":"","sources":["../../src/Directives/Section.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;oBAET,MAAM,GAAG,MAAM;CAqBlC,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SectionDirective = void 0;
4
+ exports.SectionDirective = {
5
+ name: 'section',
6
+ handle(content) {
7
+ if (content.startsWith('@section')) {
8
+ const match = content.match(/@section\s*\(([^)]*)\)/);
9
+ const name = match && match[1] ? match[1].replace(/['"]/g, '') : '';
10
+ return `_engine.startSection("${name}", _output);\n_output = "";\n`;
11
+ }
12
+ if (content === '@endsection') {
13
+ return `_output = _engine.popSection(_output);\n`;
14
+ }
15
+ if (content.startsWith('@yield')) {
16
+ const match = content.match(/@yield\s*\(([^)]*)\)/);
17
+ const name = match && match[1] ? match[1] : '""';
18
+ return `_output += _engine.yield(${name});\n`;
19
+ }
20
+ if (content.startsWith('@extends')) {
21
+ const match = content.match(/@extends\s*\((.*)\)/);
22
+ const parent = match && match[1] ? match[1] : '""';
23
+ return `_engine.extend(${parent});\n`;
24
+ }
25
+ return '';
26
+ }
27
+ };
28
+ //# sourceMappingURL=Section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Section.js","sourceRoot":"","sources":["../../src/Directives/Section.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG;IAC5B,IAAI,EAAE,SAAS;IACf,MAAM,CAAC,OAAe;QAClB,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACtD,MAAM,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,OAAO,yBAAyB,IAAI,+BAA+B,CAAC;QACxE,CAAC;QACD,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;YAC5B,OAAO,0CAA0C,CAAC;QACtD,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjD,OAAO,4BAA4B,IAAI,MAAM,CAAC;QAClD,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACnD,OAAO,kBAAkB,MAAM,MAAM,CAAC;QAC1C,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ export interface ViewConfig {
2
+ viewsPath: string;
3
+ cachePath?: string;
4
+ extension?: string;
5
+ cache?: boolean;
6
+ }
7
+ export declare class Engine {
8
+ private config;
9
+ private sections;
10
+ private sectionStack;
11
+ private parentTemplate;
12
+ private compiler;
13
+ private templateLoader;
14
+ private compiledFunctions;
15
+ constructor(config: ViewConfig);
16
+ /**
17
+ * Add a custom directive to the template compiler.
18
+ */
19
+ addDirective(directive: any): void;
20
+ /**
21
+ * Render a template file.
22
+ */
23
+ render(template: string, data?: Record<string, any>, isInternal?: boolean): Promise<string>;
24
+ /**
25
+ * Internal render logic.
26
+ */
27
+ private renderTemplate;
28
+ extend(parent: string): void;
29
+ startSection(name: string, previousOutput: string): void;
30
+ popSection(content: string): string;
31
+ yield(name: string): string;
32
+ }
33
+ //# sourceMappingURL=Engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../src/Engine.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,MAAM;IAQH,OAAO,CAAC,MAAM;IAP1B,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,YAAY,CAAkD;IACtE,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,iBAAiB,CAAoC;gBAEzC,MAAM,EAAE,UAAU;IAKtC;;OAEG;IACI,YAAY,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;IAIzC;;OAEG;IACU,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,UAAU,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB1G;;OAEG;YACW,cAAc;IAwDrB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI5B,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI;IAIxD,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IASnC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAGrC"}
package/dist/Engine.js ADDED
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Engine = void 0;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const Compiler_1 = require("./Compiler");
40
+ const Template_1 = require("./Template");
41
+ class Engine {
42
+ constructor(config) {
43
+ this.config = config;
44
+ this.sections = {};
45
+ this.sectionStack = [];
46
+ this.parentTemplate = null;
47
+ this.compiledFunctions = new Map();
48
+ this.compiler = new Compiler_1.Compiler();
49
+ this.templateLoader = new Template_1.Template(config);
50
+ }
51
+ /**
52
+ * Add a custom directive to the template compiler.
53
+ */
54
+ addDirective(directive) {
55
+ this.compiler.addDirective(directive);
56
+ }
57
+ /**
58
+ * Render a template file.
59
+ */
60
+ async render(template, data = {}, isInternal = false) {
61
+ if (!isInternal) {
62
+ this.sections = {};
63
+ }
64
+ this.parentTemplate = null;
65
+ const content = await this.renderTemplate(template, data);
66
+ if (this.parentTemplate) {
67
+ const parent = this.parentTemplate;
68
+ this.parentTemplate = null;
69
+ return this.render(parent, data, true);
70
+ }
71
+ return content;
72
+ }
73
+ /**
74
+ * Internal render logic.
75
+ */
76
+ async renderTemplate(templateName, data) {
77
+ // 1. Check In-Memory Cache
78
+ if (this.config.cache && this.compiledFunctions.has(templateName)) {
79
+ return await this.compiledFunctions.get(templateName)(this, data);
80
+ }
81
+ const cacheFile = this.config.cachePath
82
+ ? path.join(this.config.cachePath, templateName.replace(/[\.\/\\]/g, '_') + '.js')
83
+ : null;
84
+ let jsCode = null;
85
+ // 2. Check Disk Cache
86
+ if (this.config.cache && cacheFile && fs.existsSync(cacheFile)) {
87
+ try {
88
+ jsCode = fs.readFileSync(cacheFile, 'utf8');
89
+ }
90
+ catch (e) {
91
+ // Fail silently and recompile
92
+ }
93
+ }
94
+ // 3. Compile if not found in cache
95
+ if (!jsCode) {
96
+ const rawContent = this.templateLoader.read(templateName);
97
+ jsCode = this.compiler.compile(rawContent);
98
+ // Save to Disk Cache
99
+ if (this.config.cache && cacheFile) {
100
+ try {
101
+ if (!fs.existsSync(this.config.cachePath)) {
102
+ fs.mkdirSync(this.config.cachePath, { recursive: true });
103
+ }
104
+ fs.writeFileSync(cacheFile, jsCode);
105
+ }
106
+ catch (e) {
107
+ console.error(`View Cache Warning: Failed to write to ${this.config.cachePath}`);
108
+ }
109
+ }
110
+ }
111
+ // 4. Create Function and Save to Memory Cache
112
+ const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
113
+ const renderFunc = new AsyncFunction('_engine', '_data', jsCode);
114
+ if (this.config.cache) {
115
+ this.compiledFunctions.set(templateName, renderFunc);
116
+ }
117
+ try {
118
+ return await renderFunc(this, data);
119
+ }
120
+ catch (e) {
121
+ throw new Error(`Error rendering template "${templateName}": ${e.message}`);
122
+ }
123
+ }
124
+ // Methods called from compiled templates
125
+ extend(parent) {
126
+ this.parentTemplate = parent;
127
+ }
128
+ startSection(name, previousOutput) {
129
+ this.sectionStack.push({ name, previousOutput });
130
+ }
131
+ popSection(content) {
132
+ const section = this.sectionStack.pop();
133
+ if (section) {
134
+ this.sections[section.name] = content;
135
+ return section.previousOutput;
136
+ }
137
+ return content;
138
+ }
139
+ yield(name) {
140
+ return this.sections[name] || '';
141
+ }
142
+ }
143
+ exports.Engine = Engine;
144
+ //# sourceMappingURL=Engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Engine.js","sourceRoot":"","sources":["../src/Engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { ViewConfig } from './Engine';
2
+ export declare class Template {
3
+ private config;
4
+ constructor(config: ViewConfig);
5
+ /**
6
+ * Resolve and read template content.
7
+ */
8
+ read(template: string): string;
9
+ /**
10
+ * Resolve template name to file path.
11
+ */
12
+ private resolvePath;
13
+ }
14
+ //# sourceMappingURL=Template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Template.d.ts","sourceRoot":"","sources":["../src/Template.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,qBAAa,QAAQ;IACL,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,UAAU;IAEtC;;OAEG;IACI,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQrC;;OAEG;IACH,OAAO,CAAC,WAAW;CAKtB"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Template = void 0;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ class Template {
40
+ constructor(config) {
41
+ this.config = config;
42
+ }
43
+ /**
44
+ * Resolve and read template content.
45
+ */
46
+ read(template) {
47
+ const filePath = this.resolvePath(template);
48
+ if (!fs.existsSync(filePath)) {
49
+ throw new Error(`View template not found: ${filePath}`);
50
+ }
51
+ return fs.readFileSync(filePath, 'utf8');
52
+ }
53
+ /**
54
+ * Resolve template name to file path.
55
+ */
56
+ resolvePath(template) {
57
+ const ext = this.config.extension || '.html';
58
+ const fileName = template.replace(/\./g, path.sep) + ext;
59
+ return path.join(this.config.viewsPath, fileName);
60
+ }
61
+ }
62
+ exports.Template = Template;
63
+ //# sourceMappingURL=Template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Template.js","sourceRoot":"","sources":["../src/Template.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAGlC,MAAa,QAAQ;IACjB,YAAoB,MAAkB;QAAlB,WAAM,GAAN,MAAM,CAAY;IAAI,CAAC;IAE3C;;OAEG;IACI,IAAI,CAAC,QAAgB;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,QAAgB;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC;QAC7C,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACzD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACtD,CAAC;CACJ;AAtBD,4BAsBC"}
package/dist/View.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { ViewConfig } from './Engine';
2
+ export declare class View {
3
+ private engine;
4
+ constructor(config: ViewConfig);
5
+ /**
6
+ * Add a custom directive to the template compiler.
7
+ */
8
+ addDirective(directive: any): void;
9
+ /**
10
+ * Render a template with data.
11
+ */
12
+ render(template: string, data?: Record<string, any>): Promise<string>;
13
+ }
14
+ //# sourceMappingURL=View.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"View.d.ts","sourceRoot":"","sources":["../src/View.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,UAAU,EAAE,MAAM,UAAU,CAAC;AAE9C,qBAAa,IAAI;IACb,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,UAAU;IAI9B;;OAEG;IACI,YAAY,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;IAIzC;;OAEG;IACU,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAGzF"}
package/dist/View.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.View = void 0;
4
+ const Engine_1 = require("./Engine");
5
+ class View {
6
+ constructor(config) {
7
+ this.engine = new Engine_1.Engine(config);
8
+ }
9
+ /**
10
+ * Add a custom directive to the template compiler.
11
+ */
12
+ addDirective(directive) {
13
+ this.engine.addDirective(directive);
14
+ }
15
+ /**
16
+ * Render a template with data.
17
+ */
18
+ async render(template, data = {}) {
19
+ return this.engine.render(template, data);
20
+ }
21
+ }
22
+ exports.View = View;
23
+ //# sourceMappingURL=View.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"View.js","sourceRoot":"","sources":["../src/View.ts"],"names":[],"mappings":";;;AAAA,qCAA8C;AAE9C,MAAa,IAAI;IAGb,YAAY,MAAkB;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,eAAM,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,SAAc;QAC9B,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,OAA4B,EAAE;QAChE,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;CACJ;AApBD,oBAoBC"}
@@ -0,0 +1,4 @@
1
+ export * from './View';
2
+ export * from './Engine';
3
+ export * from './Compiler';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./View"), exports);
18
+ __exportStar(require("./Engine"), exports);
19
+ __exportStar(require("./Compiler"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AACvB,2CAAyB;AACzB,6CAA2B"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@arikajs/view",
3
+ "version": "0.1.0",
4
+ "description": "Server-side rendering and template engine for the ArikaJS framework.",
5
+ "license": "MIT",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc -p tsconfig.json",
10
+ "build:tests": "tsc -p tsconfig.test.json",
11
+ "clean": "rm -rf dist",
12
+ "prepare": "echo skip",
13
+ "test": "npm run build && npm run build:tests && node scripts/fix-test-imports.js && node --test 'dist/tests/**/*.test.js'",
14
+ "test:watch": "npm run build && npm run build:tests && node --test --watch 'dist/tests/**/*.test.js'"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "keywords": [
20
+ "arika",
21
+ "arika-js",
22
+ "framework",
23
+ "view",
24
+ "template",
25
+ "ssr",
26
+ "renderer"
27
+ ],
28
+ "engines": {
29
+ "node": ">=20.0.0"
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/arikajs/view.git"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/arikajs/view/issues"
37
+ },
38
+ "homepage": "https://github.com/arikajs/view#readme",
39
+ "dependencies": {},
40
+ "devDependencies": {
41
+ "@types/node": "^20.11.24",
42
+ "typescript": "^5.3.3"
43
+ },
44
+ "author": "Prakash Tank"
45
+ }