Skip to content

Commit

Permalink
Add CustomEvent polyfill (#78)
Browse files Browse the repository at this point in the history
* Change how localstorage events are created

* Add CustomEvent polyfill

* Use class again

* Update node version

* 2.4.2

* Update node versions
  • Loading branch information
jharrilim authored Jul 25, 2021
1 parent 7933169 commit df04273
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:

strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
node-version: [12.x, 14.x, 16.x]

steps:
- uses: actions/checkout@v1
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/npmpublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
node-version: 14
- run: npm ci
- run: npm test

Expand All @@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
node-version: 14
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish
Expand All @@ -39,7 +39,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
node-version: 14
registry-url: https://npm.pkg.github.com/
- run: npm ci
- run: npm publish
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rehooks/local-storage",
"version": "2.4.1",
"version": "2.4.2",
"description": "React hook for local-storage",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useLocalStorage } from './use-localstorage';

export { writeStorage, deleteFromStorage } from './local-storage-events';
export { writeStorage, deleteFromStorage, LocalStorageChanged } from './local-storage-events';

export { useLocalStorage };

Expand Down
43 changes: 33 additions & 10 deletions src/local-storage-events.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
import { storage } from './storage'
interface KVP<K, V> {
key: K,
value: V
import { storage } from './storage';

/**
* CustomEvent polyfill derived from: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
*/
(() => {
if (typeof global.window === 'undefined') {
global.window = {} as unknown as Window & typeof globalThis;
}

if (typeof global.window.CustomEvent === 'function') {
return;
}

function CustomEvent<T>(
typeArg: string,
params: CustomEventInit<T> = { bubbles: false, cancelable: false }
): CustomEvent<T> {
const evt = document.createEvent('CustomEvent');
evt.initCustomEvent(typeArg, params?.bubbles ?? false, params?.cancelable ?? false, params?.detail);
return evt;
}

window.CustomEvent = CustomEvent as unknown as typeof window.CustomEvent;
})();

export interface LocalStorageEventPayload<TValue> {
key: string;
value: TValue;
}


Expand All @@ -10,14 +35,12 @@ interface KVP<K, V> {
* have the ability of updating the LocalStorage from outside of the component,
* but still update the component without prop drilling or creating a dependency
* on a large library such as Redux.
*
* @class LocalStorageChanged
* @extends {CustomEvent<KVP<string, string>>}
*/
export class LocalStorageChanged<TValue> extends CustomEvent<KVP<string, TValue>> {

export class LocalStorageChanged<TValue> extends CustomEvent<LocalStorageEventPayload<TValue>> {
static eventName = 'onLocalStorageChange';

constructor(payload: KVP<string, TValue>) {
constructor(payload: LocalStorageEventPayload<TValue>) {
super(LocalStorageChanged.eventName, { detail: payload });
}
}
Expand All @@ -31,7 +54,7 @@ export class LocalStorageChanged<TValue> extends CustomEvent<KVP<string, TValue>
* @returns {evt is LocalStorageChanged<TValue>} if true, evt is asserted to be LocalStorageChanged.
*/
export function isTypeOfLocalStorageChanged<TValue>(evt: any): evt is LocalStorageChanged<TValue> {
return (!!evt) && (evt instanceof LocalStorageChanged || (evt.detail && evt.type === LocalStorageChanged.eventName));
return !!evt && evt.type === LocalStorageChanged.eventName;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/use-localstorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function useLocalStorage<TValue = string>(
const onLocalStorageChange = (event: LocalStorageChanged<TValue> | StorageEvent) => {
// An event value can be of TValue when `localStorage.setItem` is called, or null when
// `localStorage.removeItem` is called.
if (isTypeOfLocalStorageChanged(event)) {
if (isTypeOfLocalStorageChanged<TValue>(event)) {
if (event.detail.key === key) {
updateLocalState(event.detail.value);
}
Expand Down
17 changes: 8 additions & 9 deletions test/local-storage-events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ describe('Module: local-storage-events', () => {
it('is constructable with an object containing key and value', () => {
const key = 'foo';
const value = 'bar';

const localStorageChanged = new LocalStorageChanged({ key, value });

expect(localStorageChanged).toBeInstanceOf(LocalStorageChanged);

expect(localStorageChanged.detail.key).toBe(key);
expect(localStorageChanged.detail.value).toBe(value);
});

it('uses the correct event name', () => {
const key = 'foo';
const value = 'bar';

const localStorageChanged = new LocalStorageChanged({ key, value });

expect(localStorageChanged.type).toBe(LocalStorageChanged.eventName);
});
});
Expand All @@ -29,7 +28,7 @@ describe('Module: local-storage-events', () => {
const value = 'bar';

writeStorage(key, value);

expect(localStorage.getItem(key)).toBe(value);
});

Expand Down Expand Up @@ -59,7 +58,7 @@ describe('Module: local-storage-events', () => {
it('can write negative numbers', () => {
const key = 'onestepforward';
const value = -2;

writeStorage(key, value);

expect(localStorage.getItem(key)).toBe(`${value}`);
Expand Down Expand Up @@ -91,7 +90,7 @@ describe('Module: local-storage-events', () => {
describe('when deleting a value that does not exist', () => {
it('is still null', () => {
const key = 'chocolate';

expect(localStorage.getItem(key)).toBe(null);
expect(() => deleteFromStorage(key)).not.toThrow();
expect(localStorage.getItem(key)).toBe(null);
Expand Down

0 comments on commit df04273

Please sign in to comment.