{"id":19813582,"url":"https://github.com/lazamar/smvc","last_synced_at":"2025-05-01T10:30:59.153Z","repository":{"id":232615461,"uuid":"783651203","full_name":"lazamar/smvc","owner":"lazamar","description":"A Straightforward Model View Controller library for the frontend.","archived":false,"fork":false,"pushed_at":"2024-05-19T23:00:27.000Z","size":61,"stargazers_count":61,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-10T10:41:56.202Z","etag":null,"topics":["javascript-library","mvc","mvc-architecture","mvc-framework","mvc-pattern"],"latest_commit_sha":null,"homepage":"https://lazamar.github.io/smvc/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lazamar.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-08T10:00:30.000Z","updated_at":"2024-10-12T01:24:35.000Z","dependencies_parsed_at":"2024-04-21T20:56:56.324Z","dependency_job_id":"2569fac9-ac60-4c23-a221-b2f68c2273aa","html_url":"https://github.com/lazamar/smvc","commit_stats":null,"previous_names":["lazamar/html-ui","lazamar/smvc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazamar%2Fsmvc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazamar%2Fsmvc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazamar%2Fsmvc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazamar%2Fsmvc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lazamar","download_url":"https://codeload.github.com/lazamar/smvc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224251536,"owners_count":17280787,"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":["javascript-library","mvc","mvc-architecture","mvc-framework","mvc-pattern"],"created_at":"2024-11-12T09:36:50.089Z","updated_at":"2024-11-12T09:36:51.078Z","avatar_url":"https://github.com/lazamar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# smvc\n\n[![NPM Version](https://img.shields.io/npm/v/smvc.svg?style=flat)](https://www.npmjs.com/package/smvc)\n![GitHub License](https://img.shields.io/github/license/lazamar/smvc)\n![No Dependencies](https://img.shields.io/badge/dependencies-0-green)\n\n**Straightforward Model View Controller**\n\nThis is a simple-as-it-gets library for using a virtual DOM to separate the handling of state and view.\n\nThe entire API consists of 4 functions.\n\nIt uses simple JavaScript, has no dependencies, requires no transpilation, and has fewer than 300 lines of code.\n\nRead the [blog post](https://lazamar.github.io/virtual-dom/)\n\n### Example\n\nVisit the [demos](https://lazamar.github.io/smvc/demos/) page.\n\nA complete example. See it in action [here](https://lazamar.github.io/smvc/demos/minimal.html).\n\n```html\n\u003chtml\u003e\n  \u003cbody\u003e\n    \u003cdiv id=\"container\"\u003e\u003c/div\u003e\n    \u003cscript src=\"./smvc.js\"\u003e\u003c/script\u003e\n    \u003cscript\u003e\n      const { init, h, text } = SMVC;\n      const root = document.querySelector(\"#container\");\n      const initialState = 0;\n\n      const update = (state, msg, enqueue) =\u003e state + msg;\n\n      const view = (state) =\u003e [\n        h(\"div\", { style: \"color: red\", onClick: () =\u003e 2 }, [\n          h(\"p\", {}, [\n            text(`The count is ${state}. Click here to increment.`)\n          ])\n        ])\n      ];\n\n      const { enqueue } = init(root, initialState, update, view);\n      enqueue(1);\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Quickstart\n\nAfter importing `smvc.js` start your application by calling `smvc.init` with the appropriate arguments.\n\nYou can use the library as follows:\n\n```javascript\n// `SMVC` is the only identifier the library adds to the global\n// scope. It is an object with a function to start the\n// application and two functions to build html elements\nconst { init, h, text } = SMVC;\n\n// Where the application will be rendered\nconst root = document.querySelector(\"#container\");\n\n// An initial state for the application.\nconst initialState = { ... };\n\n// How to update that state\nfunction update(state, msg, enqueue) { ... }\n\n// A function to build the view using the `h` and `text`\n// functions from in the SMVC object.\nfunction view(state) { ... }\n\n// Start the application. `init` returns an object with the\n// enqueue function, which is is used to scheduled messages\n// to be used to update the state.\nconst { enqueue } = init(root, initialState, update, view);\n```\n\n### Creating HTML\n\nThis library creates elements in the page based on a description of how the page should look like.\n\nThe user-defined `view` function should return this description in the form of an\narray of element descriptions.\n\nThere are two functions to create HTML element descriptions.\n\n* `text(str: string) : Element` - Describe a text node.\n* `h(tag: string, properties: Object, children: Array\u003cElement\u003e) : Element` - Describe an HTML element.\n\nThe `properties` object should contain HTML properties and attributes as keys.\n\nKeys that start with the `on` prefix in the `properties` object are treated as\nevent listeners and its values should be functions.\n\nEvent listener functions will be given the event they are handling as an argument.\n\nIf an event listener function returns a value different from `undefined` this\nvalue will be used as a message and queued to be sent to the update function.\n\nExamples:\n\n```javascript\nfunction view(state) {\n  return [\n    // A `div` with a class.\n    h(\"div\", { class: \"container\" }, [ ... ]),\n\n    // A disabled button.\n    h(\"button\", { disabled: \"true\" }, [ ... ]),\n\n    // A button that will emit the string `\"toggle\"` as a message when clicked.\n    h(\"button\", { onClick: () =\u003e \"toggle\" }, [ ... ]),\n\n    // A button that will emit a message containing the HTML event handled by the onClick listener.\n    h(\"button\", { onClick: e =\u003e e }, [ ... ])\n  ]\n}\n```\n\n### Emitting messages\n\nThe state is updated by handling messages in the user-defined `update` function.\n\nThere are two ways to emit messages.\n\n**Returning from an event listener**\n\nAny value that is not `undefined` returned by an event listener will be emitted as a message.\n\n```javascript\n// A button which when clicked will emit as a message\n// the object { tag: \"clicked, event: \u003cevent\u003e }\n// where \u003cevent\u003e is the HTML event being handled.\nh(\n    \"button\",\n    {\n        onClick : function (e) {\n            return { tag: \"clicked\", event: e }\n        }\n    },\n    [ text(\"click\") ]\n)\n```\n\n**Using the `enqueue` function**\n\nThis function is in the object returned by `init` and will schedule a message to be handled.\n\n``` javascript\nconst { enqueue } = init(root, initialState, update, view);\n\n// Emit a message.\nenqueue({ tag: \"setCounter\", value: 2 });\n```\n\nIt is safe to call `enqueue` inside the `update` function.\n\nMessages are put in a queue and the `update` function is called for each of them in order.\n\n### Updating the state\n\nThe user-defined `update` function is the part of the program where the state\nshould be changed. It must return the new state.\n\nIt takes three arguments:\n\n* The current state.\n* The message to be handled.\n* The `enqueue` function.\n\nIt is safe to call `enqueue` from inside `update`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flazamar%2Fsmvc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flazamar%2Fsmvc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flazamar%2Fsmvc/lists"}