All Projects → pmros → Cyclow

pmros / Cyclow

Licence: mit
A reactive frontend framework for JavaScript

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Cyclow

Fritz2
Easily build reactive web-apps in Kotlin based on flows and coroutines.
Stars: ✭ 308 (+193.33%)
Mutual labels:  reactive, framework, frontend
Vue.py
Pythonic Vue.js
Stars: ✭ 223 (+112.38%)
Mutual labels:  reactive, framework, frontend
Kvision
Object oriented web framework for Kotlin/JS
Stars: ✭ 658 (+526.67%)
Mutual labels:  reactive, framework, frontend
Connective
agent-based reactive programming library for typescript
Stars: ✭ 98 (-6.67%)
Mutual labels:  reactive, data-flow, framework
Primitive
⛏️ ‎ A front-end design toolkit for developing web apps.
Stars: ✭ 783 (+645.71%)
Mutual labels:  framework, frontend
Servicetalk
A networking framework that evolves with your application
Stars: ✭ 656 (+524.76%)
Mutual labels:  reactive, framework
Tarant
Reactive, actor based framework that can be used in client and server side.
Stars: ✭ 33 (-68.57%)
Mutual labels:  reactive, frontend
Rocket.jl
Functional reactive programming extensions library for Julia
Stars: ✭ 69 (-34.29%)
Mutual labels:  reactive, framework
Displayjs
A simple JavaScript framework for building ambitious UIs 😊
Stars: ✭ 590 (+461.9%)
Mutual labels:  framework, frontend
Aurelia
Aurelia 2, a standards-based, front-end framework designed for high-performing, ambitious applications.
Stars: ✭ 995 (+847.62%)
Mutual labels:  framework, frontend
Axentix
Axentix is an open source Framework based on CSS Grid using HTML, CSS and JS. The easy layout control and grid system makes it one of the most easy to learn framework.
Stars: ✭ 75 (-28.57%)
Mutual labels:  framework, frontend
Nerv
A blazing fast React alternative, compatible with IE8 and React 16.
Stars: ✭ 5,409 (+5051.43%)
Mutual labels:  framework, frontend
Wire
Reactive data processing framework for visual programming tools
Stars: ✭ 86 (-18.1%)
Mutual labels:  reactive, framework
Vue Bootstrap With Material Design
Vue Bootstrap with Material Design - Powerful and free UI KIT
Stars: ✭ 803 (+664.76%)
Mutual labels:  framework, frontend
Frint
Modular JavaScript framework for building scalable and reactive applications
Stars: ✭ 608 (+479.05%)
Mutual labels:  reactive, framework
Monster Ui
The JavaScript framework to leverages the power of Kazoo
Stars: ✭ 54 (-48.57%)
Mutual labels:  framework, frontend
Neo
Create blazing fast multithreaded Web Apps
Stars: ✭ 1,219 (+1060.95%)
Mutual labels:  framework, frontend
Viewi
Powerful tool for building full-stack and completely reactive user interfaces using PHP
Stars: ✭ 93 (-11.43%)
Mutual labels:  reactive, frontend
Spring Data R2dbc
Provide support to increase developer productivity in Java when using Reactive Relational Database Connectivity. Uses familiar Spring concepts such as a DatabaseClient for core API usage and lightweight repository style data access.
Stars: ✭ 534 (+408.57%)
Mutual labels:  reactive, framework
Xreact
reactive x react = xreact
Stars: ✭ 565 (+438.1%)
Mutual labels:  reactive, data-flow

logo

npm version Build Status Join the chat at https://gitter.im/cyclow/Lobby

cyclow is a reactive frontend framework for JavaScript. It's inspired by another frameworks like Cycle.js and TSERS. It uses graflow as stream library.

Example

This a simple counter example:

  import { Block, run } from 'cyclow'

  const Counter = () => Block({
    on: {
      'in.init':  () => state => 0,
      'dom.click': () => state => state + 1
    },
    view: state => ({
      tag: 'button',
      on: {click: 'click'},
      content: `Count: ${state}`
    })
  })

  run(Counter)

Try it online!

More samples

You can build and open samples in a browser:

  git clone https://github.com/pmros/cyclow
  cd cyclow
  npm install
  npm run samples

Samples include a TodoMVC sample.

You can find even more samples at JS Comp and compare them with another implementations using frameworks like React, Angular or Cycle.

Why cyclow?

There are many JavaScript frameworks so... why another one? Well I really like Cycle.js. It's a nice reactive framework. TSERS is like Cycle.js and it adds a simple state manager and another features. But both are too pure (in the functional programmming sense) for me.

