npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@engineerapart/stencil-lift

v0.1.7

Published

Stencil Lift - An SSR-safe data loading, serialization, and rehydration utility for Stencil apps, powered by Redux

Downloads

18

Readme

Built With Stencil

npm (scoped) npm bundle size (minified + gzip) npm

Stencil

Stencil is a compiler for building fast web apps using Web Components.

Stencil combines the best concepts of the most popular frontend frameworks into a compile-time rather than run-time tool. Stencil takes TypeScript, JSX, a tiny virtual DOM layer, efficient one-way data binding, an asynchronous rendering pipeline (similar to React Fiber), and lazy-loading out of the box, and generates 100% standards-based Web Components that run in any browser supporting the Custom Elements v1 spec.

Stencil components are just Web Components, so they work in any major framework or with no framework at all.

Stencil Lift

[Blurb]

This project is specifically designed to be used in Stencil applications, but there is no particular reason it can't be used in a vanilla JS app. Instructions for doing this are below.

Installing

To start building a new web component using Stencil, clone this repo to a new directory:

npm i @engineerapart/stencil-lift

or

yarn add @engineerapart/stencil-lift

Using the component + data services

You don't have to set up anything. No, really. Just connect your components and go.

Connecting Components

There are 3 steps to getting up and running.

  1. In your main application element (usually app.tsx - your top-level element), wrap the entire tree with the <stencil-lift> component:
@Component(...)
export class MyApp {
  constructor() {
    // whatever
  }

  render() {
    <stencil-lift>
      <your-app-tree></your-app-tree>
    </stencil-lift>
  }
}
  1. Wrap a component you want to connect in the Lift decorator (or export your class wrapped with Lift({key: 'blah'})(YourComponent) as a Higher Order Component):
import { Lift } from '@engineerapart/stencil-lift/';

@Lift({ key: 'YourDescriptiveKey' })
@Component(...)
export class MyComponent {

}

// Alternatively:
export default Lift({key: 'YourDescriptiveKey'})(YourComponent);
  1. If you want to load data in that component on the server, and receive it on the client, add a getInitialProps function to your component (yes, inspired by Next.js) that returns the data in the same shape you want to receive it:
import { Lift } from '@engineerapart/stencil-lift/';

@Lift({ key: 'YourDescriptiveKey' })
@Component(...)
export class MyComponent {

  @State() someKey: any; // if you know the type, put the type!

  async getInitialProps({ Lift, isServer }) => {
    const response = await fetch('http://yourapi/resource/1');
    const data = await response.json();
    // Note that 'someKey' matches the State property above!
    return { someKey: data };
  }

  render() {
    return (
      <div>
        {this.someKey.field}
      </div>
    );
  }
}

That's it. That is literally it. You thought that was going to be harder.

Receiving data from the store without getInitialProps

You remember that data key you put in the Lift({key}) decorator? You can receive any data you want. No really. Let's say you have a loader that executes at the top level of your app on the server. You can push this data directly into stencil-lift and receive it in any component that wants it.

This also means you can load data in one component and display it in any other component.

Adding data to the <stencil-lift> top-level component:

// This can come from wherever you want it to.
const initialState = {
  bubble: {
    title: 'Hello world',
    text: 'I am the very model of a modern major general!',
  }
}

@Component(...)
export class MyApp {

  @State() initialState2: any;

  async componentWillLoad() {
    this.initialState2 = fetch(...);
  }

  render() {
    return (
      <stencil-lift initialState={{...initialState, ...initialState2}}>
        <your-app-tree></your-app-tree>
      </stencil-lift>
    );
  }
}

Receive the data wherever you want:

Same as the original example. No really.

import { Lift } from '@engineerapart/stencil-lift/';

@Lift({ key: 'bubble' })
@Component(...)
export class MyComponent {

  @State() title: string;
  @State() text: string;

  render() {
    return <div>{this.title}<span>{this.text}</span></div>;
  }
}

Other Uses

If it hadn't already occurred to you, you can also use Stencil Lift on the client without any data loading capabilities. Say for example you have a JSON data blob that you have in your bundle; you can inject that directly into <stencil-lift> to disburse it to the component tree. This allows you to have a single entry point for your data and the components simply declare what they need, instead of configuring each component with its data.

Does this work with prerendering?

Yes. If you find any problems with it don't hesitate to open an issue :)

Documentation

stencil-lift Properties

| Prop | Description | |--- |--- | | initialState | The initial data you want pushed to the store. The object's high-level keys correspond to the key argument used in the Lift decorator. | | mergeState | Merge your initialState argument with loaded data, or force it to be used wholly. | | deleteOnClientLoad | For sensitive data, you may not wish it to remain available to the Window context. This will cause it (and the corresponding JS) to be deleted from the window. |

Lift decorator properties

| Prop | Description | |--- |--- | | key | The redux state slice under which this component's data will be stored. You can receive data from ANY state slice - not just the one you generate. |

Example

There is a working example of all of these concepts in the src/components/example folder.

TODO List:

  • [ ] Wire up the components to receive data changes from the redux store on the client. This is easy to do and will be in the next version.
  • [ ] Allow a Lift decorator to receive data from several state slices: Incorporate reselect for this.
  • [ ] Support generic Redux reducers. Let you reshape your data however you see fit before it is stored.
  • [ ] Support side effects in actions. This is less useful, since you can generate the side effect in your component, but you may wish to dispatch an action on the client that is consumed by a different component

Building/Contributing

Clone the project and install dependencies:

git clone https://github.com/engineerapart/stencil-lift.git
cd stencil-lift
npm i && npm start (or npm start:ssr)
- or -
yarn && yarn start (or yarn start:ssr)

IMPORTANT NOTE

For now, there is a bug in the Stencil compiler that causes the lift component to lose its script tag. Make sure you do not remove the line logLevel: 'debug' from the stencil.config.js file. Specifically the bug is actually in uglify-es when using beautify:false and will likely take some time to track down. The ONLY effect this has is that the built packages retain their whitespace - but since gzip compression largely takes care of this it is not a big issue.

You can disable logLevel: 'debug' when running the server if you want, but it must be enabled for the build step.

License

MIT