@sigx/terminal 0.1.26 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,12 @@
1
+ //#region \0rolldown/runtime.js
1
2
  var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
2
- const ComputedSymbol = Symbol("computed");
3
- let activeEffect = null;
3
+ //#endregion
4
+ //#region ../reactivity/src/types.ts
5
+ /** Symbol to identify computed values */
6
+ var ComputedSymbol = Symbol("computed");
7
+ //#endregion
8
+ //#region ../reactivity/src/effect.ts
9
+ var activeEffect = null;
4
10
  var batchDepth = 0;
5
11
  var pendingEffects = /* @__PURE__ */ new Set();
6
12
  function setActiveEffect(effect) {
@@ -9,6 +15,18 @@ function setActiveEffect(effect) {
9
15
  function getActiveEffect() {
10
16
  return activeEffect;
11
17
  }
18
+ /**
19
+ * Batch multiple reactive updates into a single flush.
20
+ * Effects are deferred until the batch completes, avoiding redundant re-renders.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * batch(() => {
25
+ * count.value++;
26
+ * name.value = 'Alice';
27
+ * }); // effects run once after both updates
28
+ * ```
29
+ */
12
30
  function batch(fn) {
13
31
  batchDepth++;
14
32
  try {
@@ -59,9 +77,32 @@ function runEffect(fn) {
59
77
  };
60
78
  return runner;
61
79
  }
80
+ /**
81
+ * Create a reactive effect that re-runs whenever its tracked dependencies change.
82
+ * Returns a runner with a `.stop()` method to dispose the effect.
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * const count = signal(0);
87
+ * const runner = effect(() => console.log(count.value));
88
+ * count.value++; // logs: 1
89
+ * runner.stop();
90
+ * ```
91
+ */
62
92
  function effect(fn) {
63
93
  return runEffect(fn);
64
94
  }
95
+ /**
96
+ * Execute a function without tracking any reactive dependencies.
97
+ * Useful for reading signals inside an effect without creating a subscription.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * effect(() => {
102
+ * const val = untrack(() => someSignal.value); // not tracked
103
+ * });
104
+ * ```
105
+ */
65
106
  function untrack(fn) {
66
107
  const prev = activeEffect;
67
108
  activeEffect = null;
@@ -71,6 +112,19 @@ function untrack(fn) {
71
112
  activeEffect = prev;
72
113
  }
73
114
  }
115
+ /**
116
+ * Create an effect scope that collects reactive effects for bulk disposal.
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * const scope = effectScope();
121
+ * scope.run(() => {
122
+ * effect(() => console.log(count.value));
123
+ * effect(() => console.log(name.value));
124
+ * });
125
+ * scope.stop(); // disposes both effects
126
+ * ```
127
+ */
74
128
  function effectScope(_detached) {
75
129
  const effects = [];
76
130
  let active = true;
@@ -85,26 +139,49 @@ function effectScope(_detached) {
85
139
  }
86
140
  };
87
141
  }
88
- const ITERATE_KEY = Symbol("iterate");
89
- const reactiveToRaw = /* @__PURE__ */ new WeakMap();
90
- const rawToReactive = /* @__PURE__ */ new WeakMap();
142
+ //#endregion
143
+ //#region ../reactivity/src/collections.ts
144
+ /** Symbol for tracking iteration dependencies (forEach, keys, values, entries, size) */
145
+ var ITERATE_KEY = Symbol("iterate");
146
+ /** WeakMap to get raw object from reactive proxy */
147
+ var reactiveToRaw = /* @__PURE__ */ new WeakMap();
148
+ /** WeakMap to get reactive proxy from raw object */
149
+ var rawToReactive = /* @__PURE__ */ new WeakMap();
150
+ /**
151
+ * Returns the raw, original object from a reactive proxy.
152
+ * If the value is not a proxy, returns it as-is.
153
+ */
91
154
  function toRaw(observed) {
92
155
  const raw = reactiveToRaw.get(observed);
93
156
  return raw ? toRaw(raw) : observed;
94
157
  }
158
+ /**
159
+ * Checks if a value is a reactive proxy created by signal().
160
+ */
95
161
  function isReactive(value) {
96
162
  return reactiveToRaw.has(value);
97
163
  }
164
+ /**
165
+ * Checks if a value is a collection type (Set, Map, WeakSet, WeakMap).
166
+ */
98
167
  function isCollection(value) {
99
168
  if (!value || typeof value !== "object") return false;
100
169
  const ctor = value.constructor;
101
170
  return ctor === Set || ctor === Map || ctor === WeakSet || ctor === WeakMap;
102
171
  }
172
+ /**
173
+ * Checks if a value is an iterable collection (Set or Map, not Weak variants).
174
+ */
103
175
  function isIterableCollection(value) {
104
176
  if (!value || typeof value !== "object") return false;
105
177
  const ctor = value.constructor;
106
178
  return ctor === Set || ctor === Map;
107
179
  }
180
+ /**
181
+ * Checks if a value is an "exotic" built-in object that should NOT be proxied.
182
+ * These objects have internal slots that cannot be accessed through Proxy.
183
+ * Proxying them causes errors like "Method X called on incompatible receiver".
184
+ */
108
185
  function shouldNotProxy(value) {
109
186
  if (!value || typeof value !== "object") return false;
110
187
  const proto = Object.prototype.toString.call(value);
@@ -128,6 +205,11 @@ function shouldNotProxy(value) {
128
205
  "[object BigUint64Array]"
129
206
  ].includes(proto);
130
207
  }
208
+ /**
209
+ * Creates instrumented collection methods that properly handle reactivity.
210
+ * These methods call the real collection methods on the raw object while
211
+ * tracking dependencies and triggering updates.
212
+ */
131
213
  function createCollectionInstrumentations(depsMap, getOrCreateDep) {
132
214
  const instrumentations = {};
133
215
  instrumentations.has = function(key) {
@@ -230,6 +312,9 @@ function createCollectionInstrumentations(depsMap, getOrCreateDep) {
230
312
  };
231
313
  return instrumentations;
232
314
  }
315
+ /**
316
+ * Creates a reactive iterator that wraps values in reactive proxies.
317
+ */
233
318
  function createReactiveIterator(innerIterator, wrapValues) {
234
319
  return {
235
320
  next() {
@@ -248,6 +333,9 @@ function createReactiveIterator(innerIterator, wrapValues) {
248
333
  }
249
334
  };
250
335
  }
336
+ /**
337
+ * Creates a reactive entries iterator that wraps both keys and values.
338
+ */
251
339
  function createReactiveEntriesIterator(innerIterator) {
252
340
  return {
253
341
  next() {
@@ -267,18 +355,37 @@ function createReactiveEntriesIterator(innerIterator) {
267
355
  }
268
356
  };
269
357
  }
358
+ //#endregion
359
+ //#region ../reactivity/src/signal.ts
360
+ /** Check if a value is a primitive type */
270
361
  function isPrimitive(value) {
271
362
  if (value === null || value === void 0) return true;
272
363
  const type = typeof value;
273
364
  return type === "string" || type === "number" || type === "boolean" || type === "symbol" || type === "bigint";
274
365
  }
275
366
  var accessObserver = null;
367
+ /** @internal Get the current access observer for computed/model integration */
276
368
  function getAccessObserver() {
277
369
  return accessObserver;
278
370
  }
371
+ /** @internal Temporarily suspend the access observer (used by computed to prevent leakage) */
279
372
  function setAccessObserver(observer) {
280
373
  accessObserver = observer;
281
374
  }
375
+ /**
376
+ * Detect which reactive property a selector function accesses.
377
+ *
378
+ * Runs `selector()` while observing property accesses and returns the
379
+ * last `[target, key]` pair accessed, or `null` if nothing was read.
380
+ * Used internally by the model/two-way-binding system.
381
+ *
382
+ * @example
383
+ * ```ts
384
+ * const state = signal({ form: { name: 'Alice' } });
385
+ * const result = detectAccess(() => state.form.name);
386
+ * // result === [state.form, 'name']
387
+ * ```
388
+ */
282
389
  function detectAccess(selector) {
283
390
  let result = null;
284
391
  const prev = accessObserver;
@@ -415,6 +522,14 @@ function signal(target) {
415
522
  rawToReactive.set(objectTarget, proxy);
416
523
  return proxy;
417
524
  }
525
+ //#endregion
526
+ //#region ../reactivity/src/watch.ts
527
+ /**
528
+ * Deeply traverses an object to trigger reactive tracking on all nested properties.
529
+ * @param value The value to traverse
530
+ * @param depth Maximum depth to traverse (Infinity for unlimited, number for limited)
531
+ * @param seen Set of already visited objects to prevent circular references
532
+ */
418
533
  function traverse(value, depth = Infinity, seen = /* @__PURE__ */ new Set()) {
419
534
  if (depth <= 0) return value;
420
535
  if (value === null || typeof value !== "object") return value;
@@ -431,6 +546,19 @@ function traverse(value, depth = Infinity, seen = /* @__PURE__ */ new Set()) {
431
546
  else for (const key of Object.keys(value)) traverse(value[key], depth - 1, seen);
432
547
  return value;
433
548
  }
549
+ /**
550
+ * Watch a reactive source and run a callback when it changes.
551
+ * Supports deep watching, immediate invocation, and pause/resume.
552
+ *
553
+ * @example
554
+ * ```ts
555
+ * const count = signal(0);
556
+ * const handle = watch(() => count.value, (newVal, oldVal) => {
557
+ * console.log(`${oldVal} → ${newVal}`);
558
+ * });
559
+ * handle.stop(); // stop watching
560
+ * ```
561
+ */
434
562
  function watch(source, cb, options) {
435
563
  let oldValue;
436
564
  let isFirst = true;
@@ -495,6 +623,8 @@ function watch(source, cb, options) {
495
623
  resume
496
624
  });
497
625
  }
626
+ //#endregion
627
+ //#region ../reactivity/src/computed.ts
498
628
  function computed(getterOrOptions) {
499
629
  let getter;
500
630
  let setter;
@@ -562,20 +692,47 @@ function computed(getterOrOptions) {
562
692
  }
563
693
  return computedObj;
564
694
  }
695
+ /**
696
+ * Type guard to check if a value is a computed signal.
697
+ *
698
+ * @example
699
+ * ```ts
700
+ * const doubled = computed(() => count.value * 2);
701
+ * console.log(isComputed(doubled)); // true
702
+ * console.log(isComputed({ value: 1 })); // false
703
+ * ```
704
+ */
565
705
  function isComputed(value) {
566
706
  return value !== null && typeof value === "object" && ComputedSymbol in value;
567
707
  }
708
+ //#endregion
709
+ //#region ../runtime-core/src/plugins.ts
568
710
  var plugins = [];
711
+ /**
712
+ * Get all registered plugins (internal use)
713
+ */
569
714
  function getComponentPlugins() {
570
715
  return plugins;
571
716
  }
572
717
  var contextExtensions = [];
718
+ /**
719
+ * Apply all registered context extensions to a context object.
720
+ * Called internally by the renderer when creating component contexts.
721
+ */
573
722
  function applyContextExtensions(ctx) {
574
723
  for (const extension of contextExtensions) extension(ctx);
575
724
  }
725
+ //#endregion
726
+ //#region __vite-browser-external
576
727
  var require___vite_browser_external = /* @__PURE__ */ __commonJSMin(((exports, module) => {
577
728
  module.exports = {};
578
729
  }));
730
+ //#endregion
731
+ //#region ../runtime-core/src/async-context.ts
732
+ /**
733
+ * Try to load AsyncLocalStorage from Node.js.
734
+ * Returns null in browser environments.
735
+ */
579
736
  var asyncLocalStorage = null;
580
737
  try {
581
738
  if (typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined") {
@@ -587,6 +744,10 @@ var _fallbackContext = {
587
744
  currentComponentContext: null,
588
745
  currentSuspenseBoundary: null
589
746
  };
747
+ /**
748
+ * Get the current request context.
749
+ * Returns the AsyncLocalStorage store if available, otherwise the module-level fallback.
750
+ */
590
751
  function getRequestContext() {
591
752
  if (asyncLocalStorage) {
592
753
  const store = asyncLocalStorage.getStore();
@@ -594,25 +755,56 @@ function getRequestContext() {
594
755
  }
595
756
  return _fallbackContext;
596
757
  }
758
+ /**
759
+ * Get the current component context (request-safe).
760
+ */
597
761
  function getCurrentInstanceSafe() {
598
762
  return getRequestContext().currentComponentContext;
599
763
  }
764
+ /**
765
+ * Set the current component context (request-safe).
766
+ * Returns the previous value.
767
+ */
600
768
  function setCurrentInstanceSafe(ctx) {
601
769
  const reqCtx = getRequestContext();
602
770
  const prev = reqCtx.currentComponentContext;
603
771
  reqCtx.currentComponentContext = ctx;
604
772
  return prev;
605
773
  }
774
+ /**
775
+ * Get the current suspense boundary (request-safe).
776
+ */
606
777
  function getCurrentSuspenseBoundarySafe() {
607
778
  return getRequestContext().currentSuspenseBoundary;
608
779
  }
780
+ /**
781
+ * Set the current suspense boundary (request-safe).
782
+ * Returns the previous value.
783
+ */
609
784
  function setCurrentSuspenseBoundarySafe(boundary) {
610
785
  const reqCtx = getRequestContext();
611
786
  const prev = reqCtx.currentSuspenseBoundary;
612
787
  reqCtx.currentSuspenseBoundary = boundary;
613
788
  return prev;
614
789
  }
790
+ //#endregion
791
+ //#region ../runtime-core/src/component.ts
615
792
  var currentComponentContext = null;
793
+ /**
794
+ * Returns the setup context of the currently executing component, or `null` if called outside setup.
795
+ *
796
+ * Use this to access the component context (props, emit, etc.) from composable functions
797
+ * or lifecycle hooks that run during component setup.
798
+ *
799
+ * @example
800
+ * ```ts
801
+ * function useMyComposable() {
802
+ * const ctx = getCurrentInstance();
803
+ * if (!ctx) throw new Error('Must be called during component setup');
804
+ * ctx.onMounted(({ el }) => console.log('Mounted to', el));
805
+ * }
806
+ * ```
807
+ */
616
808
  function getCurrentInstance() {
617
809
  return getCurrentInstanceSafe() ?? currentComponentContext;
618
810
  }
@@ -622,26 +814,108 @@ function setCurrentInstance(ctx) {
622
814
  currentComponentContext = ctx;
623
815
  return prevSafe ?? prevModule;
624
816
  }
817
+ /**
818
+ * Register a callback to run after the component is mounted to the DOM.
819
+ * Must be called during component setup.
820
+ *
821
+ * @param fn - Callback receiving a {@link MountContext} with the component's root element.
822
+ *
823
+ * @example
824
+ * ```ts
825
+ * const MyComponent = component(() => {
826
+ * onMounted(({ el }) => {
827
+ * console.log('Mounted to', el);
828
+ * });
829
+ * return () => <div>Hello</div>;
830
+ * });
831
+ * ```
832
+ */
625
833
  function onMounted(fn) {
626
834
  if (currentComponentContext) currentComponentContext.onMounted(fn);
627
835
  else console.warn("onMounted called outside of component setup");
628
836
  }
837
+ /**
838
+ * Register a callback to run when the component is unmounted from the DOM.
839
+ * Must be called during component setup. Use for cleanup (event listeners, timers, subscriptions).
840
+ *
841
+ * @param fn - Callback receiving a {@link MountContext} with the component's root element.
842
+ *
843
+ * @example
844
+ * ```ts
845
+ * const MyComponent = component(() => {
846
+ * const timer = setInterval(() => tick(), 1000);
847
+ * onUnmounted(() => clearInterval(timer));
848
+ * return () => <div>Tick</div>;
849
+ * });
850
+ * ```
851
+ */
629
852
  function onUnmounted(fn) {
630
853
  if (currentComponentContext) currentComponentContext.onUnmounted(fn);
631
854
  else console.warn("onUnmounted called outside of component setup");
632
855
  }
856
+ /**
857
+ * Register a callback to run immediately after component setup completes,
858
+ * before the first render. Must be called during component setup.
859
+ *
860
+ * @example
861
+ * ```ts
862
+ * const MyComponent = component(() => {
863
+ * onCreated(() => console.log('Setup done, about to render'));
864
+ * return () => <div>Hello</div>;
865
+ * });
866
+ * ```
867
+ */
633
868
  function onCreated(fn) {
634
869
  if (currentComponentContext) currentComponentContext.onCreated(fn);
635
870
  else console.warn("onCreated called outside of component setup");
636
871
  }
872
+ /**
873
+ * Register a callback to run after every reactive re-render of the component.
874
+ * Must be called during component setup.
875
+ *
876
+ * @example
877
+ * ```ts
878
+ * const Counter = component(() => {
879
+ * const state = signal({ count: 0 });
880
+ * onUpdated(() => console.log('Re-rendered with count:', state.count));
881
+ * return () => <button onClick={() => state.count++}>{state.count}</button>;
882
+ * });
883
+ * ```
884
+ */
637
885
  function onUpdated(fn) {
638
886
  if (currentComponentContext) currentComponentContext.onUpdated(fn);
639
887
  else console.warn("onUpdated called outside of component setup");
640
888
  }
641
889
  var componentRegistry = /* @__PURE__ */ new Map();
890
+ /**
891
+ * Get component metadata (for DevTools)
892
+ */
642
893
  function getComponentMeta(factory) {
643
894
  return componentRegistry.get(factory);
644
895
  }
896
+ /**
897
+ * Define a component. Returns a JSX factory function.
898
+ *
899
+ * @param setup - Setup function that receives context and returns a render function
900
+ * @param options - Optional configuration (e.g., name for DevTools)
901
+ *
902
+ * @example
903
+ * ```tsx
904
+ * type CardProps = DefineProp<"title", string> & DefineSlot<"header">;
905
+ *
906
+ * export const Card = component<CardProps>((ctx) => {
907
+ * const { title } = ctx.props;
908
+ * const { slots } = ctx;
909
+ *
910
+ * return () => (
911
+ * <div class="card">
912
+ * {slots.header?.() ?? <h2>{title}</h2>}
913
+ * {slots.default()}
914
+ * </div>
915
+ * );
916
+ * });
917
+ * ```
918
+ */
645
919
  function component(setup, options) {
646
920
  const factory = function(props) {
647
921
  return {
@@ -665,6 +939,28 @@ function component(setup, options) {
665
939
  getComponentPlugins().forEach((p) => p.onDefine?.(options?.name, factory, setup));
666
940
  return factory;
667
941
  }
942
+ //#endregion
943
+ //#region ../runtime-core/src/errors.ts
944
+ /**
945
+ * Structured error system for SignalX runtime.
946
+ *
947
+ * Every runtime error has a unique code (SIGX001–SIGX999) so users can
948
+ * programmatically handle errors and look them up in documentation.
949
+ *
950
+ * @example
951
+ * ```ts
952
+ * try {
953
+ * app.mount('#app');
954
+ * } catch (e) {
955
+ * if (e instanceof SigxError && e.code === 'SIGX101') {
956
+ * // handle missing mount target
957
+ * }
958
+ * }
959
+ * ```
960
+ */
961
+ /**
962
+ * Base error class for all SignalX runtime errors.
963
+ */
668
964
  var SigxError = class extends Error {
669
965
  constructor(message, options) {
670
966
  super(message);
@@ -674,7 +970,15 @@ var SigxError = class extends Error {
674
970
  if (options.cause) this.cause = options.cause;
675
971
  }
676
972
  };
677
- const SigxErrorCode = {
973
+ /**
974
+ * Error codes for the SignalX runtime.
975
+ *
976
+ * Ranges:
977
+ * - SIGX001–SIGX099: App lifecycle
978
+ * - SIGX100–SIGX199: Rendering / mounting
979
+ * - SIGX200–SIGX299: Dependency injection
980
+ */
981
+ var SigxErrorCode = {
678
982
  NO_MOUNT_FUNCTION: "SIGX001",
679
983
  RENDER_TARGET_NOT_FOUND: "SIGX100",
680
984
  MOUNT_TARGET_NOT_FOUND: "SIGX101",
@@ -718,8 +1022,23 @@ function provideInvalidInjectableError() {
718
1022
  suggestion: "Create an injectable first:\n const useMyService = defineInjectable(() => new MyService());\n defineProvide(useMyService);"
719
1023
  });
720
1024
  }
1025
+ //#endregion
1026
+ //#region ../runtime-core/src/di/injectable.ts
1027
+ /**
1028
+ * Global singleton instances (fallback when no provider found)
1029
+ */
721
1030
  var globalInstances = /* @__PURE__ */ new Map();
1031
+ /**
1032
+ * Token for the AppContext injectable.
1033
+ * Used to provide/lookup the AppContext in the component tree.
1034
+ */
722
1035
  var appContextToken = Symbol("sigx:appContext");
1036
+ /**
1037
+ * Lookup a provided value by token, traversing component tree.
1038
+ * The AppContext is provided at the root component level, so it's found
1039
+ * just like any other provided value.
1040
+ * @internal
1041
+ */
723
1042
  function lookupProvided(token) {
724
1043
  const ctx = getCurrentInstance();
725
1044
  if (!ctx) return;
@@ -729,6 +1048,10 @@ function lookupProvided(token) {
729
1048
  current = current.parent;
730
1049
  }
731
1050
  }
1051
+ /**
1052
+ * Provide a value at the current component level
1053
+ * @internal
1054
+ */
732
1055
  function provideAtComponent(token, value) {
733
1056
  const ctx = getCurrentInstance();
734
1057
  if (!ctx) throw provideOutsideSetupError();
@@ -736,6 +1059,26 @@ function provideAtComponent(token, value) {
736
1059
  if (!node.provides) node.provides = /* @__PURE__ */ new Map();
737
1060
  node.provides.set(token, value);
738
1061
  }
1062
+ /**
1063
+ * Define an injectable service/value that can be provided at app or component level.
1064
+ *
1065
+ * The returned function can be called to get the current instance:
1066
+ * - If provided at component level via `defineProvide()`, returns that instance
1067
+ * - If provided at app level via `app.defineProvide()`, returns that instance
1068
+ * - Otherwise falls back to a global singleton created by the factory
1069
+ *
1070
+ * @example
1071
+ * ```typescript
1072
+ * // Define a service
1073
+ * const useApiConfig = defineInjectable(() => ({
1074
+ * baseUrl: 'https://api.example.com'
1075
+ * }));
1076
+ *
1077
+ * // Use it in any component - gets nearest provided instance or global singleton
1078
+ * const config = useApiConfig();
1079
+ * console.log(config.baseUrl);
1080
+ * ```
1081
+ */
739
1082
  function defineInjectable(factory) {
740
1083
  const token = Symbol();
741
1084
  const useFn = (() => {
@@ -748,6 +1091,34 @@ function defineInjectable(factory) {
748
1091
  useFn._token = token;
749
1092
  return useFn;
750
1093
  }
1094
+ /**
1095
+ * Provide a new instance of an injectable at the current component level.
1096
+ * Child components will receive this instance when calling the injectable function.
1097
+ *
1098
+ * @param useFn - The injectable function created by defineInjectable
1099
+ * @param factory - Optional custom factory to create the instance (overrides default)
1100
+ *
1101
+ * @example
1102
+ * ```typescript
1103
+ * const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));
1104
+ *
1105
+ * const MyComponent = component(() => {
1106
+ * // Create and provide a new instance for this subtree
1107
+ * const config = defineProvide(useApiConfig);
1108
+ * config.baseUrl = 'https://custom.api.com';
1109
+ *
1110
+ * return () => <ChildComponent />;
1111
+ * });
1112
+ *
1113
+ * // Or provide a pre-constructed instance:
1114
+ * const MyComponent2 = component(() => {
1115
+ * const customService = createMyService({ custom: 'options' });
1116
+ * defineProvide(useMyService, () => customService);
1117
+ *
1118
+ * return () => <ChildComponent />;
1119
+ * });
1120
+ * ```
1121
+ */
751
1122
  function defineProvide(useFn, factory) {
752
1123
  const actualFactory = factory ?? useFn._factory;
753
1124
  const token = useFn._token;
@@ -756,31 +1127,110 @@ function defineProvide(useFn, factory) {
756
1127
  provideAtComponent(token, instance);
757
1128
  return instance;
758
1129
  }
1130
+ /**
1131
+ * Get the current AppContext from the component tree.
1132
+ * The AppContext is provided at the root component level during mount/hydrate/SSR.
1133
+ *
1134
+ * @example
1135
+ * ```typescript
1136
+ * const appContext = useAppContext();
1137
+ * console.log(appContext?.app);
1138
+ * ```
1139
+ */
759
1140
  function useAppContext() {
760
1141
  return lookupProvided(appContextToken) ?? null;
761
1142
  }
1143
+ /**
1144
+ * Get the AppContext token.
1145
+ * Used by renderers to provide the AppContext at the root component level.
1146
+ * @internal
1147
+ */
762
1148
  function getAppContextToken() {
763
1149
  return appContextToken;
764
1150
  }
1151
+ /**
1152
+ * Provide the AppContext on a component's provides Map.
1153
+ * Called by the renderer for the ROOT component only.
1154
+ * @internal
1155
+ */
765
1156
  function provideAppContext(ctx, appContext) {
766
1157
  const node = ctx;
767
1158
  if (!node.provides) node.provides = /* @__PURE__ */ new Map();
768
1159
  node.provides.set(appContextToken, appContext);
769
1160
  if (appContext.provides) for (const [token, value] of appContext.provides) node.provides.set(token, value);
770
1161
  }
771
- const __DIRECTIVE__ = Symbol.for("sigx.directive");
1162
+ //#endregion
1163
+ //#region ../runtime-core/src/directives.ts
1164
+ /**
1165
+ * Marker symbol to identify directive definitions.
1166
+ * @internal
1167
+ */
1168
+ var __DIRECTIVE__ = Symbol.for("sigx.directive");
1169
+ /**
1170
+ * Define a directive. This is an identity function that marks the definition
1171
+ * for type inference and runtime identification.
1172
+ *
1173
+ * @example
1174
+ * ```ts
1175
+ * const highlight = defineDirective<string>({
1176
+ * mounted(el, { value }) {
1177
+ * el.style.backgroundColor = value;
1178
+ * },
1179
+ * updated(el, { value }) {
1180
+ * el.style.backgroundColor = value;
1181
+ * }
1182
+ * });
1183
+ * ```
1184
+ */
772
1185
  function defineDirective(definition) {
773
1186
  definition[__DIRECTIVE__] = true;
774
1187
  return definition;
775
1188
  }
1189
+ /**
1190
+ * Check if a value is a directive definition.
1191
+ */
776
1192
  function isDirective(value) {
777
1193
  return value != null && typeof value === "object" && value[__DIRECTIVE__] === true;
778
1194
  }
1195
+ //#endregion
1196
+ //#region ../runtime-core/src/app.ts
779
1197
  var isDev = typeof process !== "undefined" && process.env.NODE_ENV !== "production" || true;
780
1198
  var defaultMountFn = null;
1199
+ /**
1200
+ * Set the default mount function for the platform.
1201
+ * Called by platform packages (runtime-dom, runtime-terminal) on import.
1202
+ *
1203
+ * @example
1204
+ * ```typescript
1205
+ * // In @sigx/runtime-dom
1206
+ * import { setDefaultMount } from '@sigx/runtime-core';
1207
+ * setDefaultMount(domMount);
1208
+ * ```
1209
+ */
781
1210
  function setDefaultMount(mountFn) {
782
1211
  defaultMountFn = mountFn;
783
1212
  }
1213
+ /**
1214
+ * Create an application instance.
1215
+ *
1216
+ * @example
1217
+ * ```tsx
1218
+ * import { defineApp, defineInjectable } from '@sigx/runtime-core';
1219
+ *
1220
+ * // Define an injectable service
1221
+ * const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));
1222
+ *
1223
+ * const app = defineApp(<App />);
1224
+ *
1225
+ * app.use(myPlugin, { option: 'value' });
1226
+ *
1227
+ * // Provide custom instance at app level
1228
+ * const config = app.defineProvide(useApiConfig);
1229
+ * config.baseUrl = 'https://custom.api.com';
1230
+ *
1231
+ * app.mount(document.getElementById('app')!);
1232
+ * ```
1233
+ */
784
1234
  function defineApp(rootComponent) {
785
1235
  const installedPlugins = /* @__PURE__ */ new Set();
786
1236
  const context = {
@@ -867,6 +1317,10 @@ function defineApp(rootComponent) {
867
1317
  context.provides.set(appContextToken, context);
868
1318
  return app;
869
1319
  }
1320
+ /**
1321
+ * Notify all app hooks that a component was created.
1322
+ * Called by the renderer after setup() returns.
1323
+ */
870
1324
  function notifyComponentCreated(context, instance) {
871
1325
  if (!context) return;
872
1326
  for (const hooks of context.hooks) try {
@@ -875,6 +1329,10 @@ function notifyComponentCreated(context, instance) {
875
1329
  handleHookError(context, err, instance, "onComponentCreated");
876
1330
  }
877
1331
  }
1332
+ /**
1333
+ * Notify all app hooks that a component was mounted.
1334
+ * Called by the renderer after mount hooks run.
1335
+ */
878
1336
  function notifyComponentMounted(context, instance) {
879
1337
  if (!context) return;
880
1338
  for (const hooks of context.hooks) try {
@@ -883,6 +1341,10 @@ function notifyComponentMounted(context, instance) {
883
1341
  handleHookError(context, err, instance, "onComponentMounted");
884
1342
  }
885
1343
  }
1344
+ /**
1345
+ * Notify all app hooks that a component was unmounted.
1346
+ * Called by the renderer before cleanup.
1347
+ */
886
1348
  function notifyComponentUnmounted(context, instance) {
887
1349
  if (!context) return;
888
1350
  for (const hooks of context.hooks) try {
@@ -891,6 +1353,10 @@ function notifyComponentUnmounted(context, instance) {
891
1353
  handleHookError(context, err, instance, "onComponentUnmounted");
892
1354
  }
893
1355
  }
1356
+ /**
1357
+ * Notify all app hooks that a component updated.
1358
+ * Called by the renderer after re-render.
1359
+ */
894
1360
  function notifyComponentUpdated(context, instance) {
895
1361
  if (!context) return;
896
1362
  for (const hooks of context.hooks) try {
@@ -899,6 +1365,10 @@ function notifyComponentUpdated(context, instance) {
899
1365
  handleHookError(context, err, instance, "onComponentUpdated");
900
1366
  }
901
1367
  }
1368
+ /**
1369
+ * Handle an error in a component. Returns true if the error was handled.
1370
+ * Called by the renderer when an error occurs in setup or render.
1371
+ */
902
1372
  function handleComponentError(context, err, instance, info) {
903
1373
  if (!context) return false;
904
1374
  for (const hooks of context.hooks) try {
@@ -913,16 +1383,84 @@ function handleComponentError(context, err, instance, info) {
913
1383
  }
914
1384
  return false;
915
1385
  }
1386
+ /**
1387
+ * Handle errors that occur in hooks themselves
1388
+ */
916
1389
  function handleHookError(context, err, instance, hookName) {
917
1390
  console.error(`Error in ${hookName} hook:`, err);
918
1391
  if (context.config.errorHandler) try {
919
1392
  context.config.errorHandler(err, instance, `plugin hook: ${hookName}`);
920
1393
  } catch {}
921
1394
  }
1395
+ //#endregion
1396
+ //#region ../runtime-core/src/compound.ts
1397
+ /**
1398
+ * Creates a compound component by attaching sub-components as static properties.
1399
+ *
1400
+ * This enables the pattern of `Parent.Child` components (e.g., `Menu.Item`, `Card.Body`)
1401
+ * while preserving full TypeScript type inference for both the parent and children.
1402
+ *
1403
+ * @param main - The main/parent component factory
1404
+ * @param sub - An object containing sub-components to attach
1405
+ * @returns The main component with sub-components attached as static properties
1406
+ *
1407
+ * @example
1408
+ * ```tsx
1409
+ * // Define individual components
1410
+ * const _Menu = component<MenuProps>(ctx => { ... });
1411
+ * const _MenuItem = component<MenuItemProps>(ctx => { ... });
1412
+ * const _MenuTitle = component<MenuTitleProps>(ctx => { ... });
1413
+ *
1414
+ * // Create compound component
1415
+ * export const Menu = compound(_Menu, {
1416
+ * Item: _MenuItem,
1417
+ * Title: _MenuTitle,
1418
+ * });
1419
+ *
1420
+ * // Usage in JSX
1421
+ * <Menu>
1422
+ * <Menu.Title>Navigation</Menu.Title>
1423
+ * <Menu.Item value="home">Home</Menu.Item>
1424
+ * <Menu.Item value="about">About</Menu.Item>
1425
+ * </Menu>
1426
+ * ```
1427
+ */
922
1428
  function compound(main, sub) {
923
1429
  return Object.assign(main, sub);
924
1430
  }
1431
+ //#endregion
1432
+ //#region ../runtime-core/src/model.ts
1433
+ /**
1434
+ * Model<T> - Unified two-way binding type for SignalX components.
1435
+ *
1436
+ * Provides a single interface for reading, writing, and forwarding model bindings.
1437
+ *
1438
+ * @example
1439
+ * ```tsx
1440
+ * const Input = component<InputProps>(({ props }) => {
1441
+ * // Read
1442
+ * console.log(props.model.value);
1443
+ *
1444
+ * // Write
1445
+ * props.model.value = "new value";
1446
+ *
1447
+ * // Forward to child
1448
+ * <Child model={props.model} />
1449
+ *
1450
+ * // Forward via context
1451
+ * defineProvide(inputContext, () => props.model);
1452
+ * });
1453
+ * ```
1454
+ */
1455
+ /** Symbol to identify Model objects */
925
1456
  var MODEL_SYMBOL = Symbol.for("sigx.model");
1457
+ /**
1458
+ * Creates a Model<T> from a binding tuple and update handler.
1459
+ *
1460
+ * @param tuple - The [sourceObject, key] tuple from reactivity detection
1461
+ * @param updateHandler - Function called when value is set (enables parent interception)
1462
+ * @returns A Model<T> with .value getter/setter and .binding for forwarding
1463
+ */
926
1464
  function createModel(tuple, updateHandler) {
927
1465
  const [obj, key] = tuple;
928
1466
  return {
@@ -942,23 +1480,57 @@ function createModel(tuple, updateHandler) {
942
1480
  [MODEL_SYMBOL]: true
943
1481
  };
944
1482
  }
1483
+ /**
1484
+ * Creates a Model<T> from an existing binding (for forwarding scenarios).
1485
+ *
1486
+ * @param binding - The full binding tuple [obj, key, handler]
1487
+ * @returns A new Model<T> wrapping the same binding
1488
+ */
945
1489
  function createModelFromBinding(binding) {
946
1490
  const [obj, key, handler] = binding;
947
1491
  return createModel([obj, key], handler);
948
1492
  }
1493
+ /**
1494
+ * Type guard to check if a value is a Model<T>.
1495
+ *
1496
+ * Used by JSX runtime to detect forwarded models and extract their bindings.
1497
+ */
949
1498
  function isModel(value) {
950
1499
  return value !== null && typeof value === "object" && MODEL_SYMBOL in value && value[MODEL_SYMBOL] === true;
951
1500
  }
1501
+ //#endregion
1502
+ //#region ../runtime-core/src/platform.ts
952
1503
  var platformModelProcessor = null;
1504
+ /**
1505
+ * Get the current platform model processor (for internal use).
1506
+ */
953
1507
  function getPlatformModelProcessor() {
954
1508
  return platformModelProcessor;
955
1509
  }
1510
+ //#endregion
1511
+ //#region ../runtime-core/src/utils/is-component.ts
1512
+ /**
1513
+ * Check if a value is a SignalX component (has __setup).
1514
+ *
1515
+ * SignalX components are created with component() and have a __setup
1516
+ * property containing the setup function.
1517
+ *
1518
+ * @example
1519
+ * ```ts
1520
+ * const MyComponent = component((ctx) => () => <div/>);
1521
+ * isComponent(MyComponent); // true
1522
+ * isComponent(() => <div/>); // false (plain function component)
1523
+ * isComponent('div'); // false
1524
+ * ```
1525
+ */
956
1526
  function isComponent(type) {
957
1527
  return typeof type === "function" && "__setup" in type;
958
1528
  }
959
- const Fragment = Symbol.for("sigx.Fragment");
960
- const Text = Symbol.for("sigx.Text");
961
- const Comment = Symbol.for("sigx.Comment");
1529
+ //#endregion
1530
+ //#region ../runtime-core/src/jsx-runtime.ts
1531
+ var Fragment = Symbol.for("sigx.Fragment");
1532
+ var Text = Symbol.for("sigx.Text");
1533
+ var Comment = Symbol.for("sigx.Comment");
962
1534
  function normalizeChildren(children) {
963
1535
  if (children == null || children === false || children === true) return [];
964
1536
  if (isComputed(children)) return normalizeChildren(children.value);
@@ -1023,6 +1595,9 @@ function normalizeChildren(children) {
1023
1595
  if (children.type) return [children];
1024
1596
  return [];
1025
1597
  }
1598
+ /**
1599
+ * Create a JSX element - this is the core function called by TSX transpilation
1600
+ */
1026
1601
  function jsx(type, props, key) {
1027
1602
  const processedProps = { ...props };
1028
1603
  const models = {};
@@ -1123,11 +1698,26 @@ function jsx(type, props, key) {
1123
1698
  dom: null
1124
1699
  };
1125
1700
  }
1701
+ /**
1702
+ * JSX Factory for fragments
1703
+ */
1126
1704
  function jsxs(type, props, key) {
1127
1705
  return jsx(type, props, key);
1128
1706
  }
1129
- const jsxDEV = jsx;
1707
+ var jsxDEV = jsx;
1708
+ //#endregion
1709
+ //#region ../runtime-core/src/lazy.tsx
1710
+ /**
1711
+ * Lazy loading utilities for sigx components.
1712
+ *
1713
+ * Provides runtime-only lazy loading with no build dependencies.
1714
+ * Works with any bundler that supports dynamic import().
1715
+ */
1130
1716
  var currentSuspenseBoundary = null;
1717
+ /**
1718
+ * Register a promise with the current Suspense boundary
1719
+ * @internal
1720
+ */
1131
1721
  function registerPendingPromise(promise) {
1132
1722
  const boundary = getCurrentSuspenseBoundarySafe() ?? currentSuspenseBoundary;
1133
1723
  if (boundary) {
@@ -1140,6 +1730,33 @@ function registerPendingPromise(promise) {
1140
1730
  }
1141
1731
  return false;
1142
1732
  }
1733
+ /**
1734
+ * Create a lazy-loaded component wrapper.
1735
+ *
1736
+ * The component will be loaded on first render. Use with `<Suspense>` to show
1737
+ * a fallback while loading.
1738
+ *
1739
+ * @param loader - Function that returns a Promise resolving to the component
1740
+ * @returns A component factory that loads the real component on demand
1741
+ *
1742
+ * @example
1743
+ * ```tsx
1744
+ * import { lazy, Suspense } from 'sigx';
1745
+ *
1746
+ * // Component will be in a separate chunk
1747
+ * const HeavyChart = lazy(() => import('./components/HeavyChart'));
1748
+ *
1749
+ * // Usage
1750
+ * <Suspense fallback={<Spinner />}>
1751
+ * <HeavyChart data={chartData} />
1752
+ * </Suspense>
1753
+ *
1754
+ * // Preload on hover
1755
+ * <button onMouseEnter={() => HeavyChart.preload()}>
1756
+ * Show Chart
1757
+ * </button>
1758
+ * ```
1759
+ */
1143
1760
  function lazy(loader) {
1144
1761
  let Component = null;
1145
1762
  let promise = null;
@@ -1223,7 +1840,30 @@ function lazy(loader) {
1223
1840
  };
1224
1841
  return LazyWrapper;
1225
1842
  }
1226
- const Suspense = component((ctx) => {
1843
+ /**
1844
+ * Suspense boundary component for handling async loading states.
1845
+ *
1846
+ * Wraps lazy-loaded components and shows a fallback while they load.
1847
+ *
1848
+ * @example
1849
+ * ```tsx
1850
+ * import { lazy, Suspense } from 'sigx';
1851
+ *
1852
+ * const LazyDashboard = lazy(() => import('./Dashboard'));
1853
+ *
1854
+ * // Basic usage
1855
+ * <Suspense fallback={<div>Loading...</div>}>
1856
+ * <LazyDashboard />
1857
+ * </Suspense>
1858
+ *
1859
+ * // With spinner component
1860
+ * <Suspense fallback={<Spinner size="large" />}>
1861
+ * <LazyDashboard />
1862
+ * <LazyCharts />
1863
+ * </Suspense>
1864
+ * ```
1865
+ */
1866
+ var Suspense = component((ctx) => {
1227
1867
  const { props, slots } = ctx;
1228
1868
  const state = ctx.signal({
1229
1869
  isReady: false,
@@ -1273,9 +1913,48 @@ const Suspense = component((ctx) => {
1273
1913
  }
1274
1914
  };
1275
1915
  }, { name: "Suspense" });
1916
+ /**
1917
+ * Check if a component is a lazy-loaded component
1918
+ */
1276
1919
  function isLazyComponent(component) {
1277
1920
  return component && component.__lazy === true;
1278
1921
  }
1922
+ //#endregion
1923
+ //#region ../runtime-core/src/use-async.ts
1924
+ /**
1925
+ * useAsync — composable for loading async dependencies in components.
1926
+ *
1927
+ * Wraps an async loader in a reactive signal with loading/error states.
1928
+ * No renderer changes required — works with sigx's existing effect system.
1929
+ *
1930
+ * @example
1931
+ * ```tsx
1932
+ * import { component, useAsync } from 'sigx';
1933
+ *
1934
+ * const CodeEditor = component(({ signal: s }) => {
1935
+ * const libs = useAsync(async () => {
1936
+ * const { EditorView } = await import('@codemirror/view');
1937
+ * const { json } = await import('@codemirror/lang-json');
1938
+ * return { EditorView, json };
1939
+ * });
1940
+ *
1941
+ * return () => {
1942
+ * if (libs.loading) return <div class="skeleton" />;
1943
+ * if (libs.error) return <div class="error">{libs.error.message}</div>;
1944
+ * return <div ref={el => new libs.value!.EditorView({ parent: el })} />;
1945
+ * };
1946
+ * });
1947
+ * ```
1948
+ */
1949
+ /**
1950
+ * Load an async resource inside a component's setup function.
1951
+ *
1952
+ * Returns a reactive object with `value`, `loading`, and `error` fields.
1953
+ * The component's render function re-runs automatically when the state changes.
1954
+ *
1955
+ * @param loader — async function that returns the resource
1956
+ * @returns reactive AsyncState
1957
+ */
1279
1958
  function useAsync(loader) {
1280
1959
  const state = signal({
1281
1960
  value: null,
@@ -1295,7 +1974,38 @@ function useAsync(loader) {
1295
1974
  });
1296
1975
  return state;
1297
1976
  }
1298
- const ErrorBoundary = component((ctx) => {
1977
+ //#endregion
1978
+ //#region ../runtime-core/src/error-boundary.ts
1979
+ /**
1980
+ * ErrorBoundary component for catching render errors.
1981
+ *
1982
+ * Catches errors thrown during child component rendering and displays
1983
+ * a fallback UI. Works during both SSR and client-side rendering.
1984
+ *
1985
+ * @example
1986
+ * ```tsx
1987
+ * import { ErrorBoundary } from 'sigx';
1988
+ *
1989
+ * <ErrorBoundary
1990
+ * fallback={(error, retry) => (
1991
+ * <div>
1992
+ * <p>Something went wrong: {error.message}</p>
1993
+ * <button onClick={retry}>Retry</button>
1994
+ * </div>
1995
+ * )}
1996
+ * >
1997
+ * <RiskyComponent />
1998
+ * </ErrorBoundary>
1999
+ * ```
2000
+ */
2001
+ /**
2002
+ * ErrorBoundary component.
2003
+ *
2004
+ * Wraps children and catches errors thrown during rendering.
2005
+ * When an error occurs, displays the `fallback` UI.
2006
+ * Provides a `retry` function to reset and re-render children.
2007
+ */
2008
+ var ErrorBoundary = component((ctx) => {
1299
2009
  const { fallback } = ctx.props;
1300
2010
  const { slots } = ctx;
1301
2011
  const state = ctx.signal({
@@ -1323,6 +2033,8 @@ const ErrorBoundary = component((ctx) => {
1323
2033
  }
1324
2034
  };
1325
2035
  }, { name: "ErrorBoundary" });
2036
+ //#endregion
2037
+ //#region ../runtime-core/src/utils/index.ts
1326
2038
  var Utils = class {
1327
2039
  static isPromise(value) {
1328
2040
  return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
@@ -1334,13 +2046,17 @@ function guid$1() {
1334
2046
  return (c == "x" ? r : r & 3 | 8).toString(16);
1335
2047
  });
1336
2048
  }
1337
- const guid = guid$1;
1338
- let InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes) {
2049
+ //#endregion
2050
+ //#region ../runtime-core/src/models/index.ts
2051
+ var guid = guid$1;
2052
+ var InstanceLifetimes = /* @__PURE__ */ function(InstanceLifetimes) {
1339
2053
  InstanceLifetimes[InstanceLifetimes["Transient"] = 0] = "Transient";
1340
2054
  InstanceLifetimes[InstanceLifetimes["Scoped"] = 1] = "Scoped";
1341
2055
  InstanceLifetimes[InstanceLifetimes["Singleton"] = 2] = "Singleton";
1342
2056
  return InstanceLifetimes;
1343
2057
  }({});
2058
+ //#endregion
2059
+ //#region ../runtime-core/src/messaging/index.ts
1344
2060
  function createTopic(_options) {
1345
2061
  let subscribers = [];
1346
2062
  const publish = (data) => {
@@ -1369,6 +2085,8 @@ function createTopic(_options) {
1369
2085
  function toSubscriber(topic) {
1370
2086
  return { subscribe: (handler) => topic.subscribe(handler) };
1371
2087
  }
2088
+ //#endregion
2089
+ //#region ../runtime-core/src/di/factory.ts
1372
2090
  var SubscriptionHandler = class {
1373
2091
  constructor() {
1374
2092
  this.unsubs = [];
@@ -1408,6 +2126,21 @@ function defineFactory(setup, _lifetime, _typeIdentifier) {
1408
2126
  if (setup.length <= 1) return defineInjectable(() => factoryCreator());
1409
2127
  return factoryCreator;
1410
2128
  }
2129
+ //#endregion
2130
+ //#region ../runtime-core/src/utils/props-accessor.ts
2131
+ /**
2132
+ * Creates a props accessor - a simple reactive proxy for props.
2133
+ * Use destructuring with defaults for optional props.
2134
+ *
2135
+ * @example
2136
+ * ```ts
2137
+ * // In component setup:
2138
+ * const { count = 0, label = 'Default' } = ctx.props;
2139
+ *
2140
+ * // Or spread to forward props
2141
+ * <ChildComponent {...ctx.props} />
2142
+ * ```
2143
+ */
1411
2144
  function createPropsAccessor(reactiveProps) {
1412
2145
  return new Proxy(reactiveProps, {
1413
2146
  get(target, key) {
@@ -1431,6 +2164,39 @@ function createPropsAccessor(reactiveProps) {
1431
2164
  }
1432
2165
  });
1433
2166
  }
2167
+ //#endregion
2168
+ //#region ../runtime-core/src/utils/slots.ts
2169
+ /**
2170
+ * Slots system for component children.
2171
+ * Supports default and named slots with reactivity.
2172
+ */
2173
+ /**
2174
+ * Create slots object from children and slots prop.
2175
+ * Uses a version signal to trigger re-renders when children change.
2176
+ *
2177
+ * Supports named slots via:
2178
+ * - `slots` prop object (e.g., `slots={{ header: () => <div>...</div> }}`)
2179
+ * - `slot` prop on children (e.g., `<div slot="header">...</div>`)
2180
+ *
2181
+ * @example
2182
+ * ```tsx
2183
+ * // Parent component
2184
+ * <Card slots={{ header: () => <h1>Title</h1> }}>
2185
+ * <p>Default content</p>
2186
+ * <span slot="footer">Footer text</span>
2187
+ * </Card>
2188
+ *
2189
+ * // Card component setup
2190
+ * const slots = createSlots(children, slotsFromProps);
2191
+ * return () => (
2192
+ * <div>
2193
+ * {slots.header()}
2194
+ * {slots.default()}
2195
+ * {slots.footer()}
2196
+ * </div>
2197
+ * );
2198
+ * ```
2199
+ */
1434
2200
  function createSlots(children, slotsFromProps) {
1435
2201
  const versionSignal = signal({ v: 0 });
1436
2202
  function extractNamedSlotsFromChildren(c) {
@@ -1451,7 +2217,7 @@ function createSlots(children, slotsFromProps) {
1451
2217
  namedSlots
1452
2218
  };
1453
2219
  }
1454
- const slotsObj = {
2220
+ return new Proxy({
1455
2221
  _children: children,
1456
2222
  _slotsFromProps: slotsFromProps || {},
1457
2223
  _version: versionSignal,
@@ -1462,8 +2228,7 @@ function createSlots(children, slotsFromProps) {
1462
2228
  const { defaultChildren } = extractNamedSlotsFromChildren(c);
1463
2229
  return defaultChildren.filter((child) => child != null && child !== false && child !== true);
1464
2230
  }
1465
- };
1466
- return new Proxy(slotsObj, { get(target, prop) {
2231
+ }, { get(target, prop) {
1467
2232
  if (prop in target) return target[prop];
1468
2233
  if (typeof prop === "string") return function(scopedProps) {
1469
2234
  target._version.v;
@@ -1477,6 +2242,39 @@ function createSlots(children, slotsFromProps) {
1477
2242
  };
1478
2243
  } });
1479
2244
  }
2245
+ //#endregion
2246
+ //#region ../runtime-core/src/utils/normalize.ts
2247
+ /**
2248
+ * VNode normalization utilities.
2249
+ * Converts render results into proper VNode structures.
2250
+ */
2251
+ /**
2252
+ * Normalize render result to a VNode (wrapping arrays in Fragment).
2253
+ * Handles null, undefined, false, true by returning an empty Text node.
2254
+ *
2255
+ * This is used to normalize the return value of component render functions
2256
+ * into a consistent VNode structure for the renderer to process.
2257
+ *
2258
+ * @example
2259
+ * ```ts
2260
+ * // Conditional rendering returns null/false
2261
+ * normalizeSubTree(null) // → empty Text node
2262
+ * normalizeSubTree(false) // → empty Text node
2263
+ *
2264
+ * // Arrays become Fragments
2265
+ * normalizeSubTree([<A/>, <B/>]) // → Fragment with children
2266
+ *
2267
+ * // Primitives become Text nodes
2268
+ * normalizeSubTree("hello") // → Text node
2269
+ * normalizeSubTree(42) // → Text node
2270
+ *
2271
+ * // Computed signals are auto-unwrapped
2272
+ * normalizeSubTree(computed(() => "hi")) // → Text node with "hi"
2273
+ *
2274
+ * // VNodes pass through
2275
+ * normalizeSubTree(<div/>) // → same VNode
2276
+ * ```
2277
+ */
1480
2278
  function normalizeSubTree(result) {
1481
2279
  if (result == null || result === false || result === true) return {
1482
2280
  type: Text,
@@ -1504,14 +2302,41 @@ function normalizeSubTree(result) {
1504
2302
  };
1505
2303
  return result;
1506
2304
  }
1507
- const CLIENT_DIRECTIVE_PREFIX = "client:";
1508
- const CLIENT_DIRECTIVES = [
2305
+ //#endregion
2306
+ //#region ../runtime-core/src/hydration/index.ts
2307
+ /**
2308
+ * Hydration utilities for SSR
2309
+ *
2310
+ * These utilities are shared between server-side rendering (stream.ts)
2311
+ * and client-side hydration (hydrate.ts). They are placed in runtime-core
2312
+ * to allow any SSR implementation to use them.
2313
+ *
2314
+ * @module
2315
+ */
2316
+ /**
2317
+ * Client directive prefix used for selective hydration
2318
+ */
2319
+ var CLIENT_DIRECTIVE_PREFIX = "client:";
2320
+ /**
2321
+ * Valid client directive names
2322
+ */
2323
+ var CLIENT_DIRECTIVES = [
1509
2324
  "client:load",
1510
2325
  "client:idle",
1511
2326
  "client:visible",
1512
2327
  "client:media",
1513
2328
  "client:only"
1514
2329
  ];
2330
+ /**
2331
+ * Create an emit function for component context.
2332
+ * This is a common pattern used in both mountComponent and hydrateComponent.
2333
+ *
2334
+ * @example
2335
+ * ```ts
2336
+ * const emit = createEmit(reactiveProps);
2337
+ * emit('click', eventData); // Calls props.onClick(eventData)
2338
+ * ```
2339
+ */
1515
2340
  function createEmit(reactiveProps) {
1516
2341
  return (event, ...args) => {
1517
2342
  const eventName = `on${event[0].toUpperCase() + event.slice(1)}`;
@@ -1519,6 +2344,8 @@ function createEmit(reactiveProps) {
1519
2344
  if (handler && typeof handler === "function") handler(...args);
1520
2345
  };
1521
2346
  }
2347
+ //#endregion
2348
+ //#region ../runtime-core/src/renderer.ts
1522
2349
  function createRenderer(options) {
1523
2350
  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, patchDirective: hostPatchDirective, onElementMounted: hostOnElementMounted, onElementUnmounted: hostOnElementUnmounted, getActiveElement: hostGetActiveElement, restoreFocus: hostRestoreFocus } = options;
1524
2351
  let currentAppContext = null;
@@ -1801,6 +2628,9 @@ function createRenderer(options) {
1801
2628
  newChildren.forEach((c) => c.parent = newVNode);
1802
2629
  reconcileChildrenArray(container, oldChildren, newChildren, parentIsSVG);
1803
2630
  }
2631
+ /**
2632
+ * Check for duplicate keys in an array of VNodes and warn in development.
2633
+ */
1804
2634
  function checkDuplicateKeys(children) {
1805
2635
  if (process.env.NODE_ENV === "production") return;
1806
2636
  const seenKeys = /* @__PURE__ */ new Set();
@@ -1834,14 +2664,14 @@ function createRenderer(options) {
1834
2664
  } else if (isSameVNode(oldStartVNode, newEndVNode)) {
1835
2665
  patch(oldStartVNode, newEndVNode, parent);
1836
2666
  const nodeToMove = oldStartVNode.dom;
1837
- const anchor = hostNextSibling(oldEndVNode.dom);
2667
+ const anchor = oldEndVNode.dom ? hostNextSibling(oldEndVNode.dom) : null;
1838
2668
  if (nodeToMove) hostInsert(nodeToMove, parent, anchor);
1839
2669
  oldStartVNode = oldChildren[++oldStartIdx];
1840
2670
  newEndVNode = newChildren[--newEndIdx];
1841
2671
  } else if (isSameVNode(oldEndVNode, newStartVNode)) {
1842
2672
  patch(oldEndVNode, newStartVNode, parent);
1843
2673
  const nodeToMove = oldEndVNode.dom;
1844
- const anchor = oldStartVNode.dom;
2674
+ const anchor = oldStartVNode.dom ?? null;
1845
2675
  if (nodeToMove) hostInsert(nodeToMove, parent, anchor);
1846
2676
  oldEndVNode = oldChildren[--oldEndIdx];
1847
2677
  newStartVNode = newChildren[++newStartIdx];
@@ -1853,12 +2683,12 @@ function createRenderer(options) {
1853
2683
  patch(vnodeToMove, newStartVNode, parent);
1854
2684
  oldChildren[idxInOld] = void 0;
1855
2685
  if (vnodeToMove.dom && oldStartVNode.dom) hostInsert(vnodeToMove.dom, parent, oldStartVNode.dom);
1856
- } else mount(newStartVNode, parent, oldStartVNode.dom, parentIsSVG);
2686
+ } else mount(newStartVNode, parent, oldStartVNode.dom ?? null, parentIsSVG);
1857
2687
  newStartVNode = newChildren[++newStartIdx];
1858
2688
  }
1859
2689
  if (oldStartIdx > oldEndIdx) {
1860
2690
  if (newStartIdx <= newEndIdx) {
1861
- const anchor = newChildren[newEndIdx + 1] == null ? null : newChildren[newEndIdx + 1].dom;
2691
+ const anchor = newChildren[newEndIdx + 1] == null ? null : newChildren[newEndIdx + 1].dom ?? null;
1862
2692
  for (let i = newStartIdx; i <= newEndIdx; i++) mount(newChildren[i], parent, anchor, parentIsSVG);
1863
2693
  }
1864
2694
  } else if (newStartIdx > newEndIdx) {
@@ -2020,8 +2850,10 @@ function createRenderer(options) {
2020
2850
  mountComponent
2021
2851
  };
2022
2852
  }
2853
+ //#endregion
2854
+ //#region ../runtime-terminal/src/focus.ts
2023
2855
  var focusableIds = /* @__PURE__ */ new Set();
2024
- const focusState = signal({ activeId: null });
2856
+ var focusState = signal({ activeId: null });
2025
2857
  function registerFocusable(id) {
2026
2858
  focusableIds.add(id);
2027
2859
  if (focusState.activeId === null) focusState.activeId = id;
@@ -2046,6 +2878,8 @@ function focusPrev() {
2046
2878
  const ids = Array.from(focusableIds);
2047
2879
  focusState.activeId = ids[((focusState.activeId ? ids.indexOf(focusState.activeId) : -1) - 1 + ids.length) % ids.length];
2048
2880
  }
2881
+ //#endregion
2882
+ //#region ../runtime-terminal/src/utils.ts
2049
2883
  function getColorCode(color) {
2050
2884
  switch (color) {
2051
2885
  case "red": return "\x1B[31m";
@@ -2073,7 +2907,10 @@ function getBackgroundColorCode(color) {
2073
2907
  function stripAnsi(str) {
2074
2908
  return str.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
2075
2909
  }
2076
- const Input = component(({ props, emit }) => {
2910
+ //#endregion
2911
+ //#region ../runtime-terminal/src/components/Input.tsx
2912
+ /** @jsxImportSource @sigx/runtime-core */
2913
+ var Input = component(({ props, emit }) => {
2077
2914
  const id = Math.random().toString(36).slice(2);
2078
2915
  let isReady = false;
2079
2916
  const isFocused = () => focusState.activeId === id;
@@ -2128,7 +2965,10 @@ const Input = component(({ props, emit }) => {
2128
2965
  });
2129
2966
  };
2130
2967
  }, { name: "Input" });
2131
- const ProgressBar = component(({ props }) => {
2968
+ //#endregion
2969
+ //#region ../runtime-terminal/src/components/ProgressBar.tsx
2970
+ /** @jsxImportSource @sigx/runtime-core */
2971
+ var ProgressBar = component(({ props }) => {
2132
2972
  return () => {
2133
2973
  const value = props.value || 0;
2134
2974
  const max = props.max || 100;
@@ -2144,7 +2984,10 @@ const ProgressBar = component(({ props }) => {
2144
2984
  return /* @__PURE__ */ jsx("box", { children: /* @__PURE__ */ jsx("text", { children: colorCode + barChar.repeat(filledLen) + emptyChar.repeat(emptyLen) + reset + ` ${Math.round(percentage * 100)}%` }) });
2145
2985
  };
2146
2986
  }, { name: "ProgressBar" });
2147
- const Button = component(({ props, emit }) => {
2987
+ //#endregion
2988
+ //#region ../runtime-terminal/src/components/Button.tsx
2989
+ /** @jsxImportSource @sigx/runtime-core */
2990
+ var Button = component(({ props, emit }) => {
2148
2991
  const id = Math.random().toString(36).slice(2);
2149
2992
  const isFocused = () => focusState.activeId === id;
2150
2993
  const pressed = signal({ value: false });
@@ -2187,7 +3030,10 @@ const Button = component(({ props, emit }) => {
2187
3030
  });
2188
3031
  };
2189
3032
  }, { name: "Button" });
2190
- const Checkbox = component(({ props, emit }) => {
3033
+ //#endregion
3034
+ //#region ../runtime-terminal/src/components/Checkbox.tsx
3035
+ /** @jsxImportSource @sigx/runtime-core */
3036
+ var Checkbox = component(({ props, emit }) => {
2191
3037
  const id = Math.random().toString(36).slice(2);
2192
3038
  const isFocused = () => focusState.activeId === id;
2193
3039
  const checked = () => !!props.model?.value;
@@ -2235,7 +3081,10 @@ const Checkbox = component(({ props, emit }) => {
2235
3081
  ] });
2236
3082
  };
2237
3083
  }, { name: "Checkbox" });
2238
- const Select = component(({ props, emit }) => {
3084
+ //#endregion
3085
+ //#region ../runtime-terminal/src/components/Select.tsx
3086
+ /** @jsxImportSource @sigx/runtime-core */
3087
+ var Select = component(({ props, emit }) => {
2239
3088
  const id = Math.random().toString(36).slice(2);
2240
3089
  let isReady = false;
2241
3090
  const isFocused = () => focusState.activeId === id;
@@ -2308,7 +3157,7 @@ const Select = component(({ props, emit }) => {
2308
3157
  }), descriptionElement] });
2309
3158
  };
2310
3159
  }, { name: "Select" });
2311
- const { render } = createRenderer({
3160
+ var { render } = createRenderer({
2312
3161
  patchProp: (el, key, prev, next) => {
2313
3162
  el.props[key] = next;
2314
3163
  scheduleRender();
@@ -2396,6 +3245,10 @@ function flushRender() {
2396
3245
  process.stdout.write(lines.join("\x1B[K\n") + "\x1B[K");
2397
3246
  process.stdout.write("\x1B[J");
2398
3247
  }
3248
+ /**
3249
+ * Check if a node has a box element as an immediate child.
3250
+ * This is used to determine if a component wrapper should be treated as a block element.
3251
+ */
2399
3252
  function hasBoxChild(node) {
2400
3253
  for (const child of node.children) if (child.tag === "box") return true;
2401
3254
  return false;
@@ -2532,6 +3385,15 @@ function renderTerminal(app, options = {}) {
2532
3385
  } };
2533
3386
  }
2534
3387
  var unmountFn = null;
3388
+ /**
3389
+ * Helper function to mount the terminal for CLI apps.
3390
+ * Returns a mount target that can be passed to defineApp().mount().
3391
+ *
3392
+ * @example
3393
+ * ```tsx
3394
+ * defineApp(MyApp).mount(mountTerminal());
3395
+ * ```
3396
+ */
2535
3397
  function mountTerminal(options = { clearConsole: true }) {
2536
3398
  return {
2537
3399
  mount: terminalMount,
@@ -2541,6 +3403,9 @@ function mountTerminal(options = { clearConsole: true }) {
2541
3403
  }
2542
3404
  };
2543
3405
  }
3406
+ /**
3407
+ * Exit the terminal app cleanly, restoring terminal state.
3408
+ */
2544
3409
  function exitTerminal() {
2545
3410
  if (unmountFn) {
2546
3411
  unmountFn();
@@ -2549,7 +3414,21 @@ function exitTerminal() {
2549
3414
  process.stdout.write("\x1B[?25h");
2550
3415
  process.stdout.write("\x1B[2J\x1B[H");
2551
3416
  }
2552
- const terminalMount = (component, options, appContext) => {
3417
+ /**
3418
+ * Mount function for Terminal environments.
3419
+ * Use this with defineApp().mount() to render to the terminal.
3420
+ *
3421
+ * @example
3422
+ * ```tsx
3423
+ * import { defineApp } from '@sigx/runtime-core';
3424
+ * import { terminalMount } from '@sigx/runtime-terminal';
3425
+ *
3426
+ * const app = defineApp(<Counter />);
3427
+ * app.use(loggingPlugin)
3428
+ * .mount({ clearConsole: true }, terminalMount);
3429
+ * ```
3430
+ */
3431
+ var terminalMount = (component, options, appContext) => {
2553
3432
  rootNode = {
2554
3433
  type: "root",
2555
3434
  props: {},
@@ -2577,6 +3456,7 @@ const terminalMount = (component, options, appContext) => {
2577
3456
  };
2578
3457
  };
2579
3458
  setDefaultMount(terminalMount);
3459
+ //#endregion
2580
3460
  export { Button, CLIENT_DIRECTIVES, CLIENT_DIRECTIVE_PREFIX, Checkbox, Comment, ComputedSymbol, ErrorBoundary, Fragment, Input, InstanceLifetimes, ProgressBar, Select, SigxError, SigxErrorCode, SubscriptionHandler, Suspense, Text, Utils, asyncSetupClientError, batch, component, compound, computed, createModel, createModelFromBinding, createTopic, defineApp, defineDirective, defineFactory, defineInjectable, defineProvide, detectAccess, effect, effectScope, exitTerminal, focus, focusNext, focusPrev, focusState, getComponentMeta, getCurrentInstance, guid, isComponent, isComputed, isDirective, isLazyComponent, isModel, isReactive, jsx, jsxDEV, jsxs, lazy, mountTargetNotFoundError, mountTerminal, noMountFunctionError, onCreated, onKey, onMounted, onUnmounted, onUpdated, provideInvalidInjectableError, provideOutsideSetupError, registerFocusable, render, renderNodeToLines, renderTargetNotFoundError, renderTerminal, signal, terminalMount, toRaw, toSubscriber, unregisterFocusable, untrack, useAppContext, useAsync, watch };
2581
3461
 
2582
3462
  //# sourceMappingURL=index.js.map