@realglebivanov/reactive 1.0.2 → 1.0.3

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
@@ -27,8 +27,8 @@ declare class ValueObservable<T> implements Observable<T>, Updatable<T> {
27
27
  subscribe(id: symbol, observer: Observer<T>): void;
28
28
  subscribeInit(id: symbol, observer: Observer<T>): void;
29
29
  update(updateFn: UpdateFn<T>): void;
30
- private notify;
31
30
  private notifyAll;
31
+ private notify;
32
32
  }
33
33
 
34
34
  type ObservableValue<O extends Observable<any>> = O extends Observable<infer T> ? T : never;
@@ -87,50 +87,6 @@ declare class ScopedObservable<T extends Observable<any>> implements Observable<
87
87
  update(this: ScopedObservable<Updatable<Value<T>> & Observable<Value<T>>>, updateFn: UpdateFn<Value<T>>): void;
88
88
  }
89
89
 
90
- type Observer<T> = (value: T) => void;
91
- type UpdateFn<T> = (value: T) => T;
92
- interface Observable<T> {
93
- unsubscribeAll(): void;
94
- unsubscribe(id: symbol): void;
95
- subscribe(id: symbol, observer: Observer<T>): void;
96
- subscribeInit(id: symbol, observer: Observer<T>): void;
97
- }
98
- interface Updatable<T> {
99
- update(updateFn: UpdateFn<T>): void;
100
- }
101
-
102
- type ReactiveNode<T extends Node> = Lifecycle & T & ReactiveNodeSetters<T>;
103
- interface ReactiveNodeSetters<T extends Node> {
104
- clk: <R extends ReactiveNode<T>>(cb: EventListenerOrEventListenerObject) => R;
105
- }
106
- type TagReactiveNode<K extends keyof HTMLElementTagNameMap> = ReactiveNode<HTMLElementTagNameMap[K]> & TagReactiveNodeSetters<K>;
107
- interface TagReactiveNodeSetters<K extends keyof HTMLElementTagNameMap> {
108
- att: (name: string, value: string) => TagReactiveNode<K>;
109
- att$: (name: string, value: Observable<string>) => TagReactiveNode<K>;
110
- }
111
- declare const toTagReactiveNode: <K extends keyof HTMLElementTagNameMap>(node: HTMLElementTagNameMap[K], handlers: Lifecycle[]) => TagReactiveNode<K>;
112
- declare const toReactiveNode: <T extends Node>(node: T, handlers: Lifecycle[]) => ReactiveNode<T>;
113
- declare const reactiveTextNode: (text: string) => ReactiveNode<Text>;
114
-
115
- type InputChild<T extends Node, K extends keyof HTMLElementTagNameMap = keyof HTMLElementTagNameMap> = TagReactiveNode<K> | ReactiveNode<T> | string;
116
- declare const tag: <K extends keyof HTMLElementTagNameMap>(name: K, ...inputChildren: InputChild<Node>[]) => TagReactiveNode<K>;
117
- declare const tags: {
118
- img: (src: string) => TagReactiveNode<"img">;
119
- input: (type: string) => TagReactiveNode<"input">;
120
- canvas: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"canvas">;
121
- button: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"button">;
122
- h1: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"h1">;
123
- h2: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"h2">;
124
- h3: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"h3">;
125
- p: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"p">;
126
- a: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"a">;
127
- div: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"div">;
128
- ul: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"ul">;
129
- li: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"li">;
130
- span: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"span">;
131
- select: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"select">;
132
- };
133
-
134
90
  type Observables = Record<string, Observable<any>>;
