Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-singleton-hook

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-singleton-hook - npm Package Compare versions

Comparing version 3.2.3 to 3.3.0

31

dist/react-singleton-hook.js

@@ -77,2 +77,5 @@ (function (global, factory) {

mountQueue.push(item);
return function () {
throw new Error('Can not unmount container! It is like a bug in react-singleton-hook library, because of unmountIfNoConsumers: true'); // mountQueue = mountQueue.filter(i => i !== item);
};
};

@@ -97,5 +100,12 @@

mountIntoContainer = function mountIntoContainer(item) {
return setHooks(function (hooks) {
setHooks(function (hooks) {
return [].concat(hooks, [item]);
});
return function () {
setHooks(function (hooks) {
return hooks.filter(function (i) {
return i !== item;
});
});
};
};

@@ -117,10 +127,18 @@

mountIntoContainer(hook);
return mountIntoContainer(hook);
};
var singletonHook = function singletonHook(initValue, useHookBody) {
var singletonHook = function singletonHook(initValue, useHookBody, options) {
if (options === void 0) {
options = {};
}
var mounted = false;
var removeHook = undefined;
var initStateCalculated = false;
var lastKnownState = undefined;
var consumers = [];
var _options = options,
_options$unmountIfNoC = _options.unmountIfNoConsumers,
unmountIfNoConsumers = _options$unmountIfNoC === void 0 ? false : _options$unmountIfNoC;

@@ -153,3 +171,3 @@ var applyStateChange = function applyStateChange(newState) {

mounted = true;
addHook({
removeHook = addHook({
initValue: initValue,

@@ -169,2 +187,7 @@ useHookBody: useHookBody,

consumers.splice(consumers.indexOf(setState), 1);
if (consumers.length === 0 && unmountIfNoConsumers) {
removeHook();
mounted = false;
}
}; // eslint-disable-next-line react-hooks/exhaustive-deps

@@ -171,0 +194,0 @@ }, []);

2

dist/react-singleton-hook.min.js

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

!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react"),require("react-dom")):"function"==typeof define&&define.amd?define(["exports","react","react-dom"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).ReactSingletonHook={},e.React,e.ReactDOM)}(this,(function(e,n,t){"use strict";function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=o(n);function u(){return(u=Object.assign||function(e){for(var n=1;arguments.length>n;n++){var t=arguments[n];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e}).apply(this,arguments)}var a=function(e){var t=e.useHookBody,o=e.applyStateChange,r=n.useRef(e.initValue);if("function"!=typeof t)throw Error("function expected as hook body parameter. got "+typeof t);var u=t();return n.useLayoutEffect((function(){r.current!==u&&(r.current=u,o(u))}),[o,u]),null},i=function(e){console&&console.warn&&console.warn(e)},f="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this,l=!1,c=!1,s=!1,d=[],p=function(e){d.push(e)},y=function(){c=!0,n.useEffect((function(){l&&i("SingletonHooksContainer is mounted second time. You should mount SingletonHooksContainer before any other component and never unmount it.Alternatively, dont use SingletonHooksContainer it at all, we will handle that for you."),l=!0}),[]);var e=n.useState([]),t=e[0],o=e[1];return n.useEffect((function(){p=function(e){return o((function(n){return[].concat(n,[e])}))},o(d)}),[]),r.default.createElement(r.default.Fragment,null,t.map((function(e,n){return r.default.createElement(a,u({},e,{key:n}))})))},m=function(e){var n;c||s||(s=!0,n=y,f.document&&f.document.createElement?t.render(r.default.createElement(n,null),f.document.createElement("div")):i("Can not mount SingletonHooksContainer on server side. Did you manage to run useEffect on server? Please mount SingletonHooksContainer into your components tree manually.")),p(e)},g=function(e,o){var r=!1,u=!1,a=void 0,i=[],f=function(e){a=e,t.unstable_batchedUpdates((function(){return i.forEach((function(n){return n(e)}))}))},l=function(){return u||(a="function"==typeof e?e():e,u=!0),a};return function(){var t=n.useState(l),u=t[0],c=t[1];return n.useEffect((function(){return r||(r=!0,m({initValue:e,useHookBody:o,applyStateChange:f})),i.push(c),a!==u&&c(a),function(){i.splice(i.indexOf(c),1)}}),[]),u}},h={singletonHook:g,SingletonHooksContainer:y};e.SingletonHooksContainer=y,e.default=h,e.singletonHook=g,Object.defineProperty(e,"__esModule",{value:!0})}));
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react"),require("react-dom")):"function"==typeof define&&define.amd?define(["exports","react","react-dom"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).ReactSingletonHook={},e.React,e.ReactDOM)}(this,(function(e,n,t){"use strict";function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=o(n);function u(){return(u=Object.assign||function(e){for(var n=1;arguments.length>n;n++){var t=arguments[n];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e}).apply(this,arguments)}var i=function(e){var t=e.useHookBody,o=e.applyStateChange,r=n.useRef(e.initValue);if("function"!=typeof t)throw Error("function expected as hook body parameter. got "+typeof t);var u=t();return n.useLayoutEffect((function(){r.current!==u&&(r.current=u,o(u))}),[o,u]),null},a=function(e){console&&console.warn&&console.warn(e)},f="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this,l=!1,c=!1,s=!1,d=[],p=function(e){return d.push(e),function(){throw Error("Can not unmount container! It is like a bug in react-singleton-hook library, because of unmountIfNoConsumers: true")}},m=function(){c=!0,n.useEffect((function(){l&&a("SingletonHooksContainer is mounted second time. You should mount SingletonHooksContainer before any other component and never unmount it.Alternatively, dont use SingletonHooksContainer it at all, we will handle that for you."),l=!0}),[]);var e=n.useState([]),t=e[0],o=e[1];return n.useEffect((function(){p=function(e){return o((function(n){return[].concat(n,[e])})),function(){o((function(n){return n.filter((function(n){return n!==e}))}))}},o(d)}),[]),r.default.createElement(r.default.Fragment,null,t.map((function(e,n){return r.default.createElement(i,u({},e,{key:n}))})))},y=function(e){var n;return c||s||(s=!0,n=m,f.document&&f.document.createElement?t.render(r.default.createElement(n,null),f.document.createElement("div")):a("Can not mount SingletonHooksContainer on server side. Did you manage to run useEffect on server? Please mount SingletonHooksContainer into your components tree manually.")),p(e)},g=function(e,o,r){void 0===r&&(r={});var u=!1,i=void 0,a=!1,f=void 0,l=[],c=r.unmountIfNoConsumers,s=void 0!==c&&c,d=function(e){f=e,t.unstable_batchedUpdates((function(){return l.forEach((function(n){return n(e)}))}))},p=function(){return a||(f="function"==typeof e?e():e,a=!0),f};return function(){var t=n.useState(p),r=t[0],a=t[1];return n.useEffect((function(){return u||(u=!0,i=y({initValue:e,useHookBody:o,applyStateChange:d})),l.push(a),f!==r&&a(f),function(){l.splice(l.indexOf(a),1),0===l.length&&s&&(i(),u=!1)}}),[]),r}},h={singletonHook:g,SingletonHooksContainer:m};e.SingletonHooksContainer=m,e.default=h,e.singletonHook=g,Object.defineProperty(e,"__esModule",{value:!0})}));

