quickjs 0.15.1 → 0.17.0.pre

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54fe50175028245be99548bdb43a1884ceb956f77a999fca6c4cdf9ea9085a13
4
- data.tar.gz: ddbf8d46cfec89db687899ec083e7ef2859ebd4ff9d711c9a18801d15c8d4ad0
3
+ metadata.gz: 7b233c0e106654a50f4af274fef6a4dd77f0b53cc0a703473cda844da6ba3763
4
+ data.tar.gz: 50dfeaf56422ee74e8cb8711a58e1678c8141ac4bb7256a4d8861fa1a9415c93
5
5
  SHA512:
6
- metadata.gz: ce86220556d6e2bbf06f2da42227876f972a991e4beca36ecce89efcfc84f11ee6d62172813442368af11632f33f970db97535eab435f3fa6046be955c98529d
7
- data.tar.gz: 255c23efa72230afbac3760e1cd8efd8ba29038263371ed4a4bc591dfbc58da9e48e2524bde82151cb8b10d14cda87255170fe0c46377efec8cb114ea8e9a855
6
+ metadata.gz: 9f77f8b802055b1ec67ad9b4f45fb54cbdb1349a473457572c1c1b72115283bed9b99b15029e101256147ce0bbc72b64371fcbdd0ede6e8e9ba5e8d4a0bb0376
7
+ data.tar.gz: 9387e82c41c0242caa67c16a67b48a204c32512b116c5e4cc61d83e892bec053393facaf7ac2553642b876cacecb3622ddb37a846fd1eea959c21ea7df70b569
data/CLAUDE.md CHANGED
@@ -55,6 +55,14 @@ Tests use minitest with `describe`/`it` blocks. Key test files:
55
55
  - `test/quickjs_test.rb` — Main test suite (value conversion, errors, VM features, ESM imports, function definitions)
56
56
  - `test/quickjs_polyfill_test.rb` — Intl polyfill tests
57
57
 
58
+ ## Release Process
59
+
60
+ 1. On `main`, run `bundle exec rake polyfills:build` — rebuilds polyfill bundles and syncs `polyfills/package.json` version to match the gem version
61
+ 2. Bump `lib/quickjs/version.rb` and `Gemfile.lock` to the new version
62
+ 3. Commit `lib/quickjs/version.rb`, `Gemfile.lock`, `polyfills/package.json`, `polyfills/package-lock.json` as `"prepare vX.Y.Z"` — do NOT push; `rake release` handles that
63
+ 4. Run `bundle exec rake release` — tags, pushes to GitHub, and publishes to RubyGems (human step; do not run this as Claude)
64
+ 5. Create a GitHub release via `gh release create` with notes following the pattern of previous releases
65
+
58
66
  ## Build Notes
59
67
 
60
68
  - `extconf.rb` compiles with `-DNDEBUG` to avoid conflicts with Ruby 4.0 GC assertions
data/README.md CHANGED
@@ -85,6 +85,21 @@ vm.eval_code('a.b = "d";')
85
85
  vm.eval_code('a.b;') #=> "d"
86
86
  ```
87
87
 
88
+ #### `Quickjs::VM#compile`: 🚀 Cache parsed bundles as a `Quickjs::Runnable`
89
+
90
+ Parsing large JS bundles is the dominant cost of a fresh evaluation. `compile` parses once and returns a `Quickjs::Runnable` wrapping the serialized bytecode; `run(on:)` executes it on any VM of the same QuickJS build, skipping the parser. Useful when the same bundle is evaluated repeatedly across short-lived VMs (test environments, page-per-VM web emulators).
91
+
92
+ ```rb
93
+ runnable = Quickjs::VM.new.compile(File.read('big_bundle.js'), filename: 'big_bundle.js')
94
+
95
+ vm = Quickjs::VM.new
96
+ runnable.run(on: vm) # use the given VM (no parse cost)
97
+ runnable.run # spin up a fresh VM with default options
98
+ runnable.run(on: { features: [::Quickjs::POLYFILL_INTL] }) # ad-hoc VM with options
99
+ ```
100
+
101
+ `Runnable#to_s` returns the underlying bytecode as a frozen ASCII-8BIT `String`, suitable for caching to memory or disk. `Quickjs::Runnable.new(bytecode_string)` reconstructs a `Runnable` from that blob — validation happens lazily at `run` time, so a corrupt or wrong-build blob surfaces as `Quickjs::RuntimeError` when executed. The bytecode format is tied to the QuickJS build, so include the gem version in your cache key if you persist across upgrades.
102
+
88
103
  #### `Quickjs::VM#call`: ⚡ Call a JS function directly with Ruby arguments
