{"id":18041619,"url":"https://github.com/katyo/literium","last_synced_at":"2025-06-26T22:33:21.447Z","repository":{"id":66335228,"uuid":"123953603","full_name":"katyo/literium","owner":"katyo","description":"Pretty simple Web-application framework","archived":false,"fork":false,"pushed_at":"2018-12-08T16:09:56.000Z","size":800,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-24T02:36:44.917Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/katyo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2018-03-05T17:23:06.000Z","updated_at":"2019-04-09T08:11:55.000Z","dependencies_parsed_at":"2023-07-18T12:31:38.621Z","dependency_job_id":null,"html_url":"https://github.com/katyo/literium","commit_stats":{"total_commits":342,"total_committers":1,"mean_commits":342.0,"dds":0.0,"last_synced_commit":"57d89b3822e5eace481b02ea05b2dd7d95e51dad"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/katyo%2Fliterium","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/katyo%2Fliterium/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/katyo%2Fliterium/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/katyo%2Fliterium/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/katyo","download_url":"https://codeload.github.com/katyo/literium/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247277956,"owners_count":20912635,"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-30T16:11:01.627Z","updated_at":"2025-04-05T02:25:36.088Z","avatar_url":"https://github.com/katyo.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pretty simple Web-application framework\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) [![npm version](https://badge.fury.io/js/literium.svg)](https://badge.fury.io/js/literium) [![npm downloads](https://img.shields.io/npm/dm/literium.svg)](https://www.npmjs.com/package/literium) [![Build Status](https://travis-ci.org/katyo/literium.svg?branch=master)](https://travis-ci.org/katyo/literium)\n\nCurrently this is an __experimental__ Web-framework built on top of _[snabbdom-ng](https://github.com/katyo/snabbdom/tree/nextgen)_.\n\nThe _snabbdom-ng_ is the modified _[snabbdom](https://github.com/snabbdom/snabbdom)_ __Virtual DOM__ library.\n\n## Overview\n\nLiterium is a client-side framework for modern Web-application.\nIts core principles are explicit state, controllable behavior, declarative code, effeciency, simplicity and flexibility.\n\n## Features\n\n* Browser interaction (Client-side)\n* Dynamic HTML generation (Server-side)\n* Static HTML pre-rendering\n* Preferred to live at top-level (i.e. root `\u003chtml\u003e`-node or `document.documentElement`)\n\n## Architecture\n\nThe _component_ is a part of _application_ which lives and can be used independently from it.\nSo the _application_ itself is a root _component_ which lives at top-level.\n\nThe _state_ and _event_ is a main objects which application operates with using some set of operations.\nThe _state_ object uniquely determines current state of the _component_ or _application_.\nThe _event_ objects is used to modify the state of the _component_ or _application_.\n\n## Functions\n\n### Emit\\\u003cSignal\u003e\n\nThe _emit_ function allows to send events to _component_ in order to modify its state.\n\n```typescript\nexport interface Emit\u003cSignal\u003e {\n    (signal: Signal): void;\n}\n```\n\nTo deal with sub-components you can change the type of `Signal` using `map_emit()` function, like so:\n\n```typescript\nimport { Emit } from 'literium';\n\ninterface SubSignal { }\n\ninterface Signal {\n  _: SubSignal;\n}\n\nconst emit: Emit\u003cSignal\u003e;\n\nconst sub_emit: Emit\u003cSubSignal\u003e =\n  map_emit((sub_signal: SubSignal) =\u003e ({ _: sub_signal }))\n  (emit);\n```\n\nWhen the `Keyed` container is used to wrap signals you can do it much simpler:\n\n```typescript\nimport { Keyed, Emit } from 'literium';\n\ninterface SubSignal { }\n\ntype Signal = Keyed\u003c'sub-signal', SubSignal\u003e;\n\nconst emit: Emit\u003cSignal\u003e;\n\nconst sub_emit: Emit\u003cSubSignal\u003e = Emit.wrap(emit, 'sub-signal');\n```\n\n### Done\n\nThe _done_ function allows to notify the host when some asynchronous operation is complete.\n\n```typescript\nexport interface Done {\n    (): void;\n}\n```\n\n### Fork\\\u003cSignal\u003e\n\nThe _fork_ function can be used to start some asynchronous operation which may send signals to the component.\n\n```typescript\nexport interface Fork\u003cSignal\u003e {\n    (): [Emit\u003cSignal\u003e, Done];\n}\n```\n\nYou may use it like so:\n\n```typescript\n/* start task */\nconst [emit, done] = fork();\n\n/* emit events */\nemit({ $: 'some-signal' });\n...\nemit({ $: 'other-signal' });\n\n/* end task */\ndone();\n```\n\nThis way simplifies asynchronous code handling both on client and server.\n\nTo deal with sub-components you can change the type of `Signal` using `map_fork` function, like so:\n\n```typescript\nimport { Fork } from 'literium';\n\ninterface SubSignal { }\n\ninterface Signal { _: SubSignal; }\n\nfunction wrapSubSignal(sub_signal: SubSignal): Signal {\n    return { _: sub_signal };\n}\n\nconst fork: Fork\u003cSignal\u003e;\n\nconst sub_fork: Fork\u003cSubSignal\u003e = map_fork(wrapSubSignal)(fork);\n```\n\nWhen the `Keyed` container is used to wrap events you can do it much simpler:\n\n```typescript\nimport { Keyed, Fork } from 'literium';\n\ninterface SubSignal { }\n\ntype Signal = Keyed\u003c'sub-signal', SubSignal\u003e;\n\nconst fork: Fork\u003cSignal\u003e;\n\nconst sub_fork: Fork\u003cSubSignal\u003e = wrap_fork(fork, 'sub-signal');\n```\n\n### Create\\\u003cState, Signal\u003e\n\nThe function _create_ is purposed to get initial state of the component.\n\n```typescript\nexport interface Create\u003cState, Signal\u003e {\n    (fork: Fork\u003cSignal\u003e): State;\n}\n```\n\nThe component can start asynchronous operations on initializing using _fork_.\n\n### Update\\\u003cState, Signal\u003e\n\nThe function _update_ is purposed to change current state of the component.\n\n```typescript\nexport interface Update\u003cState, Signal\u003e {\n    (state: Readonly\u003cState\u003e, signal: Signal, fork: Fork\u003cSignal\u003e): State;\n}\n```\n\nAlso the component can start asynchronous operations on updating.\n\n### Render\\\u003cState, Signal\u003e\n\nThe function _render_ is used to render the component in current state.\n\n```typescript\nexport interface Render\u003cState, Signal\u003e {\n    (state: Readonly\u003cState\u003e, emit: Emit\u003cSignal\u003e): VNode;\n}\n```\n\n## Component\\\u003cState, Signal\u003e\n\nBy default the components have a state so it must implements all three methods.\n\n```typescript\nexport interface Component\u003cState, Signal\u003e {\n    create: Create\u003cState, Signal\u003e;\n    update: Update\u003cState, Signal\u003e;\n    render: Render\u003cState, Signal\u003e;\n}\n```\n\n### Combining\n\nThe components may be combined with other components in any reasonable way.\nAlso you have full control on the state and event handling of the nested components in the parent.\nBut you must provide right event routing and state changing for the nested components to have expected behavior.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkatyo%2Fliterium","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkatyo%2Fliterium","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkatyo%2Fliterium/lists"}