@@ -14,2 +14,5 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

mountQueue.push(item);
return function () {
throw new Error('Can not unmount container! It is like a bug in react-singleton-hook library, because of unmountIfNoConsumers: true'); // mountQueue = mountQueue.filter(i => i !== item);
};
};

@@ -34,5 +37,12 @@

mountIntoContainer = function mountIntoContainer(item) {
return setHooks(function (hooks) {
setHooks(function (hooks) {
return [].concat(hooks, [item]);
});
return function () {
setHooks(function (hooks) {
return hooks.filter(function (i) {
return i !== item;
});
});
};
};

@@ -54,3 +64,3 @@

mountIntoContainer(hook);
return mountIntoContainer(hook);
};

@@ -57,0 +67,0 @@ export var resetLocalStateForTests = function resetLocalStateForTests() {

import { useEffect, useState } from 'react';
import { addHook } from './components/SingletonHooksContainer';
import { batch } from './utils/env';
export var singletonHook = function singletonHook(initValue, useHookBody) {
export var singletonHook = function singletonHook(initValue, useHookBody, options) {
if (options === void 0) {
options = {};
}
var mounted = false;
var removeHook = undefined;
var initStateCalculated = false;
var lastKnownState = undefined;
var consumers = [];
var _options = options,
_options$unmountIfNoC = _options.unmountIfNoConsumers,
unmountIfNoConsumers = _options$unmountIfNoC === void 0 ? false : _options$unmountIfNoC;

@@ -36,3 +44,3 @@ var applyStateChange = function applyStateChange(newState) {

mounted = true;
addHook({
removeHook = addHook({
initValue: initValue,

@@ -52,2 +60,7 @@ useHookBody: useHookBody,

consumers.splice(consumers.indexOf(setState), 1);
if (consumers.length === 0 && unmountIfNoConsumers) {
removeHook();
mounted = false;
}
}; // eslint-disable-next-line react-hooks/exhaustive-deps

@@ -54,0 +67,0 @@ }, []);

@@ -6,4 +6,11 @@

declare namespace ReactSingletonHook {
function singletonHook<ValueType>(initialState: ValueType | (() => ValueType), useHook: () => ValueType): () => ValueType;
function singletonHook<ValueType>(
initialState: ValueType | (() => ValueType),
useHook: () => ValueType,
options?: {
unmountIfNoConsumers?: boolean
}
): () => ValueType;
function SingletonHooksContainer(): any;
}

@@ -27,2 +27,5 @@ "use strict";

mountQueue.push(item);
return function () {
throw new Error('Can not unmount container! It is like a bug in react-singleton-hook library, because of unmountIfNoConsumers: true'); // mountQueue = mountQueue.filter(i => i !== item);
};
};

@@ -48,5 +51,12 @@

mountIntoContainer = function mountIntoContainer(item) {
return setHooks(function (hooks) {
setHooks(function (hooks) {
return [].concat(hooks, [item]);
});
return function () {
setHooks(function (hooks) {
return hooks.filter(function (i) {
return i !== item;
});
});
};
};

@@ -71,3 +81,3 @@

mountIntoContainer(hook);
return mountIntoContainer(hook);
};

@@ -74,0 +84,0 @@

@@ -12,7 +12,15 @@ "use strict";

var singletonHook = function singletonHook(initValue, useHookBody) {
var singletonHook = function singletonHook(initValue, useHookBody, options) {
if (options === void 0) {
options = {};
}
var mounted = false;
var removeHook = undefined;
var initStateCalculated = false;
var lastKnownState = undefined;
var consumers = [];
var _options = options,
_options$unmountIfNoC = _options.unmountIfNoConsumers,
unmountIfNoConsumers = _options$unmountIfNoC === void 0 ? false : _options$unmountIfNoC;

@@ -45,3 +53,3 @@ var applyStateChange = function applyStateChange(newState) {

mounted = true;
(0, _SingletonHooksContainer.addHook)({
removeHook = (0, _SingletonHooksContainer.addHook)({
initValue: initValue,

@@ -61,2 +69,7 @@ useHookBody: useHookBody,

consumers.splice(consumers.indexOf(setState), 1);
if (consumers.length === 0 && unmountIfNoConsumers) {
removeHook();
mounted = false;
}
}; // eslint-disable-next-line react-hooks/exhaustive-deps

@@ -63,0 +76,0 @@ }, []);

{
"name": "react-singleton-hook",
"version": "3.2.3",
"version": "3.3.0",
"description": "Share custom hook state across all components",

@@ -39,3 +39,3 @@ "keywords": [

"peerDependencies": {
"react": "15 - 17"
"react": "15 - 18"
},

@@ -52,33 +52,36 @@ "peerDependenciesMeta": {

"devDependencies": {
"@babel/cli": "^7.16.0",
"@babel/core": "^7.16.5",
"@babel/eslint-parser": "^7.16.5",
"@babel/plugin-proposal-object-rest-spread": "^7.16.5",
"@babel/plugin-transform-react-display-name": "^7.16.5",
"@babel/plugin-transform-react-jsx": "^7.16.5",
"@babel/preset-env": "^7.16.5",
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-node-resolve": "^13.1.1",
"@rollup/plugin-replace": "^3.0.0",
"@testing-library/jest-dom": "^5.16.1",
"@babel/cli": "^7.17.6",
"@babel/core": "^7.17.9",
"@babel/eslint-parser": "^7.17.0",
"@babel/plugin-proposal-object-rest-spread": "^7.17.3",
"@babel/plugin-transform-object-assign": "^7.16.7",
"@babel/plugin-transform-react-display-name": "^7.16.7",
"@babel/plugin-transform-react-jsx": "^7.17.3",
"@babel/preset-env": "^7.16.11",
"@rollup/plugin-commonjs": "^21.0.3",
"@rollup/plugin-node-resolve": "^13.2.0",
"@rollup/plugin-replace": "^4.0.0",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/jest-native": "^4.0.4",
"@testing-library/react": "^12.1.2",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/react-native": "^9.0.0",
"babel-jest": "^27.4.5",
"@testing-library/react": "^13.0.1",
"@testing-library/react-hooks": "^8.0.0",
"@testing-library/react-native": "^9.1.0",
"babel-jest": "^27.5.1",
"cross-env": "^7.0.3",
"es3ify": "^0.2.2",
"eslint": "^8.4.1",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"glob": "^7.2.0",
"jest": "^27.4.5",
"npm-check-updates": "^12.0.3",
"react": "^16.8.6",
"react-dom": "^17.0.2",
"react-native": "^0.66.4",
"react-test-renderer": "^17.0.2",
"eslint": "^8.13.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
"glob": "^8.0.1",
"jest": "^27.5.1",
"metro-babel-register": "^0.70.1",
"metro-react-native-babel-preset": "^0.70.1",
"npm-check-updates": "^12.5.9",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-native": "^0.68.0",
"react-test-renderer": "^18.0.0",
"rimraf": "^3.0.2",
"rollup": "^2.61.1",
"rollup": "^2.70.1",
"rollup-plugin-babel": "^4.4.0",

@@ -85,0 +88,0 @@ "rollup-plugin-terser": "^7.0.2"

@@ -300,2 +300,15 @@ React Singleton Hook

### Unmounting hooks when there are no consumers
You can pass the last optional parameter `options` to the `singletonHook` to
configure if the hook should be unmounted when no one consumes it:
```js
const useHook = singletonHook(
initVal,
() => { /*hook body*/ },
{ unmountIfNoConsumers: true }
);
```
## React Native

@@ -302,0 +315,0 @@ To use this library with react-native you always have to mount `SingletonHooksContainer` manually.

@@ -11,3 +11,9 @@ import React, { useState, useEffect } from 'react';

let mountQueue = [];
const mountIntoContainerDefault = (item) => { mountQueue.push(item); };
const mountIntoContainerDefault = (item) => {
mountQueue.push(item);
return () => {
throw new Error('Can not unmount container! It is like a bug in react-singleton-hook library, because of unmountIfNoConsumers: true');
// mountQueue = mountQueue.filter(i => i !== item);
};
};
let mountIntoContainer = mountIntoContainerDefault;

@@ -29,3 +35,8 @@

useEffect(() => {
mountIntoContainer = item => setHooks(hooks => [...hooks, item]);
mountIntoContainer = item => {
setHooks(hooks => [...hooks, item]);
return () => {
setHooks(hooks => hooks.filter(i => i !== item));
};
};
setHooks(mountQueue);

@@ -43,3 +54,3 @@ }, []);

}
mountIntoContainer(hook);
return mountIntoContainer(hook);
};

@@ -46,0 +57,0 @@

@@ -5,7 +5,11 @@ import { useEffect, useState } from 'react';

export const singletonHook = (initValue, useHookBody) => {
export const singletonHook = (initValue, useHookBody, options = {}) => {
let mounted = false;
let removeHook = undefined;
let initStateCalculated = false;
let lastKnownState = undefined;
let consumers = [];
let {
unmountIfNoConsumers = false
} = options;

@@ -31,3 +35,3 @@ const applyStateChange = (newState) => {

mounted = true;
addHook({ initValue, useHookBody, applyStateChange });
removeHook = addHook({ initValue, useHookBody, applyStateChange });
}

@@ -39,3 +43,9 @@

}
return () => { consumers.splice(consumers.indexOf(setState), 1); };
return () => {
consumers.splice(consumers.indexOf(setState), 1);
if (consumers.length === 0 && unmountIfNoConsumers) {
removeHook();
mounted = false;
}
};

@@ -42,0 +52,0 @@ // eslint-disable-next-line react-hooks/exhaustive-deps

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