0.2.0 • Published 28 days ago

modelly v0.2.0

Weekly downloads
-
License
MIT
Repository
-
Last release
28 days ago

Modelly

Event-driven data models for a business logic independent of the UI

  • Framework agnostic: manage a data outside of UI, you don’t need to touch the UI to run change-dependent logic, for example with React hooks
  • Decentralized: split a business logic before components, modules or chunks
  • Boilerplate-free: describe the data and flow of working with them

Install

npm install modelly

or

yarn add modelly

Usage

Base example

import {Channel} from 'modelly'
import {api} from './api'

class User extends Channel {
  displayName?: string
  email?: string

  async fetch() {
    const {displayName, email} = await api.getCurrentUser()
    this.displayName = displayName
    this.email = email
  }
}

const currentUser = new User()

currentUser.on('update', () => {
  // current user is fetched {displayName: '...', email: '...'}
})

currentUser.fetch()

Nested models

import {Channel} from 'modelly'

class User extends Channel {
  displayName: string
  email: string

  async fetch() {
    const {displayName, email} = await api.getCurrentUser()
    this.displayName = displayName
    this.email = email
  }
}

class Auth extends Channel {
  currentUser: User

  async login(credentials) {
    await api.createSession(credentials)
    this.currentUser = new User()
    this.currentUser.fetch()
  }
}

const auth = new Auth()

auth.on('update', () => {
  // session is created {currentUser: {}}
  // current user is fetched {currentUser: {displayName: '...', email: '...'}}
})

auth.login({email: '...', password: '...'})

Custom events

import {Channel} from 'modelly'

interface User {
  displayName: string
  email: string
}

class Auth extends Channel {
  currentUser: User

  async login(credentials) {
    this.currentUser = await api.createSession(credentials)
    this.emit('login')
  }
}

interface Book {
  title: string
}

class Books extends Channel {
  books: Book[]

  fetch = () => {
    this.books = await api.getBooks(credentials)
  }
}

const auth = new Auth()
const books = new Books()

auth.on('login', books.fetch)

auth.on('update', () => {
  // render auth in header
})

books.on('update', () => {
  // render books list
})

auth.login({email: '...', password: '...'})

Extend a channel

Example using dependency injection – API service into a model

import {Channel} from 'modelly'
import {api, ApiService} from './api'

class InjectedChannel extends Channel {
  api: ApiService

  constructor(api: ApiService) {
    super()

    this.api = api
  }
}

class User extends InjectedChannel {
  displayName?: string
  email?: string

  async fetch() {
    const {displayName, email} = await this.api.getCurrentUser()
    this.displayName = displayName
    this.email = email
  }
}

const currentUser = new User(api)

currentUser.on('update', () => {
  // current user is fetched {displayName: '...', email: '...'}
})

currentUser.fetch()

License

MIT

0.2.0

28 days ago

0.1.1

7 months ago

0.1.0

7 months ago