voodoojs 0.11.2 → 0.12.2

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 +1 -1
  2. package/dist/{chunk-IGZSDZKU.js → chunk-7AKBELZA.js} +4 -4
  3. package/dist/{chunk-V3O3WOZH.js → chunk-AVXQPDQH.js} +4 -4
  4. package/dist/{chunk-AH2VXDZD.js → chunk-K2U3O36M.js} +193 -20
  5. package/dist/{chunk-IS3DR2KY.js → chunk-MEE2ZAKJ.js} +3 -3
  6. package/dist/{chunk-DJJB35SR.js → chunk-NVANUFWZ.js} +6 -6
  7. package/dist/{chunk-H2ZUEQWV.js → chunk-OWCQV42D.js} +112 -20
  8. package/dist/{chunk-KQYSJHZR.js → chunk-RTZEIVNA.js} +5 -5
  9. package/dist/{chunk-NFDXVIII.js → chunk-RXOLGHSU.js} +3 -3
  10. package/dist/{chunk-WJP3YGUI.js → chunk-S4BXAGAW.js} +4 -4
  11. package/dist/{chunk-DCE5WIGA.js → chunk-UGLD36KV.js} +5 -5
  12. package/dist/{chunk-UV5PMS7P.js → chunk-YV4I45SK.js} +4 -4
  13. package/dist/essential.cjs +297 -28
  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 +325 -34
  22. package/dist/index.d.cts +88 -4
  23. package/dist/index.d.ts +88 -4
  24. package/dist/index.js +38 -24
  25. package/dist/{query-DiQAS73Q.d.cts → query-D_BGQw8m.d.cts} +12 -1
  26. package/dist/{query-Cf-7iibE.d.ts → query-Dl6Urlwd.d.ts} +12 -1
  27. package/dist/reactivity.cjs +1 -1
  28. package/dist/reactivity.js +2 -2
  29. package/dist/socket.cjs +29 -2
  30. package/dist/socket.js +9 -9
  31. package/dist/style-GWGXWHB4.js +5 -0
  32. package/dist/utils.cjs +1 -1
  33. package/dist/utils.js +2 -2
  34. package/dist/voodoo.core.js +277 -27
  35. package/dist/voodoo.core.min.js +17 -17
  36. package/dist/voodoo.full.js +325 -36
  37. package/dist/voodoo.full.min.js +59 -55
  38. package/dist/voodoo.js +305 -30
  39. package/dist/voodoo.min.js +29 -25
  40. package/package.json +1 -1
  41. package/dist/style-4X62SABN.js +0 -5
package/dist/http.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * Voodoo.js v0.11.2
4
+ * Voodoo.js v0.12.2
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-DJJB35SR.js';
2
- import './chunk-UV5PMS7P.js';
3
- import './chunk-IGZSDZKU.js';
4
- import './chunk-NFDXVIII.js';
5
- import './chunk-IS3DR2KY.js';
1
+ export { HttpError, clearCache, flushOfflineQueue, http, request } from './chunk-NVANUFWZ.js';
2
+ import './chunk-YV4I45SK.js';
3
+ import './chunk-7AKBELZA.js';
4
+ import './chunk-RXOLGHSU.js';
5
+ import './chunk-MEE2ZAKJ.js';
6
6
  //# sourceMappingURL=http.js.map
7
7
  //# sourceMappingURL=http.js.map
package/dist/index.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  /**
6
- * Voodoo.js v0.11.2
6
+ * Voodoo.js v0.12.2
7
7
  * JavaScript feels like magic.
8
8
  * (c) 2026 Voodoo.js contributors. MIT License.
9
9
  */
@@ -1773,6 +1773,23 @@ var DELIBERATELY_WITHHELD = /* @__PURE__ */ new Set([
1773
1773
  "SharedWorker",
1774
1774
  "ServiceWorker"
1775
1775
  ]);
