@pyreon/vue-compat 0.13.1 → 0.14.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.
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"d4e3dc19-1","name":"jsx-runtime.ts"},{"uid":"d4e3dc19-3","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"d4e3dc19-1":{"renderedLength":186,"gzipLength":138,"brotliLength":0,"metaUid":"d4e3dc19-0"},"d4e3dc19-3":{"renderedLength":12003,"gzipLength":2957,"brotliLength":0,"metaUid":"d4e3dc19-2"}},"nodeMetas":{"d4e3dc19-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"index.js":"d4e3dc19-1"},"imported":[{"uid":"d4e3dc19-4"},{"uid":"d4e3dc19-5"}],"importedBy":[{"uid":"d4e3dc19-2"}]},"d4e3dc19-2":{"id":"/src/index.ts","moduleParts":{"index.js":"d4e3dc19-3"},"imported":[{"uid":"d4e3dc19-4"},{"uid":"d4e3dc19-5"},{"uid":"d4e3dc19-6"},{"uid":"d4e3dc19-0"}],"importedBy":[],"isEntry":true},"d4e3dc19-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"d4e3dc19-2"},{"uid":"d4e3dc19-0"}]},"d4e3dc19-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"d4e3dc19-2"},{"uid":"d4e3dc19-0"}]},"d4e3dc19-6":{"id":"@pyreon/runtime-dom","moduleParts":{},"imported":[],"importedBy":[{"uid":"d4e3dc19-2"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"b9349412-1","name":"jsx-runtime.ts"},{"uid":"b9349412-3","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"b9349412-1":{"renderedLength":186,"gzipLength":138,"brotliLength":0,"metaUid":"b9349412-0"},"b9349412-3":{"renderedLength":21702,"gzipLength":5144,"brotliLength":0,"metaUid":"b9349412-2"}},"nodeMetas":{"b9349412-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"index.js":"b9349412-1"},"imported":[{"uid":"b9349412-4"},{"uid":"b9349412-5"}],"importedBy":[{"uid":"b9349412-2"}]},"b9349412-2":{"id":"/src/index.ts","moduleParts":{"index.js":"b9349412-3"},"imported":[{"uid":"b9349412-4"},{"uid":"b9349412-5"},{"uid":"b9349412-6"},{"uid":"b9349412-0"}],"importedBy":[],"isEntry":true},"b9349412-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"b9349412-2"},{"uid":"b9349412-0"}]},"b9349412-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"b9349412-2"},{"uid":"b9349412-0"}]},"b9349412-6":{"id":"@pyreon/runtime-dom","moduleParts":{},"imported":[],"importedBy":[{"uid":"b9349412-2"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"jsx-runtime.js","children":[{"name":"src","children":[{"uid":"d37de618-1","name":"jsx-runtime.ts"},{"uid":"d37de618-3","name":"jsx-dev-runtime.ts"}]}]}],"isRoot":true},"nodeParts":{"d37de618-1":{"renderedLength":2340,"gzipLength":841,"brotliLength":0,"metaUid":"d37de618-0"},"d37de618-3":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"d37de618-2"}},"nodeMetas":{"d37de618-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"jsx-runtime.js":"d37de618-1"},"imported":[{"uid":"d37de618-4"},{"uid":"d37de618-5"}],"importedBy":[{"uid":"d37de618-2"}]},"d37de618-2":{"id":"/src/jsx-dev-runtime.ts","moduleParts":{"jsx-runtime.js":"d37de618-3"},"imported":[{"uid":"d37de618-0"}],"importedBy":[],"isEntry":true},"d37de618-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"d37de618-0"}]},"d37de618-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"d37de618-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"jsx-runtime.js","children":[{"name":"src","children":[{"uid":"fe017e8d-1","name":"jsx-runtime.ts"},{"uid":"fe017e8d-3","name":"jsx-dev-runtime.ts"}]}]}],"isRoot":true},"nodeParts":{"fe017e8d-1":{"renderedLength":2604,"gzipLength":949,"brotliLength":0,"metaUid":"fe017e8d-0"},"fe017e8d-3":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"fe017e8d-2"}},"nodeMetas":{"fe017e8d-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"jsx-runtime.js":"fe017e8d-1"},"imported":[{"uid":"fe017e8d-4"},{"uid":"fe017e8d-5"}],"importedBy":[{"uid":"fe017e8d-2"}]},"fe017e8d-2":{"id":"/src/jsx-dev-runtime.ts","moduleParts":{"jsx-runtime.js":"fe017e8d-3"},"imported":[{"uid":"fe017e8d-0"}],"importedBy":[],"isEntry":true},"fe017e8d-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"fe017e8d-0"}]},"fe017e8d-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"fe017e8d-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Fragment, createContext, h as pyreonH, onMount, onUnmount, onUpdate, popContext, pushContext, useContext } from "@pyreon/core";
1
+ import { Fragment, Portal, createContext, h as pyreonH, onMount, onUnmount, onUpdate, popContext, pushContext, useContext } from "@pyreon/core";
2
2
  import { batch, computed as computed$1, createStore, effect, nextTick as nextTick$1, signal } from "@pyreon/reactivity";
