dommy-js-quickjs 0.11.0 → 0.13.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df093cff1000de6ad73f27367c17845c2b6846b87785913d70695b0d38938daf
4
- data.tar.gz: aab8821f4e6974306d7e47b35730f32d7340cec51437d0926e94986e692bbb4d
3
+ metadata.gz: 2e6b8409eac9474ca6bd31c48e4225296f6bdd646d1582fbd7971e40918f3fda
4
+ data.tar.gz: da8deb2816c76b5a98932321957bb60411d338a86cd5a3322feff937d71c43cf
5
5
  SHA512:
6
- metadata.gz: efe4b423fc15fc33f2e3a77108f145cadf0d4d072b69c9447f958cbdcb872b367cd7857ce07a975bacb2d7a64a36c3bee760a4070ebfcc893bff8e6df8ea8441
7
- data.tar.gz: c5fa56f132d9df6e4c067f96f0fa5c1e915c63d9ff641832c72aac75307e6fad57d7e671e4585e0cdffe73419cba0e965a08d750e2c50e5dfbad223b5987c6f1
6
+ metadata.gz: 56fcec71210297cfa232936f6abb9a046bbd4174034567407c9a6d843978edd242eb2a1f0a975ff78b434d16600baf2fdad0dbc849c37d8f7f79b0cf0a57de64
7
+ data.tar.gz: bd4f983f1baf57ea48d10190953f0ab824899395a7650ffc11bebb49d042bf7ba308f119c8aae09a9bbdbb040e048deac390323a2d9e1d425b6738739a7a9dc2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.13.0 — 2026-10-20
4
+
5
+ Requires `dommy >= 0.17.0, < 0.18` and `quickjs ~> 0.22.0`.
6
+
7
+ ### Changed
8
+
9
+ - Requires `dommy >= 0.17.0, < 0.18` (was `>= 0.16.0, < 0.17`). dommy 0.17.0 requires makiri `~> 0.16.0`.
10
+ - The bare `self`, `top`, `parent` and `frames` are the window: `self === window` and `top === window` hold. `self`, `parent` and `frames` are [Replaceable]; `top` is readonly, so assigning it in strict code throws.
11
+ - An assignment to the bare `location` navigates, as `window.location = url` does.
12
+ - The bare `history`, `navigator` and `crypto` are readonly: `history = 1` leaves the window's History, and throws in strict code. `indexedDB` and `caches`, which dommy does not implement, are not globals, so `"indexedDB" in globalThis` is false and a page can define its own.
13
+ - A bare global that forwards to the window (`fetch`, `setTimeout`, `localStorage`, …) reaches the window's own member: replacing `window.fetch` replaces the bare `fetch`, and a wrapper that calls a saved `fetch` calls the original instead of itself.
14
+ - The bare `queueMicrotask` reports what its callback throws at the window (`reportError`), as `window.queueMicrotask` does, instead of rejecting a promise nobody holds.
15
+
16
+ ### Fixed
17
+
18
+ - The shims (`browser_globals.js`, `timer_globals.js`, `intl_polyfill.js`, `wasm_stub.js`) no longer declare their helpers at the top level of the page's realm. A page's own top-level `let group`, `class Collator` or `let __rbDefer` was a redeclaration SyntaxError, and a page's `let __rbTimerOrigins` made every bare `setTimeout` throw `TypeError: not a function`. Each shim now runs in an IIFE; the timers keep their origin map in a local. `test/dommy/js/test_shim_scope.rb` declares every former helper name from a page.
19
+
20
+ ## 0.12.0 — 2026-10-10
21
+
22
+ Requires `dommy >= 0.16.0, < 0.17` and `quickjs ~> 0.22.0`.
23
+
24
+ ### Added
25
+
26
+ - A bare `frameElement` global, read from the window on each access (a frame's container can change). It is a plain readonly attribute, so unlike the [Replaceable] ones below an assignment does not replace it.
27
+
28
+ ### Changed
29
+
30
+ - Requires `dommy >= 0.16.0, < 0.17` (was `>= 0.15.0, < 0.16`). dommy 0.16.0 needs makiri 0.16.0 and changes what `Session#click_link` and `#click_button` return; the suite passes against it, and the boot-cost bound below needs its lazy interface seeding.
31
+ - The realm's bootstrap bundles no longer hand their completion value to Ruby. `window_builtins.js` ends by assigning `window.globalThis`, so every page load converted the whole global object to a Ruby value: 184 host reads and about 6 ms. `Backend#run_bundle` now discards it (the compiled bundle ends with `void 0`). `test/dommy/js/test_window_boot.rb` checks that lazily seeded interfaces resolve like eager ones and bounds the bridge crossings of opening a window (`install_window` under 60; it was 424).
32
+ - The bare timer globals follow the IDL: `setTimeout(handler, timeout = 0, ...arguments)` and `setInterval` hand the extra arguments to the handler, and every timer global has the IDL's `length` (`setTimeout.length` is 1, `clearTimeout.length` 0).
33
+ - The bare forwards to window methods (`structuredClone`, `fetch`, `postMessage`, `addEventListener`, …) carry the operation's name and `length` from dommy's generated WebIDL signatures, instead of being 0-length `(...args)` wrappers.
34
+ - `innerWidth`, `innerHeight`, `scrollX`/`scrollY`, `pageXOffset`/`pageYOffset` and `devicePixelRatio` are read from the window on each access rather than copied once at boot, and an assignment replaces them ([Replaceable]).
35
+ - The WPT file runner boots its browser with `navigable: true`, so an `<iframe src>` loads through dommy's child navigables and the browser's resources (dommy now gives every iframe an initial `about:blank` document and navigates it from a task). `dom/nodes/Element-matches.html` and `Element-webkitMatchesSelector.html` are back to 669/669 and `ParentNode-querySelector-All.html` to 1975/1975.
36
+ - Tests follow dommy's spec changes: a srcless or `about:blank` iframe fires `load` during `appendChild`; boot runs HTML's "the end" to the load task, so a `setTimeout(0)` queued while parsing has fired before `Dommy::Browser.new` / `Session#visit` return, even with `settle: false` (which still leaves what the load handler queued pending); an unhandled rejection fails from the queued "notify about rejected promises" task, at the next `settle`, not from `execute`; and the custom element construction-stack test defines through a `CustomElementRegistry` host object and runs `__rbHost.ceUpgrade`.
37
+
38
+ ### Fixed
39
+
40
+ - The bare `localStorage` and `sessionStorage` globals are read from the window on each access instead of being copied at boot, so a window on an opaque origin (`about:blank`, which `Dommy::Browser.visit` starts from, `data:`, a sandboxed frame) no longer fails to install its globals with `SecurityError: Storage is disabled for an opaque origin`; the page gets that `SecurityError` when it reads them, as the HTML spec says. They are no longer enumerable own properties of the global.
41
+
3
42
  ## 0.11.0 — 2026-10-04
4
43
 
5
44
  Requires `dommy >= 0.15.0, < 0.16` and `quickjs ~> 0.22.0`.
@@ -96,8 +96,14 @@ module Dommy
96
96
  @bundle_cache = {}
97
97
  @bundle_mutex = Mutex.new
98
98
 
99
+ # A bundle runs for its side effects, so its completion value is
100
+ # discarded (the trailing `void 0`, on a line of its own so a final
101
+ # line comment cannot swallow it). Whatever its last statement
102
+ # evaluated to would otherwise be converted to a Ruby value on every
103
+ # VM — for window_builtins.js, whose last statement assigns
104
+ # `window.globalThis`, the entire global object.
99
105
  def self.compiled_bundle(cache_key, source)
100
- @bundle_mutex.synchronize { @bundle_cache[cache_key] ||= compile(source, filename: cache_key.to_s) }
106
+ @bundle_mutex.synchronize { @bundle_cache[cache_key] ||= compile("#{source}\n;void 0;", filename: cache_key.to_s) }
101
107
  end
102
108
 
103
109
  # Execute precompiled bytecode (a Quickjs::Runnable) on this VM in global
@@ -1,36 +1,150 @@
1
1
  // The bare browser globals frameworks reach for, aliased onto the installed
2
2
  // window. This is what lets real frontend bundles (Turbo, …) run unmodified.
3
- globalThis.self = globalThis;
4
- // Top-level window: parent/top are the window itself (spec), so frame-walking
5
- // loops terminate instead of dereferencing undefined.
6
- globalThis.parent = globalThis;
7
- globalThis.top = globalThis;
8
- // `frames` is the window itself, indexable by child-frame number
9
- // (`frames[0]` === the first <iframe>'s contentWindow).
10
- globalThis.frames = window;
11
- globalThis.location = window.location;
12
- globalThis.history = window.history;
13
- globalThis.navigator = window.navigator;
14
- globalThis.sessionStorage = window.sessionStorage;
15
- globalThis.localStorage = window.localStorage;
3
+ //
4
+ // The window's names for itself are the window proxy, as everywhere else a
5
+ // window is handed out (`window.self`, `document.defaultView`, a frame's
6
+ // `parent`): globalThis is the one object that is not, since QuickJS makes the
7
+ // global. For the top-level window, parent and top are the window itself
8
+ // (spec), so frame-walking loops terminate. `frames` is indexable by
9
+ // child-frame number (`frames[0]` === the first <iframe>'s contentWindow).
10
+ // They read the live `window`, which a host can rebind. self, parent and
11
+ // frames are [Replaceable]: an assignment replaces the accessor with the
12
+ // value. top is [LegacyUnforgeable]: an assignment leaves it (a strict-mode one
13
+ // throws).
14
+ //
15
+ // Every bare global here that stands for a window member reaches the
16
+ // window's own implementation (dommy's `__rbWindowMember`), not whatever the
17
+ // window answers for the name: the window answers with the bare global
18
+ // itself, and a page that saved the bare `fetch` before wrapping
19
+ // `window.fetch` must get the original back, as from a browser's native
20
+ // function. Each is declared so to dommy (`__rbWindowForward`). Against a
21
+ // dommy without them, they read the window as before.
22
+ //
23
+ // The IIFE keeps the helpers below out of the page's global scope.
24
+ (function () {
25
+ const __rbForward = globalThis.__rbWindowForward || ((fn) => fn);
26
+ const __rbMember = globalThis.__rbWindowMember || ((name) => window[name]);
27
+ // A [Replaceable] attribute: read through `get`, replaced by an assignment.
28
+ const __rbReplaceable = (name, get) => {
29
+ Object.defineProperty(globalThis, name, {
30
+ get,
31
+ set(value) {
32
+ Object.defineProperty(globalThis, name, { value, writable: true, enumerable: true, configurable: true });
33
+ },
34
+ enumerable: true,
35
+ configurable: true,
36
+ });
37
+ };
38
+ for (const __n of ["self", "parent", "frames"]) {
39
+ __rbReplaceable(__n, __rbForward(function () { return window; }));
40
+ }
41
+ // Getter only, so a strict-mode assignment throws, as on a browser's window.
42
+ Object.defineProperty(globalThis, "top", {
43
+ get: __rbForward(function () { return window; }),
44
+ enumerable: true,
45
+ configurable: true,
46
+ });
47
+ // `location` is the window's own [LegacyUnforgeable] attribute with
48
+ // [PutForwards=href]: an assignment navigates, as `window.location = url`
49
+ // does. A window has one Location for its life (a cross-document navigation
50
+ // makes a new realm), so it is read again only when a host rebinds `window`.
51
+ let __rbLocationWindow = null;
52
+ let __rbLocation = null;
53
+ Object.defineProperty(globalThis, "location", {
54
+ get: __rbForward(function () {
55
+ if (__rbLocationWindow !== window) {
56
+ __rbLocationWindow = window;
57
+ __rbLocation = __rbMember("location");
58
+ }
59
+ return __rbLocation;
60
+ }),
61
+ set(value) { window.location = value; },
62
+ enumerable: true,
63
+ configurable: true,
64
+ });
65
+ // The objects a window keeps for its life, aliased by reference. history,
66
+ // navigator, crypto, indexedDB and caches are plain readonly attributes, so
67
+ // assigning the bare name leaves them (a strict-mode assignment throws);
68
+ // performance, screen and visualViewport are [Replaceable], so an assignment
69
+ // replaces them. A name the window has no object for (dommy implements
70
+ // neither indexedDB nor caches) is left undefined: pinning a read-only
71
+ // `undefined` would make `"indexedDB" in globalThis` claim the feature and
72
+ // refuse the polyfill a page assigns in its place.
73
+ for (const __n of ["history", "navigator", "crypto", "indexedDB", "caches"]) {
74
+ try {
75
+ const value = window[__n];
76
+ if (value == null) continue;
77
+ Object.defineProperty(globalThis, __n, { value, writable: false, enumerable: true, configurable: true });
78
+ } catch (__e) {}
79
+ }
80
+ // Web Storage is read from the window on each access, not copied at boot: the
81
+ // sessionStorage / localStorage getters throw a SecurityError when "obtain a
82
+ // session/local storage bottle map" fails (HTML, Web storage), which it does
83
+ // for an opaque origin (Storage Standard, "obtain a storage key": an opaque
84
+ // origin is failure). A page on about:blank, data: or a sandboxed frame must
85
+ // see that when it reads `localStorage`, and it must not abort installing the
86
+ // rest of the globals. Not enumerable: on a real window they are accessors of
87
+ // Window.prototype, not own keys of the global — and an enumerable throwing
88
+ // getter would break whatever walks the global's own properties (handing
89
+ // `globalThis` to the host, as window_builtins.js does, reads each of them).
90
+ for (const __n of ["sessionStorage", "localStorage"]) {
91
+ Object.defineProperty(globalThis, __n, {
92
+ get: __rbForward(function () { return __rbMember(__n); }),
93
+ enumerable: false,
94
+ configurable: true,
95
+ });
96
+ }
16
97
  globalThis.CSS = window.CSS;
17
- globalThis.getComputedStyle = (...args) => window.getComputedStyle(...args);
18
- globalThis.matchMedia = (...args) => window.matchMedia(...args);
19
- globalThis.fetch = (...args) => window.fetch(...args);
20
- globalThis.addEventListener = (...args) => window.addEventListener(...args);
21
- globalThis.removeEventListener = (...args) => window.removeEventListener(...args);
22
- globalThis.dispatchEvent = (event) => window.dispatchEvent(event);
98
+ // A bare window method forwards to the window, named and sized as the IDL
99
+ // declares it (`structuredClone.length` is 1, not a rest wrapper's 0): the
100
+ // generated signatures dommy loads give each operation's required-argument
101
+ // count, looked up along the interface's inheritance (EventTarget's
102
+ // addEventListener).
103
+ const __rbWindowOperation = (name) => {
104
+ const signatures = globalThis.__rbIdlSignatures || {};
105
+ for (let iface = "Window"; iface && signatures[iface]; iface = signatures[iface].inherits) {
106
+ const operation = (signatures[iface].operations || {})[name];
107
+ if (operation) return operation;
108
+ }
109
+ return null;
110
+ };
111
+ const __rbForwardWindowMethod = (name) => {
112
+ const forward = __rbForward(function (...args) { return __rbMember(name).apply(window, args); });
113
+ const operation = __rbWindowOperation(name);
114
+ Object.defineProperty(forward, "name", { value: name });
115
+ Object.defineProperty(forward, "length", { value: operation ? operation.required : 0 });
116
+ globalThis[name] = forward;
117
+ };
118
+ for (const __m of ["getComputedStyle", "matchMedia", "fetch",
119
+ "addEventListener", "removeEventListener", "dispatchEvent"]) {
120
+ __rbForwardWindowMethod(__m);
121
+ }
23
122
 
24
- // More bare globals frameworks read directly (e.g. performance.now(), crypto,
25
- // screen). Objects/values are aliased by reference; methods are wrapped so
26
- // `this` binds to the window. All already exist on window.
27
- for (const __n of ["performance", "crypto", "screen", "visualViewport",
28
- "indexedDB", "caches", "devicePixelRatio",
29
- "innerWidth", "innerHeight", "scrollX", "scrollY", "pageXOffset"]) {
123
+ // The [Replaceable] objects frameworks read directly (performance.now(),
124
+ // screen), aliased by reference as plain data properties, which an assignment
125
+ // replaces; methods forward (above) so `this` binds to the window.
126
+ for (const __n of ["performance", "screen", "visualViewport"]) {
30
127
  try { globalThis[__n] = window[__n]; } catch (__e) {}
31
128
  }
129
+ // Values that change (a resize, a scroll) are read from the window each time
130
+ // rather than copied once at boot. They are [Replaceable]: an assignment
131
+ // replaces the accessor with the assigned value, as on a real window.
132
+ for (const __n of ["devicePixelRatio", "innerWidth", "innerHeight",
133
+ "scrollX", "scrollY", "pageXOffset", "pageYOffset"]) {
134
+ try { __rbReplaceable(__n, __rbForward(function () { return __rbMember(__n); })); } catch (__e) {}
135
+ }
136
+ // `frameElement` is a plain readonly attribute: read from the window each
137
+ // time (a frame's container can change), never replaced by an assignment.
138
+ try {
139
+ Object.defineProperty(globalThis, "frameElement", {
140
+ get: __rbForward(function () { return __rbMember("frameElement"); }),
141
+ enumerable: false,
142
+ configurable: true,
143
+ });
144
+ } catch (__e) {}
32
145
  for (const __m of ["scrollTo", "scrollBy", "requestIdleCallback", "cancelIdleCallback",
33
146
  "getSelection", "structuredClone", "reportError", "btoa", "atob",
34
147
  "alert", "confirm", "prompt", "open", "postMessage"]) {
35
- try { globalThis[__m] = (...args) => window[__m](...args); } catch (__e) {}
148
+ try { __rbForwardWindowMethod(__m); } catch (__e) {}
36
149
  }
150
+ })();
@@ -3,6 +3,9 @@
3
3
  // defined` (nuxt.com, i18n libraries, …). Install a small locale-naive
4
4
  // polyfill: it formats reasonably (grouped numbers, ISO-ish dates) so pages run
5
5
  // instead of crashing, without pulling in full ICU.
6
+ // The IIFE keeps its helpers and constructors (I, group, Collator, …) out of
7
+ // the page's global scope, where a page's own `let group` would collide.
8
+ (function () {
6
9
  if (typeof globalThis.Intl === "undefined") {
7
10
  var I = {};
8
11
  var group = function (s) {
@@ -54,3 +57,4 @@ if (typeof globalThis.Intl === "undefined") {
54
57
  I.getCanonicalLocales = function (locs) { return Array.isArray(locs) ? locs.slice() : locs ? [String(locs)] : []; };
55
58
  globalThis.Intl = I;
56
59
  }
60
+ })();
@@ -9,38 +9,70 @@
9
9
  // and only stringified if the callback actually throws (see
10
10
  // __rbFetchTimerOrigin + Runtime#handle_timer_error); a successful callback
11
11
  // forgets its origin and the map is size-capped, so this stays cheap.
12
- globalThis.__rbTimerOrigins = new Map();
12
+ //
13
+ // The IIFE keeps the helpers out of the page's global scope: a page's own
14
+ // `let __rbDefer` would be a redeclaration, and a page's `let` of a name the
15
+ // helpers looked up globally would take its place. __rbDefer keeps its name,
16
+ // which marks the frame ErrorTranslator strips from origin stacks.
17
+ (function () {
18
+ const origins = new Map();
13
19
  const __rbDefer = (schedule, fn, delay) => {
14
20
  if (typeof fn !== "function") return schedule(fn, delay);
15
21
  const origin = new Error();
16
22
  let id;
17
23
  const wrapped = function () {
18
24
  const result = fn.apply(this, arguments);
19
- __rbTimerOrigins.delete(id); // ran cleanly — no need to keep it
25
+ origins.delete(id); // ran cleanly — no need to keep it
20
26
  return result;
21
27
  };
22
28
  id = schedule(wrapped, delay);
23
- __rbTimerOrigins.set(id, origin);
24
- if (__rbTimerOrigins.size > 4096) __rbTimerOrigins.delete(__rbTimerOrigins.keys().next().value);
29
+ origins.set(id, origin);
30
+ if (origins.size > 4096) origins.delete(origins.keys().next().value);
25
31
  return id;
26
32
  };
27
33
  globalThis.__rbFetchTimerOrigin = (id) => {
28
- const origin = __rbTimerOrigins.get(id);
34
+ const origin = origins.get(id);
29
35
  if (!origin) return "";
30
- __rbTimerOrigins.delete(id);
36
+ origins.delete(id);
31
37
  return origin.stack || "";
32
38
  };
33
- globalThis.setTimeout = (fn, delay) => __rbDefer((f, d) => window.setTimeout(f, d), fn, delay);
34
- globalThis.clearTimeout = (id) => window.clearTimeout(id);
35
- globalThis.setInterval = (fn, delay) => __rbDefer((f, d) => window.setInterval(f, d), fn, delay);
36
- globalThis.clearInterval = (id) => window.clearInterval(id);
37
- globalThis.requestAnimationFrame = (fn) => __rbDefer((f) => window.requestAnimationFrame(f), fn);
38
- globalThis.cancelAnimationFrame = (id) => window.cancelAnimationFrame(id);
39
+ // Each stands for the window's own and reaches it directly (dommy's
40
+ // `__rbWindowMember`), not through whatever the window answers for the name,
41
+ // which is this very function (see browser_globals.js).
42
+ const __rbTimerForward = globalThis.__rbWindowForward || ((fn) => fn);
43
+ const __rbTimerMember = globalThis.__rbWindowMember || ((name) => window[name]);
44
+ // The signatures are the IDL's (HTML "timers"): `setTimeout(handler, timeout
45
+ // = 0, ...arguments)` hands the extra arguments to the handler, and the
46
+ // defaults keep each function's `length` the IDL's (1, 0, 1, 0, 1, 1).
47
+ globalThis.setTimeout = __rbTimerForward(function setTimeout(handler, timeout = 0, ...args) {
48
+ return __rbDefer((f, d) => __rbTimerMember("setTimeout").call(window, f, d, ...args), handler, timeout);
49
+ });
50
+ globalThis.clearTimeout = __rbTimerForward(function clearTimeout(id = 0) { return __rbTimerMember("clearTimeout").call(window, id); });
51
+ globalThis.setInterval = __rbTimerForward(function setInterval(handler, timeout = 0, ...args) {
52
+ return __rbDefer((f, d) => __rbTimerMember("setInterval").call(window, f, d, ...args), handler, timeout);
53
+ });
54
+ globalThis.clearInterval = __rbTimerForward(function clearInterval(id = 0) { return __rbTimerMember("clearInterval").call(window, id); });
55
+ globalThis.requestAnimationFrame = __rbTimerForward(function requestAnimationFrame(callback) {
56
+ return __rbDefer((f) => __rbTimerMember("requestAnimationFrame").call(window, f), callback);
57
+ });
58
+ globalThis.cancelAnimationFrame = __rbTimerForward(function cancelAnimationFrame(handle) {
59
+ return __rbTimerMember("cancelAnimationFrame").call(window, handle);
60
+ });
39
61
  // queueMicrotask must share the engine's promise-job (microtask) queue so its
40
62
  // callbacks are FIFO-ordered with Promise reactions (the WHATWG
41
63
  // single-microtask-queue model). Routing through the Ruby scheduler instead
42
64
  // would drain on a separate pass, reordering it after all native promise jobs.
43
- globalThis.queueMicrotask = (fn) => {
44
- if (typeof fn !== "function") throw new TypeError("queueMicrotask requires a function");
45
- Promise.resolve().then(() => { fn(); });
46
- };
65
+ // What the callback throws is reported at the window (HTML "report an
66
+ // exception"), as window.queueMicrotask's is, rather than rejecting a promise
67
+ // nobody holds.
68
+ globalThis.queueMicrotask = __rbTimerForward(function queueMicrotask(callback) {
69
+ if (typeof callback !== "function") throw new TypeError("queueMicrotask requires a function");
70
+ Promise.resolve().then(() => {
71
+ try {
72
+ callback();
73
+ } catch (error) {
74
+ __rbTimerMember("reportError").call(window, error);
75
+ }
76
+ });
77
+ });
78
+ })();
@@ -7,6 +7,9 @@
7
7
  // `Memory` honors `{shared:true}` with a SharedArrayBuffer, which the engine
8
8
  // does ship. That is also what WPT's common/sab.js needs: it derives the SAB
9
9
  // constructor from `new WebAssembly.Memory({shared:true}).buffer.constructor`.
10
+ // The IIFE keeps its helpers (unsupported, throwUnsupported) out of the
11
+ // page's global scope.
12
+ (function () {
10
13
  if (typeof globalThis.WebAssembly === "undefined") {
11
14
  var unsupported = function () { return Promise.reject(new Error("WebAssembly is not supported")); };
12
15
  var throwUnsupported = function () { throw new Error("WebAssembly is not supported"); };
@@ -24,3 +27,4 @@ if (typeof globalThis.WebAssembly === "undefined") {
24
27
  CompileError: Error, LinkError: Error, RuntimeError: Error,
25
28
  };
26
29
  }
30
+ })();
@@ -3,7 +3,7 @@
3
3
  module Dommy
4
4
  module Js
5
5
  module Quickjs
6
- VERSION = "0.11.0"
6
+ VERSION = "0.13.0"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dommy-js-quickjs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - takahashim
@@ -29,20 +29,20 @@ dependencies:
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 0.15.0
32
+ version: 0.17.0
33
33
  - - "<"
34
34
  - !ruby/object:Gem::Version
35
- version: '0.16'
35
+ version: '0.18'
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 0.15.0
42
+ version: 0.17.0
43
43
  - - "<"
44
44
  - !ruby/object:Gem::Version
45
- version: '0.16'
45
+ version: '0.18'
46
46
  description: |
47
47
  dommy-js-quickjs lets JavaScript drive a Dommy DOM by embedding QuickJS (via
48
48
  the quickjs gem) and bridging DOM nodes to JS through an ES Proxy that routes
@@ -97,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
97
  - !ruby/object:Gem::Version
98
98
  version: '0'
99
99
  requirements: []
100
- rubygems_version: 4.0.20
100
+ rubygems_version: 3.6.9
101
101
  specification_version: 4
102
102
  summary: QuickJS backend for running JavaScript against a Dommy DOM.
103
103
  test_files: []