135
91
  type ScopedObservables<T extends Observables> = {
136
92
  [K in keyof T]: ScopedObservable<T[K]>;
@@ -157,8 +113,8 @@ declare class Context<T extends Node, P> {
157
113
  type ReactiveNodeBuilder<T extends Node> = (() => ReactiveNode<T>);
158
114
  type Params<A extends Node, B extends Node> = {
159
115
  if$: Observable<boolean>;
160
- then: ReactiveNodeBuilder<A> | string;
161
- otherwise: ReactiveNodeBuilder<B> | string;
116
+ then?: ReactiveNodeBuilder<A> | string | undefined;
117
+ otherwise?: ReactiveNodeBuilder<B> | string | undefined;
162
118
  };
163
119
  declare const cond: <A extends Node, B extends Node>({ if$, then, otherwise }: Params<A, B>) => ReactiveNode<Comment>;
164
120
 
@@ -218,12 +174,7 @@ declare class ReactiveItem<T, N extends ReactiveNode<Node>> {
218
174
  type Hole = Observable<string> | string;
219
175
  declare const template: (strings: TemplateStringsArray, ...holes: Hole[]) => ReactiveNode<Comment>;
220
176
 
221
- type RouteKey<T extends RouteCollection<Node>> = keyof T & string;
222
- type RouteCollection<N extends Node> = Record<string, ReactiveNode<N>>;
223
- type RouterOpts<T extends RouteCollection<Node>> = {
224
- notFoundRoute: RouteKey<T>;
225
- };
226
- declare const router: <T extends RouteCollection<Node>>(routes: T, opts: RouterOpts<T>) => ReactiveNode<Comment>;
177
+ declare const reactiveTextNode: (text: string) => ReactiveNode<Text>;
227
178
 
228
179
  type Source<T> = Observable<Event<T>> & Updatable<Event<T>>;
229
180
  declare class ReactiveArray<T> {
@@ -239,4 +190,73 @@ declare class ReactiveArray<T> {
239
190
  private emit;
240
191
  }
241
192
 
242
- export { type BuildFn, type Collection, type Event, type InputChild, type Key, type KeyFn, type Observable, type Observer, ReactiveArray, ReactiveItem, ReactiveItemCollection, type ReactiveNode, type ReactiveNodeSetters, ScopedObservable, type TagReactiveNode, type TagReactiveNodeSetters, type Task, type TaskRunner, type Updatable, type UpdateFn, buildDedupMicrotaskRunner, buildMicrotaskRunner, component, cond, dedupMicrotaskRunner, dedupObservable, iterable, mapObservable, microtaskRunner, observable, reactiveTextNode, router, scopedObservable, tag, tags, template, toReactiveNode, toTagReactiveNode };
193
+ declare const inputObservable: <I extends "input" | "textarea" | "select">(input: TagReactiveNode<I>, value$: Observable<string> & Updatable<string>) => InputObservable<I>;
194
+ declare class InputObservable<I extends 'input' | 'textarea' | 'select'> implements Observable<string>, Updatable<string> {
195
+ private input;
196
+ private value$;
197
+ private aliases;
198
+ constructor(input: TagReactiveNode<I>, value$: Observable<string> & Updatable<string>);
199
+ subscribe(id: symbol, observer: Observer<string>): void;
200
+ subscribeInit(id: symbol, observer: Observer<string>): void;
201
+ unsubscribe(id: symbol): void;
202
+ unsubscribeAll(): void;
203
+ update(updateFn: UpdateFn<string>): void;
204
+ private toInputObserver;
205
+ }
206
+
207
+ type Observer<T> = (value: T) => void;
208
+ type UpdateFn<T> = (value: T) => T;
209
+ interface Observable<T> {
210
+ unsubscribeAll(): void;
211
+ unsubscribe(id: symbol): void;
212
+ subscribe(id: symbol, observer: Observer<T>): void;
213
+ subscribeInit(id: symbol, observer: Observer<T>): void;
214
+ }
215
+ interface Updatable<T> {
216
+ update(updateFn: UpdateFn<T>): void;
217
+ }
218
+ declare const once: <T extends any[]>(fn: (...values: T) => void, ...observables: { [K in keyof T]: Observable<T[K]>; }) => void;
219
+
220
+ type ReactiveNode<T extends Node> = Lifecycle & T & ReactiveNodeSetters<T>;
221
+ interface ReactiveNodeSetters<T extends Node> {
222
+ listen: <R extends ReactiveNode<T>>(this: R, type: string, cb: EventListenerOrEventListenerObject) => R;
223
+ clk: <R extends ReactiveNode<T>>(this: R, cb: EventListenerOrEventListenerObject) => R;
224
+ }
225
+ type TagReactiveNode<K extends keyof HTMLElementTagNameMap> = ReactiveNode<HTMLElementTagNameMap[K]> & TagReactiveNodeSetters<K>;
226
+ interface TagReactiveNodeSetters<K extends keyof HTMLElementTagNameMap> {
227
+ att: (name: string, value: string) => TagReactiveNode<K>;
228
+ class$: (value: Observable<string>) => TagReactiveNode<K>;
229
+ att$: (name: string, value: Observable<string>) => TagReactiveNode<K>;
230
+ prop$: <N extends keyof HTMLElementTagNameMap[K]>(name: N, value: Observable<HTMLElementTagNameMap[K][N]>) => TagReactiveNode<K>;
231
+ model$: <I extends 'input' | 'textarea' | 'select'>(this: TagReactiveNode<I>, value$: Observable<string> & Updatable<string>) => TagReactiveNode<I>;
232
+ }
233
+ declare const toTagReactiveNode: <K extends keyof HTMLElementTagNameMap>(node: HTMLElementTagNameMap[K], handlers: Lifecycle[]) => TagReactiveNode<K>;
234
+ declare const toReactiveNode: <T extends Node>(node: T, handlers: Lifecycle[]) => ReactiveNode<T>;
235
+
236
+ type InputChild<T extends Node, K extends keyof HTMLElementTagNameMap = keyof HTMLElementTagNameMap> = TagReactiveNode<K> | ReactiveNode<T> | string;
237
+ declare const tag: <K extends keyof HTMLElementTagNameMap>(name: K, ...inputChildren: InputChild<Node>[]) => TagReactiveNode<K>;
238
+ declare const tags: {
239
+ img: (src: string) => TagReactiveNode<"img">;
240
+ input: (type: string) => TagReactiveNode<"input">;
241
+ canvas: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"canvas">;
242
+ button: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"button">;
243
+ h1: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"h1">;
244
+ h2: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"h2">;
245
+ h3: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"h3">;
246
+ p: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"p">;
247
+ a: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"a">;
248
+ div: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"div">;
249
+ ul: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"ul">;
250
+ li: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"li">;
251
+ span: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"span">;
252
+ select: <T extends InputChild<Node>[]>(...children: T) => TagReactiveNode<"select">;
253
+ };
254
+
255
+ type RouteKey<T extends RouteCollection<Node>> = keyof T & string;
256
+ type RouteCollection<N extends Node> = Record<string, ReactiveNode<N>>;
257
+ type RouterOpts<T extends RouteCollection<Node>> = {
258
+ notFoundRoute: RouteKey<T>;
259
+ };
260
+ declare const router: <T extends RouteCollection<Node>>(routes: T, opts: RouterOpts<T>) => ReactiveNode<Comment>;
261
+
262
+ export { type BuildFn, type Collection, type Event, type InputChild, InputObservable, type Key, type KeyFn, type Observable, type Observer, ReactiveArray, ReactiveItem, ReactiveItemCollection, type ReactiveNode, type ReactiveNodeSetters, ScopedObservable, type TagReactiveNode, type TagReactiveNodeSetters, type Task, type TaskRunner, type Updatable, type UpdateFn, buildDedupMicrotaskRunner, buildMicrotaskRunner, component, cond, dedupMicrotaskRunner, dedupObservable, inputObservable, iterable, mapObservable, microtaskRunner, observable, once, reactiveTextNode, router, scopedObservable, tag, tags, template, toReactiveNode, toTagReactiveNode };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var c=(i=>(i[i.Active=0]="Active",i[i.Inactive=1]="Inactive",i[i.Mounted=2]="Mounted",i[i.Unmounted=3]="Unmounted",i))(c||{}),v=n=>{let e=3;return {mount:t=>{if(e!==3)return console.warn(`Mounting in status ${c[e]}`);for(let s of n)s.mount(t);e=2;},activate:()=>{if(e!==2&&e!==1)return console.warn(`Activating in status ${c[e]}`);for(let t of n)t.activate();e=0;},deactivate:()=>{if(e!==0)return console.warn(`Deactivating in status ${c[e]}`);for(let t of n)t.deactivate();e=1;},unmount(){if(e!==1)return console.warn(`Unmounting in status ${c[e]}`);for(let t of n)t.unmount();e=3;}}};var k=(n,e)=>{let t=[...e],s=L(t),i=K(t),o=v(t);return Object.assign(n,i,s,o)},d=(n,e)=>{let t=[...e],s=K(t),i=v(t);return Object.assign(n,s,i)},u=n=>{let e=document.createTextNode(n);return d(e,[{mount:s=>s.appendChild(e),activate:()=>{},deactivate:()=>{},unmount:()=>e.remove()}])},L=n=>({att:function(e,t){return this.setAttribute(e,t),this},att$:function(e,t){let s=Symbol(`Attribute: ${e}`);return n.push({mount:i=>{},activate:()=>t.subscribeInit(s,i=>this.setAttribute(e,i)),deactivate:()=>t.unsubscribe(s),unmount:()=>{}}),this}}),K=n=>({clk:function(e){return n.push({mount:t=>{},activate:()=>this.addEventListener("click",e),deactivate:()=>this.removeEventListener("click",e),unmount:()=>{}}),this}});var r=(n,...e)=>{let t=document.createElement(n),s=[];for(let i of e)if(typeof i=="string")s.push(u(i));else if(i instanceof Node)s.push(i);else throw new Error("Unsupported child type");return k(t,[{mount:i=>{i.appendChild(t);for(let o of s)o.mount(t);},activate:()=>{for(let i of s)i.activate();},deactivate:()=>{for(let i of s)i.deactivate();},unmount:()=>{for(let i of s)i.unmount();t.remove();}}])},z={img:n=>r("img").att("src",n),input:n=>r("input").att("type",n),canvas:(...n)=>r("canvas",...n),button:(...n)=>r("button",...n),h1:(...n)=>r("h1",...n),h2:(...n)=>r("h2",...n),h3:(...n)=>r("h3",...n),p:(...n)=>r("p",...n),a:(...n)=>r("a",...n),div:(...n)=>r("div",...n),ul:(...n)=>r("ul",...n),li:(...n)=>r("li",...n),span:(...n)=>r("span",...n),select:(...n)=>r("select",...n)};var A=()=>{let n=new Set,e=()=>queueMicrotask(()=>{let t=Array.from(n);n.clear();for(let s of t)s();});return t=>{n.has(t)||(n.add(t),!(n.size>1)&&e());}},I=A(),V=()=>{let n=[],e=()=>queueMicrotask(()=>{let t=n.toReversed();n.length=0;for(let s of t)s();});return t=>{n.push(t),n.length==1&&e();}},C=V();var S=(n,e={microtaskRunner:I})=>new p(n,e),p=class{constructor(e,t){this.value=e;this.opts=t;this.observers=new Map;}unsubscribeAll(){this.observers.clear();}unsubscribe(e){this.observers.delete(e);}subscribe(e,t){this.observers.has(e)&&console.warn("Duplicate observer id",e),this.observers.set(e,t);}subscribeInit(e,t){this.subscribe(e,t),this.notify(e,t);}update(e){this.value=e(this.value),this.opts.microtaskRunner(this.notifyAll.bind(this));}notify(e,t){try{this.observers.get(e)===t&&t(this.value);}catch(s){console.error(s);}}notifyAll(){for(let[e,t]of this.observers.entries())this.notify(e,t);}};var w=(n,...e)=>new h(n,e),h=class{constructor(e,t){this.mapFn=e;this.observables=t;this.observers=new Map;this.initializedIndices=new Set;this.ids=t.map(s=>Symbol("MapObservable")),this.currentValues=[];}unsubscribeAll(){this.observers.clear(),this.innerUnubscribe();}unsubscribe(e){this.observers.delete(e),this.innerUnubscribe();}subscribe(e,t){this.observers.set(e,t),this.innerSubscribe();}subscribeInit(e,t){this.subscribe(e,t);}notifyObservers(e){return t=>{if(this.currentValues[e]=t,this.initializedIndices.add(e),this.initializedIndices.size===this.currentValues.length)for(let s of this.observers.values())s(this.mapFn(...this.currentValues));}}innerSubscribe(){if(this.observers.size===1)for(let[e,t]of this.observables.entries())t.subscribeInit(this.ids[e],this.notifyObservers(e));}innerUnubscribe(){if(this.observers.size===0)for(let[e,t]of this.observables.entries())t.unsubscribe(this.ids[e]);}};var F=(n,e=(s,i)=>s==i,t=s=>s)=>new m(n,e,t),m=class{constructor(e,t,s){this.innerObservable=e;this.compareEqualFn=t;this.cloneFn=s;this.id=Symbol("DedupObservable");this.currentValue=void 0;this.isInitialized=false;this.observers=new Map;}unsubscribeAll(){this.observers.clear(),this.innerUnubscribe();}unsubscribe(e){this.observers.delete(e),this.innerUnubscribe();}subscribe(e,t){this.observers.set(e,t),this.innerSubscribe();}subscribeInit(e,t){this.subscribe(e,t);}innerSubscribe(){this.observers.size===1&&this.innerObservable.subscribeInit(this.id,this.updateValue.bind(this));}updateValue(e){if(!(this.isInitialized&&this.compareEqualFn(this.currentValue,e))){this.currentValue=this.cloneFn(e),this.isInitialized=true;for(let t of this.observers.values())t(this.currentValue);}}innerUnubscribe(){this.observers.size===0&&(this.currentValue=void 0,this.isInitialized=false,this.innerObservable.unsubscribe(this.id));}};var E=n=>new f(n),f=class{constructor(e){this.innerObservable=e;this.aliases=new Map;}unsubscribeAll(){for(let e of this.aliases.values())this.innerObservable.unsubscribe(e);this.aliases.clear();}unsubscribe(e){let t=this.aliases.get(e);t!==void 0&&(this.aliases.delete(e),this.innerObservable.unsubscribe(t));}subscribe(e,t){let s=Symbol("ScopedObservable");this.aliases.set(e,s),this.innerObservable.subscribe(s,t);}subscribeInit(e,t){let s=Symbol("ScopedObservable");this.aliases.set(e,s),this.innerObservable.subscribeInit(s,t);}update(e){"update"in this.innerObservable&&this.innerObservable.update(e);}};var P={observables:()=>({}),derivedObservables:()=>({}),cache:false,props:{}},Z=n=>new N(Object.assign({},P,n)).toReactiveNode(),T=class{constructor(e,t){this.parent=e;this.props=t;}},N=class{constructor(e){this.opts=e;}toReactiveNode(){return d(document.createComment("Component"),[{mount:e=>{var t;(this.node===void 0||!this.opts.cache)&&this.setupNode(e),(t=this.node)==null||t.mount(e);},activate:()=>{var e;return (e=this.node)==null?void 0:e.activate()},deactivate:()=>{var e;if((e=this.node)==null||e.deactivate(),this.observables!==void 0)for(let t in this.observables)this.observables[t].unsubscribeAll();},unmount:()=>{var e;(e=this.node)==null||e.unmount(),this.opts.cache||this.cleanUp();}}])}setupNode(e){this.observables=this.buildObservables(),this.context=new T(e,this.opts.props),this.node=this.opts.render.call(this.context,this.observables),this.context.node=this.node;}cleanUp(){this.context!==void 0&&(this.context.node=void 0),this.node=void 0,this.observables=void 0;}buildObservables(){let e=this.opts.observables(),t=this.opts.derivedObservables(e),s=Object.assign({},e,t);return this.toScoped(s)}toScoped(e){let t={};for(let s in e){let i=s;t[i]=E(e[i]);}return t}};var ne=({if$:n,then:e,otherwise:t})=>new y(F(n),e,t).toReactiveNode(),y=class{constructor(e,t,s){this.if$=e;this.then=t;this.otherwise=s;this.id=Symbol("Cond");}toReactiveNode(){let e=document.createComment("Cond"),t=s=>this.updateNode(e,s);return d(e,[{mount:s=>s.appendChild(e),activate:()=>this.if$.subscribeInit(this.id,t),deactivate:()=>{var s;this.if$.unsubscribe(this.id),(s=this.currentNode)==null||s.deactivate();},unmount:()=>{var s;(s=this.currentNode)==null||s.unmount(),this.currentNode=void 0,e.remove();}}])}updateNode(e,t){let s=t?this.buildNode(this.then):this.buildNode(this.otherwise);try{this.switchNode(e,s);}catch(i){console.error(i);}}buildNode(e){if(typeof e=="function")return e();if(typeof e=="string")return u(e);throw new Error("Then/otherwise should be either string or function")}switchNode(e,t){var s,i;(s=this.currentNode)==null||s.deactivate(),(i=this.currentNode)==null||i.unmount(),t.mount(e.parentNode),t.activate(),this.currentNode=t;}};var l=class{constructor(e,t,s){this.anchor=e;this.value=t;this.node=s;}mount(e){let t=this.anchor.parentNode,s=(e==null?void 0:e.node.nextSibling)||null;t!==null&&(this.node.parentNode===null&&this.node.mount(t),t.insertBefore(this.node,s));}activate(e){this.generationId===void 0&&this.node.activate(),this.generationId=e;}deactivate(){this.node.deactivate();}unmount(){this.node.unmount();}};var b=class{constructor(e,t){this.keyFn=e;this.buildFn=t;this.generationId=0;this.items=new Map;}deactivate(){for(let e of this.items.values())e.deactivate();}unmount(){for(let e of this.items.values())e.unmount();this.items.clear(),this.generationId=0;}replace(e,t){this.generationId++;let s=null;for(let[i,o]of t.entries()){let a=this.keyFn(i,o),g=this.getOrInsert(e,s,a,o);g.generationId=this.generationId,s=g;}this.removeStaleItems();}replaceKeys(e,t){for(let[s,i]of t.entries()){let o=this.keyFn(s,i),a=this.items.get(o);a!==void 0&&(this.insertItem(e,a,o,i),a.deactivate(),a.unmount());}}append(e,t){for(let[s,i]of t.entries()){let o=this.keyFn(s,i);this.insertItem(e,null,o,i);}}remove(e){for(let[t,s]of e.entries()){let i=this.keyFn(t,s),o=this.items.get(i);o!==void 0&&(o.deactivate(),o.unmount(),this.items.delete(i));}}getOrInsert(e,t,s,i){let o=this.items.get(s);return o===void 0?this.insertItem(e,t,s,i):o.value===i?o:(o.deactivate(),o.unmount(),this.insertItem(e,t,s,i))}insertItem(e,t,s,i){let o=this.buildFn(s,i),a=new l(e,i,o);return a.mount(t),a.activate(this.generationId),this.items.set(s,a),a}removeStaleItems(){for(let[e,t]of this.items.entries())t.generationId!==this.generationId&&(t.deactivate(),t.unmount(),this.items.delete(e));}};var le=({it$:n,buildFn:e,keyFn:t})=>new O(n,e,t).toReactiveNode(),O=class{constructor(e,t,s){this.id=Symbol("Iterable");this.it$=this.toEventObservable(e),this.items=new b(s,t);}toReactiveNode(){let e=document.createComment("Iterable"),t=s=>{switch(s.type){case "replace":return this.items.replace(e,s.items);case "replaceKeys":return this.items.replaceKeys(e,s.items);case "append":return this.items.append(e,s.items);case "remove":return this.items.remove(s.items);default:return console.warn("Unsupported event type",s)}};return d(e,[{mount:s=>s.appendChild(e),activate:()=>this.it$.subscribeInit(this.id,t),deactivate:()=>{this.it$.unsubscribe(this.id),this.items.deactivate();},unmount:()=>{this.items.unmount(),e.remove();}}])}toEventObservable(e){return w(t=>t instanceof Array||t instanceof Map?{type:"replace",items:t}:t,e)}};var pe=(n,...e)=>new x(n,e).toReactiveNode(),x=class{constructor(e,t){this.strings=e;this.holes=t;}toReactiveNode(){let e=this.buildNodes(),t=document.createComment("Template");return d(t,[{mount:s=>this.appendNodes(s,e),activate:()=>{for(let s of e)this.attachObservable(s);},deactivate:()=>{for(let s of e)this.detachObservable(s);},unmount:()=>this.removeNodes(e)}])}buildNodes(){return this.strings.map((e,t)=>{let s=this.holes[t],i={staticNodes:[document.createTextNode(e)],dynamicNode:void 0};return typeof s=="string"?i.staticNodes.push(document.createTextNode(s)):typeof s=="object"&&s!==null&&(i.dynamicNode={node:document.createTextNode(""),observerId:Symbol(`Template${t}`),observable:s}),i})}appendNodes(e,t){for(let{staticNodes:s,dynamicNode:i}of t){for(let o of s)e.appendChild(o);i!==void 0&&e.appendChild(i.node);}}attachObservable(e){if(e===void 0||e.dynamicNode===void 0)return;let{node:t,observerId:s,observable:i}=e.dynamicNode;i.subscribeInit(s,o=>t.data=o);}removeNodes(e){for(let{staticNodes:t,dynamicNode:s}of e){for(let i of t)i.remove();s!==void 0&&s.node.remove();}}detachObservable(e){if(e.dynamicNode===void 0)return;let{observerId:t,observable:s}=e.dynamicNode;s.unsubscribe(t);}};var Te=(n,e)=>new R(n,e).toReactiveNode(),R=class{constructor(e,t){this.routes=e;this.opts=t;this.hashChangeListener=()=>this.syncHash();}toReactiveNode(){let e=document.createComment("Router");return d(e,[{mount:t=>{if(this.anchor!==void 0)return console.warn("Router is already active");this.anchor=e,t.appendChild(e);},activate:()=>{this.syncHash(),window.addEventListener("hashchange",this.hashChangeListener);},deactivate:()=>{var t;window.removeEventListener("hashchange",this.hashChangeListener),(t=this.currentRoute)==null||t.deactivate();},unmount:()=>{var t;(t=this.currentRoute)==null||t.unmount(),this.currentRoute=void 0,e.remove();}}])}syncHash(){var t,s;let e=this.getNewRoute();e===this.currentRoute||e===void 0||((t=this.currentRoute)==null||t.deactivate(),(s=this.currentRoute)==null||s.unmount(),this.currentRoute=e,C(()=>{var o;let i=(o=this.anchor)==null?void 0:o.parentElement;i!=null&&(e.mount(i),e.activate());}));}getNewRoute(){let e=location.hash.slice(1)||"/",t=this.isRouteKey(e)?e:this.opts.notFoundRoute;return this.routes[t]}isRouteKey(e){return e in this.routes}};var M=class{constructor(e=[]){this.items=e;this.observables=[];}get observable$(){let e=S({type:"replace",items:this.items});return this.observables.push(new WeakRef(e)),e}push(...e){this.items.push(...e),this.emit({type:"append",items:e});}pop(){if(this.items.length===0)return;let e=this.items.length-1,t=this.items.pop();return this.emit({type:"remove",items:new Map().set(e,t)}),t}remove(e){if(e.length==0)return;let t=new Map;for(let s of e)s in this.items&&(t.set(s,this.items[s]),delete this.items[s]);this.emit({type:"remove",items:t});}replace(e){this.items=e,this.emit({type:"replace",items:e});}replaceKeys(e){for(let[t,s]of e.entries())t in this.items&&(this.items[t]=s);this.emit({type:"replaceKeys",items:e});}emit(e){var s;let t=i=>e;for(let i of this.observables)(s=i.deref())==null||s.update(t);}};export{M as ReactiveArray,l as ReactiveItem,b as ReactiveItemCollection,f as ScopedObservable,A as buildDedupMicrotaskRunner,V as buildMicrotaskRunner,Z as component,ne as cond,I as dedupMicrotaskRunner,F as dedupObservable,le as iterable,w as mapObservable,C as microtaskRunner,S as observable,u as reactiveTextNode,Te as router,E as scopedObservable,r as tag,z as tags,pe as template,d as toReactiveNode,k as toTagReactiveNode};//# sourceMappingURL=index.js.map
1
+ var u=(i,...e)=>new p(i,e),p=class{constructor(e,t){this.mapFn=e;this.observables=t;this.observers=new Map;this.initializedIndices=new Set;this.ids=t.map(s=>Symbol("MapObservable")),this.currentValues=[];}unsubscribeAll(){this.observers.clear(),this.innerUnubscribe();}unsubscribe(e){this.observers.delete(e),this.innerUnubscribe();}subscribe(e,t){if(this.observers.has(e))return console.warn(`Duplicate observer id ${e.toString()}`);this.observers.set(e,t),this.innerSubscribe();}subscribeInit(e,t){if(this.subscribe(e,t),this.initializedIndices.size!==this.ids.length||this.observers.size==1)return;let s=this.mapFn(...this.currentValues);t(s);}notifyObservers(e){return t=>{if(this.currentValues[e]=t,this.initializedIndices.add(e),this.initializedIndices.size!==this.ids.length)return;let s=this.mapFn(...this.currentValues);for(let n of this.observers.values())n(s);}}innerSubscribe(){if(this.observers.size===1)for(let[e,t]of this.observables.entries())t.subscribeInit(this.ids[e],this.notifyObservers(e));}innerUnubscribe(){if(this.observers.size===0){for(let[e,t]of this.observables.entries())t.unsubscribe(this.ids[e]);this.initializedIndices.clear();}}};var $=()=>{let i=new Set,e=()=>queueMicrotask(()=>{let t=Array.from(i);i.clear();for(let s of t)s();});return t=>{i.has(t)||(i.add(t),!(i.size>1)&&e());}},K=$(),V=()=>{let i=[],e=()=>queueMicrotask(()=>{let t=i.toReversed();i.length=0;for(let s of t)s();});return t=>{i.push(t),i.length==1&&e();}},C=V();var S=(i,e={microtaskRunner:K})=>new h(i,e),h=class{constructor(e,t){this.value=e;this.opts=t;this.observers=new Map;}unsubscribeAll(){this.observers.clear();}unsubscribe(e){this.observers.delete(e);}subscribe(e,t){this.observers.has(e)&&console.warn("Duplicate observer id",e),this.observers.set(e,t);}subscribeInit(e,t){this.subscribe(e,t),this.notify(e,t);}update(e){this.value=e(this.value),this.opts.microtaskRunner(this.notifyAll.bind(this));}notifyAll(){for(let[e,t]of this.observers.entries())this.notify(e,t);}notify(e,t){try{this.observers.get(e)===t&&t(this.value);}catch(s){console.error(s);}}};var M=(i,e=(s,n)=>s==n,t=s=>s)=>new m(i,e,t),m=class{constructor(e,t,s){this.innerObservable=e;this.compareEqualFn=t;this.cloneFn=s;this.id=Symbol("DedupObservable");this.currentValue=void 0;this.isInitialized=false;this.observers=new Map;}unsubscribeAll(){this.observers.clear(),this.innerUnubscribe();}unsubscribe(e){this.observers.delete(e),this.innerUnubscribe();}subscribe(e,t){this.observers.set(e,t),this.innerSubscribe();}subscribeInit(e,t){this.subscribe(e,t),!(this.observers.size===1||!this.isInitialized)&&t(this.currentValue);}innerSubscribe(){this.observers.size===1&&this.innerObservable.subscribeInit(this.id,this.updateValue.bind(this));}updateValue(e){if(!(this.isInitialized&&this.compareEqualFn(this.currentValue,e))){this.currentValue=this.cloneFn(e),this.isInitialized=true;for(let t of this.observers.values())t(this.currentValue);}}innerUnubscribe(){this.observers.size===0&&(this.currentValue=void 0,this.isInitialized=false,this.innerObservable.unsubscribe(this.id));}};var E=i=>new f(i),f=class{constructor(e){this.innerObservable=e;this.aliases=new Map;}unsubscribeAll(){for(let e of this.aliases.values())this.innerObservable.unsubscribe(e);this.aliases.clear();}unsubscribe(e){let t=this.aliases.get(e);t!==void 0&&(this.aliases.delete(e),this.innerObservable.unsubscribe(t));}subscribe(e,t){let s=Symbol("ScopedObservable");this.aliases.set(e,s),this.innerObservable.subscribe(s,t);}subscribeInit(e,t){let s=Symbol("ScopedObservable");this.aliases.set(e,s),this.innerObservable.subscribeInit(s,t);}update(e){"update"in this.innerObservable&&this.innerObservable.update(e);}};var F=(i,e)=>new T(i,e),T=class{constructor(e,t){this.input=e;this.value$=t;this.aliases=new Map;}subscribe(e,t){if(this.aliases.has(e))return;let s=Symbol("InputObservable");this.aliases.set(e,[s,t]),this.value$.subscribe(s,this.toInputObserver(t));}subscribeInit(e,t){if(this.aliases.has(e))return;let s=Symbol("InputObservable");this.aliases.set(e,[s,t]),this.value$.subscribeInit(s,this.toInputObserver(t));}unsubscribe(e){let t=this.aliases.get(e);t!==void 0&&(this.value$.unsubscribe(t[0]),this.aliases.delete(e));}unsubscribeAll(){for(let[e,t]of this.aliases.values())this.value$.unsubscribe(e);this.aliases.clear();}update(e){this.value$.update(e);}toInputObserver(e){return t=>{this.input.value!==t&&e(t);}}};var G=(i,...e)=>{let t=Symbol("Once"),s=u((...n)=>n,...e);s.subscribeInit(t,n=>{s.unsubscribe(t),i(...n);});};var c=(n=>(n[n.Active=0]="Active",n[n.Inactive=1]="Inactive",n[n.Mounted=2]="Mounted",n[n.Unmounted=3]="Unmounted",n))(c||{}),N=i=>{let e=3;return {mount:t=>{if(e!==3)return console.warn(`Mounting in status ${c[e]}`);for(let s of i)s.mount(t);e=2;},activate:()=>{if(e!==2&&e!==1)return console.warn(`Activating in status ${c[e]}`);for(let t of i)t.activate();e=0;},deactivate:()=>{if(e!==0)return console.warn(`Deactivating in status ${c[e]}`);for(let t of i)t.deactivate();e=1;},unmount(){if(e!==1)return console.warn(`Unmounting in status ${c[e]}`);for(let t of i)t.unmount();e=3;}}};var w=(i,e)=>{let t=[...e],s=A(t),n=L(t),r=N(t);return Object.assign(i,n,s,r)},a=(i,e)=>{let t=[...e],s=L(t),n=N(t);return Object.assign(i,s,n)},A=i=>({att:function(e,t){return this.setAttribute(e,t),this},class$:function(e){return this.att$("class",e)},att$:function(e,t){let s=Symbol(`Attribute: ${e}`);return i.push({mount:n=>{},activate:()=>t.subscribeInit(s,n=>this.setAttribute(e,n)),deactivate:()=>t.unsubscribe(s),unmount:()=>{}}),this},model$:function(e){let t=F(this,e);return this.prop$("value",t).listen("input",s=>t.update(n=>this.value))},prop$:function(e,t){let s=Symbol(`Property: ${e.toString()}`);return i.push({mount:n=>{},activate:()=>t.subscribeInit(s,n=>this[e]=n),deactivate:()=>t.unsubscribe(s),unmount:()=>{}}),this}}),L=i=>({clk:function(e){return this.listen("click",e)},listen:function(e,t){return i.push({mount:s=>{},activate:()=>this.addEventListener(e,t),deactivate:()=>this.removeEventListener(e,t),unmount:()=>{}}),this}});var P={observables:()=>({}),derivedObservables:()=>({}),cache:false,props:{}},de=i=>new O(Object.assign({},P,i)).toReactiveNode(),y=class{constructor(e,t){this.parent=e;this.props=t;}},O=class{constructor(e){this.opts=e;}toReactiveNode(){return a(document.createComment("Component"),[{mount:e=>{var t;(this.node===void 0||!this.opts.cache)&&this.setupNode(e),(t=this.node)==null||t.mount(e);},activate:()=>{var e;return (e=this.node)==null?void 0:e.activate()},deactivate:()=>{var e,t;if((e=this.node)==null||e.deactivate(),this.observables!==void 0)for(let s in this.observables)(t=this.observables[s])==null||t.unsubscribeAll();},unmount:()=>{var e;(e=this.node)==null||e.unmount(),this.opts.cache||this.cleanUp();}}])}setupNode(e){this.observables=this.buildObservables(),this.context=new y(e,this.opts.props),this.node=this.opts.render.call(this.context,this.observables),this.context.node=this.node;}cleanUp(){this.context!==void 0&&(this.context.node=void 0),this.node=void 0,this.observables=void 0;}buildObservables(){let e=this.opts.observables(),t=this.opts.derivedObservables(e),s=Object.assign({},e,t);return this.toScoped(s)}toScoped(e){let t={};for(let s in e){let n=s;t[n]=E(e[n]);}return t}};var U=class{constructor(e=[]){this.items=e;this.observables=[];}get observable$(){let e=S({type:"replace",items:this.items});return this.observables.push(new WeakRef(e)),e}push(...e){this.items.push(...e),this.emit({type:"append",items:e});}pop(){if(this.items.length===0)return;let e=this.items.length-1,t=this.items.pop();return this.emit({type:"remove",items:new Map().set(e,t)}),t}remove(e){if(e.length==0)return;let t=new Map;for(let s of e)s in this.items&&(t.set(s,this.items[s]),delete this.items[s]);this.emit({type:"remove",items:t});}replace(e){this.items=e,this.emit({type:"replace",items:e});}replaceKeys(e){for(let[t,s]of e.entries())t in this.items&&(this.items[t]=s);this.emit({type:"replaceKeys",items:e});}emit(e){var s;let t=n=>e;for(let n of this.observables)(s=n.deref())==null||s.update(t);}};var l=i=>{let e=document.createTextNode(i);return a(e,[{mount:s=>s.appendChild(e),activate:()=>{},deactivate:()=>{},unmount:()=>e.remove()}])};var fe=({if$:i,then:e,otherwise:t})=>new x(M(i),e,t).toReactiveNode(),x=class{constructor(e,t,s){this.if$=e;this.then=t;this.otherwise=s;this.id=Symbol("Cond");}toReactiveNode(){let e=document.createComment("Cond"),t=s=>this.updateNode(e,s);return a(e,[{mount:s=>s.appendChild(e),activate:()=>this.if$.subscribeInit(this.id,t),deactivate:()=>{var s;this.if$.unsubscribe(this.id),(s=this.currentNode)==null||s.deactivate();},unmount:()=>{var s;(s=this.currentNode)==null||s.unmount(),this.currentNode=void 0,e.remove();}}])}updateNode(e,t){let s=t?this.buildNode(this.then):this.buildNode(this.otherwise);try{this.switchNode(e,s);}catch(n){console.error(n);}}buildNode(e){if(typeof e=="function")return e();if(typeof e=="string")return l(e);if(e!==void 0)throw new Error("Then/otherwise should be either string or function")}switchNode(e,t){var s,n,r;(s=this.currentNode)==null||s.deactivate(),(n=this.currentNode)==null||n.unmount(),this.currentNode=t,t!==void 0&&(t.mount(e.parentNode),(r=e.parentNode)==null||r.insertBefore(t,e.nextSibling),t.activate());}};var b=class{constructor(e,t,s){this.anchor=e;this.value=t;this.node=s;}mount(e){let t=this.anchor.parentNode,s=(e==null?void 0:e.node.nextSibling)||null;t!==null&&(this.node.parentNode===null&&this.node.mount(t),t.insertBefore(this.node,s));}activate(e){this.generationId===void 0&&this.node.activate(),this.generationId=e;}deactivate(){this.node.deactivate();}unmount(){this.node.unmount();}};var v=class{constructor(e,t){this.keyFn=e;this.buildFn=t;this.generationId=0;this.items=new Map;}deactivate(){for(let e of this.items.values())e.deactivate();}unmount(){for(let e of this.items.values())e.unmount();this.items.clear(),this.generationId=0;}replace(e,t){this.generationId++;let s=null;for(let[n,r]of t.entries()){let d=this.keyFn(n,r),k=this.getOrInsert(e,s,d,r);k.generationId=this.generationId,s=k;}this.removeStaleItems();}replaceKeys(e,t){for(let[s,n]of t.entries()){let r=this.keyFn(s,n),d=this.items.get(r);d!==void 0&&(this.insertItem(e,d,r,n),d.deactivate(),d.unmount());}}append(e,t){for(let[s,n]of t.entries()){let r=this.keyFn(s,n);this.insertItem(e,null,r,n);}}remove(e){for(let[t,s]of e.entries()){let n=this.keyFn(t,s),r=this.items.get(n);r!==void 0&&(r.deactivate(),r.unmount(),this.items.delete(n));}}getOrInsert(e,t,s,n){let r=this.items.get(s);return r===void 0?this.insertItem(e,t,s,n):r.value===n?r:(r.deactivate(),r.unmount(),this.insertItem(e,t,s,n))}insertItem(e,t,s,n){let r=this.buildFn(s,n),d=new b(e,n,r);return d.mount(t),d.activate(this.generationId),this.items.set(s,d),d}removeStaleItems(){for(let[e,t]of this.items.entries())t.generationId!==this.generationId&&(t.deactivate(),t.unmount(),this.items.delete(e));}};var Ie=({it$:i,buildFn:e,keyFn:t})=>new R(i,e,t).toReactiveNode(),R=class{constructor(e,t,s){this.id=Symbol("Iterable");this.it$=this.toEventObservable(e),this.items=new v(s,t);}toReactiveNode(){let e=document.createComment("Iterable"),t=s=>{switch(s.type){case "replace":return this.items.replace(e,s.items);case "replaceKeys":return this.items.replaceKeys(e,s.items);case "append":return this.items.append(e,s.items);case "remove":return this.items.remove(s.items);default:return console.warn("Unsupported event type",s)}};return a(e,[{mount:s=>s.appendChild(e),activate:()=>this.it$.subscribeInit(this.id,t),deactivate:()=>{this.it$.unsubscribe(this.id),this.items.deactivate();},unmount:()=>{this.items.unmount(),e.remove();}}])}toEventObservable(e){return u(t=>t instanceof Array||t instanceof Map?{type:"replace",items:t}:t,e)}};var Ce=(i,...e)=>new g(i,e).toReactiveNode(),g=class{constructor(e,t){this.strings=e;this.holes=t;}toReactiveNode(){let e=this.buildNodes(),t=document.createComment("Template");return a(t,[{mount:s=>this.appendNodes(s,e),activate:()=>{for(let s of e)this.attachObservable(s);},deactivate:()=>{for(let s of e)this.detachObservable(s);},unmount:()=>this.removeNodes(e)}])}buildNodes(){return this.strings.map((e,t)=>{let s=this.holes[t],n={staticNodes:[document.createTextNode(e)],dynamicNode:void 0};return typeof s=="string"?n.staticNodes.push(document.createTextNode(s)):typeof s=="object"&&s!==null&&(n.dynamicNode={node:document.createTextNode(""),observerId:Symbol(`Template${t}`),observable:s}),n})}appendNodes(e,t){for(let{staticNodes:s,dynamicNode:n}of t){for(let r of s)e.appendChild(r);n!==void 0&&e.appendChild(n.node);}}attachObservable(e){if(e===void 0||e.dynamicNode===void 0)return;let{node:t,observerId:s,observable:n}=e.dynamicNode;n.subscribeInit(s,r=>t.data=r);}removeNodes(e){for(let{staticNodes:t,dynamicNode:s}of e){for(let n of t)n.remove();s!==void 0&&s.node.remove();}}detachObservable(e){if(e.dynamicNode===void 0)return;let{observerId:t,observable:s}=e.dynamicNode;s.unsubscribe(t);}};var o=(i,...e)=>{let t=document.createElement(i),s=[];for(let n of e)if(typeof n=="string")s.push(l(n));else if(n instanceof Node)s.push(n);else throw new Error("Unsupported child type");return w(t,[{mount:n=>{n.appendChild(t);for(let r of s)r.mount(t);},activate:()=>{for(let n of s)n.activate();},deactivate:()=>{for(let n of s)n.deactivate();},unmount:()=>{for(let n of s)n.unmount();t.remove();}}])},Fe={img:i=>o("img").att("src",i),input:i=>o("input").att("type",i),canvas:(...i)=>o("canvas",...i),button:(...i)=>o("button",...i),h1:(...i)=>o("h1",...i),h2:(...i)=>o("h2",...i),h3:(...i)=>o("h3",...i),p:(...i)=>o("p",...i),a:(...i)=>o("a",...i),div:(...i)=>o("div",...i),ul:(...i)=>o("ul",...i),li:(...i)=>o("li",...i),span:(...i)=>o("span",...i),select:(...i)=>o("select",...i)};var $e=(i,e)=>new I(i,e).toReactiveNode(),I=class{constructor(e,t){this.routes=e;this.opts=t;this.hashChangeListener=()=>this.syncHash();}toReactiveNode(){let e=document.createComment("Router");return a(e,[{mount:t=>{if(this.anchor!==void 0)return console.warn("Router is already active");this.anchor=e,t.appendChild(e);},activate:()=>{this.syncHash(),window.addEventListener("hashchange",this.hashChangeListener);},deactivate:()=>{var t;window.removeEventListener("hashchange",this.hashChangeListener),(t=this.currentRoute)==null||t.deactivate();},unmount:()=>{var t;(t=this.currentRoute)==null||t.unmount(),this.currentRoute=void 0,e.remove();}}])}syncHash(){var t,s;let e=this.getNewRoute();e===this.currentRoute||e===void 0||((t=this.currentRoute)==null||t.deactivate(),(s=this.currentRoute)==null||s.unmount(),this.currentRoute=e,C(()=>{var r;let n=(r=this.anchor)==null?void 0:r.parentElement;n!=null&&(e.mount(n),e.activate());}));}getNewRoute(){let e=location.hash.slice(1)||"/",t=this.isRouteKey(e)?e:this.opts.notFoundRoute;return this.routes[t]}isRouteKey(e){return e in this.routes}};export{T as InputObservable,U as ReactiveArray,b as ReactiveItem,v as ReactiveItemCollection,f as ScopedObservable,$ as buildDedupMicrotaskRunner,V as buildMicrotaskRunner,de as component,fe as cond,K as dedupMicrotaskRunner,M as dedupObservable,F as inputObservable,Ie as iterable,u as mapObservable,C as microtaskRunner,S as observable,G as once,l as reactiveTextNode,$e as router,E as scopedObservable,o as tag,Fe as tags,Ce as template,a as toReactiveNode,w as toTagReactiveNode};//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realglebivanov/reactive",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "A simple and permissive observable-driven UI toolkit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",