89
104
 
90
105
  ```rb
@@ -129,6 +144,26 @@ vm.import('DefaultExport', from: File.read('exports.esm.js'))
129
144
  vm.import('* as all', from: File.read('exports.esm.js'))
130
145
  ```
131
146
 
147
+ #### `Quickjs::VM#module_loader=`: 🧩 Resolve `import` specifiers from Ruby
148
+
149
+ By default, `import` specifiers that aren't already loaded fall through to QuickJS's filesystem loader. Set a `module_loader` Proc to resolve specifiers in-memory instead — useful when the source code lives in a database, an importmap, or a virtual filesystem.
150
+
151
+ ```rb
152
+ vm = Quickjs::VM.new
153
+ modules = {
154
+ 'a' => "import { b } from 'b'; export const a = () => `a-${b()}`;",
155
+ 'b' => "export const b = () => 'b-result';"
156
+ }
157
+ vm.module_loader = ->(name) { modules[name] }
158
+
159
+ vm.import(['a'], filename: 'a')
160
+ vm.eval_code('a()') #=> 'a-b-result'
161
+ ```
162
+
163
+ The Proc receives the (already normalized) module specifier and returns the module source as a `String`, or `nil` to signal "not found" (which raises `Quickjs::ReferenceError` on the JS side). Pass `nil` to clear a previously set loader.
164
+
165
+ When `module_loader=` is set, pass `filename:` to `import` instead of `from:` to resolve a named specifier directly through the loader — no inline bridge source needed.
166
+
132
167
  #### `Quickjs::VM#define_function`: 💎 Define a global function for JS by Ruby
133
168
 
134
169
  ```rb
@@ -193,6 +228,37 @@ vm.eval_code('console.log("hello", 42)')
193
228
  # log.raw #=> Array of raw Ruby values
194
229
  ```
195
230
 
231
+ #### Memory management: 🔍 Inspect and control VM memory
232
+
233
+ ```rb
234
+ vm = Quickjs::VM.new
235
+
236
+ vm.memory_usage
237
+ # => { malloc_size: Integer, malloc_limit: Integer, memory_used_size: Integer,
238
+ # atom_count: Integer, str_count: Integer, obj_count: Integer,
239
+ # prop_count: Integer, shape_count: Integer,
240
+ # js_func_count: Integer, js_func_code_size: Integer,
241
+ # c_func_count: Integer, array_count: Integer }
242
+
243
+ vm.gc! # trigger a QuickJS GC cycle; returns nil
244
+
245
+ vm.memory_poisoned? #=> false (true once the VM has hit out-of-memory)
246
+ ```
247
+
248
+ When the JS heap exhausts its memory limit, QuickJS enters a fragile state where further evaluation can segfault the process. `memory_poisoned?` flips to `true` after such an event, and subsequent `eval_code` / `call` calls raise `Quickjs::RuntimeError` immediately instead of risking a crash. Rescue it and recreate the VM.
249
+
250
+ ```rb
251
+ vm = Quickjs::VM.new(memory_limit: 256 * 1024 * 1024)
252
+
253
+ begin
254
+ vm.eval_code(js)
255
+ rescue Quickjs::RuntimeError => e
256
+ raise unless vm.memory_poisoned?
257
+ vm = Quickjs::VM.new(memory_limit: 256 * 1024 * 1024)
258
+ retry
259
+ end
260
+ ```
261
+
196
262
  ### Value Conversion
197
263
 
198
264
  | JavaScript | | Ruby | Note |