3
3
  import { mount } from "@pyreon/runtime-dom";
4
4
 
@@ -14,8 +14,9 @@ function getHookIndex() {
14
14
 
15
15
  //#endregion
16
16
  //#region src/index.ts
17
- const V_IS_REF = Symbol("__v_isRef");
17
+ const V_IS_REF = Symbol.for("__v_isRef");
18
18
  const V_IS_READONLY = Symbol("__v_isReadonly");
19
+ const V_SKIP = Symbol("__v_skip");
19
20
  const V_RAW = Symbol("__v_raw");
20
21
  /**
21
22
  * Creates a reactive ref wrapping the given value.
@@ -88,6 +89,15 @@ function isRef(val) {
88
89
  function unref(r) {
89
90
  return isRef(r) ? r.value : r;
90
91
  }
92
+ /**
93
+ * Unwraps a ref, calls a getter, or returns the value as-is.
94
+ * Vue 3.3+ API for normalizing ref/getter/value inputs.
95
+ */
96
+ function toValue(source) {
97
+ if (isRef(source)) return source.value;
98
+ if (typeof source === "function") return source();
99
+ return source;
100
+ }
91
101
  function computed(fnOrOptions) {
92
102
  const ctx = getCurrentCtx();
93
103
  if (ctx) {
@@ -134,6 +144,7 @@ const rawMap = /* @__PURE__ */ new WeakMap();
134
144
  * call `scheduleRerender()`.
135
145
  */
136
146
  function reactive(obj) {
147
+ if (obj[V_SKIP]) return obj;
137
148
  const ctx = getCurrentCtx();
138
149
  if (ctx) {
139
150
  const idx = getHookIndex();
@@ -183,7 +194,22 @@ function readonly(obj) {
183
194
  }
184
195
  return _createReadonlyProxy(obj);
185
196
  }
186
- function _createReadonlyProxy(obj) {
197
+ /**
198
+ * Returns a shallow readonly proxy — only top-level properties throw on set.
199
+ * Nested objects are NOT wrapped in readonly (unlike `readonly()`).
200
+ */
201
+ function shallowReadonly(obj) {
202
+ const ctx = getCurrentCtx();
203
+ if (ctx) {
204
+ const idx = getHookIndex();
205
+ if (idx < ctx.hooks.length) return ctx.hooks[idx];
206
+ const proxy = _createShallowReadonlyProxy(obj);
207
+ ctx.hooks[idx] = proxy;
208
+ return proxy;
209
+ }
210
+ return _createShallowReadonlyProxy(obj);
211
+ }
212
+ function _createShallowReadonlyProxy(obj) {
187
213
  return new Proxy(obj, {
188
214
  get(target, key) {
189
215
  if (key === V_IS_READONLY) return true;
@@ -199,6 +225,24 @@ function _createReadonlyProxy(obj) {
199
225
  }
200
226
  });
201
227
  }
228
+ function _createReadonlyProxy(obj) {
229
+ return new Proxy(obj, {
230
+ get(target, key) {
231
+ if (key === V_IS_READONLY) return true;
232
+ if (key === V_RAW) return target;
233
+ const value = Reflect.get(target, key);
234
+ if (value !== null && typeof value === "object" && !isRef(value)) return _createReadonlyProxy(value);
235
+ return value;
236
+ },
237
+ set(_target, key) {
238
+ if (key === V_IS_READONLY || key === V_RAW) return true;
239
+ throw new Error(`Cannot set property "${String(key)}" on a readonly object`);
240
+ },
241
+ deleteProperty(_target, key) {
242
+ throw new Error(`Cannot delete property "${String(key)}" from a readonly object`);
243
+ }
244
+ });
245
+ }
202
246
  /**
203
247
  * Returns the raw (unwrapped) object behind a reactive or readonly proxy.
204
248
  */
@@ -255,12 +299,102 @@ function toRefs(obj) {
255
299
  for (const key of Object.keys(obj)) result[key] = _createToRef(obj, key);
256
300
  return result;
257
301
  }
258
- /**
259
- * Watches a reactive source and calls `cb` when it changes.
260
- *
261
- * Inside a component: hook-indexed, created once. Disposed on unmount.
262
- */
263
302
  function watch(source, cb, options) {
303
+ if (Array.isArray(source)) return _watchArray(source, cb, options);
304
+ return _watchSingle(source, cb, options);
305
+ }
306
+ function _watchArray(sources, cb, options) {
307
+ const getters = sources.map((s) => isRef(s) ? () => s.value : s);
308
+ let cleanupFn;
309
+ const onCleanup = (fn) => {
310
+ cleanupFn = fn;
311
+ };
312
+ const runCleanup = () => {
313
+ if (cleanupFn) {
314
+ cleanupFn();
315
+ cleanupFn = void 0;
316
+ }
317
+ };
318
+ const ctx = getCurrentCtx();
319
+ if (ctx) {
320
+ const idx = getHookIndex();
321
+ if (idx < ctx.hooks.length) return ctx.hooks[idx];
322
+ let oldValues;
323
+ let initialized = false;
324
+ if (options?.immediate) {
325
+ const current = getters.map((g) => g());
326
+ cb(current, getters.map(() => void 0), onCleanup);
327
+ oldValues = current;
328
+ initialized = true;
329
+ }
330
+ let running = false;
331
+ const combined = computed$1(() => getters.map((g) => g()));
332
+ const e = effect(() => {
333
+ if (running) return;
334
+ running = true;
335
+ try {
336
+ const newValues = combined();
337
+ if (initialized) {
338
+ runCleanup();
339
+ cb([...newValues], oldValues ? [...oldValues] : getters.map(() => void 0), onCleanup);
340
+ }
341
+ oldValues = [...newValues];
342
+ initialized = true;
343
+ } finally {
344
+ running = false;
345
+ }
346
+ });
347
+ const stop = () => {
348
+ runCleanup();
349
+ e.dispose();
350
+ };
351
+ ctx.hooks[idx] = stop;
352
+ ctx.unmountCallbacks.push(stop);
353
+ return stop;
354
+ }
355
+ let oldValues;
356
+ let initialized = false;
357
+ if (options?.immediate) {
358
+ const current = getters.map((g) => g());
359
+ cb(current, getters.map(() => void 0), onCleanup);
360
+ oldValues = current;
361
+ initialized = true;
362
+ }
363
+ let running = false;
364
+ const combined = computed$1(() => getters.map((g) => g()));
365
+ const e = effect(() => {
366
+ if (running) return;
367
+ running = true;
368
+ try {
369
+ const newValues = combined();
370
+ if (initialized) {
371
+ runCleanup();
372
+ cb([...newValues], oldValues ? [...oldValues] : getters.map(() => void 0), onCleanup);
373
+ }
374
+ oldValues = [...newValues];
375
+ initialized = true;
376
+ } finally {
377
+ running = false;
378
+ }
379
+ });
380
+ const stop = () => {
381
+ runCleanup();
382
+ e.dispose();
383
+ };
384
+ if (_currentEffectScope) _currentEffectScope._cleanups.push(stop);
385
+ return stop;
386
+ }
387
+ function _watchSingle(source, cb, options) {
388
+ let cleanupFn;
389
+ const onCleanup = (fn) => {
390
+ cleanupFn = fn;
391
+ };
392
+ const runCleanup = () => {
393
+ if (cleanupFn) {
394
+ cleanupFn();
395
+ cleanupFn = void 0;
396
+ }
397
+ };
264
398
  const ctx = getCurrentCtx();
265
399
  if (ctx) {
266
400
  const idx = getHookIndex();
@@ -271,7 +405,7 @@ function watch(source, cb, options) {
271
405
  if (options?.immediate) {
272
406
  oldValue = void 0;
273
407
  const current = getter();
274
- cb(current, oldValue);
408
+ cb(current, oldValue, onCleanup);
275
409
  oldValue = current;
276
410
  initialized = true;
277
411
  }
@@ -281,14 +415,20 @@ function watch(source, cb, options) {
281
415
  running = true;
282
416
  try {
283
417
  const newValue = getter();
284
- if (initialized) cb(newValue, oldValue);
418
+ if (initialized) {
419
+ runCleanup();
420
+ cb(newValue, oldValue, onCleanup);
421
+ }
285
422
  oldValue = newValue;
286
423
  initialized = true;
287
424
  } finally {
288
425
  running = false;
289
426
  }
290
427
  });
291
- const stop = () => e.dispose();
428
+ const stop = () => {
429
+ runCleanup();
430
+ e.dispose();
431
+ };
292
432
  ctx.hooks[idx] = stop;
293
433
  ctx.unmountCallbacks.push(stop);
294
434
  return stop;
@@ -299,7 +439,7 @@ function watch(source, cb, options) {
299
439
  if (options?.immediate) {
300
440
  oldValue = void 0;
301
441
  const current = getter();
302
- cb(current, oldValue);
442
+ cb(current, oldValue, onCleanup);
303
443
  oldValue = current;
304
444
  initialized = true;
305
445
  }
@@ -309,23 +449,43 @@ function watch(source, cb, options) {
309
449
  running = true;
310
450
  try {
311
451
  const newValue = getter();
312
- if (initialized) cb(newValue, oldValue);
452
+ if (initialized) {
453
+ runCleanup();
454
+ cb(newValue, oldValue, onCleanup);
455
+ }
313
456
  oldValue = newValue;
314
457
  initialized = true;
315
458
  } finally {
316
459
  running = false;
317
460
  }
318
461
  });
319
- return () => e.dispose();
462
+ const stop = () => {
463
+ runCleanup();
464
+ e.dispose();
465
+ };
466
+ if (_currentEffectScope) _currentEffectScope._cleanups.push(stop);
467
+ return stop;
320
468
  }
321
469
  /**
322
470
  * Runs the given function reactively — re-executes whenever its tracked
323
- * dependencies change.
471
+ * dependencies change. Passes an `onCleanup` registration function to the
472
+ * callback, matching Vue 3's `watchEffect((onCleanup) => { ... })` API.
324
473
  *
325
474
  * Inside a component: hook-indexed, created once. Disposed on unmount.
326
475
  */
327
476
  function watchEffect(fn) {
328
477
  const ctx = getCurrentCtx();
478
+ let cleanupFn;
479
+ const onCleanup = (cleanup) => {
480
+ cleanupFn = cleanup;
481
+ };
482
+ const runEffect = () => {
483
+ if (cleanupFn) {
484
+ cleanupFn();
485
+ cleanupFn = void 0;
486
+ }
487
+ fn(onCleanup);
488
+ };
329
489
  if (ctx) {
330
490
  const idx = getHookIndex();
331
491
  if (idx < ctx.hooks.length) return ctx.hooks[idx];
@@ -334,12 +494,15 @@ function watchEffect(fn) {
334
494
  if (running) return;
335
495
  running = true;
336
496
  try {
337
- fn();
497
+ runEffect();
338
498
  } finally {
339
499
  running = false;
340
500
  }
341
501
  });
342
- const stop = () => e.dispose();
502
+ const stop = () => {
503
+ if (cleanupFn) cleanupFn();
504
+ e.dispose();
505
+ };
343
506
  ctx.hooks[idx] = stop;
344
507
  ctx.unmountCallbacks.push(stop);
345
508
  return stop;
@@ -349,12 +512,17 @@ function watchEffect(fn) {
349
512
  if (running) return;
350
513
  running = true;
351
514
  try {
352
- fn();
515
+ runEffect();
353
516
  } finally {
354
517
  running = false;
355
518
  }
356
519
  });
357
- return () => e.dispose();
520
+ const stop = () => {
521
+ if (cleanupFn) cleanupFn();
522
+ e.dispose();
523
+ };
524
+ if (_currentEffectScope) _currentEffectScope._cleanups.push(stop);
525
+ return stop;
358
526
  }
359
527
  /**
360
528
  * Registers a callback to run after the component is mounted.
@@ -463,10 +631,14 @@ function provide(key, value) {
463
631
  }
464
632
  /**
465
633
  * Injects a value provided by an ancestor component.
634
+ * Supports Vue 3's factory default pattern: `inject(key, () => expensiveDefault, true)`.
466
635
  */
467
- function inject(key, defaultValue) {
636
+ function inject(key, defaultValue, treatDefaultAsFactory) {
468
637
  const value = useContext(getOrCreateContext(key));
469
- return value !== void 0 ? value : defaultValue;
638
+ if (value !== void 0) return value;
639
+ if (defaultValue === void 0) return void 0;
640
+ if (treatDefaultAsFactory && typeof defaultValue === "function") return defaultValue();
641
+ return defaultValue;
470
642
  }
471
643
  /**
472
644
  * Defines a component using Vue 3 Composition API style.
@@ -475,7 +647,16 @@ function inject(key, defaultValue) {
475
647
  function defineComponent(options) {
476
648
  if (typeof options === "function") return options;
477
649
  const comp = (props) => {
478
- const result = options.setup(props);
650
+ const children = props.children;
651
+ const setupCtx = {
652
+ emit: (event, ...args) => {
653
+ const handler = props[`on${event.charAt(0).toUpperCase()}${event.slice(1)}`];
654
+ if (typeof handler === "function") handler(...args);
655
+ },
656
+ slots: { default: children !== void 0 ? (() => children) : void 0 },
657
+ attrs: props
658
+ };
659
+ const result = options.setup(props, setupCtx);
479
660
  if (typeof result === "function") return result();
480
661
  return result;
481
662
  };
@@ -483,16 +664,215 @@ function defineComponent(options) {
483
664
  return comp;
484
665
  }
485
666
  /**
667
+ * Defines an async component that lazily loads on first use.
668
+ * Supports both a bare loader function and an options object with
669
+ * loadingComponent, errorComponent, delay, and timeout.
670
+ *
671
+ * Returns a ComponentFn with a `__loading` property for Suspense integration.
672
+ */
673
+ function defineAsyncComponent(loader) {
674
+ const load = typeof loader === "function" ? loader : loader.loader;
675
+ const loaded = signal(null);
676
+ const error = signal(null);
677
+ let promise = null;
678
+ const startLoad = () => {
679
+ if (promise) return;
680
+ promise = load().then((mod) => loaded.set(mod.default), (err) => error.set(err instanceof Error ? err : new Error(String(err))));
681
+ };
682
+ const AsyncComp = ((props) => {
683
+ startLoad();
684
+ const err = error();
685
+ if (err) throw err;
686
+ const comp = loaded();
687
+ if (!comp) return null;
688
+ return comp(props);
689
+ });
690
+ AsyncComp.__loading = () => {
691
+ const isLoading = loaded() === null && error() === null;
692
+ if (isLoading) startLoad();
693
+ return isLoading;
694
+ };
695
+ return AsyncComp;
696
+ }
697
+ /**
486
698
  * Creates a Pyreon application instance — Vue 3 `createApp()` compatible.
487
699
  */
488
700
  function createApp(component, props) {
489
- return { mount(el) {
490
- const container = typeof el === "string" ? document.querySelector(el) : el;
491
- if (!container) throw new Error(`Cannot find mount target: ${el}`);
492
- return mount(pyreonH(component, props ?? null), container);
493
- } };
701
+ const provisions = [];
702
+ const app = {
703
+ mount(el) {
704
+ const container = typeof el === "string" ? document.querySelector(el) : el;
705
+ if (!container) throw new Error(`Cannot find mount target: ${el}`);
706
+ for (const { key, value } of provisions) {
707
+ const ctx = getOrCreateContext(key);
708
+ pushContext(new Map([[ctx.id, value]]));
709
+ }
710
+ return mount(pyreonH(component, props ?? null), container);
711
+ },
712
+ use(plugin) {
713
+ plugin.install(app);
714
+ return app;
715
+ },
716
+ provide(key, value) {
717
+ provisions.push({
718
+ key,
719
+ value
720
+ });
721
+ return app;
722
+ }
723
+ };
724
+ return app;
494
725
  }
726
+ /**
727
+ * Returns `true` if the value was created by `reactive()`.
728
+ */
729
+ function isReactive(value) {
730
+ return value !== null && typeof value === "object" && rawMap.has(value);
731
+ }
732
+ /**
733
+ * Returns `true` if the value was created by `readonly()`.
734
+ */
735
+ function isReadonly(value) {
736
+ return value !== null && typeof value === "object" && value[V_IS_READONLY] === true;
737
+ }
738
+ /**
739
+ * Returns `true` if the value is either reactive or readonly.
740
+ */
741
+ function isProxy(value) {
742
+ return isReactive(value) || isReadonly(value);
743
+ }
744
+ /**
745
+ * Marks an object so that `reactive()` will return it as-is (not wrapped).
746
+ */
747
+ function markRaw(obj) {
748
+ obj[V_SKIP] = true;
749
+ return obj;
750
+ }
751
+ let _currentEffectScope = null;
752
+ /**
753
+ * Creates an effect scope that collects reactive effects for grouped disposal.
754
+ *
755
+ * @param detached - If true, the scope is not collected by a parent scope.
756
+ */
757
+ function effectScope(detached) {
758
+ const cleanups = [];
759
+ let active = true;
760
+ const scope = {
761
+ get active() {
762
+ return active;
763
+ },
764
+ run(fn) {
765
+ if (!active) return void 0;
766
+ const prev = _currentEffectScope;
767
+ _currentEffectScope = scope;
768
+ try {
769
+ return fn();
770
+ } finally {
771
+ _currentEffectScope = prev;
772
+ }
773
+ },
774
+ stop() {
775
+ if (!active) return;
776
+ active = false;
777
+ for (const fn of cleanups) fn();
778
+ cleanups.length = 0;
779
+ }
780
+ };
781
+ if (!detached && _currentEffectScope) {
782
+ const parentCleanups = _currentEffectScope._cleanups;
783
+ if (parentCleanups) parentCleanups.push(() => scope.stop());
784
+ }
785
+ scope._cleanups = cleanups;
786
+ return scope;
787
+ }
788
+ /**
789
+ * Returns the current active effect scope, or undefined if none.
790
+ */
791
+ function getCurrentScope() {
792
+ return _currentEffectScope ?? void 0;
793
+ }
794
+ /**
795
+ * Registers a cleanup function on the current effect scope.
796
+ */
797
+ function onScopeDispose(fn) {
798
+ if (_currentEffectScope) _currentEffectScope._cleanups.push(fn);
799
+ }
800
+ /**
801
+ * Registers an error capture handler.
802
+ * No direct equivalent in Pyreon — stored but not actively used.
803
+ */
804
+ function onErrorCaptured(fn) {
805
+ const ctx = getCurrentCtx();
806
+ if (ctx) {
807
+ const idx = getHookIndex();
808
+ if (idx < ctx.hooks.length) return;
809
+ ctx.hooks[idx] = fn;
810
+ }
811
+ }
812
+ /**
813
+ * Dev-only lifecycle hook — no-op in Pyreon.
814
+ */
815
+ function onRenderTracked(_fn) {}
816
+ /**
817
+ * Dev-only lifecycle hook — no-op in Pyreon.
818
+ */
819
+ function onRenderTriggered(_fn) {}
820
+ /**
821
+ * Teleport — renders children into a different DOM element.
822
+ * Maps to Pyreon's Portal.
823
+ */
824
+ function Teleport(props) {
825
+ const target = typeof props.to === "string" ? document.querySelector(props.to) : props.to;
826
+ if (!target) return props.children ?? null;
827
+ return Portal({
828
+ target,
829
+ children: props.children ?? null
830
+ });
831
+ }
832
+ /**
833
+ * KeepAlive — not supported in Pyreon. Renders children as-is.
834
+ */
835
+ function KeepAlive(props) {
836
+ return props.children ?? null;
837
+ }
838
+ /**
839
+ * Runs a watchEffect that flushes after DOM updates.
840
+ * In Pyreon, same as `watchEffect()`.
841
+ */
842
+ function watchPostEffect(fn) {
843
+ return watchEffect(fn);
844
+ }
845
+ /**
846
+ * Runs a watchEffect that flushes synchronously.
847
+ * In Pyreon, same as `watchEffect()`.
848
+ */
849
+ function watchSyncEffect(fn) {
850
+ return watchEffect(fn);
851
+ }
852
+ /**
853
+ * Creates a customized ref with explicit control over dependency tracking
854
+ * and update triggering.
855
+ */
856
+ function customRef(factory) {
857
+ const s = signal(0);
858
+ const { get, set } = factory(() => {
859
+ s();
860
+ }, () => s.set(s.peek() + 1));
861
+ return {
862
+ [V_IS_REF]: true,
863
+ get value() {
864
+ return get();
865
+ },
866
+ set value(v) {
867
+ set(v);
868
+ }
869
+ };
870
+ }
871
+ /**
872
+ * Compatibility version string — indicates Vue 3 API compatibility.
873
+ */
874
+ const version = "3.5.0-pyreon";
495
875
 
496
876
  //#endregion
497
- export { Fragment, batch, computed, createApp, defineComponent, pyreonH as h, inject, isRef, nextTick, onBeforeMount, onBeforeUnmount, onMounted, onUnmounted, onUpdated, provide, reactive, readonly, ref, shallowReactive, shallowRef, toRaw, toRef, toRefs, triggerRef, unref, watch, watchEffect };
877
+ export { Fragment, KeepAlive, Teleport, batch, computed, createApp, customRef, defineAsyncComponent, defineComponent, effectScope, getCurrentScope, pyreonH as h, inject, isProxy, isReactive, isReadonly, isRef, markRaw, nextTick, onBeforeMount, onBeforeUnmount, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onUnmounted, onUpdated, provide, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toRefs, toValue, triggerRef, unref, version, watch, watchEffect, watchPostEffect, watchSyncEffect };
498
878
  //# sourceMappingURL=index.js.map