{"id":14990201,"url":"https://github.com/stoxy-js/stoxy","last_synced_at":"2025-04-12T02:05:53.124Z","repository":{"id":52640370,"uuid":"307470863","full_name":"stoxy-js/stoxy","owner":"stoxy-js","description":"Stoxy is a state management API for all modern Web Technologies","archived":false,"fork":false,"pushed_at":"2022-05-24T17:55:50.000Z","size":4485,"stargazers_count":76,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-12T02:05:45.214Z","etag":null,"topics":["async","indexeddb","javascript","lit","preact","react","state","state-management","typescript","webcomponent"],"latest_commit_sha":null,"homepage":"","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/stoxy-js.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":"2020-10-26T18:37:16.000Z","updated_at":"2023-12-29T17:14:00.000Z","dependencies_parsed_at":"2022-09-01T03:21:18.724Z","dependency_job_id":null,"html_url":"https://github.com/stoxy-js/stoxy","commit_stats":null,"previous_names":["matsuuu/stoxy"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stoxy-js%2Fstoxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stoxy-js%2Fstoxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stoxy-js%2Fstoxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stoxy-js%2Fstoxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stoxy-js","download_url":"https://codeload.github.com/stoxy-js/stoxy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248505862,"owners_count":21115354,"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":["async","indexeddb","javascript","lit","preact","react","state","state-management","typescript","webcomponent"],"created_at":"2024-09-24T14:19:41.967Z","updated_at":"2025-04-12T02:05:53.081Z","avatar_url":"https://github.com/stoxy-js.png","language":"JavaScript","readme":"![Stoxy Logo](assets/stoxy.png)\n\n![](https://badgen.net/npm/v/@stoxy/core)\n![](https://badgen.net/bundlephobia/dependency-count/@stoxy/core)\n![](https://badgen.net/bundlephobia/minzip/@stoxy/core)\n\n# 🗂️ Stoxy\n\nStoxy is a state management API for all modern Web Technologies.\n\nStoxy allows you to easily handle, persist and update data in your DOM without the weight of a framework.\n\n# 📖 Official docs\n\nOfficial docs can be found [here](https://stoxy.dev)\n\n## Additional tooling\n\n- [Stoxy Hooks for (P)React](https://github.com/stoxy-js/hooks)\n- [Stoxy Element Mixin for Web Components](https://github.com/stoxy-js/stoxy-element-mixin)\n\n\n## ❓ How\n\nStoxy utilizes the browser's tooling with respect to your computer's memory.\n\nStoxy stores the data in a in-browser Database called [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API),\nonly keeping the latest 5 accessed objects in-memory for faster access.\n\nStoxy utilizes a promise-based use flow making it really easy to asynchronously read and write from the storage.\n\nIf your browser doesn't support IndexedDB, there's no need to worry. Stoxy recognizes these cases automatically, and\nopts out of using it and utilizes a in-memory system only.\n\n## ❓ Why\n\n\n### Motivation\n\nThe motivation behind Stoxy as to provide a simpler solution for cross-app state management.\n\nWith Stoxy you are up and running after writing just one line of code. After setting your first state object, \nyou have a functional state system ready to be used.\n\n```js copy\nimport { write } from \"@stoxy/core\";\n\nwrite(\"users\", userList);\n```\n\n### Simplicity\n\nAll of Stoxy's commands are 1-2 parameters long, and can be executed as \"one-liners\".\n\nThey are however extremely extendable due to the nature of the state management system of Stoxy. Some of the Stoxy core\nfunctions like `update` and `remove`  even take delegates or predicates as a parameter to give the developer\nmore control over their state management.\n\n### Ecosystem\n\nStoxy ships with a small set of Web Components, which are framework agnostic components ready for use in any project.\n\nThe components are built to as reactive pieces of an application, updating their contents according to state\nchange without the developer having to do any work.\n\nWhen writing websites with dynamic content, the markdown can easily become a spaghetti of plain text and\nJavascript escaped variables inside a template literal. like:\n\n```javascript\n\u003ch1\u003eHello, ${user.name}\u003c/h1\u003e\n\u003cp\u003eYour profile has accumulated ${user.viewCount} views\u003c/p\u003e\n\u003cp\u003eTop 3 visitors on your page:\u003c/p\u003e\n\u003cul\u003e\n    ${\n        user.topVisitors.map(vis =\u003e `\u003cli\u003e${vis}\u003c/li\u003e`);\n    }\n\u003c/ul\u003e\n```\n\nWith Stoxy, the same markdown could be created without being in the same context as the data with:\n\n```html\n\u003cstoxy-object key=\"user\" prefix=\"u.\"\u003e\n    \u003ch1\u003eHello, u.name\u003c/h1\u003e\n    \u003cp\u003eYour profile has accumulated u.viewCount views\u003c/p\u003e\n    \u003cp\u003eTop 3 visitors on your page:\u003c/p\u003e\n    \u003cul\u003e\n        \u003cstoxy-repeat key=\"user.topVisitors\" id=\"vis\"\u003e\n            \u003cli\u003evis\u003c/li\u003e\n        \u003c/stoxy-repeat\u003e\n    \u003c/ul\u003e\n\u003c/stoxy-object\u003e\n```\n\n⚠️ **Dynamic content inside Stoxy Elements updates when the data does. Update once, DOM updates everywhere.**\n\n\nStoxy also supports different libraries:\n\n**LitElement / Class based Components**\n\n```javascript\n\nclass MyComponent extends StoxyElement(LitElement) {\n  static stoxyProperties = {\n    key: \"example-data\",\n    state: {\n      username: \"World\",\n      clicks: 0,\n      description: \"This is a example of Stoxy Element Mixin\",\n    },\n    init: true,\n  };\n\n  static get properties() {\n    return {\n      username: { type: String },\n      clicks: { type: Number },\n      description: { type: String },\n    };\n  }\n\n  constructor() {\n    super();\n\n    this.username = \"\";\n    this.clicks = 0;\n    this.description = \"\";\n  }\n\n  render() {\n    return html`\n      \u003ch2\u003eHello, ${this.username}!\u003c/h2\u003e\n      \u003cp\u003eYou have clicked the clicker ${this.clicks} times\u003c/p\u003e\n      \u003cp\u003e${this.description}\u003c/p\u003e\n    `;\n  }\n}\n```\n\n\n**React/Preact with Hooks**\n\n```javascript\nimport { useStoxy } from \"@stoxy/hooks\";\nimport React from \"react\";\n\nexport function Clicker() {\n    // You can rename the variables returned by useStoxy while destructuring\n    const { state: counterState, update: updateConter } = useStoxy(React, {\n        key: \"demo.counter\",\n        state: 0\n    });\n\n    function inc() {\n        // No need to add the key name here\n        updateCounter(c =\u003e c += 1);\n    }\n\n    return (\n        \u003cdiv\u003e\n            \u003cp\u003ePushed {counterState} times\u003c/p\u003e\n            \u003cbutton onClick={inc} type=\"button\"\u003eClick\u003c/button\u003e\n        \u003c/div\u003e\n    );\n}\n```\n\n\n### Persistence\n\nStoxy comes shipped with persistence out of the box. There are many cases in which it is beneficial to persist the state\ndata through page reloads and navigation. Wether it be stale-while-revalidate patterns, or just static information fetched \nfrom the API.\n\nThe Persistence in Stoxy is opt-in, meaning that you control exactly what information gets persisted.\n\n\n### Use them how you want to\n\nThe whole core set of Stoxy is built from smaller modules, which can be attached at will.\n\nThis means that you can use Stoxy only for managing state, and then handle all the events through subscribers,\nor you can go all in on Stoxy and deploy a whole application built with stoxy elements using barely any Javascript\n\n\n\n## 🔔 Reactivity\n\nStoxy is a reactive state management system, meaning that when you update the data in Stoxy with the `write` command,\nall of the elements using that object will automatically update their content in the DOM.\n\nNo more need for flowing data around the whole system.\n\n```javascript\nwrite('user', newData);\n\n// Triggers update in the element below\n\n\u003cstoxy-object key=\"user\" prefix=\"u.\"\u003e\n    \u003cp\u003eHello, u.name\u003c/p\u003e\n\u003c/stoxy-object\u003e;\n```\n\nStoxy will not update any element which's data didn't change, enhancing the performance greatly.\n\n**_ Only the DOM elements which had their data changed will be updated _**\n\n## 🧰 Installation\n\nTo install the full stoxy suite, run\n\n```sh\nnpm install @stoxy/stoxy\n```\n\nYou can also install packages from the stoxy suite as standalone modules.\n\n```sh\nnpm install @stoxy/core @stoxy/string @stoxy/repeat @stoxy/form @stoxy/object\n```\n\n## Usage\n\nStoxy can be used currently in 3 ways, which interoperate between each other:\n\n1. With just the @stoxy/core and the function below\n2. With Stoxy Elements\n3. With [Stoxy Element Mixin](https://github.com/stoxy-js/stoxy-element-mixin)\n\nYou can freely mix and match these implementations too! \n\n#### Write\n\n```js\nimport { write } from '@stoxy/core';\n\nwrite(\"counter\", 0);\n\n```\n\n---\n\n```js\nimport { write } from '@stoxy/core';\n\n\nwrite(\"Shoppingcart\", [{id: 123, name: \"Free gift\"}]);\n```\n\n#### Read\n\n```js\nimport { read } from '@stoxy/core';\n\nread('shoppingcart').then(shoppingCartItems =\u003e {\n    shoppingCartItems.map(item =\u003e console.log(item));\n});\n```\n\n---\n\n```js\nimport { read } from '@stoxy/core';\n\nasync function getItems() {\n    const items = await read('shoppingcart');\n    return items;\n}\n```\n\n#### Sub\n\n```js\nimport { sub } from '@stoxy/core';\n\nsub(\"shoppingcart\", updateItemCount);\n\nfunction updateItemCount(e) {\n    write(\"itemcount\", e.data.length);\n}\n```\n\n#### Clear\n\n```js\nimport { clear } from '@stoxy/core';\n\nclear('shoppingcart');\n```\n\n#### Update\n\n```js\nimport { write, update } from '@stoxy/core';\n\nwrite(\"counter\", 0);\n\n// Update counter every second\nsetInterval(() =\u003e {\n    update(\"counter\", counter =\u003e counter += 1);\n}, 1000);\n\n```\n\n#### Remove\n\n```js\nimport { remove } from '@stoxy/core';\n\n// Removes product with the id 1\nremove(\"shoppingcart\", product =\u003e product.id === 1);\n```\n\n---\n\n```js\nimport { remove } from '@stoxy/core';\n\n// Remove all products with a price over 5\nremove(\"shoppingcart\", product =\u003e product.price \u003e 5);\n```\n\n---\n\n```js\nimport { remove } from '@stoxy/core';\n\n// Remove all meat\nremove(\"shoppingcart\", removeMeat);\n\nfunction removeMeat(product) {\n    if (product.type === \"Meat\" || product.type === \"Chicken\") {\n        return true;\n    }\n    return false;\n}\n```\n\n#### Persist key\n\n```js\nimport { persistKey } from '@stoxy/core';\n\npersistKey('shoppingcart');\n\n// with multiple keys\npersistKey('shoppingcart', 'history', 'address');\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstoxy-js%2Fstoxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstoxy-js%2Fstoxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstoxy-js%2Fstoxy/lists"}