{"id":15685610,"url":"https://github.com/zordius/webtasks","last_synced_at":"2025-05-07T17:21:49.926Z","repository":{"id":22119164,"uuid":"25449772","full_name":"zordius/webtasks","owner":"zordius","description":"A lightweight web framework based on express and subtask.js","archived":false,"fork":false,"pushed_at":"2014-11-26T06:58:50.000Z","size":1924,"stargazers_count":9,"open_issues_count":3,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-26T03:11:33.108Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.npmjs.org/package/webtasks","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zordius.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-20T03:45:09.000Z","updated_at":"2018-05-04T07:44:37.000Z","dependencies_parsed_at":"2022-08-19T15:10:06.014Z","dependency_job_id":null,"html_url":"https://github.com/zordius/webtasks","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zordius%2Fwebtasks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zordius%2Fwebtasks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zordius%2Fwebtasks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zordius%2Fwebtasks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zordius","download_url":"https://codeload.github.com/zordius/webtasks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243000463,"owners_count":20219681,"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-10-03T17:27:40.660Z","updated_at":"2025-03-11T08:31:02.098Z","avatar_url":"https://github.com/zordius.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"webtasks\n========\n\nA lightweight web framework based on \u003ca href=\"https://github.com/strongloop/express\"\u003eexpress\u003c/a\u003e and \u003ca href=\"https://github.com/zordius/subtask.js\"\u003esubtask.js\u003c/a\u003e\n\n[![npm version](https://img.shields.io/npm/v/webtasks.svg)](https://www.npmjs.org/package/webtasks) [![Dependency Status](https://david-dm.org/zordius/webtasks.png)](https://david-dm.org/zordius/webtasks) [![Build Status](https://travis-ci.org/zordius/webtasks.svg?branch=master)](https://travis-ci.org/zordius/webtasks) [![Test Coverage](https://codeclimate.com/github/zordius/webtasks/badges/coverage.svg)](https://codeclimate.com/github/zordius/webtasks) [![Code Climate](https://codeclimate.com/github/zordius/webtasks/badges/gpa.svg)](https://codeclimate.com/github/zordius/webtasks) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE.txt)\nFeatures\n--------\n\nMake developer decouple complex web application logic into small logic pieces for reusing, and speed up implement and testing.\n\n* All logical components are webtasks in commonjs.\n* All webtask are async.\n* React support (and server side rendering)\n\n**Logical components in this framework**\n\n* **Input**: focus on deal with params or other request based inputs\n* **Data**: call api or get data from storage\n* **Module**: handle presentation logics then rendered with a view\n* **Page**: composite modules then rendered with a view\n* **React**: handle presentation logics then rendered with given properties (data)\n* **Ajax**: collect data then output as JSON\n\nGetting Started\n---------------\n\n**Create your app**\n\n```\nnpm init\nnpm install webtasks --save\n```\n\n**Hello World**\n\n* Create a page webtask in `page/hello.js`:\n\n```javascript\n/*jslint node: true */                                                                                  \n'use strict';\n\nmodule.exports = function () {\n    return this.task({\n        title: 'Good!',\n        description: 'Hello World'\n    });\n};\n```\n\n* Create a \u003ca href=\"http://handlebarsjs.com/\"\u003ehandlebars.js\u003c/a\u003e view for `page/hello.js` in `view/page_hello.hbs` :\n\n```\n\u003chtml\u003e\n\u003chead\u003e\n\u003ctitle\u003e{{title}}\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n{{description}}\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n* Create an \u003ca href=\"http://expressjs.com/\"\u003eexpress\u003c/a\u003e server in `server.js` :\n\n```javascript\n/*jslint node: true */\n'use strict';\n\nvar app = require('webtasks');\n\napp\n.use(app.middleware('page', 'hello'))\n.listen(3000);\n```\n\n* Start the server and browse http://localhost:3000/ :\n\n```sh\nnode server.js\n```\n\nAbout Webtask\n-------------\n\nWebtask is extended from \u003ca href=\"https://github.com/zordius/subtask.js\"\u003esubtask\u003c/a\u003e with \u003ca href=\"#context-api\"\u003eContext API\u003c/a\u003e . Webtasks are automatic singleton per-request, developers do not need to worry about api optimization or task sequence.\n\nFor example, to deliver an article page for login user brings this task depdency:\n\n```\n[checkLogin] -\u003e [getArticle] -\u003e [setPageTitle] -\u003e [composeModules]\n```\n\nIf we add another module depend on another data source, then the module tasks will be appended after composeModules and make the task queue longer. When we try to speed up html deliver time, we will mess up the module composite tasks and data tasks.\n\nWhen this done by webtasks it will like:\n\n```javascript\n// NOTE: pseudo code\narticlePage = webtask({\n    isLogin: input('isLogin'),\n    title: param('id').pipe(data('getArticle')).pick('title'),   // one data('getArticle')\n    story: param('id').pipe(module('article')),\n});\n\narticleModule = param('id').pipe(data('getArticle'));            // another data('getArticle')\n\ndataGetArticle = function (id) {\n    return webtask( ..... call API by id );\n};\n```\n\nAll `data('getArticle')` with same id in this request refer to single webtask instance, the API call will be executed only one time in a request. Another good news is all webtask/subtask are executed parallel, you get performance boost. And, all webtasks focus on handle jobs for itself, you do not need to add extra code to maintain states cross different modules.\n\nPage Component\n--------------\n\nPage is a webtask which will be rendered by a handlebars.js temlpate view. All pages are placed under `page` directory, and all views for pages are placed under `view` directory with `page_*` prefix.\n\nModule Component\n----------------\n\nModule is a webtask which will be rendered by a handlebars.js temlpate view. All modules are placed under `module` directory, and all views for pages are placed under `view` directory with `module_*` prefix. The behavior of a module or a page are exact same, they are named differently for concept reason.\n\nData Component\n--------------\n\nData is a webtask without view and focus on get and processs data. All data are placed under `data` directory.\n\nInput Component\n---------------\n\nInput is a webtask without view and focus on get and process inputs from request, all inputs are places under `input` directory. The behavior of a input or a data are exact same, they are named differently for concept reason.\n\nAJAX Component\n--------------\n\nAJAX is a webtask without view and focus on response json by different request. Actually AJAX is normal webtask placed under `ajax` directory, and in most case it will execute input and data subtasks.\n\n\nREACT Component\n---------------\n\n\u003ca href=\"http://facebook.github.io/react/\"\u003eREACT\u003c/a\u003e is pure \u003ca href=\"http://facebook.github.io/react/docs/jsx-in-depth.html\"\u003ejsx\u003c/a\u003e commonjs module be placed under `react` directory. You can pipe data into react component to render static or dynamic modules, please check the Context API: `this.react` and `this.dreact` .\n\nContext API\n-----------\n\nAll these API return a subtask\n\n* `this.query(name)` : access to `req.query[name]` , return a subtask\n* `this.param(name)` : access to `req.params[name]` , return a subtask\n* `this.header(name)` : access to `req.header(name)` , return a subtask\n* `this.cookie(name)` : access to `req.cookies[name]` , return a subtask\n* `this.input(name)` : get a input subtask\n\n* `this.page(name)` : get a page subtask creator\n* `this.module(name)` : get a module subtask creator\n* `this.data(name)` : get a data subtask creator\n* `this.react` : get a react subtask creator (static)\n* `this.dreact` : get a react subtask creator (will be rendered at server side then be binded at client side)\n* `this.creact` : get a react subtask creator (will be rendered/binded at client side)\n\nTODO\n----\n\n* sample project\n* react state ajax bridge\n* flux?\n* css component\n* gulp env\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzordius%2Fwebtasks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzordius%2Fwebtasks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzordius%2Fwebtasks/lists"}