@aetherframework/template-engine 1.0.0 → 1.0.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.
package/README.md CHANGED
@@ -5,7 +5,7 @@ A modern, lightweight template engine for Node.js with Blade-like syntax, suppor
5
5
  Features
6
6
 
7
7
  - Blade-like Syntax: Familiar syntax similar to Laravel Blade
8
- - Template Inheritance: Support for `@extends`, `@section`, `@yield`
8
+ - Template Inheritance: Support for `@extends`, `@section`, `@yield`, `@include`
9
9
  - Conditionals & Loops: `@if`, `@else`, `@endif`, `@foreach`, `@endforeach`
10
10
  - Custom Functions: `{{ route('home') }}`, `{{ asset('images/logo.png') }}`
11
11
  - Chained Properties: `{{ auth().user.name }}`
@@ -609,6 +609,436 @@ project/
609
609
  └── app.js
610
610
  ```
611
611
 
612
+
613
+ ---
614
+
615
+ Compression Features
616
+
617
+ The Aether Template Engine includes a powerful built-in compression system that automatically minifies and optimizes your HTML, CSS, and JavaScript output for production environments. This feature helps reduce bandwidth usage, improve page load times, and enhance overall performance.
618
+
619
+ Basic Compression Configuration
620
+
621
+ ```javascript
622
+ import AetherEngine from '@aetherframework/template-engine';
623
+
624
+ // Initialize the engine with compression enabled
625
+ const engine = new AetherEngine({
626
+ templateDir: './templates',
627
+ cacheEnabled: true,
628
+ debug: process.env.NODE_ENV === 'development',
629
+
630
+ // Compression configuration
631
+ compressionEnabled: true, // Enable/disable compression globally
632
+ minifyHTML: true, // Minify HTML structure (remove whitespace, comments)
633
+ minifyCSS: true, // Minify inline CSS styles
634
+ minifyJS: true, // Minify inline JavaScript code
635
+ mangleJS: false, // Obfuscate JavaScript variable names (production only)
636
+ removeComments: true, // Remove HTML/CSS/JS comments
637
+ collapseWhitespace: true, // Collapse multiple whitespace characters
638
+ removeAttributeQuotes: false, // Remove optional quotes from HTML attributes
639
+ removeEmptyAttributes: false, // Remove empty HTML attributes
640
+ cacheCompressed: true, // Cache compressed results for performance
641
+ cacheTTL: 3600000 // Cache time-to-live in milliseconds (1 hour)
642
+ });
643
+
644
+ await engine.initialize();
645
+ ```
646
+
647
+ Environment-Based Configuration
648
+
649
+ ```javascript
650
+ // Development environment - disable compression for easier debugging
651
+ const devEngine = new AetherEngine({
652
+ compressionEnabled: false,
653
+ minifyHTML: false,
654
+ minifyCSS: false,
655
+ minifyJS: false,
656
+ mangleJS: false,
657
+ removeComments: false,
658
+ collapseWhitespace: false,
659
+ cacheCompressed: false,
660
+ debug: true
661
+ });
662
+
663
+ // Production environment - enable all compression for optimal performance
664
+ const prodEngine = new AetherEngine({
665
+ compressionEnabled: true,
666
+ minifyHTML: true,
667
+ minifyCSS: true,
668
+ minifyJS: true,
669
+ mangleJS: true, // Obfuscate JS in production for security
670
+ removeComments: true,
671
+ collapseWhitespace: true,
672
+ removeAttributeQuotes: true,
673
+ removeEmptyAttributes: true,
674
+ cacheCompressed: true,
675
+ cacheTTL: 3600000, // 1 hour cache
676
+ debug: false
677
+ });
678
+ ```
679
+
680
+ Per-Render Compression Options
681
+
682
+ You can override compression settings for individual template renders:
683
+
684
+ ```javascript
685
+ // Render with specific compression options
686
+ const html = await engine.render('template.aether', data, {
687
+ compression: {
688
+ minifyHTML: true,
689
+ minifyCSS: true,
690
+ minifyJS: true,
691
+ mangleJS: process.env.NODE_ENV === 'production',
692
+ removeComments: true,
693
+ collapseWhitespace: true
694
+ }
695
+ });
696
+ ```
697
+
698
+ Compression Examples
699
+
700
+ Before Compression (Development):
701
+ ```html
702
+ <!DOCTYPE html>
703
+ <html lang="en">
704
+ <head>
705
+ <meta charset="UTF-8">
706
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
707
+ <title>My Application</title>
708
+ <style>
709
+ /* Main styles */
710
+ body {
711
+ margin: 0;
712
+ padding: 0;
713
+ font-family: Arial, sans-serif;
714
+ }
715
+
716
+ .container {
717
+ width: 100%;
718
+ max-width: 1200px;
719
+ margin: 0 auto;
720
+ padding: 20px;
721
+ }
722
+ </style>
723
+ </head>
724
+ <body>
725
+ <div class="container">
726
+ <h1>Welcome to {{ app.name }}</h1>
727
+ <p>This is a sample page with uncompressed output.</p>
728
+ </div>
729
+
730
+ <script>
731
+ // JavaScript code
732
+ function greetUser(name) {
733
+ console.log("Hello, " + name + "!");
734
+ }
735
+
736
+ greetUser("John");
737
+ </script>
738
+ </body>
739
+ </html>
740
+ ```
741
+
742
+ After Compression (Production):
743
+ ```html
744
+ <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>My Application</title><style>body{margin:0;padding:0;font-family:Arial,sans-serif}.container{width:100%;max-width:1200px;margin:0 auto;padding:20px}</style></head><body><div class="container"><h1>Welcome to MyApp</h1><p>This is a sample page with compressed output.</p></div><script>function a(b){console.log("Hello, "+b+"!")}a("John")</script></body></html>
745
+ ```
746
+
747
+ Compression Statistics and Cache Management
748
+
749
+ ```javascript
750
+ // Get compression statistics
751
+ const stats = engine.getCompressionStats();
752
+ console.log(stats);
753
+ // Output: { cacheSize: 15, cacheHits: 42, cacheTTL: 3600000, options: {...} }
754
+
755
+ // Clear compression cache (useful during development)
756
+ engine.clearCompressionCache();
757
+
758
+ // Check if compression is enabled
759
+ const isCompressionEnabled = engine.options.compressionEnabled;
760
+ ```
761
+
762
+ SSR Mode with Compression
763
+
764
+ ```javascript
765
+ import { SSRModeEngine } from '@aetherframework/template-engine';
766
+
767
+ const ssrEngine = new SSRModeEngine({
768
+ templateDir: './templates',
769
+ hydrate: true,
770
+ stream: false,
771
+
772
+ // SSR-specific compression options
773
+ compressSSR: true,
774
+ minifySSR: true,
775
+
776
+ // General compression settings
777
+ compressionEnabled: true,
778
+ minifyHTML: true,
779
+ minifyCSS: true,
780
+ minifyJS: true,
781
+ mangleJS: process.env.NODE_ENV === 'production',
782
+ removeComments: true,
783
+ collapseWhitespace: true,
784
+ cacheCompressed: true
785
+ });
786
+
787
+ // Render with SSR and compression
788
+ const html = await ssrEngine.render('app.aether', data);
789
+ ```
790
+
791
+ Template Mode with Compression
792
+
793
+ ```javascript
794
+ import { TemplateModeEngine } from '@aetherframework/template-engine';
795
+
796
+ const templateEngine = new TemplateModeEngine({
797
+ templateDir: './templates',
798
+ layoutSupport: true,
799
+ includeSupport: true,
800
+
801
+ // Template-specific compression
802
+ compressTemplates: true,
803
+ minifyTemplates: true,
804
+
805
+ // General compression settings
806
+ compressionEnabled: true,
807
+ minifyHTML: true,
808
+ minifyCSS: true,
809
+ minifyJS: true,
810
+ mangleJS: false, // Usually keep JS readable in template mode
811
+ removeComments: true,
812
+ collapseWhitespace: true,
813
+ cacheCompressed: true
814
+ });
815
+
816
+ // Render template with compression
817
+ const html = await templateEngine.render('page.aether', data);
818
+ ```
819
+
820
+ Environment Configuration
821
+
822
+ Create a `.env` file with compression settings:
823
+
824
+ ```env
825
+ Compression Configuration
826
+ COMPRESSION_ENABLED=true
827
+ MINIFY_HTML=true
828
+ MINIFY_CSS=true
829
+ MINIFY_JS=true
830
+ MANGLE_JS=true
831
+ REMOVE_COMMENTS=true
832
+ COLLAPSE_WHITESPACE=true
833
+ REMOVE_ATTRIBUTE_QUOTES=true
834
+ REMOVE_EMPTY_ATTRIBUTES=true
835
+ CACHE_COMPRESSED=true
836
+ CACHE_TTL=3600000
837
+
838
+ Template Engine Configuration
839
+ TEMPLATE_ENGINE_MODE=template
840
+ TEMPLATE_DIR=./templates
841
+ CACHE_ENABLED=true
842
+ CACHE_TTL=300000
843
+ DEBUG=false
844
+ ```
845
+
846
+ Express.js Integration with Compression
847
+
848
+ ```javascript
849
+ import express from 'express';
850
+ import { createEngine } from '@aetherframework/template-engine';
851
+
852
+ const app = express();
853
+
854
+ // Initialize template engine with compression
855
+ const factory = await createEngine({
856
+ templateDir: './views',
857
+ cacheEnabled: process.env.NODE_ENV === 'production',
858
+
859
+ // Compression based on environment
860
+ compressionEnabled: process.env.NODE_ENV === 'production',
861
+ minifyHTML: process.env.NODE_ENV === 'production',
862
+ minifyCSS: process.env.NODE_ENV === 'production',
863
+ minifyJS: process.env.NODE_ENV === 'production',
864
+ mangleJS: process.env.NODE_ENV === 'production',
865
+ removeComments: process.env.NODE_ENV === 'production',
866
+ collapseWhitespace: true,
867
+ cacheCompressed: true
868
+ });
869
+
870
+ const renderer = factory.createRenderer('aether');
871
+
872
+ // Middleware to add render method with compression
873
+ app.use((req, res, next) => {
874
+ res.render = async (template, data = {}, options = {}) => {
875
+ try {
876
+ const html = await renderer.render(template, {
877
+ ...data,
878
+ req,
879
+ res,
880
+ csrfToken: req.csrfToken ? req.csrfToken() : null
881
+ }, {
882
+ // Override compression per route if needed
883
+ compression: {
884
+ minifyHTML: true,
885
+ minifyCSS: true,
886
+ minifyJS: true,
887
+ mangleJS: process.env.NODE_ENV === 'production',
888
+ ...options.compression
889
+ }
890
+ });
891
+
892
+ // Set compression headers
893
+ res.setHeader('X-Compression-Enabled', 'true');
894
+ res.setHeader('X-Compression-Mode', 'template');
895
+ res.setHeader('Cache-Control', 'public, max-age=3600');
896
+
897
+ res.send(html);
898
+ } catch (error) {
899
+ console.error('Render error:', error);
900
+ res.status(500).send('Internal Server Error');
901
+ }
902
+ };
903
+ next();
904
+ });
905
+
906
+ // Route with compressed output
907
+ app.get('/', async (req, res) => {
908
+ const data = {
909
+ title: 'Home Page',
910
+ user: req.user || null,
911
+ products: await Product.find(),
912
+ csrfToken: req.csrfToken ? req.csrfToken() : null
913
+ };
914
+
915
+ await res.render('home', data, {
916
+ // Optional: Custom compression for this route
917
+ compression: {
918
+ minifyHTML: true,
919
+ minifyCSS: true,
920
+ minifyJS: true,
921
+ mangleJS: process.env.NODE_ENV === 'production'
922
+ }
923
+ });
924
+ });
925
+
926
+ app.listen(3000, () => {
927
+ console.log('Server running on http://localhost:3000');
928
+ console.log(`Compression: ${process.env.NODE_ENV === 'production' ? 'Enabled' : 'Disabled'}`);
929
+ });
930
+ ```
931
+
932
+ Performance Benefits
933
+
934
+ 1. Reduced Bandwidth Usage: Compressed HTML can be 30-70% smaller than uncompressed versions
935
+ 2. Faster Page Load Times: Smaller file sizes lead to quicker downloads and parsing
936
+ 3. Improved SEO: Faster loading pages are favored by search engines
937
+ 4. Better User Experience: Users see content faster, especially on mobile devices
938
+ 5. Reduced Server Load: Less data transmission means lower server resource usage
939
+ 6. Enhanced Security: JavaScript obfuscation (`mangleJS`) makes code harder to reverse-engineer
940
+
941
+ Compression Options Reference
942
+
943
+ | Option | Type | Default | Description |
944
+ |--------|------|---------|-------------|
945
+ | `compressionEnabled` | boolean | `false` | Enable/disable compression globally |
946
+ | `minifyHTML` | boolean | `true` | Minify HTML structure (remove whitespace, comments) |
947
+ | `minifyCSS` | boolean | `true` | Minify inline CSS styles |
948
+ | `minifyJS` | boolean | `true` | Minify inline JavaScript code |
949
+ | `mangleJS` | boolean | `false` | Obfuscate JavaScript variable names |
950
+ | `removeComments` | boolean | `true` | Remove HTML, CSS, and JavaScript comments |
951
+ | `collapseWhitespace` | boolean | `true` | Collapse multiple whitespace characters into single spaces |
952
+ | `removeAttributeQuotes` | boolean | `false` | Remove optional quotes from HTML attributes |
953
+ | `removeEmptyAttributes` | boolean | `false` | Remove empty HTML attributes |
954
+ | `cacheCompressed` | boolean | `true` | Cache compressed results to avoid re-compression |
955
+ | `cacheTTL` | number | `3600000` | Cache time-to-live in milliseconds (1 hour) |
956
+
957
+ Troubleshooting Compression
958
+
959
+ Common Issues:
960
+
961
+ 1. Compression not working: Ensure `compressionEnabled` is set to `true` in your configuration
962
+ 2. JavaScript errors after compression: Disable `mangleJS` or check for variable name conflicts in your code
963
+ 3. CSS broken after compression: Verify CSS syntax is valid and doesn't contain edge cases
964
+ 4. Cache not updating: Clear compression cache with `engine.clearCompressionCache()` during development
965
+ 5. Performance issues: Adjust `cacheTTL` based on your application's update frequency
966
+
967
+ Debug Mode for Compression:
968
+
969
+ ```javascript
970
+ const engine = new AetherEngine({
971
+ compressionEnabled: true,
972
+ debug: true // Enable debug logs
973
+ });
974
+
975
+ // Check compression logs in console
976
+ // [AetherEngine] Compression applied: 10240 → 5120 bytes (50% reduction)
977
+ // [AetherEngine] Cache hit for template: home.aether
978
+ // [AetherEngine] Compression statistics: { cacheSize: 5, cacheHits: 23 }
979
+ ```
980
+
981
+ Best Practices
982
+
983
+ 1. Development Environment: Disable compression (`compressionEnabled: false`) for easier debugging and readable output
984
+ 2. Production Environment: Enable all compression options for optimal performance and security
985
+ 3. Testing: Test with `mangleJS: false` first, then enable for production after verification
986
+ 4. Monitoring: Use `getCompressionStats()` to monitor cache performance and hit rates
987
+ 5. Caching Strategy: Always enable `cacheCompressed: true` in production to avoid re-compressing the same content
988
+ 6. Incremental Deployment: Deploy compression changes gradually and monitor for issues
989
+ 7. Backup Originals: Keep uncompressed templates in source control for debugging purposes
990
+
991
+ Advanced Compression Configuration
992
+
993
+ For fine-grained control over compression behavior:
994
+
995
+ ```javascript
996
+ const engine = new AetherEngine({
997
+ compressionEnabled: true,
998
+
999
+ // HTML-specific options
1000
+ minifyHTML: true,
1001
+ collapseWhitespace: true,
1002
+ conservativeCollapse: false, // Preserve single whitespace
1003
+ preserveLineBreaks: false, // Remove all line breaks
1004
+ removeComments: true,
1005
+ removeEmptyAttributes: true,
1006
+ removeAttributeQuotes: true,
1007
+ removeOptionalTags: false, // Don't remove optional tags like </li>
1008
+
1009
+ // CSS-specific options
1010
+ minifyCSS: true,
1011
+ cssMinifierOptions: {
1012
+ level: 2, // Optimization level (1-3)
1013
+ compatibility: '*', // Browser compatibility
1014
+ format: 'keep-breaks' // Output formatting
1015
+ },
1016
+
1017
+ // JavaScript-specific options
1018
+ minifyJS: true,
1019
+ mangleJS: true,
1020
+ mangleOptions: {
1021
+ reserved: ['render', 'data', 'helpers'] // Variables to preserve
1022
+ },
1023
+ jsMinifierOptions: {
1024
+ compress: {
1025
+ drop_console: true, // Remove console statements
1026
+ drop_debugger: true // Remove debugger statements
1027
+ },
1028
+ mangle: {
1029
+ properties: false // Don't mangle property names
1030
+ }
1031
+ },
1032
+
1033
+ // Cache configuration
1034
+ cacheCompressed: true,
1035
+ cacheTTL: 3600000,
1036
+ cacheMaxSize: 100 // Maximum number of cached items
1037
+ });
1038
+ ```
1039
+
1040
+ This compression feature is seamlessly integrated into the Aether Template Engine, providing automatic optimization without requiring changes to your template code. The system intelligently handles different content types and provides configurable options for both development and production environments.
1041
+
612
1042
  Performance Tips
613
1043
 
614
1044
  1. Enable Caching in Production: Always enable caching in production environments
package/index.js CHANGED
@@ -23,6 +23,9 @@ export { default as EngineRegistry } from './src/core/EngineRegistry.js';
23
23
  export { default as ModeManager } from './src/core/ModeManager.js';
24
24
  export { default as CacheManager } from './src/core/CacheManager.js';
25
25
 
26
+ // Export compression utilities
27
+ export { default as CompressionEngine } from './src/engines/CompressionEngine.js';
28
+
26
29
  /**
27
30
  * Create a template engine factory with default configuration
28
31
  * @param {Object} options - Configuration options
@@ -71,7 +74,16 @@ export async function quickStart(options = {}) {
71
74
  mode: 'template',
72
75
  templateDir: './templates',
73
76
  cacheEnabled: true,
74
- debug: process.env.NODE_ENV === 'development'
77
+ debug: process.env.NODE_ENV === 'development',
78
+ // Add compression options
79
+ compressionEnabled: process.env.NODE_ENV === 'production',
80
+ minifyHTML: process.env.NODE_ENV === 'production',
81
+ minifyCSS: process.env.NODE_ENV === 'production',
82
+ minifyJS: process.env.NODE_ENV === 'production',
83
+ mangleJS: process.env.NODE_ENV === 'production',
84
+ removeComments: process.env.NODE_ENV === 'production',
85
+ collapseWhitespace: true,
86
+ cacheCompressed: true
75
87
  };
76
88
 
77
89
  const config = { ...defaultOptions, ...options };
@@ -146,6 +158,10 @@ export async function quickStart(options = {}) {
146
158
  <span>Template Dir:</span>
147
159
  <code class="bg-gray-900 px-2 py-1 rounded">{{templateDir}}</code>
148
160
  </div>
161
+ <div class="flex items-center justify-between">
162
+ <span>Compression:</span>
163
+ <span class="{{compressionEnabled ? 'text-green-500' : 'text-red-500'}}">{{compressionEnabled ? 'Enabled' : 'Disabled'}}</span>
164
+ </div>
149
165
  </div>
150
166
  </div>
151
167
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aetherframework/template-engine",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A lightweight, high-performance template engine with SSR support and custom syntax",
5
5
  "main": "index.js",
6
6
  "type": "module",