1776
+ function guardedTimer(name) {
1777
+ return function(handler, timeout, ...rest) {
1778
+ if (typeof handler !== "function") {
1779
+ throw new VoodooRuntimeError(
1780
+ `${name} needs a function. Passing a string would compile it, which this library never does.`
1781
+ );
1782
+ }
1783
+ const timer = globalThis[name];
1784
+ return timer(handler, timeout, ...rest);
1785
+ };
1786
+ }
1787
+ function forwardGlobal(name) {
1788
+ return function(...args) {
1789
+ const fn = globalThis[name];
1790
+ return fn(...args);
1791
+ };
1792
+ }
1776
1793
  var allowedGlobals = {
1777
1794
  Math,
1778
1795
  JSON,
@@ -1791,7 +1808,17 @@ var allowedGlobals = {
1791
1808
  isFinite,
1792
1809
  encodeURIComponent,
1793
1810
  decodeURIComponent,
1794
- console
1811
+ console,
1812
+ ...typeof setTimeout !== "undefined" ? {
1813
+ setTimeout: guardedTimer("setTimeout"),
1814
+ setInterval: guardedTimer("setInterval"),
1815
+ clearTimeout: forwardGlobal("clearTimeout"),
1816
+ clearInterval: forwardGlobal("clearInterval")
1817
+ } : {},
1818
+ ...typeof requestAnimationFrame !== "undefined" ? {
1819
+ requestAnimationFrame: forwardGlobal("requestAnimationFrame"),
1820
+ cancelAnimationFrame: forwardGlobal("cancelAnimationFrame")
1821
+ } : {}
1795
1822
  };
1796
1823
  var VoodooRuntimeError = class extends Error {
1797
1824
  constructor(message, expression) {
@@ -2237,6 +2264,10 @@ var magics = /* @__PURE__ */ new Map();
2237
2264
  function magic(name, getter) {
2238
2265
  magics.set(name.startsWith("$") ? name : `$${name}`, getter);
2239
2266
  }
2267
+ var hooks = /* @__PURE__ */ new Map();
2268
+ function hook(name, getter) {
2269
+ hooks.set(name, getter);
2270
+ }
2240
2271
  var Scope = class _Scope {
2241
2272
  // Assignment order matches the order the fields were declared in before, so
2242
2273
  // the properties are created in the same sequence they always were.
@@ -2292,7 +2323,10 @@ var Scope = class _Scope {
2292
2323
  s = s.parent;
2293
2324
  }
2294
2325
  if (name.charCodeAt(0) === 36 && magics.has(name)) {
2295
- return this.magicContainer(name);
2326
+ return this.magicContainer(name, magics);
2327
+ }
2328
+ if (hooks.has(name)) {
2329
+ return this.magicContainer(name, hooks);
2296
2330
  }
2297
2331
  return void 0;
2298
2332
  }
@@ -2321,11 +2355,11 @@ var Scope = class _Scope {
2321
2355
  reactiveChild(vars, el = null) {
2322
2356
  return new _Scope(reactive(vars), this, el ?? this.el);
2323
2357
  }
2324
- magicContainer(name) {
2358
+ magicContainer(name, registry) {
2325
2359
  if (!this.magicCache) this.magicCache = /* @__PURE__ */ new Map();
2326
2360
  const cached = this.magicCache.get(name);
2327
2361
  if (cached) return cached;
2328
- const getter = magics.get(name);
2362
+ const getter = registry.get(name);
2329
2363
  const scope = this;
2330
2364
  const container2 = {};
2331
2365
  Object.defineProperty(container2, name, {
@@ -2722,7 +2756,16 @@ function runDirective(el, attr2, scope) {
2722
2756
  },
2723
2757
  effect(fn) {
2724
2758
  const owner = ownerScope();
2725
- owner.run(() => effect(fn, { scope: owner }));
2759
+ const hosted = () => {
2760
+ const previous = hookHost;
2761
+ hookHost = el;
2762
+ try {
2763
+ fn();
2764
+ } finally {
2765
+ hookHost = previous;
2766
+ }
2767
+ };
2768
+ owner.run(() => effect(hosted, { scope: owner }));
2726
2769
  },
2727
2770
  cleanup(fn) {
2728
2771
  addCleanup(el, fn);
@@ -2770,6 +2813,56 @@ function walk(node, scope) {
2770
2813
  return;
2771
2814
  }
2772
2815
  initialized.add(el);
2816
+ const previousHost = hookHost;
2817
+ hookHost = el;
2818
+ try {
2819
+ walkElementDirectives(el, attrs, tagComponent, current2);
2820
+ } finally {
2821
+ hookHost = previousHost;
2822
+ }
2823
+ }
2824
+ var hookHost = null;
2825
+ function currentHookHost() {
2826
+ return hookHost;
2827
+ }
2828
+ function createDataScope(expression, parent, el) {
2829
+ let ast = null;
2830
+ try {
2831
+ ast = parse(expression);
2832
+ } catch {
2833
+ ast = null;
2834
+ }
2835
+ const plain = ast && ast.t === "obj" && ast.props.every(
2836
+ (p2) => !p2.spread && !p2.keyExpr
2837
+ );
2838
+ if (!plain) {
2839
+ const raw = evaluateIn(expression, parent, "v-data");
2840
+ return parent.reactiveChild(raw && typeof raw === "object" ? raw : {}, el);
2841
+ }
2842
+ const scope = parent.reactiveChild({}, el);
2843
+ const props = ast.props;
2844
+ for (const prop of props) {
2845
+ if (prop.key === null) continue;
2846
+ try {
2847
+ if (prop.getter) {
2848
+ const compute2 = evaluate(prop.value, scope);
2849
+ Object.defineProperty(scope.data, prop.key, {
2850
+ enumerable: true,
2851
+ configurable: true,
2852
+ get: () => compute2.call(scope.data)
2853
+ });
2854
+ } else {
2855
+ scope.data[prop.key] = evaluate(prop.value, scope);
2856
+ }
2857
+ } catch (err) {
2858
+ if (inDevelopment()) warnInvalidExpression(el, expression, expression, err);
2859
+ else handleError(err, "v-data");
2860
+ }
2861
+ }
2862
+ return scope;
2863
+ }
2864
+ function walkElementDirectives(el, attrs, tagComponent, scope) {
2865
+ let current2 = scope;
2773
2866
  for (const attr2 of attrs) {
2774
2867
  const def = directives.get(attr2.name);
2775
2868
  if (def?.terminal) {
@@ -2789,11 +2882,10 @@ function walk(node, scope) {
2789
2882
  nodeScopes.set(el, current2);
2790
2883
  }
2791
2884
  } else if (dataAttr || componentAttr) {
2792
- const raw = dataAttr ? evaluateIn(dataAttr.expression || "{}", current2, "v-data") : {};
2793
- current2 = current2.reactiveChild(raw && typeof raw === "object" ? raw : {}, el);
2885
+ current2 = createDataScope(dataAttr ? dataAttr.expression || "{}" : "{}", current2, el);
2794
2886
  nodeScopes.set(el, current2);
2795
2887
  }
2796
- const attributeScope = mountedComponent ? activeScope2 : current2;
2888
+ const attributeScope = mountedComponent ? scope : current2;
2797
2889
  for (const attr2 of attrs) {
2798
2890
  if (attr2.name === "data" || attr2.name === "component") continue;
2799
2891
  runDirective(el, attr2, attributeScope);
@@ -2948,13 +3040,13 @@ var componentAliases = /* @__PURE__ */ new Map();
2948
3040
  var started = false;
2949
3041
  var observer = null;
2950
3042
  var startHooks = [];
2951
- function onStart(hook) {
2952
- startHooks.push(hook);
3043
+ function onStart(hook2) {
3044
+ startHooks.push(hook2);
2953
3045
  }
2954
3046
  function runPhase(target2, after) {
2955
- for (const hook of startHooks) {
3047
+ for (const hook2 of startHooks) {
2956
3048
  try {
2957
- hook(target2, after);
3049
+ hook2(target2, after);
2958
3050
  } catch (error) {
2959
3051
  console.error("[Voodoo] a start hook failed", error);
2960
3052
  }
@@ -3332,10 +3424,10 @@ var LIFECYCLE = /* @__PURE__ */ new Set([
3332
3424
  "destroyed"
3333
3425
  ]);
3334
3426
  function callHook(def, instance, name) {
3335
- const hook = def[name];
3336
- if (typeof hook !== "function") return;
3427
+ const hook2 = def[name];
3428
+ if (typeof hook2 !== "function") return;
3337
3429
  try {
3338
- hook.call(instance);
3430
+ hook2.call(instance);
3339
3431
  } catch (err) {
3340
3432
  handleError(err, `hook ${name}`);
3341
3433
  }
@@ -4775,6 +4867,7 @@ var toast = Object.assign(
4775
4867
  );
4776
4868
 
4777
4869
  // src/storage/index.ts
4870
+ init_reactivity();
4778
4871
  function createStorage(getStore, prefix = "") {
4779
4872
  const full = (key) => prefix + key;
4780
4873
  return {
@@ -4944,21 +5037,28 @@ var cache2 = {
4944
5037
  };
4945
5038
  var THEME_KEY = "voodoo:theme";
4946
5039
  var picked = null;
5040
+ var revision = ref(0);
4947
5041
  var theme = {
4948
5042
  /** Theme chosen by the user, or `system` when never set. */
4949
5043
  get current() {
5044
+ void revision.value;
4950
5045
  return storage.get(THEME_KEY) ?? picked ?? "system";
4951
5046
  },
4952
5047
  /** Theme effectively applied, resolving `system`. */
4953
5048
  get resolved() {
4954
5049
  const value = this.current;
4955
5050
  if (value !== "system") return value;
5051
+ if (typeof document !== "undefined") {
5052
+ const authored = document.documentElement.getAttribute("data-theme");
5053
+ if (authored === "light" || authored === "dark") return authored;
5054
+ }
4956
5055
  if (typeof matchMedia === "undefined") return "light";
4957
5056
  return matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
4958
5057
  },
4959
5058
  set(value) {
4960
5059
  picked = value;
4961
5060
  storage.set(THEME_KEY, value);
5061
+ revision.value++;
4962
5062
  this.apply();
4963
5063
  },
4964
5064
  toggle() {
@@ -4992,8 +5092,17 @@ var theme = {
4992
5092
  init() {
4993
5093
  if (typeof document === "undefined") return;
4994
5094
  this.apply();
5095
+ if (typeof MutationObserver !== "undefined") {
5096
+ new MutationObserver(() => {
5097
+ revision.value++;
5098
+ }).observe(document.documentElement, {
5099
+ attributes: true,
5100
+ attributeFilter: ["data-theme"]
5101
+ });
5102
+ }
4995
5103
  if (typeof matchMedia === "undefined") return;
4996
5104
  matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
5105
+ revision.value++;
4997
5106
  if (this.current === "system") this.apply();
4998
5107
  });
4999
5108
  }
@@ -5126,6 +5235,140 @@ function installMagics() {
5126
5235
  );
5127
5236
  }
5128
5237
 
5238
+ // src/hooks/index.ts
5239
+ init_reactivity();
5240
+ var tables = /* @__PURE__ */ new WeakMap();
5241
+ function tableFor(scope) {
5242
+ const host = currentHookHost() ?? scope.el ?? scope;
5243
+ let table = tables.get(host);
5244
+ if (!table) {
5245
+ table = { slots: [], index: 0, scheduled: false, bound: false };
5246
+ tables.set(host, table);
5247
+ }
5248
+ const el = currentHookHost() ?? scope.el;
5249
+ if (!table.bound && el) {
5250
+ table.bound = true;
5251
+ const owned = table;
5252
+ addCleanup(el, () => {
5253
+ for (const slot of owned.slots) {
5254
+ if (slot.dispose) slot.dispose();
5255
+ if (slot.runner) stop(slot.runner);
5256
+ }
5257
+ owned.slots.length = 0;
5258
+ });
5259
+ }
5260
+ if (!table.scheduled) {
5261
+ table.scheduled = true;
5262
+ const pending2 = table;
5263
+ queueMicrotask(() => {
5264
+ pending2.index = 0;
5265
+ pending2.scheduled = false;
5266
+ });
5267
+ }
5268
+ return table;
5269
+ }
5270
+ function nextSlot(scope, kind) {
5271
+ const table = tableFor(scope);
5272
+ const at = table.index++;
5273
+ let slot = table.slots[at];
5274
+ if (!slot || slot.kind !== kind) {
5275
+ if (slot) {
5276
+ if (slot.dispose) slot.dispose();
5277
+ if (slot.runner) stop(slot.runner);
5278
+ }
5279
+ slot = { kind, deps: null, value: void 0 };
5280
+ table.slots[at] = slot;
5281
+ }
5282
+ return slot;
5283
+ }
5284
+ function depsChanged(previous, next) {
5285
+ if (!previous || !next) return true;
5286
+ if (previous.length !== next.length) return true;
5287
+ for (let i = 0; i < next.length; i++) {
5288
+ if (!Object.is(previous[i], next[i])) return true;
5289
+ }
5290
+ return false;
5291
+ }
5292
+ function normalizeDeps(deps) {
5293
+ return Array.isArray(deps) ? deps.slice() : null;
5294
+ }
5295
+ function useState(scope, initial) {
5296
+ const slot = nextSlot(scope, "state");
5297
+ if (slot.value === void 0) slot.value = ref(initial);
5298
+ return slot.value;
5299
+ }
5300
+ function useEffect(scope, fn, deps) {
5301
+ const slot = nextSlot(scope, "effect");
5302
+ const next = normalizeDeps(deps);
5303
+ const runCleanup = () => {
5304
+ if (slot.dispose) {
5305
+ const dispose = slot.dispose;
5306
+ slot.dispose = void 0;
5307
+ dispose();
5308
+ }
5309
+ };
5310
+ if (next) {
5311
+ const first = slot.deps === null && !slot.runner;
5312
+ if (first || depsChanged(slot.deps, next)) {
5313
+ slot.deps = next;
5314
+ runCleanup();
5315
+ const result = fn();
5316
+ if (typeof result === "function") slot.dispose = result;
5317
+ }
5318
+ return;
5319
+ }
5320
+ if (slot.runner) return;
5321
+ slot.deps = null;
5322
+ slot.runner = effect(() => {
5323
+ runCleanup();
5324
+ const result = fn();
5325
+ if (typeof result === "function") slot.dispose = result;
5326
+ });
5327
+ }
5328
+ function useMemo(scope, fn, deps) {
5329
+ const slot = nextSlot(scope, "memo");
5330
+ const next = normalizeDeps(deps);
5331
+ if (!next) {
5332
+ if (!slot.value) slot.value = computed(fn);
5333
+ return slot.value;
5334
+ }
5335
+ if (!slot.value) {
5336
+ slot.value = ref(fn());
5337
+ slot.deps = next;
5338
+ } else if (depsChanged(slot.deps, next)) {
5339
+ slot.deps = next;
5340
+ slot.value.value = fn();
5341
+ }
5342
+ return slot.value;
5343
+ }
5344
+ function useRef(scope, initial) {
5345
+ const slot = nextSlot(scope, "ref");
5346
+ if (!slot.value) slot.value = markRaw({ current: initial });
5347
+ return slot.value;
5348
+ }
5349
+ function useContext(name, initial) {
5350
+ if (initial !== void 0 && !(name in allStores)) {
5351
+ store(name, initial);
5352
+ }
5353
+ return allStores[name];
5354
+ }
5355
+ function installHooks() {
5356
+ hook("useState", (scope) => (initial) => useState(scope, initial));
5357
+ hook(
5358
+ "useEffect",
5359
+ (scope) => (fn, deps) => useEffect(scope, fn, deps)
5360
+ );
5361
+ hook(
5362
+ "useMemo",
5363
+ (scope) => (fn, deps) => useMemo(scope, fn, deps)
5364
+ );
5365
+ hook("useRef", (scope) => (initial) => useRef(scope, initial));
5366
+ hook(
5367
+ "useContext",
5368
+ () => (name, initial) => useContext(name, initial)
5369
+ );
5370
+ }
5371
+
5129
5372
  // src/http/resource.ts
5130
5373
  init_reactivity();
5131
5374
  function pick(value, path) {
@@ -6708,6 +6951,7 @@ setComponentMounter(mountComponent);
6708
6951
  setScopeMarker(markNodeScope);
6709
6952
  setDirectiveRegistrar(directive);
6710
6953
  installMagics();
6954
+ installHooks();
6711
6955
  var eventBus = /* @__PURE__ */ new Map();
6712
6956
  function on(name, handler) {
6713
6957
  let set2 = eventBus.get(name);
@@ -6741,7 +6985,7 @@ function off(name, handler) {
6741
6985
  eventBus.get(name)?.delete(handler);
6742
6986
  }
6743
6987
  function directive(name, definition) {
6744
- const hooks = typeof definition === "function" ? { mounted: definition, updated: definition } : definition;
6988
+ const hooks2 = typeof definition === "function" ? { mounted: definition, updated: definition } : definition;
6745
6989
  defineDirective(
6746
6990
  name,
6747
6991
  (ctx) => {
@@ -6757,36 +7001,36 @@ function directive(name, definition) {
6757
7001
  scope: ctx.scope,
6758
7002
  instance: ctx.scope.owner?.component ?? null
6759
7003
  });
6760
- const initial = hooks.raw ? ctx.expression : ctx.evaluate();
6761
- hooks.created?.(ctx.el, makeBinding(initial));
6762
- hooks.beforeMount?.(ctx.el, makeBinding(initial));
7004
+ const initial = hooks2.raw ? ctx.expression : ctx.evaluate();
7005
+ hooks2.created?.(ctx.el, makeBinding(initial));
7006
+ hooks2.beforeMount?.(ctx.el, makeBinding(initial));
6763
7007
  ctx.effect(() => {
6764
- const value = hooks.raw ? ctx.expression : ctx.evaluate();
7008
+ const value = hooks2.raw ? ctx.expression : ctx.evaluate();
6765
7009
  if (!mounted2) {
6766
7010
  mounted2 = true;
6767
7011
  oldValue = value;
6768
- hooks.mounted?.(ctx.el, makeBinding(value));
7012
+ hooks2.mounted?.(ctx.el, makeBinding(value));
6769
7013
  return;
6770
7014
  }
6771
7015
  if (value === oldValue) return;
6772
7016
  const binding = makeBinding(value);
6773
- hooks.updated?.(ctx.el, binding);
7017
+ hooks2.updated?.(ctx.el, binding);
6774
7018
  oldValue = value;
6775
7019
  });
6776
7020
  ctx.cleanup(() => {
6777
7021
  const binding = makeBinding(oldValue);
6778
- hooks.beforeUnmount?.(ctx.el, binding);
6779
- hooks.unmounted?.(ctx.el, binding);
7022
+ hooks2.beforeUnmount?.(ctx.el, binding);
7023
+ hooks2.unmounted?.(ctx.el, binding);
6780
7024
  });
6781
7025
  },
6782
- { priority: hooks.priority ?? exports.PRIORITY.DEFAULT, terminal: hooks.terminal ?? false }
7026
+ { priority: hooks2.priority ?? exports.PRIORITY.DEFAULT, terminal: hooks2.terminal ?? false }
6783
7027
  );
6784
7028
  }
6785
7029
  function data(values) {
6786
7030
  Object.defineProperties(rootScope.data, Object.getOwnPropertyDescriptors(values));
6787
7031
  return rootScope.data;
6788
7032
  }
6789
- var version2 = "0.11.2";
7033
+ var version2 = "0.12.2";
6790
7034
  var core = {
6791
7035
  // Utilities first: Voodoo's own names can override.
6792
7036
  ...utils_exports,
@@ -9908,6 +10152,7 @@ defineDirective("collapse", ({ el }) => {
9908
10152
  ensureUi();
9909
10153
  collapseOf(el);
9910
10154
  });
10155
+ var selfToggling = /* @__PURE__ */ new WeakSet();
9911
10156
  defineDirective("collapse-toggle", ({ el, expression, cleanup }) => {
9912
10157
  ensureUi();
9913
10158
  const target2 = resolveTarget(el, expression);
@@ -9916,6 +10161,8 @@ defineDirective("collapse-toggle", ({ el, expression, cleanup }) => {
9916
10161
  controller.triggers.add(el);
9917
10162
  controller.sync();
9918
10163
  makeInteractive(el, cleanup);
10164
+ selfToggling.add(el);
10165
+ cleanup(() => selfToggling.delete(el));
9919
10166
  const onClick = (event) => {
9920
10167
  event.preventDefault();
9921
10168
  controller.toggle();
@@ -10326,10 +10573,11 @@ defineDirective("accordion", ({ el, cleanup }) => {
10326
10573
  if (index === -1) return;
10327
10574
  event.preventDefault();
10328
10575
  const controller = controllers2[index];
10329
- if (single && !controller.open) {
10576
+ const ownToggle = selfToggling.has(header);
10577
+ if (single && (ownToggle ? controller.open : !controller.open)) {
10330
10578
  for (const other of controllers2) if (other !== controller) other.hide();
10331
10579
  }
10332
- controller.toggle();
10580
+ if (!ownToggle) controller.toggle();
10333
10581
  };
10334
10582
  const onKeyDown = (event) => {
10335
10583
  const header = event.target?.closest(".v-accordion-header");
@@ -13148,12 +13396,15 @@ magic("$history", (scope) => scope.el ? findController(scope.el) : null);
13148
13396
 
13149
13397
  // src/sound/index.ts
13150
13398
  init_registry();
13399
+ init_reactivity();
13400
+ init_style();
13151
13401
  var audioContext = null;
13152
13402
  var masterVolume = 0.35;
13153
13403
  var isMuted = false;
13154
13404
  var hasLoadedPreference = false;
13155
13405
  var VOLUME_KEY = "voodoo:sound:volume";
13156
13406
  var MUTE_KEY = "voodoo:sound:muted";
13407
+ var muteRevision = ref(0);
13157
13408
  function loadPreference() {
13158
13409
  if (hasLoadedPreference) return;
13159
13410
  hasLoadedPreference = true;
@@ -13465,6 +13716,7 @@ var sound = {
13465
13716
  loadPreference();
13466
13717
  isMuted = value;
13467
13718
  storage.set(MUTE_KEY, isMuted);
13719
+ muteRevision.value++;
13468
13720
  },
13469
13721
  /** Unmutes sound. */
13470
13722
  unmute() {
@@ -13476,8 +13728,18 @@ var sound = {
13476
13728
  this.mute(!isMuted);
13477
13729
  return isMuted;
13478
13730
  },
13479
- /** `true` when muted. */
13731
+ /**
13732
+ * `true` when muted.
13733
+ *
13734
+ * Reads a revision ref first, so that an expression asking whether sound is
13735
+ * muted actually re-runs when it changes. The state lives in a module
13736
+ * variable and in localStorage, both invisible to the Proxy, so
13737
+ * `v-show="$sound.muted"` used to render once and then never move: a page had
13738
+ * no way to show whether it was muted, which made the mute button look like
13739
+ * it did nothing at all.
13740
+ */
13480
13741
  get muted() {
13742
+ void muteRevision.value;
13481
13743
  loadPreference();
13482
13744
  return isMuted;
13483
13745
  },
@@ -13527,11 +13789,18 @@ defineDirective("sound", ({ el, arg, expression, modifiers, scope, cleanup, eval
13527
13789
  el.addEventListener(event, play);
13528
13790
  cleanup(() => el.removeEventListener(event, play));
13529
13791
  });
13792
+ var MUTE_CSS = `
13793
+ .v-muted{opacity:.55}
13794
+ .v-muted::after{content:" \\1F507";font-size:.9em}
13795
+ .v-mute-on::after{content:" \\1F50A";font-size:.9em}
13796
+ `;
13530
13797
  defineDirective("mute", ({ el, cleanup }) => {
13798
+ injectStyle("mute", MUTE_CSS);
13531
13799
  const sync = () => {
13532
13800
  const isMuted2 = sound.muted;
13533
13801
  el.setAttribute("aria-pressed", String(isMuted2));
13534
13802
  el.classList.toggle("v-muted", isMuted2);
13803
+ el.classList.toggle("v-mute-on", !isMuted2);
13535
13804
  };
13536
13805
  const toggle = () => {
13537
13806
  sound.toggle();
@@ -17829,8 +18098,22 @@ register("v-table", {
17829
18098
  }
17830
18099
  },
17831
18100
  methods: {
17832
- cell(row, column) {
17833
- const value = get(row, column.key);
18101
+ /**
18102
+ * A row may be an object keyed by column, or a positional array.
18103
+ *
18104
+ * Only the object form was ever read. The documentation's own example on
18105
+ * the components page passes `[['Ada', 'Engineer']]` against columns
18106
+ * `['Name', 'Role']`, and looking `'Name'` up on an array finds nothing, so
18107
+ * every cell rendered empty while the header row and the row count both
18108
+ * looked perfectly right — which is a hard failure to even notice, let
18109
+ * alone diagnose.
18110
+ *
18111
+ * The index comes from the template rather than `cols.indexOf(column)`,
18112
+ * because `cols` is a computed and identity is not guaranteed to survive a
18113
+ * recomputation.
18114
+ */
18115
+ cell(row, column, index) {
18116
+ const value = Array.isArray(row) && typeof index === "number" ? row[index] : get(row, column.key);
17834
18117
  if (value === null || value === void 0) return "";
17835
18118
  return String(value);
17836
18119
  },
@@ -17878,8 +18161,8 @@ register("v-table", {
17878
18161
  </thead>
17879
18162
  <tbody>
17880
18163
  <tr v-for="(row, index) in sorted" :key="index">
17881
- <td v-for="column in cols" :key="column.key" :style="alignStyle(column)"
17882
- v-text="cell(row, column)"></td>
18164
+ <td v-for="(column, ci) in cols" :key="column.key" :style="alignStyle(column)"
18165
+ v-text="cell(row, column, ci)"></td>
17883
18166
  </tr>
17884
18167
  <tr v-if="!sorted.length">
17885
18168
  <td class="v-table-empty" :colspan="cols.length || 1" v-text="empty"></td>
@@ -23569,11 +23852,14 @@ exports.getLocale = getLocale;
23569
23852
  exports.getScope = getScope;
23570
23853
  exports.gpu = gpu;
23571
23854
  exports.groupBy = groupBy;
23855
+ exports.hook = hook;
23856
+ exports.hooks = hooks;
23572
23857
  exports.hotkey = hotkey;
23573
23858
  exports.http = http;
23574
23859
  exports.i18n = i18n;
23575
23860
  exports.inView = inView;
23576
23861
  exports.injectStyle = injectStyle;
23862
+ exports.installHooks = installHooks;
23577
23863
  exports.instances = instances;
23578
23864
  exports.isBrowser = isBrowser;
23579
23865
  exports.isDevtoolsWidgetMounted = isDevtoolsWidgetMounted;
@@ -23660,6 +23946,11 @@ exports.unmask = unmask;
23660
23946
  exports.unmountDevtoolsWidget = unmountDevtoolsWidget;
23661
23947
  exports.unref = unref;
23662
23948
  exports.url = url;
23949
+ exports.useContext = useContext;
23950
+ exports.useEffect = useEffect;
23951
+ exports.useMemo = useMemo;
23952
+ exports.useRef = useRef;
23953
+ exports.useState = useState;
23663
23954
  exports.uuid = uuid;
23664
23955
  exports.validate = validate;
23665
23956
  exports.validator = validator;