New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@xtia/jel

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@xtia/jel - npm Package Compare versions

Comparing version
0.9.1
to
0.10.0
+4
-2
index.d.ts

@@ -1,7 +0,9 @@

export { DomEntity, ElementClassDescriptor, ElementDescriptor, DOMContent, DomHelper, StyleAccessor, JelEntity } from "./internal/types";
import { $ } from "./internal/element";
import { DomEntity } from "./internal/types";
export { DomEntity, ElementClassDescriptor, ElementDescriptor, DOMContent, DomHelper, StyleAccessor, JelEntity, EventEmitterMap } from "./internal/types";
export { createEntity } from "./internal/util";
export { createEventSource, interval, timeout, SubjectEmitter, toEventEmitter, type EventEmitter, combineEmitters } from "./internal/emitter";
export { createEventSource, createEventsSource, interval, timeout, SubjectEmitter, toEventEmitter, type EventEmitter, type EventRecording, type EventRecorder, combineEmitters } from "./internal/emitter";
export { createEventsProxy } from "./internal/proxy";
export { $ };
export declare const $body: DomEntity<HTMLElement>;
export declare const windowEvents: import(".").EventEmitterMap<WindowEventMap>;
import { $ } from "./internal/element";
import { createEventsProxy } from "./internal/proxy";
export { createEntity } from "./internal/util";
export { createEventSource, interval, timeout, SubjectEmitter, toEventEmitter, combineEmitters } from "./internal/emitter";
export { createEventSource, createEventsSource, interval, timeout, SubjectEmitter, toEventEmitter, combineEmitters } from "./internal/emitter";
export { createEventsProxy } from "./internal/proxy";
export { $ };
export const $body = "document" in globalThis ? $(document.body) : undefined;
export const windowEvents = createEventsProxy(window);

@@ -14,2 +14,3 @@ import { DomHelper, EmitterLike } from "./types";

get length(): number;
get value(): string;
toString(): string;

@@ -16,0 +17,0 @@ replace(token: string, newToken: string): void;

@@ -1,2 +0,3 @@

import { attribsProxy, eventsProxy, styleProxy } from "./proxy";
import { toEventEmitter } from "./emitter.js";
import { attribsProxy, createEventsProxy, styleProxy } from "./proxy";
import { entityDataSymbol, isContent, isJelEntity, isReactiveSource } from "./util";

@@ -20,3 +21,3 @@ const elementWrapCache = new WeakMap();

function createElement(tag, descriptor = {}) {
if (isContent(descriptor))
if (isContent(descriptor) || isReactiveSource(descriptor))
descriptor = {

@@ -204,4 +205,4 @@ content: descriptor,

if (typeof value == "object" && value) {
if ("listen" in value || "subscribe" in value) {
addListener("style", prop, value);
if (isReactiveSource(value)) {
addListener("style", prop, toEventEmitter(value));
return;

@@ -352,3 +353,3 @@ }

}),
events: new Proxy(element, eventsProxy)
events: createEventsProxy(element),
};

@@ -387,2 +388,5 @@ elementWrapCache.set(element, domEntity);

}
get value() {
return this.classList.value;
}
toString() {

@@ -400,11 +404,7 @@ return this.classList.toString();

const result = [];
const entries = this.classList.entries();
let entry = entries.next();
while (!entry.done) {
const [idx, value] = entry.value;
result.push(cb(value, idx));
entry = entries.next();
}
this.classList.forEach((v, i) => {
result.push(cb(v, i));
});
return result;
}
}

@@ -1,8 +0,2 @@

import { EmitterLike } from "./types";
type Handler<T> = (value: T) => void;
type Period = {
asMilliseconds: number;
} | {
asSeconds: number;
};
import { Dictionary, EmissionSource, EmitterLike, EventHandlerMap, EventSource, Handler, Period } from "./types";
export type ListenFunc<T> = (handler: Handler<T>) => UnsubscribeFunc;

@@ -33,2 +27,3 @@ export type UnsubscribeFunc = () => void;

