Home

Awesome

mst-decorators

Class based MobX-State-Tree definitions.

NPM version Build Status Coverage Status

Some features:

How to use

yarn add mst-decorators
import {getEnv} from 'mobx-state-tree'
import {model, view, ref, bool, array, map, maybe, id, str, jsonDate} from 'mst-decorators'

@model class BaseUser {
  @id id
  @str username
  @str password
}

@model class User extends BaseUser {
  @maybe(str) phone
  @maybe(str) firstName
  @maybe(str) lastName
  
  // view
  get fullName() {
    if (!this.firstName && !this.lastName) return
    if (!this.lastName) return this.firstName
    if (!this.firstName) return this.lastName
    return `${this.firstName} ${this.lastName}`
  }

  // view with parameter
  // we need @view to distinguish it from actions
  @view prefixName(prefix) {
    return `${prefix} ${this.fullName}`
  }

  // action
  setPhone(phone) {
    this.phone = phone
  }
}

@model class Location {
  @num long
  @num lat
}

const Sender = maybe(ref(User))

@model class Message {
  @id id
  @Sender sender
  @str text
  @jsonDate date
  @bool unread = true // default value
  @model(class {
    @maybe(Location) location
    @array(str) files
    @array(str) images
  }) attachments

  static preProcessSnapshot(snap) {
    //...
  }
  static postProcessSnapshot(snap) {
    //...
  }
  
  // attach watchers to model instance
  // they are not actions so you can't modify state tree here
  onPatch(patch, reversePatch) {
    //...
  }
  onSnapshot(snapshot) {
    //...
  }
  onAction(call) {
    //...
  }
}

@model class Chat {
  @id id
  @array(Message) messages
  @map(User) users

  api = undefined // volatile; you should set any value (!)

  // lifecycle hook action
  afterCreate() {
    this.api = getEnv(this).api
  }

  // flow
  *fetchMessages() {
    this.messages = yield this.api.fetchMessages(this.id)
  }
}

const chat = Chat.create({id: '1'}, {api})
chat.fetchMessages()

TS

Because class decorator can't modify type declaration in TS you should use model function instead @model decorator.

class Message {
  @str text
}

export default model(Message)
import Message from './message'

class Chat {
  @array(Message) text
}

export default model(Chat)

API