git ssb

1+

dinoworm 🐛 / catstack



Tree:
📄.gitignore
📄README.md
📁bin
📄browser.js
📄browserEntry.js
📁example
📄index.js
📁lib
📁modules
📄package.json
📄server.js
📁types
README.md

catstack

work in progress

modular framework for data-driven real-time apps

cat stack

made by Enspiral Root Systems

inspired by ahdinosaur/mad-science-handbook

for previous version, see catstack@1

concepts

tools

scripts

install

generate new project

catstack gen:project

start

dev

starts development environment

catstack start:dev

prod

starts production environment

catstack start

test

runs pull-test tests

can optionally take a glob

npm run test -- './todos/**/*.test.js'

default glob is ./**/*.test.js ignoring node_modules

lint

checks for standard style

can optionally take a glob

npm run lint -- './todos/**/*.js'

default glob is ./**/*.js ignoring node_modules

format

converts to standard style if possible

can optionally take a glob

npm run format -- './**/*.js'

default glob is ./**/*.js ignoring node_modules

db:clean

directory structure

domain overview

in contrast to frameworks like Rails which split our app into directories for each "type" of file (models, views, controllers), our app is split into directories for each conceptual domain, where each domain contains the various types of files within that domain.

each domain directory may contain any of:

${ domain }/state.js

// cats/state.js`
module.exports = {
  create: () => ({
    init: () => ({
      model: {},
      effect: null
    })
  })
}

/${ domain }/actions/*.js

// cats/actions/create.js
module.exports = {
  create: () => ({
    update: (model, action) => {
      console.log('cat:create', model, action)
      return model
    }
  })
}

/${ domain }/effects/*.js

// cats/effects/fetch.js
module.exports = {
  create: () => ({
    run: (model, effect) => {
      console.log('cat:fetch', effect)
    }
  })
}

/${ domain }/get/*.js

// cats/get/cats.js
module.exports = {
  create: () => (state) => state.cats
}

/${ domain }/pages/*.js

// cats/pages/show.js
module.exports = {
  needs: {
    'app.layouts.main': 'first',
    cats: {
      'elements.profile': 'first',
      'get.show': 'first'
    }
  },
  create: (api) => ({
    route: '/cats/:catId',
    layout: api.layouts.main,
    get: api.cats.get.show,
    view: api.cats.profile
  })
}

/${ domain }/elements/*.js

// cats/elements/profile.js
module.exports = {
  needs: {
    'inu.html': 'first'
  },
  create: (api) => ({
    view: (cat) => api.html`
      <div>${cat.name}</div>
    `
  })
}

/${ domain }/service.js

// cats/service.js
module.exports = {
  needs: {
    data: 'first'
  },
  manifest: {
    all: 'source',
    get: 'async'
  },
  create: function (api) {
    const cats = [{
      name: 'Fluffy'
    }, {
      name: 'Zoe'
    }]

    return {
      methods: { all, get }
    }

    function all () {
      return pull.values(cats)
    }

    function get (id, cb) {
      cb(null, data[id])
    }
  }
})

FAQ

how do i do relations between models?

implement them in your getters.js file as selectors.

in the future, we should extract common relations into helper creators.

Built with git-ssb-web