mapAsync<R>(mapFunc: (value: T) => Promise<R>): EventEmitter<R>;
as<R>(value: R): EventEmitter<R>;
/**

@@ -94,3 +89,3 @@ * Creates a chainable emitter that selectively forwards emissions along the chain

/**
* Creates a chainable emitter that
* Creates a chainable emitter that forwards the next emission from the parent
* **Experimental**: May change in future revisions

@@ -102,2 +97,4 @@ * Note: only listens to the parent while at least one downstream subscription is present

once(): EventEmitter<T>;
once(handler: Handler<T>): UnsubscribeFunc;
getNext(): Promise<T>;
delay(ms: number): EventEmitter<T>;

@@ -146,7 +143,34 @@ delay(period: Period): EventEmitter<T>;

or<U>(...emitters: EmitterLike<U>[]): EventEmitter<T | U>;
then<R>(handler: (value: T) => R): Promise<R>;
memo(): Memo<T | undefined>;
memo(initial: T): Memo<T>;
memo<U>(initial: U): Memo<T | U>;
record(): EventRecorder<T>;
}
export declare class EventRecorder<T> {
private startTime;
private entries;
private recording;
private unsubscribe;
constructor(emitter: EventEmitter<T>);
private add;
stop(): EventRecording<T>;
}
export declare class EventRecording<T> {
private _entries;
constructor(entries: [number, T][]);
export(): [number, T][];
play(speed?: number): EventEmitter<T>;
}
type EmitEmitterPair<T> = {
emit: (value: T) => void;
emitter: EventEmitter<T>;
};
type CreateEventSourceOptions<T> = {
initialHandler?: Handler<T>;
/**
* Function to call when subscription count changes from 0
* Return a *deactivation* function, which will be called when subscription count changes back to 0
*/
activate?(): UnsubscribeFunc;
};
/**

@@ -183,8 +207,11 @@ * Creates a linked EventEmitter and emit() pair

*/
export declare function createEventSource<T>(initialHandler?: Handler<T>): {
emit: (value: T) => void;
emitter: EventEmitter<T>;
export declare function createEventSource<T>(initialHandler?: Handler<T>): EmitEmitterPair<T>;
export declare function createEventSource<T>(options?: CreateEventSourceOptions<T>): EmitEmitterPair<T>;
export declare function createEventsSource<Map extends Dictionary<any>>(initialListeners?: EventHandlerMap<Map>): {
emitters: import("./types").EventEmitterMap<Map>;
trigger: <K extends keyof Map>(name: K, value: Map[K]) => void;
};
export declare function interval(ms: number): EventEmitter<number>;
export declare function interval(period: Period): EventEmitter<number>;
export declare const animationFrames: EventEmitter<number>;
export declare function timeout(ms: number): EventEmitter<void>;

@@ -206,22 +233,13 @@ export declare function timeout(period: Period): EventEmitter<void>;

}
type EventSource<T, E extends string> = {
on: (eventName: E, handler: Handler<T>) => UnsubscribeFunc;
} | {
on: (eventName: E, handler: Handler<T>) => void | UnsubscribeFunc;
off: (eventName: E, handler: Handler<T>) => void;
} | {
addEventListener: (eventName: E, handler: Handler<T>) => UnsubscribeFunc;
} | {
addEventListener: (eventName: E, handler: Handler<T>) => void | UnsubscribeFunc;
removeEventListener: (eventName: E, handler: Handler<T>) => 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.
* Create an EventEmitter from an event source. Event source can be RxJS observable, existing `EventEmitter`, an object that
* provides a `subscribe()`/`listen() => UnsubscribeFunc` method, or a subscribe function itself.
* @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 declare function toEventEmitter<T>(subscribe: ListenFunc<T>): EventEmitter<T>;
type Dictionary<T> = Record<string | symbol, T>;
export declare function toEventEmitter<E>(source: EmissionSource<E>): EventEmitter<E>;
/**
* Create an EventEmitter from an event provider and event name. Event source may provide matching `addEventListener`/`on(name, handler)` and `removeEventListener`/`off(name, handler)` methods, or `addEventListener`/`on(name, handler): UnsubscribeFunc.
* @param source
*/
export declare function toEventEmitter<E, N>(source: EventSource<E, N>, eventName: N): EventEmitter<E>;
type ExtractEmitterValue<T> = T extends EmitterLike<infer U> ? U : never;

@@ -228,0 +246,0 @@ type CombinedRecord<T extends Dictionary<EmitterLike<any>>> = {

@@ -0,2 +1,4 @@

import { createEventsProxy } from "./proxy.js";
import { isReactiveSource } from "./util";
const NOOP = () => { };
function periodAsMilliseconds(t) {

@@ -46,2 +48,6 @@ if (typeof t == "number")

}
as(value) {
const listen = this.transform((_, emit) => emit(value));
return new EventEmitter(listen);
}
/**

@@ -156,10 +162,3 @@ * Creates a chainable emitter that selectively forwards emissions along the chain

}
/**
* Creates a chainable emitter that
* **Experimental**: May change in future revisions
* Note: only listens to the parent while at least one downstream subscription is present
* @param notifier
* @returns
*/
once() {
once(handler) {
let parentUnsubscribe = null;

@@ -183,7 +182,14 @@ let completed = false;

});
return new EventEmitter(listen);
const emitter = new EventEmitter(listen);
return handler
? emitter.apply(handler)
: emitter;
}
getNext() {
return new Promise((resolve) => this.once(resolve));
}
delay(t) {
const ms = periodAsMilliseconds(t);
return new EventEmitter(this.transform((value, emit) => {
setTimeout(() => emit(value), periodAsMilliseconds(t));
return timeout(ms).apply(() => emit(value));
}));

@@ -328,44 +334,59 @@ }

}
then(handler) {
return new Promise(resolve => {
this.once().apply(v => resolve(handler(v)));
});
}
memo(initial) {
return new Memo(this, initial);
}
record() {
return new EventRecorder(this);
}
}
/**
* Creates a linked EventEmitter and emit() pair
* @example
* ```ts
* function createForm(options?: { onsubmit?: (data: FormData) => void }) {
* const submitEvents = createEventSource(options?.onsubmit);
* const form = $.form({
* on: {
* submit: (e) => {
* e.preventDefault();
* const data = new FormData(e.target);
* submitEvents.emit(data); // emit when form is submitted
* }
* }
* });
*
* return createEntity(form, {
* events: {
* submit: submitEvents.emitter
* }
* })
* }
*
* const form = createForm({
* onsubmit: (data) => handleSubmission(data)
* });
* ```
*
* @param initialHandler Optional listener automatically applied to the resulting Emitter
* @returns
*/
export function createEventSource(initialHandler) {
const { emit, listen } = createListenable();
export class EventRecorder {
constructor(emitter) {
this.startTime = performance.now();
this.entries = [];
this.recording = true;
this.unsubscribe = emitter.listen(v => this.add(v));
}
add(value) {
const now = performance.now();
let time = now - this.startTime;
this.entries.push([time, value]);
}
stop() {
if (!this.recording) {
throw new Error("EventRecorder already stopped");
}
this.unsubscribe();
return new EventRecording(this.entries);
}
}
export class EventRecording {
constructor(entries) {
this._entries = entries;
}
export() {
return [...this._entries];
}
play(speed = 1) {
let idx = 0;
let elapsed = 0;
const { emit, listen } = createListenable();
const unsubscribe = animationFrames.listen((frameElapsed) => {
elapsed += frameElapsed * speed;
while (idx < this._entries.length && this._entries[idx][0] <= elapsed) {
emit(this._entries[idx][1]);
idx++;
}
if (idx >= this._entries.length) {
unsubscribe();
}
});
return new EventEmitter(listen);
}
}
export function createEventSource(arg) {
if (typeof arg === "function") {
arg = { initialHandler: arg };
}
const { initialHandler, activate } = arg !== null && arg !== void 0 ? arg : {};
const { emit, listen } = createListenable(activate);
if (initialHandler)

@@ -378,2 +399,26 @@ listen(initialHandler);

}
export function createEventsSource(initialListeners) {
const handlers = {};
const emitters = createEventsProxy({
on: (name, handler) => {
if (!handlers[name])
handlers[name] = [];
const unique = { fn: handler };
handlers[name].push(unique);
return () => {
const idx = handlers[name].indexOf(unique);
handlers[name].splice(idx, 1);
if (handlers[name].length == 0)
delete handlers[name];
};
},
}, initialListeners);
return {
emitters,
trigger: (name, value) => {
var _a;
(_a = handlers[name]) === null || _a === void 0 ? void 0 : _a.forEach(entry => entry.fn(value));
}
};
}
function createListenable(sourceListen) {

@@ -412,6 +457,20 @@ const handlers = [];

}
export const animationFrames = (() => {
const { emit, listen } = createListenable(() => {
let rafId = null;
let lastTime = null;
const frame = (time) => {
rafId = requestAnimationFrame(frame);
const elapsed = time - lastTime;
emit(elapsed);
};
lastTime = performance.now();
rafId = requestAnimationFrame(frame);
return () => cancelAnimationFrame(rafId);
});
return new EventEmitter(listen);
})();
export function timeout(t) {
const ms = periodAsMilliseconds(t);
const targetTime = Date.now() + ms;
let timeoutId = null;
const { emit, listen } = createListenable(() => {

@@ -421,3 +480,5 @@ const reminaingMs = targetTime - Date.now();

return;
timeoutId = setTimeout(emit, reminaingMs);
const timeoutId = setTimeout(() => {
emit();
}, reminaingMs);
return () => clearTimeout(timeoutId);

@@ -447,3 +508,3 @@ });

super(h => {
h(this._value);
h(this._value); // immediate emit on listen
return listen(h);

@@ -472,4 +533,4 @@ });

return new EventEmitter(h => {
return source.addEventListener(eventName, h)
|| (() => source.removeEventListener(eventName, h));
source.addEventListener(eventName, h);
return () => source.removeEventListener(eventName, h);
});

@@ -476,0 +537,0 @@ }

@@ -1,4 +0,4 @@

import { SetGetStyleFunc } from "./types";
import { SetGetStyleFunc, EventSource, EventEmitterMap, EventHandlerMap } from "./types";
export declare const styleProxy: ProxyHandler<SetGetStyleFunc>;
export declare const attribsProxy: ProxyHandler<HTMLElement>;
export declare const eventsProxy: ProxyHandler<HTMLElement>;
export declare function createEventsProxy<Map>(source: EventSource<any, keyof Map>, initialListeners?: EventHandlerMap<Map>): EventEmitterMap<Map>;

@@ -37,12 +37,14 @@ import { toEventEmitter } from "./emitter";

};
export const eventsProxy = {
get: (element, key) => {
if (key == "addEventListener") {
return (name, handler) => element.addEventListener(name, handler);
}
if (key == "removeEventListener") {
return (name, handler) => element.removeEventListener(name, handler);
}
return toEventEmitter(element, key);
const eventsProxyDefinition = {
get: (object, key) => {
return toEventEmitter(object, key);
}
};
export function createEventsProxy(source, initialListeners) {
const proxy = new Proxy(source, eventsProxyDefinition);
if (initialListeners) {
Object.entries(initialListeners)
.forEach(([name, handler]) => toEventEmitter(source, name).apply(handler));
}
return proxy;
}

@@ -1,3 +0,3 @@

import { type ClassAccessor } from "./element";
import { EventEmitter, UnsubscribeFunc } from "./emitter";
import { ClassAccessor } from "./element";
import { EventEmitter, ListenFunc, UnsubscribeFunc } from "./emitter";
import { entityDataSymbol } from "./util";

@@ -13,2 +13,3 @@ export type ElementClassDescriptor = string | Record<string, boolean | EmitterLike<boolean> | undefined> | undefined | ElementClassDescriptor[];

};
export type EmissionSource<T> = EmitterLike<T> | ListenFunc<T>;
export type CSSValue = string | number | null | HexCodeContainer;

@@ -68,3 +69,3 @@ export type CSSProperty = keyof StylesDescriptor;

};
readonly events: EventsAccessor;
readonly events: EventEmitterMap<HTMLElementEventMap>;
readonly style: StyleAccessor;

