+1
-1
| export { DomEntity, ElementClassDescriptor, ElementDescriptor, DOMContent, DomHelper, StyleAccessor, JelEntity } from "./internal/types"; | ||
| import { $ } from "./internal/element"; | ||
| export { createEntity } from "./internal/util"; | ||
| export { createEventSource, interval } from "./internal/emitter"; | ||
| export { createEventSource, interval, timeout, SubjectEmitter, toEventEmitter } from "./internal/emitter"; | ||
| export { $ }; | ||
| export declare const $body: import(".").DomEntity<HTMLElement>; |
+1
-1
| import { $ } from "./internal/element"; | ||
| export { createEntity } from "./internal/util"; | ||
| export { createEventSource, interval } from "./internal/emitter"; | ||
| export { createEventSource, interval, timeout, SubjectEmitter, toEventEmitter } from "./internal/emitter"; | ||
| export { $ }; | ||
| export const $body = $(document.body); |
@@ -1,2 +0,2 @@ | ||
| import { DomHelper, Listenable } from "./types"; | ||
| import { DomHelper, EmitterLike } from "./types"; | ||
| export declare const $: DomHelper; | ||
@@ -7,7 +7,7 @@ export declare class ClassAccessor { | ||
| private unlisten; | ||
| constructor(classList: DOMTokenList, listen: (className: string, stream: Listenable<boolean>) => void, unlisten: (classNames: string[]) => void); | ||
| constructor(classList: DOMTokenList, listen: (className: string, stream: EmitterLike<boolean>) => void, unlisten: (classNames: string[]) => void); | ||
| add(...className: string[]): void; | ||
| remove(...className: string[]): void; | ||
| toggle(className: string, value?: boolean): boolean; | ||
| toggle(className: string, value: Listenable<boolean>): void; | ||
| toggle(className: string, value: EmitterLike<boolean>): void; | ||
| contains(className: string): boolean; | ||
@@ -14,0 +14,0 @@ get length(): number; |
+10
-10
| import { attribsProxy, eventsProxy, styleProxy } from "./proxy"; | ||
| import { entityDataSymbol, isContent, isJelEntity } from "./util"; | ||
| import { entityDataSymbol, isContent, isJelEntity, isReactiveSource } from "./util"; | ||
| const elementWrapCache = new WeakMap(); | ||
@@ -21,5 +21,5 @@ const recursiveAppend = (parent, c) => { | ||
| if (isContent(descriptor)) | ||
| return createElement(tag, { | ||
| descriptor = { | ||
| content: descriptor, | ||
| }); | ||
| }; | ||
| const domElement = document.createElement(tag); | ||
@@ -72,2 +72,4 @@ const ent = getWrappedElement(domElement); | ||
| } | ||
| if (descriptor.init) | ||
| descriptor.init(ent); | ||
| return ent; | ||
@@ -137,6 +139,2 @@ } | ||
| } | ||
| function isReactiveSource(value) { | ||
| return typeof value == "object" && value && (("listen" in value && typeof value.listen == "function") | ||
| || ("subscribe" in value && typeof value.subscribe == "function")); | ||
| } | ||
| function getWrappedElement(element) { | ||
@@ -179,3 +177,3 @@ if (!elementWrapCache.has(element)) { | ||
| Object.values(listeners).forEach(group => { | ||
| Object.values(group).forEach(l => { var _a; return l.unsubscribe = (_a = l.subscribe) === null || _a === void 0 ? void 0 : _a.call(l); }); | ||
| Object.values(group).forEach(l => l.unsubscribe = l.subscribe()); | ||
| }); | ||
@@ -228,5 +226,7 @@ }, | ||
| on(eventId, handler) { | ||
| element.addEventListener(eventId, eventData => { | ||
| const fn = (eventData) => { | ||
| handler.call(domEntity, eventData); | ||
| }); | ||
| }; | ||
| element.addEventListener(eventId, fn); | ||
| return () => element.removeEventListener(eventId, fn); | ||
| }, | ||
@@ -233,0 +233,0 @@ append(...content) { |
@@ -1,2 +0,2 @@ | ||
| import { Listenable } from "./types"; | ||
| import { EmitterLike } from "./types"; | ||
| type Handler<T> = (value: T) => void; | ||
@@ -98,3 +98,3 @@ export type ListenFunc<T> = (handler: Handler<T>) => UnsubscribeFunc; | ||
| */ | ||
| takeUntil(notifier: Listenable<any>): EventEmitter<T>; | ||
| takeUntil(notifier: EmitterLike<any>): EventEmitter<T>; | ||
| /** | ||
@@ -119,5 +119,11 @@ * Creates a chainable emitter that forwards its parent's emissions while the predicate returns true | ||
| cached(): EventEmitter<T>; | ||
| /** | ||
| * Creates a chainable emitter that forwards emissions from the parent and any of the provided emitters | ||
| * @param emitters | ||
| */ | ||
| or(...emitters: EmitterLike<T>[]): EmitterLike<T>; | ||
| or<U>(...emitters: EmitterLike<U>[]): EmitterLike<T | U>; | ||
| } | ||
| /** | ||
| * Creates a linked Emitter and emit() pair | ||
| * Creates a linked EventEmitter and emit() pair | ||
| * @example | ||
@@ -156,15 +162,37 @@ * ```ts | ||
| }; | ||
| export declare function createListenable<T>(onAddFirst?: () => void, onRemoveLast?: () => void): { | ||
| export declare function createListenable<T>(sourceListen?: () => UnsubscribeFunc | undefined): { | ||
| listen: (fn: (v: T) => void) => UnsubscribeFunc; | ||
| emit: (value: T) => void; | ||
| }; | ||
| export declare function interval(t: number | { | ||
| export declare function interval(ms: number | { | ||
| asMilliseconds: number; | ||
| }): EventEmitter<number>; | ||
| export declare function timeoutx(t: number | { | ||
| asMilliseconds: number; | ||
| }): EventEmitter<void>; | ||
| export declare function timeout(t: number | { | ||
| asMilliseconds: number; | ||
| }): EventEmitter<void>; | ||
| export declare class SubjectEmitter<T> extends EventEmitter<T> { | ||
| private emit; | ||
| private _value; | ||
| constructor(initial: T); | ||
| get value(): T; | ||
| next(value: T): void; | ||
| } | ||
| type EventSource<T, E extends string> = { | ||
| on: (eventName: E, handler: (value: T) => void) => UnsubscribeFunc; | ||
| } | { | ||
| on: (eventName: E, handler: (value: T) => void) => void | UnsubscribeFunc; | ||
| off: (eventName: E, handler: (value: T) => void) => void; | ||
| } | { | ||
| addEventListener: (eventName: E, handler: (value: T) => void) => UnsubscribeFunc; | ||
| } | { | ||
| addEventListener: (eventName: E, handler: (value: T) => void) => void | UnsubscribeFunc; | ||
| removeEventListener: (eventName: E, handler: (value: T) => void) => void; | ||
| }; | ||
| /** | ||
| * Create an EventEmitter from an event source. Event sources can be RxJS observables, existing EventEmitters, or objects that | ||
| * provide a subscribe()/listen() => UnsubscribeFunc method. | ||
| * @param source | ||
| */ | ||
| export declare function toEventEmitter<T>(source: EmitterLike<T>): EventEmitter<T>; | ||
| export declare function toEventEmitter<T, E extends string>(source: EventSource<T, E>, eventName: E): EventEmitter<T>; | ||
| export {}; |
+91
-55
@@ -0,1 +1,2 @@ | ||
| import { isReactiveSource } from "./util"; | ||
| export class EventEmitter { | ||
@@ -6,10 +7,5 @@ constructor(onListen) { | ||
| transform(handler) { | ||
| let parentUnsubscribe = null; | ||
| const parentListen = this.onListen; | ||
| const { emit, listen } = createListenable(() => parentUnsubscribe = parentListen(value => { | ||
| const { emit, listen } = createListenable(() => this.onListen(value => { | ||
| handler(value, emit); | ||
| }), () => { | ||
| parentUnsubscribe(); | ||
| parentUnsubscribe = null; | ||
| }); | ||
| })); | ||
| return listen; | ||
@@ -175,3 +171,4 @@ } | ||
| }); | ||
| }, clear); | ||
| return clear; | ||
| }); | ||
| return new EventEmitter(listen); | ||
@@ -231,7 +228,3 @@ } | ||
| } | ||
| }, () => { | ||
| if (sourceUnsub) { | ||
| sourceUnsub(); | ||
| sourceUnsub = null; | ||
| } | ||
| return sourceUnsub; | ||
| }); | ||
@@ -251,10 +244,4 @@ return new EventEmitter(listen); | ||
| const clear = () => { | ||
| if (parentUnsubscribe) { | ||
| parentUnsubscribe(); | ||
| parentUnsubscribe = null; | ||
| } | ||
| if (notifierUnsub) { | ||
| notifierUnsub(); | ||
| notifierUnsub = null; | ||
| } | ||
| parentUnsubscribe === null || parentUnsubscribe === void 0 ? void 0 : parentUnsubscribe(); | ||
| notifierUnsub === null || notifierUnsub === void 0 ? void 0 : notifierUnsub(); | ||
| }; | ||
@@ -269,6 +256,5 @@ const { emit, listen } = createListenable(() => { | ||
| }; | ||
| notifierUnsub = "subscribe" in notifier | ||
| ? notifier.subscribe(handler) | ||
| : notifier.listen(handler); | ||
| }, clear); | ||
| notifierUnsub = toEventEmitter(notifier).listen(handler); | ||
| return clear; | ||
| }); | ||
| return new EventEmitter(listen); | ||
@@ -282,10 +268,4 @@ } | ||
| takeWhile(predicate) { | ||
| let parentUnsubscribe = null; | ||
| let parentUnsubscribe; | ||
| let completed = false; | ||
| const clear = () => { | ||
| if (parentUnsubscribe) { | ||
| parentUnsubscribe(); | ||
| parentUnsubscribe = null; | ||
| } | ||
| }; | ||
| const { emit, listen } = createListenable(() => { | ||
@@ -300,6 +280,8 @@ if (completed) | ||
| completed = true; | ||
| clear(); | ||
| parentUnsubscribe(); | ||
| parentUnsubscribe = undefined; | ||
| } | ||
| }); | ||
| }, clear); | ||
| return () => parentUnsubscribe === null || parentUnsubscribe === void 0 ? void 0 : parentUnsubscribe(); | ||
| }); | ||
| return new EventEmitter(listen); | ||
@@ -326,11 +308,6 @@ } | ||
| let cache = null; | ||
| let unsub = null; | ||
| const { listen, emit } = createListenable(() => { | ||
| unsub = this.onListen((value => { | ||
| cache = { value }; | ||
| emit(value); | ||
| })); | ||
| }, () => { | ||
| unsub(); | ||
| }); | ||
| const { listen, emit } = createListenable(() => this.onListen((value => { | ||
| cache = { value }; | ||
| emit(value); | ||
| }))); | ||
| return new EventEmitter(handler => { | ||
@@ -342,5 +319,11 @@ if (cache) | ||
| } | ||
| or(...emitters) { | ||
| return new EventEmitter(handler => { | ||
| const unsubs = [this, ...emitters].map(e => toEventEmitter(e).listen(handler)); | ||
| return () => unsubs.forEach(unsub => unsub()); | ||
| }); | ||
| } | ||
| } | ||
| /** | ||
| * Creates a linked Emitter and emit() pair | ||
| * Creates a linked EventEmitter and emit() pair | ||
| * @example | ||
@@ -384,9 +367,10 @@ * ```ts | ||
| } | ||
| export function createListenable(onAddFirst, onRemoveLast) { | ||
| export function createListenable(sourceListen) { | ||
| const handlers = []; | ||
| let onRemoveLast; | ||
| const addListener = (fn) => { | ||
| const unique = { fn }; | ||
| handlers.push(unique); | ||
| if (onAddFirst && handlers.length == 1) | ||
| onAddFirst(); | ||
| if (sourceListen && handlers.length == 1) | ||
| onRemoveLast = sourceListen(); | ||
| return () => { | ||
@@ -406,3 +390,3 @@ const idx = handlers.indexOf(unique); | ||
| } | ||
| export function interval(t) { | ||
| export function interval(ms) { | ||
| let intervalId = null; | ||
@@ -413,9 +397,7 @@ let idx = 0; | ||
| emit(idx++); | ||
| }, typeof t == "number" ? t : t.asMilliseconds); | ||
| }, () => clearInterval(intervalId)); | ||
| }, typeof ms == "number" ? ms : ms.asMilliseconds); | ||
| return () => clearInterval(intervalId); | ||
| }); | ||
| return new EventEmitter(listen); | ||
| } | ||
| export function timeoutx(t) { | ||
| return interval(t).once().map(() => { }); | ||
| } | ||
| export function timeout(t) { | ||
@@ -430,6 +412,60 @@ const ms = typeof t === "number" ? t : t.asMilliseconds; | ||
| timeoutId = setTimeout(emit, reminaingMs); | ||
| }, () => { | ||
| clearTimeout(timeoutId); | ||
| return () => clearTimeout(timeoutId); | ||
| }); | ||
| return new EventEmitter(listen); | ||
| } | ||
| export class SubjectEmitter extends EventEmitter { | ||
| constructor(initial) { | ||
| const { emit, listen } = createListenable(); | ||
| super(h => { | ||
| h(this._value); | ||
| return listen(h); | ||
| }); | ||
| this.emit = emit; | ||
| this._value = initial; | ||
| } | ||
| get value() { | ||
| return this._value; | ||
| } | ||
| next(value) { | ||
| this._value = value; | ||
| this.emit(value); | ||
| } | ||
| } | ||
| export function toEventEmitter(source, eventName) { | ||
| if (source instanceof EventEmitter) | ||
| return source; | ||
| if (eventName !== undefined) { | ||
| // addEL() | ||
| if ("addEventListener" in source) { | ||
| if ("removeEventListener" in source && typeof source.removeEventListener == "function") { | ||
| return new EventEmitter(h => { | ||
| var _a; | ||
| return (_a = source.addEventListener(eventName, h)) !== null && _a !== void 0 ? _a : (() => source.removeEventListener(eventName, h)); | ||
| }); | ||
| } | ||
| return new EventEmitter(h => { | ||
| return source.addEventListener(eventName, h); | ||
| }); | ||
| } | ||
| // on() | ||
| if ("on" in source) { | ||
| if ("off" in source && typeof source.off == "function") { | ||
| return new EventEmitter(h => { | ||
| var _a; | ||
| return (_a = source.on(eventName, h)) !== null && _a !== void 0 ? _a : (() => source.off(eventName, h)); | ||
| }); | ||
| } | ||
| return new EventEmitter(h => { | ||
| return source.on(eventName, h); | ||
| }); | ||
| } | ||
| } | ||
| if (isReactiveSource(source)) { | ||
| const subscribe = "subscribe" in source | ||
| ? (h) => source.subscribe(h) | ||
| : (h) => source.listen(h); | ||
| return new EventEmitter(subscribe); | ||
| } | ||
| throw new Error("Invalid event source"); | ||
| } |
@@ -1,2 +0,2 @@ | ||
| import { EventEmitter } from "./emitter"; | ||
| import { toEventEmitter } from "./emitter"; | ||
| export const styleProxy = { | ||
@@ -45,11 +45,4 @@ get(style, prop) { | ||
| } | ||
| const listen = (handler) => { | ||
| const wrappedHandler = (event) => handler(event); | ||
| element.addEventListener(key, wrappedHandler); | ||
| return () => { | ||
| element.removeEventListener(key, wrappedHandler); | ||
| }; | ||
| }; | ||
| return new EventEmitter(listen); | ||
| return toEventEmitter(element, key); | ||
| } | ||
| }; |
+20
-18
| import { type ClassAccessor } from "./element"; | ||
| import { EventEmitter, UnsubscribeFunc } from "./emitter"; | ||
| import { entityDataSymbol } from "./util"; | ||
| export type ElementClassDescriptor = string | Record<string, boolean | Listenable<boolean> | undefined> | undefined | ElementClassDescriptor[]; | ||
| export type ElementClassDescriptor = string | Record<string, boolean | EmitterLike<boolean> | undefined> | undefined | ElementClassDescriptor[]; | ||
| export type DOMContent = number | null | string | Element | JelEntity<object> | Text | DOMContent[]; | ||
| export type DomEntity<T extends HTMLElement> = JelEntity<ElementAPI<T>>; | ||
| export type Listenable<T> = { | ||
| export type HTMLTag = keyof HTMLElementTagNameMap; | ||
| export type EmitterLike<T> = { | ||
| subscribe: (callback: (value: T) => void) => UnsubscribeFunc; | ||
@@ -22,6 +23,6 @@ } | { | ||
| CSSStyleDeclaration[K] | ||
| ] extends [string, string] ? K : never]+?: CSSValue | Listenable<CSSValue>; | ||
| ] extends [string, string] ? K : never]+?: CSSValue | EmitterLike<CSSValue>; | ||
| }; | ||
| export type SetStyleFunc = ((property: CSSProperty, value: CSSValue | Listenable<CSSValue>) => void); | ||
| export type SetGetStyleFunc = SetStyleFunc & ((property: CSSProperty) => string | Listenable<CSSValue>); | ||
| export type SetStyleFunc = ((property: CSSProperty, value: CSSValue | EmitterLike<CSSValue>) => void); | ||
| export type SetGetStyleFunc = SetStyleFunc & ((property: CSSProperty) => string | EmitterLike<CSSValue>); | ||
| export type StyleAccessor = ((styles: StylesDescriptor) => void) & StylesDescriptor & SetStyleFunc; | ||
@@ -36,3 +37,3 @@ type ContentlessTag = "area" | "br" | "hr" | "iframe" | "input" | "textarea" | "img" | "canvas" | "link" | "meta" | "source" | "embed" | "track" | "base"; | ||
| type ContentlessElement = HTMLElementTagNameMap[ContentlessTag]; | ||
| export type ElementDescriptor<Tag extends string> = { | ||
| export type ElementDescriptor<Tag extends HTMLTag> = { | ||
| classes?: ElementClassDescriptor; | ||
@@ -44,7 +45,8 @@ attribs?: Record<string, string | number | boolean>; | ||
| style?: StylesDescriptor; | ||
| cssVariables?: Record<string, CSSValue | Listenable<CSSValue>>; | ||
| cssVariables?: Record<string, CSSValue | EmitterLike<CSSValue>>; | ||
| init?: (entity: DomEntity<HTMLElementTagNameMap[Tag]>) => void; | ||
| } & (Tag extends TagWithValue ? { | ||
| value?: string | number; | ||
| } : {}) & (Tag extends ContentlessTag ? {} : { | ||
| content?: DOMContent | Listenable<DOMContent>; | ||
| content?: DOMContent | EmitterLike<DOMContent>; | ||
| }) & (Tag extends TagWithSrc ? { | ||
@@ -70,4 +72,4 @@ src?: string; | ||
| readonly style: StyleAccessor; | ||
| setCSSVariable(variableName: string, value: CSSValue | Listenable<CSSValue>): void; | ||
| setCSSVariable(table: Record<string, CSSValue | Listenable<CSSValue>>): void; | ||
| setCSSVariable(variableName: string, value: CSSValue | EmitterLike<CSSValue>): void; | ||
| setCSSVariable(table: Record<string, CSSValue | EmitterLike<CSSValue>>): void; | ||
| qsa(selector: string): (Element | DomEntity<HTMLElement>)[]; | ||
@@ -78,7 +80,7 @@ remove(): void; | ||
| blur(): void; | ||
| on<E extends keyof HTMLElementEventMap>(eventId: E, handler: (this: ElementAPI<T>, data: HTMLElementEventMap[E]) => void): void; | ||
| on<E extends keyof HTMLElementEventMap>(eventId: E, handler: (this: ElementAPI<T>, data: HTMLElementEventMap[E]) => void): UnsubscribeFunc; | ||
| } & (T extends ContentlessElement ? {} : { | ||
| append(...content: DOMContent[]): void; | ||
| innerHTML: string; | ||
| content: DOMContent | Listenable<DOMContent>; | ||
| content: DOMContent | EmitterLike<DOMContent>; | ||
| }) & (T extends HTMLElementTagNameMap[TagWithValue] ? { | ||
@@ -107,15 +109,15 @@ value: string; | ||
| */ | ||
| <T extends keyof HTMLElementTagNameMap>(tagName: T, descriptor: ElementDescriptor<T>) => DomEntity<HTMLElementTagNameMap[T]>) & ( | ||
| <T extends HTMLTag>(tagName: T, descriptor: ElementDescriptor<T>) => DomEntity<HTMLElementTagNameMap[T]>) & ( | ||
| /** | ||
| * Creates an element of the specified tag | ||
| */ | ||
| <T extends keyof HTMLElementTagNameMap>(tagName: T) => DomEntity<HTMLElementTagNameMap[T]>) & ( | ||
| <T extends HTMLTag>(tagName: T) => DomEntity<HTMLElementTagNameMap[T]>) & ( | ||
| /** | ||
| * Creates an element with ID and classes as specified by a selector-like string | ||
| */ | ||
| <T extends keyof HTMLElementTagNameMap>(selector: `${T}#${string}`, content?: T extends ContentlessTag ? void : DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & ( | ||
| <T extends HTMLTag>(selector: `${T}#${string}`, content?: T extends ContentlessTag ? void : DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & ( | ||
| /** | ||
| * Creates an element with ID and classes as specified by a selector-like string | ||
| */ | ||
| <T extends keyof HTMLElementTagNameMap>(selector: `${T}.${string}`, content?: T extends ContentlessTag ? void : DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & ( | ||
| <T extends HTMLTag>(selector: `${T}.${string}`, content?: T extends ContentlessTag ? void : DOMContent) => DomEntity<HTMLElementTagNameMap[T]>) & ( | ||
| /** | ||
@@ -125,5 +127,5 @@ * Wraps an existing element as a DomEntity | ||
| <T extends HTMLElement>(element: T) => DomEntity<T>) & { | ||
| [T in keyof HTMLElementTagNameMap]: (descriptor: ElementDescriptor<T>) => DomEntity<HTMLElementTagNameMap[T]>; | ||
| [T in HTMLTag]: (descriptor: ElementDescriptor<T>) => DomEntity<HTMLElementTagNameMap[T]>; | ||
| } & { | ||
| [T in keyof HTMLElementTagNameMap]: T extends ContentlessTag ? () => DomEntity<HTMLElementTagNameMap[T]> : (content?: DOMContent) => DomEntity<HTMLElementTagNameMap[T]>; | ||
| [T in HTMLTag]: T extends ContentlessTag ? () => DomEntity<HTMLElementTagNameMap[T]> : (content?: DOMContent) => DomEntity<HTMLElementTagNameMap[T]>; | ||
| }); | ||
@@ -130,0 +132,0 @@ type JelEntityData = { |
@@ -1,4 +0,4 @@ | ||
| import { DOMContent, ElementDescriptor, JelEntity } from "./types"; | ||
| import { DOMContent, ElementDescriptor, EmitterLike, HTMLTag, JelEntity } from "./types"; | ||
| export declare const entityDataSymbol: unique symbol; | ||
| export declare const isContent: (value: DOMContent | ElementDescriptor<string> | undefined) => value is DOMContent; | ||
| export declare const isContent: <T extends HTMLTag>(value: DOMContent | ElementDescriptor<T> | undefined) => value is DOMContent; | ||
| export declare function isJelEntity(content: DOMContent): content is JelEntity<object>; | ||
@@ -12,1 +12,2 @@ /** | ||
| export declare function createEntity(content: DOMContent): JelEntity<void>; | ||
| export declare function isReactiveSource(value: any): value is EmitterLike<any>; |
+4
-0
@@ -29,1 +29,5 @@ export const entityDataSymbol = Symbol("jelComponentData"); | ||
| ; | ||
| export function isReactiveSource(value) { | ||
| return typeof value == "object" && value && (("listen" in value && typeof value.listen == "function") | ||
| || ("subscribe" in value && typeof value.subscribe == "function")); | ||
| } |
+1
-1
| { | ||
| "name": "@xtia/jel", | ||
| "version": "0.7.0", | ||
| "version": "0.7.1", | ||
| "repository": { | ||
@@ -5,0 +5,0 @@ "url": "https://github.com/tiadrop/jel-ts", |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
53327
5.89%1320
5.1%