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 +316 -0
- package/LICENSE +1 -1
- package/README.md +257 -443
- package/docs/BROWSER.md +44 -34
- package/docs/GUIDE.md +1445 -0
- package/docs/INTERNALS.md +857 -0
- package/docs/PHILOSOPHY.md +624 -0
- package/docs/WHY-NOT-COFFEESCRIPT.md +7 -5
- package/docs/WHY-YES-RIP.md +227 -22
- package/docs/dist/rip.browser.js +2764 -532
- package/docs/dist/rip.browser.min.js +568 -225
- package/docs/dist/rip.browser.min.js.br +0 -0
- package/docs/examples/README.md +5 -5
- package/docs/index.html +1 -60
- package/docs/repl.html +437 -25
- package/package.json +10 -7
- package/src/browser.js +1 -2
- package/src/compiler.js +7845 -172
- package/src/grammar/grammar.rip +72 -0
- package/src/grammar/solar.rip +27 -23
- package/src/lexer.js +310 -6
- package/src/parser.js +223 -206
- package/src/repl.js +97 -1
- package/src/tags.js +62 -0
- package/docs/CODEGEN.md +0 -1023
- package/docs/COFFEESCRIPT-COMPARISON.md +0 -740
- package/docs/COMPREHENSIONS.md +0 -572
- package/docs/REGEX-PLUS.md +0 -441
- package/docs/SOLAR.md +0 -912
- package/docs/SPECIAL-OPERATORS.md +0 -769
- package/docs/STRING.md +0 -363
- package/docs/WHY-S-EXPRESSIONS.md +0 -834
- package/docs/WORKFLOW.md +0 -306
- package/docs/favicon.zip +0 -0
- package/src/codegen.js +0 -5264
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