@@ -78,2 +79,9 @@ setCSSVariable(variableName: string, value: CSSValue | EmitterLike<CSSValue>): void;

blur(): void;
/**
* Add an event listener
* @param eventId
* @param handler
* @returns Function to remove the listener
* @deprecated Use ent.events
*/
on<E extends keyof HTMLElementEventMap>(eventId: E, handler: (this: ElementAPI<T>, data: HTMLElementEventMap[E]) => void): UnsubscribeFunc;

@@ -126,3 +134,3 @@ } & (T extends ContentlessElement ? {} : {

} & {
[T in HTMLTag]: 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]>) & ((contentEmitter: EmitterLike<DOMContent>) => DomEntity<HTMLElementTagNameMap[T]>));
});

@@ -135,8 +143,26 @@ type JelEntityData = {

};
export type EventsAccessor = {
[K in keyof HTMLElementEventMap]: EventEmitter<HTMLElementEventMap[K]>;
} & {
addEventListener<K extends keyof HTMLElementEventMap>(eventName: K, listener: (event: HTMLElementEventMap[K]) => void): void;
removeEventListener<K extends keyof HTMLElementEventMap>(eventName: K, listener: (event: HTMLElementEventMap[K]) => void): void;
export type Handler<T> = (value: T) => void;
export type Period = {
asMilliseconds: number;
} | {
asSeconds: number;
};
export type EventSource<E, N> = {
on: (eventName: N, handler: Handler<E>) => UnsubscribeFunc;
} | {
on: (eventName: N, handler: Handler<E>) => void | UnsubscribeFunc;
off: (eventName: N, handler: Handler<E>) => void;
} | {
addEventListener: (eventName: N, handler: Handler<E>) => UnsubscribeFunc;
} | {
addEventListener: (eventName: N, handler: Handler<E>) => void;
removeEventListener: (eventName: N, handler: Handler<E>) => void;
};
export type Dictionary<T> = Record<string | symbol, T>;
export type EventEmitterMap<Map> = {
[K in keyof Map]: EventEmitter<Map[K]>;
};
export type EventHandlerMap<Map> = {
[K in keyof Map]?: (value: Map[K]) => void;
};
export {};
{
"name": "@xtia/jel",
"version": "0.9.1",
"version": "0.10.0",
"repository": {

@@ -5,0 +5,0 @@ "url": "https://github.com/tiadrop/jel-ts",

@@ -68,3 +68,3 @@ # Jel

name: string;
completionMessage: DOMContent;
completionMessage: () => DOMContent;
}

@@ -76,3 +76,3 @@

$.h2(`${job.name} Complete`),
$.p(job.completionMessage),
$.p(job.completionMessage()),
]);

@@ -135,3 +135,3 @@ ```

```ts
element.events.mousemove
div.events.mousemove
.takeUntil(body.events.mousedown.filter(e => e.button === 1))

@@ -142,5 +142,5 @@ .map(ev => [ev.offsetX, ev.offsetY])

For RxJS users, events can be observed with `fromEvent(element.events, "mousemove")`.
For RxJS users, events can be observed with `fromEvent(ent.element, "mousemove")`.
## Reactive styles
## Reactive properties

@@ -172,2 +172,16 @@ Style properties, content and class presence can be emitter subscriptions:

.map(msg => msg.text);
const searchInput = $("input.search");
const searchResults$ = searchInput.events.input
.debounce(300)
.map(() => searchInput.value)
.filter(term => term.length >= 2)
.mapAsync(term => performSearch(term)); // Returns emitter of search results
// Then use it reactively
$.ul({
content: searchResults$.map(results =>
results.map(result => $.li(result.title))
)
});
```

@@ -174,0 +188,0 @@ Removing an element from the page will unsubscribe from any attached stream, and resubscribe if subsequently appended.