With cyclow instead of thinking in a big global model and pure functions, you have to think in components with inputs, outputs and their own state (something like an electronic circuit). I think cyclow is more intuitive and easier while it's still reactive and quite declarative. You can compare cyclow and Cycle.js samples at JS Comp.

cyclow goal is to help you to create applications that are:

  • Declarative
  • Easy to code
  • Easy to read
  • Scalable

How it works

A cyclow app consits of a block. A block is composed of other blocks. A block is graflow component, it receives messages and send messages async.

Every block contains this default blocks:

  • in
  • events
  • state
  • view
  • dom
  • out

In addition, you can add your own blocks or custom blocks with blocks Block option.

Every block inside a block is connected through a bus block, sending and receiving messages. Bus connect blocks forming a cycle.

Messages has three parts:

  • Block
  • Signal
  • Value

You can handle messages with on Block option.

Finally, you can transform state into a Virtual DOM Element with view Block option. Virtual DOM Element will be converted into a real DOM by the renderer.

How To

How to set the initial state?

At the beginning, every block receives an init signal from in block. So you can handle this message to set a initial state.

From the counter example:

  on: {
    'in.init': () => state => 0
  }

In this case, the handler takes no params () and returns a state transformation state => 0. It's a function that takes the current state and returns the next state.

How to handle DOM events?

First, you have to catch the DOM event in view Block option. From counter example:

  view: state => ({
    tag: 'button',
    on: {click: 'click'},
    content: `Count: ${state}`
  })

Then, you can handle DOM event as a normal block message (from dom block):

  on: {
    'dom.click': () => state => state + 1
  }

If you need DOM event information, see Inputbox sample:

on: {
  ...
  'dom.text': newText => text => newText,
},
view: text => ({content: [
  {tag: 'input',
    attrs: {id: 'myInput', value: text},
    on: {keyup: (e, next) => next({text: e.target.value})}
  }
  ...
]})

How to compose blocks?

See Composition sample:

  blocks: {field: Field()},
  on: {
    'in.init': () => [{'field.init': 'Enter name'}, state => ({current: 'Steve'})],
    'field.submission': submission => state => ({current: submission})
  }

How to focus a DOM element?

See Inputbox sample:

  on: {
    'dom.focus': () => ({'dom.action': node => node.firstElementChild.focus()})
  }

How to use LocalStorage to save the state?

See TodoMVC sample:

  on: {
    'in.init': () => state => JSON.parse(localStorage.getItem('todomvc')) || initial(),
    state: state => { localStorage.setItem('todomvc', JSON.stringify(state)) }
  }

How to debug a cyclow app?

You can log every message through bus block:

  on: {
    bus: msg => {
      console.log('Message', msg)
      return msg
    }
  }

You can track state changes too:

  on: {
    state: state => console.log('State', state)
  }

Virtual DOM Element

cyclow represents DOM elements as Virtual DOM Elements, that is a simple Javascript object with the following (optional) properties:

  • tag: HTML tag (default is div)
  • attrs: Attributes (like id, class or style).
  • on: Events handlers (like click). It can be just an event message or a function that receive the DOM event and a function to send an event message.
  • content: Content can be just text, a Virtual DOM Element or an array of Virtual DOM Elements.

This is a virtual DOM element example:

  {
    tag: 'input',
    attrs: { id: 'myInput' },
    on: { keyup: (e, next) => next({text: e.target.value}) }
  }

If you prefer, you can use h hyperscript helper:

  import {Block, run, h} from 'cyclow'

  const Counter = () => Block({
    on: {
      'in.init':  () => state => 0,
      'dom.click': () => state => state + 1
    },
    view: state => view: state => h('button', {on: {click: 'click'}}, `Count: ${state}`)
  })

  run(Counter)

Renderer

A renderer is just a component factory. It creates a component that takes a Virtual DOM Element as an input and it converts into a Real DOM Element and it updates the HTML document. cyclow uses snabbdom as default renderer.

A renderer is a function that it takes target, that the DOM element id where you want to insert into the Virtual DOM Element. If you don't specify target, cyclow will append the app at the end of body.

API

run(MainComponent, options={})

Arguments:

  • MainComponent: A component factory.
  • options:
    • target (document.body by default)
    • renderer (SnabbdomRenderer by default)
    • init ({} by default)

Block(options)

Arguments:

  • options:
    • blocks
    • on
    • view

Returns: A graflow component

TODO

  • [x] Virtual DOM diff and patching
  • [x] A way to focus a DOM element
  • [x] A TodoMVC sample
  • [x] A cool logo
  • [ ] JavaScript Standard Style
  • [ ] A contributing guide
  • [ ] More e2e tests
  • [ ] More documentation
  • [ ] More samples
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].