An experimental library for hydrating web components and adding "sprinkles of reactivity" to pre-rendered HTML.
https://www.npmjs.com/package/hydroactive/v/0.1.5
Updates the README.md
to include a more accurate example.
Published by dgp1130 about 1 month ago
https://www.npmjs.com/package/hydroactive/v/0.1.5
This release lands a number of changes focused on providing stronger abstractions. Notably, ComponentRef
and ElementRef
have been removed and host
has been upgraded to a SignalComponentAccessor
which supports .connected
and .effect
.
ElementAccessor.prototype.write
as a corollary to ElementAccessor.prototype.read
. Useful for non-reactive / one-time writes to the DOM.AttrAccessor.prototype.write
as a corollary to AttrAccess.prototype.read
. Useful for non-reactive / one-time writes to the DOM.ElementRef
. Prefer ElementAccessor
or ComponentAccessor
.Connectable
. This is an interface which declares Connectable.prototype.connected
, used by ComponentAccessor
to bind to the lifecycle of a component.ReactiveRoot
. This is an interface which declares ReactiveRoot.prototype.effect
, used by SignalComponentAccessor
to bind effects to a component's lifecycle.SignalComponentAccessor
. This is a subclass of ComponentAccessor
but with knowledge of signals, meaning it implements ReactiveRoot
and provides .effect
.defineComponent
to provide a SignalComponentAccessor
. This means you can call host.effect(() => { /* ... */ })
inside a component.ComponentRef
. In general you can use host
/ SignalComponentAccessor
to fill the same need. However if you only need .connected
you should accept a Connectable
and if you only need .effect
you should accept a ReactiveRoot
.defineComponent
to defineSignalComponent
to make clear the dependency on signals.defineBaseComponent
as a corollary to defineSignalComponent
but which provides a ComponentAccessor
(as opposed to a SignalComponentAccessor
) which does not implement ReactiveRoot
(no .effect
) and therefore has no dependency on signals. If a component is simple enough to not require signals, prefer defineBaseComponent
for an even smaller bundle size.sideEffects: false
in package.json
. This should improve bundle sizes as HydroActive does not rely on top-level side effects and bundlers can take advantage of that to more aggressively eliminate unused code.https://www.npmjs.com/package/hydroactive/v/0.1.4
This release adds support for shadow roots. Now on any Queryable
you can call .shadow
to get another Queryable
scoped to that element's shadow root. This works like so:
defineComponent('hello-world', (comp, host) => {
host.query('span'); // Queries light DOM.
host.shadow.query('span'); // Queries shadow DOM.
});
This works with open shadow roots across the board. It was implemented via a new QueryRoot
class which serves as as base implementation of the Queryable
interface. To support shadow roots, QueryRoot
as well as Dehydrated
and ElementAccessor
accept a getClosedShadowRoot
function.
import { QueryRoot } from 'hydroactive';
const el: Element = /* ... */;
const root = QueryRoot.from(el, /* getClosedShadowRoot */ () => shadowRootOfEl);
root.shadow.query('...'); // Queries `shadowRootOfEl`.
This parameter does not need to be provided for open shadow roots (which are easily accessible by QueryRoot
without being explicitly given as an input), but is needed for closed shadow roots as they are otherwise inaccessible.
The host
parameter of the defineComponent
callback has been upgraded to ComponentAccessor
(a new subclass of ElementAccessor
specific to HydroActiveComponent
elements) which automatically provides this function, so host.shadow
naturally supports closed shadow roots with no additional effort necessary. This implementation also does not leak the closed shadow root or ElementInternals
object on the HydroActiveComponent
or anywhere else accessible outside the component and its ComponentAccessor
(which is naturally private to the component), so its shadow root is truly closed.
https://www.npmjs.com/package/hydroactive/v/0.1.3
Fixed publish script as the entire JS code has not been published since v0.1.0.
https://www.npmjs.com/package/hydroactive/v/0.1.1
Adds README
to the published output so it displays on the NPM package page.
https://www.npmjs.com/package/hydroactive/v/0.1.1
This release adds improved hydration support and reworks the core DOM manipulation APIs to decouple utilities like comp.live
into smaller, more composable pieces. ComponentRef
is unchanged, but defineComponent
now provides a second host
parameter (an ElementAccessor
of the host element) which serves as an entry point. See the README for a basic introduction into how live
works under the new system.
There are a few new concepts which make this work:
Queryable
- An interface which provides query
and queryAll
methods.Dehydrated
- A class which wraps a potentially dehydrated element and only lets you unwrap it by asserting that the element is hydrated or actually hydrating it yourself.ElementAccessor
- Wraps an element and provides convenient functions for reading and interacting with it.AttrAccessor
- Wraps an element and a specific attribute and provides convenient functions for reading and interacting with it.live
and bind
- Work basically the same as before, but have been moved into standalone functions which accept an ElementAccessor
as a parameter, rather than being methods on ComponentRef
. Part of the goal here is to make signals tree shakable when not used.The old APIs under ComponentRef
are likely to be removed and heavily reduced. comp.live
is basically obsoleted by the new live
standalone function for instance. Some form of ComponentRef
will likely still exist as a means of accessing ComponentRef.prototype.connected
, but what form that takes long term is still TBD.
Subscribe for a future YouTube video discussing the changes in this release and the design decisions which went into hydration support.
https://www.npmjs.com/package/hydroactive/v/0.1.0
BREAKING CHANGES: Basically everything. This is effectively starting a rewrite of HydroActive
. Most of the core developer experience is pretty similar, there's no major radical changes here. However this does not yet have feature parity with 0.0.5, so a number of APIs just don't exist yet.
See this new YouTube video for a breakdown of the project and an introduction to 0.1.0 features. The video does not contain a comprehensive list of all 0.1.0 HydroActive features, but future videos and content should continue to expand on it going forward. Release notes will also be more specific about individual changes in each incremental release.
https://www.npmjs.com/package/hydroactive/v/0.0.5
Changelog:
$.live
and $.bind
now accept Element
references in addition to string queries.$.scope
. This allows chaining additional queries limited to descendents of the scoped selector.hydrate
.Published by dgp1130 almost 2 years ago
https://www.npmjs.com/package/hydroactive/v/0.0.4
Changelog:
factory()
and templating implementation, moving hydrate()
out of /testing.js
export as a replacement. Instead of using factory()
to create a new instance of an element based on a template with a special attribute, prerender the component inside a template, clone that template, and then hydrate()
it directly. See examples in 519e458176e3c6a8b882e2b352ce65da03f85123.component('my-tag-name', () => { /* ... */ })
. A separate customElements.define()
call is no longer necessary. This makes it impossible to hydrate a HydroActive component without defining its custom element first, which removes a foot-gun that leaked dehydrated elements into user-space.$.hydrate()
to $.read()
.$.hydrate()
(originally named $.hydrateElement()
but subsequently renamed to $.hydrate()
in 6842fb7f692b6852cbacdc33bd7173db06f87921). This is like $.read()
and $.query()
, except that it requires the target to be dehydrated, and triggers hydration immediately with the given props. This allows fine-grained orchestration of hydration timing.$.query()
and $.queryAll()
to throw when they find a custom element. Use $.read()
or $.hydrate()
instead.$.query()
and $.queryAll()
's selector. This was originally intended to catch accidental dehydrated queries of custom elements, but this is now asserted more thoroughly in 6cbaa08e7e66ebf0c02affda06467adb2abb7360 and is obsoleted.Published by dgp1130 almost 2 years ago
https://www.npmjs.com/package/hydroactive/v/0.0.3
Changelog:
/testing.js
module.hit()
and deletes half the stuff in bb9d551f1be0f45f47df63aad0e2adc67c451cff.You can now test HydroActive components in Mocha-compatible environments with the hit()
function, a wrapper of it()
which grabs a DOM component from the page and executes the test with it, then cleans up the element afterwards to provide improved test isolation.
The hydrate()
function triggers hydration on the component and makes it interactive. See examples in d6e5f0959c1eb9232ad55874860cd12756b26e88 for how to use these functions for effective testing.
Published by dgp1130 almost 2 years ago
https://www.npmjs.com/package/hydroactive/v/0.0.2
Published changes:
unobserved()
. Unobserved reads of signal accessors are now always allowed. I didn't like how unobserved()
worked because it meant that any external async operations needed to put unobserved()
between every await
, which is too tricky to be worth it.$.query()
on a custom element. Custom elements should use $.hydrate()
instead.$.props
to provide signal accessors to component properties.Changes to examples:
0.0.0
, but after the original YouTube video was recorded, so it hasn't really been mentioned yet which is why I included it here.spawn-counter
example to more specifically demonstrate spawning multiple instances of a component from a single prerendered template.props-counter
example to demonstrate passing JS "props" to elements hydrated from a template.repeated-counter
example to demonstrate reusing a single template multiple times with host attributes.Full Changelog: https://github.com/dgp1130/HydroActive/compare/releases/0.0.1...releases/0.0.2
Published by dgp1130 almost 2 years ago
Published by dgp1130 almost 2 years ago
https://www.npmjs.com/package/hydroactive/v/0.0.0
Initial release. Import from hydroactive
for the functional API. import from hydroactive/class.js
for the class-based API.
While there isn't much documentation about the features or API, you can check out the YouTube video announcement which walks through a number of examples and demonstrates package features.