chispa 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -53,7 +53,7 @@ declare class Component<TProps extends Dict = any> {
53
53
  declare function component(factory: ComponentFactory<any>): (props?: any) => Component;
54
54
  declare function component<TProps extends Dict>(factory: ComponentFactory<TProps>): (props: TProps) => Component<TProps>;
55
55
  declare function onUnmount(unmountFn: () => void): void;
56
- type ItemFactoryFn<T, TProps = any> = (item: Signal<T>, index: Signal<number>, list: Signal<T[]>, props?: TProps) => ChispaContent;
56
+ type ItemFactoryFn<T, TProps = any> = (item: Signal<T>, index: Signal<number>, list: Signal<T[]>, props: TProps, key: any) => ChispaContent;
57
57
  type KeyFn<T> = (item: T, index: number) => any;
58
58
  declare class ComponentList<TItem = any, TProps extends Dict = any> {
59
59
  private readonly itemFactoryFn;
@@ -94,7 +94,7 @@ declare class ComponentList<TItem = any, TProps extends Dict = any> {
94
94
  declare function componentList<TItem>(itemFactoryFn: ItemFactoryFn<TItem, any>, keyFn: KeyFn<TItem>): (listSignal: Signal<TItem[]>, props?: any) => ComponentList<TItem>;
95
95
  declare function componentList<TItem, TProps extends Dict>(itemFactoryFn: ItemFactoryFn<TItem, TProps>, keyFn: KeyFn<TItem>): (listSignal: Signal<TItem[]>, props: TProps) => ComponentList<TItem, TProps>;
96
96
 
97
- type ExecutionKind = 'createComponent' | 'computed' | 'addReactivity';
97
+ type ExecutionKind = 'createComponent' | 'computed' | 'addReactivity' | 'injectSingleton';
98
98
  interface IDisposable {
99
99
  dispose: () => void;
100
100
  }
@@ -139,6 +139,7 @@ type WithSignals<T> = {
139
139
  };
140
140
  declare abstract class Signal<T> {
141
141
  protected abstract value: T;
142
+ abstract readonly initialValue: T;
142
143
  protected contexts: Set<Reactivity>;
143
144
  constructor();
144
145
  get(): T;
@@ -201,4 +202,48 @@ declare const ChispaDebugConfig: {
201
202
  enableReactivityWarnings: boolean;
202
203
  };
203
204
 
204
- export { type ChispaContent, type ChispaContentReactive, ChispaDebugConfig, type ChispaNodeBuilderProps, type ChispaNodeBuilderPropsReactive, type ChispaReactive, Component, type ComponentFactory, ComponentList, Link, type LinkProps, type Route, Router, type SelectOption, Signal, WritableSignal, appendChild, bindControlledCheckbox, bindControlledInput, bindControlledSelect, component, componentList, computed, effect, getItem, getValidProps, globalContext, isSignal, isWriteableSignal, navigate, onUnmount, pathMatches, setAttributes, setProps, signal };
205
+ type Constructor<T> = new (...args: any[]) => T;
206
+ /**
207
+ * A typed token that can be used to inject values or interfaces that are not
208
+ * tied to a concrete class constructor.
209
+ *
210
+ * @example
211
+ * const API_URL = new InjectionToken<string>('API_URL');
212
+ * provide(API_URL, () => 'https://api.example.com');
213
+ * const url = inject(API_URL); // string
214
+ */
215
+ declare class InjectionToken<T> {
216
+ readonly description: string;
217
+ constructor(description: string);
218
+ }
219
+ type Token<T> = Constructor<T> | InjectionToken<T>;
220
+ /**
221
+ * Registers a factory function for the given token. The factory is called
222
+ * at most once (the result is cached as a singleton). Must be called before
223
+ * the first `inject(token)` call for that token.
224
+ */
225
+ declare function provide<T>(token: Token<T>, factory: () => T): void;
226
+ interface InjectOptions {
227
+ /**
228
+ * When `true`, a new instance is created every time and is NOT added to the
229
+ * singleton cache. Any reactive effects created in the service constructor
230
+ * will be registered to the currently mounting component and disposed when
231
+ * it unmounts.
232
+ */
233
+ local?: boolean;
234
+ }
235
+ /**
236
+ * Injects (or lazily creates) the singleton service associated with `token`.
237
+ * Any reactive effects declared inside the service constructor will NOT be
238
+ * disposed when the component that first triggers the injection is unmounted.
239
+ *
240
+ * Pass `{ local: true }` to get a fresh, component-scoped instance instead:
241
+ * effects will be disposed together with the component.
242
+ */
243
+ declare function inject<T>(token: Token<T>, options?: InjectOptions): T;
244
+ /**
245
+ * Resets the entire service container. Useful for test isolation.
246
+ */
247
+ declare function resetServices(): void;
248
+
249
+ export { type ChispaContent, type ChispaContentReactive, ChispaDebugConfig, type ChispaNodeBuilderProps, type ChispaNodeBuilderPropsReactive, type ChispaReactive, Component, type ComponentFactory, ComponentList, InjectionToken, Link, type LinkProps, type Route, Router, type SelectOption, Signal, WritableSignal, appendChild, bindControlledCheckbox, bindControlledInput, bindControlledSelect, component, componentList, computed, effect, getItem, getValidProps, globalContext, inject, isSignal, isWriteableSignal, navigate, onUnmount, pathMatches, provide, resetServices, setAttributes, setProps, signal };
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ var AppContext = class {
18
18
  this.componentStack.pop();
19
19
  }
20
20
  getCurrentComponent() {
21
+ if (this.executionStack.includes("injectSingleton")) return null;
21
22
  if (this.componentStack.length === 0) {
22
23
  return null;
23
24
  }
@@ -143,7 +144,7 @@ var Signal = class {
143
144
  }
144
145
  get() {
145
146
  if (!globalContext.canReadSignal()) {
146
- throw new Error("Cannot read a signal value during component creation. Did you mean to use a computed signal instead?");
147
+ throw new Error("Cannot read a signal value during component creation. Consider using a computed signal or an effect instead.");
147
148
  }
148
149
  const ctx = globalContext.getCurrentRenderContext();
149
150
  if (ctx) {
@@ -189,11 +190,13 @@ var WritableSignal = class extends Signal {
189
190
  };
190
191
  var ComputedSignal = class extends Signal {
191
192
  value;
193
+ initialValue;
192
194
  computeFn;
193
195
  constructor(computeFn) {
194
196
  super();
195
197
  globalContext.pushExecutionStack("computed");
196
198
  this.value = computeFn();
199
+ this.initialValue = this.value;
197
200
  globalContext.popExecutionStack();
198
201
  this.computeFn = computeFn;
199
202
  }
@@ -362,7 +365,7 @@ var ComponentList = class {
362
365
  const factory = (props) => {
363
366
  const item = computed(() => this.itemsSignal.get().find((v, index2) => this.keyFn(v, index2) === key));
364
367
  const index = computed(() => this.itemsSignal.get().findIndex((v, index2) => this.keyFn(v, index2) === key));
365
- return this.itemFactoryFn ? this.itemFactoryFn(item, index, this.itemsSignal, props) : null;
368
+ return this.itemFactoryFn ? this.itemFactoryFn(item, index, this.itemsSignal, props, key) : null;
366
369
  };
367
370
  const component2 = new Component(factory, key, this.props);
368
371
  this.components.set(key, component2);
@@ -907,8 +910,76 @@ var Link = component((props) => {
907
910
  setProps(a, rest);
908
911
  return a;
909
912
  });
913
+
914
+ // src/injection.ts
915
+ var InjectionToken = class {
916
+ constructor(description) {
917
+ this.description = description;
918
+ }
919
+ };
920
+ var ServiceContainer = class {
921
+ services = /* @__PURE__ */ new Map();
922
+ factories = /* @__PURE__ */ new Map();
923
+ provide(token, factory) {
924
+ if (this.services.has(token)) {
925
+ const name = token instanceof InjectionToken ? `"${token.description}"` : token.name;
926
+ throw new Error(`Cannot call provide() for ${name} after it has already been injected.`);
927
+ }
928
+ this.factories.set(token, factory);
929
+ }
930
+ get(token) {
931
+ if (this.services.has(token)) {
932
+ return this.services.get(token);
933
+ }
934
+ let service;
935
+ globalContext.pushExecutionStack("injectSingleton");
936
+ try {
937
+ service = this.createInstance(token);
938
+ } finally {
939
+ globalContext.popExecutionStack();
940
+ }
941
+ this.services.set(token, service);
942
+ return service;
943
+ }
944
+ /**
945
+ * Creates a fresh, non-cached instance of the token's service.
946
+ * Runs inside the current component context so that any effects created
947
+ * in the constructor are bound to (and disposed with) that component.
948
+ */
949
+ getLocal(token) {
950
+ return this.createInstance(token);
951
+ }
952
+ createInstance(token) {
953
+ const factory = this.factories.get(token);
954
+ if (factory) {
955
+ return factory();
956
+ } else if (token instanceof InjectionToken) {
957
+ throw new Error(`No provider registered for InjectionToken "${token.description}"`);
958
+ } else {
959
+ return new token();
960
+ }
961
+ }
962
+ reset() {
963
+ this.services.clear();
964
+ this.factories.clear();
965
+ }
966
+ };
967
+ var services = new ServiceContainer();
968
+ function provide(token, factory) {
969
+ services.provide(token, factory);
970
+ }
971
+ function inject(token, options) {
972
+ if (options?.local) {
973
+ return services.getLocal(token);
974
+ }
975
+ return services.get(token);
976
+ }
977
+ function resetServices() {
978
+ services.reset();
979
+ }
910
980
  export {
911
981
  ChispaDebugConfig,
982
+ InjectionToken,
912
983
  Link,
913
984
  Router,
914
985
  appendChild,
@@ -922,11 +993,14 @@ export {
922
993
  getItem,
923
994
  getValidProps,
924
995
  globalContext,
996
+ inject,
925
997
  isSignal,
926
998
  isWriteableSignal,
927
999
  navigate,
928
1000
  onUnmount,
929
1001
  pathMatches,
1002
+ provide,
1003
+ resetServices,
930
1004
  setAttributes,
931
1005
  setProps,
932
1006
  signal
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/context.ts","../src/signals.ts","../src/components.ts","../src/builder.ts","../src/controlled-input.ts","../src/router.ts"],"sourcesContent":["export const ChispaDebugConfig = {\n\tenableReactivityWarnings: false,\n};\n","import { Component, ComponentList } from './components';\nimport { ChispaDebugConfig } from './config';\nimport { Signal } from './signals';\n\ntype ExecutionKind = 'createComponent' | 'computed' | 'addReactivity';\n\nexport interface IDisposable {\n\tdispose: () => void;\n}\n\nclass AppContext {\n\tprivate reactivityContextStack: Reactivity[] = [];\n\n\tprivate refreshTimeout: any = 0;\n\n\t//private contexts = new Set<RenderContext>();\n\n\tprivate dirtyReactivities = new Set<Reactivity>();\n\n\tprivate executionStack: ExecutionKind[] = [];\n\n\tprivate componentStack: (Component | ComponentList)[] = [];\n\n\tpushComponentStack(cmp: Component | ComponentList) {\n\t\tthis.componentStack.push(cmp);\n\t}\n\n\tpopComponentStack() {\n\t\tthis.componentStack.pop();\n\t}\n\n\tgetCurrentComponent() {\n\t\tif (this.componentStack.length === 0) {\n\t\t\t//console.warn('No current component');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.componentStack[this.componentStack.length - 1];\n\t}\n\n\tsetCurrentReactivityContext(context: Reactivity) {\n\t\tthis.reactivityContextStack.push(context);\n\t\t//this.contexts.add(context);\n\t}\n\n\trestorePreviousReactivityContext() {\n\t\tthis.reactivityContextStack.pop();\n\t}\n\n\tgetCurrentRenderContext() {\n\t\tif (this.reactivityContextStack.length === 0) {\n\t\t\t//console.warn('No current render context');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.reactivityContextStack[this.reactivityContextStack.length - 1];\n\t}\n\n\t// Maximum number of iterations to process during a scheduled refresh. Prevents\n\t// unbounded loops in case of uncontrolled reactivity cascades. Use the\n\t// `globalContext.maxScheduleIterations` field to override in tests or\n\t// special cases.\n\tpublic maxScheduleIterations = 100;\n\n\tscheduleRefresh() {\n\t\tif (this.refreshTimeout) {\n\t\t\tclearTimeout(this.refreshTimeout);\n\t\t}\n\t\tthis.refreshTimeout = setTimeout(() => {\n\t\t\tlet iteration = 0;\n\t\t\t// Process dirty contexts until none remain, or until the iteration limit\n\t\t\t// is reached (this avoids infinite loops when reactivities keep\n\t\t\t// re-adding themselves or each other).\n\t\t\twhile (this.dirtyReactivities.size > 0 && iteration < this.maxScheduleIterations) {\n\t\t\t\titeration++;\n\t\t\t\tconst dirtyContexts = Array.from(this.dirtyReactivities);\n\t\t\t\tdirtyContexts.forEach((ctx) => ctx.process());\n\t\t\t}\n\n\t\t\tif (this.dirtyReactivities.size > 0) {\n\t\t\t\t// Warn once if we stopped early due to the iteration limit. We also\n\t\t\t\t// clear the set to avoid repeated warnings and to avoid leaving the\n\t\t\t\t// system in a permanently spinning state.\n\t\t\t\tconsole.warn(`[AppContext.scheduleRefresh] possible uncontrolled reactivity cascade: processed ${iteration} iterations — aborting.`);\n\t\t\t\tthis.dirtyReactivities.clear();\n\t\t\t}\n\t\t}, 0);\n\t}\n\n\taddReactivity(executor: () => void) {\n\t\tconst ctx = new Reactivity(executor);\n\t\tglobalContext.pushExecutionStack('addReactivity');\n\t\tctx.exec();\n\t\tglobalContext.popExecutionStack();\n\t\treturn ctx;\n\t}\n\n\tcreateRoot(component: () => Component, mountPoint: HTMLElement) {\n\t\tthis.dirtyReactivities.clear();\n\t\tmountPoint.innerHTML = '';\n\t\tconst cmp = component();\n\t\tcmp.mount(mountPoint, null);\n\t}\n\n\tcanReadSignal() {\n\t\tconst length = this.executionStack.length;\n\t\tif (length === 0) return true;\n\t\tconst current = this.executionStack[length - 1];\n\t\treturn current !== 'createComponent';\n\t}\n\n\tpushExecutionStack(type: ExecutionKind) {\n\t\tthis.executionStack.push(type);\n\t}\n\n\tpopExecutionStack() {\n\t\tthis.executionStack.pop();\n\t}\n\n\taddDirtyContext(ctx: Reactivity) {\n\t\tthis.dirtyReactivities.add(ctx);\n\t}\n\n\tremoveDirtyContext(ctx: Reactivity) {\n\t\tthis.dirtyReactivities.delete(ctx);\n\t}\n}\n\nexport class Reactivity implements IDisposable {\n\tprivate dirty: boolean = false;\n\n\tprivate signals = new Set<Signal<any>>();\n\n\tconstructor(private readonly action: () => void) {\n\t\tconst currentComponent = globalContext.getCurrentComponent();\n\t\tif (currentComponent) {\n\t\t\tcurrentComponent.addDisposable(this);\n\t\t} else {\n\t\t\tif (ChispaDebugConfig.enableReactivityWarnings) {\n\t\t\t\tconsole.warn('Creating a Reactivity outside of a component');\n\t\t\t}\n\t\t}\n\t}\n\n\tmarkDirty() {\n\t\tthis.dirty = true;\n\t\tglobalContext.addDirtyContext(this);\n\t\tglobalContext.scheduleRefresh();\n\t}\n\n\taddSignal(signal: Signal<any>) {\n\t\tthis.signals.add(signal);\n\t}\n\n\tremoveSignal(signal: Signal<any>) {\n\t\tthis.signals.delete(signal);\n\t}\n\n\tprocess() {\n\t\tif (!this.dirty) return;\n\t\tthis.exec();\n\t\t//console.log('re-render cycle completed');\n\t\tthis.dirty = false;\n\t\tglobalContext.removeDirtyContext(this);\n\t}\n\n\texec() {\n\t\tthis.signals.forEach((s) => s.removeContext(this));\n\t\tthis.signals.clear();\n\t\tglobalContext.setCurrentReactivityContext(this);\n\t\tthis.action();\n\t\tglobalContext.restorePreviousReactivityContext();\n\t}\n\n\tdispose() {\n\t\tthis.signals.forEach((s) => s.removeContext(this));\n\t\tthis.signals.clear();\n\t\tthis.dirty = false;\n\t\tglobalContext.removeDirtyContext(this);\n\t}\n}\n\nexport const globalContext = new AppContext();\n","import { globalContext, Reactivity } from './context';\n\ntype WithSignals<T> = { [K in keyof T]: Signal<T[K]> };\n\nabstract class Signal<T> {\n\tprotected abstract value: T;\n\n\tprotected contexts: Set<Reactivity> = new Set();\n\n\tconstructor() {}\n\n\tget() {\n\t\tif (!globalContext.canReadSignal()) {\n\t\t\tthrow new Error('Cannot read a signal value during component creation. Did you mean to use a computed signal instead?');\n\t\t}\n\t\t//context.current.register(this);\n\t\tconst ctx = globalContext.getCurrentRenderContext();\n\t\tif (ctx) {\n\t\t\tthis.contexts.add(ctx);\n\t\t\tctx.addSignal(this);\n\t\t}\n\t\treturn this.value;\n\t}\n\n\tpublic readonly computed = new Proxy(\n\t\t{},\n\t\t{\n\t\t\tget: (_, prop) => {\n\t\t\t\treturn computed(() => this.get()[prop as keyof T]);\n\t\t\t},\n\t\t}\n\t) as WithSignals<T>;\n\n\tremoveContext(ctx: Reactivity) {\n\t\tthis.contexts.delete(ctx);\n\t}\n\n\tdispose() {\n\t\t//console.log('disposing signal', this);\n\t\tthis.contexts.forEach((ctx) => {\n\t\t\tctx.removeSignal(this);\n\t\t});\n\t\tthis.contexts.clear();\n\t}\n}\n\nclass WritableSignal<T> extends Signal<T> {\n\tprotected override value: T;\n\n\tpublic readonly initialValue: T;\n\n\tconstructor(initialValue: T) {\n\t\tsuper();\n\t\tthis.initialValue = initialValue;\n\t\tthis.value = initialValue;\n\t}\n\n\tset(newValue: T) {\n\t\tthis.value = newValue;\n\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t}\n\n\tupdate(updater: (value: T) => T) {\n\t\tthis.value = updater(this.value);\n\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t}\n}\n\nclass ComputedSignal<T> extends Signal<T> {\n\tprotected override value: T;\n\n\tprivate computeFn: () => T;\n\n\tconstructor(computeFn: () => T) {\n\t\tsuper();\n\t\tglobalContext.pushExecutionStack('computed');\n\t\tthis.value = computeFn();\n\t\tglobalContext.popExecutionStack();\n\t\tthis.computeFn = computeFn;\n\t}\n\n\trecompute() {\n\t\tconst newValue = this.computeFn();\n\t\tif (newValue !== this.value) {\n\t\t\tthis.value = newValue;\n\t\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t\t}\n\t}\n}\n\nexport function isSignal(value: any): value is Signal<any> {\n\treturn value instanceof Signal;\n}\n\nexport function isWriteableSignal<T>(value: Signal<T>): value is WritableSignal<T> {\n\treturn value instanceof WritableSignal;\n}\n\nexport function signal<T>(initialValue: T) {\n\tconst sig = new WritableSignal(initialValue);\n\n\t// // Creamos una función que se usará como callable\n\t// const fn = (() => sig.get()) as any;\n\n\t// // Copiamos todas las propiedades y métodos de la instancia a la función\n\t// Object.setPrototypeOf(fn, sig.constructor.prototype);\n\n\t// // Copiamos las propiedades de instancia\n\t// Object.assign(fn, this);\n\n\t// // Retornamos la función como si fuera la instancia\n\t// return fn as WritableSignal<T> & (() => T);\n\n\treturn sig;\n}\n\nexport function computed<T>(fn: () => T) {\n\tlet sig: ComputedSignal<T>;\n\tconst ctx = new Reactivity(() => {\n\t\tsig.recompute();\n\t});\n\tglobalContext.setCurrentReactivityContext(ctx);\n\tsig = new ComputedSignal(fn);\n\tglobalContext.restorePreviousReactivityContext();\n\n\treturn sig as Signal<T>;\n}\n\nexport function effect(fn: () => void) {\n\tglobalContext.addReactivity(fn);\n}\n\nexport type { Signal, WritableSignal };\n","import { ChispaContent } from './builder';\nimport { globalContext, IDisposable } from './context';\nimport { computed, Signal, WritableSignal } from './signals';\n\nexport type Dict = Record<string, any>;\nexport type ComponentFactory<TProps extends Dict> = (props: TProps) => ChispaContent;\n\nexport class Component<TProps extends Dict = any> {\n\tpublic nodes: Node[] | null = null;\n\n\tprivate container: Node | null = null;\n\n\tprivate anchor: Node | null = null;\n\n\tprivate disposables: IDisposable[] = [];\n\n\tpublic silent = true;\n\n\tconstructor(\n\t\tprivate readonly factoryFn: ComponentFactory<TProps>,\n\t\tpublic readonly key: any = null,\n\t\tpublic readonly props: TProps | null = null\n\t) {}\n\n\tmount(container: Node, anchor: Node | null = null) {\n\t\tif (!this.silent) console.log('Mounting Component', this);\n\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\n\n\t\t// If mounting within another component, register for automatic unmounting\n\t\tconst parentComponent = globalContext.getCurrentComponent();\n\t\tif (parentComponent && parentComponent !== this) {\n\t\t\tparentComponent.addDisposable({\n\t\t\t\tdispose: () => this.unmount(),\n\t\t\t});\n\t\t}\n\n\t\tglobalContext.pushExecutionStack('createComponent');\n\t\tglobalContext.pushComponentStack(this);\n\t\tconst node = this.factoryFn ? (this.factoryFn as any)(this.props) : null;\n\t\tglobalContext.popComponentStack();\n\t\tglobalContext.popExecutionStack();\n\t\t// if node is fragment, convert to array of nodes\n\t\tif (node) {\n\t\t\tif (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n\t\t\t\tthis.nodes = Array.from(node.childNodes);\n\t\t\t} else {\n\t\t\t\tthis.nodes = [node];\n\t\t\t}\n\t\t} else {\n\t\t\tthis.nodes = null;\n\t\t}\n\t\tthis.insertNodes();\n\t}\n\n\treanchor(anchor: Node | null) {\n\t\tthis.anchor = anchor;\n\n\t\t//console.log('reanchoring', this.nodes, ' before anchor', this.anchor);\n\t\tthis.insertNodes();\n\t}\n\n\tprivate insertNodes() {\n\t\tif (!this.container || !this.nodes) return;\n\t\t// Insertar en la nueva posición\n\t\tfor (const node of this.nodes) {\n\t\t\tif (this.anchor) {\n\t\t\t\tthis.container.insertBefore(node, this.anchor);\n\t\t\t} else {\n\t\t\t\tthis.container.appendChild(node);\n\t\t\t}\n\t\t}\n\t}\n\n\taddDisposable(disposable: IDisposable) {\n\t\tthis.disposables.push(disposable);\n\t}\n\n\tunmount() {\n\t\tif (!this.silent) console.log('Unmounting Component', this);\n\n\t\tif (this.nodes) {\n\t\t\tthis.nodes.forEach((node) => {\n\t\t\t\tif (node && node.parentNode) {\n\t\t\t\t\tnode.parentNode.removeChild(node);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.disposables.forEach((d) => {\n\t\t\td.dispose();\n\t\t});\n\t\tthis.disposables = [];\n\t\tthis.nodes = null;\n\t\tthis.container = null;\n\t\tthis.anchor = null;\n\t}\n}\n\n// Definimos overloads para component\nexport function component(factory: ComponentFactory<any>): (props?: any) => Component;\nexport function component<TProps extends Dict>(factory: ComponentFactory<TProps>): (props: TProps) => Component<TProps>;\n\nexport function component<TProps extends Dict = any>(factory: ComponentFactory<TProps>) {\n\treturn (props?: TProps) => {\n\t\treturn new Component(factory, null, props);\n\t};\n}\n\nexport function onUnmount(unmountFn: () => void) {\n\tconst currentComponent = globalContext.getCurrentComponent();\n\tif (currentComponent) {\n\t\tcurrentComponent.addDisposable({\n\t\t\tdispose: unmountFn,\n\t\t});\n\t} else {\n\t\tthrow new Error('onUnmount must be called within a component context');\n\t}\n}\n\ntype ItemFactoryFn<T, TProps = any> = (item: Signal<T>, index: Signal<number>, list: Signal<T[]>, props?: TProps) => ChispaContent;\ntype KeyFn<T> = (item: T, index: number) => any;\n\nexport class ComponentList<TItem = any, TProps extends Dict = any> {\n\tprivate readonly components: Map<string, Component<TProps>>;\n\tprivate container: Node | null = null; // Contenedor donde se montan los nodos\n\tprivate anchor: Node | null = null; // Nodes must be inserted before this node\n\tprivate currentKeys: any[] = [];\n\tpublic disposables: any[] = [];\n\n\tconstructor(\n\t\tprivate readonly itemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\t\tprivate readonly keyFn: KeyFn<TItem>,\n\t\tprivate readonly itemsSignal: Signal<TItem[]>,\n\t\tprivate readonly props: TProps | null = null\n\t) {\n\t\tthis.components = new Map();\n\t}\n\n\t/**\n\t * Obtiene todos los componentes\n\t */\n\tprivate getAllComponents(): Component[] {\n\t\treturn Array.from(this.components.values());\n\t}\n\n\t/**\n\t * Limpia todos los componentes\n\t */\n\tprivate clear(): void {\n\t\tArray.from(this.components.values()).forEach((component) => {\n\t\t\tthis.removeComponent(component);\n\t\t});\n\t}\n\n\t/**\n\t * Elimina un componente completo\n\t */\n\tprivate removeComponent(component: Component) {\n\t\tcomponent.unmount();\n\t\tif (component.key) {\n\t\t\tthis.components.delete(component.key);\n\t\t}\n\t}\n\n\t/**\n\t * Crea un nuevo componente\n\t */\n\tprivate createNewComponent(key: any): Component {\n\t\tconst factory = (props?: TProps) => {\n\t\t\tconst item = computed(() => this.itemsSignal.get().find((v, index) => this.keyFn(v, index) === key)!);\n\t\t\tconst index = computed(() => this.itemsSignal.get().findIndex((v, index) => this.keyFn(v, index) === key));\n\t\t\treturn this.itemFactoryFn ? this.itemFactoryFn(item, index, this.itemsSignal, props) : null;\n\t\t};\n\n\t\tconst component = new Component(factory, key, this.props);\n\t\tthis.components.set(key, component);\n\n\t\treturn component;\n\t}\n\n\tprivate getTargetAnchor(items: TItem[], index: number): Node | null {\n\t\tconst nextItem = index + 1 < items.length ? items[index + 1] : null;\n\t\tconst nextComp = nextItem ? this.components.get(this.keyFn(nextItem, index + 1)) : null;\n\t\tif (nextComp && nextComp.nodes) {\n\t\t\treturn nextComp.nodes[0];\n\t\t} else {\n\t\t\t// Es el último componente, debería insertarse antes del anchor original\n\t\t\treturn this.anchor;\n\t\t}\n\t}\n\n\t/**\n\t * Función principal que sincroniza los componentes DOM con un array de keys\n\t */\n\tprivate synchronizeComponents(): void {\n\t\tconst existingComponents = this.getAllComponents();\n\n\t\t// Identificar qué componentes eliminar (los que no están en keys)\n\t\tconst items = this.itemsSignal.get();\n\t\tconst keys = items.map((item, index) => this.keyFn(item, index));\n\t\tconst componentsToRemove = existingComponents.filter((component) => component.key && !keys.includes(component.key));\n\t\tcomponentsToRemove.forEach((component) => this.removeComponent(component));\n\n\t\tthis.currentKeys = this.currentKeys.filter((key) => keys.includes(key));\n\t\t//console.log('Current keys:', this.currentKeys, 'Target keys:', keys);\n\n\t\tif (!this.container) {\n\t\t\tconsole.warn('Container is null in synchronizeComponents');\n\t\t\treturn;\n\t\t}\n\t\t// Procesar cada key en el orden deseado\n\t\tconst container = this.container;\n\n\t\titems.forEach((item, index) => {\n\t\t\tconst targetKey = this.keyFn(item, index);\n\t\t\tconst currentKey = this.currentKeys[index];\n\t\t\tif (targetKey === currentKey) {\n\t\t\t\t// La key no ha cambiado de posición, no hacer nada\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst existingComponent = this.components.get(targetKey);\n\n\t\t\tif (existingComponent) {\n\t\t\t\tconst prevComp = this.components.get(currentKey);\n\t\t\t\tif (!prevComp || !prevComp.nodes) {\n\t\t\t\t\tconsole.warn('Previous component or its nodes not found for key', currentKey);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texistingComponent.reanchor(prevComp.nodes[0]);\n\t\t\t\t// Reordenar el array de keys actuales\n\t\t\t\tthis.currentKeys = this.currentKeys.filter((k) => k !== targetKey);\n\t\t\t\tthis.currentKeys.splice(index, 0, targetKey);\n\t\t\t} else {\n\t\t\t\t// El componente no existe, crearlo\n\t\t\t\tconst targetAnchor = this.getTargetAnchor(items, index);\n\t\t\t\tconst newComponent = this.createNewComponent(targetKey);\n\t\t\t\tnewComponent.mount(container, targetAnchor);\n\t\t\t\tthis.currentKeys.splice(index, 0, targetKey);\n\t\t\t}\n\t\t});\n\t}\n\n\tmount(container: Node, anchor: Node | null = null) {\n\t\t//console.log('Mounting ComponentList');\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\n\n\t\t// If mounting within another component, register for automatic unmounting\n\t\tconst parentComponent = globalContext.getCurrentComponent();\n\t\tif (parentComponent && parentComponent !== this) {\n\t\t\tparentComponent.addDisposable({\n\t\t\t\tdispose: () => this.unmount(),\n\t\t\t});\n\t\t}\n\n\t\tglobalContext.pushComponentStack(this);\n\t\tglobalContext.addReactivity(() => {\n\t\t\tthis.synchronizeComponents();\n\t\t});\n\t\tglobalContext.popComponentStack();\n\t}\n\n\taddDisposable(disposable: IDisposable) {\n\t\tthis.disposables.push(disposable);\n\t}\n\n\tunmount() {\n\t\t//console.log('Unmounting ComponentList');\n\t\tthis.clear();\n\t\tthis.container = null!;\n\t\tthis.anchor = null!;\n\t\tthis.disposables.forEach((d) => {\n\t\t\td.dispose();\n\t\t});\n\t}\n}\n\n// Definimos overloads para componentList\nexport function componentList<TItem>(\n\titemFactoryFn: ItemFactoryFn<TItem, any>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: Signal<TItem[]>, props?: any) => ComponentList<TItem>;\nexport function componentList<TItem, TProps extends Dict>(\n\titemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: Signal<TItem[]>, props: TProps) => ComponentList<TItem, TProps>;\n\nexport function componentList<TItem, TProps extends Dict = any>(itemFactoryFn: ItemFactoryFn<TItem, TProps>, keyFn: KeyFn<TItem>) {\n\treturn (listSignal: Signal<TItem[]>, props?: TProps) => {\n\t\tconst list = new ComponentList(itemFactoryFn, keyFn, listSignal, props);\n\t\treturn list;\n\t};\n}\n","import { Component, ComponentList } from './components';\nimport { globalContext } from './context';\nimport { computed, isSignal, type Signal } from './signals';\n\nexport type ChispaReactive<T> = T | Signal<T> | (() => T);\nexport type ChispaNode = string | number | Node | null;\nexport type ChispaContent = ChispaNode | Component | (ChispaNode | Component)[] | ComponentList;\nexport type ChispaContentReactive = ChispaReactive<ChispaContent>;\nexport type ChispaClasses = Record<string, ChispaReactive<boolean>>;\nexport type ChispaCSSPropertiesStrings = {\n\t[K in keyof CSSStyleDeclaration]?: ChispaReactive<string>;\n};\n\ntype EventPropKeys<T> = Extract<keyof T, `on${string}`>;\ntype AllowSignals<T> = { [K in keyof T]: ChispaReactive<T[K]> };\n\ntype ChispaNodeBuilderBaseProps<T> = AllowSignals<Omit<T, 'style' | 'dataset' | EventPropKeys<T>>> & Pick<T, EventPropKeys<T>>;\ninterface INodeBuilderSpecialProps {\n\taddClass?: ChispaReactive<string | string[]>;\n\tclasses?: ChispaClasses;\n\tstyle?: ChispaCSSPropertiesStrings;\n\tdataset?: Record<string, ChispaReactive<string>>;\n}\ninterface INodeBuilderAdditionalProps<T, TNodes> {\n\tnodes?: TNodes;\n\tinner?: ChispaContentReactive;\n\t_ref?: (node: T) => void | { current: T | null };\n}\nexport type ChispaNodeBuilderProps<T, TNodes> = Partial<ChispaNodeBuilderBaseProps<T>> & INodeBuilderAdditionalProps<T, TNodes> & INodeBuilderSpecialProps;\nexport type ChispaNodeBuilderPropsReactive<T, TNodes> = ChispaReactive<ChispaNodeBuilderProps<T, TNodes>>;\n\nconst forbiddenProps = ['nodes', 'inner', '_ref'];\n\nexport function getValidProps<T>(props: ChispaNodeBuilderProps<T, any>) {\n\tconst finalProps: any = {};\n\n\tfor (const propName in props) {\n\t\tif (!forbiddenProps.includes(propName)) {\n\t\t\tfinalProps[propName] = props[propName as keyof typeof props];\n\t\t}\n\t}\n\n\treturn finalProps as ChispaNodeBuilderProps<T, any>;\n}\n\nconst itemsStack: any[] = [];\nfunction findItemInStack(itemName: string): any {\n\tfor (const itemsDefs of itemsStack) {\n\t\tif (itemsDefs && itemsDefs[itemName]) {\n\t\t\treturn itemsDefs[itemName];\n\t\t}\n\t}\n\treturn null;\n}\n\nexport function getItem<T>(template: T, items: any, itemName: keyof T) {\n\titemsStack.unshift(items);\n\tconst item: any = findItemInStack(itemName as string);\n\n\tif (!item) {\n\t\titemsStack.shift();\n\t\treturn null;\n\t}\n\n\tlet res;\n\tif (item.constructor && item.constructor.name === 'Object' && !(item instanceof Element)) {\n\t\tconst Comp = template[itemName] as (props: any) => Element;\n\t\tconst itemProps = item;\n\n\t\tres = Comp(itemProps);\n\t} else {\n\t\tres = item;\n\t}\n\titemsStack.shift();\n\treturn res;\n}\n\nexport function setAttributes(node: Element, attributes: Record<string, string>) {\n\tfor (const attr in attributes) {\n\t\tconst attrValue = attributes[attr];\n\t\tif (attrValue === undefined || attrValue === null) {\n\t\t\tnode.removeAttribute(attr);\n\t\t\tcontinue;\n\t\t}\n\t\tnode.setAttribute(attr, attrValue);\n\t}\n}\n\nfunction isEventProp(prop: string) {\n\treturn prop.startsWith('on');\n}\n\nfunction getPropValue(props: any, prop: string) {\n\tconst propValue = props[prop];\n\tif (typeof propValue === 'function' && !isEventProp(prop)) {\n\t\treturn computed(propValue);\n\t}\n\treturn propValue;\n}\n\nexport function setProps<T extends Element>(node: T, props: ChispaNodeBuilderPropsReactive<T, any>) {\n\tlet _props = props;\n\tif (typeof _props === 'function') {\n\t\t_props = computed(_props);\n\t}\n\tif (isSignal(_props)) {\n\t\tglobalContext.addReactivity(() => {\n\t\t\tsetProps(node, _props.get());\n\t\t});\n\t\treturn;\n\t}\n\n\tprops = getValidProps(_props);\n\n\tif (node instanceof HTMLElement) {\n\t\tsetSpecialProps(node, props);\n\t}\n\n\tfor (const prop in props) {\n\t\tconst propValue = getPropValue(props, prop);\n\t\t//console.log('setting prop', prop, propValue )\n\t\tif (isSignal(propValue)) {\n\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t(node as any)[prop] = propValue.get();\n\t\t\t});\n\t\t} else if (propValue === undefined) {\n\t\t\tcontinue;\n\t\t} else {\n\t\t\t(node as any)[prop] = propValue;\n\t\t}\n\t}\n}\n\nfunction parseAddClassProp(value: string | string[]): string[] {\n\tconst arr = typeof value === 'string' ? value.split(' ') : value;\n\treturn arr.filter((c) => c.trim() !== '');\n}\n\nfunction setSpecialProps<T extends HTMLElement>(node: T, props: INodeBuilderSpecialProps) {\n\tif (props.style !== undefined) {\n\t\tconst style = props.style;\n\t\tfor (const styleKey in style) {\n\t\t\tlet styleValue = style[styleKey]!;\n\t\t\tif (typeof styleValue === 'function') {\n\t\t\t\tstyleValue = computed(styleValue);\n\t\t\t}\n\t\t\tif (isSignal(styleValue)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tnode.style[styleKey] = styleValue.get();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnode.style[styleKey] = styleValue;\n\t\t\t}\n\t\t}\n\t\tdelete props.style;\n\t}\n\n\tif (props.addClass !== undefined) {\n\t\tlet addClass = props.addClass;\n\t\tlet prevClass: string[] | null = null;\n\n\t\tif (typeof addClass === 'function') {\n\t\t\taddClass = computed(addClass);\n\t\t}\n\n\t\tif (isSignal(addClass)) {\n\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\tconst classes = parseAddClassProp(addClass.get());\n\t\t\t\tconst classesToRemove = prevClass ? prevClass.filter((c) => !classes.includes(c)) : [];\n\t\t\t\tnode.classList.remove(...classesToRemove);\n\t\t\t\tnode.classList.add(...classes);\n\t\t\t\tprevClass = classes;\n\t\t\t});\n\t\t} else {\n\t\t\tconst toAdd = parseAddClassProp(addClass);\n\t\t\tnode.classList.add(...toAdd);\n\t\t}\n\t\tdelete props.addClass;\n\t}\n\n\tif (props.classes !== undefined) {\n\t\tconst classes = props.classes;\n\t\tfor (const className in classes) {\n\t\t\tlet apply = classes[className];\n\t\t\tif (typeof apply === 'function') {\n\t\t\t\tapply = computed(apply);\n\t\t\t}\n\t\t\tif (isSignal(apply)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tif (apply.get()) {\n\t\t\t\t\t\tnode.classList.add(className);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.classList.remove(className);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tif (classes[className]) {\n\t\t\t\t\tnode.classList.add(className);\n\t\t\t\t} else {\n\t\t\t\t\tnode.classList.remove(className);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdelete props.classes;\n\t}\n\n\tif (props.dataset !== undefined) {\n\t\tconst dataset = props.dataset;\n\t\tfor (const datasetKey in dataset) {\n\t\t\tlet ds = dataset[datasetKey];\n\t\t\tif (typeof ds === 'function') {\n\t\t\t\tds = computed(ds);\n\t\t\t}\n\t\t\tif (isSignal(ds)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tnode.dataset[datasetKey] = ds.get();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnode.dataset[datasetKey] = ds;\n\t\t\t}\n\t\t}\n\t\tdelete props.dataset;\n\t}\n}\n\nexport function appendChild(node: Element | DocumentFragment, child: ChispaContentReactive) {\n\tif (child === null) return;\n\tif (typeof child === 'function') {\n\t\tprocessSignalChild(node, computed(child));\n\t\treturn;\n\t}\n\tif (isSignal(child)) {\n\t\tprocessSignalChild(node, child);\n\t\treturn;\n\t}\n\tif (child instanceof Component || child instanceof ComponentList) {\n\t\tchild.mount(node, null);\n\t\treturn;\n\t}\n\tif (Array.isArray(child)) {\n\t\tchild.forEach((ch) => {\n\t\t\tappendChild(node, ch);\n\t\t});\n\t\treturn;\n\t}\n\tnode.appendChild(child instanceof Node ? child : document.createTextNode(child.toString()));\n}\n\nfunction isStaticArrayWithComponents(arr: ChispaContent): arr is (Component | ChispaNode)[] {\n\tif (!Array.isArray(arr)) return false;\n\tfor (const item of arr) {\n\t\tif (item instanceof Component) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction processSignalChild(node: Element | DocumentFragment, child: Signal<ChispaContent>) {\n\tconst anchor = document.createTextNode('');\n\tnode.appendChild(anchor);\n\tlet prevValue: Component | ComponentList | null = null;\n\n\tglobalContext.addReactivity(() => {\n\t\t//console.log('Signal child changed', child);\n\t\tconst ch = child.get();\n\t\tif (prevValue) {\n\t\t\tprevValue.unmount();\n\t\t}\n\t\tif (ch === null) {\n\t\t\tprevValue = null;\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: Component | ComponentList;\n\t\tif (isStaticArrayWithComponents(ch)) {\n\t\t\tcomponent = new Component(() => {\n\t\t\t\tconst frag = document.createDocumentFragment();\n\t\t\t\tfor (const c of ch) {\n\t\t\t\t\tappendChild(frag, c);\n\t\t\t\t}\n\t\t\t\treturn frag;\n\t\t\t});\n\t\t\tcomponent.mount(node, anchor);\n\t\t} else if (ch instanceof Component || ch instanceof ComponentList) {\n\t\t\tch.mount(node, anchor);\n\t\t\tcomponent = ch;\n\t\t} else {\n\t\t\tconst wrCmp = new Component(() => toNode(ch));\n\t\t\t//wrCmp.silent = true;\n\t\t\twrCmp.mount(node, anchor);\n\t\t\tcomponent = wrCmp;\n\t\t}\n\t\tprevValue = component;\n\t});\n}\n\nfunction toNode(n: ChispaNode | ChispaNode[]): Node | null {\n\tif (Array.isArray(n)) {\n\t\tconst frag = document.createDocumentFragment();\n\t\tconst nodes = n.map((c) => toNode(c)).filter((n) => n !== null);\n\t\tfrag.append(...nodes);\n\t\treturn frag;\n\t} else if (n instanceof Node) {\n\t\treturn n;\n\t} else if (typeof n === 'string' || typeof n === 'number') {\n\t\treturn document.createTextNode(n.toString());\n\t} else {\n\t\treturn null;\n\t\t//throw new Error('Invalid node type');\n\t}\n}\n","import { appendChild, setProps } from './builder';\nimport { componentList } from './components';\nimport { globalContext } from './context';\nimport { computed, isSignal, Signal, WritableSignal } from './signals';\n\nexport interface ControlledInputOptions<T> {\n\t/**\n\t * Optional function to transform the value before setting it to the signal.\n\t * Useful for enforcing uppercase, removing invalid characters, etc.\n\t */\n\ttransform?: (value: T) => T;\n\n\t/**\n\t * Optional function to validate the value.\n\t * If it returns false, the change is rejected and the previous value is restored.\n\t */\n\tvalidate?: (value: T) => boolean;\n}\n\nexport interface SelectOption {\n\tvalue: string;\n\tlabel: string;\n\tdisabled?: boolean;\n}\n\ntype InputValueType = string | number;\n\ninterface TypeConverter<T extends InputValueType> {\n\ttoTargetType: (val: string) => T;\n\tfromTargetType: (val: T) => string;\n}\n\nfunction getTypeConverter<T extends InputValueType>(exampleValue: T): TypeConverter<T> {\n\t// TODO: Extend for other types if needed. Also support partial parsing/formatting with invalid intermediate states (e.g. for dates or decimals)\n\tif (typeof exampleValue === 'number') {\n\t\treturn {\n\t\t\ttoTargetType: (val: string) => Number(val) as T,\n\t\t\tfromTargetType: (val: T) => val.toString(),\n\t\t} as const;\n\t} else {\n\t\treturn {\n\t\t\ttoTargetType: (val: string) => val as T,\n\t\t\tfromTargetType: (val: T) => val as string,\n\t\t} as const;\n\t}\n}\n\nexport function bindControlledInput<T extends InputValueType>(\n\telement: HTMLInputElement | HTMLTextAreaElement,\n\tvalueSignal: WritableSignal<T>,\n\toptions: ControlledInputOptions<T> = {}\n) {\n\tconst { transform, validate } = options;\n\n\t// Get type converters based on the initial value type\n\tconst { toTargetType, fromTargetType } = getTypeConverter(valueSignal.initialValue);\n\n\t// Initialize value\n\telement.value = fromTargetType(valueSignal.initialValue);\n\n\t// Handle input events\n\tconst handleInput = (e: Event) => {\n\t\tconst target = e.target as HTMLInputElement;\n\t\tlet newValue = toTargetType(target.value);\n\t\tconst originalValue = valueSignal.get();\n\n\t\t// Save cursor position\n\t\tconst selectionStart = target.selectionStart;\n\t\tconst selectionEnd = target.selectionEnd;\n\n\t\t// Apply transformation if provided\n\t\tif (transform) {\n\t\t\tnewValue = transform(newValue);\n\t\t}\n\n\t\t// Apply validation if provided\n\t\tif (validate && !validate(newValue)) {\n\t\t\t// If invalid, revert to original value\n\t\t\tnewValue = originalValue;\n\t\t}\n\n\t\t// Update signal\n\t\tif (newValue !== originalValue) {\n\t\t\tvalueSignal.set(newValue);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value (e.g. transformed or rejected)\n\t\tconst newValueStr = fromTargetType(newValue);\n\t\tif (target.value !== newValueStr) {\n\t\t\tconst lengthDiff = target.value.length - newValueStr.length;\n\t\t\ttarget.value = newValueStr;\n\n\t\t\t// Restore cursor\n\t\t\tif (selectionStart !== null && selectionEnd !== null) {\n\t\t\t\t// Restore to the saved position.\n\t\t\t\t// Adjust for length difference to keep cursor relative to the content\n\t\t\t\tconst newStart = Math.max(0, selectionStart - lengthDiff);\n\t\t\t\tconst newEnd = Math.max(0, selectionEnd - lengthDiff);\n\t\t\t\ttarget.setSelectionRange(newStart, newEnd);\n\t\t\t}\n\t\t}\n\t};\n\n\telement.addEventListener('input', handleInput);\n\n\t// Subscribe to signal changes to update the input if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValueStr = fromTargetType(valueSignal.get());\n\t\t// Only update if the value is actually different to avoid cursor jumping\n\t\tif (element.value !== newValueStr) {\n\t\t\telement.value = newValueStr;\n\t\t}\n\t});\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('input', handleInput);\n\t};\n}\n\nexport function bindControlledCheckbox(element: HTMLInputElement, valueSignal: WritableSignal<boolean>, indeterminate?: Signal<boolean>) {\n\t// Initialize checked state\n\telement.checked = valueSignal.initialValue;\n\n\t// Handle change events\n\tconst handleChange = (e: Event) => {\n\t\tconst target = e.target as HTMLInputElement;\n\t\tlet newChecked = target.checked;\n\t\tconst originalValue = valueSignal.get();\n\n\t\t// Update signal\n\t\tif (newChecked !== originalValue) {\n\t\t\tvalueSignal.set(newChecked);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value\n\t\tif (target.checked !== newChecked) {\n\t\t\ttarget.checked = newChecked;\n\t\t}\n\t};\n\n\telement.addEventListener('change', handleChange);\n\n\t// Subscribe to signal changes to update the checkbox if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValue = valueSignal.get();\n\t\tif (element.checked !== newValue) {\n\t\t\telement.checked = newValue;\n\t\t}\n\t});\n\n\t// Subscribe to indeterminate signal if provided as a Signal\n\tif (indeterminate) {\n\t\tglobalContext.addReactivity(() => {\n\t\t\telement.indeterminate = indeterminate.get();\n\t\t});\n\t}\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('change', handleChange);\n\t};\n}\n\nexport function bindControlledSelect(element: HTMLSelectElement, valueSignal: WritableSignal<string>, optionList?: Signal<SelectOption[]> | SelectOption[]) {\n\tconst Options = componentList<SelectOption>(\n\t\t(option) => {\n\t\t\tconst optElement = document.createElement('option');\n\t\t\tsetProps(optElement, {\n\t\t\t\tvalue: () => option.get().value ?? '',\n\t\t\t\ttextContent: () => option.get().label ?? '',\n\t\t\t\tdisabled: () => option.get().disabled ?? false,\n\t\t\t});\n\t\t\treturn optElement;\n\t\t},\n\t\t(o) => o.value\n\t);\n\n\t// Handle change events\n\tconst handleChange = (e: Event) => {\n\t\tconst target = e.target as HTMLSelectElement;\n\t\tlet newValue = target.value;\n\t\tconst originalValue = valueSignal.get();\n\n\t\t// Update signal\n\t\tif (newValue !== originalValue) {\n\t\t\tvalueSignal.set(newValue);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value (e.g. transformed or rejected)\n\t\tif (target.value !== newValue) {\n\t\t\ttarget.value = newValue;\n\t\t}\n\t};\n\n\t// Subscribe to options signal changes if provided\n\tif (optionList) {\n\t\tconst optionsSignal = isSignal(optionList) ? optionList : computed(() => optionList || []);\n\n\t\telement.innerHTML = '';\n\t\tappendChild(element, Options(optionsSignal));\n\t\tglobalContext.addReactivity(() => {\n\t\t\tconst currValue = valueSignal.get();\n\t\t\t// If the current value is not in the new options, reset it\n\t\t\tif (!optionsSignal.get().some((opt) => opt.value === currValue)) {\n\t\t\t\telement.value = '';\n\t\t\t} else if (element.value !== currValue) {\n\t\t\t\telement.value = currValue;\n\t\t\t}\n\t\t});\n\t}\n\n\t// Subscribe to signal changes to update the select if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValue = valueSignal.get();\n\t\t// Only update if the value is actually different\n\t\tif (element.value !== newValue) {\n\t\t\telement.value = newValue;\n\t\t}\n\t});\n\n\telement.addEventListener('change', handleChange);\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('change', handleChange);\n\t};\n}\n","import { signal, computed, Signal } from './signals';\nimport { component, Component, Dict } from './components';\nimport { appendChild, ChispaNodeBuilderProps, setProps } from './builder';\n\nexport interface Route {\n\tpath: string;\n\tcomponent: (props?: any) => Component<any>;\n}\n\nconst currentPath = signal(typeof window !== 'undefined' ? window.location.pathname : '/');\n\nif (typeof window !== 'undefined') {\n\twindow.addEventListener('popstate', () => {\n\t\tcurrentPath.set(window.location.pathname);\n\t});\n}\n\nexport function navigate(to: string, replace = false) {\n\tif (typeof window === 'undefined') {\n\t\tcurrentPath.set(to);\n\t\treturn;\n\t}\n\tif (replace) {\n\t\twindow.history.replaceState({}, '', to);\n\t} else {\n\t\twindow.history.pushState({}, '', to);\n\t}\n\tcurrentPath.set(to);\n}\n\nexport function pathMatches(path: string): Signal<boolean> {\n\treturn computed(() => {\n\t\tconst current = currentPath.get();\n\t\treturn match(path, current) !== null;\n\t});\n}\n\nfunction match(routePath: string, currentPath: string): Dict | null {\n\tif (routePath === '*') return {};\n\tconst routeParts = routePath.split('/').filter(Boolean);\n\tconst currentParts = currentPath.split('/').filter(Boolean);\n\tif (routeParts.length !== currentParts.length) return null;\n\tconst params: Dict = {};\n\tfor (let i = 0; i < routeParts.length; i++) {\n\t\tif (routeParts[i].startsWith(':')) {\n\t\t\tparams[routeParts[i].substring(1)] = currentParts[i];\n\t\t} else if (routeParts[i] !== currentParts[i]) {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn params;\n}\n\nexport const Router = component<{ routes: Route[] }>((props) => {\n\tconst container = document.createElement('div');\n\tcontainer.style.display = 'contents';\n\tconst activeRoute = computed(() => {\n\t\tconst path = currentPath.get();\n\t\tfor (const route of props.routes) {\n\t\t\tconst params = match(route.path, path);\n\t\t\tif (params) {\n\t\t\t\treturn route.component(params);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t});\n\tappendChild(container, activeRoute);\n\treturn container;\n});\n\nexport interface LinkProps extends ChispaNodeBuilderProps<HTMLAnchorElement, {}> {\n\tto: string;\n}\n\nexport const Link = component<LinkProps>((props) => {\n\tconst { to, inner, ...rest } = props;\n\tconst a = document.createElement('a');\n\ta.href = to;\n\n\ta.addEventListener('click', (e) => {\n\t\tif (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.defaultPrevented || e.button !== 0) {\n\t\t\treturn;\n\t\t}\n\t\te.preventDefault();\n\t\tnavigate(to);\n\t});\n\n\tif (inner) {\n\t\tappendChild(a, inner);\n\t}\n\n\tsetProps(a, rest);\n\n\treturn a;\n});\n"],"mappings":"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","names":["component","signal","component","index","component","n","currentPath"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/context.ts","../src/signals.ts","../src/components.ts","../src/builder.ts","../src/controlled-input.ts","../src/router.ts","../src/injection.ts"],"sourcesContent":["export const ChispaDebugConfig = {\n\tenableReactivityWarnings: false,\n};\n","import { Component, ComponentList } from './components';\nimport { ChispaDebugConfig } from './config';\nimport { Signal } from './signals';\n\ntype ExecutionKind = 'createComponent' | 'computed' | 'addReactivity' | 'injectSingleton';\n\nexport interface IDisposable {\n\tdispose: () => void;\n}\n\nclass AppContext {\n\tprivate reactivityContextStack: Reactivity[] = [];\n\n\tprivate refreshTimeout: any = 0;\n\n\t//private contexts = new Set<RenderContext>();\n\n\tprivate dirtyReactivities = new Set<Reactivity>();\n\n\tprivate executionStack: ExecutionKind[] = [];\n\n\tprivate componentStack: (Component | ComponentList)[] = [];\n\n\tpushComponentStack(cmp: Component | ComponentList) {\n\t\tthis.componentStack.push(cmp);\n\t}\n\n\tpopComponentStack() {\n\t\tthis.componentStack.pop();\n\t}\n\n\tgetCurrentComponent() {\n\t\tif (this.executionStack.includes('injectSingleton')) return null;\n\t\tif (this.componentStack.length === 0) {\n\t\t\t//console.warn('No current component');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.componentStack[this.componentStack.length - 1];\n\t}\n\n\tsetCurrentReactivityContext(context: Reactivity) {\n\t\tthis.reactivityContextStack.push(context);\n\t\t//this.contexts.add(context);\n\t}\n\n\trestorePreviousReactivityContext() {\n\t\tthis.reactivityContextStack.pop();\n\t}\n\n\tgetCurrentRenderContext() {\n\t\tif (this.reactivityContextStack.length === 0) {\n\t\t\t//console.warn('No current render context');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.reactivityContextStack[this.reactivityContextStack.length - 1];\n\t}\n\n\t// Maximum number of iterations to process during a scheduled refresh. Prevents\n\t// unbounded loops in case of uncontrolled reactivity cascades. Use the\n\t// `globalContext.maxScheduleIterations` field to override in tests or\n\t// special cases.\n\tpublic maxScheduleIterations = 100;\n\n\tscheduleRefresh() {\n\t\tif (this.refreshTimeout) {\n\t\t\tclearTimeout(this.refreshTimeout);\n\t\t}\n\t\tthis.refreshTimeout = setTimeout(() => {\n\t\t\tlet iteration = 0;\n\t\t\t// Process dirty contexts until none remain, or until the iteration limit\n\t\t\t// is reached (this avoids infinite loops when reactivities keep\n\t\t\t// re-adding themselves or each other).\n\t\t\twhile (this.dirtyReactivities.size > 0 && iteration < this.maxScheduleIterations) {\n\t\t\t\titeration++;\n\t\t\t\tconst dirtyContexts = Array.from(this.dirtyReactivities);\n\t\t\t\tdirtyContexts.forEach((ctx) => ctx.process());\n\t\t\t}\n\n\t\t\tif (this.dirtyReactivities.size > 0) {\n\t\t\t\t// Warn once if we stopped early due to the iteration limit. We also\n\t\t\t\t// clear the set to avoid repeated warnings and to avoid leaving the\n\t\t\t\t// system in a permanently spinning state.\n\t\t\t\tconsole.warn(`[AppContext.scheduleRefresh] possible uncontrolled reactivity cascade: processed ${iteration} iterations — aborting.`);\n\t\t\t\tthis.dirtyReactivities.clear();\n\t\t\t}\n\t\t}, 0);\n\t}\n\n\taddReactivity(executor: () => void) {\n\t\tconst ctx = new Reactivity(executor);\n\t\tglobalContext.pushExecutionStack('addReactivity');\n\t\tctx.exec();\n\t\tglobalContext.popExecutionStack();\n\t\treturn ctx;\n\t}\n\n\tcreateRoot(component: () => Component, mountPoint: HTMLElement) {\n\t\tthis.dirtyReactivities.clear();\n\t\tmountPoint.innerHTML = '';\n\t\tconst cmp = component();\n\t\tcmp.mount(mountPoint, null);\n\t}\n\n\tcanReadSignal() {\n\t\tconst length = this.executionStack.length;\n\t\tif (length === 0) return true;\n\t\tconst current = this.executionStack[length - 1];\n\t\treturn current !== 'createComponent';\n\t}\n\n\tpushExecutionStack(type: ExecutionKind) {\n\t\tthis.executionStack.push(type);\n\t}\n\n\tpopExecutionStack() {\n\t\tthis.executionStack.pop();\n\t}\n\n\taddDirtyContext(ctx: Reactivity) {\n\t\tthis.dirtyReactivities.add(ctx);\n\t}\n\n\tremoveDirtyContext(ctx: Reactivity) {\n\t\tthis.dirtyReactivities.delete(ctx);\n\t}\n}\n\nexport class Reactivity implements IDisposable {\n\tprivate dirty: boolean = false;\n\n\tprivate signals = new Set<Signal<any>>();\n\n\tconstructor(private readonly action: () => void) {\n\t\tconst currentComponent = globalContext.getCurrentComponent();\n\t\tif (currentComponent) {\n\t\t\tcurrentComponent.addDisposable(this);\n\t\t} else {\n\t\t\tif (ChispaDebugConfig.enableReactivityWarnings) {\n\t\t\t\tconsole.warn('Creating a Reactivity outside of a component');\n\t\t\t}\n\t\t}\n\t}\n\n\tmarkDirty() {\n\t\tthis.dirty = true;\n\t\tglobalContext.addDirtyContext(this);\n\t\tglobalContext.scheduleRefresh();\n\t}\n\n\taddSignal(signal: Signal<any>) {\n\t\tthis.signals.add(signal);\n\t}\n\n\tremoveSignal(signal: Signal<any>) {\n\t\tthis.signals.delete(signal);\n\t}\n\n\tprocess() {\n\t\tif (!this.dirty) return;\n\t\tthis.exec();\n\t\t//console.log('re-render cycle completed');\n\t\tthis.dirty = false;\n\t\tglobalContext.removeDirtyContext(this);\n\t}\n\n\texec() {\n\t\tthis.signals.forEach((s) => s.removeContext(this));\n\t\tthis.signals.clear();\n\t\tglobalContext.setCurrentReactivityContext(this);\n\t\tthis.action();\n\t\tglobalContext.restorePreviousReactivityContext();\n\t}\n\n\tdispose() {\n\t\tthis.signals.forEach((s) => s.removeContext(this));\n\t\tthis.signals.clear();\n\t\tthis.dirty = false;\n\t\tglobalContext.removeDirtyContext(this);\n\t}\n}\n\nexport const globalContext = new AppContext();\n","import { globalContext, Reactivity } from './context';\n\ntype WithSignals<T> = { [K in keyof T]: Signal<T[K]> };\n\nabstract class Signal<T> {\n\tprotected abstract value: T;\n\n\tpublic abstract readonly initialValue: T;\n\n\tprotected contexts: Set<Reactivity> = new Set();\n\n\tconstructor() {}\n\n\tget() {\n\t\tif (!globalContext.canReadSignal()) {\n\t\t\tthrow new Error('Cannot read a signal value during component creation. Consider using a computed signal or an effect instead.');\n\t\t}\n\t\t//context.current.register(this);\n\t\tconst ctx = globalContext.getCurrentRenderContext();\n\t\tif (ctx) {\n\t\t\tthis.contexts.add(ctx);\n\t\t\tctx.addSignal(this);\n\t\t}\n\t\treturn this.value;\n\t}\n\n\tpublic readonly computed = new Proxy(\n\t\t{},\n\t\t{\n\t\t\tget: (_, prop) => {\n\t\t\t\treturn computed(() => this.get()[prop as keyof T]);\n\t\t\t},\n\t\t}\n\t) as WithSignals<T>;\n\n\tremoveContext(ctx: Reactivity) {\n\t\tthis.contexts.delete(ctx);\n\t}\n\n\tdispose() {\n\t\t//console.log('disposing signal', this);\n\t\tthis.contexts.forEach((ctx) => {\n\t\t\tctx.removeSignal(this);\n\t\t});\n\t\tthis.contexts.clear();\n\t}\n}\n\nclass WritableSignal<T> extends Signal<T> {\n\tprotected override value: T;\n\n\tpublic override readonly initialValue: T;\n\n\tconstructor(initialValue: T) {\n\t\tsuper();\n\t\tthis.initialValue = initialValue;\n\t\tthis.value = initialValue;\n\t}\n\n\tset(newValue: T) {\n\t\tthis.value = newValue;\n\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t}\n\n\tupdate(updater: (value: T) => T) {\n\t\tthis.value = updater(this.value);\n\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t}\n}\n\nclass ComputedSignal<T> extends Signal<T> {\n\tprotected override value: T;\n\n\tpublic override readonly initialValue: T;\n\n\tprivate computeFn: () => T;\n\n\tconstructor(computeFn: () => T) {\n\t\tsuper();\n\t\tglobalContext.pushExecutionStack('computed');\n\t\tthis.value = computeFn();\n\t\tthis.initialValue = this.value;\n\t\tglobalContext.popExecutionStack();\n\t\tthis.computeFn = computeFn;\n\t}\n\n\trecompute() {\n\t\tconst newValue = this.computeFn();\n\t\tif (newValue !== this.value) {\n\t\t\tthis.value = newValue;\n\t\t\tthis.contexts.forEach((ctx) => ctx.markDirty());\n\t\t}\n\t}\n}\n\nexport function isSignal(value: any): value is Signal<any> {\n\treturn value instanceof Signal;\n}\n\nexport function isWriteableSignal<T>(value: Signal<T>): value is WritableSignal<T> {\n\treturn value instanceof WritableSignal;\n}\n\nexport function signal<T>(initialValue: T) {\n\tconst sig = new WritableSignal(initialValue);\n\n\t// // Creamos una función que se usará como callable\n\t// const fn = (() => sig.get()) as any;\n\n\t// // Copiamos todas las propiedades y métodos de la instancia a la función\n\t// Object.setPrototypeOf(fn, sig.constructor.prototype);\n\n\t// // Copiamos las propiedades de instancia\n\t// Object.assign(fn, this);\n\n\t// // Retornamos la función como si fuera la instancia\n\t// return fn as WritableSignal<T> & (() => T);\n\n\treturn sig;\n}\n\nexport function computed<T>(fn: () => T) {\n\tlet sig: ComputedSignal<T>;\n\tconst ctx = new Reactivity(() => {\n\t\tsig.recompute();\n\t});\n\tglobalContext.setCurrentReactivityContext(ctx);\n\tsig = new ComputedSignal(fn);\n\tglobalContext.restorePreviousReactivityContext();\n\n\treturn sig as Signal<T>;\n}\n\nexport function effect(fn: () => void) {\n\tglobalContext.addReactivity(fn);\n}\n\nexport type { Signal, WritableSignal };\n","import { ChispaContent } from './builder';\nimport { globalContext, IDisposable } from './context';\nimport { computed, Signal, WritableSignal } from './signals';\n\nexport type Dict = Record<string, any>;\nexport type ComponentFactory<TProps extends Dict> = (props: TProps) => ChispaContent;\n\nexport class Component<TProps extends Dict = any> {\n\tpublic nodes: Node[] | null = null;\n\n\tprivate container: Node | null = null;\n\n\tprivate anchor: Node | null = null;\n\n\tprivate disposables: IDisposable[] = [];\n\n\tpublic silent = true;\n\n\tconstructor(\n\t\tprivate readonly factoryFn: ComponentFactory<TProps>,\n\t\tpublic readonly key: any = null,\n\t\tpublic readonly props: TProps | null = null\n\t) {}\n\n\tmount(container: Node, anchor: Node | null = null) {\n\t\tif (!this.silent) console.log('Mounting Component', this);\n\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\n\n\t\t// If mounting within another component, register for automatic unmounting\n\t\tconst parentComponent = globalContext.getCurrentComponent();\n\t\tif (parentComponent && parentComponent !== this) {\n\t\t\tparentComponent.addDisposable({\n\t\t\t\tdispose: () => this.unmount(),\n\t\t\t});\n\t\t}\n\n\t\tglobalContext.pushExecutionStack('createComponent');\n\t\tglobalContext.pushComponentStack(this);\n\t\tconst node = this.factoryFn ? (this.factoryFn as any)(this.props) : null;\n\t\tglobalContext.popComponentStack();\n\t\tglobalContext.popExecutionStack();\n\t\t// if node is fragment, convert to array of nodes\n\t\tif (node) {\n\t\t\tif (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n\t\t\t\tthis.nodes = Array.from(node.childNodes);\n\t\t\t} else {\n\t\t\t\tthis.nodes = [node];\n\t\t\t}\n\t\t} else {\n\t\t\tthis.nodes = null;\n\t\t}\n\t\tthis.insertNodes();\n\t}\n\n\treanchor(anchor: Node | null) {\n\t\tthis.anchor = anchor;\n\n\t\t//console.log('reanchoring', this.nodes, ' before anchor', this.anchor);\n\t\tthis.insertNodes();\n\t}\n\n\tprivate insertNodes() {\n\t\tif (!this.container || !this.nodes) return;\n\t\t// Insertar en la nueva posición\n\t\tfor (const node of this.nodes) {\n\t\t\tif (this.anchor) {\n\t\t\t\tthis.container.insertBefore(node, this.anchor);\n\t\t\t} else {\n\t\t\t\tthis.container.appendChild(node);\n\t\t\t}\n\t\t}\n\t}\n\n\taddDisposable(disposable: IDisposable) {\n\t\tthis.disposables.push(disposable);\n\t}\n\n\tunmount() {\n\t\tif (!this.silent) console.log('Unmounting Component', this);\n\n\t\tif (this.nodes) {\n\t\t\tthis.nodes.forEach((node) => {\n\t\t\t\tif (node && node.parentNode) {\n\t\t\t\t\tnode.parentNode.removeChild(node);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.disposables.forEach((d) => {\n\t\t\td.dispose();\n\t\t});\n\t\tthis.disposables = [];\n\t\tthis.nodes = null;\n\t\tthis.container = null;\n\t\tthis.anchor = null;\n\t}\n}\n\n// Definimos overloads para component\nexport function component(factory: ComponentFactory<any>): (props?: any) => Component;\nexport function component<TProps extends Dict>(factory: ComponentFactory<TProps>): (props: TProps) => Component<TProps>;\n\nexport function component<TProps extends Dict = any>(factory: ComponentFactory<TProps>) {\n\treturn (props?: TProps) => {\n\t\treturn new Component(factory, null, props);\n\t};\n}\n\nexport function onUnmount(unmountFn: () => void) {\n\tconst currentComponent = globalContext.getCurrentComponent();\n\tif (currentComponent) {\n\t\tcurrentComponent.addDisposable({\n\t\t\tdispose: unmountFn,\n\t\t});\n\t} else {\n\t\tthrow new Error('onUnmount must be called within a component context');\n\t}\n}\n\ntype ItemFactoryFn<T, TProps = any> = (item: Signal<T>, index: Signal<number>, list: Signal<T[]>, props: TProps, key: any) => ChispaContent;\ntype KeyFn<T> = (item: T, index: number) => any;\n\nexport class ComponentList<TItem = any, TProps extends Dict = any> {\n\tprivate readonly components: Map<string, Component<TProps>>;\n\tprivate container: Node | null = null; // Contenedor donde se montan los nodos\n\tprivate anchor: Node | null = null; // Nodes must be inserted before this node\n\tprivate currentKeys: any[] = [];\n\tpublic disposables: any[] = [];\n\n\tconstructor(\n\t\tprivate readonly itemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\t\tprivate readonly keyFn: KeyFn<TItem>,\n\t\tprivate readonly itemsSignal: Signal<TItem[]>,\n\t\tprivate readonly props: TProps | null = null\n\t) {\n\t\tthis.components = new Map();\n\t}\n\n\t/**\n\t * Obtiene todos los componentes\n\t */\n\tprivate getAllComponents(): Component[] {\n\t\treturn Array.from(this.components.values());\n\t}\n\n\t/**\n\t * Limpia todos los componentes\n\t */\n\tprivate clear(): void {\n\t\tArray.from(this.components.values()).forEach((component) => {\n\t\t\tthis.removeComponent(component);\n\t\t});\n\t}\n\n\t/**\n\t * Elimina un componente completo\n\t */\n\tprivate removeComponent(component: Component) {\n\t\tcomponent.unmount();\n\t\tif (component.key) {\n\t\t\tthis.components.delete(component.key);\n\t\t}\n\t}\n\n\t/**\n\t * Crea un nuevo componente\n\t */\n\tprivate createNewComponent(key: any): Component {\n\t\tconst factory = (props: TProps) => {\n\t\t\tconst item = computed(() => this.itemsSignal.get().find((v, index) => this.keyFn(v, index) === key)!);\n\t\t\tconst index = computed(() => this.itemsSignal.get().findIndex((v, index) => this.keyFn(v, index) === key));\n\t\t\treturn this.itemFactoryFn ? this.itemFactoryFn(item, index, this.itemsSignal, props, key) : null;\n\t\t};\n\n\t\tconst component = new Component(factory, key, this.props);\n\t\tthis.components.set(key, component);\n\n\t\treturn component;\n\t}\n\n\tprivate getTargetAnchor(items: TItem[], index: number): Node | null {\n\t\tconst nextItem = index + 1 < items.length ? items[index + 1] : null;\n\t\tconst nextComp = nextItem ? this.components.get(this.keyFn(nextItem, index + 1)) : null;\n\t\tif (nextComp && nextComp.nodes) {\n\t\t\treturn nextComp.nodes[0];\n\t\t} else {\n\t\t\t// Es el último componente, debería insertarse antes del anchor original\n\t\t\treturn this.anchor;\n\t\t}\n\t}\n\n\t/**\n\t * Función principal que sincroniza los componentes DOM con un array de keys\n\t */\n\tprivate synchronizeComponents(): void {\n\t\tconst existingComponents = this.getAllComponents();\n\n\t\t// Identificar qué componentes eliminar (los que no están en keys)\n\t\tconst items = this.itemsSignal.get();\n\t\tconst keys = items.map((item, index) => this.keyFn(item, index));\n\t\tconst componentsToRemove = existingComponents.filter((component) => component.key && !keys.includes(component.key));\n\t\tcomponentsToRemove.forEach((component) => this.removeComponent(component));\n\n\t\tthis.currentKeys = this.currentKeys.filter((key) => keys.includes(key));\n\t\t//console.log('Current keys:', this.currentKeys, 'Target keys:', keys);\n\n\t\tif (!this.container) {\n\t\t\tconsole.warn('Container is null in synchronizeComponents');\n\t\t\treturn;\n\t\t}\n\t\t// Procesar cada key en el orden deseado\n\t\tconst container = this.container;\n\n\t\titems.forEach((item, index) => {\n\t\t\tconst targetKey = this.keyFn(item, index);\n\t\t\tconst currentKey = this.currentKeys[index];\n\t\t\tif (targetKey === currentKey) {\n\t\t\t\t// La key no ha cambiado de posición, no hacer nada\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst existingComponent = this.components.get(targetKey);\n\n\t\t\tif (existingComponent) {\n\t\t\t\tconst prevComp = this.components.get(currentKey);\n\t\t\t\tif (!prevComp || !prevComp.nodes) {\n\t\t\t\t\tconsole.warn('Previous component or its nodes not found for key', currentKey);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texistingComponent.reanchor(prevComp.nodes[0]);\n\t\t\t\t// Reordenar el array de keys actuales\n\t\t\t\tthis.currentKeys = this.currentKeys.filter((k) => k !== targetKey);\n\t\t\t\tthis.currentKeys.splice(index, 0, targetKey);\n\t\t\t} else {\n\t\t\t\t// El componente no existe, crearlo\n\t\t\t\tconst targetAnchor = this.getTargetAnchor(items, index);\n\t\t\t\tconst newComponent = this.createNewComponent(targetKey);\n\t\t\t\tnewComponent.mount(container, targetAnchor);\n\t\t\t\tthis.currentKeys.splice(index, 0, targetKey);\n\t\t\t}\n\t\t});\n\t}\n\n\tmount(container: Node, anchor: Node | null = null) {\n\t\t//console.log('Mounting ComponentList');\n\t\tthis.container = container;\n\t\tthis.anchor = anchor;\n\n\t\t// If mounting within another component, register for automatic unmounting\n\t\tconst parentComponent = globalContext.getCurrentComponent();\n\t\tif (parentComponent && parentComponent !== this) {\n\t\t\tparentComponent.addDisposable({\n\t\t\t\tdispose: () => this.unmount(),\n\t\t\t});\n\t\t}\n\n\t\tglobalContext.pushComponentStack(this);\n\t\tglobalContext.addReactivity(() => {\n\t\t\tthis.synchronizeComponents();\n\t\t});\n\t\tglobalContext.popComponentStack();\n\t}\n\n\taddDisposable(disposable: IDisposable) {\n\t\tthis.disposables.push(disposable);\n\t}\n\n\tunmount() {\n\t\t//console.log('Unmounting ComponentList');\n\t\tthis.clear();\n\t\tthis.container = null!;\n\t\tthis.anchor = null!;\n\t\tthis.disposables.forEach((d) => {\n\t\t\td.dispose();\n\t\t});\n\t}\n}\n\n// Definimos overloads para componentList\nexport function componentList<TItem>(\n\titemFactoryFn: ItemFactoryFn<TItem, any>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: Signal<TItem[]>, props?: any) => ComponentList<TItem>;\nexport function componentList<TItem, TProps extends Dict>(\n\titemFactoryFn: ItemFactoryFn<TItem, TProps>,\n\tkeyFn: KeyFn<TItem>\n): (listSignal: Signal<TItem[]>, props: TProps) => ComponentList<TItem, TProps>;\n\nexport function componentList<TItem, TProps extends Dict = any>(itemFactoryFn: ItemFactoryFn<TItem, TProps>, keyFn: KeyFn<TItem>) {\n\treturn (listSignal: Signal<TItem[]>, props?: TProps) => {\n\t\tconst list = new ComponentList(itemFactoryFn, keyFn, listSignal, props);\n\t\treturn list;\n\t};\n}\n","import { Component, ComponentList } from './components';\nimport { globalContext } from './context';\nimport { computed, isSignal, type Signal } from './signals';\n\nexport type ChispaReactive<T> = T | Signal<T> | (() => T);\nexport type ChispaNode = string | number | Node | null;\nexport type ChispaContent = ChispaNode | Component | (ChispaNode | Component)[] | ComponentList;\nexport type ChispaContentReactive = ChispaReactive<ChispaContent>;\nexport type ChispaClasses = Record<string, ChispaReactive<boolean>>;\nexport type ChispaCSSPropertiesStrings = {\n\t[K in keyof CSSStyleDeclaration]?: ChispaReactive<string>;\n};\n\ntype EventPropKeys<T> = Extract<keyof T, `on${string}`>;\ntype AllowSignals<T> = { [K in keyof T]: ChispaReactive<T[K]> };\n\ntype ChispaNodeBuilderBaseProps<T> = AllowSignals<Omit<T, 'style' | 'dataset' | EventPropKeys<T>>> & Pick<T, EventPropKeys<T>>;\ninterface INodeBuilderSpecialProps {\n\taddClass?: ChispaReactive<string | string[]>;\n\tclasses?: ChispaClasses;\n\tstyle?: ChispaCSSPropertiesStrings;\n\tdataset?: Record<string, ChispaReactive<string>>;\n}\ninterface INodeBuilderAdditionalProps<T, TNodes> {\n\tnodes?: TNodes;\n\tinner?: ChispaContentReactive;\n\t_ref?: (node: T) => void | { current: T | null };\n}\nexport type ChispaNodeBuilderProps<T, TNodes> = Partial<ChispaNodeBuilderBaseProps<T>> & INodeBuilderAdditionalProps<T, TNodes> & INodeBuilderSpecialProps;\nexport type ChispaNodeBuilderPropsReactive<T, TNodes> = ChispaReactive<ChispaNodeBuilderProps<T, TNodes>>;\n\nconst forbiddenProps = ['nodes', 'inner', '_ref'];\n\nexport function getValidProps<T>(props: ChispaNodeBuilderProps<T, any>) {\n\tconst finalProps: any = {};\n\n\tfor (const propName in props) {\n\t\tif (!forbiddenProps.includes(propName)) {\n\t\t\tfinalProps[propName] = props[propName as keyof typeof props];\n\t\t}\n\t}\n\n\treturn finalProps as ChispaNodeBuilderProps<T, any>;\n}\n\nconst itemsStack: any[] = [];\nfunction findItemInStack(itemName: string): any {\n\tfor (const itemsDefs of itemsStack) {\n\t\tif (itemsDefs && itemsDefs[itemName]) {\n\t\t\treturn itemsDefs[itemName];\n\t\t}\n\t}\n\treturn null;\n}\n\nexport function getItem<T>(template: T, items: any, itemName: keyof T) {\n\titemsStack.unshift(items);\n\tconst item: any = findItemInStack(itemName as string);\n\n\tif (!item) {\n\t\titemsStack.shift();\n\t\treturn null;\n\t}\n\n\tlet res;\n\tif (item.constructor && item.constructor.name === 'Object' && !(item instanceof Element)) {\n\t\tconst Comp = template[itemName] as (props: any) => Element;\n\t\tconst itemProps = item;\n\n\t\tres = Comp(itemProps);\n\t} else {\n\t\tres = item;\n\t}\n\titemsStack.shift();\n\treturn res;\n}\n\nexport function setAttributes(node: Element, attributes: Record<string, string>) {\n\tfor (const attr in attributes) {\n\t\tconst attrValue = attributes[attr];\n\t\tif (attrValue === undefined || attrValue === null) {\n\t\t\tnode.removeAttribute(attr);\n\t\t\tcontinue;\n\t\t}\n\t\tnode.setAttribute(attr, attrValue);\n\t}\n}\n\nfunction isEventProp(prop: string) {\n\treturn prop.startsWith('on');\n}\n\nfunction getPropValue(props: any, prop: string) {\n\tconst propValue = props[prop];\n\tif (typeof propValue === 'function' && !isEventProp(prop)) {\n\t\treturn computed(propValue);\n\t}\n\treturn propValue;\n}\n\nexport function setProps<T extends Element>(node: T, props: ChispaNodeBuilderPropsReactive<T, any>) {\n\tlet _props = props;\n\tif (typeof _props === 'function') {\n\t\t_props = computed(_props);\n\t}\n\tif (isSignal(_props)) {\n\t\tglobalContext.addReactivity(() => {\n\t\t\tsetProps(node, _props.get());\n\t\t});\n\t\treturn;\n\t}\n\n\tprops = getValidProps(_props);\n\n\tif (node instanceof HTMLElement) {\n\t\tsetSpecialProps(node, props);\n\t}\n\n\tfor (const prop in props) {\n\t\tconst propValue = getPropValue(props, prop);\n\t\t//console.log('setting prop', prop, propValue )\n\t\tif (isSignal(propValue)) {\n\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t(node as any)[prop] = propValue.get();\n\t\t\t});\n\t\t} else if (propValue === undefined) {\n\t\t\tcontinue;\n\t\t} else {\n\t\t\t(node as any)[prop] = propValue;\n\t\t}\n\t}\n}\n\nfunction parseAddClassProp(value: string | string[]): string[] {\n\tconst arr = typeof value === 'string' ? value.split(' ') : value;\n\treturn arr.filter((c) => c.trim() !== '');\n}\n\nfunction setSpecialProps<T extends HTMLElement>(node: T, props: INodeBuilderSpecialProps) {\n\tif (props.style !== undefined) {\n\t\tconst style = props.style;\n\t\tfor (const styleKey in style) {\n\t\t\tlet styleValue = style[styleKey]!;\n\t\t\tif (typeof styleValue === 'function') {\n\t\t\t\tstyleValue = computed(styleValue);\n\t\t\t}\n\t\t\tif (isSignal(styleValue)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tnode.style[styleKey] = styleValue.get();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnode.style[styleKey] = styleValue;\n\t\t\t}\n\t\t}\n\t\tdelete props.style;\n\t}\n\n\tif (props.addClass !== undefined) {\n\t\tlet addClass = props.addClass;\n\t\tlet prevClass: string[] | null = null;\n\n\t\tif (typeof addClass === 'function') {\n\t\t\taddClass = computed(addClass);\n\t\t}\n\n\t\tif (isSignal(addClass)) {\n\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\tconst classes = parseAddClassProp(addClass.get());\n\t\t\t\tconst classesToRemove = prevClass ? prevClass.filter((c) => !classes.includes(c)) : [];\n\t\t\t\tnode.classList.remove(...classesToRemove);\n\t\t\t\tnode.classList.add(...classes);\n\t\t\t\tprevClass = classes;\n\t\t\t});\n\t\t} else {\n\t\t\tconst toAdd = parseAddClassProp(addClass);\n\t\t\tnode.classList.add(...toAdd);\n\t\t}\n\t\tdelete props.addClass;\n\t}\n\n\tif (props.classes !== undefined) {\n\t\tconst classes = props.classes;\n\t\tfor (const className in classes) {\n\t\t\tlet apply = classes[className];\n\t\t\tif (typeof apply === 'function') {\n\t\t\t\tapply = computed(apply);\n\t\t\t}\n\t\t\tif (isSignal(apply)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tif (apply.get()) {\n\t\t\t\t\t\tnode.classList.add(className);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.classList.remove(className);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tif (classes[className]) {\n\t\t\t\t\tnode.classList.add(className);\n\t\t\t\t} else {\n\t\t\t\t\tnode.classList.remove(className);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdelete props.classes;\n\t}\n\n\tif (props.dataset !== undefined) {\n\t\tconst dataset = props.dataset;\n\t\tfor (const datasetKey in dataset) {\n\t\t\tlet ds = dataset[datasetKey];\n\t\t\tif (typeof ds === 'function') {\n\t\t\t\tds = computed(ds);\n\t\t\t}\n\t\t\tif (isSignal(ds)) {\n\t\t\t\tglobalContext.addReactivity(() => {\n\t\t\t\t\tnode.dataset[datasetKey] = ds.get();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tnode.dataset[datasetKey] = ds;\n\t\t\t}\n\t\t}\n\t\tdelete props.dataset;\n\t}\n}\n\nexport function appendChild(node: Element | DocumentFragment, child: ChispaContentReactive) {\n\tif (child === null) return;\n\tif (typeof child === 'function') {\n\t\tprocessSignalChild(node, computed(child));\n\t\treturn;\n\t}\n\tif (isSignal(child)) {\n\t\tprocessSignalChild(node, child);\n\t\treturn;\n\t}\n\tif (child instanceof Component || child instanceof ComponentList) {\n\t\tchild.mount(node, null);\n\t\treturn;\n\t}\n\tif (Array.isArray(child)) {\n\t\tchild.forEach((ch) => {\n\t\t\tappendChild(node, ch);\n\t\t});\n\t\treturn;\n\t}\n\tnode.appendChild(child instanceof Node ? child : document.createTextNode(child.toString()));\n}\n\nfunction isStaticArrayWithComponents(arr: ChispaContent): arr is (Component | ChispaNode)[] {\n\tif (!Array.isArray(arr)) return false;\n\tfor (const item of arr) {\n\t\tif (item instanceof Component) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction processSignalChild(node: Element | DocumentFragment, child: Signal<ChispaContent>) {\n\tconst anchor = document.createTextNode('');\n\tnode.appendChild(anchor);\n\tlet prevValue: Component | ComponentList | null = null;\n\n\tglobalContext.addReactivity(() => {\n\t\t//console.log('Signal child changed', child);\n\t\tconst ch = child.get();\n\t\tif (prevValue) {\n\t\t\tprevValue.unmount();\n\t\t}\n\t\tif (ch === null) {\n\t\t\tprevValue = null;\n\t\t\treturn;\n\t\t}\n\n\t\tlet component: Component | ComponentList;\n\t\tif (isStaticArrayWithComponents(ch)) {\n\t\t\tcomponent = new Component(() => {\n\t\t\t\tconst frag = document.createDocumentFragment();\n\t\t\t\tfor (const c of ch) {\n\t\t\t\t\tappendChild(frag, c);\n\t\t\t\t}\n\t\t\t\treturn frag;\n\t\t\t});\n\t\t\tcomponent.mount(node, anchor);\n\t\t} else if (ch instanceof Component || ch instanceof ComponentList) {\n\t\t\tch.mount(node, anchor);\n\t\t\tcomponent = ch;\n\t\t} else {\n\t\t\tconst wrCmp = new Component(() => toNode(ch));\n\t\t\t//wrCmp.silent = true;\n\t\t\twrCmp.mount(node, anchor);\n\t\t\tcomponent = wrCmp;\n\t\t}\n\t\tprevValue = component;\n\t});\n}\n\nfunction toNode(n: ChispaNode | ChispaNode[]): Node | null {\n\tif (Array.isArray(n)) {\n\t\tconst frag = document.createDocumentFragment();\n\t\tconst nodes = n.map((c) => toNode(c)).filter((n) => n !== null);\n\t\tfrag.append(...nodes);\n\t\treturn frag;\n\t} else if (n instanceof Node) {\n\t\treturn n;\n\t} else if (typeof n === 'string' || typeof n === 'number') {\n\t\treturn document.createTextNode(n.toString());\n\t} else {\n\t\treturn null;\n\t\t//throw new Error('Invalid node type');\n\t}\n}\n","import { appendChild, setProps } from './builder';\nimport { componentList } from './components';\nimport { globalContext } from './context';\nimport { computed, isSignal, Signal, WritableSignal } from './signals';\n\nexport interface ControlledInputOptions<T> {\n\t/**\n\t * Optional function to transform the value before setting it to the signal.\n\t * Useful for enforcing uppercase, removing invalid characters, etc.\n\t */\n\ttransform?: (value: T) => T;\n\n\t/**\n\t * Optional function to validate the value.\n\t * If it returns false, the change is rejected and the previous value is restored.\n\t */\n\tvalidate?: (value: T) => boolean;\n}\n\nexport interface SelectOption {\n\tvalue: string;\n\tlabel: string;\n\tdisabled?: boolean;\n}\n\ntype InputValueType = string | number;\n\ninterface TypeConverter<T extends InputValueType> {\n\ttoTargetType: (val: string) => T;\n\tfromTargetType: (val: T) => string;\n}\n\nfunction getTypeConverter<T extends InputValueType>(exampleValue: T): TypeConverter<T> {\n\t// TODO: Extend for other types if needed. Also support partial parsing/formatting with invalid intermediate states (e.g. for dates or decimals)\n\tif (typeof exampleValue === 'number') {\n\t\treturn {\n\t\t\ttoTargetType: (val: string) => Number(val) as T,\n\t\t\tfromTargetType: (val: T) => val.toString(),\n\t\t} as const;\n\t} else {\n\t\treturn {\n\t\t\ttoTargetType: (val: string) => val as T,\n\t\t\tfromTargetType: (val: T) => val as string,\n\t\t} as const;\n\t}\n}\n\nexport function bindControlledInput<T extends InputValueType>(\n\telement: HTMLInputElement | HTMLTextAreaElement,\n\tvalueSignal: WritableSignal<T>,\n\toptions: ControlledInputOptions<T> = {}\n) {\n\tconst { transform, validate } = options;\n\n\t// Get type converters based on the initial value type\n\tconst { toTargetType, fromTargetType } = getTypeConverter(valueSignal.initialValue);\n\n\t// Initialize value\n\telement.value = fromTargetType(valueSignal.initialValue);\n\n\t// Handle input events\n\tconst handleInput = (e: Event) => {\n\t\tconst target = e.target as HTMLInputElement;\n\t\tlet newValue = toTargetType(target.value);\n\t\tconst originalValue = valueSignal.get();\n\n\t\t// Save cursor position\n\t\tconst selectionStart = target.selectionStart;\n\t\tconst selectionEnd = target.selectionEnd;\n\n\t\t// Apply transformation if provided\n\t\tif (transform) {\n\t\t\tnewValue = transform(newValue);\n\t\t}\n\n\t\t// Apply validation if provided\n\t\tif (validate && !validate(newValue)) {\n\t\t\t// If invalid, revert to original value\n\t\t\tnewValue = originalValue;\n\t\t}\n\n\t\t// Update signal\n\t\tif (newValue !== originalValue) {\n\t\t\tvalueSignal.set(newValue);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value (e.g. transformed or rejected)\n\t\tconst newValueStr = fromTargetType(newValue);\n\t\tif (target.value !== newValueStr) {\n\t\t\tconst lengthDiff = target.value.length - newValueStr.length;\n\t\t\ttarget.value = newValueStr;\n\n\t\t\t// Restore cursor\n\t\t\tif (selectionStart !== null && selectionEnd !== null) {\n\t\t\t\t// Restore to the saved position.\n\t\t\t\t// Adjust for length difference to keep cursor relative to the content\n\t\t\t\tconst newStart = Math.max(0, selectionStart - lengthDiff);\n\t\t\t\tconst newEnd = Math.max(0, selectionEnd - lengthDiff);\n\t\t\t\ttarget.setSelectionRange(newStart, newEnd);\n\t\t\t}\n\t\t}\n\t};\n\n\telement.addEventListener('input', handleInput);\n\n\t// Subscribe to signal changes to update the input if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValueStr = fromTargetType(valueSignal.get());\n\t\t// Only update if the value is actually different to avoid cursor jumping\n\t\tif (element.value !== newValueStr) {\n\t\t\telement.value = newValueStr;\n\t\t}\n\t});\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('input', handleInput);\n\t};\n}\n\nexport function bindControlledCheckbox(element: HTMLInputElement, valueSignal: WritableSignal<boolean>, indeterminate?: Signal<boolean>) {\n\t// Initialize checked state\n\telement.checked = valueSignal.initialValue;\n\n\t// Handle change events\n\tconst handleChange = (e: Event) => {\n\t\tconst target = e.target as HTMLInputElement;\n\t\tlet newChecked = target.checked;\n\t\tconst originalValue = valueSignal.get();\n\n\t\t// Update signal\n\t\tif (newChecked !== originalValue) {\n\t\t\tvalueSignal.set(newChecked);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value\n\t\tif (target.checked !== newChecked) {\n\t\t\ttarget.checked = newChecked;\n\t\t}\n\t};\n\n\telement.addEventListener('change', handleChange);\n\n\t// Subscribe to signal changes to update the checkbox if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValue = valueSignal.get();\n\t\tif (element.checked !== newValue) {\n\t\t\telement.checked = newValue;\n\t\t}\n\t});\n\n\t// Subscribe to indeterminate signal if provided as a Signal\n\tif (indeterminate) {\n\t\tglobalContext.addReactivity(() => {\n\t\t\telement.indeterminate = indeterminate.get();\n\t\t});\n\t}\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('change', handleChange);\n\t};\n}\n\nexport function bindControlledSelect(element: HTMLSelectElement, valueSignal: WritableSignal<string>, optionList?: Signal<SelectOption[]> | SelectOption[]) {\n\tconst Options = componentList<SelectOption>(\n\t\t(option) => {\n\t\t\tconst optElement = document.createElement('option');\n\t\t\tsetProps(optElement, {\n\t\t\t\tvalue: () => option.get().value ?? '',\n\t\t\t\ttextContent: () => option.get().label ?? '',\n\t\t\t\tdisabled: () => option.get().disabled ?? false,\n\t\t\t});\n\t\t\treturn optElement;\n\t\t},\n\t\t(o) => o.value\n\t);\n\n\t// Handle change events\n\tconst handleChange = (e: Event) => {\n\t\tconst target = e.target as HTMLSelectElement;\n\t\tlet newValue = target.value;\n\t\tconst originalValue = valueSignal.get();\n\n\t\t// Update signal\n\t\tif (newValue !== originalValue) {\n\t\t\tvalueSignal.set(newValue);\n\t\t}\n\n\t\t// Force update DOM if it doesn't match the new value (e.g. transformed or rejected)\n\t\tif (target.value !== newValue) {\n\t\t\ttarget.value = newValue;\n\t\t}\n\t};\n\n\t// Subscribe to options signal changes if provided\n\tif (optionList) {\n\t\tconst optionsSignal = isSignal(optionList) ? optionList : computed(() => optionList || []);\n\n\t\telement.innerHTML = '';\n\t\tappendChild(element, Options(optionsSignal));\n\t\tglobalContext.addReactivity(() => {\n\t\t\tconst currValue = valueSignal.get();\n\t\t\t// If the current value is not in the new options, reset it\n\t\t\tif (!optionsSignal.get().some((opt) => opt.value === currValue)) {\n\t\t\t\telement.value = '';\n\t\t\t} else if (element.value !== currValue) {\n\t\t\t\telement.value = currValue;\n\t\t\t}\n\t\t});\n\t}\n\n\t// Subscribe to signal changes to update the select if it changes externally\n\tglobalContext.addReactivity(() => {\n\t\tconst newValue = valueSignal.get();\n\t\t// Only update if the value is actually different\n\t\tif (element.value !== newValue) {\n\t\t\telement.value = newValue;\n\t\t}\n\t});\n\n\telement.addEventListener('change', handleChange);\n\n\t// Return a cleanup function\n\treturn () => {\n\t\telement.removeEventListener('change', handleChange);\n\t};\n}\n","import { signal, computed, Signal } from './signals';\nimport { component, Component, Dict } from './components';\nimport { appendChild, ChispaNodeBuilderProps, setProps } from './builder';\n\nexport interface Route {\n\tpath: string;\n\tcomponent: (props?: any) => Component<any>;\n}\n\nconst currentPath = signal(typeof window !== 'undefined' ? window.location.pathname : '/');\n\nif (typeof window !== 'undefined') {\n\twindow.addEventListener('popstate', () => {\n\t\tcurrentPath.set(window.location.pathname);\n\t});\n}\n\nexport function navigate(to: string, replace = false) {\n\tif (typeof window === 'undefined') {\n\t\tcurrentPath.set(to);\n\t\treturn;\n\t}\n\tif (replace) {\n\t\twindow.history.replaceState({}, '', to);\n\t} else {\n\t\twindow.history.pushState({}, '', to);\n\t}\n\tcurrentPath.set(to);\n}\n\nexport function pathMatches(path: string): Signal<boolean> {\n\treturn computed(() => {\n\t\tconst current = currentPath.get();\n\t\treturn match(path, current) !== null;\n\t});\n}\n\nfunction match(routePath: string, currentPath: string): Dict | null {\n\tif (routePath === '*') return {};\n\tconst routeParts = routePath.split('/').filter(Boolean);\n\tconst currentParts = currentPath.split('/').filter(Boolean);\n\tif (routeParts.length !== currentParts.length) return null;\n\tconst params: Dict = {};\n\tfor (let i = 0; i < routeParts.length; i++) {\n\t\tif (routeParts[i].startsWith(':')) {\n\t\t\tparams[routeParts[i].substring(1)] = currentParts[i];\n\t\t} else if (routeParts[i] !== currentParts[i]) {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn params;\n}\n\nexport const Router = component<{ routes: Route[] }>((props) => {\n\tconst container = document.createElement('div');\n\tcontainer.style.display = 'contents';\n\tconst activeRoute = computed(() => {\n\t\tconst path = currentPath.get();\n\t\tfor (const route of props.routes) {\n\t\t\tconst params = match(route.path, path);\n\t\t\tif (params) {\n\t\t\t\treturn route.component(params);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t});\n\tappendChild(container, activeRoute);\n\treturn container;\n});\n\nexport interface LinkProps extends ChispaNodeBuilderProps<HTMLAnchorElement, {}> {\n\tto: string;\n}\n\nexport const Link = component<LinkProps>((props) => {\n\tconst { to, inner, ...rest } = props;\n\tconst a = document.createElement('a');\n\ta.href = to;\n\n\ta.addEventListener('click', (e) => {\n\t\tif (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.defaultPrevented || e.button !== 0) {\n\t\t\treturn;\n\t\t}\n\t\te.preventDefault();\n\t\tnavigate(to);\n\t});\n\n\tif (inner) {\n\t\tappendChild(a, inner);\n\t}\n\n\tsetProps(a, rest);\n\n\treturn a;\n});\n","import { globalContext } from './context';\n\ntype Constructor<T> = new (...args: any[]) => T;\n\n/**\n * A typed token that can be used to inject values or interfaces that are not\n * tied to a concrete class constructor.\n *\n * @example\n * const API_URL = new InjectionToken<string>('API_URL');\n * provide(API_URL, () => 'https://api.example.com');\n * const url = inject(API_URL); // string\n */\nexport class InjectionToken<T> {\n\tconstructor(public readonly description: string) {}\n}\n\ntype Token<T> = Constructor<T> | InjectionToken<T>;\n\nclass ServiceContainer {\n\tprivate services = new Map<Token<any>, any>();\n\tprivate factories = new Map<Token<any>, () => any>();\n\n\tpublic provide<T>(token: Token<T>, factory: () => T): void {\n\t\tif (this.services.has(token)) {\n\t\t\tconst name = token instanceof InjectionToken ? `\"${token.description}\"` : (token as Constructor<T>).name;\n\t\t\tthrow new Error(`Cannot call provide() for ${name} after it has already been injected.`);\n\t\t}\n\t\tthis.factories.set(token, factory);\n\t}\n\n\tpublic get<T>(token: Token<T>): T {\n\t\tif (this.services.has(token)) {\n\t\t\treturn this.services.get(token) as T;\n\t\t}\n\n\t\tlet service: T;\n\n\t\tglobalContext.pushExecutionStack('injectSingleton');\n\t\ttry {\n\t\t\tservice = this.createInstance(token);\n\t\t} finally {\n\t\t\tglobalContext.popExecutionStack();\n\t\t}\n\n\t\tthis.services.set(token, service);\n\t\treturn service;\n\t}\n\n\t/**\n\t * Creates a fresh, non-cached instance of the token's service.\n\t * Runs inside the current component context so that any effects created\n\t * in the constructor are bound to (and disposed with) that component.\n\t */\n\tpublic getLocal<T>(token: Token<T>): T {\n\t\t// TODO: this is a bit hacky, we should find a cleaner way to create local instances without affecting the global singleton cache or execution stack\n\t\treturn this.createInstance(token);\n\t}\n\n\tprivate createInstance<T>(token: Token<T>): T {\n\t\tconst factory = this.factories.get(token);\n\t\tif (factory) {\n\t\t\treturn factory();\n\t\t} else if (token instanceof InjectionToken) {\n\t\t\tthrow new Error(`No provider registered for InjectionToken \"${token.description}\"`);\n\t\t} else {\n\t\t\treturn new (token as Constructor<T>)();\n\t\t}\n\t}\n\n\tpublic reset(): void {\n\t\tthis.services.clear();\n\t\tthis.factories.clear();\n\t}\n}\n\nconst services = new ServiceContainer();\n\n/**\n * Registers a factory function for the given token. The factory is called\n * at most once (the result is cached as a singleton). Must be called before\n * the first `inject(token)` call for that token.\n */\nexport function provide<T>(token: Token<T>, factory: () => T): void {\n\tservices.provide(token, factory);\n}\n\nexport interface InjectOptions {\n\t/**\n\t * When `true`, a new instance is created every time and is NOT added to the\n\t * singleton cache. Any reactive effects created in the service constructor\n\t * will be registered to the currently mounting component and disposed when\n\t * it unmounts.\n\t */\n\tlocal?: boolean;\n}\n\n/**\n * Injects (or lazily creates) the singleton service associated with `token`.\n * Any reactive effects declared inside the service constructor will NOT be\n * disposed when the component that first triggers the injection is unmounted.\n *\n * Pass `{ local: true }` to get a fresh, component-scoped instance instead:\n * effects will be disposed together with the component.\n */\nexport function inject<T>(token: Token<T>, options?: InjectOptions): T {\n\tif (options?.local) {\n\t\treturn services.getLocal(token);\n\t}\n\treturn services.get(token);\n}\n\n/**\n * Resets the entire service container. Useful for test isolation.\n */\nexport function resetServices(): void {\n\tservices.reset();\n}\n"],"mappings":"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","names":["component","signal","component","index","component","n","currentPath"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chispa",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "description": "A fully declarative UI reactive engine for building web applications.",
5
5
  "author": "José Carlos HR <joecarlhr@gmail.com>",
6
6
  "license": "MIT",