[go: up one dir, main page]

Skip to content

playframe/playframe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PlayFrame

4 kB 60 fps Functional SPA/PWA Framework

framesync + React + Redux + router + Shadow Dom alike minimalistic functional framework built to be able to update DOM up to 60 times per second. Components can rerender independently from the rest of the app and only if their local state is changed

High-performance server-side rendering for PWA support is coming soon

SPA Example
import {h, app, mount} from '@playframe/playframe'
app({
  // state
  counter: 1,
  // actions
  _: {
    inc: (e, state)=> state.counter++, // mutating
    dec: (e, {counter})=> ({counter: counter - 1}) // or returning object
  }
})( // view
  (state)=>
    <div>
      <h1>Counter: {state.counter}</h1>
      <button onclick={state._.inc}>Increment</button>
      <button onclick={state._.dec}>Decrement</button>
    </div>
  }
)( // dom container
  mount(document.body)
)
Routed Example
import {h, route, mount} from '@playframe/playframe'
route({
  greeting: "Hello",
  routes: {
    '/': ()=> <a href="/hello/world"><h1>Link</h1></a>,
    '/hello/:name': ({state, param})=> <h1>{state.greeting} {param.name}!</h1>,
    '/*': ()=>  <h1>404</h1>
  }
})(
  mount(document.body)
)

Installation

Using npm or yarn:

npm i @playframe/playframe

Using UNPKG for es6 bundle:

https://unpkg.com/@playframe/playframe@1.0.2/dist/playframe.min.js

API

PlayFrame.app(state_actions)(View)(container):

Creates a new app and mounts it into container. Initial state_actions will create a statue instance that will be passed into the View function. If state is modified by actions, app is rerendered. Returns statue instance

PlayFrame.route(state_actions)(container):

Creates a new routed app and mounts it into container. Initial state_actions should have a routes property. Returns statue instance

PlayFrame.mount(domNode):

Creates a ShaDOM container for managing DOM mutations

PlayFrame.h(nodeName, attributes, children...):

Returns a lightweight Virtual DOM node. If you are using JSX you might need ["@babel/plugin-transform-react-jsx", { "pragma": "h" }]. Or you could use rollup with buble({jsx: 'h'})

PlayFrame.Component(state_actions)(View)(upgrade)(props):

Creates a Stateful Web Component function for given state_actions, View and upgrade. upgrade will extend state_actions by using evolve function. Passing props to Component function will return Virtual DOM nodes. Styles are incaplulated by Shadow Dom. Example:

const createHover = PlayFrame.Component({
  i: 0,
  _: {add: (e, state)=> state.i++}
})((state)=>
  <my-hover onhover={state._.add}>
    <style>{`
      :host {
        display: block;
        border: ${state.i}px;
      }
    `}</style>
    <h6>This was hovered {state.i} time(s)</h6>
  </my-hover>
)
let Hover = createHover()
let View = (state)=> <Hover></Hover>

PlayFrame.use(pureComponents):

Registering custom elements for Pure Components. Example:

PlayFrame.use({
  'custom-heading': (props)=> <h1>{props.children}</h1>
})
const View = ()=> <custom-heading>Hello!</custom-heading>

PlayFrame.reuse(statefulComponents):

Registering custom elements for Stateful Components. To reuse the same Component instances we cache them in WeakMap by mkey property which needs to be an object, not a primitive value. Example:

PlayFrame.reuse({
  'my-hover': createHover
})
const hovers = [{}, {}, {}]
const View = (state)=> hovers.map((obj)=>
  <my-hover mkey={obj}></my-hover>
)

Internal functions

PlayFrame.statue(state_actions, delayed, subscribe):

Creates a statue state machine for a state_actions object. delayed will throttle state updates and latest state will be passed to subscribe function. Example:

const state_actions = {
  // state
  i: 0,
  // actions
  _: { add: (e, state)=> state.i++ },
  subCounter: {
    // nested state
    i: 0,
    // nested actions
    _: { add: (e, state)=> state.i++ },
  }
}
state = PlayFrame.statue(state_actions, requestIdleCallback, (state)=>
  console.log(state)
)
state._.add()
state.subCounter._.add()
// Will log on idle
// {i: 1, subCounter: {i: 1, _: {add}}, _: {add}}

PlayFrame.evolve(base, upgrade):

evolve function for deep object extending. If any value in upgrade is a function it will be called with existing value as an argument. Example:

const base = {
  i: 1,
  j: 2,
  onclick: (e)=>{}
}
const upgrade = {
  i: 10, // overwrite value
  j: (j)=> j * 2, // double existing value
  onclick: (onclick)=>(e)=> { // compose functions
    console.log('click')
    onclick(e); // original handler
  }
console.log(PlayFrame.evolve(base, upgrade))
// {i: 10, j: 4, onclick: loggedOnClick}
}

PlayFrame.sync.{next, catch, then, finally, render, frame}:

Initialized instance of OverSync that helps different parts of framework synchronize execution within the unified frame rendering flow

Source

sync = require('@playframe/oversync') Date.now, requestAnimationFrame
exports.sync = sync

exports.Component = require('@playframe/component') sync
exports.mount = require('@playframe/shadom') sync
router = require('@playframe/router') sync

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


exports.app = app = (state_actions)=>(view)=>(container)=>
  state_actions._ or= {}
  state = statue state_actions, sync.finally, (state)=>
    container view, state
  container view, state
  state


exports.route = (state_actions)=> app(state_actions) router


exports.h = h = require '@playframe/h'
exports.use = use = h.use

exports.reuse = (components)=>
  purified = {}
  for k, Component of components
    purified[k] = (props)=>
      mkey = props and props.mkey
      Component(mkey and {mkey}) props
  use purified
  return

About

4 kB 60 fps Functional SPA/PWA Framework

Resources

License

Stars

Watchers

Forks

Packages

No packages published