New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-containerized-state

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-containerized-state - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

dist/esm/use-sync-external-store.d.ts

30

dist/Container.d.ts
import * as React from "react";
import type { ContainerInitializer, SubscribeCallback, Unsubscribe } from "./types";
import type { ContainerInitializer, EqualityCheckFunction, SubscribeCallback, Unsubscribe, ValueSelector } from "./types";
declare class Container<T> {

@@ -8,6 +8,18 @@ private _value;

/**
* Subscribes to the container changes and returns the unsubscribe function.
* Subscribes to the changes of the container's state value
* and returns the unsubscribe function.
*/
subscribe(subscribeCallback: SubscribeCallback<T>): Unsubscribe;
/**
* Subscribes to the changes of the container's selected state values
* and returns the unsubscribe function.
*
* For more control over emission changes, you may provide a custom equality function.
*/
selectedSubscribe<P>(selector: ValueSelector<T, P>, subscribeCallback: SubscribeCallback<P>,
/**
* A custom equality function to control emission changes.
*/
isEqual?: EqualityCheckFunction<P>): Unsubscribe;
/**
* Gets the value of the state.

@@ -26,6 +38,18 @@ *

*
* This is a reactive function and will be updated on state change.
* This is a reactive function and updates on state value change.
*/
useValue(): T;
/**
* A React hook to read the values of the selected states.
*
* This is a reactive function and updates on selected state values change.
*
* For more control over re-rendering, you may provide a custom equality function.
*/
useValueSelector<P>(selector: ValueSelector<T, P>,
/**
* A custom equality function to control re-rendering.
*/
isEqual?: EqualityCheckFunction<P>): P;
/**
* A React hook to update the value of the state and notify the subscribers.

@@ -32,0 +56,0 @@ */

2

dist/Container.js

@@ -1,1 +0,1 @@

"use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,u){void 0===u&&(u=r);var i=Object.getOwnPropertyDescriptor(t,r);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,u,i)}:function(e,t,r,u){void 0===u&&(u=r),e[u]=t[r]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&__createBinding(t,e,r);return __setModuleDefault(t,e),t},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});var React=__importStar(require("react")),use_lazy_initialized_value_1=__importDefault(require("./use-lazy-initialized-value")),use_sync_external_store_1=__importDefault(require("./use-sync-external.store")),Container=function(){function e(e){Object.defineProperty(this,"_value",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_subscribers",{enumerable:!0,configurable:!0,writable:!0,value:void 0});var t="function"==typeof e?e():e;this._value=t,this._subscribers=new Set}return Object.defineProperty(e.prototype,"subscribe",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=this;this._subscribers.add(e);return function(){t._subscribers.delete(e)}}}),Object.defineProperty(e.prototype,"getValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._value}}),Object.defineProperty(e.prototype,"updateValue",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._value=e,this._subscribers.forEach((function(t){return t(e)}))}}),Object.defineProperty(e.prototype,"useValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this,t=(0,use_lazy_initialized_value_1.default)((function(){return e.subscribe.bind(e)})),r=(0,use_lazy_initialized_value_1.default)((function(){return e.getValue.bind(e)})),u=r;return(0,use_sync_external_store_1.default)(t,r,u)}}),Object.defineProperty(e.prototype,"useUpdateValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this;return React.useCallback((function(t){var r="function"==typeof t?t(e._value):t;e.updateValue(r)}),[])}}),e}();exports.default=Container;
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var u=Object.getOwnPropertyDescriptor(t,r);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,u)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&__createBinding(t,e,r);return __setModuleDefault(t,e),t},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});var React=__importStar(require("react")),use_lazy_initialized_value_1=__importDefault(require("./use-lazy-initialized-value")),use_sync_external_store_1=require("./use-sync-external-store"),Container=function(){function e(e){Object.defineProperty(this,"_value",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_subscribers",{enumerable:!0,configurable:!0,writable:!0,value:void 0});var t="function"==typeof e?e():e;this._value=t,this._subscribers=new Set}return Object.defineProperty(e.prototype,"subscribe",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=this;this._subscribers.add(e);return function(){t._subscribers.delete(e)}}}),Object.defineProperty(e.prototype,"selectedSubscribe",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t,r){var i=this,u={type:"SELECTED_SUBSCRIBE_ENTRY",selector:e,subscribeCallback:t,isEqual:r};this._subscribers.add(u);return function(){i._subscribers.delete(u)}}}),Object.defineProperty(e.prototype,"getValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._value}}),Object.defineProperty(e.prototype,"updateValue",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var t=this._value;this._value=e,this._subscribers.forEach((function(r){var i;if("type"in r){if("SELECTED_SUBSCRIBE_ENTRY"!==r.type)return;var u=r.selector,n=r.subscribeCallback,a=r.isEqual,l=u(e),o=u(t);if(!!(null!==(i=null==a?void 0:a(o,l))&&void 0!==i?i:Object.is(l,o)))return;n(l)}else{if(Object.is(t,e))return;r(e)}}))}}),Object.defineProperty(e.prototype,"useValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this,t=(0,use_lazy_initialized_value_1.default)((function(){return e.subscribe.bind(e)})),r=(0,use_lazy_initialized_value_1.default)((function(){return e.getValue.bind(e)})),i=r;return(0,use_sync_external_store_1.useSyncExternalStore)(t,r,i)}}),Object.defineProperty(e.prototype,"useValueSelector",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){var r=this,i=(0,use_lazy_initialized_value_1.default)((function(){return r.subscribe.bind(r)})),u=(0,use_lazy_initialized_value_1.default)((function(){return r.getValue.bind(r)})),n=u;return(0,use_sync_external_store_1.useSyncExternalStoreWithSelector)(i,u,n,e,t)}}),Object.defineProperty(e.prototype,"useUpdateValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this;return React.useCallback((function(t){var r="function"==typeof t?t(e._value):t;e.updateValue(r)}),[])}}),e}();exports.default=Container;
import * as React from "react";
import type { ContainerInitializer, SubscribeCallback, Unsubscribe } from "./types";
import type { ContainerInitializer, EqualityCheckFunction, SubscribeCallback, Unsubscribe, ValueSelector } from "./types";
declare class Container<T> {

@@ -8,6 +8,18 @@ private _value;

/**
* Subscribes to the container changes and returns the unsubscribe function.
* Subscribes to the changes of the container's state value
* and returns the unsubscribe function.
*/
subscribe(subscribeCallback: SubscribeCallback<T>): Unsubscribe;
/**
* Subscribes to the changes of the container's selected state values
* and returns the unsubscribe function.
*
* For more control over emission changes, you may provide a custom equality function.
*/
selectedSubscribe<P>(selector: ValueSelector<T, P>, subscribeCallback: SubscribeCallback<P>,
/**
* A custom equality function to control emission changes.
*/
isEqual?: EqualityCheckFunction<P>): Unsubscribe;
/**
* Gets the value of the state.

@@ -26,6 +38,18 @@ *

*
* This is a reactive function and will be updated on state change.
* This is a reactive function and updates on state value change.
*/
useValue(): T;
/**
* A React hook to read the values of the selected states.
*
* This is a reactive function and updates on selected state values change.
*
* For more control over re-rendering, you may provide a custom equality function.
*/
useValueSelector<P>(selector: ValueSelector<T, P>,
/**
* A custom equality function to control re-rendering.
*/
isEqual?: EqualityCheckFunction<P>): P;
/**
* A React hook to update the value of the state and notify the subscribers.

@@ -32,0 +56,0 @@ */

@@ -1,1 +0,1 @@

import*as e from"react";import r from"./use-lazy-initialized-value";import t from"./use-sync-external.store";var u=function(){function u(e){Object.defineProperty(this,"_value",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_subscribers",{enumerable:!0,configurable:!0,writable:!0,value:void 0});var r="function"==typeof e?e():e;this._value=r,this._subscribers=new Set}return Object.defineProperty(u.prototype,"subscribe",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var r=this;this._subscribers.add(e);return function(){r._subscribers.delete(e)}}}),Object.defineProperty(u.prototype,"getValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._value}}),Object.defineProperty(u.prototype,"updateValue",{enumerable:!1,configurable:!0,writable:!0,value:function(e){this._value=e,this._subscribers.forEach((function(r){return r(e)}))}}),Object.defineProperty(u.prototype,"useValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this,u=r((function(){return e.subscribe.bind(e)})),i=r((function(){return e.getValue.bind(e)}));return t(u,i,i)}}),Object.defineProperty(u.prototype,"useUpdateValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){var r=this;return e.useCallback((function(e){var t="function"==typeof e?e(r._value):e;r.updateValue(t)}),[])}}),u}();export default u;
import*as e from"react";import r from"./use-lazy-initialized-value";import{useSyncExternalStore as t,useSyncExternalStoreWithSelector as u}from"./use-sync-external-store";var i=function(){function i(e){Object.defineProperty(this,"_value",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_subscribers",{enumerable:!0,configurable:!0,writable:!0,value:void 0});var r="function"==typeof e?e():e;this._value=r,this._subscribers=new Set}return Object.defineProperty(i.prototype,"subscribe",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var r=this;this._subscribers.add(e);return function(){r._subscribers.delete(e)}}}),Object.defineProperty(i.prototype,"selectedSubscribe",{enumerable:!1,configurable:!0,writable:!0,value:function(e,r,t){var u=this,i={type:"SELECTED_SUBSCRIBE_ENTRY",selector:e,subscribeCallback:r,isEqual:t};this._subscribers.add(i);return function(){u._subscribers.delete(i)}}}),Object.defineProperty(i.prototype,"getValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){return this._value}}),Object.defineProperty(i.prototype,"updateValue",{enumerable:!1,configurable:!0,writable:!0,value:function(e){var r=this._value;this._value=e,this._subscribers.forEach((function(t){var u;if("type"in t){if("SELECTED_SUBSCRIBE_ENTRY"!==t.type)return;var i=t.selector,n=t.subscribeCallback,a=t.isEqual,l=i(e),b=i(r);if(!!(null!==(u=null==a?void 0:a(b,l))&&void 0!==u?u:Object.is(l,b)))return;n(l)}else{if(Object.is(r,e))return;t(e)}}))}}),Object.defineProperty(i.prototype,"useValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this,u=r((function(){return e.subscribe.bind(e)})),i=r((function(){return e.getValue.bind(e)}));return t(u,i,i)}}),Object.defineProperty(i.prototype,"useValueSelector",{enumerable:!1,configurable:!0,writable:!0,value:function(e,t){var i=this,n=r((function(){return i.subscribe.bind(i)})),a=r((function(){return i.getValue.bind(i)}));return u(n,a,a,e,t)}}),Object.defineProperty(i.prototype,"useUpdateValue",{enumerable:!1,configurable:!0,writable:!0,value:function(){var r=this;return e.useCallback((function(e){var t="function"==typeof e?e(r._value):e;r.updateValue(t)}),[])}}),i}();export default i;
export { default as createStateContainer } from "./create-state-container";
export type { ContainerInitializer, EqualityCheckFunction, SubscribeCallback, Unsubscribe, ValueSelector, } from "./types";
export type CallableFunction<TArgs extends any[] = [], TReturn = void> = (...args: TArgs) => TReturn;
export type SubscribeCallback<T> = (value: T) => void;
export type Unsubscribe = () => void;
export type ValueSelector<T, P> = (value: T) => P;
export type EqualityCheckFunction<P> = (a: P, b: P) => boolean;
export type SelectedSubscribeEntry<T, P> = {
type: "SELECTED_SUBSCRIBE_ENTRY";
subscribeCallback: SubscribeCallback<P>;
selector: ValueSelector<T, P>;
isEqual?: EqualityCheckFunction<P>;
};
export type ContainerInitializer<T> = T | CallableFunction<[], T>;
export { default as createStateContainer } from "./create-state-container";
export type { ContainerInitializer, EqualityCheckFunction, SubscribeCallback, Unsubscribe, ValueSelector, } from "./types";
export type CallableFunction<TArgs extends any[] = [], TReturn = void> = (...args: TArgs) => TReturn;
export type SubscribeCallback<T> = (value: T) => void;
export type Unsubscribe = () => void;
export type ValueSelector<T, P> = (value: T) => P;
export type EqualityCheckFunction<P> = (a: P, b: P) => boolean;
export type SelectedSubscribeEntry<T, P> = {
type: "SELECTED_SUBSCRIBE_ENTRY";
subscribeCallback: SubscribeCallback<P>;
selector: ValueSelector<T, P>;
isEqual?: EqualityCheckFunction<P>;
};
export type ContainerInitializer<T> = T | CallableFunction<[], T>;
{
"name": "react-containerized-state",
"version": "1.0.0",
"version": "1.1.0",
"description": "Fast and minimal state container which can be used and shared across React or non-React components.",

@@ -43,2 +43,5 @@ "main": "./dist/index.js",

},
"dependencies": {
"use-sync-external-store": "^1.2.2"
},
"devDependencies": {

@@ -49,2 +52,3 @@ "@types/node": "^20.12.12",

"@types/semver": "^7.5.8",
"@types/use-sync-external-store": "^0.0.6",
"@typescript-eslint/eslint-plugin": "^7.9.0",

@@ -51,0 +55,0 @@ "@typescript-eslint/parser": "^7.9.0",

@@ -17,3 +17,3 @@ # react-containerized-state

## Usage
## Basic usage

@@ -86,2 +86,107 @@ Consider the following example:

## Usage with selectors
There may be situations where you have to store a complex state in your container (**It is recommended to have different small containers instead of several large ones**). In these cases, you may not want to subscribe to all the fields of the complex state. Instead you want to subscribe to different parts in different components or modules.
Consider the following example:
```tsx
import { createStateContainer } from "react-containerized-state";
// You can move this container to a separate module and share it across your app
const complexState = createStateContainer({ a: 1, b: "2" });
const Controls = () => {
const updateState = complexState.useUpdateValue();
return (
<div>
<button
onClick={() => {
updateState(s => ({
...s,
a: s.a + 1,
}));
}}
>
Update State.A
</button>
<button
onClick={() => {
updateState(s => ({
...s,
b: String(Number(s.b) + 1),
}));
}}
>
Update State.B
</button>
</div>
);
};
const DisplayA = () => {
const a = complexState.useValueSelector(value => value.a);
return <div>State.A: {a}</div>;
};
const DisplayB = () => {
const b = complexState.useValueSelector(value => value.b);
return <div>State.B: {b}</div>;
};
const Container = () => {
return (
<div>
<h2>Container</h2>
<Controls />
<DisplayA />
<DisplayB />
</div>
);
};
const Page = () => {
return (
<main>
<Container />
</main>
);
};
export default Page;
```
In this example, when the user clicks on the buttons of the `Controls` component, the state changes and each component that is subscribed to a part of the container's state via `useValueSelector` hook will be notified and re-rendered as a result. In other words, `DisplayA` component re-renders only when `value.a` changes (same thing for the `DisplayB` component and the value of `value.b` state.).
You can pass in any selector you want. Think of selectors as a state transformer where you can transform a complex state into another simpler shape.
For example:
```tsx
const { a, b } = complexState.useValueSelector(value => ({ a: value.a, b: value.b}));
const valueOfB = complexState.useValueSelector(value => value.b);
```
Cool, huh?
So, what about using the complex state in a non-React environment?
You can opt-in `selectedSubscribe` instead of `subscribe`.
For example:
```ts
// Logs the new value of `value.a` on selected state changes
complexState.selectedSubscribe(value => value.a, console.log);
```
## More control of re-rendering and emission changes?
For more control over re-rendering (in React environment) and emission changes (in non-React environment) try to pass in `isEqual` parameter to the `useValueSelector` and `selectedSubscribe` (check the API section for more information).
> By default, we are using `Object.is` as equality check function.
## API

@@ -94,6 +199,21 @@

/**
* Subscribes to the container changes and returns the unsubscribe function.
* Subscribes to the changes of the container's state value
* and returns the unsubscribe function.
*/
subscribe(subscribeCallback: (value: T) => void): () => void;
/**
* Subscribes to the changes of the container's selected state values
* and returns the unsubscribe function.
*
* For more control over emission changes, you may provide a custom equality function.
*/
selectedSubscribe<P>(
selector: (value: T) => P,
subscribeCallback: (value: P) => void,
/**
* A custom equality function to control emission changes.
*/
isEqual?: (a: P, b: P) => boolean,
): () => void;
/**
* Gets the value of the state.

@@ -112,6 +232,20 @@ *

*
* This is a reactive function and will be updated on state change.
* This is a reactive function and updates on state value change.
*/
useValue(): T;
/**
* A React hook to read the values of the selected states.
*
* This is a reactive function and updates on selected state values change.
*
* For more control over re-rendering, you may provide a custom equality function.
*/
useValueSelector(
selector: (value: T) => P,
/**
* A custom equality function to control re-rendering.
*/
isEqual?: (a: P, b: P) => boolean,
): P;
/**
* A React hook to update the value of the state and notify the subscribers.

@@ -118,0 +252,0 @@ */

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc