Skip to content

Commit

Permalink
feat: add localStorage and sessionStorage with store_changed event (#13)
Browse files Browse the repository at this point in the history
* feat: add localStorage and sessionStorage with store_changed event

* fix: fix lint

* fix: fix import

* feat: use storage and onChanged event

Co-authored-by: alpers <[email protected]>
  • Loading branch information
linhan and linhan-work authored Jan 9, 2023
1 parent 8a9fcf7 commit 856bcfc
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 32 deletions.
5 changes: 2 additions & 3 deletions packages/ui-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
"version": "0.6.1-1",
"main": "index.js",
"dependencies": {
"store": "^2.0.12"
"eventemitter3": "^5.0.0"
},
"devDependencies": {
"@types/chrome": "^0.0.203",
"@types/store": "^2.0.2"
"@types/chrome": "^0.0.203"
}
}
4 changes: 3 additions & 1 deletion packages/ui-store/src/BaseStore.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

export abstract class BaseStore {
import { Events } from './event/Event';

export abstract class BaseStore extends Events {
abstract all(fn: (key: string, value: unknown) => void): void;
abstract get(key: string, fn: (value: unknown) => void): void;
abstract set(key: string, value: unknown, fn?: () => void): void;
Expand Down
20 changes: 14 additions & 6 deletions packages/ui-store/src/BrowserSession.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import storage from 'store/storages/sessionStorage';

import { SessionStorage } from './store/SessionStorage';
import { BaseStore } from './BaseStore';

export class BrowserSession extends BaseStore {
#session: SessionStorage;

constructor() {
super();
this.#session = new SessionStorage();
}

public all(fn: (key: string, value: unknown) => void): void {
storage.each((value: unknown, key: string): void => {
this.#session.each((key: string, value: unknown): void => {
fn(key, value);
});
}

public get(key: string, fn: (value: unknown) => void): void {
fn(storage.read(key) as unknown);
fn(this.#session.get(key) as unknown);
}

public remove(key: string, fn?: () => void): void {
storage.remove(key);
this.#session.remove(key);
fn && fn();
this.emit('store_changed', key);
}

public set(key: string, value: unknown, fn?: () => void): void {
storage.write(key, value as string);
this.#session.set(key, value as string);
fn && fn();
this.emit('store_changed', key, value);
}
}
24 changes: 18 additions & 6 deletions packages/ui-store/src/BrowserStore.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import store from 'store';

import { LocalStorage } from './store/LocalStorage';
import { BaseStore } from './BaseStore';

export class BrowserStore extends BaseStore {
#store: LocalStorage;

constructor() {
super();
this.#store = new LocalStorage();

window.addEventListener('storage', (event) => {
event.key && this.emit('store_changed', event.key, event.newValue);
});
}

public all(fn: (key: string, value: unknown) => void): void {
store.each((value: unknown, key: string): void => {
this.#store.each((key: string, value: unknown): void => {
fn(key, value);
});
}

public get(key: string, fn: (value: unknown) => void): void {
fn(store.get(key) as unknown);
fn(this.#store.get(key) as unknown);
}

public remove(key: string, fn?: () => void): void {
store.remove(key);
this.#store.remove(key);
fn && fn();
this.emit('store_changed', key);
}

public set(key: string, value: unknown, fn?: () => void): void {
store.set(key, value);
this.#store.set(key, value);
fn && fn();
this.emit('store_changed', key, value);
}
}
12 changes: 12 additions & 0 deletions packages/ui-store/src/ExtensionSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ import { BaseStore } from './BaseStore';
const session = chrome.storage.session;

export class ExtensionSession extends BaseStore {
constructor() {
super();

chrome.storage.onChanged.addListener((event, namespace) => {
if (namespace === 'session') {
const key = Object.keys(event)[0];

this.emit('store_changed', key, event[key]?.newValue);
}
});
}

public all(fn: (key: string, value: string) => void) {
session.get(null, (items) => {
for (const key in items) {
Expand Down
12 changes: 12 additions & 0 deletions packages/ui-store/src/ExtensionStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ import { BaseStore } from './BaseStore';
const storage = chrome.storage.local;

export class ExtensionStore extends BaseStore {
constructor() {
super();

chrome.storage.onChanged.addListener((event, namespace) => {
if (namespace === 'local') {
const key = Object.keys(event)[0];

this.emit('store_changed', key, event[key]?.newValue);
}
});
}

public all(fn: (key: string, value: string) => void) {
storage.get(null, (items) => {
for (const key in items) {
Expand Down
32 changes: 32 additions & 0 deletions packages/ui-store/src/event/Event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { EventEmitter } from 'eventemitter3';

import { StorageEvent } from './types';

export abstract class Events {
#eventemitter = new EventEmitter();

protected emit(type: StorageEvent, key: string, value?: unknown): boolean {
return this.#eventemitter.emit(type, key, value);
}

public on(type: StorageEvent, handler: (key: string, value?: unknown) => any): this {
this.#eventemitter.on(type, handler);

return this;
}

public off(type: StorageEvent, handler: (key: string, value?: unknown) => any): this {
this.#eventemitter.removeListener(type, handler);

return this;
}

public once(type: StorageEvent, handler: (key: string, value?: unknown) => any): this {
this.#eventemitter.once(type, handler);

return this;
}
}
4 changes: 4 additions & 0 deletions packages/ui-store/src/event/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

export type StorageEvent = 'store_changed';
32 changes: 32 additions & 0 deletions packages/ui-store/src/store/LocalStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { deserialize, serialize } from './utils';

export class LocalStorage {
get(key: string | null) {
if (!key) return undefined;

const val = localStorage.getItem(key);

return deserialize(val);
}

set(key: string, value: unknown) {
const val = serialize(value);

localStorage.setItem(key, val);
}

remove(key: string) {
localStorage.removeItem(key);
}

each(fn: (key: string, val: unknown) => void) {
for (let i = localStorage.length - 1; i >= 0; i--) {
const key = localStorage.key(i);

if (key) fn(key, this.get(key));
}
}
}
32 changes: 32 additions & 0 deletions packages/ui-store/src/store/SessionStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { deserialize, serialize } from './utils';

export class SessionStorage {
get(key: string | null) {
if (!key) return undefined;

const val = sessionStorage.getItem(key);

return deserialize(val);
}

set(key: string, value: unknown) {
const val = serialize(value);

sessionStorage.setItem(key, val);
}

remove(key: string) {
sessionStorage.removeItem(key);
}

each(fn: (key: string, val: unknown) => void) {
for (let i = sessionStorage.length - 1; i >= 0; i--) {
const key = sessionStorage.key(i);

if (key) fn(key, this.get(key));
}
}
}
20 changes: 20 additions & 0 deletions packages/ui-store/src/store/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

export function serialize(obj: unknown) {
return JSON.stringify(obj);
}

export function deserialize(strVal: string | null) {
if (!strVal) return undefined;

let val: any;

try {
val = JSON.parse(strVal);
} catch (e) {
val = strVal;
}

return val;
}
17 changes: 1 addition & 16 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3609,13 +3609,6 @@ __metadata:
languageName: node
linkType: hard

"@types/store@npm:^2.0.2":
version: 2.0.2
resolution: "@types/store@npm:2.0.2"
checksum: aa548e117f9a1e2b1ff0263f3261ad7066b885ed32c05019832e4cbf91bf09f5f5891cccfb4e001a6cdc87d306b1d6376b20bdf8976dfced38b18db3c9c6fef3
languageName: node
linkType: hard

"@types/tough-cookie@npm:*":
version: 4.0.2
resolution: "@types/tough-cookie@npm:4.0.2"
Expand Down Expand Up @@ -4549,8 +4542,7 @@ __metadata:
resolution: "@zcloak/ui-store@workspace:packages/ui-store"
dependencies:
"@types/chrome": ^0.0.203
"@types/store": ^2.0.2
store: ^2.0.12
eventemitter3: ^5.0.0
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -15349,13 +15341,6 @@ __metadata:
languageName: node
linkType: hard

"store@npm:^2.0.12":
version: 2.0.12
resolution: "store@npm:2.0.12"
checksum: 4e0fe69f71dc3c99af1b87e87dcb0c81fc979bd38abbcdf66d5705f1c44e6fd5e043056288efd695926c75419adc356873e6792d9b024085a8db51dbdda899ea
languageName: node
linkType: hard

"stream-browserify@npm:^3.0.0":
version: 3.0.0
resolution: "stream-browserify@npm:3.0.0"
Expand Down

0 comments on commit 856bcfc

Please sign in to comment.