@thi.ng/rdom
Advanced tools
Comparing version 1.2.0 to 1.3.0
# Change Log | ||
- **Last updated**: 2024-04-11T12:32:44Z | ||
- **Last updated**: 2024-04-20T14:42:45Z | ||
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub) | ||
@@ -12,2 +12,17 @@ | ||
## [1.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/rdom@1.3.0) (2024-04-20) | ||
#### 🚀 Features | ||
- add support for async iterables ([742e0db](https://github.com/thi-ng/umbrella/commit/742e0db)) | ||
- add $async() component wrapper | ||
- add $asyncA() attribute wrapper | ||
- update $compile() to support embedded `AsyncIterable` values | ||
- update wrapper() to support reactive/async attribs ([96ea779](https://github.com/thi-ng/umbrella/commit/96ea779)) | ||
- internally switch from `$el()` => `$compile()` | ||
#### ♻️ Refactoring | ||
- update type usage ([56d5747](https://github.com/thi-ng/umbrella/commit/56d5747)) | ||
## [1.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/rdom@1.2.0) (2024-04-11) | ||
@@ -14,0 +29,0 @@ |
import { isArray } from "@thi.ng/checks/is-array"; | ||
import { isAsyncIterable } from "@thi.ng/checks/is-async-iterable"; | ||
import { isPlainObject } from "@thi.ng/checks/is-plain-object"; | ||
import { isSubscribable } from "@thi.ng/rstream/checks"; | ||
import { $async, $asyncA } from "./async.js"; | ||
import { isComponent, isElement } from "./checks.js"; | ||
@@ -8,3 +10,3 @@ import { $el, $remove, $tree } from "./dom.js"; | ||
import { $wrapEl, $wrapText } from "./wrap.js"; | ||
const $compile = (tree) => isArray(tree) ? isComplexComponent(tree) ? complexComponent(tree) : basicComponent(tree) : isComponent(tree) ? tree : isSubscribable(tree) ? $sub(tree, "span") : tree instanceof Element ? $wrapEl(tree) : $wrapText("span", null, tree); | ||
const $compile = (tree) => isArray(tree) ? isComplexComponent(tree) ? complexComponent(tree) : basicComponent(tree) : isComponent(tree) ? tree : isSubscribable(tree) ? $sub(tree, "span") : isAsyncIterable(tree) ? $async(tree, "span") : tree instanceof Element ? $wrapEl(tree) : $wrapText("span", null, tree); | ||
const walk = (f, x, path = []) => { | ||
@@ -30,3 +32,3 @@ if (isPlainObject(x)) { | ||
} | ||
return isSubscribable(x) || isComponent(x) || isElement(x); | ||
return isSubscribable(x) || isAsyncIterable(x) || isComponent(x) || isElement(x); | ||
}; | ||
@@ -37,3 +39,7 @@ const complexComponent = (tree) => ({ | ||
walk((x, path) => { | ||
isSubscribable(x) && this.subs.push(x.subscribe(new $SubA(this, path))); | ||
if (isSubscribable(x)) { | ||
this.subs.push(x.subscribe(new $SubA(this, path))); | ||
} else if (isAsyncIterable(x)) { | ||
$asyncA(x, this, path); | ||
} | ||
}, tree[1]); | ||
@@ -40,0 +46,0 @@ this.children = []; |
@@ -1,2 +0,2 @@ | ||
import type { MaybeDeref } from "@thi.ng/api"; | ||
import type { Maybe, MaybeDeref } from "@thi.ng/api"; | ||
import type { IComponent, NumOrElement } from "./api.js"; | ||
@@ -23,3 +23,3 @@ /** | ||
*/ | ||
$el(tag: string, attribs?: any, body?: any, parent?: ParentNode | undefined, idx?: NumOrElement): Element; | ||
$el(tag: string, attribs?: any, body?: any, parent?: Maybe<ParentNode>, idx?: NumOrElement): Element; | ||
/** | ||
@@ -33,3 +33,3 @@ * Syntax sugar for {@link $comment}, creates a new comment DOM node using | ||
*/ | ||
$comment(body: string | string[], parent?: ParentNode | undefined, idx?: NumOrElement): Comment; | ||
$comment(body: string | string[], parent?: Maybe<ParentNode>, idx?: NumOrElement): Comment; | ||
/** | ||
@@ -36,0 +36,0 @@ * Syntax sugar for {@link $clear}, using this component's |
export * from "./api.js"; | ||
export * from "./async.js"; | ||
export * from "./checks.js"; | ||
@@ -3,0 +4,0 @@ export * from "./compile.js"; |
export * from "./api.js"; | ||
export * from "./async.js"; | ||
export * from "./checks.js"; | ||
@@ -3,0 +4,0 @@ export * from "./compile.js"; |
@@ -1,2 +0,2 @@ | ||
import type { Fn0 } from "@thi.ng/api"; | ||
import type { Fn0, Maybe } from "@thi.ng/api"; | ||
import type { ComponentLike, IComponent, NumOrElement } from "./api.js"; | ||
@@ -25,8 +25,8 @@ import { Component } from "./component.js"; | ||
protected opts?: IntersectionObserverInit | undefined; | ||
protected observer: IntersectionObserver | undefined; | ||
protected inner: IComponent | undefined; | ||
protected observer: Maybe<IntersectionObserver>; | ||
protected inner: Maybe<IComponent>; | ||
constructor(tag: string, attribs: any, ctor: Fn0<Promise<ComponentLike>>, opts?: IntersectionObserverInit | undefined); | ||
mount(parent: ParentNode, index?: NumOrElement | undefined): Promise<Element>; | ||
mount(parent: ParentNode, index?: NumOrElement): Promise<Element>; | ||
unmount(): Promise<void>; | ||
} | ||
//# sourceMappingURL=lazy.d.ts.map |
{ | ||
"name": "@thi.ng/rdom", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "Lightweight, reactive, VDOM-less UI/DOM components with async lifecycle and @thi.ng/hiccup compatible", | ||
@@ -40,10 +40,10 @@ "type": "module", | ||
"dependencies": { | ||
"@thi.ng/api": "^8.10.1", | ||
"@thi.ng/checks": "^3.6.1", | ||
"@thi.ng/errors": "^2.5.4", | ||
"@thi.ng/hiccup": "^5.1.28", | ||
"@thi.ng/paths": "^5.1.78", | ||
"@thi.ng/prefixes": "^2.3.16", | ||
"@thi.ng/rstream": "^8.4.0", | ||
"@thi.ng/strings": "^3.7.30" | ||
"@thi.ng/api": "^8.11.0", | ||
"@thi.ng/checks": "^3.6.2", | ||
"@thi.ng/errors": "^2.5.5", | ||
"@thi.ng/hiccup": "^5.1.29", | ||
"@thi.ng/paths": "^5.1.79", | ||
"@thi.ng/prefixes": "^2.3.17", | ||
"@thi.ng/rstream": "^8.4.1", | ||
"@thi.ng/strings": "^3.7.31" | ||
}, | ||
@@ -91,2 +91,5 @@ "devDependencies": { | ||
}, | ||
"./async": { | ||
"default": "./async.js" | ||
}, | ||
"./checks": { | ||
@@ -148,3 +151,3 @@ "default": "./checks.js" | ||
}, | ||
"gitHead": "18a0c063a7b33d790e5bc2486c106f45f663ac28\n" | ||
"gitHead": "8339d05ecc857e529c7325a9839c0063b89e728d\n" | ||
} |
@@ -25,2 +25,3 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
- [Event handlers for reactive streams](#event-handlers-for-reactive-streams) | ||
- [Embedding async iterables](#embedding-async-iterables) | ||
- [Status](#status) | ||
@@ -114,3 +115,4 @@ - [Support packages](#support-packages) | ||
reactive value transformations on other packages, i.e. | ||
[@thi.ng/rstream](https://github.com/thi-ng/umbrella/tree/develop/packages/rstream) | ||
[@thi.ng/rstream](https://github.com/thi-ng/umbrella/tree/develop/packages/rstream), | ||
[@thi.ng/transducers-async](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers-async) | ||
and | ||
@@ -120,5 +122,6 @@ [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers), | ||
constructs and patterns. Most of _rdom_ only deals with either subscribing to | ||
reactive values and/or wrapping/transforming existing subscriptions, either | ||
explicitly using the provided control components (e.g. | ||
[`$sub()`](https://docs.thi.ng/umbrella/rdom/functions/_sub.html)) or using | ||
reactive values, async iterables and/or wrapping/transforming existing | ||
subscriptions, either explicitly using the provided control components (e.g. | ||
[`$async()`](https://docs.thi.ng/umbrella/rdom/functions/_async.html)), | ||
[`$sub()`](https://docs.thi.ng/umbrella/rdom/functions/_sub.html), or using | ||
[`$compile()`](https://docs.thi.ng/umbrella/rdom/functions/_compile.html) to | ||
@@ -150,4 +153,4 @@ auto-wrap such values embedded in an hiccup tree. | ||
**All of these functions are also usable, even if you don't intend to use any | ||
other package features!** | ||
**All of the following functions are also usable, even if you don't intend to | ||
use any other package features!** | ||
@@ -175,2 +178,3 @@ - [$addChild](https://docs.thi.ng/umbrella/rdom/functions/_addChild.html) | ||
- [$async](https://docs.thi.ng/umbrella/rdom/functions/_async.html) | ||
- [$klist](https://docs.thi.ng/umbrella/rdom/functions/_klist.html) | ||
@@ -192,8 +196,8 @@ - [$list](https://docs.thi.ng/umbrella/rdom/functions/_list.html) | ||
Reactive rdom component are based on | ||
Currently, reactive rdom components are based on | ||
[@thi.ng/rstream](https://github.com/thi-ng/umbrella/tree/develop/packages/rstream) | ||
subscriptions. In order to create a feedback loop between those reactive state | ||
values and their subscribed UI components, input event handlers need to feed any | ||
user changes back to those reactive state(s). To reduce boilerplate for these | ||
tasks, the following higher order input event handlers are provided: | ||
subscriptions. To create a feedback loop between those reactive state values and | ||
their subscribed UI components, input event handlers need to feed any user | ||
changes back to those reactive state(s). To reduce boilerplate for these tasks, | ||
the following higher order input event handlers are provided: | ||
@@ -227,3 +231,4 @@ - [$input](https://docs.thi.ng/umbrella/rdom/functions/_input.html) | ||
Click counter: | ||
Click counter using [thi.ng/rstream](https://github.com/thi-ng/umbrella/tree/develop/packages/rstream) and | ||
[thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers): | ||
@@ -249,2 +254,30 @@ ```ts | ||
### Embedding async iterables | ||
Work is underway to better support [built-in | ||
AsyncIterables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols) | ||
(possibly entirely in-lieu of rstream constructs). Currently, they can only be directly used for simple text or attribute values (also see the [rdom-async example](https://github.com/thi-ng/umbrella/blob/develop/examples/rdom-async)): | ||
```ts | ||
import { $compile } from "@thi.ng/rdom"; | ||
import { range, source } from "@thi.ng/transducers-async"; | ||
// infinite 1Hz counter | ||
const counter = range(1000); | ||
// manually updated click counter (also an async iterable) | ||
const clicks = source(0); | ||
// event handler to update click count | ||
const updateClicks = () => clicks.update((x)=> x + 1); | ||
// compile DOM with embedded async iterables | ||
$compile( | ||
["div", {}, | ||
["div", {}, "counter: ", counter], | ||
["button", { onclick: updateClicks }, "clicks: ", clicks] | ||
] | ||
).mount(document.body) | ||
``` | ||
## Status | ||
@@ -285,8 +318,8 @@ | ||
```html | ||
<script type="module" src="https://cdn.skypack.dev/@thi.ng/rdom"></script> | ||
<script type="module" src="https://esm.run/@thi.ng/rdom"></script> | ||
``` | ||
[Skypack documentation](https://docs.skypack.dev/) | ||
[JSDelivr documentation](https://www.jsdelivr.com/) | ||
Package sizes (brotli'd, pre-treeshake): ESM: 4.04 KB | ||
Package sizes (brotli'd, pre-treeshake): ESM: 4.21 KB | ||
@@ -331,2 +364,3 @@ ## Dependencies | ||
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/ramp-scroll-anim.png" width="240"/> | Scroll-based, reactive, multi-param CSS animation basics | [Demo](https://demo.thi.ng/umbrella/ramp-scroll-anim/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/ramp-scroll-anim) | | ||
| | Basic & barebones usage of async iterables in thi.ng/rdom | [Demo](https://demo.thi.ng/umbrella/rdom-async/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-async) | | ||
| | Demonstates various rdom usage patterns | [Demo](https://demo.thi.ng/umbrella/rdom-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-basics) | | ||
@@ -333,0 +367,0 @@ | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-delayed-update.jpg" width="240"/> | Dynamically loaded images w/ preloader state | [Demo](https://demo.thi.ng/umbrella/rdom-delayed-update/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-delayed-update) | |
@@ -1,2 +0,2 @@ | ||
import type { Fn2, Path } from "@thi.ng/api"; | ||
import type { Fn2, Maybe, Path } from "@thi.ng/api"; | ||
import type { ISubscribable } from "@thi.ng/rstream"; | ||
@@ -45,5 +45,5 @@ import { Subscription } from "@thi.ng/rstream/subscription"; | ||
export declare class $Sub<T = any> extends Subscription<T, T> { | ||
protected inner: IMountWithState<T | undefined>; | ||
protected inner: IMountWithState<Maybe<T>>; | ||
el?: Element; | ||
constructor(inner: IMountWithState<T | undefined>, id?: string); | ||
constructor(inner: IMountWithState<Maybe<T>>, id?: string); | ||
mount(parent: ParentNode, index?: NumOrElement): Promise<Element>; | ||
@@ -50,0 +50,0 @@ unmount(): Promise<void>; |
import type { IComponent, IMountWithState } from "./api.js"; | ||
export interface WrappedComponent<T> extends IMountWithState<T> { | ||
inner: IComponent<any>; | ||
} | ||
/** | ||
@@ -10,3 +13,3 @@ * Returns a component wrapper for a single DOM element whose TEXT body can be | ||
*/ | ||
export declare const $wrapText: (tag: string, attribs?: any, body?: any) => IMountWithState<any>; | ||
export declare const $wrapText: (tag: string, attribs?: any, body?: any) => WrappedComponent<any>; | ||
/** | ||
@@ -39,3 +42,3 @@ * Returns a component wrapper for a single DOM element whose HTML body can be | ||
*/ | ||
export declare const $wrapHtml: (tag: string, attribs?: any, body?: import("@thi.ng/api").MaybeDeref<string> | undefined) => IMountWithState<import("@thi.ng/api").MaybeDeref<string>>; | ||
export declare const $wrapHtml: (tag: string, attribs?: any, body?: import("@thi.ng/api").MaybeDeref<string> | undefined) => WrappedComponent<import("@thi.ng/api").MaybeDeref<string>>; | ||
/** | ||
@@ -42,0 +45,0 @@ * {@link IComponent} wrapper for an existing DOM element. When mounted, the |
@@ -1,6 +0,7 @@ | ||
import { $addChild, $el, $html, $remove, $text } from "./dom.js"; | ||
import { $compile } from "./compile.js"; | ||
import { $addChild, $html, $remove, $text } from "./dom.js"; | ||
const wrapper = (update) => (tag, attribs, body) => ({ | ||
el: void 0, | ||
async mount(parent, index, state) { | ||
this.el = $el(tag, attribs, null, parent, index); | ||
this.inner = $compile([tag, attribs]); | ||
this.el = await this.inner.mount(parent, index); | ||
update(this.el, state != null ? state : body); | ||
@@ -10,3 +11,3 @@ return this.el; | ||
async unmount() { | ||
$remove(this.el); | ||
this.inner.unmount(); | ||
this.el = void 0; | ||
@@ -13,0 +14,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
130814
40
2158
489
Updated@thi.ng/api@^8.11.0
Updated@thi.ng/checks@^3.6.2
Updated@thi.ng/errors@^2.5.5
Updated@thi.ng/hiccup@^5.1.29
Updated@thi.ng/paths@^5.1.79
Updated@thi.ng/prefixes@^2.3.17
Updated@thi.ng/rstream@^8.4.1
Updated@thi.ng/strings@^3.7.31