Skip to content

Commit f379624

Browse files
authored
Merge pull request #16 from kinde-oss/feat/storageSetItems
feat: add setItems to storage
2 parents 153dda5 + aa264e8 commit f379624

File tree

10 files changed

+100
-18
lines changed

10 files changed

+100
-18
lines changed

lib/sessionManager/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export const storageSettings: StorageSettingsType = {
1313
maxLength: 2000,
1414
};
1515

16-
export { MemoryStorage } from "./stores/memory.ts";
17-
export { ChromeStore } from "./stores/chromeStore.ts";
18-
export { ExpoSecureStore } from "./stores/expoSecureStore.ts";
16+
export { MemoryStorage } from "./stores/memory.js";
17+
export { ChromeStore } from "./stores/chromeStore.js";
18+
export { ExpoSecureStore } from "./stores/expoSecureStore.js";
1919
export { LocalStorage } from "./stores/localStorage.ts";
20-
export * from "./types.ts";
20+
export { type SessionManager, StorageKeys } from "./types.ts";

lib/sessionManager/stores/chromeStore.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ describe.skip("GoogleStorage standard keys", () => {
4343
await sessionManager.getSessionItem(StorageKeys.accessToken),
4444
).toBeNull();
4545
});
46+
47+
it("should set many items", async () => {
48+
await sessionManager.setItems({
49+
[StorageKeys.accessToken]: "accessTokenValue",
50+
[StorageKeys.idToken]: "idTokenValue",
51+
});
52+
expect(await sessionManager.getSessionItem(StorageKeys.accessToken)).toBe(
53+
"accessTokenValue",
54+
);
55+
expect(await sessionManager.getSessionItem(StorageKeys.idToken)).toBe(
56+
"idTokenValue",
57+
);
58+
});
4659
});
4760

4861
// TODO: Fix tests, need to mock chrome storage

lib/sessionManager/stores/chromeStore.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { storageSettings } from "../index.js";
2-
import { StorageKeys, type SessionManager } from "../types.js";
2+
import { SessionBase, StorageKeys, type SessionManager } from "../types.js";
33
import { splitString } from "../utils.js";
44

