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

react-localstorage-ts

Package Overview
Dependencies
Maintainers
2
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-localstorage-ts - npm Package Compare versions

Comparing version 2.0.0-beta.14 to 2.0.0-beta.15

2

package.json
{
"name": "react-localstorage-ts",
"version": "2.0.0-beta.14",
"version": "2.0.0-beta.15",
"description": "A small library to wrap browser's localstorage in a functional fashion.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -14,6 +14,9 @@ ![release](https://github.com/fido-id/react-localstorage-ts/actions/workflows/release.yml/badge.svg)

### yarn
```shell
yarn add react-localstorage-ts
```
### npm
```shell

@@ -24,2 +27,3 @@ npm install -S react-localstorage-ts

## quick start
First create the hooks to read/write the values you just defined:

@@ -30,20 +34,22 @@

import * as t from "io-ts"
import {
makeUseLocalItem,
} from "react-localstorage-ts"
import {ThemeFlavour} from "./codecs"
import { makeHooksFromStorage, createLocalStorage } from "react-localstorage-ts"
import { ThemeFlavourCodec, AuthTokenCodec } from "./codecs"
export const useThemeFlavour = makeUseLocalItem(
"theme",
ThemeFlavour,
{ defaultValue: "light" },
export const localStorage = createLocalStorage(
{
themeFlavour: ThemeFlavourCodec,
authToken: AuthTokenCodec,
},
{ defaultValues: { themeFlavour: "light" } },
)
export const useAccessToken = makeUseLocalItem("access_token", t.string)
export const hooks = makeHooksFromStorage(storage)
```
then you use them in your react components:
```tsx
// App.tsx
import * as React from "react"
import * as E from "fp-ts/Either"
import * as LV from "react-localstorage-ts/LocalValue"
import LightThemeApp from "./components/LightThemeApp"

@@ -54,11 +60,11 @@ import DarkThemeApp from "./components/DarkThemeApp"

const App: React.FC = () => {
const [theme, setTheme] = useThemeFlavour()
const [themeFlavour, setThemeFlavour] = hooks.useThemeFlavour()
return pipe(
theme,
E.fold(
LV.fold2(
() => {
console.error('wrong value stored in localStorage!')
console.error("wrong value stored in localStorage!")
},
themeFlavour => {
(themeFlavour) => {
switch (themeFlavour) {

@@ -72,4 +78,4 @@ case "light": {

}
}
)
},
),
)

@@ -80,4 +86,7 @@ }

```
## LocalValue
A new data structure is defined for items stored in localstorage, `LocalValue`. When dealing with a value stored in your localstorage there are three possibilities:
1. there is no value in your localstorage (optionality).

@@ -105,5 +114,5 @@ 2. the value is present, but it is wrong (correctness).

```
It also has instances for some of the most common type-classes
and you can use it in the same way you usually use your usual `fp-ts` abstractions:
It also has instances for some of the most common `fp-ts` type-classes, so that you can use it in the same way you usually use other `fp-ts` abstractions:
```tsx

@@ -127,3 +136,7 @@ // LoginLayout.tsx

token,
LV.fold(() => null, () => null, () => <>{ children }</>), // N.B. when you don't want to deal with the "incorrect" cases, you can use fold2 and only define two handling funcitons
LV.fold(
() => "no token in storage",
() => "malformed token in storage",
() => <>{children}</>,
), // N.B. when you want to treat the "absent" and "incorrect" case in the same way, you can use fold2 and only define two handling funcitons
)

@@ -141,3 +154,3 @@ }

React.useEffect(() => {
if (LV.isValid) {
if (LV.isValid(token)) {
goToHomePage()

@@ -149,6 +162,4 @@ }

<Form
onSubmit={
(formValues) => api
.getToken(formValues)
.then(t => setToken(t))
onSubmit={(formValues) =>
api.getToken(formValues).then((t) => setToken(t))
}

@@ -161,25 +172,49 @@ />

## defining codecs
Given that browsers only allows you to store serialized data in string format, codecs must conform to the shape `Codec<E, string, B>`, where `E` is the shape of the decoding error, `B` is the shape of the runtime error and `string` is the type resulting after encoding.
Given that browsers only allows you to store serialized data in string format, codecs must conform to the shape `Codec<E, string, B>`, where `E` is the type of the decoding error, `string` is the type of the data before decoding and `B` is the type of the runtime value.
---
> N.B. this is only useful if you use `io-ts`.
If you use `io-ts` you can simply create a layer to convert `io-ts` codecs to `Codec` compliant instances:
As this kind of string conversion is very often just a JSON stringification of your encoded value, we export a utility that conveniently transform `io-ts` codecs into valid ones by first applying your encoding and then stringifying the result:
```ts
import { fromIoTsCodec } from "react-localstorage-ts/io-ts"
import { pipe } from "fp-ts/lib/function"
import * as t from "io-ts"
import * as E from "fp-ts/Either"
import { Json, JsonFromString } from "io-ts-types"
import * as LV from "./LocalValue"
import { Codec } from "./Codec"
const WrongCodec = t.type({ s: t.string, d: DateFromISOString })
const adaptIoTsCodec = <A, B>(C: t.Type<B, A>): Codec<t.Errors, A, B> => {
return {
encode: C.encode,
decode: (u: unknown) => LV.fromEither(C.decode(u)),
}
}
const CorrectCodec = fromIoTsCodec(WrongCodec)
export const fromIoTsCodec = <A, B extends Json>(C: t.Type<A, B>) => {
const stringCodec = new t.Type<A, string>(
C.name,
C.is,
(u, c) => {
return pipe(
t.string.validate(u, c),
E.chain((jsonString) => JsonFromString.validate(jsonString, c)),
E.chain((json) => C.validate(json, c)),
)
},
(v) => {
return pipe(v, C.encode, JsonFromString.encode)
},
)
return adaptIoTsCodec(stringCodec)
}
```
## updating localstorage from outside react components
If you want to update your localstorage from outside of a react component while still having your components "react" to the change,
you can use the utilities `getLocalElement`, `setLocalElement` and `removeLocalElement`.
you can use the utilities `getLocalValue`, `setLocalElement` and `removeLocalElement`.
## contributing
to commit to this repository there are a few rules:
- your commits must follow the conventional commit standard (it should be enforced by husky `commit-msg` hook).

@@ -190,2 +225,3 @@ - your code must be formatted using prettier.

## release flow
[here](https://github.com/semantic-release/semantic-release/blob/1405b94296059c0c6878fb8b626e2c5da9317632/docs/recipes/pre-releases.md) you can find an explanation of the release flow.
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