rip-lang 1.5.7 β†’ 2.5.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/CHANGELOG.md CHANGED
@@ -1,3 +1,5 @@
1
+ <p><img src="docs/rip.svg" alt="Rip Logo" width="100"></p>
2
+
1
3
  # Changelog
2
4
 
3
5
  All notable changes to Rip will be documented in this file.
@@ -5,6 +7,320 @@ All notable changes to Rip will be documented in this file.
5
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
9
 
10
+ ## [2.5.0] - 2026-01-16
11
+
12
+ ### Major Release - Parser Optimization + Complete Framework
13
+
14
+ This release consolidates all improvements since 2.2.1 into a polished, well-documented package. Rip is now a complete language AND reactive framework in just 51KB (Brotli compressed).
15
+
16
+ ---
17
+
18
+ ### πŸš€ Parser Optimization
19
+
20
+ **Interleaved Delta-Encoded Parse Table** - Major size reduction for the generated parser:
21
+ - New format in `solar.rip`: `[count, Ξ”key₁, Ξ”keyβ‚‚..., val₁, valβ‚‚...]` per state
22
+ - **31% smaller Brotli** for parser alone (19.2KB β†’ 13.2KB)
23
+ - **17% faster module load** time
24
+ - Identical runtime performance (same data structure after decode)
25
+ - Solar parser generator now **250Γ— faster** than Jison
26
+
27
+ ---
28
+
29
+ ### ✨ New Language Features
30
+
31
+ **Ruby-Style Constructor Syntax**:
32
+ ```coffee
33
+ # Both are equivalent
34
+ counter = new Counter()
35
+ counter = Counter.new() # Ruby-style - elegant!
36
+
37
+ # Works with arguments
38
+ user = User.new("Alice", 30)
39
+
40
+ # Chainable
41
+ Counter.new().mount("#app")
42
+ ```
43
+
44
+ **"Equal, Dammit!" Operator (`=!`)**:
45
+ ```coffee
46
+ # Regular assignment β†’ let (can reassign)
47
+ host = "localhost"
48
+ host = "example.com" # OK
49
+
50
+ # Equal, dammit! β†’ const (can't reassign)
51
+ API_URL =! "https://api.example.com"
52
+ API_URL = "other" # Error! const cannot be reassigned
53
+ ```
54
+ Note: `=!` compiles to plain `const` - does NOT pull in the reactive runtime.
55
+
56
+ **Smart Two-Way Binding**:
57
+ ```coffee
58
+ # Automatically uses valueAsNumber for number/range inputs
59
+ input type: "number", value <=> count # No .valueAsNumber needed!
60
+ input type: "range", value <=> volume # Just works!
61
+ ```
62
+
63
+ ---
64
+
65
+ ### 🎨 Template & Component Improvements
66
+
67
+ **Pug-Style Shorthand**:
68
+ ```coffee
69
+ # Implicit div for class-only selectors
70
+ .card # β†’ <div class="card">
71
+ .btn.primary # β†’ <div class="btn primary">
72
+
73
+ # Nested shorthand works correctly
74
+ .container
75
+ .row
76
+ .col "Content"
77
+ ```
78
+
79
+ **Dynamic Class Syntax**:
80
+ ```coffee
81
+ div.("bg-white rounded-lg shadow-md") # Static Tailwind classes
82
+ button.(active && "bg-blue-500") # Conditional classes
83
+ ```
84
+
85
+ **Component Mount with Selectors**:
86
+ ```coffee
87
+ # Both work
88
+ Counter.new().mount(document.body)
89
+ Counter.new().mount("#app") # Selector string support
90
+ ```
91
+
92
+ ---
93
+
94
+ ### πŸ–₯️ Browser REPL Enhancements
95
+
96
+ **Live Demo Tab** (now default):
97
+ - Interactive component demos
98
+ - Temperature converter, counter examples
99
+ - Real-time reactive updates
100
+
101
+ **UI Improvements**:
102
+ - Tab state persists in URL hash
103
+ - No flash of wrong tab on page load
104
+ - Consistent pane header heights
105
+ - GitHub icon link in header
106
+
107
+ **Demo Improvements**:
108
+ - Shows `@prop` syntax for component props
109
+ - Uses Ruby-style `.new()` syntax
110
+ - Fat arrows for proper `this` binding
111
+
112
+ ---
113
+
114
+ ### πŸ“š Documentation Overhaul
115
+
116
+ **Consolidated Documentation** - 13 files merged into 4 main docs:
117
+ - `docs/GUIDE.md` - Language features, reactivity, templates, components
118
+ - `docs/INTERNALS.md` - Compiler architecture, S-expressions, Solar
119
+ - `docs/PHILOSOPHY.md` - Design principles, CoffeeScript comparison
120
+ - `docs/BROWSER.md` - Browser usage, REPL, deployment
121
+
122
+ **Kept Separate** (referenced from PHILOSOPHY.md):
123
+ - `docs/WHY-NOT-COFFEESCRIPT.md` - The case against CoffeeScript
124
+ - `docs/WHY-YES-RIP.md` - The case for Rip
125
+
126
+ **Updated Statistics**:
127
+ - ~14,000 LOC total (smaller than CoffeeScript's 17,760, yet includes full reactive framework)
128
+ - 51KB browser bundle (compiler + reactive runtime + templates + components)
129
+ - 1046 tests passing
130
+ - Solar: ~1,000 LOC, 250Γ— faster than Jison
131
+
132
+ ---
133
+
134
+ ### πŸ”§ Internal Improvements
135
+
136
+ **Compiler Consolidation**:
137
+ - Merged `codegen.js` into `compiler.js` (single file for all code generation)
138
+ - Renamed `docs/CODEGEN.md` to `docs/COMPILER.md`
139
+
140
+ **Project Cleanup**:
141
+ - Deleted unused `src/runtime.js` (runtime now embedded in compiler output)
142
+ - Deleted redundant `docs/demo.html`
143
+ - Overhauled `AGENT.md` for accuracy
144
+ - Added `notes.txt` to `.gitignore`
145
+
146
+ **Bug Fixes**:
147
+ - Fixed `<=>` two-way binding in components
148
+ - Fixed reactive variable shadowing in function bodies
149
+ - Fixed nested Pug-style shorthand in render blocks
150
+ - Fixed `generateParam` bug
151
+ - Consistent name handling in `generateReadonly`
152
+
153
+ ---
154
+
155
+ ### πŸ“Š Updated Scores
156
+
157
+ | Category | Score | Notes |
158
+ |----------|-------|-------|
159
+ | **Reactivity** | A+ | Fine-grained, signals, effects |
160
+ | **Templates** | A | S-expressions, Pug shorthand |
161
+ | **Components** | A | Props, lifecycle, context API |
162
+ | **Performance** | A | 250Γ— faster parser gen, 51KB bundle |
163
+
164
+ ---
165
+
166
+ ### Summary
167
+
168
+ **What's in 51KB?**
169
+ - Complete compiler (lexer, parser, code generator)
170
+ - Reactive runtime (signals, derived values, effects)
171
+ - Template engine (S-expression syntax, dynamic classes)
172
+ - Component system (props, lifecycle, fine-grained updates)
173
+ - Zero dependencies
174
+
175
+ **Comparison**:
176
+ - React (min+gzip): ~42KB (just the library, no compiler)
177
+ - Vue (min+gzip): ~34KB (just the library, no compiler)
178
+ - **Rip: 51KB (complete language + framework, runs anywhere!)**
179
+
180
+ ---
181
+
182
+ ## [2.2.1] - 2026-01-15
183
+
184
+ ### Added - Context API & Error Primitives
185
+
186
+ **Context API** - Pass data through component trees without prop drilling:
187
+ - `setContext(key, value)` - Set context in current component
188
+ - `getContext(key)` - Get context from nearest ancestor
189
+ - `hasContext(key)` - Check if context exists
190
+
191
+ **Error Primitives** - Low-level building blocks for error handling:
192
+ - `__catchErrors(fn)` - Wrap function to route errors to handler
193
+ - `__handleError(error)` - Route error to handler or rethrow
194
+ - `__setErrorHandler(fn)` - Set current error handler
195
+
196
+ **Dynamic Class Syntax** - Cleaner Tailwind support:
197
+ ```coffee
198
+ div.("bg-white rounded-lg shadow-md") # Static classes
199
+ button.(active && "bg-blue-500") # Conditional classes
200
+ ```
201
+
202
+ **Other Improvements**:
203
+ - Components now track parent via `_parent` pointer
204
+ - Batching optimization with `__batch()` for grouped updates
205
+ - Improved reactive runtime documentation (~330 lines total)
206
+
207
+ **Updated Scores**:
208
+ - Components: B+ β†’ A- (Context API implemented)
209
+ - Tests: 1017 β†’ 1033
210
+
211
+ ---
212
+
213
+ ## [2.2.0] - 2026-01-15
214
+
215
+ ### Added - Keyed Reconciliation & Per-Item Effects
216
+
217
+ **The Final Boss: True Svelte-Class Performance**
218
+
219
+ Lists now have O(1) performance for ALL operations:
220
+ - **Add item**: Create 1 node (not rebuild all)
221
+ - **Remove item**: Remove 1 node (not rebuild all)
222
+ - **Reorder**: Move existing nodes (not recreate)
223
+ - **Selection change**: Per-item effects update independently
224
+
225
+ **Key Features**:
226
+ - Keyed reconciliation via `key:` attribute
227
+ - Per-item effects with proper cleanup
228
+ - Conditional effect cleanup (no memory leaks)
229
+ - Effect disposal on item removal
230
+
231
+ **Example**:
232
+ ```coffee
233
+ for item, i in items
234
+ li key: item.id, class: (i == selected && "selected"), item.name
235
+ ```
236
+
237
+ Each item gets its own effect. Changing `selected` updates ONLY the affected classes, not the whole list.
238
+
239
+ ---
240
+
241
+ ## [2.1.0] - 2026-01-15
242
+
243
+ ### Added - Fine-Grained Reactivity
244
+
245
+ **MAJOR PERFORMANCE IMPROVEMENT**: Components now update only specific DOM nodes that changed, not the entire tree. This brings Rip to Svelte-class performance.
246
+
247
+ **Architecture Change**:
248
+ - Before: `render()` recreates all DOM on every state change
249
+ - After: `_create()` builds DOM once, `_setup()` wires minimal effects
250
+
251
+ **Performance**:
252
+ - Text binding: O(1) instead of O(n)
253
+ - Attribute binding: O(1) instead of O(n)
254
+ - **30-40x faster** for typical reactive updates
255
+
256
+ **New Features**:
257
+ - Fine-grained text bindings: `span count` β†’ effect updates just that text node
258
+ - Fine-grained attribute bindings: `div class: active` β†’ effect updates just that attribute
259
+ - Fine-grained conditionals: `if show` β†’ anchor-based content swapping
260
+ - Fine-grained loops: `for item in items` β†’ tracked node list
261
+ - Named slots: Props can be DOM nodes (`@header`, `@footer`, etc.)
262
+
263
+ **Updated Scores**:
264
+ - Reactivity: A β†’ A+
265
+ - Templates: A- β†’ A
266
+ - Components: A- β†’ A
267
+
268
+ ---
269
+
270
+ ## [2.0.0] - 2026-01-14
271
+
272
+ ### Added - Reactive UI Framework
273
+
274
+ **Phase 1: Reactivity** (previously released)
275
+ - Signal-based reactivity: `count = 0` creates reactive state
276
+ - Derived values: `doubled ~= count * 2` auto-tracks dependencies
277
+ - Effects: `effect -> console.log count` runs on changes
278
+ - Runtime: `__signal()`, `__computed()`, `__effect()`, `__batch()`, `__readonly()`
279
+
280
+ **Phase 2: Templates**
281
+ - Indentation-based template syntax in `render` blocks
282
+ - CSS-style selectors: `div#main.card.active`
283
+ - Event handlers: `@click: handler`
284
+ - Event modifiers: `@click.prevent.stop: handler`
285
+ - Two-way binding: `input value <=> username`
286
+ - Spread attributes: `div ...props`
287
+ - Dynamic classes: `div.('btn', isActive && 'active')` (clsx-style)
288
+ - Control flow: `if`/`else`, `for` loops in templates
289
+ - Special attributes: `key:`, `ref:`
290
+ - Multiple roots via `DocumentFragment`
291
+ - Runtime helpers: `h()`, `frag()`, `txt()`, `cx()`
292
+
293
+ **Phase 3: Components**
294
+ - `component` keyword for defining UI components
295
+ - Props system:
296
+ - Required: `@label`
297
+ - Optional: `@label?`
298
+ - Default: `@label = "default"`
299
+ - Rest: `@...rest`
300
+ - Reactive state within components (auto-signals)
301
+ - Derived values within components (auto-computed)
302
+ - Component composition: `Button label: "Click"` inside render
303
+ - Children/slots: `@children` prop for nested content
304
+ - Lifecycle hooks: `mounted:`, `unmounted:`
305
+ - Reactive re-rendering via effect-based mount
306
+
307
+ ### Changed
308
+ - Grammar extended with `component`, `render`, `style` keywords
309
+ - Lexer handles template contexts (ID selectors, arrow injection)
310
+ - Codegen generates ES6 classes for components
311
+
312
+ ### Technical Details
313
+ - Components compile to ES6 classes with constructor, render, mount, unmount
314
+ - Props validated at construction (required props throw if missing)
315
+ - State variables become `__signal()` calls
316
+ - Derived values become `__computed()` calls
317
+ - `mount()` wraps render in `__effect()` for reactive updates
318
+ - PascalCase names in templates trigger component instantiation
319
+
320
+ All 1033 tests passing (100%) βœ…
321
+
322
+ ---
323
+
8
324
  ## [1.5.7] - 2025-11-16
9
325
 
10
326
  ### Changed
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Steve Shreeve
3
+ Copyright (c) 2026 Steve Shreeve
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal