voodoojs 0.11.1 → 0.12.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.
Files changed (41) hide show
  1. package/README.md +4 -3
  2. package/dist/{chunk-32J7GDLD.js → chunk-4M4ZXHNY.js} +94 -21
  3. package/dist/{chunk-TXWSOPF2.js → chunk-72PMUUMT.js} +4 -4
  4. package/dist/{chunk-OHSGDVPA.js → chunk-AFMCDNYS.js} +5 -5
  5. package/dist/{chunk-KE6WWJOB.js → chunk-D7675IJG.js} +6 -6
  6. package/dist/{chunk-BEQEBFQ2.js → chunk-GXPNWCGE.js} +3 -3
  7. package/dist/{chunk-FCJ2APGN.js → chunk-HNM3CTBD.js} +5 -5
  8. package/dist/{chunk-OJDW7KXT.js → chunk-KN7NAKBL.js} +4 -4
  9. package/dist/{chunk-FITEA237.js → chunk-LLNDLLKV.js} +4 -4
  10. package/dist/{chunk-J6RTM5P4.js → chunk-NP66JM2P.js} +4 -4
  11. package/dist/{chunk-XG2UDP4O.js → chunk-RDHYPGH6.js} +187 -18
  12. package/dist/{chunk-GC3BKNPT.js → chunk-T5ION5NG.js} +3 -3
  13. package/dist/essential.cjs +273 -27
  14. package/dist/essential.d.cts +1 -1
  15. package/dist/essential.d.ts +1 -1
  16. package/dist/essential.js +10 -10
  17. package/dist/gpu.cjs +1 -1
  18. package/dist/gpu.js +10 -10
  19. package/dist/http.cjs +1 -1
  20. package/dist/http.js +5 -5
  21. package/dist/index.cjs +283 -29
  22. package/dist/index.d.cts +88 -4
  23. package/dist/index.d.ts +88 -4
  24. package/dist/index.js +20 -20
  25. package/dist/{query-p04Fl8VW.d.ts → query-DzHfm8Kg.d.ts} +12 -1
  26. package/dist/{query-CbHihkvO.d.cts → query-XooOh4vB.d.cts} +12 -1
  27. package/dist/reactivity.cjs +1 -1
  28. package/dist/reactivity.js +2 -2
  29. package/dist/socket.cjs +11 -3
  30. package/dist/socket.js +9 -9
  31. package/dist/style-GR4X6O7I.js +5 -0
  32. package/dist/utils.cjs +1 -1
  33. package/dist/utils.js +2 -2
  34. package/dist/voodoo.core.js +252 -26
  35. package/dist/voodoo.core.min.js +17 -17
  36. package/dist/voodoo.full.js +276 -29
  37. package/dist/voodoo.full.min.js +57 -53
  38. package/dist/voodoo.js +274 -27
  39. package/dist/voodoo.min.js +29 -25
  40. package/package.json +1 -1
  41. package/dist/style-MX6ZATL4.js +0 -5
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Voodoo.js v0.11.1
2
+ * Voodoo.js v0.12.1
3
3
  * JavaScript feels like magic.
4
4
  * (c) 2026 Voodoo.js contributors. MIT License.
5
5
  */
@@ -61,5 +61,5 @@ function usePlugin(V, plugin, options) {
61
61
  }
62
62
 
63
63
  export { PRIORITY, components, config, defineDirective, directives, normalizeComponentName, usePlugin };
64
- //# sourceMappingURL=chunk-GC3BKNPT.js.map
65
- //# sourceMappingURL=chunk-GC3BKNPT.js.map
64
+ //# sourceMappingURL=chunk-T5ION5NG.js.map
65
+ //# sourceMappingURL=chunk-T5ION5NG.js.map
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  /**
6
- * Voodoo.js v0.11.1
6
+ * Voodoo.js v0.12.1
7
7
  * JavaScript feels like magic.
8
8
  * (c) 2026 Voodoo.js contributors. MIT License.
9
9
  */
@@ -1626,9 +1626,17 @@ var Parser = class {
1626
1626
  if (t.type === "punct") {
1627
1627
  if (t.value === "(") {
1628
1628
  this.next();
1629
- const expr = this.parseExpression();
1629
+ const body = [this.parseExpression()];
1630
+ while (this.isPunct(",")) {
1631
+ this.next();
1632
+ if (this.isPunct(")")) {
1633
+ const stray = this.peek();
1634
+ throw new VoodooSyntaxError("Trailing comma in a group", this.source, stray.start);
1635
+ }
1636
+ body.push(this.parseExpression());
1637
+ }
1630
1638
  this.expect(")");
1631
- return expr;
1639
+ return body.length === 1 ? body[0] : { t: "seq", body };
1632
1640
  }
1633
1641
  if (t.value === "[") return this.parseArrayLiteral();
1634
1642
  if (t.value === "{") return this.parseObjectLiteral();
@@ -2229,6 +2237,10 @@ var magics = /* @__PURE__ */ new Map();
2229
2237
  function magic(name, getter) {
2230
2238
  magics.set(name.startsWith("$") ? name : `$${name}`, getter);
2231
2239
  }
2240
+ var hooks = /* @__PURE__ */ new Map();
2241
+ function hook(name, getter) {
2242
+ hooks.set(name, getter);
2243
+ }
2232
2244
  var Scope = class _Scope {
2233
2245
  // Assignment order matches the order the fields were declared in before, so
2234
2246
  // the properties are created in the same sequence they always were.
@@ -2284,7 +2296,10 @@ var Scope = class _Scope {
2284
2296
  s = s.parent;
2285
2297
  }
2286
2298
  if (name.charCodeAt(0) === 36 && magics.has(name)) {
2287
- return this.magicContainer(name);
2299
+ return this.magicContainer(name, magics);
2300
+ }
2301
+ if (hooks.has(name)) {
2302
+ return this.magicContainer(name, hooks);
2288
2303
  }
2289
2304
  return void 0;
2290
2305
  }
@@ -2313,11 +2328,11 @@ var Scope = class _Scope {
2313
2328
  reactiveChild(vars, el = null) {
2314
2329
  return new _Scope(reactive(vars), this, el ?? this.el);
2315
2330
  }
2316
- magicContainer(name) {
2331
+ magicContainer(name, registry) {
2317
2332
  if (!this.magicCache) this.magicCache = /* @__PURE__ */ new Map();
2318
2333
  const cached = this.magicCache.get(name);
2319
2334
  if (cached) return cached;
2320
- const getter = magics.get(name);
2335
+ const getter = registry.get(name);
2321
2336
  const scope = this;
2322
2337
  const container2 = {};
2323
2338
  Object.defineProperty(container2, name, {
@@ -2706,7 +2721,16 @@ function runDirective(el, attr2, scope) {
2706
2721
  },
2707
2722
  effect(fn) {
2708
2723
  const owner = ownerScope();
2709
- owner.run(() => effect(fn, { scope: owner }));
2724
+ const hosted = () => {
2725
+ const previous = hookHost;
2726
+ hookHost = el;
2727
+ try {
2728
+ fn();
2729
+ } finally {
2730
+ hookHost = previous;
2731
+ }
2732
+ };
2733
+ owner.run(() => effect(hosted, { scope: owner }));
2710
2734
  },
2711
2735
  cleanup(fn) {
2712
2736
  addCleanup(el, fn);
@@ -2754,6 +2778,56 @@ function walk(node, scope) {
2754
2778
  return;
2755
2779
  }
2756
2780
  initialized.add(el);
2781
+ const previousHost = hookHost;
2782
+ hookHost = el;
2783
+ try {
2784
+ walkElementDirectives(el, attrs, tagComponent, current2);
2785
+ } finally {
2786
+ hookHost = previousHost;
2787
+ }
2788
+ }
2789
+ var hookHost = null;
2790
+ function currentHookHost() {
2791
+ return hookHost;
2792
+ }
2793
+ function createDataScope(expression, parent, el) {
2794
+ let ast = null;
2795
+ try {
2796
+ ast = parse(expression);
2797
+ } catch {
2798
+ ast = null;
2799
+ }
2800
+ const plain = ast && ast.t === "obj" && ast.props.every(
2801
+ (p2) => !p2.spread && !p2.keyExpr
2802
+ );
2803
+ if (!plain) {
2804
+ const raw = evaluateIn(expression, parent, "v-data");
2805
+ return parent.reactiveChild(raw && typeof raw === "object" ? raw : {}, el);
2806
+ }
2807
+ const scope = parent.reactiveChild({}, el);
2808
+ const props = ast.props;
2809
+ for (const prop of props) {
2810
+ if (prop.key === null) continue;
2811
+ try {
2812
+ if (prop.getter) {
2813
+ const compute = evaluate(prop.value, scope);
2814
+ Object.defineProperty(scope.data, prop.key, {
2815
+ enumerable: true,
2816
+ configurable: true,
2817
+ get: () => compute.call(scope.data)
2818
+ });
2819
+ } else {
2820
+ scope.data[prop.key] = evaluate(prop.value, scope);
2821
+ }
2822
+ } catch (err) {
2823
+ if (inDevelopment()) warnInvalidExpression(el, expression, expression, err);
2824
+ else handleError(err, "v-data");
2825
+ }
2826
+ }
2827
+ return scope;
2828
+ }
2829
+ function walkElementDirectives(el, attrs, tagComponent, scope) {
2830
+ let current2 = scope;
2757
2831
  for (const attr2 of attrs) {
2758
2832
  const def = directives.get(attr2.name);
2759
2833
  if (def?.terminal) {
@@ -2773,11 +2847,10 @@ function walk(node, scope) {
2773
2847
  nodeScopes.set(el, current2);
2774
2848
  }
2775
2849
  } else if (dataAttr || componentAttr) {
2776
- const raw = dataAttr ? evaluateIn(dataAttr.expression || "{}", current2, "v-data") : {};
2777
- current2 = current2.reactiveChild(raw && typeof raw === "object" ? raw : {}, el);
2850
+ current2 = createDataScope(dataAttr ? dataAttr.expression || "{}" : "{}", current2, el);
2778
2851
  nodeScopes.set(el, current2);
2779
2852
  }
2780
- const attributeScope = mountedComponent ? activeScope2 : current2;
2853
+ const attributeScope = mountedComponent ? scope : current2;
2781
2854
  for (const attr2 of attrs) {
2782
2855
  if (attr2.name === "data" || attr2.name === "component") continue;
2783
2856
  runDirective(el, attr2, attributeScope);
@@ -2933,9 +3006,9 @@ var started = false;
2933
3006
  var observer = null;
2934
3007
  var startHooks = [];
2935
3008
  function runPhase(target, after) {
2936
- for (const hook of startHooks) {
3009
+ for (const hook2 of startHooks) {
2937
3010
  try {
2938
- hook(target, after);
3011
+ hook2(target, after);
2939
3012
  } catch (error) {
2940
3013
  console.error("[Voodoo] a start hook failed", error);
2941
3014
  }
@@ -3313,10 +3386,10 @@ var LIFECYCLE = /* @__PURE__ */ new Set([
3313
3386
  "destroyed"
3314
3387
  ]);
3315
3388
  function callHook(def, instance, name) {
3316
- const hook = def[name];
3317
- if (typeof hook !== "function") return;
3389
+ const hook2 = def[name];
3390
+ if (typeof hook2 !== "function") return;
3318
3391
  try {
3319
- hook.call(instance);
3392
+ hook2.call(instance);
3320
3393
  } catch (err) {
3321
3394
  handleError(err, `hook ${name}`);
3322
3395
  }
@@ -4753,6 +4826,7 @@ var toast = Object.assign(
4753
4826
  );
4754
4827
 
4755
4828
  // src/storage/index.ts
4829
+ init_reactivity();
4756
4830
  function createStorage(getStore, prefix = "") {
4757
4831
  const full = (key) => prefix + key;
4758
4832
  return {
@@ -4922,21 +4996,28 @@ var cache2 = {
4922
4996
  };
4923
4997
  var THEME_KEY = "voodoo:theme";
4924
4998
  var picked = null;
4999
+ var revision = ref(0);
4925
5000
  var theme = {
4926
5001
  /** Theme chosen by the user, or `system` when never set. */
4927
5002
  get current() {
5003
+ void revision.value;
4928
5004
  return storage.get(THEME_KEY) ?? picked ?? "system";
4929
5005
  },
4930
5006
  /** Theme effectively applied, resolving `system`. */
4931
5007
  get resolved() {
4932
5008
  const value = this.current;
4933
5009
  if (value !== "system") return value;
5010
+ if (typeof document !== "undefined") {
5011
+ const authored = document.documentElement.getAttribute("data-theme");
5012
+ if (authored === "light" || authored === "dark") return authored;
5013
+ }
4934
5014
  if (typeof matchMedia === "undefined") return "light";
4935
5015
  return matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
4936
5016
  },
4937
5017
  set(value) {
4938
5018
  picked = value;
4939
5019
  storage.set(THEME_KEY, value);
5020
+ revision.value++;
4940
5021
  this.apply();
4941
5022
  },
4942
5023
  toggle() {
@@ -4970,8 +5051,17 @@ var theme = {
4970
5051
  init() {
4971
5052
  if (typeof document === "undefined") return;
4972
5053
  this.apply();
5054
+ if (typeof MutationObserver !== "undefined") {
5055
+ new MutationObserver(() => {
5056
+ revision.value++;
5057
+ }).observe(document.documentElement, {
5058
+ attributes: true,
5059
+ attributeFilter: ["data-theme"]
5060
+ });
5061
+ }
4973
5062
  if (typeof matchMedia === "undefined") return;
4974
5063
  matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
5064
+ revision.value++;
4975
5065
  if (this.current === "system") this.apply();
4976
5066
  });
4977
5067
  }
@@ -5104,6 +5194,140 @@ function installMagics() {
5104
5194
  );
5105
5195
  }
5106
5196
 
5197
+ // src/hooks/index.ts
5198
+ init_reactivity();
5199
+ var tables = /* @__PURE__ */ new WeakMap();
5200
+ function tableFor(scope) {
5201
+ const host = currentHookHost() ?? scope.el ?? scope;
5202
+ let table = tables.get(host);
5203
+ if (!table) {
5204
+ table = { slots: [], index: 0, scheduled: false, bound: false };
5205
+ tables.set(host, table);
5206
+ }
5207
+ const el = currentHookHost() ?? scope.el;
5208
+ if (!table.bound && el) {
5209
+ table.bound = true;
5210
+ const owned = table;
5211
+ addCleanup(el, () => {
5212
+ for (const slot of owned.slots) {
5213
+ if (slot.dispose) slot.dispose();
5214
+ if (slot.runner) stop(slot.runner);
5215
+ }
5216
+ owned.slots.length = 0;
5217
+ });
5218
+ }
5219
+ if (!table.scheduled) {
5220
+ table.scheduled = true;
5221
+ const pending = table;
5222
+ queueMicrotask(() => {
5223
+ pending.index = 0;
5224
+ pending.scheduled = false;
5225
+ });
5226
+ }
5227
+ return table;
5228
+ }
5229
+ function nextSlot(scope, kind) {
5230
+ const table = tableFor(scope);
5231
+ const at = table.index++;
5232
+ let slot = table.slots[at];
5233
+ if (!slot || slot.kind !== kind) {
5234
+ if (slot) {
5235
+ if (slot.dispose) slot.dispose();
5236
+ if (slot.runner) stop(slot.runner);
5237
+ }
5238
+ slot = { kind, deps: null, value: void 0 };
5239
+ table.slots[at] = slot;
5240
+ }
5241
+ return slot;
5242
+ }
5243
+ function depsChanged(previous, next) {
5244
+ if (!previous || !next) return true;
5245
+ if (previous.length !== next.length) return true;
5246
+ for (let i = 0; i < next.length; i++) {
5247
+ if (!Object.is(previous[i], next[i])) return true;
5248
+ }
5249
+ return false;
5250
+ }
5251
+ function normalizeDeps(deps) {
5252
+ return Array.isArray(deps) ? deps.slice() : null;
5253
+ }
5254
+ function useState(scope, initial) {
5255
+ const slot = nextSlot(scope, "state");
5256
+ if (slot.value === void 0) slot.value = ref(initial);
5257
+ return slot.value;
5258
+ }
5259
+ function useEffect(scope, fn, deps) {
5260
+ const slot = nextSlot(scope, "effect");
5261
+ const next = normalizeDeps(deps);
5262
+ const runCleanup = () => {
5263
+ if (slot.dispose) {
5264
+ const dispose = slot.dispose;
5265
+ slot.dispose = void 0;
5266
+ dispose();
5267
+ }
5268
+ };
5269
+ if (next) {
5270
+ const first = slot.deps === null && !slot.runner;
5271
+ if (first || depsChanged(slot.deps, next)) {
5272
+ slot.deps = next;
5273
+ runCleanup();
5274
+ const result = fn();
5275
+ if (typeof result === "function") slot.dispose = result;
5276
+ }
5277
+ return;
5278
+ }
5279
+ if (slot.runner) return;
5280
+ slot.deps = null;
5281
+ slot.runner = effect(() => {
5282
+ runCleanup();
5283
+ const result = fn();
5284
+ if (typeof result === "function") slot.dispose = result;
5285
+ });
5286
+ }
5287
+ function useMemo(scope, fn, deps) {
5288
+ const slot = nextSlot(scope, "memo");
5289
+ const next = normalizeDeps(deps);
5290
+ if (!next) {
5291
+ if (!slot.value) slot.value = computed(fn);
5292
+ return slot.value;
5293
+ }
5294
+ if (!slot.value) {
5295
+ slot.value = ref(fn());
5296
+ slot.deps = next;
5297
+ } else if (depsChanged(slot.deps, next)) {
5298
+ slot.deps = next;
5299
+ slot.value.value = fn();
5300
+ }
5301
+ return slot.value;
5302
+ }
5303
+ function useRef(scope, initial) {
5304
+ const slot = nextSlot(scope, "ref");
5305
+ if (!slot.value) slot.value = markRaw({ current: initial });
5306
+ return slot.value;
5307
+ }
5308
+ function useContext(name, initial) {
5309
+ if (initial !== void 0 && !(name in allStores)) {
5310
+ store(name, initial);
5311
+ }
5312
+ return allStores[name];
5313
+ }
5314
+ function installHooks() {
5315
+ hook("useState", (scope) => (initial) => useState(scope, initial));
5316
+ hook(
5317
+ "useEffect",
5318
+ (scope) => (fn, deps) => useEffect(scope, fn, deps)
5319
+ );
5320
+ hook(
5321
+ "useMemo",
5322
+ (scope) => (fn, deps) => useMemo(scope, fn, deps)
5323
+ );
5324
+ hook("useRef", (scope) => (initial) => useRef(scope, initial));
5325
+ hook(
5326
+ "useContext",
5327
+ () => (name, initial) => useContext(name, initial)
5328
+ );
5329
+ }
5330
+
5107
5331
  // src/http/resource.ts
5108
5332
  init_reactivity();
5109
5333
  function pick(value, path) {
@@ -6686,6 +6910,7 @@ setComponentMounter(mountComponent);
6686
6910
  setScopeMarker(markNodeScope);
6687
6911
  setDirectiveRegistrar(directive);
6688
6912
  installMagics();
6913
+ installHooks();
6689
6914
  var eventBus = /* @__PURE__ */ new Map();
6690
6915
  function on(name, handler) {
6691
6916
  let set2 = eventBus.get(name);
@@ -6719,7 +6944,7 @@ function off(name, handler) {
6719
6944
  eventBus.get(name)?.delete(handler);
6720
6945
  }
6721
6946
  function directive(name, definition) {
6722
- const hooks = typeof definition === "function" ? { mounted: definition, updated: definition } : definition;
6947
+ const hooks2 = typeof definition === "function" ? { mounted: definition, updated: definition } : definition;
6723
6948
  defineDirective(
6724
6949
  name,
6725
6950
  (ctx) => {
@@ -6735,36 +6960,36 @@ function directive(name, definition) {
6735
6960
  scope: ctx.scope,
6736
6961
  instance: ctx.scope.owner?.component ?? null
6737
6962
  });
6738
- const initial = hooks.raw ? ctx.expression : ctx.evaluate();
6739
- hooks.created?.(ctx.el, makeBinding(initial));
6740
- hooks.beforeMount?.(ctx.el, makeBinding(initial));
6963
+ const initial = hooks2.raw ? ctx.expression : ctx.evaluate();
6964
+ hooks2.created?.(ctx.el, makeBinding(initial));
6965
+ hooks2.beforeMount?.(ctx.el, makeBinding(initial));
6741
6966
  ctx.effect(() => {
6742
- const value = hooks.raw ? ctx.expression : ctx.evaluate();
6967
+ const value = hooks2.raw ? ctx.expression : ctx.evaluate();
6743
6968
  if (!mounted) {
6744
6969
  mounted = true;
6745
6970
  oldValue = value;
6746
- hooks.mounted?.(ctx.el, makeBinding(value));
6971
+ hooks2.mounted?.(ctx.el, makeBinding(value));
6747
6972
  return;
6748
6973
  }
6749
6974
  if (value === oldValue) return;
6750
6975
  const binding = makeBinding(value);
6751
- hooks.updated?.(ctx.el, binding);
6976
+ hooks2.updated?.(ctx.el, binding);
6752
6977
  oldValue = value;
6753
6978
  });
6754
6979
  ctx.cleanup(() => {
6755
6980
  const binding = makeBinding(oldValue);
6756
- hooks.beforeUnmount?.(ctx.el, binding);
6757
- hooks.unmounted?.(ctx.el, binding);
6981
+ hooks2.beforeUnmount?.(ctx.el, binding);
6982
+ hooks2.unmounted?.(ctx.el, binding);
6758
6983
  });
6759
6984
  },
6760
- { priority: hooks.priority ?? PRIORITY.DEFAULT, terminal: hooks.terminal ?? false }
6985
+ { priority: hooks2.priority ?? PRIORITY.DEFAULT, terminal: hooks2.terminal ?? false }
6761
6986
  );
6762
6987
  }
6763
6988
  function data(values) {
6764
6989
  Object.defineProperties(rootScope.data, Object.getOwnPropertyDescriptors(values));
6765
6990
  return rootScope.data;
6766
6991
  }
6767
- var version2 = "0.11.1";
6992
+ var version2 = "0.12.1";
6768
6993
  var core = {
6769
6994
  // Utilities first: Voodoo's own names can override.
6770
6995
  ...utils_exports,
@@ -12197,12 +12422,15 @@ magic("$history", (scope) => scope.el ? findController(scope.el) : null);
12197
12422
 
12198
12423
  // src/sound/index.ts
12199
12424
  init_registry();
12425
+ init_reactivity();
12426
+ init_style();
12200
12427
  var audioContext = null;
12201
12428
  var masterVolume = 0.35;
12202
12429
  var isMuted = false;
12203
12430
  var hasLoadedPreference = false;
12204
12431
  var VOLUME_KEY = "voodoo:sound:volume";
12205
12432
  var MUTE_KEY = "voodoo:sound:muted";
12433
+ var muteRevision = ref(0);
12206
12434
  function loadPreference() {
12207
12435
  if (hasLoadedPreference) return;
12208
12436
  hasLoadedPreference = true;
@@ -12514,6 +12742,7 @@ var sound = {
12514
12742
  loadPreference();
12515
12743
  isMuted = value;
12516
12744
  storage.set(MUTE_KEY, isMuted);
12745
+ muteRevision.value++;
12517
12746
  },
12518
12747
  /** Unmutes sound. */
12519
12748
  unmute() {
@@ -12525,8 +12754,18 @@ var sound = {
12525
12754
  this.mute(!isMuted);
12526
12755
  return isMuted;
12527
12756
  },
12528
- /** `true` when muted. */
12757
+ /**
12758
+ * `true` when muted.
12759
+ *
12760
+ * Reads a revision ref first, so that an expression asking whether sound is
12761
+ * muted actually re-runs when it changes. The state lives in a module
12762
+ * variable and in localStorage, both invisible to the Proxy, so
12763
+ * `v-show="$sound.muted"` used to render once and then never move: a page had
12764
+ * no way to show whether it was muted, which made the mute button look like
12765
+ * it did nothing at all.
12766
+ */
12529
12767
  get muted() {
12768
+ void muteRevision.value;
12530
12769
  loadPreference();
12531
12770
  return isMuted;
12532
12771
  },
@@ -12576,11 +12815,18 @@ defineDirective("sound", ({ el, arg, expression, modifiers, scope, cleanup, eval
12576
12815
  el.addEventListener(event, play);
12577
12816
  cleanup(() => el.removeEventListener(event, play));
12578
12817
  });
12818
+ var MUTE_CSS = `
12819
+ .v-muted{opacity:.55}
12820
+ .v-muted::after{content:" \\1F507";font-size:.9em}
12821
+ .v-mute-on::after{content:" \\1F50A";font-size:.9em}
12822
+ `;
12579
12823
  defineDirective("mute", ({ el, cleanup }) => {
12824
+ injectStyle("mute", MUTE_CSS);
12580
12825
  const sync = () => {
12581
12826
  const isMuted2 = sound.muted;
12582
12827
  el.setAttribute("aria-pressed", String(isMuted2));
12583
12828
  el.classList.toggle("v-muted", isMuted2);
12829
+ el.classList.toggle("v-mute-on", !isMuted2);
12584
12830
  };
12585
12831
  const toggle = () => {
12586
12832
  sound.toggle();
@@ -1,4 +1,4 @@
1
- import { c as core, V as VoodooCollection } from './query-CbHihkvO.cjs';
1
+ import { c as core, V as VoodooCollection } from './query-XooOh4vB.cjs';
2
2
  import './http.cjs';
3
3
  import './utils.cjs';
4
4
  import './reactivity.cjs';
@@ -1,4 +1,4 @@
1
- import { c as core, V as VoodooCollection } from './query-p04Fl8VW.js';
1
+ import { c as core, V as VoodooCollection } from './query-DzHfm8Kg.js';
2
2
  import './http.js';
3
3
  import './utils.js';
4
4
  import './reactivity.js';
package/dist/essential.js CHANGED
@@ -1,15 +1,15 @@
1
- import { core, sound, hotkey, palette, registerMask, unmask, applyMask, masks, mask, clearErrors, showFieldError, showFormErrors, messages, serializeForm, validate, validator, dialog, prompt, confirm, alert, modal, VoodooCollection, fromHtml, ready2, query } from './chunk-XG2UDP4O.js';
2
- import './chunk-KE6WWJOB.js';
3
- import { magic } from './chunk-32J7GDLD.js';
4
- import './chunk-FITEA237.js';
5
- import './chunk-TXWSOPF2.js';
6
- import './chunk-OJDW7KXT.js';
7
- import './chunk-J6RTM5P4.js';
8
- import './chunk-GC3BKNPT.js';
9
- import './chunk-BEQEBFQ2.js';
1
+ import { core, sound, hotkey, palette, registerMask, unmask, applyMask, masks, mask, clearErrors, showFieldError, showFormErrors, messages, serializeForm, validate, validator, dialog, prompt, confirm, alert, modal, VoodooCollection, fromHtml, ready2, query } from './chunk-RDHYPGH6.js';
2
+ import './chunk-D7675IJG.js';
3
+ import { magic } from './chunk-4M4ZXHNY.js';
4
+ import './chunk-LLNDLLKV.js';
5
+ import './chunk-72PMUUMT.js';
6
+ import './chunk-KN7NAKBL.js';
7
+ import './chunk-NP66JM2P.js';
8
+ import './chunk-T5ION5NG.js';
9
+ import './chunk-GXPNWCGE.js';
10
10
 
11
11
  /**
12
- * Voodoo.js v0.11.1
12
+ * Voodoo.js v0.12.1
13
13
  * JavaScript feels like magic.
14
14
  * (c) 2026 Voodoo.js contributors. MIT License.
15
15
  */
package/dist/gpu.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  /**
6
- * Voodoo.js v0.11.1
6
+ * Voodoo.js v0.12.1
7
7
  * JavaScript feels like magic.
8
8
  * (c) 2026 Voodoo.js contributors. MIT License.
9
9
  */
package/dist/gpu.js CHANGED
@@ -1,15 +1,15 @@
1
- import { supported, clock, shared, gpu, surface, effect, frameLoop, frame } from './chunk-OHSGDVPA.js';
2
- export { clock, compute, describeWgslType, destroy, effect, findEntry, flattenValue, frame, frameLoop, gpu, inferStruct, init, packStruct, reflectBindings, reflectEntries, reflectStructs, reflectWgsl, resetShared, shared, splitTopLevel, stripWgslComments, supported, surface, target, uniforms, writeField, writeStruct } from './chunk-OHSGDVPA.js';
3
- import { http } from './chunk-KE6WWJOB.js';
4
- import { originalAttributes, destroy } from './chunk-32J7GDLD.js';
5
- import { handleError } from './chunk-FITEA237.js';
6
- import { warn, describeElement } from './chunk-TXWSOPF2.js';
7
- import './chunk-OJDW7KXT.js';
8
- import { defineDirective } from './chunk-GC3BKNPT.js';
9
- import './chunk-BEQEBFQ2.js';
1
+ import { supported, clock, shared, gpu, surface, effect, frameLoop, frame } from './chunk-AFMCDNYS.js';
2
+ export { clock, compute, describeWgslType, destroy, effect, findEntry, flattenValue, frame, frameLoop, gpu, inferStruct, init, packStruct, reflectBindings, reflectEntries, reflectStructs, reflectWgsl, resetShared, shared, splitTopLevel, stripWgslComments, supported, surface, target, uniforms, writeField, writeStruct } from './chunk-AFMCDNYS.js';
3
+ import { http } from './chunk-D7675IJG.js';
4
+ import { originalAttributes, destroy } from './chunk-4M4ZXHNY.js';
5
+ import { handleError } from './chunk-LLNDLLKV.js';
6
+ import { warn, describeElement } from './chunk-72PMUUMT.js';
7
+ import './chunk-KN7NAKBL.js';
8
+ import { defineDirective } from './chunk-T5ION5NG.js';
9
+ import './chunk-GXPNWCGE.js';
10
10
 
11
11
  /**
12
- * Voodoo.js v0.11.1
12
+ * Voodoo.js v0.12.1
13
13
  * JavaScript feels like magic.
14
14
  * (c) 2026 Voodoo.js contributors. MIT License.
15
15
  */
package/dist/http.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * Voodoo.js v0.11.1
4
+ * Voodoo.js v0.12.1
5
5
  * JavaScript feels like magic.
6
6
  * (c) 2026 Voodoo.js contributors. MIT License.
7
7
  */
package/dist/http.js CHANGED
@@ -1,7 +1,7 @@
1
- export { HttpError, clearCache, flushOfflineQueue, http, request } from './chunk-KE6WWJOB.js';
2
- import './chunk-TXWSOPF2.js';
3
- import './chunk-OJDW7KXT.js';
4
- import './chunk-GC3BKNPT.js';
5
- import './chunk-BEQEBFQ2.js';
1
+ export { HttpError, clearCache, flushOfflineQueue, http, request } from './chunk-D7675IJG.js';
2
+ import './chunk-72PMUUMT.js';
3
+ import './chunk-KN7NAKBL.js';
4
+ import './chunk-T5ION5NG.js';
5
+ import './chunk-GXPNWCGE.js';
6
6
  //# sourceMappingURL=http.js.map
7
7
  //# sourceMappingURL=http.js.map