{"id":13555311,"url":"https://github.com/root-systems/catstack","last_synced_at":"2025-04-03T08:30:54.706Z","repository":{"id":57195046,"uuid":"46977644","full_name":"root-systems/catstack","owner":"root-systems","description":"[ON HOLD] :cat2: :cat2: :cat2: A modular mad science framework for teams working on production web apps.","archived":false,"fork":false,"pushed_at":"2017-03-30T08:12:16.000Z","size":206,"stargazers_count":49,"open_issues_count":21,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-02T22:49:19.910Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://catstack.herokuapp.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/root-systems.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-27T11:50:25.000Z","updated_at":"2024-08-30T11:29:52.000Z","dependencies_parsed_at":"2022-09-16T05:21:50.084Z","dependency_job_id":null,"html_url":"https://github.com/root-systems/catstack","commit_stats":null,"previous_names":["enspiral-root-systems/catstack"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/root-systems%2Fcatstack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/root-systems%2Fcatstack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/root-systems%2Fcatstack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/root-systems%2Fcatstack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/root-systems","download_url":"https://codeload.github.com/root-systems/catstack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246965465,"owners_count":20861872,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T12:03:08.568Z","updated_at":"2025-04-03T08:30:49.692Z","avatar_url":"https://github.com/root-systems.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","others"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg\n    alt=\"catstack on a post-it note\"\n    src=\"http://i.imgur.com/v5zw1z3.jpg\"\n    height=\"200\"\n  /\u003e\n  \u003cbr /\u003e\n  catstack\n\u003c/h1\u003e\n\n\u003ch4 align=\"center\"\u003e\n  :cat2: :cat2: :cat2: A modular framework for teams working on production web apps.\n\u003c/h4\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003c!-- stability --\u003e\n  \u003ca href=\"https://nodejs.org/api/documentation.html#documentation_stability_index\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/stability-experimental-orange.svg?style=flat-square\" alt=\"stability\" /\u003e\n  \u003c/a\u003e\n  \u003c!-- npm version --\u003e\n  \u003ca href=\"https://npmjs.org/package/catstack\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/catstack.svg?style=flat-square\" alt=\"npm version\" /\u003e\n  \u003c/a\u003e\n  \u003c!-- build status --\u003e\n  \u003ca href=\"https://travis-ci.org/enspiral-root-systems/catstack\"\u003e\n    \u003cimg src=\"https://img.shields.io/travis/enspiral-root-systems/catstack/master.svg?style=flat-square\" alt=\"build status\" /\u003e\n  \u003c/a\u003e\n  \u003c!-- test coverage --\u003e\n  \u003ca href=\"https://codecov.io/github/enspiral-root-systems/catstack\"\u003e\n    \u003cimg src=\"https://img.shields.io/codecov/c/github/enspiral-root-systems/catstack/master.svg?style=flat-square\" alt=\"test coverage\" /\u003e\n  \u003c/a\u003e\n  \u003c!-- downloads --\u003e\n  \u003ca href=\"https://npmjs.org/package/catstack\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dm/catstack.svg?style=flat-square\"\n      alt=\"Downloads\" /\u003e\n  \u003c/a\u003e\n  \u003c!-- standard style --\u003e\n  \u003ca href=\"https://github.com/feross/standard\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square\" alt=\"standard style\" /\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003etable of contents\u003c/summary\u003e\n  \u003cli\u003e\u003ca href=\"#features\"\u003efeatures\u003c/a\u003e\u003c/li\u003e\n  \u003cli\u003e\u003ca href=\"#demos\"\u003edemos\u003c/a\u003e\u003c/li\u003e\n  \u003cli\u003e\u003ca href=\"#concepts\"\u003econcepts\u003c/a\u003e\u003c/li\u003e\n  \u003cli\u003e\u003ca href=\"#bin\"\u003ebin\u003c/a\u003e\u003c/li\u003e\n  \u003cli\u003e\u003ca href=\"#api\"\u003eapi\u003c/a\u003e\u003c/li\u003e\n  \u003cli\u003e\u003ca href=\"#install\"\u003einstall\u003c/a\u003e\u003c/li\u003e\n  \u003cli\u003e\u003ca href=\"#inspiration\"\u003einspiration\u003c/a\u003e\u003c/li\u003e\n\u003c/details\u003e\n\nsponsored by [Enspiral Root Systems](https://github.com/enspiral-root-systems/meta)\n\ninspired by [`ahdinosaur/mad-science-handbook`](https://github.com/ahdinosaur/mad-science-handbook)\n\nfor previous version, see [catstack@1](https://github.com/enspiral-root-systems/catstack/commit/8830cf8b4bb8ce794ed491d03ab0d96bbb66df8f)\n\n## features\n\n- provides development architecture which linearly scales complexity as your app evolves.\n- provides prescriptive opinions to bootstap teams onto a consistent development platform across projects.\n- everything is a [`depject`](https://github.com/depject/depject) module that can be overridden or combined.\n- app file structure maps to app modules, making it easy to separate concerns and get things done.\n- provides full stack app server for both development and production.\n- consistent concepts across front and back end.\n\n\n## demos\n\n- [catstack.herokuapp.com](https://catstack.herokuapp.com/): this repo's [./example](example) deployed to heroku\n\n## concepts\n\n- [modules](https://github.com/dominictarr/depject)\n- [streams](https://github.com/pull-stream/pull-stream)\n- [services](https://github.com/ahdinosaur/vas)\n- [state, actions, effects, html views](https://github.com/ahdinosaur/inu)\n- [data logs and views](https://github.com/flumedb/flumedb)\n- [commands](http://substack.net/task_automation_with_npm_run)\n\n## bin\n\n- [generate](#generate)\n- [dev](#dev)\n- [server](#server)\n- [test](#test)\n- [lint](#lint)\n\n### gen\n\nTODO\n\ngenerate new project\n\n```shell\ncatstack generate:project\n```\n\n### start\n\n#### dev\n\nstarts development server\n\n```shell\ncatstack dev server\n```\n\n#### server\n\nstarts production server\n\n```shell\ncatstack server\n```\n\n### test\n\nruns [`pull-test`](https://github.com/ahdinosaur/pull-test) tests\n\ncan optionally take a [glob](https://www.npmjs.com/package/glob)\n\n```shell\nnpm run test -- './todos/**/*.test.js'\n```\n\ndefault glob is `./**/*.test.js` ignoring `node_modules`\n\n### lint\n\nchecks for [standard style](http://standardjs.com)\n\ncan optionally take a [glob](https://www.npmjs.com/package/glob)\n\n```shell\nnpm run lint -- './todos/**/*.js'\n```\n\ndefault glob is `./**/*.js` ignoring `node_modules`\n\n## directory structure\n\nthe `catstack` files are organized in the following hierarchy:\n\n\u003e ${topic} / ${type} / ${module}.js\n\n- `config/`\n  - `config/index.js`\n  - `config/${ NODE_ENV }.js`\n- `${ topic }/`\n- tests are any files that end in `.test.js`\n\n### topic overview\n\nin 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 topic, where each topic contains the various types of files *within* that topic.\n\neach topic directory may contain any of:\n\n- `state.js`: exports initial store state\n- `action/*.js`: exports store actions\n- `effect/*.js`: exports effects\n- `getter/*.js`: exports [`reselect`](https://www.npmjs.com/package/reselect) getters\n- `page/*.js`: exports routed views\n- `element/*.js`: exports presentation views\n- `helper/*.js`: exports helper functions\n- `service.js`: exports [`vas`](https://github.com/ahdinosaur/vas) service\n\n### `${ topic }/state.js`\n\n```js\n// cats/state.js`\nmodule.exports = {\n  create: () =\u003e ({\n    init: () =\u003e ({\n      model: {},\n      effect: null\n    })\n  })\n}\n```\n\n### `/${ topic }/action/*.js`\n\n```js\n// cats/action/create.js\nmodule.exports = {\n  create: () =\u003e ({\n    update: (model, action) =\u003e {\n      console.log('cat:create', model, action)\n      return model\n    }\n  })\n}\n```\n\n### `/${ topic }/effect/*.js`\n\n```js\n// cats/effect/fetch.js\nmodule.exports = {\n  create: () =\u003e ({\n    run: (model, effect) =\u003e {\n      console.log('cat:fetch', effect)\n    }\n  })\n}\n```\n\n### `/${ topic }/get/*.js`\n\n```js\n// cats/get/cats.js\nmodule.exports = {\n  create: () =\u003e (state) =\u003e state.cats\n}\n```\n\n### `/${ topic }/page/*.js`\n\n```js\n// cats/page/show.js\nmodule.exports = {\n  needs: {\n    'app.layout.main': 'first',\n    cats: {\n      'element.profile': 'first',\n      'get.show': 'first'\n    }\n  },\n  create: (api) =\u003e ({\n    route: '/cats/:catId',\n    layout: api.layout.main,\n    get: api.cats.get.show,\n    view: api.cats.element.profile\n  })\n}\n```\n\n### `/${ topic }/element/*.js`\n\n```js\n// cats/element/profile.js\nmodule.exports = {\n  needs: {\n    'inu.html': 'first'\n  },\n  create: (api) =\u003e ({\n    view: (cat) =\u003e api.html`\n      \u003cdiv\u003e${cat.name}\u003c/div\u003e\n    `\n  })\n}\n```\n\n### `/${ topic }/service.js`\n\n```js\n// cats/service.js\nmodule.exports = {\n  needs: {\n    data: 'first'\n  },\n  manifest: {\n    all: 'source',\n    get: 'async'\n  },\n  create: function (api) {\n    const cats = [{\n      name: 'Fluffy'\n    }, {\n      name: 'Zoe'\n    }]\n\n    return {\n      methods: { all, get }\n    }\n\n    function all () {\n      return pull.values(cats)\n    }\n\n    function get (id, cb) {\n      cb(null, data[id])\n    }\n  }\n})\n```\n\n## FAQ\n\n### how do i do relations between models?\n\nimplement them in your `getters.js` file as selectors.\n\nin the future, we should extract common relations into helper creators.\n\n## license\n\nThe Apache License\n\nCopyright \u0026copy; 2016-2017 Michael Williams\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froot-systems%2Fcatstack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froot-systems%2Fcatstack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froot-systems%2Fcatstack/lists"}