melina 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/ARCHITECTURE.md +115 -0
- package/CHANGELOG.md +53 -0
- package/CONTRIBUTING.md +132 -0
- package/GUIDE.md +950 -538
- package/README.md +236 -131
- package/package.json +9 -3
- package/src/IslandOrchestrator.tsx +2 -2
- package/src/Link.tsx +65 -65
- package/src/client.ts +1286 -0
- package/src/island.ts +69 -69
- package/src/plugin.ts +283 -236
- package/src/router.ts +5 -3
- package/src/runtime/hangar.ts +399 -399
- package/src/web.ts +1647 -1324
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Melina.js Architecture Overview
|
|
2
|
+
|
|
3
|
+
> For the complete technical deep dive, see [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md)
|
|
4
|
+
|
|
5
|
+
## The Big Picture
|
|
6
|
+
|
|
7
|
+
Melina.js is a **runtime-native** web framework that eliminates traditional frontend toolchains:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Traditional: Source → Webpack → Babel → PostCSS → Disk → Serve
|
|
11
|
+
Melina.js: Source → Bun.build() → Memory → Serve
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Core Architecture
|
|
15
|
+
|
|
16
|
+
### 1. Islands Architecture
|
|
17
|
+
|
|
18
|
+
Only interactive components hydrate in the browser:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌─────────────────────────────────────────────────────────┐
|
|
22
|
+
│ Static HTML │
|
|
23
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
24
|
+
│ │ Counter │ │ SearchBar│ │ JobTracker│ ← Islands │
|
|
25
|
+
│ │ (React) │ │ (React) │ │ (React) │ │
|
|
26
|
+
│ └──────────┘ └──────────┘ └──────────┘ │
|
|
27
|
+
└─────────────────────────────────────────────────────────┘
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. The Two Zones
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
<body>
|
|
34
|
+
{/* ZONE 1: Persistent (never unmounts) */}
|
|
35
|
+
<header><SearchBar /></header>
|
|
36
|
+
|
|
37
|
+
{/* ZONE 2: Swappable (replaced on navigation) */}
|
|
38
|
+
<main id="melina-page-content">
|
|
39
|
+
{children}
|
|
40
|
+
</main>
|
|
41
|
+
|
|
42
|
+
{/* ZONE 1: Persistent */}
|
|
43
|
+
<footer><JobTracker /></footer>
|
|
44
|
+
</body>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. The Hangar Architecture
|
|
48
|
+
|
|
49
|
+
A single, persistent React root manages all islands:
|
|
50
|
+
|
|
51
|
+
- **Single Root** — One React root at `document.documentElement`
|
|
52
|
+
- **Portal-Based Rendering** — Islands are "docked" into placeholders
|
|
53
|
+
- **Surgical Updates** — Only swapped content triggers new hydration
|
|
54
|
+
- **Storage Nodes** — Browser-native state (focus, audio, iframes) preserved
|
|
55
|
+
|
|
56
|
+
### 4. In-Memory Build System
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// No dist/ folder - assets live in RAM
|
|
60
|
+
const result = await Bun.build({
|
|
61
|
+
entrypoints: [file],
|
|
62
|
+
outdir: undefined, // ← Memory only
|
|
63
|
+
target: 'browser',
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 5. Browser-Native Dependencies
|
|
68
|
+
|
|
69
|
+
Import Maps instead of vendor bundles:
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<script type="importmap">
|
|
73
|
+
{
|
|
74
|
+
"imports": {
|
|
75
|
+
"react": "https://esm.sh/react@19.1.1",
|
|
76
|
+
"react-dom/client": "https://esm.sh/react-dom@19.1.1/client"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
</script>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Key Concepts
|
|
83
|
+
|
|
84
|
+
| Concept | Description |
|
|
85
|
+
|---------|-------------|
|
|
86
|
+
| **Server Graph** | Layouts/pages render on Bun, output HTML |
|
|
87
|
+
| **Client Graph** | Islands hydrate in browser with React |
|
|
88
|
+
| **Partial Swaps** | Only `#melina-page-content` changes |
|
|
89
|
+
| **View Transitions** | Native CSS morphing between pages |
|
|
90
|
+
| **Event Bus** | Cross-island communication pattern |
|
|
91
|
+
|
|
92
|
+
## File Structure
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
app/
|
|
96
|
+
├── layout.tsx → Root layout (persistent)
|
|
97
|
+
├── page.tsx → / route
|
|
98
|
+
├── about/page.tsx → /about route
|
|
99
|
+
├── blog/[slug]/page.tsx → /blog/:slug (dynamic)
|
|
100
|
+
├── api/hello/route.ts → API endpoint
|
|
101
|
+
└── components/
|
|
102
|
+
└── Counter.tsx → 'use client' island
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Trade-offs
|
|
106
|
+
|
|
107
|
+
| Benefit | Trade-off |
|
|
108
|
+
|---------|-----------|
|
|
109
|
+
| ⚡ Sub-100ms builds | 🔒 Requires Bun runtime |
|
|
110
|
+
| 📦 Minimal JavaScript | 🌐 CDN dependency (esm.sh) |
|
|
111
|
+
| 🎯 Zero configuration | 🧠 Islands mental model |
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
**[Read the full Architecture Deep Dive →](./docs/ARCHITECTURE.md)**
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2026-01-31
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Hangar Architecture** — Single persistent React root with portal-based rendering
|
|
12
|
+
- **High-Fidelity State Persistence** — Islands in layouts survive navigation without state loss
|
|
13
|
+
- **View Transitions API** — Native CSS morphing between pages with `view-transition-name`
|
|
14
|
+
- **Storage Nodes** — Browser-native state (focus, audio playback, iframes) preserved across navigation
|
|
15
|
+
- **`melina:navigation-start` event** — Fired before navigation for View Transition coordination
|
|
16
|
+
- **Improved documentation** — Comprehensive developer guide and architecture deep dive
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- Navigation now uses "Fetch-Before-Transition" orchestration pattern
|
|
20
|
+
- Islands are managed by unified IslandManager instead of individual roots
|
|
21
|
+
- Props desynchronization is now documented as intentional trade-off
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- View Transitions now correctly capture snapshots before DOM changes
|
|
25
|
+
- Duplicate `view-transition-name` errors during navigation
|
|
26
|
+
- Ghost artifacts ("Black Hole" effect) eliminated
|
|
27
|
+
- Unix socket cleanup on server restart
|
|
28
|
+
|
|
29
|
+
## [0.2.0] - 2026-01-15
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- **Partial Page Swaps** — SPA-like navigation without client-side routing
|
|
33
|
+
- **Persistent Islands** — Islands in layout survive navigation
|
|
34
|
+
- **`melina:navigated` event** — Fired after navigation completes
|
|
35
|
+
- Nested layouts support
|
|
36
|
+
- Dynamic route segments (`[slug]`)
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- Client components now require `island()` wrapper
|
|
40
|
+
- Navigation uses `#melina-page-content` container
|
|
41
|
+
|
|
42
|
+
## [0.1.0] - 2026-01-01
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- Initial release
|
|
46
|
+
- File-based routing (Next.js App Router style)
|
|
47
|
+
- Islands architecture with selective hydration
|
|
48
|
+
- In-memory build system using `Bun.build()`
|
|
49
|
+
- Import Maps for browser-native module resolution
|
|
50
|
+
- Tailwind CSS v4 integration
|
|
51
|
+
- `<Link>` component for navigation
|
|
52
|
+
- API routes (`route.ts`)
|
|
53
|
+
- CLI commands (`melina init`, `melina start`)
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Contributing to Melina.js
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to Melina.js! 🦊
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- [Bun](https://bun.sh) v1.2 or higher
|
|
10
|
+
- Git
|
|
11
|
+
|
|
12
|
+
### Setup
|
|
13
|
+
|
|
14
|
+
1. Fork the repository
|
|
15
|
+
2. Clone your fork:
|
|
16
|
+
```bash
|
|
17
|
+
git clone https://github.com/YOUR_USERNAME/melina.js.git
|
|
18
|
+
cd melina.js
|
|
19
|
+
```
|
|
20
|
+
3. Install dependencies:
|
|
21
|
+
```bash
|
|
22
|
+
bun install
|
|
23
|
+
```
|
|
24
|
+
4. Run the example app:
|
|
25
|
+
```bash
|
|
26
|
+
cd examples/app-router
|
|
27
|
+
bun run dev
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Development Workflow
|
|
31
|
+
|
|
32
|
+
### Project Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
melina.js/
|
|
36
|
+
├── src/ # Source code
|
|
37
|
+
│ ├── web.ts # Main server & router
|
|
38
|
+
│ ├── island.ts # Island helper
|
|
39
|
+
│ ├── Link.tsx # Link component
|
|
40
|
+
│ └── runtime/ # Client-side runtime
|
|
41
|
+
├── bin/ # CLI
|
|
42
|
+
├── docs/ # Documentation
|
|
43
|
+
├── examples/ # Example applications
|
|
44
|
+
└── tests/ # Test suite
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Running Tests
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
bun test
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Testing Changes
|
|
54
|
+
|
|
55
|
+
The best way to test changes is with the example apps in `examples/`:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cd examples/app-router
|
|
59
|
+
bun run dev
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Making Changes
|
|
63
|
+
|
|
64
|
+
### Code Style
|
|
65
|
+
|
|
66
|
+
- TypeScript for all source files
|
|
67
|
+
- Use clear, descriptive variable names
|
|
68
|
+
- Add JSDoc comments for public APIs
|
|
69
|
+
- Keep functions small and focused
|
|
70
|
+
|
|
71
|
+
### Commit Messages
|
|
72
|
+
|
|
73
|
+
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
feat: add View Transitions support
|
|
77
|
+
fix: resolve props desynchronization in persistent islands
|
|
78
|
+
docs: update API reference
|
|
79
|
+
chore: update dependencies
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Pull Requests
|
|
83
|
+
|
|
84
|
+
1. Create a feature branch:
|
|
85
|
+
```bash
|
|
86
|
+
git checkout -b feat/my-feature
|
|
87
|
+
```
|
|
88
|
+
2. Make your changes
|
|
89
|
+
3. Write/update tests as needed
|
|
90
|
+
4. Update documentation if applicable
|
|
91
|
+
5. Push and create a PR
|
|
92
|
+
|
|
93
|
+
## Areas for Contribution
|
|
94
|
+
|
|
95
|
+
### Good First Issues
|
|
96
|
+
|
|
97
|
+
- Documentation improvements
|
|
98
|
+
- Example apps
|
|
99
|
+
- Bug fixes with clear reproduction steps
|
|
100
|
+
|
|
101
|
+
### Larger Contributions
|
|
102
|
+
|
|
103
|
+
- New features (please open an issue first to discuss)
|
|
104
|
+
- Performance optimizations
|
|
105
|
+
- TypeScript type improvements
|
|
106
|
+
|
|
107
|
+
## Architecture Notes
|
|
108
|
+
|
|
109
|
+
### Key Concepts
|
|
110
|
+
|
|
111
|
+
- **Islands Architecture**: Only interactive components hydrate
|
|
112
|
+
- **Hangar**: Single persistent React root managing all islands
|
|
113
|
+
- **Partial Swaps**: Only `#melina-page-content` is replaced
|
|
114
|
+
- **In-Memory Builds**: No `dist/` folder, assets in RAM
|
|
115
|
+
|
|
116
|
+
### Files to Know
|
|
117
|
+
|
|
118
|
+
| File | Purpose |
|
|
119
|
+
|------|---------|
|
|
120
|
+
| `src/web.ts` | Server, router, build system |
|
|
121
|
+
| `src/island.ts` | `island()` helper for client components |
|
|
122
|
+
| `src/runtime/hangar.ts` | Client-side island management |
|
|
123
|
+
| `src/Link.tsx` | Navigation component |
|
|
124
|
+
|
|
125
|
+
## Questions?
|
|
126
|
+
|
|
127
|
+
- Open an [issue](https://github.com/mements/melina.js/issues)
|
|
128
|
+
- Check existing [discussions](https://github.com/mements/melina.js/discussions)
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|