Skip to content

Commit

Permalink
fix: Extract to Types
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Mar 27, 2024
1 parent c462b3c commit 2989c33
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 93 deletions.
53 changes: 53 additions & 0 deletions src/LazyTurboModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { NativeModules, Platform, TurboModule } from 'react-native';

/**
* Lazily get a TurboModule by wrapping it in a Proxy.
*/
export function getLazyTurboModule<T extends TurboModule>(
initializeTurboModule: () => T | undefined
): T {
const proxy = new Proxy<T>(undefined, {
get: (target, property) => {
if (target == null) {
// Target is null, let's initialize it!
target = initializeTurboModule();

if (target == null) {
// if it still is null, something went wrong!
let message =
'Failed to create a new MMKV instance: The native MMKV Module could not be found.';
message +=
'\n* Make sure react-native-mmkv is correctly autolinked (run `npx react-native config` to verify)';
if (Platform.OS === 'ios' || Platform.OS === 'macos') {
message +=
'\n* Make sure you ran `pod install` in the ios/ directory.';
}
if (Platform.OS === 'android') {
message += '\n* Make sure gradle is synced.';
}
// check if Expo
const ExpoConstants =
NativeModules.NativeUnimoduleProxy?.modulesConstants
?.ExponentConstants;
if (ExpoConstants != null) {
if (ExpoConstants.appOwnership === 'expo') {
// We're running Expo Go
throw new Error(
'react-native-mmkv is not supported in Expo Go! Use EAS (`expo prebuild`) or eject to a bare workflow instead.'
);
} else {
// We're running Expo bare / standalone
message += '\n* Make sure you ran `expo prebuild`.';
}
}

message += '\n* Make sure you rebuilt the app.';
throw new Error(message);
}
}

return target[property];
},
});
return proxy;
}
91 changes: 1 addition & 90 deletions src/MMKV.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,98 +3,9 @@ import { createMMKV } from './createMMKV';
import { createMockMMKV } from './createMMKV.mock';
import { isJest } from './PlatformChecker';
import { Configuration } from './NativeMmkv';
import { Listener, MMKVInterface, NativeMMKV } from './Types';
export { Configuration, Mode } from './NativeMmkv';

interface Listener {
remove: () => void;
}

/**
* Represents a single MMKV instance.
*/
export interface NativeMMKV {
/**
* Set a value for the given `key`.
*/
set: (key: string, value: boolean | string | number | ArrayBuffer) => void;
/**
* Get the boolean value for the given `key`, or `undefined` if it does not exist.
*
* @default undefined
*/
getBoolean: (key: string) => boolean | undefined;
/**
* Get the string value for the given `key`, or `undefined` if it does not exist.
*
* @default undefined
*/
getString: (key: string) => string | undefined;
/**
* Get the number value for the given `key`, or `undefined` if it does not exist.
*
* @default undefined
*/
getNumber: (key: string) => number | undefined;
/**
* Get a raw buffer of unsigned 8-bit (0-255) data.
*
* @default undefined
*/
getBuffer: (key: string) => ArrayBuffer | undefined;
/**
* Checks whether the given `key` is being stored in this MMKV instance.
*/
contains: (key: string) => boolean;
/**
* Delete the given `key`.
*/
delete: (key: string) => void;
/**
* Get all keys.
*
* @default []
*/
getAllKeys: () => string[];
/**
* Delete all keys.
*/
clearAll: () => void;
/**
* Sets (or updates) the encryption-key to encrypt all data in this MMKV instance with.
*
* To remove encryption, pass `undefined` as a key.
*
* Encryption keys can have a maximum length of 16 bytes.
*/
recrypt: (key: string | undefined) => void;
/**
* Trims the storage space and clears memory cache.
*
* Since MMKV does not resize itself after deleting keys, you can call `trim()`
* after deleting a bunch of keys to manually trim the memory- and
* disk-file to reduce storage and memory usage.
*
* In most applications, this is not needed at all.
*/
trim(): void;
/**
* Get the current total size of the storage, in bytes.
*/
readonly size: number;
}

interface MMKVInterface extends NativeMMKV {
/**
* Adds a value changed listener. The Listener will be called whenever any value
* in this storage instance changes (set or delete).
*
* To unsubscribe from value changes, call `remove()` on the Listener.
*/
addOnValueChangedListener: (
onValueChanged: (key: string) => void
) => Listener;
}

const onValueChangedListeners = new Map<string, ((key: string) => void)[]>();

/**
Expand Down
89 changes: 89 additions & 0 deletions src/Types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* Represents a single MMKV instance.
*/
export interface NativeMMKV {
/**
* Set a value for the given `key`.
*/
set: (key: string, value: boolean | string | number | ArrayBuffer) => void;
/**
* Get the boolean value for the given `key`, or `undefined` if it does not exist.
*
* @default undefined
*/
getBoolean: (key: string) => boolean | undefined;
/**
* Get the string value for the given `key`, or `undefined` if it does not exist.
*
* @default undefined
*/
getString: (key: string) => string | undefined;
/**
* Get the number value for the given `key`, or `undefined` if it does not exist.
*
* @default undefined
*/
getNumber: (key: string) => number | undefined;
/**
* Get a raw buffer of unsigned 8-bit (0-255) data.
*
* @default undefined
*/
getBuffer: (key: string) => ArrayBuffer | undefined;
/**
* Checks whether the given `key` is being stored in this MMKV instance.
*/
contains: (key: string) => boolean;
/**
* Delete the given `key`.
*/
delete: (key: string) => void;
/**
* Get all keys.
*
* @default []
*/
getAllKeys: () => string[];
/**
* Delete all keys.
*/
clearAll: () => void;
/**
* Sets (or updates) the encryption-key to encrypt all data in this MMKV instance with.
*
* To remove encryption, pass `undefined` as a key.
*
* Encryption keys can have a maximum length of 16 bytes.
*/
recrypt: (key: string | undefined) => void;
/**
* Trims the storage space and clears memory cache.
*
* Since MMKV does not resize itself after deleting keys, you can call `trim()`
* after deleting a bunch of keys to manually trim the memory- and
* disk-file to reduce storage and memory usage.
*
* In most applications, this is not needed at all.
*/
trim(): void;
/**
* Get the current total size of the storage, in bytes.
*/
readonly size: number;
}

export interface Listener {
remove: () => void;
}

export interface MMKVInterface extends NativeMMKV {
/**
* Adds a value changed listener. The Listener will be called whenever any value
* in this storage instance changes (set or delete).
*
* To unsubscribe from value changes, call `remove()` on the Listener.
*/
addOnValueChangedListener: (
onValueChanged: (key: string) => void
) => Listener;
}
2 changes: 1 addition & 1 deletion src/createMMKV.mock.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { NativeMMKV } from './MMKV';
import type { NativeMMKV } from './Types';

/* Mock MMKV instance for use in tests */
export const createMockMMKV = (): NativeMMKV => {
Expand Down
3 changes: 2 additions & 1 deletion src/createMMKV.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Configuration, NativeMMKV } from './MMKV';
import type { Configuration } from './MMKV';
import type { NativeMMKV } from './Types';
import { getMMKVTurboModule } from './NativeMmkv';

const module = getMMKVTurboModule();
Expand Down
3 changes: 2 additions & 1 deletion src/createMMKV.web.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* global localStorage */
import type { Configuration, NativeMMKV } from './MMKV';
import type { Configuration } from './MMKV';
import type { NativeMMKV } from './Types';
import { createTextEncoder } from './createTextEncoder';

const canUseDOM =
Expand Down

0 comments on commit 2989c33

Please sign in to comment.