From 0f6106984b8de5900a20e49b24e83345458d08b3 Mon Sep 17 00:00:00 2001 From: Adam Utsch Date: Sun, 17 Nov 2024 15:18:00 -0600 Subject: [PATCH] fix: Improve support for web projects Starting with 3.x webpack required the addition of react-native-web to work. Webpack would throw errors even with react-native-web but those errors seemed to be ignored and everything worked as expected. Vite configuration will not ignore those errors even with react-native-web. This re-arranges some code and adds some new web entry points. React-native-web will no longer be necessary to use this library with webpack/vite configurations. --- package/src/MMKV.ts | 8 ++- package/src/MemoryWarningListener.web.ts | 5 ++ package/src/NativeMmkv.ts | 5 ++ package/src/Types.ts | 74 ++++++++++++++++++++++++ package/src/createMMKV.ts | 4 +- package/src/createMMKV.web.ts | 3 +- package/src/hooks.ts | 2 +- package/src/index.ts | 2 +- 8 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 package/src/MemoryWarningListener.web.ts diff --git a/package/src/MMKV.ts b/package/src/MMKV.ts index 82106225..51312936 100644 --- a/package/src/MMKV.ts +++ b/package/src/MMKV.ts @@ -1,8 +1,12 @@ import { createMMKV } from './createMMKV'; import { createMockMMKV } from './createMMKV.mock'; import { isTest } from './PlatformChecker'; -import type { Configuration } from './NativeMmkv'; -import type { Listener, MMKVInterface, NativeMMKV } from './Types'; +import type { + Configuration, + Listener, + MMKVInterface, + NativeMMKV, +} from './Types'; import { addMemoryWarningListener } from './MemoryWarningListener'; const onValueChangedListeners = new Map void)[]>(); diff --git a/package/src/MemoryWarningListener.web.ts b/package/src/MemoryWarningListener.web.ts new file mode 100644 index 00000000..fbc52eb8 --- /dev/null +++ b/package/src/MemoryWarningListener.web.ts @@ -0,0 +1,5 @@ +import { MMKVInterface } from './Types'; + +export const addMemoryWarningListener = (_mmkv: MMKVInterface): void => { + //no-op function, there is not a web equivalent to memory warning +}; diff --git a/package/src/NativeMmkv.ts b/package/src/NativeMmkv.ts index f4765aa9..d480e2b0 100644 --- a/package/src/NativeMmkv.ts +++ b/package/src/NativeMmkv.ts @@ -4,6 +4,11 @@ import type { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes'; import { ModuleNotFoundError } from './ModuleNotFoundError'; import { getMMKVPlatformContextTurboModule } from './NativeMmkvPlatformContext'; +/** + * IMPORTANT: These types are also in the Types.ts file. + * Due to how react-native-codegen works these are required here as the spec types can not be separated from spec. + * We also need the types separate to allow bypassing importing turbo module registry in web + */ /** * Configures the mode of the MMKV instance. */ diff --git a/package/src/Types.ts b/package/src/Types.ts index bfd2af56..627bd369 100644 --- a/package/src/Types.ts +++ b/package/src/Types.ts @@ -1,3 +1,77 @@ +/** + * IMPORTANT: Some of these types are also in the NativeMmkv.ts file. + * Due to how react-native-codegen works these are required here as the spec types can not be separated from spec. + * We also need the types separate to allow bypassing importing turbo module registry in web + */ + +/** + * Configures the mode of the MMKV instance. + */ +export enum Mode { + /** + * The MMKV instance is only used from a single process (this app). + */ + SINGLE_PROCESS, + /** + * The MMKV instance may be used from multiple processes, such as app clips, share extensions or background services. + */ + MULTI_PROCESS, +} + +/** + * Used for configuration of a single MMKV instance. + */ +export interface Configuration { + /** + * The MMKV instance's ID. If you want to use multiple instances, make sure to use different IDs! + * + * @example + * ```ts + * const userStorage = new MMKV({ id: `user-${userId}-storage` }) + * const globalStorage = new MMKV({ id: 'global-app-storage' }) + * ``` + * + * @default 'mmkv.default' + */ + id: string; + /** + * The MMKV instance's root path. By default, MMKV stores file inside `$(Documents)/mmkv/`. You can customize MMKV's root directory on MMKV initialization: + + * @example + * ```ts + * const temporaryStorage = new MMKV({ path: '/tmp/' }) + * ``` + * + * @note On iOS, if an `AppGroup` is set in `Info.plist` and `path` is `undefined`, MMKV will use the `AppGroup` directory. + * App Groups allow you to share MMKV storage between apps, widgets and extensions within the same AppGroup bundle. + * For more information, see [the `Configuration` section](https://github.com/Tencent/MMKV/wiki/iOS_tutorial#configuration). + * + * @default undefined + */ + path?: string; + /** + * The MMKV instance's encryption/decryption key. By default, MMKV stores all key-values in plain text on file, relying on iOS's sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV. + * + * Encryption keys can have a maximum length of 16 bytes. + * + * @example + * ```ts + * const secureStorage = new MMKV({ encryptionKey: 'my-encryption-key!' }) + * ``` + * + * @default undefined + */ + encryptionKey?: string; + /** + * Configure the processing mode for MMKV. + * - `SINGLE_PROCESS`: The MMKV instance is only used from a single process (this app). + * - `MULTI_PROCESS`: The MMKV instance may be used from multiple processes, such as app clips, share extensions or background services. + * + * @default SINGLE_PROCESS + */ + mode?: Mode; +} + /** * Represents a single MMKV instance. */ diff --git a/package/src/createMMKV.ts b/package/src/createMMKV.ts index 2cc31c39..2d46c6cd 100644 --- a/package/src/createMMKV.ts +++ b/package/src/createMMKV.ts @@ -1,6 +1,6 @@ import { Platform } from 'react-native'; -import { getMMKVTurboModule, Mode, type Configuration } from './NativeMmkv'; -import type { NativeMMKV } from './Types'; +import { getMMKVTurboModule } from './NativeMmkv'; +import { type Configuration, Mode, type NativeMMKV } from './Types'; import { getMMKVPlatformContextTurboModule } from './NativeMmkvPlatformContext'; export const createMMKV = (config: Configuration): NativeMMKV => { diff --git a/package/src/createMMKV.web.ts b/package/src/createMMKV.web.ts index 6f61a4a0..09734aa8 100644 --- a/package/src/createMMKV.web.ts +++ b/package/src/createMMKV.web.ts @@ -1,6 +1,5 @@ /* global localStorage */ -import type { Configuration } from './NativeMmkv'; -import type { NativeMMKV } from './Types'; +import type { Configuration, NativeMMKV } from './Types'; import { createTextEncoder } from './createTextEncoder'; const canUseDOM = diff --git a/package/src/hooks.ts b/package/src/hooks.ts index e2a80a85..d3522a27 100644 --- a/package/src/hooks.ts +++ b/package/src/hooks.ts @@ -1,6 +1,6 @@ import { useRef, useState, useMemo, useCallback, useEffect } from 'react'; import { MMKV } from './MMKV'; -import type { Configuration } from './NativeMmkv'; +import type { Configuration } from './Types'; function isConfigurationEqual( left?: Configuration, diff --git a/package/src/index.ts b/package/src/index.ts index 49de64f0..37e695a9 100644 --- a/package/src/index.ts +++ b/package/src/index.ts @@ -1,4 +1,4 @@ export * from './MMKV'; export * from './hooks'; -export { Mode, Configuration } from './NativeMmkv'; +export { Mode, type Configuration } from './Types';