55
function getStorageValue(key: string): unknown | undefined {
@@ -18,7 +18,10 @@ function getStorageValue(key: string): unknown | undefined {
1818
* Provides a chrome.store.local based session manager implementation for the browser.
1919
* @class ChromeStore
2020
*/
21-
export class ChromeStore<V = StorageKeys> implements SessionManager<V> {
21+
export class ChromeStore<V extends string = StorageKeys>
22+
extends SessionBase<V>
23+
implements SessionManager<V>
24+
{
2225
/**
2326
* Clears all items from session store.
2427
* @returns {void}

lib/sessionManager/stores/expoSecureStore.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ describe.skip("ExpoSecureStore standard keys", () => {
4343
await sessionManager.getSessionItem(StorageKeys.accessToken),
4444
).toBeNull();
4545
});
46+
47+
it("should set many items", async () => {
48+
await sessionManager.setItems({
49+
[StorageKeys.accessToken]: "accessTokenValue",
50+
[StorageKeys.idToken]: "idTokenValue",
51+
});
52+
expect(await sessionManager.getSessionItem(StorageKeys.accessToken)).toBe(
53+
"accessTokenValue",
54+
);
55+
expect(await sessionManager.getSessionItem(StorageKeys.idToken)).toBe(
56+
"idTokenValue",
57+
);
58+
});
4659
});
4760

4861
describe.skip("ExpoSecureStore keys: storageKeys", () => {

lib/sessionManager/stores/expoSecureStore.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { storageSettings } from "../index.js";
2-
import { StorageKeys, type SessionManager } from "../types.js";
2+
import { SessionBase, StorageKeys } from "../types.js";
33
import { splitString } from "../utils.js";
44

55
let expoSecureStore: typeof import("expo-secure-store") | undefined = undefined;
@@ -16,8 +16,11 @@ async function waitForExpoSecureStore() {
1616
* Provides a expo local store based session manager implementation for the browser.
1717
* @class ExpoSecureStore
1818
*/
19-
export class ExpoSecureStore<V = StorageKeys> implements SessionManager<V> {
19+
export class ExpoSecureStore<
20+
V extends string = StorageKeys,
21+
> extends SessionBase<V> {
2022
constructor() {
23+
super();
2124
this.loadExpoStore();
2225
}
2326

lib/sessionManager/stores/localStorage.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ describe("LocalStorage standard keys", () => {
3434
});
3535

3636
it("should set and get an item in session storage", async () => {
37-
console.log("here");
3837
await sessionManager.setSessionItem(StorageKeys.accessToken, "testValue");
3938
expect(await sessionManager.getSessionItem(StorageKeys.accessToken)).toBe(
4039
"testValue",

lib/sessionManager/stores/localStorage.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
import { storageSettings } from "../index.js";
2-
import { StorageKeys, type SessionManager } from "../types.js";
2+
import { SessionBase, StorageKeys, type SessionManager } from "../types.js";
33
import { splitString } from "../utils.js";
44

55
/**
66
* Provides a localStorage based session manager implementation for the browser.
77
* @class LocalStorage
88
*/
9-
export class LocalStorage<V = StorageKeys> implements SessionManager<V> {
9+
export class LocalStorage<V extends string = StorageKeys>
10+
extends SessionBase<V>
11+
implements SessionManager<V>
12+
{
1013
constructor() {
14+
super();
1115
console.warn("LocalStorage store should not be used in production");
1216
}
1317

14-
setItems: Set<V | StorageKeys> = new Set<V>();
18+
private internalItems: Set<V | StorageKeys> = new Set<V>();
1519

1620
/**
1721
* Clears all items from session store.
1822
* @returns {void}
1923
*/
2024
async destroySession(): Promise<void> {
21-
this.setItems.forEach((key) => {
25+
this.internalItems.forEach((key) => {
2226
this.removeSessionItem(key);
2327
});
2428
}
@@ -35,7 +39,7 @@ export class LocalStorage<V = StorageKeys> implements SessionManager<V> {
3539
): Promise<void> {
3640
// clear items first
3741
await this.removeSessionItem(itemKey);
38-
this.setItems.add(itemKey);
42+
this.internalItems.add(itemKey);
3943

4044
if (typeof itemValue === "string") {
4145
splitString(itemValue, storageSettings.maxLength).forEach(
@@ -97,6 +101,6 @@ export class LocalStorage<V = StorageKeys> implements SessionManager<V> {
97101

98102
index++;
99103
}
100-
this.setItems.delete(itemKey);
104+
this.internalItems.delete(itemKey);
101105
}
102106
}

lib/sessionManager/stores/memory.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ describe("MemoryStorage standard keys", () => {
4343
await sessionManager.getSessionItem(StorageKeys.accessToken),
4444
).toBeNull();
4545
});
46+
47+
it("should set many items", async () => {
48+
await sessionManager.setItems({
49+
[StorageKeys.accessToken]: "accessTokenValue",
50+
[StorageKeys.idToken]: "idTokenValue",
51+
});
52+
expect(await sessionManager.getSessionItem(StorageKeys.accessToken)).toBe(
53+
"accessTokenValue",
54+
);
55+
expect(await sessionManager.getSessionItem(StorageKeys.idToken)).toBe(
56+
"idTokenValue",
57+
);
58+
});
4659
});
4760

4861
describe("MemoryStorage keys: storageKeys", () => {

lib/sessionManager/stores/memory.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { storageSettings } from "../index.js";
2-
import { StorageKeys, type SessionManager } from "../types.js";
2+
import { SessionBase, StorageKeys, type SessionManager } from "../types.js";
33
import { splitString } from "../utils.js";
44

55
/**
66
* Provides a memory based session manager implementation for the browser.
77
* @class MemoryStorage
88
*/
9-
export class MemoryStorage<V = StorageKeys> implements SessionManager<V> {
9+
export class MemoryStorage<V extends string = StorageKeys>
10+
extends SessionBase<V>
11+
implements SessionManager<V>
12+
{
1013
private memCache: Record<string, unknown> = {};
1114

1215
/**

lib/sessionManager/types.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,31 @@ export type StorageSettingsType = {
1818
maxLength: number;
1919
};
2020

21-
export interface SessionManager<V = StorageKeys> {
21+
export abstract class SessionBase<V extends string = StorageKeys>
22+
implements SessionManager<V>
23+
{
24+
abstract getSessionItem<T = unknown>(
25+
itemKey: V | StorageKeys,
26+
): Awaitable<T | unknown | null>;
27+
abstract setSessionItem<T = unknown>(
28+
itemKey: V | StorageKeys,
29+
itemValue: T,
30+
): Awaitable<void>;
31+
abstract removeSessionItem(itemKey: V | StorageKeys): Awaitable<void>;
32+
abstract destroySession(): Awaitable<void>;
33+
34+
async setItems(items: Partial<Record<V, unknown>>): Awaitable<void> {
35+
await Promise.all(
36+
(Object.entries(items) as [V | StorageKeys, unknown][]).map(
37+
([key, value]) => {
38+
return this.setSessionItem(key, value);
39+
},
40+
),
41+
);
42+
}
43+
}
44+
45+
export interface SessionManager<V extends string = StorageKeys> {
2246
/**
2347
*
2448
* Gets the item for the provided key from the storage.
@@ -49,4 +73,11 @@ export interface SessionManager<V = StorageKeys> {
4973
* Destroys the session
5074
*/
5175
destroySession: () => Awaitable<void>;
76+
77+
/**
78+
* Sets multiple items simultaneously.
79+
* @param {Record<V | StorageKeys, unknown>} items - Object containing key-value pairs to store
80+
* @returns {Promise<void>}
81+
*/
82+
setItems(items: Partial<Record<V, unknown>>): Awaitable<void>;
5283
}

0 commit comments

Comments
 (0)