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

use-session-storage-state

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

use-session-storage-state - npm Package Compare versions

Comparing version 18.2.0 to 19.0.0

4

index.d.ts

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

import useSessionStorageState from './src/useSessionStorageState';
import type { SessionStorageOptions, SessionStorageState } from './src/useSessionStorageState';
import useSessionStorageState from './src/useSessionStorageState.js';
import type { SessionStorageOptions, SessionStorageState } from './src/useSessionStorageState.js';
export default useSessionStorageState;
export type { SessionStorageOptions, SessionStorageState };

@@ -1,7 +0,2 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const useSessionStorageState_1 = __importDefault(require("./src/useSessionStorageState"));
exports.default = useSessionStorageState_1.default;
import useSessionStorageState from './src/useSessionStorageState.js';
export default useSessionStorageState;
{
"name": "use-session-storage-state",
"version": "18.2.0",
"version": "19.0.0",
"description": "React hook that persist data in sessionStorage",
"license": "MIT",
"repository": "astoilkov/use-session-storage-state",
"repository": {
"type": "git",
"url": "git+https://github.com/astoilkov/use-session-storage-state.git"
},
"funding": "https://github.com/sponsors/astoilkov",

@@ -25,22 +28,24 @@ "homepage": "https://github.com/astoilkov/use-session-storage-state",

],
"module": "es/index.js",
"jsnext:main": "es/index.js",
"type": "module",
"exports": {
"types": "./index.d.ts",
"default": "./index.js"
},
"sideEffects": false,
"scripts": {
"build": "tsc && tsc --project tsconfig.esm.json",
"size": "yarn run build && size-limit",
"build": "tsc",
"size": "yarn build && size-limit",
"lint": "eslint --cache --format=pretty --ext=.ts ./",
"test": "yarn run build && yarn run lint && if [[ -z $CI ]]; then jest --coverage --coverageReporters=text; else jest --coverage; fi",
"release": "yarn run build && np",
"test": "yarn build && yarn lint && vitest --run",
"release": "yarn build && np",
"prettier": "prettier --write --config .prettierrc.yaml {*.ts,*.json}"
},
"engines": {
"node": ">=12"
"node": ">=14"
},
"files": [
"index.js",
"src/*.js",
"index.d.ts",
"src/*.d.ts",
"es/**/*.js"
"src/**/*.js",
"src/**/*.d.ts"
],

