Skip to content

Commit

Permalink
feat: Support id on web (#524)
Browse files Browse the repository at this point in the history
* feat: Support `id` on web

Local storage does not have a concept of separate stores in user code,
this change emulates that behaviour by prefixing the keys in local
storage with `id`.

This retains backwards compatibility with existing web MMKV stores by
treating the the default `mmkv.default` id is as prefixless.

Fixes #520

* feat: Adds a check to key and id values to reject our wildcard character on web (a backslash) (#1)

* feat: Adds a check to key and id values to reject our wildcard character on web (a backslash)

---------

Co-authored-by: Jonathan Jacobs <jonathan@yoco.co.za>
Co-authored-by: CannibalKush <45557293+CannibalKush@users.noreply.github.com>
  • Loading branch information
3 people committed Apr 7, 2023
1 parent 1c81574 commit 76cbf26
Showing 1 changed file with 27 additions and 11 deletions.
38 changes: 27 additions & 11 deletions src/createMMKV.web.ts
Expand Up @@ -6,9 +6,6 @@ const canUseDOM =
typeof window !== 'undefined' && window.document?.createElement != null;

export const createMMKV = (config: MMKVConfiguration): NativeMMKV => {
if (config.id !== 'mmkv.default') {
throw new Error("MMKV: 'id' is not supported on Web!");
}
if (config.encryptionKey != null) {
throw new Error("MMKV: 'encryptionKey' is not supported on Web!");
}
Expand All @@ -32,28 +29,47 @@ export const createMMKV = (config: MMKVConfiguration): NativeMMKV => {

const textEncoder = createTextEncoder();

if (config.id.indexOf('\\') !== -1) {
throw new Error('MMKV: `id` cannot contain the backslash character (`\\`)!');
}

const keyPrefix = (config.id && config.id !== 'mmkv.default') ? `${config.id}\\` : null;
const prefixedKey = (key: string) => {
if (keyPrefix === null) return key;
return `${keyPrefix}\\${key}`;
};

return {
clearAll: () => storage().clear(),
delete: (key) => storage().removeItem(key),
set: (key, value) => storage().setItem(key, value.toString()),
getString: (key) => storage().getItem(key) ?? undefined,
delete: (key) => storage().removeItem(prefixedKey(key)),
set: (key, value) => {
if (key.indexOf('\\') !== -1) {
throw new Error('MMKV: `key` cannot contain the backslash character (`\\`)!');
}
storage().setItem(prefixedKey(key), value.toString())
},
getString: (key) => storage().getItem(prefixedKey(key)) ?? undefined,
getNumber: (key) => {
const value = storage().getItem(key);
const value = storage().getItem(prefixedKey(key));
if (value == null) return undefined;
return Number(value);
},
getBoolean: (key) => {
const value = storage().getItem(key);
const value = storage().getItem(prefixedKey(key));
if (value == null) return undefined;
return value === 'true';
},
getBuffer: (key) => {
const value = storage().getItem(key);
const value = storage().getItem(prefixedKey(key));
if (value == null) return undefined;
return textEncoder.encode(value);
},
getAllKeys: () => Object.keys(storage()),
contains: (key) => storage().getItem(key) != null,
getAllKeys: () => {
const keys = Object.keys(storage());
if (keyPrefix === null) return keys;
return keys.filter(key => key.startsWith(keyPrefix));
},
contains: (key) => storage().getItem(prefixedKey(key)) != null,
recrypt: () => {
throw new Error('`recrypt(..)` is not supported on Web!');
},
Expand Down

0 comments on commit 76cbf26

Please sign in to comment.