Releases: atomicojs/atomico
Improvement for error log and jsx-runtime
Error log
For errors due to transformation of serializable values, Atomico now adds a wrapper to improve the inspection of the origin of the error, example:
With this you can easily identify which is the target (webcomponent) that generates the error due to a wrong attribute setting.
jsx-runtime
Added path jsx-dev-runtime as an alias for path jsx-runtime.
New hooks useInsertionEffect, useId, useAsync and useSuspense 🎉
This PR refactors part of the Atomico code, to introduce new features and maintenance improvements.
new features.
- The hooks api has been refactored to now allow hooks to be tagged, thanks to this tag in the future it will be possible to filter the execution of hooks and improve their inspection, currently this functionality is being used by the new
useInsertionEffecthook. - in the previous version it introduced use Promise as an advance to asynchronous handling within the core, this hook has allowed us to add in this version 2 new hooks
useAsyncanduseSuspense. - se agrega
useId, con soporte tanto al usar SSR o Browser.
useInsertionEffect
copy of React's useInsertionEffect, similar to useEffect, but this hook is executed before rendering the DOM, this hook is useful for 3rd party apis looking to manipulate the DOM before rendering the component's DOM.
useId
copy of React's useId, creates a unique ID for the Atomico context, the generated ID will depend on the origin, whether it is SSR or Client.
SSR ID Example: s0-1.
CLIENT ID Example: c0-1.
useAsync y useSuspense
useAsync: this hook is a step before the adoption of React's use hook, it allows to suspend the rendering execution of the webcomponent and to communicate to useSuspense the execution suspension.
const getUser = (id: number): Promise<{ name: string }> =>
fetch(`user/${id}`).then((res) => res.json());
function component({ id }) {
const user = useAsync(getUser, [id]);
return <host>{user.name}</host>;
}Nota 1: This hook conditions the execution of the promise according to a list of optional arguments, which allows the promise to be regenerated every time the list changes.
Nota 2: useAsync suspends rendering execution and resumes it only if the promise has been resolved or rejected.
useSuspense: captures all nested executions that have been paused, it returns an object that defines the state of the executions.
function component() {
const status = useSuspense();
return (
<host shadowDom>
{status.pending ? "Loading..." : status.fulfilled ? "Done!" : "Error!"}~
<slot />
</host>
);
}Maintenance improvements
- migration of the use of let by const, to improve the maintenance syntax within core.
- deleveraging of the context api internally.
- migration of types from JSDOC to JSDOC with TS.
Warnings
This new change has generated modifications to the core at the level of hooks, currently the changes have passed all the tests without complications, we will be attentive to any bug or unexpected behavior.
For creators of third party APIs based on createHooks, cleanEffects now has 3 execution steps:
- The first run clears the effects of
useInsertionEffects. - The second run clears the effects of
useLayoutEffects. - The third and last run clears the effects of
useEffect.
You should update your tests by adding the third run to clean up the useEffect, example:
hooks.cleanEffects()()();the usePromise hook is added
usePromise
This hook allows us to observe the resolution of a promise, with this hook we seek to provide a utility at the core level to work with asynchronous tasks
Syntax
import { usePromise } from "atomico";
const callback = (id: number)=>Promise.resolve(id);
const args:Parameters<typeof callback> = [1];
const autorun = true;
const promise = usePromise( callback, args, autorun );
where:
callback: asynchronous function.args: arguments that callback requires.autorun: by default true, it automatically executes the promise, if it is false the execution of the promise is suspended.promise: return object, at the type level it defines the following properties:pending: boolean, defines if the promise is executed but pending resolution.fulfilled: boolean , defines if the promise has been fulfilledresult: result of the promise.rejected: boolean, defines if the promise has been rejected.
Example
import { usePromise } from "atomico";
const getUsers = (id: number) => Promise.resolve({ id, name: "Atomico" });
function component() {
const promise = usePromise(getUsers, [1]);
return (
<host>
{promise.fulfilled ? (
<h1>Done!</h1>
) : promise.pending ? (
<h1>Loading...</h1>
) : (
<h1>Error!</h1>
)}
</host>
);
}Note: At the type level, autocompletion is conditional on the state you are looking to observe.
Fix Any export
Exposes at the Any type level, this is an alias for null but at the Atomico level
Fix the any declaration when using the Component type
1.66.3 fix type any
Fix types for TS when using Component type
1.66.2 fix types for TS when using Component type
Fix Component types for Typescript
Atomico through TS declarations extracted all the global constructors available in Window, sometimes these constructors were modified by third-party libraries, which could cause the props to not be inferred correctly.
This version limits the declared types ( If you are a user of any global type not considered, attach it to an issue to add it to the allowed types )
new JSX type is added (feature for TSX only)
JSX type
this new type creates a wrapper to instantiate an element retrieved from the DOM in JSX, example:
import { JSX } from "atomico";
const [ Template ] = useSlot< JSX<{value: number} >>(ref);
<Template value={10}/>This enhances the technique of referencing slots as templates
Fix props.children for lite components
Now lite components correctly receive props.children
Add support for function components
Thanks to @efoken, [email protected] now allows stateless function instances in JSX🎉, for example:
// Just a plain function, no Custom Element...
const CloseIcon = (props) => (
<svg viewBox="0 0 16 16" width="16" height="16" {...props}>...</svg>
);
// ... can be re-used in JSX like this:
function button() {
return (
<host shadowDom>
<button>
<CloseIcon aria-hidden="true" />
</button>
</host>
);
}