{"id":25178015,"url":"https://github.com/mimshins/containerized-state","last_synced_at":"2025-07-03T08:33:21.973Z","repository":{"id":276380661,"uuid":"924581571","full_name":"mimshins/containerized-state","owner":"mimshins","description":"Fast and minimal state container which can be used and shared across every environment.","archived":false,"fork":false,"pushed_at":"2025-04-23T07:21:45.000Z","size":168,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-12T02:05:19.265Z","etag":null,"topics":["observer-pattern","state","state-management","typescript","vanilla-js"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/mimshins.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-30T09:28:48.000Z","updated_at":"2025-03-16T13:07:46.000Z","dependencies_parsed_at":"2025-03-16T16:15:34.629Z","dependency_job_id":null,"html_url":"https://github.com/mimshins/containerized-state","commit_stats":null,"previous_names":["mimshins/containerized-state"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/mimshins/containerized-state","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimshins%2Fcontainerized-state","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimshins%2Fcontainerized-state/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimshins%2Fcontainerized-state/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimshins%2Fcontainerized-state/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mimshins","download_url":"https://codeload.github.com/mimshins/containerized-state/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimshins%2Fcontainerized-state/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263290752,"owners_count":23443655,"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":["observer-pattern","state","state-management","typescript","vanilla-js"],"created_at":"2025-02-09T14:50:59.134Z","updated_at":"2025-07-03T08:33:21.954Z","avatar_url":"https://github.com/mimshins.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# containerized-state\n\nFast and minimal state container which can be used and shared across every environment. \n\n[![license](https://img.shields.io/github/license/mimshins/containerized-state?color=010409\u0026style=for-the-badge)](https://github.com/mimshins/containerized-state/blob/main/LICENSE)\n[![npm latest package](https://img.shields.io/npm/v/containerized-state?color=010409\u0026style=for-the-badge)](https://www.npmjs.com/package/containerized-state)\n[![npm downloads](https://img.shields.io/npm/dt/containerized-state?color=010409\u0026style=for-the-badge)](https://www.npmjs.com/package/containerized-state)\n[![bundle size](https://img.shields.io/bundlephobia/minzip/containerized-state?style=for-the-badge\u0026color=%23010409)](https://bundlephobia.com/package/containerized-state)\n\n\n## Installation\n\nTo install the package, run:\n\n```bash\nnpm install containerized-state\n# Or via any other package manager\n```\n\n## API Reference\n\nThis library exposes two APIs:\n\n### `StateContainer`:\n\nThe `StateContainer` class is a utility for centralized state management, providing mechanisms to subscribe to state changes and notify subscribers efficiently. It supports both default and computed subscriptions, ensuring that updates are only propagated when necessary. This class is ideal for applications that require reactive state handling, optimization for performance, and customizable state change notifications.\n\n```ts\nclass StateContainer\u003cT\u003e {\n  static create\u003cT\u003e(initializer: Initializer\u003cT\u003e): StateContainer\u003cT\u003e;\n  constructor(initializer: Initializer\u003cT\u003e);\n  setValue(newValue: T): void;\n  getValue(): T;\n  subscribe(\n    cb: SubscribeCallback\u003cT\u003e,\n    options?: {\n      signal?: AbortSignal;\n    },\n  ): Unsubscribe;\n  computedSubscribe\u003cP\u003e(\n    computeValue: ComputeValue\u003cT, P\u003e,\n    cb: SubscribeCallback\u003cP\u003e,\n    options?: {\n      signal?: AbortSignal;\n      isEqual?: EqualityCheckFunction\u003cP\u003e;\n    },\n  ): Unsubscribe;\n}\n```\n\n#### `setValue`\n\nUpdates the value of the state and notifies the subscribers.\n\n#### `getValue`\n\nReturns a snapshot of the state.\n\n#### `subscribe`\n\nSubscribes to the changes of the container's state value and returns the unsubscribe function.\n\n#### `computedSubscribe`\n\nSubscribes to the changes of the container's selected state values and returns the unsubscribe function.\nFor more control over emission changes, you may provide a custom equality function.\n\n### `AsyncStateContainer`:\n\nThis class is ideal for applications where state updates involve asynchronous processes, ensuring that all subscribers are notified correctly even after async changes. Additionally, it is particularly useful for handling heavy and slow calculations, allowing these operations to complete without blocking the main execution flow.\n\n```ts\nclass AsyncStateContainer\u003cT\u003e {\n  static create\u003cT\u003e(initializer: Initializer\u003cT\u003e): StateContainer\u003cT\u003e;\n  constructor(initializer: Initializer\u003cT\u003e);\n  setValue(newValue: T): Promise\u003cvoid\u003e;\n  getValue(): T;\n  subscribe(\n    cb: SubscribeCallback\u003cT\u003e,\n    options?: {\n      signal?: AbortSignal;\n    },\n  ): Unsubscribe;\n  computedSubscribe\u003cP\u003e(\n    computeValue: ComputeValue\u003cT, P\u003e,\n    cb: SubscribeCallback\u003cP\u003e,\n    options?: {\n      signal?: AbortSignal;\n      isEqual?: EqualityCheckFunction\u003cP\u003e;\n    },\n  ): Unsubscribe;\n}\n```\n\n#### `setValue`\n\nUpdates the value of the state and notifies the subscribers. This will be resolved when all the subscribers are notified.\n\n#### `getValue`\n\nReturns a snapshot of the state.\n\n#### `subscribe`\n\nSubscribes to the changes of the container's state value and returns the unsubscribe function.\n\n#### `computedSubscribe`\n\nSubscribes to the changes of the container's selected state values and returns the unsubscribe function.\nFor more control over emission changes, you may provide a custom equality function.\n\n### `subscribe` vs. `computedSubscribe`\n\nBoth the `subscribe` and `computedSubscribe` methods allow you to subscribe to changes in the container's state, but they serve different purposes and offer different levels of control.\n\n#### `subscribe`\n\nThe `subscribe` method allows you to subscribe to any changes in the container's state. This method is straightforward and notifies subscribers every time the state changes, regardless of the nature of the change.\n\n##### Parameters\n\n- `cb`: A callback function that is invoked whenever the state changes. The callback receives the new state value as its argument.\n- `options` (optional): An object containing additional options for the subscription.\n  - `signal` (optional): An `AbortSignal` reference that can be used to unsubscribe from changes. If the signal is aborted, the subscription is automatically removed.\n\n##### Returns\n\nA function that can be called to manually unsubscribe from the changes.\n\n##### Usage\n\n```ts\n// Define a state container with an initial value\nconst container = StateContainer.create(42);\n// You can also instantiate a new container using the `new` keyword. For example: `new StateContainer(42)`.\n\n// Define a callback function that will be invoked when the state changes\nconst callback: SubscribeCallback\u003cnumber\u003e = newValue =\u003e {\n  console.log(\"State changed:\", newValue);\n};\n\n// Subscribe to the state changes\nconst unsubscribe = container.subscribe(callback);\n\n// Update the state\ncontainer.setValue(24); // This will trigger the callback\n\n// Unsubscribe from the changes\nunsubscribe();\n```\n\n#### `computedSubscribe`\n\nThe `computedSubscribe` method allows you to subscribe to changes in selected state values derived from the container's state. This method is useful for scenarios where you need more granular control over state changes, such as monitoring specific computed properties rather than the entire state.\n\n##### Parameters\n\n- `computeValue`: A function that takes the current state value and returns the computed value of type `P`. This function is used to derive the value that the subscriber is interested in.\n- `cb`: A callback function that is invoked whenever the computed value changes. The callback receives the new computed value as its argument.\n- `options` (optional): An object containing additional options for the subscription.\n  - `signal` (optional): An `AbortSignal` reference that can be used to unsubscribe from changes. If the signal is aborted, the subscription is automatically removed.\n  - `isEqual` (optional): A custom equality function to control emission changes. This function takes the previous and current computed values as arguments and returns a boolean indicating whether they are equal. If they are equal, the callback is not invoked.\n\n##### Returns\n\nA function that can be called to manually unsubscribe from the changes.\n\n##### Usage\n\n```ts\ntype State = {\n  count: number;\n  name: string;\n};\n\n// Define a state container with an initial value\nconst container = StateContainer.create\u003cState\u003e({ count: 0, name: \"John\" });\n// You can also instantiate a new container using the `new` keyword. For example: `new StateContainer(42)`.\n\n// Define a compute value function that selects a specific part of the state\nconst computeValue: ComputeValue\u003cState, number\u003e = state =\u003e state.count;\n\n// Define a callback function that will be invoked when the computed value changes\nconst callback: SubscribeCallback\u003cnumber\u003e = newValue =\u003e {\n  console.log(\"Computed value changed:\", newValue);\n};\n\n// Subscribe to the computed value changes\nconst unsubscribe = container.computedSubscribe(computeValue, callback);\n\n// Update the state\ncontainer.setValue({ count: 1, name: \"John\" }); // This will not trigger the callback (`count` remains the same)\ncontainer.setValue({ count: 2, name: \"Doe\" });  // This will trigger the callback (`count` changes)\n\n// Unsubscribe from the changes\nunsubscribe();\n```\n\n## Contributing\n\nRead the [contributing guide](https://github.com/mimshins/containerized-state/blob/main/CONTRIBUTING.md) to learn about our development process, how to propose bug fixes and improvements, and how to build and test your changes.\n\nContributing to \"Containerized State\" is about more than just issues and pull requests! There are many other ways to support the project beyond contributing to the code base.\n\n## License\n\nThis project is licensed under the terms of the [MIT license](https://github.com/mimshins/containerized-state/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmimshins%2Fcontainerized-state","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmimshins%2Fcontainerized-state","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmimshins%2Fcontainerized-state/lists"}