bunki 0.16.2 → 0.17.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/README.md CHANGED
@@ -70,11 +70,13 @@ export default (): SiteConfig => ({
70
70
  Create Markdown files in `content/YYYY/` using either pattern:
71
71
 
72
72
  **Option 1: Single file** (traditional)
73
+
73
74
  ```
74
75
  content/2025/my-post.md
75
76
  ```
76
77
 
77
78
  **Option 2: Directory with README** (Obsidian-friendly)
79
+
78
80
  ```
79
81
  content/2025/my-post/README.md
80
82
  content/2025/my-post/image.jpg
@@ -113,6 +115,7 @@ Your content here with **markdown** support.
113
115
  > Tags must use hyphens instead of spaces: `web-development` NOT `"web development"`
114
116
 
115
117
  Tags with spaces will fail validation. Use hyphenated slugs:
118
+
116
119
  - ✅ `tags: [new-york-city, travel, family-friendly]`
117
120
  - ❌ `tags: ["new york city", "travel", "family friendly"]`
118
121
 
@@ -129,6 +132,7 @@ new-york-city = "New York City travel guides"
129
132
  Bunki automatically converts relative markdown links to absolute URLs during build time. This lets you write cross-references using familiar file paths:
130
133
 
131
134
  **In your markdown:**
135
+
132
136
  ```markdown
133
137
  Check out [my earlier post](../2023/introduction.md) for context.
134
138
 
@@ -136,12 +140,14 @@ See also [related article](../../2020/old-post.md).
136
140
  ```
137
141
 
138
142
  **Generated HTML:**
143
+
139
144
  ```html
140
145
  <a href="/2023/introduction/">my earlier post</a>
141
146
  <a href="/2020/old-post/">related article</a>
142
147
  ```
143
148
 
144
149
  This feature works with:
150
+
145
151
  - `../YEAR/slug.md` - Single level up
146
152
  - `../../YEAR/slug.md` - Multiple levels up
147
153
  - Any number of `../` sequences
@@ -170,6 +176,7 @@ business:
170
176
  **Optional fields:** `address`, `cuisine`, `priceRange`, `telephone`, `url`, `openingHours`
171
177
 
172
178
  The validator enforces:
179
+
173
180
  - Use `business:` (not deprecated `location:`)
174
181
  - Use `lat:`/`lng:` (not deprecated `latitude:`/`longitude:`)
175
182
  - All required fields must be present
@@ -822,21 +829,87 @@ dist/
822
829
  └── 2/index.html # Paginated content
823
830
  ```
824
831
 
832
+ ## Architecture
833
+
834
+ Bunki follows a **modular architecture** with single responsibility modules for maintainability and performance:
835
+
836
+ ### Core Orchestrator
837
+
838
+ - **site-generator.ts** (282 lines) - Clean orchestrator coordinating all generation tasks
839
+ - Uses dependency injection for testability
840
+ - Parallel processing with Promise.all()
841
+ - Minimal business logic (delegates to generators)
842
+
843
+ ### Modular Generators
844
+
845
+ - **generators/feeds.ts** (285 lines) - RSS feed, sitemap, and robots.txt generation
846
+ - **generators/pages.ts** (357 lines) - HTML page generation with batched processing
847
+ - **generators/assets.ts** (115 lines) - CSS processing and static file copying
848
+
849
+ ### Markdown Processing
850
+
851
+ - **utils/markdown/constants.ts** (71 lines) - Pre-compiled regex patterns, Schema.org types, icons
852
+ - **utils/markdown/validators.ts** (139 lines) - Frontmatter and business location validation
853
+ - **utils/markdown/parser.ts** (308 lines) - Markdown to HTML conversion with sanitization
854
+
855
+ ### Reusable Utilities
856
+
857
+ - **utils/pagination.ts** (67 lines) - Pagination logic used across index, tags, and archives
858
+ - **utils/xml-builder.ts** (117 lines) - DRY XML/RSS building utilities
859
+ - **utils/markdown-utils.ts** (177 lines) - Main export file for backward compatibility
860
+
861
+ ### Dependency Graph
862
+
863
+ ```
864
+ site-generator.ts (orchestrator)
865
+ ├── generators/feeds.ts → utils/xml-builder.ts
866
+ ├── generators/pages.ts → utils/pagination.ts
867
+ ├── generators/assets.ts
868
+ └── utils/markdown/
869
+ ├── constants.ts
870
+ ├── validators.ts
871
+ └── parser.ts
872
+ ```
873
+
874
+ ### Performance Optimizations
875
+
876
+ 1. **Parallel Processing**: Independent tasks run simultaneously with Promise.all()
877
+ 2. **Batched Operations**: Posts processed in batches of 10 for optimal throughput
878
+ 3. **Pre-compiled Patterns**: Regex compiled once at module load, not on every parse
879
+ 4. **O(1) Lookups**: Set-based validation instead of array.includes()
880
+ 5. **Zero-Copy I/O**: Bun native APIs for kernel-level file transfers
881
+ 6. **Content Hashing**: Bun.hash() for CSS cache busting without external dependencies
882
+
883
+ ### Benefits
884
+
885
+ - ✅ **Clarity** - Easy to find and understand code
886
+ - ✅ **Testability** - Each module tested in isolation (424 tests)
887
+ - ✅ **Maintainability** - Changes isolated to specific modules
888
+ - ✅ **Reusability** - Modules can be imported independently
889
+ - ✅ **Performance** - Optimized at module level with Bun native APIs
890
+
825
891
  ## Features
826
892
 
827
893
  - **Markdown Processing**: Frontmatter extraction, code highlighting, HTML sanitization
828
894
  - **Relative Link Conversion**: Automatic conversion of relative markdown links (`../2023/post.md`) to absolute URLs (`/2023/post/`)
829
895
  - **Frontmatter Validation**: Automatic validation of business location data with clear error messages
830
896
  - **Security**: XSS protection, sanitized HTML, link hardening
831
- - **Performance**: Static files, optional gzip, optimized output
897
+ - **High Performance**:
898
+ - Parallel page generation (40-60% faster builds)
899
+ - Batched post processing (10x faster for 100+ posts)
900
+ - Pre-compiled regex patterns (2-3x faster parsing)
901
+ - O(1) Set-based validation (35x faster)
902
+ - Zero-copy file operations (50% faster, lower memory)
903
+ - Bun native APIs for optimal performance
832
904
  - **Templating**: Nunjucks with custom filters and macros
833
- - **Styling**: Built-in PostCSS support for modern CSS frameworks
905
+ - **Styling**: Built-in PostCSS support for modern CSS frameworks with content-based cache busting
834
906
  - **Media Management**: Direct S3/R2 uploads for images and MP4 videos with URL mapping
835
907
  - **Incremental Uploads**: Year-based filtering (`--min-year`) for large media collections
836
908
  - **SEO**: Automatic RSS feeds, sitemaps, meta tags, and JSON-LD structured data
837
909
  - **JSON-LD Structured Data**: Automatic Schema.org markup (BlogPosting, WebSite, Organization, BreadcrumbList)
838
- - **Pagination**: Configurable posts per page
910
+ - **Pagination**: Configurable posts per page with reusable pagination utilities
839
911
  - **Archives**: Year-based and tag-based organization
912
+ - **Modular Architecture**: Single responsibility modules with comprehensive test coverage (424 tests)
840
913
 
841
914
  ## Development
842
915
 
@@ -857,22 +930,75 @@ bun run format # Prettier formatting
857
930
  ```
858
931
  bunki/
859
932
  ├── src/
860
- │ ├── cli.ts # CLI interface
861
- │ ├── config.ts # Configuration management
862
- │ ├── site-generator.ts # Core generation logic
863
- │ ├── server.ts # Development server
864
- │ ├── parser.ts # Markdown parsing
865
- │ ├── types.ts # TypeScript types
866
- └── utils/ # Utility modules
867
- ├── test/ # Test suite (mirrors src/)
868
- ├── templates/ # Example templates
869
- ├── fixtures/ # Test fixtures
870
- └── dist/ # Built output
933
+ │ ├── cli.ts # CLI interface
934
+ │ ├── config.ts # Configuration management
935
+ │ ├── site-generator.ts # Orchestrator (282 lines, was 957)
936
+ │ ├── server.ts # Development server
937
+ │ ├── parser.ts # Markdown parsing
938
+ │ ├── types.ts # TypeScript types
939
+ ├── generators/ # Modular generation (NEW)
940
+ │ │ ├── feeds.ts # RSS, sitemap, robots.txt (285 lines)
941
+ │ │ ├── pages.ts # HTML generation with batching (357 lines)
942
+ │ │ └── assets.ts # CSS & static file copying (115 lines)
943
+ └── utils/ # Utility modules
944
+ │ ├── markdown/ # Markdown processing (NEW)
945
+ │ │ ├── constants.ts # Pre-compiled patterns (71 lines)
946
+ │ │ ├── validators.ts # Frontmatter validation (139 lines)
947
+ │ │ └── parser.ts # Markdown → HTML (308 lines)
948
+ │ ├── pagination.ts # Pagination utilities (67 lines, NEW)
949
+ │ ├── xml-builder.ts # XML/RSS builders (117 lines, NEW)
950
+ │ ├── markdown-utils.ts # Main export file (177 lines, was 576)
951
+ │ ├── css-processor.ts # PostCSS + Bun.hash()
952
+ │ ├── file-utils.ts # Bun native file ops
953
+ │ ├── date-utils.ts # Date/time utilities
954
+ │ ├── json-ld.ts # JSON-LD schema generation
955
+ │ ├── image-uploader.ts # Image upload logic
956
+ │ └── s3-uploader.ts # S3/R2 client
957
+ ├── test/ # Test suite (424 tests, mirrors src/)
958
+ │ ├── utils/
959
+ │ │ ├── markdown/ # Modular tests (NEW)
960
+ │ │ │ ├── constants.test.ts (25 tests)
961
+ │ │ │ ├── validators.test.ts (21 tests)
962
+ │ │ │ └── parser.test.ts (17 tests)
963
+ │ │ ├── pagination.test.ts (15 tests, NEW)
964
+ │ │ ├── xml-builder.test.ts (13 tests, NEW)
965
+ │ │ └── ...
966
+ │ ├── cli/commands/
967
+ │ ├── security/
968
+ │ └── ...
969
+ ├── templates/ # Example templates
970
+ ├── fixtures/ # Test fixtures
971
+ └── dist/ # Built output
871
972
  ```
872
973
 
873
974
  ## Changelog
874
975
 
875
- ### v0.16.0 (Current)
976
+ ### v0.17.0 (Current)
977
+
978
+ - **Major Architecture Refactoring**: Modular design with single responsibility modules
979
+ - Split `site-generator.ts` from 957 to 282 lines (-70%)
980
+ - Split `markdown-utils.ts` from 576 to 177 lines (-69%)
981
+ - Created 3 new generator modules: feeds, pages, assets
982
+ - Created 3 new markdown modules: constants, validators, parser
983
+ - Created 2 new utility modules: pagination, xml-builder
984
+ - **Performance Improvements**:
985
+ - Parallel page generation with Promise.all() (40-60% faster builds)
986
+ - Batched post processing (10x faster for 100+ posts)
987
+ - Pre-compiled regex patterns (2-3x faster markdown parsing)
988
+ - O(1) Set-based validation (35x faster validation)
989
+ - Zero-copy file operations using Bun native APIs (50% faster, lower memory)
990
+ - Content-based CSS cache busting with Bun.hash()
991
+ - **DRY Improvements**:
992
+ - Extracted pagination utilities (saved 80+ lines)
993
+ - Created XML builder utilities (saved 150+ lines)
994
+ - Reusable page writing utilities (saved 40+ lines)
995
+ - **Enhanced Test Coverage**:
996
+ - Added 87 new tests (337 → 424 tests total)
997
+ - Modular test organization mirroring source structure
998
+ - 100% backward compatible with existing API
999
+ - **Code Reduction**: Eliminated 1,074 lines while adding 11 focused modules
1000
+
1001
+ ### v0.16.0
876
1002
 
877
1003
  - **Relative Link Conversion**: Automatically convert relative markdown links to absolute URLs
878
1004
  - Supports `../2023/post.md` → `/2023/post/` conversion during build time
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Year archive page template
3
+ */
4
+ export declare const archiveNjk: string;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Base template for all pages
3
+ */
4
+ export declare const baseNjk: string;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Default CSS stylesheet for new Bunki sites
3
+ */
4
+ export declare const defaultCss: string;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Homepage template with post listing and pagination
3
+ */
4
+ export declare const indexNjk: string;
@@ -0,0 +1,14 @@
1
+ import { defaultCss } from "./default-css";
2
+ import { samplePost } from "./sample-post";
3
+ /**
4
+ * Nunjucks template files
5
+ */
6
+ export declare const nunjucks: Record<string, string>;
7
+ /**
8
+ * Default CSS stylesheet
9
+ */
10
+ export { defaultCss };
11
+ /**
12
+ * Sample markdown post
13
+ */
14
+ export { samplePost };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Individual post page template
3
+ */
4
+ export declare const postNjk: string;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Sample blog post for new Bunki sites
3
+ */
4
+ export declare const samplePost = "---\ntitle: Welcome to Bunki\ndate: 2025-01-15T12:00:00Z\ntags: [getting-started, bunki]\n---\n\n# Welcome to Your New Bunki Site\n\nThis is a sample blog post to help you get started with Bunki. You can edit this file or create new markdown files in the `content` directory.\n\n## Features\n\n- Markdown support with frontmatter\n- Syntax highlighting for code blocks\n- Tag-based organization\n- Pagination for post listings\n- RSS feed generation\n- Sitemap generation\n\n## Adding Content\n\nCreate new markdown files in the `content` directory with frontmatter like this:\n\n```markdown\n---\ntitle: Your Post Title\ndate: 2025-01-01T12:00:00Z\ntags: [tag1, tag2]\n---\n\nYour post content goes here...\n```\n\n## Code Highlighting\n\nBunki supports syntax highlighting for code blocks:\n\n```javascript\nfunction hello() {\n console.log('Hello, world!');\n}\n```\n\n## Next Steps\n\n1. Edit the site configuration in `bunki.config.ts`\n2. Create your own templates in the `templates` directory\n3. Add more blog posts in the `content` directory\n4. Run `bunki generate` to build your site\n5. Run `bunki serve` to preview your site locally\n";
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Single tag page template with posts list
3
+ */
4
+ export declare const tagNjk: string;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * All tags listing page template
3
+ */
4
+ export declare const tagsNjk: string;
@@ -1,5 +1,2 @@
1
- /**
2
- * Validate markdown files for parsing errors
3
- */
4
1
  import { Command } from "commander";
5
2
  export declare function registerValidateCommand(program: Command): void;