@@ -52,28 +57,27 @@ "peerDependencies": {

"devDependencies": {
"@size-limit/preset-small-lib": "^7.0.8",
"@testing-library/react": "^13.3.0",
"@types/jest": "^28.1.1",
"@types/react": "^18.0.12",
"@types/react-dom": "^18.0.4",
"@typescript-eslint/eslint-plugin": "^5.27.1",
"@typescript-eslint/parser": "^5.27.1",
"@size-limit/preset-small-lib": "^11.1.1",
"@testing-library/react": "^14.0.0",
"@types/react": "^18.2.67",
"@types/react-dom": "^18.2.22",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitest/coverage-v8": "^1.4.0",
"confusing-browser-globals": "^1.0.11",
"eslint": "^8.17.0",
"eslint-config-strictest": "^0.4.0",
"eslint-formatter-pretty": "^4.0.0",
"eslint": "^8.21.0",
"eslint-config-strictest": "^0.8.1",
"eslint-formatter-pretty": "^5.0.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.5.0",
"eslint-plugin-unicorn": "^42.0.0",
"jest": "^28.1.1",
"jest-environment-jsdom": "^28.1.1",
"np": "^7.6.1",
"prettier": "^2.6.2",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"eslint-plugin-unicorn": "^43.0.2",
"jsdom": "^22.1.0",
"np": "^7.6.3",
"prettier": "^3.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-test-renderer": "^18.1.0",
"size-limit": "^7.0.8",
"superjson": "^1.9.1",
"ts-jest": "^28.0.4",
"typescript": "^4.7.3"
"size-limit": "^11.1.1",
"superjson": "^2.2.1",
"typescript": "^5.4.2",
"vitest": "^1.4.0"
},

@@ -83,9 +87,9 @@ "size-limit": [

"name": "import *",
"path": "es/index.js",
"path": "index.js",
"limit": "1.75 kB",
"gzip": false
"brotli": false
},
{
"name": "import *",
"path": "es/index.js",
"path": "index.js",
"limit": "800 B"

@@ -92,0 +96,0 @@ }

@@ -7,3 +7,2 @@ # `use-session-storage-state`

[![Gzipped Size](https://img.shields.io/bundlephobia/minzip/use-session-storage-state)](https://bundlephobia.com/result?p=use-session-storage-state)
[![Test Coverage](https://img.shields.io/codeclimate/coverage/astoilkov/use-session-storage-state)](https://codeclimate.com/github/astoilkov/use-session-storage-state/test_coverage)
[![Build Status](https://img.shields.io/github/actions/workflow/status/astoilkov/use-session-storage-state/main.yml?branch=main)](https://github.com/astoilkov/use-session-storage-state/actions/workflows/main.yml)

@@ -25,5 +24,5 @@

- Clone of [`use-local-storage-state`](https://github.com/astoilkov/use-local-storage-state) that I've been [maintaining for the past 2 years](https://github.com/astoilkov/use-local-storage-state/graphs/contributors).
- React 18 concurrent rendering support.
- Clone of [`use-local-storage-state`](https://github.com/astoilkov/use-local-storage-state) that I've been [actively maintaining for the past 4 years](https://github.com/astoilkov/use-local-storage-state/graphs/contributors).
- SSR support.
- Works with concurrent rendering and React 19.
- Handles the `Window` [`storage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event) event and updates changes across iframe's. Disable with `storageSync: false`.

@@ -30,0 +29,0 @@ - In-memory fallback when `sessionStorage` throws an error and can't store the data. Provides a `isPersistent` API to let you notify the user their data isn't currently being stored.

import type { Dispatch, SetStateAction } from 'react';
export declare const inMemoryData: Map<string, unknown>;
export declare type SessionStorageOptions<T> = {
export type SessionStorageOptions<T> = {
defaultValue?: T | (() => T);

@@ -11,3 +11,3 @@ storageSync?: boolean;

};
export declare type SessionStorageState<T> = [
export type SessionStorageState<T> = [
T,

@@ -20,4 +20,4 @@ Dispatch<SetStateAction<T>>,

];
export default function useSessionStorageState(key: string, options?: Omit<SessionStorageOptions<unknown>, 'defaultValue'>): SessionStorageState<unknown>;
export default function useSessionStorageState(key: string, options?: SessionStorageOptions<undefined>): SessionStorageState<unknown>;
export default function useSessionStorageState<T>(key: string, options?: Omit<SessionStorageOptions<T | undefined>, 'defaultValue'>): SessionStorageState<T | undefined>;
export default function useSessionStorageState<T>(key: string, options?: SessionStorageOptions<T>): SessionStorageState<T>;

@@ -1,55 +0,20 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.inMemoryData = void 0;
const react_1 = require("react");
// in memory fallback used then `sessionStorage` throws an error
exports.inMemoryData = new Map();
function useSessionStorageState(key, options) {
const [defaultValue] = (0, react_1.useState)(options === null || options === void 0 ? void 0 : options.defaultValue);
// SSR support
// - on the server, return a constant value
// - this makes the implementation simpler and smaller because the `sessionStorage` object is
// `undefined` on the server
if (typeof window === 'undefined') {
return [
defaultValue,
() => { },
{
isPersistent: true,
removeItem: () => { },
},
];
}
import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';
// in memory fallback used when `sessionStorage` throws an error
export const inMemoryData = new Map();
export default function useSessionStorageState(key, options) {
const serializer = options === null || options === void 0 ? void 0 : options.serializer;
// disabling ESLint because the above if statement can be executed only on the server. the value
// of `window` can't change between calls.
// eslint-disable-next-line react-hooks/rules-of-hooks
const [defaultValue] = useState(options === null || options === void 0 ? void 0 : options.defaultValue);
return useBrowserSessionStorageState(key, defaultValue, options === null || options === void 0 ? void 0 : options.storageSync, serializer === null || serializer === void 0 ? void 0 : serializer.parse, serializer === null || serializer === void 0 ? void 0 : serializer.stringify);
}
exports.default = useSessionStorageState;
function useBrowserSessionStorageState(key, defaultValue, storageSync = true, parse = parseJSON, stringify = JSON.stringify) {
// store default value in sessionStorage:
// - initial issue: https://github.com/astoilkov/use-local-storage-state/issues/26
// issues that were caused by incorrect initial and secondary implementations:
// - https://github.com/astoilkov/use-local-storage-state/issues/30
// - https://github.com/astoilkov/use-local-storage-state/issues/33
if (!exports.inMemoryData.has(key) &&
defaultValue !== undefined &&
goodTry(() => sessionStorage.getItem(key)) === null) {
// reasons for `sessionStorage` to throw an error:
// - maximum quota is exceeded
// - under Mobile Safari (since iOS 5) when the user enters private mode
// `sessionStorage.setItem()` will throw
// - trying to access sessionStorage object when cookies are disabled in Safari throws
// "SecurityError: The operation is insecure."
goodTry(() => sessionStorage.setItem(key, stringify(defaultValue)));
}
// we keep the `parsed` value in a ref because `useSyncExternalStore` requires a cached version
const storageValue = (0, react_1.useRef)({
item: null,
parsed: defaultValue,
const storageItem = useRef({
string: null,
parsed: undefined,
});
const value = (0, react_1.useSyncExternalStore)((0, react_1.useCallback)((onStoreChange) => {
const onChange = (localKey) => {
if (key === localKey) {
const value = useSyncExternalStore(
// useSyncExternalStore.subscribe
useCallback((onStoreChange) => {
const onChange = (sessionKey) => {
if (key === sessionKey) {
onStoreChange();

@@ -63,16 +28,13 @@ }

}, [key]),
// eslint-disable-next-line react-hooks/exhaustive-deps
// useSyncExternalStore.getSnapshot
() => {
var _a;
const item = (_a = goodTry(() => sessionStorage.getItem(key))) !== null && _a !== void 0 ? _a : null;
if (exports.inMemoryData.has(key)) {
storageValue.current = {
item,
parsed: exports.inMemoryData.get(key),
};
const string = (_a = goodTry(() => sessionStorage.getItem(key))) !== null && _a !== void 0 ? _a : null;
if (inMemoryData.has(key)) {
storageItem.current.parsed = inMemoryData.get(key);
}
else if (item !== storageValue.current.item) {
else if (string !== storageItem.current.string) {
let parsed;
try {
parsed = item === null ? defaultValue : parse(item);
parsed = string === null ? defaultValue : parse(string);
}

@@ -82,13 +44,30 @@ catch (_b) {

}
storageValue.current = {
item,
parsed,
};
storageItem.current.parsed = parsed;
}
return storageValue.current.parsed;
storageItem.current.string = string;
// store default value in sessionStorage:
// - initial issue: https://github.com/astoilkov/use-local-storage-state/issues/26
// issues that were caused by incorrect initial and secondary implementations:
// - https://github.com/astoilkov/use-local-storage-state/issues/30
// - https://github.com/astoilkov/use-local-storage-state/issues/33
if (string === null && defaultValue !== undefined) {
// reasons for `sessionStorage` to throw an error:
// - maximum quota is exceeded
// - under Mobile Safari (since iOS 5) when the user enters private mode
// `sessionStorage.setItem()` will throw
// - trying to access sessionStorage object when cookies are disabled in Safari throws
// "SecurityError: The operation is insecure."
// eslint-disable-next-line no-console
goodTry(() => {
const string = stringify(defaultValue);
sessionStorage.setItem(key, string);
storageItem.current = { string, parsed: defaultValue };
});
}
return storageItem.current.parsed;
},
// istanbul ignore next
// useSyncExternalStore.getServerSnapshot
() => defaultValue);
const setState = (0, react_1.useCallback)((newValue) => {
const value = newValue instanceof Function ? newValue(storageValue.current.parsed) : newValue;
const setState = useCallback((newValue) => {
const value = newValue instanceof Function ? newValue(storageItem.current.parsed) : newValue;
// reasons for `sessionStorage` to throw an error:

@@ -102,6 +81,6 @@ // - maximum quota is exceeded

sessionStorage.setItem(key, stringify(value));
exports.inMemoryData.delete(key);
inMemoryData.delete(key);
}
catch (_a) {
exports.inMemoryData.set(key, value);
inMemoryData.set(key, value);
}

@@ -113,3 +92,3 @@ triggerCallbacks(key);

// triggered the change
(0, react_1.useEffect)(() => {
useEffect(() => {
if (!storageSync) {

@@ -126,10 +105,10 @@ return undefined;

}, [key, storageSync]);
return (0, react_1.useMemo)(() => [
return useMemo(() => [
value,
setState,
{
isPersistent: value === defaultValue || !exports.inMemoryData.has(key),
isPersistent: value === defaultValue || !inMemoryData.has(key),
removeItem() {
goodTry(() => sessionStorage.removeItem(key));
exports.inMemoryData.delete(key);
inMemoryData.delete(key);
triggerCallbacks(key);

@@ -156,5 +135,3 @@ },

}
catch (_a) {
return undefined;
}
catch (_a) { }
}
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