atomicojs / atomico

Atomico a micro-library for creating webcomponents using only functions, hooks and virtual-dom.
https://atomicojs.dev
MIT License
1.15k stars 43 forks source link

R 1.68.0 #102

Closed UpperCod closed 1 year ago

UpperCod commented 1 year ago

This PR refactors part of the Atomico code, to introduce new features and maintenance improvements.

new features.

  1. 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 useInsertionEffect hook.
  2. 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 useAsync and useSuspense.
  3. 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

  1. migration of the use of let by const, to improve the maintenance syntax within core.
  2. deleveraging of the context api internally.
  3. 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:

  1. The first run clears the effects of useInsertionEffects.
  2. The second run clears the effects of useLayoutEffects.
  3. 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()()();