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

@playframe/component

v1.1.1

Published

Pure Stateful Styled Components

Downloads

1

Readme

PlayFrame

Component

0.3 kB Pure Stateful Styled Components

Installation

npm install --save @playframe/component

Description

Pure Functional Styled Web Components for PlayFrame. Components are rendered independetly from the rest of the app. By using Shadow DOM provided by ShaDOM we achieve scoped styling and simple css selectors. Please consider using CSS Variables for maximum animation performance and flexibility.

You can create instances manually and keep them in parent state or you can register them with fp.use or h.use and create them dynamically. To be able to identify the same dynamic component we use a unique object mkey as a WeakMap key. For a UserView Component actual user object would be a perfect WeakMap key

Usage

import h from '@playframe/h'
import oversync from '@playframe/oversync'
import component from '@playframe/component'

const sync = oversync(Date.now, requestAnimationFrame)
const Component = component(sync)

export default myCounter = (Component)=>
  Component({
    seconds: 0,
    _: {
      reset: ()=> {seconds: 0}
      increment: (x, state)=> {
        state.seconds++
        setTimeout( state._.increment,
          (1000 - Date.now() % 1000) || 1000 )
      }
    }
  })((state)=>
    <my-counter style={ {'--border': state.border} }>
      <style>{`
        :host {
          display: block;
          border: var(--border, 0);
        }
      `}</style>
      <div>
        {props.children}
        <br/>
        {state.seconds} seconds passed
        <br/>
        <button onclick={state._.reset}> Reset </button>
      </div>
    </my-counter>
  )

// our Counter instance with initial props
const MyCounter = myCounter(Component)({seconds: 42})

// reset in 10 seconds
setTimeout(MyCounter._.reset, 10000)

const view = ()=>
  <MyCounter border="1px solid grey">
    <h1>Hello</h1>
  </MyCounter>

// or we can register component as custom element
h.use({'my-counter': (props)=>
  let mkey = props && props.mkey
  makeMyCounter(Component)({mkey})(props)
})

// mkey is used as WeakMap key to cache our statefull component
const mkey = {uniqueObject: true}

const view = ()=>
  <my-counter mkey={mkey} border="1px solid grey">Hello</my-counter>

Annotated Source

We are going to use statue for managing state of our Component

evolve = require '@playframe/evolve'
statue = require '@playframe/statue'

How about using a tree of WeakMap instances to cache our Component instances by mkey? This allows us to cache our components aggresively because our _cache will be cleaned automatically by Garbage Collector if mkey gets dereferenced

Let's export a higher order function that takes sync engine, state_actions for statue and a pure view function.

module.exports = (sync)=>(state_actions)=>(view)=> _cache = new WeakMap; (upgrade)=>
  if (mkey = upgrade and upgrade.mkey) and
      Component = _cache.get mkey
    return Component

  _v_dom = null
  _props = null
  _rendering = false
  _state = evolve state_actions, upgrade

Creating a statue that will deliver the latest state on sync.render and patch shadow DOM if needed

  _state = statue _state, sync.render, (state)=>
    _state = state
    do patch_shadow unless _rendering
    _rendering = false
    return

patch_shadow is responsible for producing new virtual DOM and using patch method for shadow DOM mutation provided by ShaDOM.

  patch_shadow = =>
    {patch} = _v_dom
    _v_dom = view _state
    _v_dom.patch = patch
    patch _v_dom
    return

  render = =>
    _v_dom = view _state
    attr = _v_dom[1] or= {}
    attr.attachShadow or= mode: 'open'
    return

Here we create our Component function that mimics your view function. But first it's checking if props are meant to update _state

  Component = (props)=>
    if _v_dom
      unless props is _props
        # shallow equality check
        for k, v of props when v isnt _state[k]
          # updating state with props and rendering
          _state = _state._ _props = props
          _rendering = true
          do render
          break

    else # first run
      _state = Object.assign _state._(), _props = props
      do render

    _v_dom

Assigning high level methods from statue, adding instance to cache and our fresh Component is ready!

  Component._ = _state._

  _cache.set mkey, Component if mkey

  Component