rip-lang 3.5.0 → 3.6.1

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
@@ -7,14 +7,16 @@ All notable changes to Rip will be documented in this file.
7
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
8
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
- ## [3.5.0] - 2026-02-10
10
+ ## [3.6.0] - 2026-02-10
11
11
 
12
- ### Browser Runtime Enhancements
12
+ ### Browser Runtime — Full Async/Await Support
13
13
 
14
- - **`importRip(url)`**New function to fetch, compile, and import `.rip` files as ES modules via blob URL. Registered on `globalThis` for use in `<script type="text/rip">` blocks.
15
- - **Async `<script type="text/rip">`** `processRipScripts` now wraps compiled code in an async IIFE, enabling `await` (Rip's `!` operator) in inline scripts.
16
- - **Eager reactive runtime** — `globalThis.__rip` is registered when `rip.browser.js` loads, making reactive primitives available to framework code without the compiler needing to detect reactive operators.
17
- - **`compileToJS` on globalThis** — The compiler function is now globally accessible, enabling auto-detection by framework code like `launch()`.
14
+ - **`rip()` console REPL** Wraps user code in a Rip `do ->` block, so the compiler handles implicit return and auto-async natively. Sync code returns values directly; async code returns a Promise (use `await rip("...")` in the console). Variables persist on `globalThis` across calls.
15
+ - **`importRip(url)`** Fetch, compile, and import `.rip` files as ES modules via blob URL. Registered on `globalThis` for use in `<script type="text/rip">` blocks.
16
+ - **Async `<script type="text/rip">`** — `processRipScripts` wraps compiled code in an async IIFE, enabling `await` (Rip's `!` operator) in inline scripts.
17
+ - **Playground**Run button uses async IIFE for `await` support. Cmd+Enter shortcut registered on Monaco editor.
18
+ - **Eager reactive runtime** — `globalThis.__rip` is registered when `rip.browser.js` loads, making reactive primitives available to framework code.
19
+ - **`compileToJS` on globalThis** — The compiler function is globally accessible for framework auto-detection.
18
20
 
19
21
  ## [3.4.3] - 2026-02-09
20
22
 
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.5.0-blue.svg" alt="Version"></a>
12
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.6.0-blue.svg" alt="Version"></a>
13
13
  <a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
14
14
  <a href="#"><img src="https://img.shields.io/badge/tests-1140%2F1140-brightgreen.svg" alt="Tests"></a>
15
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
@@ -264,17 +264,25 @@ Smaller codebase, modern output, built-in reactivity.
264
264
 
265
265
  ## Browser
266
266
 
267
- Run Rip directly in the browser:
267
+ Run Rip directly in the browser — inline scripts and the console REPL both support `await` via the `!` operator:
268
268
 
269
269
  ```html
270
- <script src="https://shreeve.github.io/rip-lang/docs/dist/rip.browser.min.js"></script>
270
+ <script type="module" src="/rip/browser.js"></script>
271
271
  <script type="text/rip">
272
- def greet(name)
273
- console.log "Hello, #{name}!"
274
- greet "World"
272
+ res = fetch! 'https://api.example.com/data'
273
+ data = res.json!
274
+ console.log data
275
275
  </script>
276
276
  ```
277
277
 
278
+ The `rip()` function is available in the browser console:
279
+
280
+ ```javascript
281
+ rip("42 * 10 + 8") // → 428
282
+ rip("(x * x for x in [1..5])") // → [1, 4, 9, 16, 25]
283
+ await rip("res = fetch! 'https://api.example.com/todos/1'; res.json!") // → {id: 1, ...}
284
+ ```
285
+
278
286
  **Try it live:** [shreeve.github.io/rip-lang](https://shreeve.github.io/rip-lang/)
279
287
 
280
288
  ---
@@ -299,7 +307,7 @@ Simple arrays (with `.loc`) instead of AST node classes. The compiler is self-ho
299
307
  | Grammar | `src/grammar/grammar.rip` | 935 |
300
308
  | Parser Generator | `src/grammar/solar.rip` | 916 |
301
309
  | REPL | `src/repl.js` | 707 |
302
- | Browser Entry | `src/browser.js` | 107 |
310
+ | Browser Entry | `src/browser.js` | 119 |
303
311
  | Tags | `src/tags.js` | 63 |
304
312
  | **Total** | | **~10,325** |
305
313
 
@@ -311,7 +319,7 @@ Rip includes optional packages for full-stack development:
311
319
 
312
320
  | Package | Version | Purpose |
313
321
  |---------|---------|---------|
314
- | [rip-lang](https://www.npmjs.com/package/rip-lang) | 3.5.0 | Core language compiler |
322
+ | [rip-lang](https://www.npmjs.com/package/rip-lang) | 3.6.0 | Core language compiler |
315
323
  | [@rip-lang/api](packages/api/) | 1.1.4 | HTTP framework (Sinatra-style routing, 37 validators) |
316
324
  | [@rip-lang/server](packages/server/) | 1.1.3 | Multi-worker app server (hot reload, HTTPS, mDNS) |
317
325
  | [@rip-lang/db](packages/db/) | 1.1.2 | DuckDB server with official UI (pure Bun FFI) |
package/docs/RIP-GUIDE.md CHANGED
@@ -534,6 +534,57 @@ user.save!()
534
534
 
535
535
  ---
536
536
 
537
+ ## Browser
538
+
539
+ Rip runs directly in the browser with full async/await support — no build step.
540
+
541
+ ### Inline Scripts
542
+
543
+ Load the compiler, then write Rip:
544
+
545
+ ```html
546
+ <script type="module" src="/rip/browser.js"></script>
547
+ <script type="text/rip">
548
+ res = fetch! 'https://api.example.com/data'
549
+ data = res.json!
550
+ console.log data
551
+ </script>
552
+ ```
553
+
554
+ The `!` operator works in inline scripts — `processRipScripts` wraps
555
+ compiled code in an async IIFE transparently.
556
+
557
+ ### Console REPL
558
+
559
+ The `rip()` function is available in any browser console where `rip.browser.js`
560
+ is loaded:
561
+
562
+ ```javascript
563
+ rip("42 * 10 + 8") // → 428
564
+ rip("name = 'Alice'") // → 'Alice' (persists on globalThis)
565
+ rip("(x * x for x in [1..5])") // → [1, 4, 9, 16, 25]
566
+
567
+ // Async — use await, Chrome displays the resolved value
568
+ await rip("res = fetch! 'https://jsonplaceholder.typicode.com/todos/1'; res.json!")
569
+ // → {userId: 1, id: 1, title: 'delectus aut autem', completed: false}
570
+ ```
571
+
572
+ Sync code returns values directly. Async code (using `!`) returns a Promise
573
+ that Chrome auto-awaits. Variables persist between calls on `globalThis`.
574
+
575
+ ### `importRip(url)`
576
+
577
+ Fetch, compile, and import a `.rip` file as an ES module:
578
+
579
+ ```html
580
+ <script type="text/rip">
581
+ { launch } = importRip! '/rip/ui.rip'
582
+ launch '/demo'
583
+ </script>
584
+ ```
585
+
586
+ ---
587
+
537
588
  ## Full-Stack Example
538
589
 
539
590
  A complete API server in Rip:
@@ -7560,8 +7560,8 @@ function getComponentRuntime() {
7560
7560
  return new CodeGenerator({}).getComponentRuntime();
7561
7561
  }
7562
7562
  // src/browser.js
7563
- var VERSION = "3.5.0";
7564
- var BUILD_DATE = "2026-02-10@20:22:29GMT";
7563
+ var VERSION = "3.6.1";
7564
+ var BUILD_DATE = "2026-02-11@00:29:14GMT";
7565
7565
  if (typeof globalThis !== "undefined" && !globalThis.__rip) {
7566
7566
  new Function(getReactiveRuntime())();
7567
7567
  }
@@ -7612,10 +7612,19 @@ async function importRip(url) {
7612
7612
  }
7613
7613
  function rip(code) {
7614
7614
  try {
7615
- const js = compileToJS(code);
7616
- let persistentJs = js.replace(/^let\s+[^;]+;\s*\n\s*/m, "");
7617
- persistentJs = persistentJs.replace(/^const\s+/gm, "var ");
7618
- const result = (1, eval)(persistentJs);
7615
+ const indented = code.replace(/^/gm, " ");
7616
+ const wrapped = compileToJS(`do ->
7617
+ ${indented}`);
7618
+ let js = wrapped.replace(/^let\s+[^;]+;\s*\n\s*/m, "");
7619
+ js = js.replace(/^const\s+(\w+)\s*=/gm, "globalThis.$1 =");
7620
+ const result = (0, eval)(js);
7621
+ if (result && typeof result.then === "function") {
7622
+ return result.then((v) => {
7623
+ if (v !== undefined)
7624
+ globalThis._ = v;
7625
+ return v;
7626
+ });
7627
+ }
7619
7628
  if (result !== undefined)
7620
7629
  globalThis._ = result;
7621
7630
  return result;