@sigx/terminal 0.1.4 → 0.1.6

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.
package/dist/index.js CHANGED
@@ -1,7 +1,13 @@
1
- //#region ../reactivity/src/index.ts
1
+ const ComputedSymbol = Symbol("computed");
2
2
  let activeEffect = null;
3
- let batchDepth = 0;
4
- const pendingEffects = /* @__PURE__ */ new Set();
3
+ var batchDepth = 0;
4
+ var pendingEffects = /* @__PURE__ */ new Set();
5
+ function setActiveEffect(effect) {
6
+ activeEffect = effect;
7
+ }
8
+ function getActiveEffect() {
9
+ return activeEffect;
10
+ }
5
11
  function batch(fn) {
6
12
  batchDepth++;
7
13
  try {
@@ -11,10 +17,25 @@ function batch(fn) {
11
17
  if (batchDepth === 0) {
12
18
  const effects = Array.from(pendingEffects);
13
19
  pendingEffects.clear();
14
- for (const effect$1 of effects) effect$1();
20
+ for (const effect of effects) effect();
15
21
  }
16
22
  }
17
23
  }
24
+ function cleanup(effect) {
25
+ if (!effect.deps) return;
26
+ for (const dep of effect.deps) dep.delete(effect);
27
+ effect.deps.length = 0;
28
+ }
29
+ function track(depSet) {
30
+ if (!activeEffect) return;
31
+ depSet.add(activeEffect);
32
+ activeEffect.deps.push(depSet);
33
+ }
34
+ function trigger(depSet) {
35
+ const effects = Array.from(depSet);
36
+ for (const effect of effects) if (batchDepth > 0) pendingEffects.add(effect);
37
+ else effect();
38
+ }
18
39
  function runEffect(fn) {
19
40
  const effectFn = function() {
20
41
  cleanup(effectFn);
@@ -28,27 +49,228 @@ function runEffect(fn) {
28
49
  runner.stop = () => cleanup(effectFn);
29
50
  return runner;
30
51
  }
31
- function cleanup(effect$1) {
32
- if (!effect$1.deps) return;
33
- for (const dep of effect$1.deps) dep.delete(effect$1);
34
- effect$1.deps.length = 0;
52
+ function effect(fn) {
53
+ return runEffect(fn);
35
54
  }
36
- function track(depSet) {
37
- if (!activeEffect) return;
38
- depSet.add(activeEffect);
39
- activeEffect.deps.push(depSet);
55
+ function untrack(fn) {
56
+ const prev = activeEffect;
57
+ activeEffect = null;
58
+ try {
59
+ return fn();
60
+ } finally {
61
+ activeEffect = prev;
62
+ }
40
63
  }
41
- function trigger(depSet) {
42
- const effects = Array.from(depSet);
43
- for (const effect$1 of effects) if (batchDepth > 0) pendingEffects.add(effect$1);
44
- else effect$1();
64
+ function effectScope(detached) {
65
+ const effects = [];
66
+ let active = true;
67
+ return {
68
+ run(fn) {
69
+ if (!active) return void 0;
70
+ return fn();
71
+ },
72
+ stop() {
73
+ active = false;
74
+ effects.forEach((e) => e());
75
+ }
76
+ };
77
+ }
78
+ const ITERATE_KEY = Symbol("iterate");
79
+ const reactiveToRaw = /* @__PURE__ */ new WeakMap();
80
+ const rawToReactive = /* @__PURE__ */ new WeakMap();
81
+ function toRaw(observed) {
82
+ const raw = reactiveToRaw.get(observed);
83
+ return raw ? toRaw(raw) : observed;
84
+ }
85
+ function isReactive(value) {
86
+ return reactiveToRaw.has(value);
87
+ }
88
+ function isCollection(value) {
89
+ if (!value || typeof value !== "object") return false;
90
+ const ctor = value.constructor;
91
+ return ctor === Set || ctor === Map || ctor === WeakSet || ctor === WeakMap;
92
+ }
93
+ function isIterableCollection(value) {
94
+ if (!value || typeof value !== "object") return false;
95
+ const ctor = value.constructor;
96
+ return ctor === Set || ctor === Map;
97
+ }
98
+ function shouldNotProxy(value) {
99
+ if (!value || typeof value !== "object") return false;
100
+ const proto = Object.prototype.toString.call(value);
101
+ return [
102
+ "[object Date]",
103
+ "[object RegExp]",
104
+ "[object Error]",
105
+ "[object Promise]",
106
+ "[object ArrayBuffer]",
107
+ "[object DataView]",
108
+ "[object Int8Array]",
109
+ "[object Uint8Array]",
110
+ "[object Uint8ClampedArray]",
111
+ "[object Int16Array]",
112
+ "[object Uint16Array]",
113
+ "[object Int32Array]",
114
+ "[object Uint32Array]",
115
+ "[object Float32Array]",
116
+ "[object Float64Array]",
117
+ "[object BigInt64Array]",
118
+ "[object BigUint64Array]"
119
+ ].includes(proto);
120
+ }
121
+ function createCollectionInstrumentations(depsMap, getOrCreateDep) {
122
+ const instrumentations = {};
123
+ instrumentations.has = function(key) {
124
+ const target = toRaw(this);
125
+ const rawKey = toRaw(key);
126
+ track(getOrCreateDep(rawKey));
127
+ return target.has(rawKey);
128
+ };
129
+ instrumentations.get = function(key) {
130
+ const target = toRaw(this);
131
+ const rawKey = toRaw(key);
132
+ track(getOrCreateDep(rawKey));
133
+ const value = target.get(rawKey);
134
+ if (value && typeof value === "object") return rawToReactive.get(value) || value;
135
+ return value;
136
+ };
137
+ Object.defineProperty(instrumentations, "size", { get() {
138
+ const target = toRaw(this);
139
+ track(getOrCreateDep(ITERATE_KEY));
140
+ return target.size;
141
+ } });
142
+ instrumentations.forEach = function(callback, thisArg) {
143
+ const target = toRaw(this);
144
+ track(getOrCreateDep(ITERATE_KEY));
145
+ target.forEach((value, key) => {
146
+ const reactiveValue = value && typeof value === "object" ? rawToReactive.get(value) || value : value;
147
+ const reactiveKey = key && typeof key === "object" ? rawToReactive.get(key) || key : key;
148
+ callback.call(thisArg, reactiveValue, reactiveKey, this);
149
+ });
150
+ };
151
+ instrumentations.keys = function() {
152
+ const target = toRaw(this);
153
+ track(getOrCreateDep(ITERATE_KEY));
154
+ return createReactiveIterator(target.keys(), false);
155
+ };
156
+ instrumentations.values = function() {
157
+ const target = toRaw(this);
158
+ track(getOrCreateDep(ITERATE_KEY));
159
+ return createReactiveIterator(target.values(), true);
160
+ };
161
+ instrumentations.entries = function() {
162
+ const target = toRaw(this);
163
+ track(getOrCreateDep(ITERATE_KEY));
164
+ return createReactiveEntriesIterator(target.entries());
165
+ };
166
+ instrumentations[Symbol.iterator] = function() {
167
+ const target = toRaw(this);
168
+ track(getOrCreateDep(ITERATE_KEY));
169
+ if (target instanceof Set) return createReactiveIterator(target.values(), true);
170
+ else return createReactiveEntriesIterator(target.entries());
171
+ };
172
+ instrumentations.add = function(value) {
173
+ const target = toRaw(this);
174
+ const rawValue = toRaw(value);
175
+ const hadKey = target.has(rawValue);
176
+ target.add(rawValue);
177
+ if (!hadKey) {
178
+ const dep = depsMap.get(rawValue);
179
+ if (dep) trigger(dep);
180
+ const iterDep = depsMap.get(ITERATE_KEY);
181
+ if (iterDep) trigger(iterDep);
182
+ }
183
+ return this;
184
+ };
185
+ instrumentations.set = function(key, value) {
186
+ const target = toRaw(this);
187
+ const rawKey = toRaw(key);
188
+ const rawValue = toRaw(value);
189
+ const hadKey = target.has(rawKey);
190
+ const oldValue = target.get(rawKey);
191
+ target.set(rawKey, rawValue);
192
+ if (!hadKey) {
193
+ const iterDep = depsMap.get(ITERATE_KEY);
194
+ if (iterDep) trigger(iterDep);
195
+ }
196
+ if (!hadKey || !Object.is(oldValue, rawValue)) {
197
+ const dep = depsMap.get(rawKey);
198
+ if (dep) trigger(dep);
199
+ }
200
+ return this;
201
+ };
202
+ instrumentations.delete = function(key) {
203
+ const target = toRaw(this);
204
+ const rawKey = toRaw(key);
205
+ const hadKey = target.has(rawKey);
206
+ const result = target.delete(rawKey);
207
+ if (hadKey) {
208
+ const dep = depsMap.get(rawKey);
209
+ if (dep) trigger(dep);
210
+ const iterDep = depsMap.get(ITERATE_KEY);
211
+ if (iterDep) trigger(iterDep);
212
+ }
213
+ return result;
214
+ };
215
+ instrumentations.clear = function() {
216
+ const target = toRaw(this);
217
+ const hadItems = target.size > 0;
218
+ target.clear();
219
+ if (hadItems) for (const dep of depsMap.values()) trigger(dep);
220
+ };
221
+ return instrumentations;
222
+ }
223
+ function createReactiveIterator(innerIterator, wrapValues) {
224
+ return {
225
+ next() {
226
+ const { value, done } = innerIterator.next();
227
+ if (done) return {
228
+ value: void 0,
229
+ done: true
230
+ };
231
+ return {
232
+ value: wrapValues && value && typeof value === "object" ? rawToReactive.get(value) || value : value,
233
+ done: false
234
+ };
235
+ },
236
+ [Symbol.iterator]() {
237
+ return this;
238
+ }
239
+ };
240
+ }
241
+ function createReactiveEntriesIterator(innerIterator) {
242
+ return {
243
+ next() {
244
+ const { value, done } = innerIterator.next();
245
+ if (done) return {
246
+ value: void 0,
247
+ done: true
248
+ };
249
+ const [key, val] = value;
250
+ return {
251
+ value: [key && typeof key === "object" ? rawToReactive.get(key) || key : key, val && typeof val === "object" ? rawToReactive.get(val) || val : val],
252
+ done: false
253
+ };
254
+ },
255
+ [Symbol.iterator]() {
256
+ return this;
257
+ }
258
+ };
259
+ }
260
+ function isPrimitive(value) {
261
+ if (value === null || value === void 0) return true;
262
+ const type = typeof value;
263
+ return type === "string" || type === "number" || type === "boolean" || type === "symbol" || type === "bigint";
264
+ }
265
+ var accessObserver = null;
266
+ function getAccessObserver() {
267
+ return accessObserver;
45
268
  }
46
- let accessObserver = null;
47
269
  function detectAccess(selector) {
48
270
  let result = null;
49
271
  const prev = accessObserver;
50
272
  accessObserver = (target, key) => {
51
- result = [target, key];
273
+ if (result === null) result = [target, key];
52
274
  };
53
275
  try {
54
276
  selector();
@@ -57,19 +279,43 @@ function detectAccess(selector) {
57
279
  }
58
280
  return result;
59
281
  }
60
- function untrack(fn) {
61
- const prev = activeEffect;
62
- activeEffect = null;
63
- try {
64
- return fn();
65
- } finally {
66
- activeEffect = prev;
67
- }
68
- }
282
+ var arrayInstrumentations = {};
283
+ [
284
+ "push",
285
+ "pop",
286
+ "shift",
287
+ "unshift",
288
+ "splice",
289
+ "sort",
290
+ "reverse"
291
+ ].forEach((method) => {
292
+ arrayInstrumentations[method] = function(...args) {
293
+ let res;
294
+ batch(() => {
295
+ res = Array.prototype[method].apply(this, args);
296
+ });
297
+ return res;
298
+ };
299
+ });
69
300
  function signal(target) {
301
+ if (isPrimitive(target)) return signal({ value: target });
302
+ const objectTarget = target;
303
+ if (shouldNotProxy(objectTarget)) return objectTarget;
304
+ if (isReactive(objectTarget)) return objectTarget;
305
+ const existingProxy = rawToReactive.get(objectTarget);
306
+ if (existingProxy) return existingProxy;
70
307
  const depsMap = /* @__PURE__ */ new Map();
71
308
  const reactiveCache = /* @__PURE__ */ new WeakMap();
72
- return new Proxy(target, {
309
+ const getOrCreateDep = (key) => {
310
+ let dep = depsMap.get(key);
311
+ if (!dep) {
312
+ dep = /* @__PURE__ */ new Set();
313
+ depsMap.set(key, dep);
314
+ }
315
+ return dep;
316
+ };
317
+ const collectionInstrumentations = isCollection(objectTarget) ? createCollectionInstrumentations(depsMap, getOrCreateDep) : null;
318
+ const proxy = new Proxy(objectTarget, {
73
319
  get(obj, prop, receiver) {
74
320
  if (prop === "$set") return (newValue) => {
75
321
  batch(() => {
@@ -85,16 +331,22 @@ function signal(target) {
85
331
  }
86
332
  });
87
333
  };
334
+ if (collectionInstrumentations) {
335
+ if (prop === "size" && isIterableCollection(obj)) {
336
+ track(getOrCreateDep(ITERATE_KEY));
337
+ return obj.size;
338
+ }
339
+ if (prop in collectionInstrumentations) {
340
+ const instrumented = collectionInstrumentations[prop];
341
+ if (typeof instrumented === "function") return instrumented.bind(receiver);
342
+ return instrumented;
343
+ }
344
+ }
88
345
  if (Array.isArray(obj) && typeof prop === "string" && arrayInstrumentations.hasOwnProperty(prop)) return arrayInstrumentations[prop];
89
346
  const value = Reflect.get(obj, prop);
90
347
  if (accessObserver) accessObserver(receiver, prop);
91
- let dep = depsMap.get(prop);
92
- if (!dep) {
93
- dep = /* @__PURE__ */ new Set();
94
- depsMap.set(prop, dep);
95
- }
96
- track(dep);
97
- if (value && typeof value === "object") {
348
+ if (!collectionInstrumentations) track(getOrCreateDep(prop));
349
+ if (value && typeof value === "object" && !shouldNotProxy(value)) {
98
350
  let cached = reactiveCache.get(value);
99
351
  if (!cached) {
100
352
  cached = signal(value);
@@ -134,28 +386,26 @@ function signal(target) {
134
386
  return result;
135
387
  }
136
388
  });
389
+ reactiveToRaw.set(proxy, objectTarget);
390
+ rawToReactive.set(objectTarget, proxy);
391
+ return proxy;
392
+ }
393
+ function traverse(value, depth = Infinity, seen = /* @__PURE__ */ new Set()) {
394
+ if (depth <= 0) return value;
395
+ if (value === null || typeof value !== "object") return value;
396
+ if (seen.has(value)) return value;
397
+ seen.add(value);
398
+ if (Array.isArray(value)) for (let i = 0; i < value.length; i++) traverse(value[i], depth - 1, seen);
399
+ else if (value instanceof Map) value.forEach((v, k) => {
400
+ traverse(k, depth - 1, seen);
401
+ traverse(v, depth - 1, seen);
402
+ });
403
+ else if (value instanceof Set) value.forEach((v) => {
404
+ traverse(v, depth - 1, seen);
405
+ });
406
+ else for (const key of Object.keys(value)) traverse(value[key], depth - 1, seen);
407
+ return value;
137
408
  }
138
- function effect(fn) {
139
- return runEffect(fn);
140
- }
141
- const arrayInstrumentations = {};
142
- [
143
- "push",
144
- "pop",
145
- "shift",
146
- "unshift",
147
- "splice",
148
- "sort",
149
- "reverse"
150
- ].forEach((method) => {
151
- arrayInstrumentations[method] = function(...args) {
152
- let res;
153
- batch(() => {
154
- res = Array.prototype[method].apply(this, args);
155
- });
156
- return res;
157
- };
158
- });
159
409
  function watch(source, cb, options) {
160
410
  let oldValue;
161
411
  let isFirst = true;
@@ -163,8 +413,13 @@ function watch(source, cb, options) {
163
413
  let paused = false;
164
414
  let pendingValue;
165
415
  let hasPending = false;
416
+ let stopped = false;
417
+ const deep = options?.deep;
418
+ const traverseDepth = deep === true ? Infinity : typeof deep === "number" ? deep : 0;
166
419
  const runner = effect(() => {
167
- const newValue = typeof source === "function" ? source() : source;
420
+ if (stopped) return;
421
+ let newValue = typeof source === "function" ? source() : source;
422
+ if (traverseDepth > 0) traverse(newValue, traverseDepth);
168
423
  if (paused) {
169
424
  pendingValue = newValue;
170
425
  hasPending = true;
@@ -174,15 +429,24 @@ function watch(source, cb, options) {
174
429
  if (options?.immediate) {
175
430
  if (cleanupFn) cleanupFn();
176
431
  cb(newValue, oldValue, (fn) => cleanupFn = fn);
432
+ if (options?.once) {
433
+ stopped = true;
434
+ queueMicrotask(() => stop());
435
+ }
177
436
  }
178
437
  isFirst = false;
179
438
  } else {
180
439
  if (cleanupFn) cleanupFn();
181
440
  cb(newValue, oldValue, (fn) => cleanupFn = fn);
441
+ if (options?.once) {
442
+ stopped = true;
443
+ queueMicrotask(() => stop());
444
+ }
182
445
  }
183
446
  oldValue = newValue;
184
447
  });
185
448
  const stop = () => {
449
+ stopped = true;
186
450
  runner.stop();
187
451
  if (cleanupFn) cleanupFn();
188
452
  };
@@ -206,101 +470,201 @@ function watch(source, cb, options) {
206
470
  resume
207
471
  });
208
472
  }
209
- function effectScope(detached) {
210
- const effects = [];
211
- let active = true;
212
- return {
213
- run(fn) {
214
- if (!active) return void 0;
215
- return fn();
216
- },
217
- stop() {
218
- active = false;
219
- effects.forEach((e) => e());
473
+ function computed(getterOrOptions) {
474
+ let getter;
475
+ let setter;
476
+ if (typeof getterOrOptions === "function") getter = getterOrOptions;
477
+ else {
478
+ getter = getterOrOptions.get;
479
+ setter = getterOrOptions.set;
480
+ }
481
+ const subscribers = /* @__PURE__ */ new Set();
482
+ let cachedValue;
483
+ let dirty = true;
484
+ const computedEffect = function() {
485
+ if (!dirty) {
486
+ dirty = true;
487
+ trigger(subscribers);
488
+ }
489
+ };
490
+ computedEffect.deps = [];
491
+ const computeValue = () => {
492
+ cleanup(computedEffect);
493
+ const prevEffect = getActiveEffect();
494
+ setActiveEffect(computedEffect);
495
+ try {
496
+ cachedValue = getter();
497
+ dirty = false;
498
+ return cachedValue;
499
+ } finally {
500
+ setActiveEffect(prevEffect);
220
501
  }
221
502
  };
503
+ const computedObj = {
504
+ [ComputedSymbol]: true,
505
+ get value() {
506
+ const observer = getAccessObserver();
507
+ if (observer) observer(computedObj, "value");
508
+ track(subscribers);
509
+ return dirty ? computeValue() : cachedValue;
510
+ }
511
+ };
512
+ if (setter) {
513
+ Object.defineProperty(computedObj, "value", {
514
+ get() {
515
+ const observer = getAccessObserver();
516
+ if (observer) observer(computedObj, "value");
517
+ track(subscribers);
518
+ return dirty ? computeValue() : cachedValue;
519
+ },
520
+ set(newValue) {
521
+ setter(newValue);
522
+ },
523
+ enumerable: true,
524
+ configurable: false
525
+ });
526
+ return computedObj;
527
+ }
528
+ return computedObj;
222
529
  }
223
-
224
- //#endregion
225
- //#region ../runtime-core/src/platform.ts
226
- let platformSyncProcessor$1 = null;
227
- /**
228
- * Set the platform-specific sync processor for intrinsic elements.
229
- * Called by runtime-dom to handle checkbox/radio/select sync bindings.
230
- */
231
- function setPlatformSyncProcessor(fn) {
232
- platformSyncProcessor$1 = fn;
233
- }
234
- /**
235
- * Get the current platform sync processor (for internal use).
236
- */
237
- function getPlatformSyncProcessor() {
238
- return platformSyncProcessor$1;
530
+ function isComputed(value) {
531
+ return value !== null && typeof value === "object" && ComputedSymbol in value;
239
532
  }
240
-
241
- //#endregion
242
- //#region ../runtime-core/src/plugins.ts
243
- const plugins$1 = [];
533
+ var platformModelProcessor = null;
534
+ function setPlatformModelProcessor(fn) {
535
+ platformModelProcessor = fn;
536
+ }
537
+ function getPlatformModelProcessor() {
538
+ return platformModelProcessor;
539
+ }
540
+ var plugins = [];
244
541
  function registerComponentPlugin(plugin) {
245
- plugins$1.push(plugin);
542
+ plugins.push(plugin);
246
543
  }
247
- /**
248
- * Get all registered plugins (internal use)
249
- */
250
544
  function getComponentPlugins() {
251
- return plugins$1;
545
+ return plugins;
252
546
  }
253
-
254
- //#endregion
255
- //#region ../runtime-core/src/app.ts
256
- const isDev = typeof process !== "undefined" && true || true;
257
- /**
258
- * Unique symbol for app context injection
259
- */
260
- const AppContextKey = Symbol("sigx:app");
261
- let defaultMountFn = null;
262
- /**
263
- * Set the default mount function for the platform.
264
- * Called by platform packages (runtime-dom, runtime-terminal) on import.
265
- *
266
- * @example
267
- * ```typescript
268
- * // In @sigx/runtime-dom
269
- * import { setDefaultMount } from '@sigx/runtime-core';
270
- * setDefaultMount(domMount);
271
- * ```
272
- */
547
+ var contextExtensions = [];
548
+ function registerContextExtension(extension) {
549
+ contextExtensions.push(extension);
550
+ }
551
+ function applyContextExtensions(ctx) {
552
+ for (const extension of contextExtensions) extension(ctx);
553
+ }
554
+ var currentComponentContext = null;
555
+ function getCurrentInstance() {
556
+ return currentComponentContext;
557
+ }
558
+ function setCurrentInstance(ctx) {
559
+ const prev = currentComponentContext;
560
+ currentComponentContext = ctx;
561
+ return prev;
562
+ }
563
+ function onMounted(fn) {
564
+ if (currentComponentContext) currentComponentContext.onMounted(fn);
565
+ else console.warn("onMounted called outside of component setup");
566
+ }
567
+ function onUnmounted(fn) {
568
+ if (currentComponentContext) currentComponentContext.onUnmounted(fn);
569
+ else console.warn("onUnmounted called outside of component setup");
570
+ }
571
+ function onCreated(fn) {
572
+ if (currentComponentContext) currentComponentContext.onCreated(fn);
573
+ else console.warn("onCreated called outside of component setup");
574
+ }
575
+ function onUpdated(fn) {
576
+ if (currentComponentContext) currentComponentContext.onUpdated(fn);
577
+ else console.warn("onUpdated called outside of component setup");
578
+ }
579
+ var componentRegistry = /* @__PURE__ */ new Map();
580
+ function getComponentMeta(factory) {
581
+ return componentRegistry.get(factory);
582
+ }
583
+ function createPropsProxy(target, onAccess) {
584
+ return new Proxy(target, { get(obj, prop) {
585
+ if (typeof prop === "string" && onAccess) onAccess(prop);
586
+ return obj[prop];
587
+ } });
588
+ }
589
+ function component(setup, options) {
590
+ const factory = function(props) {
591
+ return {
592
+ type: factory,
593
+ props: props || {},
594
+ key: props?.key || null,
595
+ children: [],
596
+ dom: null
597
+ };
598
+ };
599
+ factory.__setup = setup;
600
+ factory.__name = options?.name;
601
+ factory.__props = null;
602
+ factory.__events = null;
603
+ factory.__ref = null;
604
+ factory.__slots = null;
605
+ componentRegistry.set(factory, {
606
+ name: options?.name,
607
+ setup
608
+ });
609
+ getComponentPlugins().forEach((p) => p.onDefine?.(options?.name, factory, setup));
610
+ return factory;
611
+ }
612
+ var globalInstances = /* @__PURE__ */ new Map();
613
+ var appContextToken = Symbol("sigx:appContext");
614
+ function lookupProvided(token) {
615
+ const ctx = getCurrentInstance();
616
+ if (!ctx) return;
617
+ let current = ctx;
618
+ while (current) {
619
+ if (current.provides && current.provides.has(token)) return current.provides.get(token);
620
+ current = current.parent;
621
+ }
622
+ }
623
+ function provideAtComponent(token, value) {
624
+ const ctx = getCurrentInstance();
625
+ if (!ctx) throw new Error("defineProvide must be called inside a component setup function");
626
+ if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
627
+ ctx.provides.set(token, value);
628
+ }
629
+ function defineInjectable(factory) {
630
+ const token = Symbol();
631
+ const useFn = (() => {
632
+ const provided = lookupProvided(token);
633
+ if (provided !== void 0) return provided;
634
+ if (!globalInstances.has(token)) globalInstances.set(token, factory());
635
+ return globalInstances.get(token);
636
+ });
637
+ useFn._factory = factory;
638
+ useFn._token = token;
639
+ return useFn;
640
+ }
641
+ function defineProvide(useFn, factory) {
642
+ const actualFactory = factory ?? useFn._factory;
643
+ const token = useFn._token;
644
+ if (!actualFactory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
645
+ const instance = actualFactory();
646
+ provideAtComponent(token, instance);
647
+ return instance;
648
+ }
649
+ function useAppContext() {
650
+ return lookupProvided(appContextToken) ?? null;
651
+ }
652
+ function getAppContextToken() {
653
+ return appContextToken;
654
+ }
655
+ function provideAppContext(ctx, appContext) {
656
+ if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
657
+ ctx.provides.set(appContextToken, appContext);
658
+ if (appContext.provides) for (const [token, value] of appContext.provides) ctx.provides.set(token, value);
659
+ }
660
+ var isDev = typeof process !== "undefined" && process.env.NODE_ENV !== "production" || true;
661
+ var defaultMountFn = null;
273
662
  function setDefaultMount(mountFn) {
274
663
  defaultMountFn = mountFn;
275
664
  }
276
- /**
277
- * Get the current default mount function.
278
- * @internal
279
- */
280
665
  function getDefaultMount() {
281
666
  return defaultMountFn;
282
667
  }
283
- /**
284
- * Create an application instance.
285
- *
286
- * @example
287
- * ```tsx
288
- * import { defineApp, defineInjectable } from '@sigx/runtime-core';
289
- * import { render } from '@sigx/runtime-dom';
290
- *
291
- * // Define an injectable service
292
- * const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));
293
- *
294
- * const app = defineApp(<App />);
295
- *
296
- * app.use(myPlugin, { option: 'value' });
297
- *
298
- * // Provide using the injectable token (works with inject())
299
- * app.provide(useApiConfig, { baseUrl: 'https://custom.api.com' });
300
- *
301
- * app.mount(document.getElementById('app')!, render);
302
- * ```
303
- */
304
668
  function defineApp(rootComponent) {
305
669
  const installedPlugins = /* @__PURE__ */ new Set();
306
670
  const context = {
@@ -311,7 +675,7 @@ function defineApp(rootComponent) {
311
675
  };
312
676
  let isMounted = false;
313
677
  let container = null;
314
- let unmountFn$1 = null;
678
+ let unmountFn = null;
315
679
  const app = {
316
680
  config: context.config,
317
681
  use(plugin, options) {
@@ -325,11 +689,13 @@ function defineApp(rootComponent) {
325
689
  else if (isDev) console.warn("Invalid plugin: must be a function or have an install() method.");
326
690
  return app;
327
691
  },
328
- provide(token, value) {
329
- const actualToken = token?._token ?? token;
330
- if (isDev && context.provides.has(actualToken)) console.warn(`App-level provide: token is being overwritten.`);
331
- context.provides.set(actualToken, value);
332
- return app;
692
+ defineProvide(useFn, factory) {
693
+ const actualFactory = factory ?? useFn._factory;
694
+ const token = useFn._token;
695
+ if (!actualFactory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
696
+ const instance = actualFactory();
697
+ context.provides.set(token, instance);
698
+ return instance;
333
699
  },
334
700
  hook(hooks) {
335
701
  context.hooks.push(hooks);
@@ -345,7 +711,7 @@ function defineApp(rootComponent) {
345
711
  container = target;
346
712
  isMounted = true;
347
713
  const result = mountFn(rootComponent, target, context);
348
- if (typeof result === "function") unmountFn$1 = result;
714
+ if (typeof result === "function") unmountFn = result;
349
715
  return app;
350
716
  },
351
717
  unmount() {
@@ -353,7 +719,7 @@ function defineApp(rootComponent) {
353
719
  if (isDev) console.warn("App is not mounted.");
354
720
  return;
355
721
  }
356
- if (unmountFn$1) unmountFn$1();
722
+ if (unmountFn) unmountFn();
357
723
  context.provides.clear();
358
724
  isMounted = false;
359
725
  container = null;
@@ -366,15 +732,16 @@ function defineApp(rootComponent) {
366
732
  },
367
733
  get _container() {
368
734
  return container;
735
+ },
736
+ get _rootComponent() {
737
+ return rootComponent;
369
738
  }
370
739
  };
371
740
  context.app = app;
741
+ const appContextToken = getAppContextToken();
742
+ context.provides.set(appContextToken, context);
372
743
  return app;
373
744
  }
374
- /**
375
- * Notify all app hooks that a component was created.
376
- * Called by the renderer after setup() returns.
377
- */
378
745
  function notifyComponentCreated(context, instance) {
379
746
  if (!context) return;
380
747
  for (const hooks of context.hooks) try {
@@ -383,10 +750,6 @@ function notifyComponentCreated(context, instance) {
383
750
  handleHookError(context, err, instance, "onComponentCreated");
384
751
  }
385
752
  }
386
- /**
387
- * Notify all app hooks that a component was mounted.
388
- * Called by the renderer after mount hooks run.
389
- */
390
753
  function notifyComponentMounted(context, instance) {
391
754
  if (!context) return;
392
755
  for (const hooks of context.hooks) try {
@@ -395,10 +758,6 @@ function notifyComponentMounted(context, instance) {
395
758
  handleHookError(context, err, instance, "onComponentMounted");
396
759
  }
397
760
  }
398
- /**
399
- * Notify all app hooks that a component was unmounted.
400
- * Called by the renderer before cleanup.
401
- */
402
761
  function notifyComponentUnmounted(context, instance) {
403
762
  if (!context) return;
404
763
  for (const hooks of context.hooks) try {
@@ -407,10 +766,6 @@ function notifyComponentUnmounted(context, instance) {
407
766
  handleHookError(context, err, instance, "onComponentUnmounted");
408
767
  }
409
768
  }
410
- /**
411
- * Notify all app hooks that a component updated.
412
- * Called by the renderer after re-render.
413
- */
414
769
  function notifyComponentUpdated(context, instance) {
415
770
  if (!context) return;
416
771
  for (const hooks of context.hooks) try {
@@ -419,10 +774,6 @@ function notifyComponentUpdated(context, instance) {
419
774
  handleHookError(context, err, instance, "onComponentUpdated");
420
775
  }
421
776
  }
422
- /**
423
- * Handle an error in a component. Returns true if the error was handled.
424
- * Called by the renderer when an error occurs in setup or render.
425
- */
426
777
  function handleComponentError(context, err, instance, info) {
427
778
  if (!context) return false;
428
779
  for (const hooks of context.hooks) try {
@@ -437,105 +788,54 @@ function handleComponentError(context, err, instance, info) {
437
788
  }
438
789
  return false;
439
790
  }
440
- /**
441
- * Handle errors that occur in hooks themselves
442
- */
443
791
  function handleHookError(context, err, instance, hookName) {
444
792
  console.error(`Error in ${hookName} hook:`, err);
445
793
  if (context.config.errorHandler) try {
446
794
  context.config.errorHandler(err, instance, `plugin hook: ${hookName}`);
447
795
  } catch {}
448
796
  }
449
-
450
- //#endregion
451
- //#region ../runtime-core/src/component.ts
452
- let currentComponentContext = null;
453
- function getCurrentInstance() {
454
- return currentComponentContext;
455
- }
456
- function setCurrentInstance(ctx) {
457
- const prev = currentComponentContext;
458
- currentComponentContext = ctx;
459
- return prev;
797
+ function compound(main, sub) {
798
+ return Object.assign(main, sub);
460
799
  }
461
- function onMount(fn) {
462
- if (currentComponentContext) currentComponentContext.onMount(fn);
463
- else console.warn("onMount called outside of component setup");
800
+ var MODEL_SYMBOL = Symbol.for("sigx.model");
801
+ function createModel(tuple, updateHandler) {
802
+ const [obj, key] = tuple;
803
+ return {
804
+ get value() {
805
+ return obj[key];
806
+ },
807
+ set value(v) {
808
+ updateHandler(v);
809
+ },
810
+ get binding() {
811
+ return [
812
+ obj,
813
+ key,
814
+ updateHandler
815
+ ];
816
+ },
817
+ [MODEL_SYMBOL]: true
818
+ };
464
819
  }
465
- function onCleanup(fn) {
466
- if (currentComponentContext) currentComponentContext.onCleanup(fn);
467
- else console.warn("onCleanup called outside of component setup");
820
+ function createModelFromBinding(binding) {
821
+ const [obj, key, handler] = binding;
822
+ return createModel([obj, key], handler);
468
823
  }
469
- const componentRegistry$1 = /* @__PURE__ */ new Map();
470
- /**
471
- * Get component metadata (for DevTools)
472
- */
473
- function getComponentMeta(factory) {
474
- return componentRegistry$1.get(factory);
824
+ function isModel(value) {
825
+ return value !== null && typeof value === "object" && MODEL_SYMBOL in value && value[MODEL_SYMBOL] === true;
475
826
  }
476
- /**
477
- * Helper to create a proxy that tracks property access
478
- */
479
- function createPropsProxy(target, onAccess) {
480
- return new Proxy(target, { get(obj, prop) {
481
- if (typeof prop === "string" && onAccess) onAccess(prop);
482
- return obj[prop];
483
- } });
827
+ function getModelSymbol() {
828
+ return MODEL_SYMBOL;
484
829
  }
485
- /**
486
- * Define a component. Returns a JSX factory function.
487
- *
488
- * @param setup - Setup function that receives context and returns a render function
489
- * @param options - Optional configuration (e.g., name for DevTools)
490
- *
491
- * @example
492
- * ```tsx
493
- * type CardProps = DefineProp<"title", string> & DefineSlot<"header">;
494
- *
495
- * export const Card = defineComponent<CardProps>((ctx) => {
496
- * const { title } = ctx.props;
497
- * const { slots } = ctx;
498
- *
499
- * return () => (
500
- * <div class="card">
501
- * {slots.header?.() ?? <h2>{title}</h2>}
502
- * {slots.default()}
503
- * </div>
504
- * );
505
- * });
506
- * ```
507
- */
508
- function defineComponent(setup, options) {
509
- const factory = function(props) {
510
- return {
511
- type: factory,
512
- props: props || {},
513
- key: props?.key || null,
514
- children: [],
515
- dom: null
516
- };
517
- };
518
- factory.__setup = setup;
519
- factory.__name = options?.name;
520
- factory.__props = null;
521
- factory.__events = null;
522
- factory.__ref = null;
523
- factory.__slots = null;
524
- componentRegistry$1.set(factory, {
525
- name: options?.name,
526
- setup
527
- });
528
- getComponentPlugins().forEach((p) => p.onDefine?.(options?.name, factory, setup));
529
- return factory;
830
+ function isComponent(type) {
831
+ return typeof type === "function" && "__setup" in type;
530
832
  }
531
-
532
- //#endregion
533
- //#region ../runtime-core/src/jsx-runtime.ts
534
833
  const Fragment = Symbol.for("sigx.Fragment");
535
834
  const Text = Symbol.for("sigx.Text");
536
- function normalizeChildren$1(children) {
835
+ function normalizeChildren(children) {
537
836
  if (children == null || children === false || children === true) return [];
538
- if (Array.isArray(children)) return children.flatMap((c) => normalizeChildren$1(c));
837
+ if (isComputed(children)) return normalizeChildren(children.value);
838
+ if (Array.isArray(children)) return children.flatMap((c) => normalizeChildren(c));
539
839
  if (typeof children === "string" || typeof children === "number") return [{
540
840
  type: Text,
541
841
  props: {},
@@ -547,64 +847,92 @@ function normalizeChildren$1(children) {
547
847
  if (children.type) return [children];
548
848
  return [];
549
849
  }
550
- /**
551
- * Check if a type is a sigx component (has __setup)
552
- */
553
- function isComponent$2(type) {
554
- return typeof type === "function" && "__setup" in type;
555
- }
556
- /**
557
- * Create a JSX element - this is the core function called by TSX transpilation
558
- */
559
850
  function jsx(type, props, key) {
560
851
  const processedProps = { ...props || {} };
852
+ const models = {};
853
+ const isComponentType = isComponent(type);
561
854
  if (props) {
562
- for (const propKey in props) if (propKey === "sync") {
563
- let syncBinding = props[propKey];
564
- if (typeof syncBinding === "function") {
565
- const detected = detectAccess(syncBinding);
566
- if (detected) syncBinding = detected;
567
- }
568
- if (Array.isArray(syncBinding) && syncBinding.length === 2) {
569
- const [stateObj, key$1] = syncBinding;
855
+ for (const propKey in props) if (propKey === "model") {
856
+ let modelBinding = props[propKey];
857
+ let tuple = null;
858
+ let updateHandler = null;
859
+ if (isModel(modelBinding)) {
860
+ const [obj, key, handler] = modelBinding.binding;
861
+ tuple = [obj, key];
862
+ updateHandler = handler;
863
+ } else if (typeof modelBinding === "function") {
864
+ const detected = detectAccess(modelBinding);
865
+ if (detected && typeof detected[1] === "string") tuple = detected;
866
+ } else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === "string") tuple = modelBinding;
867
+ if (tuple) {
868
+ const [stateObj, stateKey] = tuple;
570
869
  let handled = false;
571
- const platformProcessor = getPlatformSyncProcessor();
572
- if (typeof type === "string" && platformProcessor) handled = platformProcessor(type, processedProps, [stateObj, key$1], props);
573
- if (!handled) {
574
- processedProps.value = stateObj[key$1];
575
- const existingHandler = processedProps["onUpdate:value"];
576
- processedProps["onUpdate:value"] = (v) => {
577
- stateObj[key$1] = v;
870
+ if (!updateHandler) {
871
+ const existingHandler = processedProps["onUpdate:modelValue"];
872
+ updateHandler = (v) => {
873
+ const customHandler = stateObj[`onUpdate:${stateKey}`];
874
+ if (typeof customHandler === "function") customHandler(v);
875
+ else stateObj[stateKey] = v;
578
876
  if (existingHandler) existingHandler(v);
579
877
  };
580
878
  }
581
- delete processedProps.sync;
879
+ const platformProcessor = getPlatformModelProcessor();
880
+ if (typeof type === "string" && platformProcessor) handled = platformProcessor(type, processedProps, tuple, props);
881
+ if (isComponentType) {
882
+ models.model = createModel(tuple, updateHandler);
883
+ processedProps["onUpdate:modelValue"] = updateHandler;
884
+ } else if (!handled) {
885
+ processedProps.modelValue = stateObj[stateKey];
886
+ processedProps["onUpdate:modelValue"] = updateHandler;
887
+ }
888
+ delete processedProps.model;
582
889
  }
583
- } else if (propKey.startsWith("sync:")) {
584
- const syncBinding = props[propKey];
585
- if (Array.isArray(syncBinding) && syncBinding.length === 2) {
586
- const [stateObj, key$1] = syncBinding;
587
- const name = propKey.slice(5);
588
- processedProps[name] = stateObj[key$1];
890
+ } else if (propKey.startsWith("model:")) {
891
+ let modelBinding = props[propKey];
892
+ const name = propKey.slice(6);
893
+ let tuple = null;
894
+ let updateHandler = null;
895
+ if (isModel(modelBinding)) {
896
+ const [obj, key, handler] = modelBinding.binding;
897
+ tuple = [obj, key];
898
+ updateHandler = handler;
899
+ } else if (typeof modelBinding === "function") {
900
+ const detected = detectAccess(modelBinding);
901
+ if (detected && typeof detected[1] === "string") tuple = detected;
902
+ } else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === "string") tuple = modelBinding;
903
+ if (tuple) {
904
+ const [stateObj, stateKey] = tuple;
589
905
  const eventName = `onUpdate:${name}`;
590
- const existingHandler = processedProps[eventName];
591
- processedProps[eventName] = (v) => {
592
- stateObj[key$1] = v;
593
- if (existingHandler) existingHandler(v);
594
- };
906
+ if (!updateHandler) {
907
+ const existingHandler = processedProps[eventName];
908
+ updateHandler = (v) => {
909
+ const customHandler = stateObj[`onUpdate:${stateKey}`];
910
+ if (typeof customHandler === "function") customHandler(v);
911
+ else stateObj[stateKey] = v;
912
+ if (existingHandler) existingHandler(v);
913
+ };
914
+ }
915
+ if (isComponentType) {
916
+ models[name] = createModel(tuple, updateHandler);
917
+ processedProps[eventName] = updateHandler;
918
+ } else {
919
+ processedProps[name] = stateObj[stateKey];
920
+ processedProps[eventName] = updateHandler;
921
+ }
595
922
  delete processedProps[propKey];
596
923
  }
597
924
  }
598
925
  }
599
- if (isComponent$2(type)) {
600
- const { children: children$1, ...rest$1 } = processedProps;
926
+ if (Object.keys(models).length > 0) processedProps.$models = models;
927
+ if (isComponent(type)) {
928
+ const { children, ...rest } = processedProps;
601
929
  return {
602
930
  type,
603
931
  props: {
604
- ...rest$1,
605
- children: children$1
932
+ ...rest,
933
+ children
606
934
  },
607
- key: key || rest$1.key || null,
935
+ key: key || rest.key || null,
608
936
  children: [],
609
937
  dom: null
610
938
  };
@@ -615,33 +943,17 @@ function jsx(type, props, key) {
615
943
  type,
616
944
  props: rest,
617
945
  key: key || rest.key || null,
618
- children: normalizeChildren$1(children),
946
+ children: normalizeChildren(children),
619
947
  dom: null
620
948
  };
621
949
  }
622
- /**
623
- * JSX Factory for fragments
624
- */
625
950
  function jsxs(type, props, key) {
626
951
  return jsx(type, props, key);
627
952
  }
628
953
  const jsxDEV = jsx;
629
-
630
- //#endregion
631
- //#region ../runtime-core/src/lazy.tsx
632
- /**
633
- * Lazy loading utilities for sigx components.
634
- *
635
- * Provides runtime-only lazy loading with no build dependencies.
636
- * Works with any bundler that supports dynamic import().
637
- */
638
- let currentSuspenseBoundary$1 = null;
639
- /**
640
- * Register a promise with the current Suspense boundary
641
- * @internal
642
- */
954
+ var currentSuspenseBoundary = null;
643
955
  function registerPendingPromise(promise) {
644
- const boundary = currentSuspenseBoundary$1;
956
+ const boundary = currentSuspenseBoundary;
645
957
  if (boundary) {
646
958
  boundary.pending.add(promise);
647
959
  promise.finally(() => {
@@ -652,39 +964,12 @@ function registerPendingPromise(promise) {
652
964
  }
653
965
  return false;
654
966
  }
655
- /**
656
- * Create a lazy-loaded component wrapper.
657
- *
658
- * The component will be loaded on first render. Use with `<Suspense>` to show
659
- * a fallback while loading.
660
- *
661
- * @param loader - Function that returns a Promise resolving to the component
662
- * @returns A component factory that loads the real component on demand
663
- *
664
- * @example
665
- * ```tsx
666
- * import { lazy, Suspense } from 'sigx';
667
- *
668
- * // Component will be in a separate chunk
669
- * const HeavyChart = lazy(() => import('./components/HeavyChart'));
670
- *
671
- * // Usage
672
- * <Suspense fallback={<Spinner />}>
673
- * <HeavyChart data={chartData} />
674
- * </Suspense>
675
- *
676
- * // Preload on hover
677
- * <button onMouseEnter={() => HeavyChart.preload()}>
678
- * Show Chart
679
- * </button>
680
- * ```
681
- */
682
967
  function lazy(loader) {
683
968
  let Component = null;
684
969
  let promise = null;
685
970
  let error = null;
686
971
  let state = "pending";
687
- const LazyWrapper = defineComponent((ctx) => {
972
+ const LazyWrapper = component((ctx) => {
688
973
  const loadState = ctx.signal({
689
974
  state,
690
975
  tick: 0
@@ -733,30 +1018,7 @@ function lazy(loader) {
733
1018
  };
734
1019
  return LazyWrapper;
735
1020
  }
736
- /**
737
- * Suspense boundary component for handling async loading states.
738
- *
739
- * Wraps lazy-loaded components and shows a fallback while they load.
740
- *
741
- * @example
742
- * ```tsx
743
- * import { lazy, Suspense } from 'sigx';
744
- *
745
- * const LazyDashboard = lazy(() => import('./Dashboard'));
746
- *
747
- * // Basic usage
748
- * <Suspense fallback={<div>Loading...</div>}>
749
- * <LazyDashboard />
750
- * </Suspense>
751
- *
752
- * // With spinner component
753
- * <Suspense fallback={<Spinner size="large" />}>
754
- * <LazyDashboard />
755
- * <LazyCharts />
756
- * </Suspense>
757
- * ```
758
- */
759
- const Suspense = defineComponent((ctx) => {
1021
+ const Suspense = component((ctx) => {
760
1022
  const { props, slots } = ctx;
761
1023
  const state = ctx.signal({
762
1024
  isReady: false,
@@ -769,14 +1031,14 @@ const Suspense = defineComponent((ctx) => {
769
1031
  if (boundary.pending.size === 0) state.isReady = true;
770
1032
  }
771
1033
  };
772
- ctx.onMount(() => {
1034
+ ctx.onMounted(() => {
773
1035
  if (boundary.pending.size === 0) state.isReady = true;
774
1036
  });
775
1037
  return () => {
776
1038
  state.isReady;
777
1039
  state.pendingCount;
778
- const prevBoundary = currentSuspenseBoundary$1;
779
- currentSuspenseBoundary$1 = boundary;
1040
+ const prevBoundary = currentSuspenseBoundary;
1041
+ currentSuspenseBoundary = boundary;
780
1042
  try {
781
1043
  const children = slots.default();
782
1044
  if (boundary.pending.size > 0) {
@@ -800,19 +1062,13 @@ const Suspense = defineComponent((ctx) => {
800
1062
  }
801
1063
  throw err;
802
1064
  } finally {
803
- currentSuspenseBoundary$1 = prevBoundary;
1065
+ currentSuspenseBoundary = prevBoundary;
804
1066
  }
805
1067
  };
806
1068
  }, { name: "Suspense" });
807
- /**
808
- * Check if a component is a lazy-loaded component
809
- */
810
1069
  function isLazyComponent(component) {
811
1070
  return component && component.__lazy === true;
812
1071
  }
813
-
814
- //#endregion
815
- //#region ../runtime-core/src/utils/index.ts
816
1072
  var Utils = class {
817
1073
  static isPromise(value) {
818
1074
  return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
@@ -824,116 +1080,144 @@ function guid$1() {
824
1080
  return (c == "x" ? r : r & 3 | 8).toString(16);
825
1081
  });
826
1082
  }
827
-
828
- //#endregion
829
- //#region ../runtime-core/src/models/index.ts
830
- const guid = guid$1;
831
- let InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes$1) {
832
- InstanceLifetimes$1[InstanceLifetimes$1["Transient"] = 0] = "Transient";
833
- InstanceLifetimes$1[InstanceLifetimes$1["Scoped"] = 1] = "Scoped";
834
- InstanceLifetimes$1[InstanceLifetimes$1["Singleton"] = 2] = "Singleton";
835
- return InstanceLifetimes$1;
836
- }({});
837
- function valueOf(obj) {
838
- return obj;
1083
+ function createPropsAccessor(reactiveProps) {
1084
+ return new Proxy(reactiveProps, {
1085
+ get(target, key) {
1086
+ if (typeof key === "symbol") return void 0;
1087
+ return target[key];
1088
+ },
1089
+ has(target, key) {
1090
+ if (typeof key === "symbol") return false;
1091
+ return key in target;
1092
+ },
1093
+ ownKeys(target) {
1094
+ return Object.keys(target);
1095
+ },
1096
+ getOwnPropertyDescriptor(target, key) {
1097
+ if (typeof key === "symbol") return void 0;
1098
+ if (key in target) return {
1099
+ enumerable: true,
1100
+ configurable: true,
1101
+ writable: false
1102
+ };
1103
+ }
1104
+ });
839
1105
  }
840
-
841
- //#endregion
842
- //#region ../runtime-core/src/messaging/index.ts
843
- function createTopic(options) {
844
- let subscribers = [];
845
- const publish = (data) => {
846
- subscribers.forEach((s) => s(data));
1106
+ function createSlots(children, slotsFromProps) {
1107
+ const versionSignal = signal({ v: 0 });
1108
+ function extractNamedSlotsFromChildren(c) {
1109
+ const defaultChildren = [];
1110
+ const namedSlots = {};
1111
+ if (c == null) return {
1112
+ defaultChildren,
1113
+ namedSlots
1114
+ };
1115
+ const items = Array.isArray(c) ? c : [c];
1116
+ for (const child of items) if (child && typeof child === "object" && child.props && child.props.slot) {
1117
+ const slotName = child.props.slot;
1118
+ if (!namedSlots[slotName]) namedSlots[slotName] = [];
1119
+ namedSlots[slotName].push(child);
1120
+ } else defaultChildren.push(child);
1121
+ return {
1122
+ defaultChildren,
1123
+ namedSlots
1124
+ };
1125
+ }
1126
+ const slotsObj = {
1127
+ _children: children,
1128
+ _slotsFromProps: slotsFromProps || {},
1129
+ _version: versionSignal,
1130
+ _isPatching: false,
1131
+ default: function() {
1132
+ this._version.v;
1133
+ const c = this._children;
1134
+ const { defaultChildren } = extractNamedSlotsFromChildren(c);
1135
+ return defaultChildren.filter((child) => child != null && child !== false && child !== true);
1136
+ }
847
1137
  };
848
- const subscribe = (handler) => {
849
- subscribers.push(handler);
850
- const unsubscribe = () => {
851
- const idx = subscribers.indexOf(handler);
852
- if (idx > -1) subscribers.splice(idx, 1);
1138
+ return new Proxy(slotsObj, { get(target, prop) {
1139
+ if (prop in target) return target[prop];
1140
+ if (typeof prop === "string") return function(scopedProps) {
1141
+ target._version.v;
1142
+ if (target._slotsFromProps && typeof target._slotsFromProps[prop] === "function") {
1143
+ const result = target._slotsFromProps[prop](scopedProps);
1144
+ if (result == null) return [];
1145
+ return Array.isArray(result) ? result : [result];
1146
+ }
1147
+ const { namedSlots } = extractNamedSlotsFromChildren(target._children);
1148
+ return namedSlots[prop] || [];
853
1149
  };
854
- try {
855
- onCleanup(unsubscribe);
856
- } catch (e) {}
857
- return { unsubscribe };
1150
+ } });
1151
+ }
1152
+ function normalizeSubTree(result) {
1153
+ if (result == null || result === false || result === true) return {
1154
+ type: Text,
1155
+ props: {},
1156
+ key: null,
1157
+ children: [],
1158
+ dom: null,
1159
+ text: ""
858
1160
  };
859
- const destroy = () => {
860
- subscribers = [];
1161
+ if (isComputed(result)) return normalizeSubTree(result.value);
1162
+ if (Array.isArray(result)) return {
1163
+ type: Fragment,
1164
+ props: {},
1165
+ key: null,
1166
+ children: result,
1167
+ dom: null
861
1168
  };
862
- return {
863
- publish,
864
- subscribe,
865
- destroy
1169
+ if (typeof result === "string" || typeof result === "number") return {
1170
+ type: Text,
1171
+ props: {},
1172
+ key: null,
1173
+ children: [],
1174
+ dom: null,
1175
+ text: result
866
1176
  };
1177
+ return result;
867
1178
  }
868
- function toSubscriber(topic) {
869
- return { subscribe: (handler) => topic.subscribe(handler) };
870
- }
871
-
872
- //#endregion
873
- //#region ../runtime-core/src/di/injectable.ts
874
- function inject(token) {
875
- const ctx = getCurrentInstance();
876
- if (!ctx) return void 0;
877
- let current = ctx;
878
- while (current) {
879
- if (current.provides && current.provides.has(token)) return current.provides.get(token);
880
- current = current.parent;
881
- }
882
- const appContext = getAppContext(ctx);
883
- if (appContext && appContext.provides.has(token)) return appContext.provides.get(token);
884
- }
885
- /**
886
- * Get the app context from the current component context
887
- */
888
- function getAppContext(ctx) {
889
- let current = ctx;
890
- while (current) {
891
- if (current._appContext) return current._appContext;
892
- current = current.parent;
893
- }
894
- return null;
895
- }
896
- /**
897
- * Inject the App instance (useful for plugins)
898
- */
899
- function injectApp() {
900
- return inject(AppContextKey);
901
- }
902
- function provide(token, value) {
903
- const ctx = getCurrentInstance();
904
- if (!ctx) {
905
- console.warn("provide called outside of component setup");
906
- return;
907
- }
908
- if (!ctx.provides) ctx.provides = /* @__PURE__ */ new Map();
909
- ctx.provides.set(token, value);
1179
+ const guid = guid$1;
1180
+ let InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes) {
1181
+ InstanceLifetimes[InstanceLifetimes["Transient"] = 0] = "Transient";
1182
+ InstanceLifetimes[InstanceLifetimes["Scoped"] = 1] = "Scoped";
1183
+ InstanceLifetimes[InstanceLifetimes["Singleton"] = 2] = "Singleton";
1184
+ return InstanceLifetimes;
1185
+ }({});
1186
+ function valueOf(obj) {
1187
+ return obj;
910
1188
  }
911
- const globalInstances = /* @__PURE__ */ new Map();
912
- function defineInjectable(factory) {
913
- const token = factory;
914
- const useFn = () => {
915
- const injected = inject(token);
916
- if (injected) return injected;
917
- if (!globalInstances.has(token)) globalInstances.set(token, factory());
918
- return globalInstances.get(token);
1189
+ function createTopic(options) {
1190
+ let subscribers = [];
1191
+ const publish = (data) => {
1192
+ subscribers.forEach((s) => s(data));
1193
+ };
1194
+ const subscribe = (handler) => {
1195
+ subscribers.push(handler);
1196
+ const unsubscribe = () => {
1197
+ const idx = subscribers.indexOf(handler);
1198
+ if (idx > -1) subscribers.splice(idx, 1);
1199
+ };
1200
+ try {
1201
+ onUnmounted(unsubscribe);
1202
+ } catch (e) {}
1203
+ return { unsubscribe };
1204
+ };
1205
+ const destroy = () => {
1206
+ subscribers = [];
1207
+ };
1208
+ return {
1209
+ publish,
1210
+ subscribe,
1211
+ destroy
919
1212
  };
920
- useFn._factory = factory;
921
- useFn._token = token;
922
- return useFn;
923
1213
  }
924
- function defineProvide(useFn) {
925
- const factory = useFn._factory;
926
- const token = useFn._token;
927
- if (!factory || !token) throw new Error("defineProvide must be called with a function created by defineInjectable");
928
- const instance = factory();
929
- provide(token, instance);
930
- return instance;
1214
+ function toSubscriber(topic) {
1215
+ return { subscribe: (handler) => topic.subscribe(handler) };
931
1216
  }
932
-
933
- //#endregion
934
- //#region ../runtime-core/src/di/factory.ts
935
1217
  var SubscriptionHandler = class {
936
- unsubs = [];
1218
+ constructor() {
1219
+ this.unsubs = [];
1220
+ }
937
1221
  add(unsub) {
938
1222
  this.unsubs.push(unsub);
939
1223
  }
@@ -959,7 +1243,7 @@ function defineFactory(setup, lifetime, typeIdentifier) {
959
1243
  };
960
1244
  if (customDispose) customDispose(dispose);
961
1245
  else try {
962
- onCleanup(() => dispose());
1246
+ onUnmounted(() => dispose());
963
1247
  } catch (e) {}
964
1248
  return {
965
1249
  ...result,
@@ -969,160 +1253,64 @@ function defineFactory(setup, lifetime, typeIdentifier) {
969
1253
  if (setup.length <= 1) return defineInjectable(() => factoryCreator());
970
1254
  return factoryCreator;
971
1255
  }
972
-
973
- //#endregion
974
- //#region ../runtime-core/src/stores/store.ts
975
- function defineStore(name, setup, lifetime = InstanceLifetimes.Scoped) {
976
- return defineFactory((ctxFactory, ...args) => {
977
- const scope = effectScope(true);
978
- let messages = [];
979
- const id = `${name}_${guid()}`;
980
- const result = setup({
981
- ...ctxFactory,
982
- defineState: (state) => {
983
- return defineState(state, id, scope, messages);
984
- },
985
- defineActions: (actions) => {
986
- return defineActions(actions, id, messages);
987
- }
988
- }, ...args);
989
- ctxFactory.onDeactivated(() => {
990
- scope.stop();
991
- messages?.forEach((m) => m.destroy());
992
- messages = null;
993
- });
994
- if (!result.name) result.name = id;
995
- return result;
996
- }, lifetime);
997
- }
998
- function defineActions(actions, storeInstanceName, messages) {
999
- const events = {};
1000
- const namespace = `${storeInstanceName}.actions.${guid()}`;
1001
- const onDispatching = {};
1002
- const onDispatched = {};
1003
- const onFailure = {};
1004
- const result = {
1005
- onDispatching,
1006
- onDispatched,
1007
- onFailure
1256
+ const CLIENT_DIRECTIVE_PREFIX = "client:";
1257
+ const CLIENT_DIRECTIVES = [
1258
+ "client:load",
1259
+ "client:idle",
1260
+ "client:visible",
1261
+ "client:media",
1262
+ "client:only"
1263
+ ];
1264
+ function filterClientDirectives(props) {
1265
+ const filtered = {};
1266
+ for (const key in props) if (!key.startsWith("client:")) filtered[key] = props[key];
1267
+ return filtered;
1268
+ }
1269
+ function getHydrationDirective(props) {
1270
+ if (props["client:load"] !== void 0) return { strategy: "load" };
1271
+ if (props["client:idle"] !== void 0) return { strategy: "idle" };
1272
+ if (props["client:visible"] !== void 0) return { strategy: "visible" };
1273
+ if (props["client:only"] !== void 0) return { strategy: "only" };
1274
+ if (props["client:media"] !== void 0) return {
1275
+ strategy: "media",
1276
+ media: props["client:media"]
1008
1277
  };
1009
- function getEvent(actionName, type) {
1010
- const name = `${actionName}.${type}`;
1011
- if (!events[name]) {
1012
- events[name] = createTopic({
1013
- namespace,
1014
- name
1015
- });
1016
- messages.push(events[name]);
1017
- }
1018
- return events[name];
1019
- }
1020
- Object.keys(actions).forEach((actionName) => {
1021
- onDispatching[actionName] = { subscribe: (fn) => {
1022
- return getEvent(actionName, "onDispatching").subscribe(function() {
1023
- fn.apply(this, arguments[0]);
1024
- });
1025
- } };
1026
- onDispatched[actionName] = { subscribe: (fn) => {
1027
- return getEvent(actionName, "onDispatched").subscribe(function() {
1028
- const msg = arguments[0];
1029
- const allArguments = [msg.result].concat(Array.from(msg.args));
1030
- fn.apply(this, allArguments);
1031
- });
1032
- } };
1033
- onFailure[actionName] = { subscribe: (fn) => {
1034
- return getEvent(actionName, "onFailure").subscribe(function() {
1035
- const msg = arguments[0];
1036
- const allArguments = [msg.reason].concat(Array.from(msg.args));
1037
- fn.apply(this, allArguments);
1038
- });
1039
- } };
1040
- result[actionName] = function() {
1041
- try {
1042
- const currentArguments = arguments;
1043
- getEvent(actionName, "onDispatching").publish(currentArguments);
1044
- const returnedResult = actions[actionName].apply(this, currentArguments);
1045
- if (Utils.isPromise(returnedResult)) returnedResult.then((result$1) => {
1046
- getEvent(actionName, "onDispatched").publish({
1047
- result: returnedResult,
1048
- args: currentArguments
1049
- });
1050
- });
1051
- else getEvent(actionName, "onDispatched").publish({
1052
- result: returnedResult,
1053
- args: currentArguments
1054
- });
1055
- return returnedResult;
1056
- } catch (err) {
1057
- console.error(err);
1058
- getEvent(actionName, "onFailure").publish({
1059
- reason: err,
1060
- args: arguments
1061
- });
1062
- }
1063
- };
1064
- });
1065
- return result;
1278
+ return null;
1066
1279
  }
1067
- function defineState(value, storeInstanceName, scope, messages) {
1068
- const state = signal(value);
1069
- const events = {};
1070
- const mutate = {};
1071
- function initProperty(key) {
1072
- scope.run(() => {
1073
- watch(() => state[key], (newValue) => {
1074
- triggerEvent(key, newValue);
1075
- }, {
1076
- deep: true,
1077
- immediate: true
1078
- });
1079
- });
1080
- mutate[key] = (val) => {
1081
- try {
1082
- let newValue;
1083
- if (typeof val === "function") newValue = val(state[key]);
1084
- else newValue = val;
1085
- state[key] = newValue;
1086
- } catch (err) {
1087
- console.error(err);
1088
- }
1089
- };
1090
- const eventKey = `onMutated${key.charAt(0).toUpperCase()}${key.slice(1)}`;
1091
- if (!events[eventKey]) {
1092
- const topic = createTopic({
1093
- namespace: `${storeInstanceName}.events`,
1094
- name: eventKey
1095
- });
1096
- events[eventKey] = topic;
1097
- messages.push(topic);
1098
- }
1099
- }
1100
- function triggerEvent(name, value$1) {
1101
- const keyString = name;
1102
- events[`onMutated${keyString.charAt(0).toUpperCase()}${keyString.slice(1)}`]?.publish(value$1);
1280
+ function hasClientDirective(props) {
1281
+ for (const key in props) if (key.startsWith("client:")) return true;
1282
+ return false;
1283
+ }
1284
+ function serializeProps(props) {
1285
+ const filtered = filterClientDirectives(props);
1286
+ const result = {};
1287
+ let hasProps = false;
1288
+ for (const key in filtered) {
1289
+ const value = filtered[key];
1290
+ if (key === "children" || key === "key" || key === "ref" || key === "slots") continue;
1291
+ if (typeof value === "function") continue;
1292
+ if (typeof value === "symbol") continue;
1293
+ if (value === void 0) continue;
1294
+ if (key.startsWith("on") && key.length > 2 && key[2] === key[2].toUpperCase()) continue;
1295
+ try {
1296
+ JSON.stringify(value);
1297
+ result[key] = value;
1298
+ hasProps = true;
1299
+ } catch {}
1103
1300
  }
1104
- if (value) Object.keys(value).forEach((key) => {
1105
- initProperty(key);
1106
- });
1107
- return {
1108
- state,
1109
- events,
1110
- mutate
1111
- };
1301
+ return hasProps ? result : void 0;
1112
1302
  }
1113
-
1114
- //#endregion
1115
- //#region ../runtime-core/src/renderer.ts
1116
- /**
1117
- * Check if a vnode type is a component (has __setup)
1118
- */
1119
- function isComponent(type) {
1120
- return typeof type === "function" && "__setup" in type;
1303
+ function createEmit(reactiveProps) {
1304
+ return (event, ...args) => {
1305
+ const eventName = `on${event[0].toUpperCase() + event.slice(1)}`;
1306
+ const handler = ("value" in reactiveProps ? reactiveProps.value : reactiveProps)?.[eventName];
1307
+ if (handler && typeof handler === "function") handler(...args);
1308
+ };
1121
1309
  }
1122
1310
  function createRenderer(options) {
1123
1311
  const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
1124
1312
  let currentAppContext = null;
1125
- function render$1(element, container, appContext) {
1313
+ function render(element, container, appContext) {
1126
1314
  if (appContext) currentAppContext = appContext;
1127
1315
  const oldVNode = container._vnode;
1128
1316
  let vnode = null;
@@ -1151,7 +1339,72 @@ function createRenderer(options) {
1151
1339
  container._vnode = null;
1152
1340
  }
1153
1341
  }
1154
- function mount(vnode, container, before = null) {
1342
+ const svgTags = new Set([
1343
+ "svg",
1344
+ "animate",
1345
+ "animateMotion",
1346
+ "animateTransform",
1347
+ "circle",
1348
+ "clipPath",
1349
+ "defs",
1350
+ "desc",
1351
+ "ellipse",
1352
+ "feBlend",
1353
+ "feColorMatrix",
1354
+ "feComponentTransfer",
1355
+ "feComposite",
1356
+ "feConvolveMatrix",
1357
+ "feDiffuseLighting",
1358
+ "feDisplacementMap",
1359
+ "feDistantLight",
1360
+ "feDropShadow",
1361
+ "feFlood",
1362
+ "feFuncA",
1363
+ "feFuncB",
1364
+ "feFuncG",
1365
+ "feFuncR",
1366
+ "feGaussianBlur",
1367
+ "feImage",
1368
+ "feMerge",
1369
+ "feMergeNode",
1370
+ "feMorphology",
1371
+ "feOffset",
1372
+ "fePointLight",
1373
+ "feSpecularLighting",
1374
+ "feSpotLight",
1375
+ "feTile",
1376
+ "feTurbulence",
1377
+ "filter",
1378
+ "foreignObject",
1379
+ "g",
1380
+ "image",
1381
+ "line",
1382
+ "linearGradient",
1383
+ "marker",
1384
+ "mask",
1385
+ "metadata",
1386
+ "mpath",
1387
+ "path",
1388
+ "pattern",
1389
+ "polygon",
1390
+ "polyline",
1391
+ "radialGradient",
1392
+ "rect",
1393
+ "set",
1394
+ "stop",
1395
+ "switch",
1396
+ "symbol",
1397
+ "text",
1398
+ "textPath",
1399
+ "title",
1400
+ "tspan",
1401
+ "use",
1402
+ "view"
1403
+ ]);
1404
+ function isSvgTag(tag) {
1405
+ return svgTags.has(tag);
1406
+ }
1407
+ function mount(vnode, container, before = null, parentIsSVG = false) {
1155
1408
  if (vnode == null || vnode === false || vnode === true) return;
1156
1409
  if (vnode.type === Text) {
1157
1410
  const node = hostCreateText(String(vnode.text));
@@ -1164,26 +1417,29 @@ function createRenderer(options) {
1164
1417
  const anchor = hostCreateComment("");
1165
1418
  vnode.dom = anchor;
1166
1419
  hostInsert(anchor, container, before);
1167
- if (vnode.children) vnode.children.forEach((child) => mount(child, container, anchor));
1420
+ if (vnode.children) vnode.children.forEach((child) => mount(child, container, anchor, parentIsSVG));
1168
1421
  return;
1169
1422
  }
1170
1423
  if (isComponent(vnode.type)) {
1171
1424
  mountComponent(vnode, container, before, vnode.type.__setup);
1172
1425
  return;
1173
1426
  }
1174
- const element = hostCreateElement(vnode.type);
1427
+ const tag = vnode.type;
1428
+ const isSVG = tag === "svg" || parentIsSVG && tag !== "foreignObject";
1429
+ const element = hostCreateElement(tag, isSVG);
1175
1430
  vnode.dom = element;
1176
1431
  element.__vnode = vnode;
1177
1432
  if (vnode.props) {
1178
- for (const key in vnode.props) if (key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, null, vnode.props[key]);
1179
- if (vnode.props.ref) {
1433
+ for (const key in vnode.props) if (key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, null, vnode.props[key], isSVG);
1434
+ if (vnode.props.ref) untrack(() => {
1180
1435
  if (typeof vnode.props.ref === "function") vnode.props.ref(element);
1181
1436
  else if (typeof vnode.props.ref === "object") vnode.props.ref.current = element;
1182
- }
1437
+ });
1183
1438
  }
1439
+ const childIsSVG = isSVG && tag !== "foreignObject";
1184
1440
  if (vnode.children) vnode.children.forEach((child) => {
1185
1441
  child.parent = vnode;
1186
- mount(child, element);
1442
+ mount(child, element, null, childIsSVG);
1187
1443
  });
1188
1444
  hostInsert(element, container, before);
1189
1445
  }
@@ -1195,10 +1451,10 @@ function createRenderer(options) {
1195
1451
  const subTree = internalVNode._subTree;
1196
1452
  if (subTree) unmount(subTree, container);
1197
1453
  if (vnode.dom) hostRemove(vnode.dom);
1198
- if (vnode.props?.ref) {
1454
+ if (vnode.props?.ref) untrack(() => {
1199
1455
  if (typeof vnode.props.ref === "function") vnode.props.ref(null);
1200
1456
  else if (typeof vnode.props.ref === "object") vnode.props.ref.current = null;
1201
- }
1457
+ });
1202
1458
  return;
1203
1459
  }
1204
1460
  if (vnode.type === Fragment) {
@@ -1206,10 +1462,10 @@ function createRenderer(options) {
1206
1462
  if (vnode.dom) hostRemove(vnode.dom);
1207
1463
  return;
1208
1464
  }
1209
- if (vnode.props?.ref) {
1465
+ if (vnode.props?.ref) untrack(() => {
1210
1466
  if (typeof vnode.props.ref === "function") vnode.props.ref(null);
1211
1467
  else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = null;
1212
- }
1468
+ });
1213
1469
  if (vnode.children && vnode.children.length > 0) vnode.children.forEach((child) => unmount(child, vnode.dom));
1214
1470
  if (vnode.dom) hostRemove(vnode.dom);
1215
1471
  }
@@ -1217,7 +1473,7 @@ function createRenderer(options) {
1217
1473
  if (oldVNode === newVNode) return;
1218
1474
  if (!isSameVNode(oldVNode, newVNode)) {
1219
1475
  const parent = hostParentNode(oldVNode.dom) || container;
1220
- const nextSibling = hostNextSibling(oldVNode.dom);
1476
+ const nextSibling = oldVNode.dom ? hostNextSibling(oldVNode.dom) : null;
1221
1477
  unmount(oldVNode, parent);
1222
1478
  mount(newVNode, parent, nextSibling);
1223
1479
  return;
@@ -1232,12 +1488,25 @@ function createRenderer(options) {
1232
1488
  const props = oldInternal._componentProps;
1233
1489
  newInternal._componentProps = props;
1234
1490
  if (props) {
1235
- const newProps$1 = newVNode.props || {};
1491
+ const newProps = newVNode.props || {};
1492
+ const newModels = newVNode.props?.$models || {};
1236
1493
  untrack(() => {
1237
- for (const key in newProps$1) if (key !== "children" && key !== "key" && key !== "ref") {
1238
- if (props[key] !== newProps$1[key]) props[key] = newProps$1[key];
1494
+ for (const key in newProps) if (key !== "children" && key !== "key" && key !== "ref" && key !== "$models") {
1495
+ if (props[key] !== newProps[key]) props[key] = newProps[key];
1496
+ }
1497
+ for (const modelKey in newModels) {
1498
+ const newModel = newModels[modelKey];
1499
+ const oldModel = props[modelKey];
1500
+ if (isModel(newModel)) {
1501
+ if (isModel(oldModel)) {
1502
+ const [newObj, newKey] = newModel.binding;
1503
+ const [oldObj, oldKey] = oldModel.binding;
1504
+ if (newObj === oldObj && newKey === oldKey) continue;
1505
+ }
1506
+ props[modelKey] = newModel;
1507
+ }
1239
1508
  }
1240
- for (const key in props) if (!(key in newProps$1) && key !== "children" && key !== "key" && key !== "ref") delete props[key];
1509
+ for (const key in props) if (!(key in newProps) && !(key in newModels) && key !== "children" && key !== "key" && key !== "ref" && key !== "$models") delete props[key];
1241
1510
  });
1242
1511
  }
1243
1512
  const slotsRef = oldInternal._slots;
@@ -1265,27 +1534,43 @@ function createRenderer(options) {
1265
1534
  return;
1266
1535
  }
1267
1536
  if (newVNode.type === Fragment) {
1268
- patchChildren(oldVNode, newVNode, container);
1537
+ patchChildren(oldVNode, newVNode, container, false);
1269
1538
  return;
1270
1539
  }
1271
1540
  const element = newVNode.dom = oldVNode.dom;
1541
+ if (!element) {
1542
+ mount(newVNode, container);
1543
+ return;
1544
+ }
1545
+ const tag = newVNode.type;
1546
+ const isSVG = tag === "svg" || isSvgTag(tag);
1272
1547
  const oldProps = oldVNode.props || {};
1273
1548
  const newProps = newVNode.props || {};
1274
- for (const key in oldProps) if (!(key in newProps) && key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, oldProps[key], null);
1549
+ for (const key in oldProps) if (!(key in newProps) && key !== "children" && key !== "key" && key !== "ref") hostPatchProp(element, key, oldProps[key], null, isSVG);
1275
1550
  for (const key in newProps) {
1276
1551
  const oldValue = oldProps[key];
1277
1552
  const newValue = newProps[key];
1278
- if (key !== "children" && key !== "key" && key !== "ref" && oldValue !== newValue) hostPatchProp(element, key, oldValue, newValue);
1553
+ if (key !== "children" && key !== "key" && key !== "ref" && oldValue !== newValue) hostPatchProp(element, key, oldValue, newValue, isSVG);
1279
1554
  }
1280
- patchChildren(oldVNode, newVNode, element);
1555
+ patchChildren(oldVNode, newVNode, element, isSVG && tag !== "foreignObject");
1281
1556
  }
1282
- function patchChildren(oldVNode, newVNode, container) {
1557
+ function patchChildren(oldVNode, newVNode, container, parentIsSVG = false) {
1283
1558
  const oldChildren = oldVNode.children;
1284
1559
  const newChildren = newVNode.children;
1285
1560
  newChildren.forEach((c) => c.parent = newVNode);
1286
- reconcileChildrenArray(container, oldChildren, newChildren);
1561
+ reconcileChildrenArray(container, oldChildren, newChildren, parentIsSVG);
1287
1562
  }
1288
- function reconcileChildrenArray(parent, oldChildren, newChildren) {
1563
+ function checkDuplicateKeys(children) {
1564
+ if (process.env.NODE_ENV === "production") return;
1565
+ const seenKeys = /* @__PURE__ */ new Set();
1566
+ for (const child of children) if (child?.key != null) {
1567
+ const keyStr = String(child.key);
1568
+ if (seenKeys.has(keyStr)) console.warn(`[SignalX] Duplicate key "${child.key}" detected in list. Keys should be unique among siblings to ensure correct reconciliation. This may cause unexpected behavior when items are reordered, added, or removed.`);
1569
+ seenKeys.add(keyStr);
1570
+ }
1571
+ }
1572
+ function reconcileChildrenArray(parent, oldChildren, newChildren, parentIsSVG = false) {
1573
+ if (process.env.NODE_ENV !== "production") checkDuplicateKeys(newChildren);
1289
1574
  let oldStartIdx = 0;
1290
1575
  let oldEndIdx = oldChildren.length - 1;
1291
1576
  let oldStartVNode = oldChildren[0];
@@ -1327,13 +1612,13 @@ function createRenderer(options) {
1327
1612
  patch(vnodeToMove, newStartVNode, parent);
1328
1613
  oldChildren[idxInOld] = void 0;
1329
1614
  if (vnodeToMove.dom && oldStartVNode.dom) hostInsert(vnodeToMove.dom, parent, oldStartVNode.dom);
1330
- } else mount(newStartVNode, parent, oldStartVNode.dom);
1615
+ } else mount(newStartVNode, parent, oldStartVNode.dom, parentIsSVG);
1331
1616
  newStartVNode = newChildren[++newStartIdx];
1332
1617
  }
1333
1618
  if (oldStartIdx > oldEndIdx) {
1334
1619
  if (newStartIdx <= newEndIdx) {
1335
1620
  const anchor = newChildren[newEndIdx + 1] == null ? null : newChildren[newEndIdx + 1].dom;
1336
- for (let i = newStartIdx; i <= newEndIdx; i++) mount(newChildren[i], parent, anchor);
1621
+ for (let i = newStartIdx; i <= newEndIdx; i++) mount(newChildren[i], parent, anchor, parentIsSVG);
1337
1622
  }
1338
1623
  } else if (newStartIdx > newEndIdx) {
1339
1624
  for (let i = oldStartIdx; i <= oldEndIdx; i++) if (oldChildren[i]) unmount(oldChildren[i], parent);
@@ -1350,7 +1635,11 @@ function createRenderer(options) {
1350
1635
  const map = /* @__PURE__ */ new Map();
1351
1636
  for (let i = beginIdx; i <= endIdx; i++) {
1352
1637
  const key = children[i]?.key;
1353
- if (key != null) map.set(String(key), i);
1638
+ if (key != null) {
1639
+ const keyStr = String(key);
1640
+ if (process.env.NODE_ENV !== "production" && map.has(keyStr)) console.warn(`[SignalX] Duplicate key "${key}" detected in list. Keys should be unique among siblings to ensure correct reconciliation. This may cause unexpected behavior when items are reordered, added, or removed.`);
1641
+ map.set(keyStr, i);
1642
+ }
1354
1643
  }
1355
1644
  return map;
1356
1645
  }
@@ -1358,43 +1647,6 @@ function createRenderer(options) {
1358
1647
  for (let i = beginIdx; i <= endIdx; i++) if (children[i] && isSameVNode(children[i], newChild)) return i;
1359
1648
  return null;
1360
1649
  }
1361
- /**
1362
- * Creates a props accessor that can be called with defaults or accessed directly.
1363
- * After calling with defaults, direct property access uses those defaults.
1364
- */
1365
- function createPropsAccessor(reactiveProps) {
1366
- let defaults = {};
1367
- const proxy = new Proxy(function propsAccessor() {}, {
1368
- get(_, key) {
1369
- if (typeof key === "symbol") return void 0;
1370
- const value = reactiveProps[key];
1371
- return value != null ? value : defaults[key];
1372
- },
1373
- apply(_, __, args) {
1374
- if (args[0] && typeof args[0] === "object") defaults = {
1375
- ...defaults,
1376
- ...args[0]
1377
- };
1378
- return proxy;
1379
- },
1380
- has(_, key) {
1381
- if (typeof key === "symbol") return false;
1382
- return key in reactiveProps || key in defaults;
1383
- },
1384
- ownKeys() {
1385
- return [...new Set([...Object.keys(reactiveProps), ...Object.keys(defaults)])];
1386
- },
1387
- getOwnPropertyDescriptor(_, key) {
1388
- if (typeof key === "symbol") return void 0;
1389
- if (key in reactiveProps || key in defaults) return {
1390
- enumerable: true,
1391
- configurable: true,
1392
- writable: false
1393
- };
1394
- }
1395
- });
1396
- return proxy;
1397
- }
1398
1650
  function mountComponent(vnode, container, before, setup) {
1399
1651
  const anchor = hostCreateComment("");
1400
1652
  vnode.dom = anchor;
@@ -1402,14 +1654,21 @@ function createRenderer(options) {
1402
1654
  hostInsert(anchor, container, before);
1403
1655
  let exposed = null;
1404
1656
  let exposeCalled = false;
1405
- const { children, slots: slotsFromProps, ...propsData } = vnode.props || {};
1406
- const reactiveProps = signal(propsData);
1657
+ const { children, slots: slotsFromProps, $models: modelsData, ...propsData } = vnode.props || {};
1658
+ const propsWithModels = { ...propsData };
1659
+ if (modelsData) for (const modelKey in modelsData) {
1660
+ const modelValue = modelsData[modelKey];
1661
+ if (isModel(modelValue)) propsWithModels[modelKey] = modelValue;
1662
+ }
1663
+ const reactiveProps = signal(propsWithModels);
1407
1664
  const internalVNode = vnode;
1408
1665
  internalVNode._componentProps = reactiveProps;
1409
1666
  const slots = createSlots(children, slotsFromProps);
1410
1667
  internalVNode._slots = slots;
1668
+ const createdHooks = [];
1411
1669
  const mountHooks = [];
1412
- const cleanupHooks = [];
1670
+ const updatedHooks = [];
1671
+ const unmountHooks = [];
1413
1672
  const parentInstance = getCurrentInstance();
1414
1673
  const componentName = vnode.type.__name;
1415
1674
  const ctx = {
@@ -1417,16 +1676,19 @@ function createRenderer(options) {
1417
1676
  signal,
1418
1677
  props: createPropsAccessor(reactiveProps),
1419
1678
  slots,
1420
- emit: (event, ...args) => {
1421
- const handler = reactiveProps[`on${event[0].toUpperCase() + event.slice(1)}`];
1422
- if (handler && typeof handler === "function") handler(...args);
1423
- },
1679
+ emit: createEmit(reactiveProps),
1424
1680
  parent: parentInstance,
1425
- onMount: (fn) => {
1681
+ onMounted: (fn) => {
1426
1682
  mountHooks.push(fn);
1427
1683
  },
1428
- onCleanup: (fn) => {
1429
- cleanupHooks.push(fn);
1684
+ onUnmounted: (fn) => {
1685
+ unmountHooks.push(fn);
1686
+ },
1687
+ onCreated: (fn) => {
1688
+ createdHooks.push(fn);
1689
+ },
1690
+ onUpdated: (fn) => {
1691
+ updatedHooks.push(fn);
1430
1692
  },
1431
1693
  expose: (exposedValue) => {
1432
1694
  exposed = exposedValue;
@@ -1435,8 +1697,9 @@ function createRenderer(options) {
1435
1697
  renderFn: null,
1436
1698
  update: () => {}
1437
1699
  };
1700
+ applyContextExtensions(ctx);
1438
1701
  ctx.__name = componentName;
1439
- if (currentAppContext) ctx._appContext = currentAppContext;
1702
+ if (!parentInstance && currentAppContext) provideAppContext(ctx, currentAppContext);
1440
1703
  const componentInstance = {
1441
1704
  name: componentName,
1442
1705
  ctx,
@@ -1445,8 +1708,11 @@ function createRenderer(options) {
1445
1708
  const prev = setCurrentInstance(ctx);
1446
1709
  let renderFn;
1447
1710
  try {
1448
- renderFn = setup(ctx);
1711
+ const setupResult = setup(ctx);
1712
+ if (setupResult && typeof setupResult.then === "function") throw new Error(`Async setup in component "${componentName}" is only supported during SSR. On the client, use pre-loaded data from hydration or fetch in onMounted.`);
1713
+ renderFn = setupResult;
1449
1714
  notifyComponentCreated(currentAppContext, componentInstance);
1715
+ createdHooks.forEach((hook) => hook());
1450
1716
  } catch (err) {
1451
1717
  if (!handleComponentError(currentAppContext, err, componentInstance, "setup")) throw err;
1452
1718
  } finally {
@@ -1454,8 +1720,10 @@ function createRenderer(options) {
1454
1720
  }
1455
1721
  if (vnode.props?.ref) {
1456
1722
  const refValue = exposeCalled ? exposed : null;
1457
- if (typeof vnode.props.ref === "function") vnode.props.ref(refValue);
1458
- else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = refValue;
1723
+ untrack(() => {
1724
+ if (typeof vnode.props.ref === "function") vnode.props.ref(refValue);
1725
+ else if (vnode.props.ref && typeof vnode.props.ref === "object") vnode.props.ref.current = refValue;
1726
+ });
1459
1727
  }
1460
1728
  if (renderFn) {
1461
1729
  ctx.renderFn = renderFn;
@@ -1469,6 +1737,7 @@ function createRenderer(options) {
1469
1737
  if (prevSubTree) {
1470
1738
  patch(prevSubTree, subTree, container);
1471
1739
  notifyComponentUpdated(currentAppContext, componentInstance);
1740
+ updatedHooks.forEach((hook) => hook());
1472
1741
  } else mount(subTree, container, anchor);
1473
1742
  internalVNode._subTree = subTree;
1474
1743
  } catch (err) {
@@ -1487,106 +1756,18 @@ function createRenderer(options) {
1487
1756
  notifyComponentMounted(currentAppContext, componentInstance);
1488
1757
  vnode.cleanup = () => {
1489
1758
  notifyComponentUnmounted(currentAppContext, componentInstance);
1490
- cleanupHooks.forEach((hook) => hook(mountCtx));
1491
- };
1492
- }
1493
- /**
1494
- * Create slots object from children and slots prop.
1495
- * Uses a version signal to trigger re-renders when children change.
1496
- * Supports named slots via:
1497
- * - `slots` prop object (e.g., slots={{ header: () => <div>...</div> }})
1498
- * - `slot` prop on children (e.g., <div slot="header">...</div>)
1499
- */
1500
- function createSlots(children, slotsFromProps) {
1501
- const versionSignal = signal({ v: 0 });
1502
- function extractNamedSlotsFromChildren(c) {
1503
- const defaultChildren = [];
1504
- const namedSlots = {};
1505
- if (c == null) return {
1506
- defaultChildren,
1507
- namedSlots
1508
- };
1509
- const items = Array.isArray(c) ? c : [c];
1510
- for (const child of items) if (child && typeof child === "object" && child.props && child.props.slot) {
1511
- const slotName = child.props.slot;
1512
- if (!namedSlots[slotName]) namedSlots[slotName] = [];
1513
- namedSlots[slotName].push(child);
1514
- } else defaultChildren.push(child);
1515
- return {
1516
- defaultChildren,
1517
- namedSlots
1518
- };
1519
- }
1520
- const slotsObj = {
1521
- _children: children,
1522
- _slotsFromProps: slotsFromProps || {},
1523
- _version: versionSignal,
1524
- _isPatching: false,
1525
- default: function() {
1526
- this._version.v;
1527
- const c = this._children;
1528
- const { defaultChildren } = extractNamedSlotsFromChildren(c);
1529
- return defaultChildren.filter((child) => child != null && child !== false && child !== true);
1530
- }
1531
- };
1532
- return new Proxy(slotsObj, { get(target, prop) {
1533
- if (prop in target) return target[prop];
1534
- if (typeof prop === "string") return function(scopedProps) {
1535
- target._version.v;
1536
- if (target._slotsFromProps && typeof target._slotsFromProps[prop] === "function") {
1537
- const result = target._slotsFromProps[prop](scopedProps);
1538
- if (result == null) return [];
1539
- return Array.isArray(result) ? result : [result];
1540
- }
1541
- const { namedSlots } = extractNamedSlotsFromChildren(target._children);
1542
- return namedSlots[prop] || [];
1543
- };
1544
- } });
1545
- }
1546
- /**
1547
- * Normalize render result to a VNode (wrapping arrays in Fragment)
1548
- * Note: Falsy values (null, undefined, false, true) from conditional rendering
1549
- * are handled by mount() which guards against them, so no filtering needed here.
1550
- */
1551
- function normalizeSubTree(result) {
1552
- if (Array.isArray(result)) return {
1553
- type: Fragment,
1554
- props: {},
1555
- key: null,
1556
- children: result,
1557
- dom: null
1558
- };
1559
- if (typeof result === "string" || typeof result === "number") return {
1560
- type: Text,
1561
- props: {},
1562
- key: null,
1563
- children: [],
1564
- dom: null,
1565
- text: result
1759
+ unmountHooks.forEach((hook) => hook(mountCtx));
1566
1760
  };
1567
- return result;
1568
1761
  }
1569
1762
  return {
1570
- render: render$1,
1571
- createApp: (rootComponent) => {
1572
- return { mount(selectorOrContainer) {
1573
- let container = null;
1574
- if (typeof selectorOrContainer === "string") {
1575
- if (options.querySelector) container = options.querySelector(selectorOrContainer);
1576
- } else container = selectorOrContainer;
1577
- if (!container) {
1578
- console.warn(`Container not found: ${selectorOrContainer}`);
1579
- return;
1580
- }
1581
- render$1(rootComponent, container);
1582
- } };
1583
- }
1763
+ render,
1764
+ patch,
1765
+ mount,
1766
+ unmount,
1767
+ mountComponent
1584
1768
  };
1585
1769
  }
1586
-
1587
- //#endregion
1588
- //#region ../runtime-terminal/src/focus.ts
1589
- const focusableIds = /* @__PURE__ */ new Set();
1770
+ var focusableIds = /* @__PURE__ */ new Set();
1590
1771
  const focusState = signal({ activeId: null });
1591
1772
  function registerFocusable(id) {
1592
1773
  focusableIds.add(id);
@@ -1612,9 +1793,6 @@ function focusPrev() {
1612
1793
  const ids = Array.from(focusableIds);
1613
1794
  focusState.activeId = ids[((focusState.activeId ? ids.indexOf(focusState.activeId) : -1) - 1 + ids.length) % ids.length];
1614
1795
  }
1615
-
1616
- //#endregion
1617
- //#region ../runtime-terminal/src/utils.ts
1618
1796
  function getColorCode(color) {
1619
1797
  switch (color) {
1620
1798
  case "red": return "\x1B[31m";
@@ -1642,316 +1820,62 @@ function getBackgroundColorCode(color) {
1642
1820
  function stripAnsi(str) {
1643
1821
  return str.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
1644
1822
  }
1645
-
1646
- //#endregion
1647
- //#region ../runtime-core/dist/index.js
1648
- let platformSyncProcessor = null;
1649
- /**
1650
- * Get the current platform sync processor (for internal use).
1651
- */
1652
- function getPlatformSyncProcessor$1() {
1653
- return platformSyncProcessor;
1654
- }
1655
- const plugins = [];
1656
- /**
1657
- * Get all registered plugins (internal use)
1658
- */
1659
- function getComponentPlugins$1() {
1660
- return plugins;
1661
- }
1662
- const componentRegistry = /* @__PURE__ */ new Map();
1663
- /**
1664
- * Define a component. Returns a JSX factory function.
1665
- *
1666
- * @param setup - Setup function that receives context and returns a render function
1667
- * @param options - Optional configuration (e.g., name for DevTools)
1668
- *
1669
- * @example
1670
- * ```tsx
1671
- * type CardProps = DefineProp<"title", string> & DefineSlot<"header">;
1672
- *
1673
- * export const Card = defineComponent<CardProps>((ctx) => {
1674
- * const { title } = ctx.props;
1675
- * const { slots } = ctx;
1676
- *
1677
- * return () => (
1678
- * <div class="card">
1679
- * {slots.header?.() ?? <h2>{title}</h2>}
1680
- * {slots.default()}
1681
- * </div>
1682
- * );
1683
- * });
1684
- * ```
1685
- */
1686
- function defineComponent$1(setup, options) {
1687
- const factory = function(props) {
1688
- return {
1689
- type: factory,
1690
- props: props || {},
1691
- key: props?.key || null,
1692
- children: [],
1693
- dom: null
1694
- };
1695
- };
1696
- factory.__setup = setup;
1697
- factory.__name = options?.name;
1698
- factory.__props = null;
1699
- factory.__events = null;
1700
- factory.__ref = null;
1701
- factory.__slots = null;
1702
- componentRegistry.set(factory, {
1703
- name: options?.name,
1704
- setup
1705
- });
1706
- getComponentPlugins$1().forEach((p) => p.onDefine?.(options?.name, factory, setup));
1707
- return factory;
1708
- }
1709
- const Fragment$1 = Symbol.for("sigx.Fragment");
1710
- const Text$1 = Symbol.for("sigx.Text");
1711
- function normalizeChildren(children) {
1712
- if (children == null || children === false || children === true) return [];
1713
- if (Array.isArray(children)) return children.flatMap((c) => normalizeChildren(c));
1714
- if (typeof children === "string" || typeof children === "number") return [{
1715
- type: Text$1,
1716
- props: {},
1717
- key: null,
1718
- children: [],
1719
- dom: null,
1720
- text: children
1721
- }];
1722
- if (children.type) return [children];
1723
- return [];
1724
- }
1725
- /**
1726
- * Check if a type is a sigx component (has __setup)
1727
- */
1728
- function isComponent$1(type) {
1729
- return typeof type === "function" && "__setup" in type;
1730
- }
1731
- /**
1732
- * Create a JSX element - this is the core function called by TSX transpilation
1733
- */
1734
- function jsx$1(type, props, key) {
1735
- const processedProps = { ...props || {} };
1736
- if (props) {
1737
- for (const propKey in props) if (propKey === "sync") {
1738
- let syncBinding = props[propKey];
1739
- if (typeof syncBinding === "function") {
1740
- const detected = detectAccess(syncBinding);
1741
- if (detected) syncBinding = detected;
1742
- }
1743
- if (Array.isArray(syncBinding) && syncBinding.length === 2) {
1744
- const [stateObj, key$1] = syncBinding;
1745
- let handled = false;
1746
- const platformProcessor = getPlatformSyncProcessor$1();
1747
- if (typeof type === "string" && platformProcessor) handled = platformProcessor(type, processedProps, [stateObj, key$1], props);
1748
- if (!handled) {
1749
- processedProps.value = stateObj[key$1];
1750
- const existingHandler = processedProps["onUpdate:value"];
1751
- processedProps["onUpdate:value"] = (v) => {
1752
- stateObj[key$1] = v;
1753
- if (existingHandler) existingHandler(v);
1754
- };
1755
- }
1756
- delete processedProps.sync;
1757
- }
1758
- } else if (propKey.startsWith("sync:")) {
1759
- const syncBinding = props[propKey];
1760
- if (Array.isArray(syncBinding) && syncBinding.length === 2) {
1761
- const [stateObj, key$1] = syncBinding;
1762
- const name = propKey.slice(5);
1763
- processedProps[name] = stateObj[key$1];
1764
- const eventName = `onUpdate:${name}`;
1765
- const existingHandler = processedProps[eventName];
1766
- processedProps[eventName] = (v) => {
1767
- stateObj[key$1] = v;
1768
- if (existingHandler) existingHandler(v);
1769
- };
1770
- delete processedProps[propKey];
1771
- }
1772
- }
1773
- }
1774
- if (isComponent$1(type)) {
1775
- const { children: children$1, ...rest$1 } = processedProps;
1776
- return {
1777
- type,
1778
- props: {
1779
- ...rest$1,
1780
- children: children$1
1781
- },
1782
- key: key || rest$1.key || null,
1783
- children: [],
1784
- dom: null
1785
- };
1786
- }
1787
- if (typeof type === "function" && type !== Fragment$1) return type(processedProps);
1788
- const { children, ...rest } = processedProps;
1789
- return {
1790
- type,
1791
- props: rest,
1792
- key: key || rest.key || null,
1793
- children: normalizeChildren(children),
1794
- dom: null
1795
- };
1796
- }
1797
- /**
1798
- * JSX Factory for fragments
1799
- */
1800
- function jsxs$1(type, props, key) {
1801
- return jsx$1(type, props, key);
1802
- }
1803
- /**
1804
- * Lazy loading utilities for sigx components.
1805
- *
1806
- * Provides runtime-only lazy loading with no build dependencies.
1807
- * Works with any bundler that supports dynamic import().
1808
- */
1809
- let currentSuspenseBoundary = null;
1810
- /**
1811
- * Register a promise with the current Suspense boundary
1812
- * @internal
1813
- */
1814
- function registerPendingPromise$1(promise) {
1815
- const boundary = currentSuspenseBoundary;
1816
- if (boundary) {
1817
- boundary.pending.add(promise);
1818
- promise.finally(() => {
1819
- boundary.pending.delete(promise);
1820
- if (boundary.pending.size === 0) boundary.onResolve();
1821
- });
1822
- return true;
1823
- }
1824
- return false;
1825
- }
1826
- /**
1827
- * Suspense boundary component for handling async loading states.
1828
- *
1829
- * Wraps lazy-loaded components and shows a fallback while they load.
1830
- *
1831
- * @example
1832
- * ```tsx
1833
- * import { lazy, Suspense } from 'sigx';
1834
- *
1835
- * const LazyDashboard = lazy(() => import('./Dashboard'));
1836
- *
1837
- * // Basic usage
1838
- * <Suspense fallback={<div>Loading...</div>}>
1839
- * <LazyDashboard />
1840
- * </Suspense>
1841
- *
1842
- * // With spinner component
1843
- * <Suspense fallback={<Spinner size="large" />}>
1844
- * <LazyDashboard />
1845
- * <LazyCharts />
1846
- * </Suspense>
1847
- * ```
1848
- */
1849
- const Suspense$1 = defineComponent$1((ctx) => {
1850
- const { props, slots } = ctx;
1851
- const state = ctx.signal({
1852
- isReady: false,
1853
- pendingCount: 0
1854
- });
1855
- const boundary = {
1856
- pending: /* @__PURE__ */ new Set(),
1857
- onResolve: () => {
1858
- state.pendingCount = boundary.pending.size;
1859
- if (boundary.pending.size === 0) state.isReady = true;
1860
- }
1861
- };
1862
- ctx.onMount(() => {
1863
- if (boundary.pending.size === 0) state.isReady = true;
1864
- });
1865
- return () => {
1866
- state.isReady;
1867
- state.pendingCount;
1868
- const prevBoundary = currentSuspenseBoundary;
1869
- currentSuspenseBoundary = boundary;
1870
- try {
1871
- const children = slots.default();
1872
- if (boundary.pending.size > 0) {
1873
- const fallback = props.fallback;
1874
- if (typeof fallback === "function") return fallback();
1875
- return fallback ?? null;
1876
- }
1877
- if (Array.isArray(children)) {
1878
- const filtered = children.filter((c) => c != null && c !== false && c !== true);
1879
- if (filtered.length === 0) return null;
1880
- if (filtered.length === 1) return filtered[0];
1881
- return filtered;
1882
- }
1883
- return children;
1884
- } catch (err) {
1885
- if (err instanceof Promise) {
1886
- registerPendingPromise$1(err);
1887
- const fallback = props.fallback;
1888
- if (typeof fallback === "function") return fallback();
1889
- return fallback ?? null;
1890
- }
1891
- throw err;
1892
- } finally {
1893
- currentSuspenseBoundary = prevBoundary;
1894
- }
1895
- };
1896
- }, { name: "Suspense" });
1897
-
1898
- //#endregion
1899
- //#region ../runtime-terminal/src/components/Input.tsx
1900
- /** @jsxImportSource @sigx/runtime-core */
1901
- const Input = defineComponent(({ props, emit }) => {
1823
+ const Input = component(({ props, emit }) => {
1902
1824
  const id = Math.random().toString(36).slice(2);
1825
+ let isReady = false;
1903
1826
  const isFocused = () => focusState.activeId === id;
1827
+ const getValue = () => props.model?.value || "";
1904
1828
  const handleKey = (key) => {
1905
1829
  if (!isFocused()) return;
1830
+ if (!isReady) return;
1906
1831
  if (key === "\r") {
1907
- emit("submit", props.value || "");
1832
+ emit("submit", getValue());
1908
1833
  return;
1909
1834
  }
1910
1835
  if (key === "\n") return;
1911
1836
  if (key === "" || key === "\b") {
1912
- const val = props.value || "";
1837
+ const val = getValue();
1913
1838
  if (val.length > 0) {
1914
- const newValue$1 = val.slice(0, -1);
1915
- emit("update:value", newValue$1);
1916
- emit("input", newValue$1);
1839
+ const newValue = val.slice(0, -1);
1840
+ if (props.model) props.model.value = newValue;
1841
+ emit("input", newValue);
1917
1842
  }
1918
1843
  return;
1919
1844
  }
1920
1845
  if (key.length > 1) return;
1921
- const newValue = (props.value || "") + key;
1922
- emit("update:value", newValue);
1846
+ const newValue = getValue() + key;
1847
+ if (props.model) props.model.value = newValue;
1923
1848
  emit("input", newValue);
1924
1849
  };
1925
1850
  let keyCleanup = null;
1926
- onMount(() => {
1851
+ onMounted(() => {
1927
1852
  registerFocusable(id);
1928
1853
  if (props.autofocus) focus(id);
1929
1854
  keyCleanup = onKey(handleKey);
1855
+ setTimeout(() => {
1856
+ isReady = true;
1857
+ }, 50);
1930
1858
  });
1931
- onCleanup(() => {
1859
+ onUnmounted(() => {
1932
1860
  if (keyCleanup) keyCleanup();
1933
1861
  unregisterFocusable(id);
1934
1862
  });
1935
1863
  return () => {
1936
- const val = (props.value || "").replace(/[\r\n]+/g, " ");
1864
+ const val = getValue().replace(/[\r\n]+/g, " ");
1937
1865
  const placeholder = (props.placeholder || "").replace(/[\r\n]+/g, " ");
1938
1866
  const showCursor = isFocused();
1939
- return /* @__PURE__ */ jsxs$1("box", {
1867
+ return /* @__PURE__ */ jsxs("box", {
1940
1868
  border: "single",
1941
1869
  borderColor: showCursor ? "green" : "white",
1942
1870
  label: props.label,
1943
- children: [/* @__PURE__ */ jsx$1("text", { children: val || placeholder }), showCursor && /* @__PURE__ */ jsx$1("text", {
1871
+ children: [/* @__PURE__ */ jsx("text", { children: val || placeholder }), showCursor && /* @__PURE__ */ jsx("text", {
1944
1872
  color: "cyan",
1945
1873
  children: "_"
1946
1874
  })]
1947
1875
  });
1948
1876
  };
1949
1877
  }, { name: "Input" });
1950
-
1951
- //#endregion
1952
- //#region ../runtime-terminal/src/components/ProgressBar.tsx
1953
- /** @jsxImportSource @sigx/runtime-core */
1954
- const ProgressBar = defineComponent(({ props }) => {
1878
+ const ProgressBar = component(({ props }) => {
1955
1879
  return () => {
1956
1880
  const value = props.value || 0;
1957
1881
  const max = props.max || 100;
@@ -1964,14 +1888,10 @@ const ProgressBar = defineComponent(({ props }) => {
1964
1888
  const percentage = Math.min(Math.max(value / max, 0), 1);
1965
1889
  const filledLen = Math.round(width * percentage);
1966
1890
  const emptyLen = width - filledLen;
1967
- return /* @__PURE__ */ jsx$1("box", { children: /* @__PURE__ */ jsx$1("text", { children: colorCode + barChar.repeat(filledLen) + emptyChar.repeat(emptyLen) + reset + ` ${Math.round(percentage * 100)}%` }) });
1891
+ return /* @__PURE__ */ jsx("box", { children: /* @__PURE__ */ jsx("text", { children: colorCode + barChar.repeat(filledLen) + emptyChar.repeat(emptyLen) + reset + ` ${Math.round(percentage * 100)}%` }) });
1968
1892
  };
1969
1893
  }, { name: "ProgressBar" });
1970
-
1971
- //#endregion
1972
- //#region ../runtime-terminal/src/components/Button.tsx
1973
- /** @jsxImportSource @sigx/runtime-core */
1974
- const Button = defineComponent(({ props, emit }) => {
1894
+ const Button = component(({ props, emit }) => {
1975
1895
  const id = Math.random().toString(36).slice(2);
1976
1896
  const isFocused = () => focusState.activeId === id;
1977
1897
  const pressed = signal({ value: false });
@@ -1989,11 +1909,11 @@ const Button = defineComponent(({ props, emit }) => {
1989
1909
  };
1990
1910
  let keyCleanup = null;
1991
1911
  let pressTimer = null;
1992
- onMount(() => {
1912
+ onMounted(() => {
1993
1913
  registerFocusable(id);
1994
1914
  keyCleanup = onKey(handleKey);
1995
1915
  });
1996
- onCleanup(() => {
1916
+ onUnmounted(() => {
1997
1917
  if (keyCleanup) keyCleanup();
1998
1918
  unregisterFocusable(id);
1999
1919
  if (pressTimer) clearTimeout(pressTimer);
@@ -2002,42 +1922,38 @@ const Button = defineComponent(({ props, emit }) => {
2002
1922
  const focused = isFocused();
2003
1923
  const label = props.label || "Button";
2004
1924
  const isPressed = pressed.value;
2005
- return /* @__PURE__ */ jsx$1("box", {
1925
+ return /* @__PURE__ */ jsx("box", {
2006
1926
  border: "single",
2007
1927
  borderColor: isPressed ? "yellow" : focused ? "green" : "white",
2008
1928
  backgroundColor: isPressed ? "red" : focused ? "blue" : void 0,
2009
1929
  dropShadow: props.dropShadow,
2010
- children: /* @__PURE__ */ jsx$1("text", {
1930
+ children: /* @__PURE__ */ jsx("text", {
2011
1931
  color: focused ? "white" : void 0,
2012
1932
  children: label
2013
1933
  })
2014
1934
  });
2015
1935
  };
2016
1936
  }, { name: "Button" });
2017
-
2018
- //#endregion
2019
- //#region ../runtime-terminal/src/components/Checkbox.tsx
2020
- /** @jsxImportSource @sigx/runtime-core */
2021
- const Checkbox = defineComponent(({ props, emit }) => {
1937
+ const Checkbox = component(({ props, emit }) => {
2022
1938
  const id = Math.random().toString(36).slice(2);
2023
1939
  const isFocused = () => focusState.activeId === id;
2024
- const checked = () => !!props.value;
1940
+ const checked = () => !!props.model?.value;
2025
1941
  const handleKey = (key) => {
2026
1942
  if (!isFocused()) return;
2027
1943
  if (props.disabled) return;
2028
1944
  if (key === "\r" || key === " ") {
2029
1945
  const next = !checked();
2030
- emit("update:value", next);
1946
+ if (props.model) props.model.value = next;
2031
1947
  emit("change", next);
2032
1948
  }
2033
1949
  };
2034
1950
  let keyCleanup = null;
2035
- onMount(() => {
1951
+ onMounted(() => {
2036
1952
  registerFocusable(id);
2037
1953
  if (props.autofocus) focus(id);
2038
1954
  keyCleanup = onKey(handleKey);
2039
1955
  });
2040
- onCleanup(() => {
1956
+ onUnmounted(() => {
2041
1957
  if (keyCleanup) keyCleanup();
2042
1958
  unregisterFocusable(id);
2043
1959
  });
@@ -2046,12 +1962,12 @@ const Checkbox = defineComponent(({ props, emit }) => {
2046
1962
  const focused = isFocused();
2047
1963
  const isChecked = checked();
2048
1964
  const disabled = !!props.disabled;
2049
- return /* @__PURE__ */ jsxs$1("box", { children: [
2050
- /* @__PURE__ */ jsx$1("text", {
1965
+ return /* @__PURE__ */ jsxs("box", { children: [
1966
+ /* @__PURE__ */ jsx("text", {
2051
1967
  color: focused ? "cyan" : "white",
2052
1968
  children: focused ? ">" : " "
2053
1969
  }),
2054
- /* @__PURE__ */ jsxs$1("text", {
1970
+ /* @__PURE__ */ jsxs("text", {
2055
1971
  color: disabled ? "white" : isChecked ? "green" : focused ? "cyan" : "white",
2056
1972
  children: [
2057
1973
  "[",
@@ -2059,86 +1975,87 @@ const Checkbox = defineComponent(({ props, emit }) => {
2059
1975
  "]"
2060
1976
  ]
2061
1977
  }),
2062
- label && /* @__PURE__ */ jsxs$1("text", {
1978
+ label && /* @__PURE__ */ jsxs("text", {
2063
1979
  color: disabled ? "white" : focused ? "cyan" : void 0,
2064
1980
  children: [" ", label]
2065
1981
  })
2066
1982
  ] });
2067
1983
  };
2068
1984
  }, { name: "Checkbox" });
2069
-
2070
- //#endregion
2071
- //#region ../runtime-terminal/src/components/Select.tsx
2072
- /** @jsxImportSource @sigx/runtime-core */
2073
- const Select = defineComponent(({ props, emit }) => {
1985
+ const Select = component(({ props, emit }) => {
2074
1986
  const id = Math.random().toString(36).slice(2);
1987
+ let isReady = false;
2075
1988
  const isFocused = () => focusState.activeId === id;
2076
1989
  const getCurrentIndex = () => {
2077
- const idx = (props.options || []).findIndex((o) => o.value === props.value);
1990
+ const idx = (props.options || []).findIndex((o) => o.value === props.model?.value);
2078
1991
  return idx >= 0 ? idx : 0;
2079
1992
  };
2080
1993
  const handleKey = (key) => {
2081
1994
  if (!isFocused()) return;
1995
+ if (!isReady) return;
2082
1996
  const options = props.options || [];
2083
1997
  if (options.length === 0) return;
2084
1998
  const currentIndex = getCurrentIndex();
2085
1999
  if (key === "\x1B[A" || key === "k") {
2086
2000
  const newValue = options[currentIndex > 0 ? currentIndex - 1 : options.length - 1].value;
2087
- emit("update:value", newValue);
2001
+ if (props.model) props.model.value = newValue;
2088
2002
  emit("change", newValue);
2089
2003
  return;
2090
2004
  }
2091
2005
  if (key === "\x1B[B" || key === "j") {
2092
2006
  const newValue = options[currentIndex < options.length - 1 ? currentIndex + 1 : 0].value;
2093
- emit("update:value", newValue);
2007
+ if (props.model) props.model.value = newValue;
2094
2008
  emit("change", newValue);
2095
2009
  return;
2096
2010
  }
2097
2011
  if (key === "\r") {
2098
- emit("submit", props.value || options[0]?.value || "");
2012
+ emit("submit", props.model?.value || options[0]?.value || "");
2099
2013
  return;
2100
2014
  }
2101
2015
  };
2102
2016
  let keyCleanup = null;
2103
- onMount(() => {
2017
+ onMounted(() => {
2104
2018
  registerFocusable(id);
2105
2019
  if (props.autofocus) focus(id);
2106
2020
  keyCleanup = onKey(handleKey);
2021
+ setTimeout(() => {
2022
+ isReady = true;
2023
+ }, 50);
2107
2024
  });
2108
- onCleanup(() => {
2025
+ onUnmounted(() => {
2109
2026
  if (keyCleanup) keyCleanup();
2110
2027
  unregisterFocusable(id);
2111
2028
  });
2112
2029
  return () => {
2113
2030
  const options = props.options || [];
2114
2031
  const focused = isFocused();
2115
- const currentValue = props.value || options[0]?.value || "";
2032
+ const currentValue = props.model?.value || options[0]?.value || "";
2116
2033
  const label = props.label;
2117
- return /* @__PURE__ */ jsx$1("box", {
2034
+ const selectedOption = options.find((o) => o.value === currentValue);
2035
+ const optionElements = options.map((option) => {
2036
+ const isSelected = option.value === currentValue;
2037
+ return /* @__PURE__ */ jsx("box", { children: /* @__PURE__ */ jsxs("text", {
2038
+ color: isSelected ? "cyan" : "white",
2039
+ children: [
2040
+ isSelected ? "❯" : " ",
2041
+ " ",
2042
+ option.label
2043
+ ]
2044
+ }) });
2045
+ });
2046
+ const descriptionElement = props.showDescription && selectedOption?.description ? /* @__PURE__ */ jsx("box", { children: /* @__PURE__ */ jsxs("text", {
2047
+ color: "#666666",
2048
+ children: [" ↳ ", selectedOption.description]
2049
+ }) }) : null;
2050
+ return /* @__PURE__ */ jsxs("box", { children: [/* @__PURE__ */ jsx("box", {
2118
2051
  border: "single",
2119
2052
  borderColor: focused ? "green" : "white",
2120
2053
  label,
2121
- children: options.map((option) => {
2122
- const isSelected = option.value === currentValue;
2123
- return /* @__PURE__ */ jsxs$1("box", { children: [/* @__PURE__ */ jsxs$1("text", {
2124
- color: isSelected ? "cyan" : "white",
2125
- children: [
2126
- isSelected ? "❯" : " ",
2127
- " ",
2128
- option.label
2129
- ]
2130
- }), option.description && isSelected && /* @__PURE__ */ jsxs$1(Fragment$1, { children: [/* @__PURE__ */ jsx$1("br", {}), /* @__PURE__ */ jsxs$1("text", {
2131
- color: "white",
2132
- children: [" ", option.description]
2133
- })] })] });
2134
- })
2135
- });
2054
+ children: optionElements
2055
+ }), descriptionElement] });
2136
2056
  };
2137
2057
  }, { name: "Select" });
2138
-
2139
- //#endregion
2140
- //#region ../runtime-terminal/src/index.ts
2141
- const renderer = createRenderer({
2058
+ const { render } = createRenderer({
2142
2059
  patchProp: (el, key, prev, next) => {
2143
2060
  el.props[key] = next;
2144
2061
  scheduleRender();
@@ -2209,9 +2126,8 @@ const renderer = createRenderer({
2209
2126
  };
2210
2127
  }
2211
2128
  });
2212
- const { render, createApp } = renderer;
2213
- let rootNode = null;
2214
- let isRendering = false;
2129
+ var rootNode = null;
2130
+ var isRendering = false;
2215
2131
  function scheduleRender() {
2216
2132
  if (isRendering) return;
2217
2133
  isRendering = true;
@@ -2227,10 +2143,6 @@ function flushRender() {
2227
2143
  process.stdout.write(lines.join("\x1B[K\n") + "\x1B[K");
2228
2144
  process.stdout.write("\x1B[J");
2229
2145
  }
2230
- /**
2231
- * Check if a node has a box element as an immediate child.
2232
- * This is used to determine if a component wrapper should be treated as a block element.
2233
- */
2234
2146
  function hasBoxChild(node) {
2235
2147
  for (const child of node.children) if (child.tag === "box") return true;
2236
2148
  return false;
@@ -2319,7 +2231,7 @@ function getBorderChars(style) {
2319
2231
  v: "│"
2320
2232
  };
2321
2233
  }
2322
- const keyHandlers = /* @__PURE__ */ new Set();
2234
+ var keyHandlers = /* @__PURE__ */ new Set();
2323
2235
  function onKey(handler) {
2324
2236
  keyHandlers.add(handler);
2325
2237
  return () => keyHandlers.delete(handler);
@@ -2366,16 +2278,7 @@ function renderTerminal(app, options = {}) {
2366
2278
  }
2367
2279
  } };
2368
2280
  }
2369
- let unmountFn = null;
2370
- /**
2371
- * Helper function to mount the terminal for CLI apps.
2372
- * Returns a mount target that can be passed to defineApp().mount().
2373
- *
2374
- * @example
2375
- * ```tsx
2376
- * defineApp(MyApp).mount(mountTerminal());
2377
- * ```
2378
- */
2281
+ var unmountFn = null;
2379
2282
  function mountTerminal(options = { clearConsole: true }) {
2380
2283
  return {
2381
2284
  mount: terminalMount,
@@ -2385,9 +2288,6 @@ function mountTerminal(options = { clearConsole: true }) {
2385
2288
  }
2386
2289
  };
2387
2290
  }
2388
- /**
2389
- * Exit the terminal app cleanly, restoring terminal state.
2390
- */
2391
2291
  function exitTerminal() {
2392
2292
  if (unmountFn) {
2393
2293
  unmountFn();
@@ -2396,20 +2296,6 @@ function exitTerminal() {
2396
2296
  process.stdout.write("\x1B[?25h");
2397
2297
  process.stdout.write("\x1B[2J\x1B[H");
2398
2298
  }
2399
- /**
2400
- * Mount function for Terminal environments.
2401
- * Use this with defineApp().mount() to render to the terminal.
2402
- *
2403
- * @example
2404
- * ```tsx
2405
- * import { defineApp } from '@sigx/runtime-core';
2406
- * import { terminalMount } from '@sigx/runtime-terminal';
2407
- *
2408
- * const app = defineApp(<Counter />);
2409
- * app.use(loggingPlugin)
2410
- * .mount({ clearConsole: true }, terminalMount);
2411
- * ```
2412
- */
2413
2299
  const terminalMount = (component, options, appContext) => {
2414
2300
  rootNode = {
2415
2301
  type: "root",
@@ -2438,7 +2324,6 @@ const terminalMount = (component, options, appContext) => {
2438
2324
  };
2439
2325
  };
2440
2326
  setDefaultMount(terminalMount);
2327
+ export { Button, CLIENT_DIRECTIVES, CLIENT_DIRECTIVE_PREFIX, Checkbox, ComputedSymbol, Fragment, Input, InstanceLifetimes, ProgressBar, Select, SubscriptionHandler, Suspense, Text, Utils, applyContextExtensions, batch, cleanup, component, compound, computed, createEmit, createModel, createModelFromBinding, createPropsAccessor, createPropsProxy, createRenderer, createSlots, createTopic, defineApp, defineFactory, defineInjectable, defineProvide, detectAccess, effect, effectScope, exitTerminal, filterClientDirectives, focus, focusNext, focusPrev, focusState, getAppContextToken, getComponentMeta, getComponentPlugins, getCurrentInstance, getDefaultMount, getHydrationDirective, getModelSymbol, getPlatformModelProcessor, guid, handleComponentError, hasClientDirective, isComponent, isComputed, isLazyComponent, isModel, isReactive, jsx, jsxDEV, jsxs, lazy, mountTerminal, normalizeSubTree, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, onCreated, onKey, onMounted, onUnmounted, onUpdated, provideAppContext, registerComponentPlugin, registerContextExtension, registerFocusable, registerPendingPromise, render, renderNodeToLines, renderTerminal, serializeProps, setCurrentInstance, setDefaultMount, setPlatformModelProcessor, signal, terminalMount, toRaw, toSubscriber, track, trigger, unregisterFocusable, untrack, useAppContext, valueOf, watch };
2441
2328
 
2442
- //#endregion
2443
- export { AppContextKey, Button, Checkbox, Fragment, Input, InstanceLifetimes, ProgressBar, Select, SubscriptionHandler, Suspense, Text, Utils, batch, createApp, createPropsProxy, createRenderer, createTopic, defineApp, defineComponent, defineFactory, defineInjectable, defineProvide, defineStore, detectAccess, effect, effectScope, exitTerminal, focus, focusNext, focusPrev, focusState, getComponentMeta, getComponentPlugins, getCurrentInstance, getDefaultMount, getPlatformSyncProcessor, guid, handleComponentError, inject, injectApp, isLazyComponent, jsx, jsxDEV, jsxs, lazy, mountTerminal, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, onCleanup, onKey, onMount, provide, registerComponentPlugin, registerFocusable, registerPendingPromise, render, renderNodeToLines, renderTerminal, setCurrentInstance, setDefaultMount, setPlatformSyncProcessor, signal, terminalMount, toSubscriber, unregisterFocusable, untrack, valueOf, watch };
2444
2329
  //# sourceMappingURL=index.js.map