diff --git a/.config/.eslintrc b/.config/.eslintrc deleted file mode 100644 index bb87ea98..00000000 --- a/.config/.eslintrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": ["@react-native-community"], - "rules": { - "no-console": "error", - "quotes": "off" - } -} diff --git a/.config/tsconfig.base.json b/.config/tsconfig.base.json index a5ee591d..9c5a2665 100644 --- a/.config/tsconfig.base.json +++ b/.config/tsconfig.base.json @@ -1,23 +1,30 @@ { - "exclude": [ - "../node_modules" - ], + "exclude": ["../node_modules"], "compilerOptions": { "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, "noImplicitOverride": true, "noImplicitReturns": true, + "noImplicitThis": true, "noPropertyAccessFromIndexSignature": true, "noUnusedLocals": true, "noUnusedParameters": true, "strict": true, - "moduleResolution": "node", + "module": "CommonJS", + "moduleResolution": "Node", "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, "allowJs": true, "checkJs": true, - "allowSyntheticDefaultImports": true, + "esModuleInterop": true, "forceConsistentCasingInFileNames": true, + "isolatedModules": true, "jsx": "react", "target": "ESNext", - "skipLibCheck": true + "pretty": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true } } diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 5ad9dfb6..f71501cb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -21,14 +21,14 @@ body: attributes: label: Version description: What version of `@react-native-async-storage/async-storage` are you using? - placeholder: 'Example: 1.15.9' + placeholder: "Example: 1.15.9" validations: required: true - type: checkboxes id: platforms attributes: label: What platforms are you seeing this issue on? - description: 'Select all that apply:' + description: "Select all that apply:" options: - label: Android - label: iOS diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e935d64d..ea8d5a58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,13 +5,30 @@ on: - main pull_request: jobs: + format: + name: Format + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Set up Node.js + uses: actions/setup-node@v3.6.0 + with: + node-version: 18.16.1 + cache: yarn + - name: Install JS dependencies + run: yarn + - name: Format + run: | + yarn format + git diff --exit-code review: name: Review runs-on: ubuntu-latest strategy: matrix: test-name: [lint, ts] - workspace: [default-storage-backend, core] + workspace: [default-storage, api] steps: - name: Checkout uses: actions/checkout@v3 @@ -44,11 +61,11 @@ jobs: with: gradle-version: wrapper arguments: react-native-async-storage_async-storage:test - build-root-directory: packages/default-storage-backend/example/android + build-root-directory: packages/default-storage/example/android - name: Build e2e binary run: | yarn build:e2e:android - working-directory: packages/default-storage-backend + working-directory: packages/default-storage ios: name: iOS @@ -59,7 +76,7 @@ jobs: - name: Cache /.ccache uses: actions/cache@v3 with: - path: packages/default-storage-backend/.ccache + path: packages/default-storage/.ccache key: ccache-ios-${{ hashFiles('yarn.lock') }} restore-keys: ccache-ios- - name: Set up Node.js @@ -73,15 +90,15 @@ jobs: - name: Bundle JS run: | yarn bundle:ios - working-directory: packages/default-storage-backend + working-directory: packages/default-storage - name: Install Pods run: | RCT_NEW_ARCH_ENABLED=1 pod install - working-directory: packages/default-storage-backend/example/ios + working-directory: packages/default-storage/example/ios - name: Build e2e binary run: | yarn build:e2e:ios - working-directory: packages/default-storage-backend + working-directory: packages/default-storage macos: name: macOS @@ -92,7 +109,7 @@ jobs: - name: Cache /.ccache uses: actions/cache@v3 with: - path: packages/default-storage-backend/.ccache + path: packages/default-storage/.ccache key: ccache-macos-${{ hashFiles('yarn.lock') }} restore-keys: ccache-macos- - name: Set up Node.js @@ -106,20 +123,20 @@ jobs: - name: Bundle JS run: | yarn bundle:macos - working-directory: packages/default-storage-backend + working-directory: packages/default-storage - name: Install Pods run: | RCT_NEW_ARCH_ENABLED=1 pod install - working-directory: packages/default-storage-backend/example/macos + working-directory: packages/default-storage/example/macos - name: Build run: | yarn build:e2e:macos - working-directory: packages/default-storage-backend + working-directory: packages/default-storage - name: Test if: false run: | yarn test:e2e:macos - working-directory: packages/default-storage-backend + working-directory: packages/default-storage windows: name: Windows @@ -142,15 +159,15 @@ jobs: - name: Install Windows test app run: | yarn install-windows-test-app -p example/windows - working-directory: packages/default-storage-backend + working-directory: packages/default-storage - name: Build run: | yarn react-native run-windows --release --arch x64 --logging --no-packager --no-launch --no-deploy --msbuildprops "BundleEntryFile=index.ts" --no-telemetry - working-directory: packages/default-storage-backend + working-directory: packages/default-storage release: name: Release - needs: [review, android, ios, macos, windows] + needs: [format, review, android, ios, macos, windows] if: github.event_name == 'push' runs-on: ubuntu-22.04 steps: @@ -170,7 +187,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GH_RELEASE_TOKEN }} GIT_AUTHOR_EMAIL: ${{ secrets.GH_BOT_EMAIL }} - GIT_AUTHOR_NAME : ${{ secrets.GH_BOT_NAME }} + GIT_AUTHOR_NAME: ${{ secrets.GH_BOT_NAME }} GIT_COMMITTER_EMAIL: ${{ secrets.GH_BOT_EMAIL }} GIT_COMMITTER_NAME: ${{ secrets.GH_BOT_NAME }} NPM_TOKEN: ${{ secrets.NPM_RELEASE_TOKEN }} @@ -178,4 +195,4 @@ jobs: git config user.email ${{ secrets.GH_BOT_EMAIL }} git config user.name ${{ secrets.GH_BOT_NAME }} yarn semantic-release - working-directory: packages/default-storage-backend + working-directory: packages/default-storage diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index f22c5ccd..a64d9f77 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,7 +1,7 @@ name: Mark stale issues and pull requests on: schedule: - - cron: '30 1 * * *' + - cron: "30 1 * * *" jobs: stale: runs-on: ubuntu-latest @@ -12,7 +12,7 @@ jobs: - uses: actions/stale@v7 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue has been marked as stale due to inactivity. Please respond or otherwise resolve the issue within 7 days or it will be closed.' - stale-pr-message: 'This PR has been marked as stale due to inactivity. Please address any comments within 7 days or it will be closed.' - exempt-issue-labels: 'help wanted :octocat:' - exempt-pr-labels: 'WIP' + stale-issue-message: "This issue has been marked as stale due to inactivity. Please respond or otherwise resolve the issue within 7 days or it will be closed." + stale-pr-message: "This PR has been marked as stale due to inactivity. Please address any comments within 7 days or it will be closed." + exempt-issue-labels: "help wanted :octocat:" + exempt-pr-labels: "WIP" diff --git a/.github/workflows/website-deployment.yml b/.github/workflows/website-deployment.yml index 2e98880f..ab647f87 100644 --- a/.github/workflows/website-deployment.yml +++ b/.github/workflows/website-deployment.yml @@ -4,7 +4,7 @@ on: branches: - main paths: - - 'packages/website/**' + - "packages/website/**" jobs: deploy: diff --git a/README.md b/README.md index be4e0deb..b1776f0d 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@ # React Native Async Storage -An asynchronous, unencrypted, persistent, key-value storage system for React Native. - +An asynchronous, unencrypted, persistent, key-value storage system for React +Native. ## Supported platforms -- iOS - Android +- iOS +- [macOS](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.8.1) - [Web](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.9.0) -- [MacOS](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.8.1) - [Windows](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.10.0) - ## Getting Started -Head over to [documentation](https://react-native-async-storage.github.io/async-storage/docs/install) to learn more. - +Head over to the +[documentation](https://react-native-async-storage.github.io/async-storage/docs/install) +to learn more. ## Running E2E locally @@ -23,27 +23,29 @@ Head over to [documentation](https://react-native-async-storage.github.io/async- 1. Create and start Android Emulator with Play services, API level 29 2. Build app and run tests - ```shell - yarn bundle:android - yarn build:e2e:android - yarn test:e2e:android - ``` - + ```shell + yarn bundle:android + yarn build:e2e:android + yarn test:e2e:android + ``` + ### iOS 1. Create and start iPhone 14 simulator with iOS version 16.4 2. Build app and run tests - ```shell - yarn bundle:ios - yarn build:e2e:ios - yarn test:e2e:ios - ``` + ```shell + yarn bundle:ios + yarn build:e2e:ios + yarn test:e2e:ios + ``` ## Contribution -Pull requests are welcome. Please open an issue first to discuss what you would like to change. + +Pull requests are welcome. Please open an issue first to discuss what you would +like to change. See the [CONTRIBUTING](.github/CONTRIBUTING.md) file for more information. ## License -MIT. +MIT diff --git a/package.json b/package.json index 658d950f..3f8f41bb 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,16 @@ "packages/*" ], "packageManager": "yarn@3.4.1", + "scripts": { + "format": "concurrently 'yarn:format:*'", + "format:c": "clang-format -i $(git ls-files '*.cpp' '*.h' '*.m' '*.mm') --style file:.config/.clang-format", + "format:js": "prettier --write --loglevel error $(git ls-files '*.js' '*.json' '*.ts' '*.tsx' '*.yml' 'README.md')" + }, "devDependencies": { - "@react-native-community/eslint-config": "3.2.0", - "eslint": "8.26.0", - "prettier": "2.8.8", - "typescript": "4.9.5" + "concurrently": "^8.2.2", + "eslint": "^8.54.0", + "prettier": "^2.8.8", + "typescript": "^5.3.0" }, "resolutions": { "@react-native-community/cli": "^10.2.5", diff --git a/packages/api/eslint.config.js b/packages/api/eslint.config.js new file mode 100644 index 00000000..f23036d9 --- /dev/null +++ b/packages/api/eslint.config.js @@ -0,0 +1 @@ +module.exports = require("@react-native-async-storage/eslint-config"); diff --git a/packages/api/example/ExampleExtension.ts b/packages/api/example/ExampleExtension.ts new file mode 100644 index 00000000..3dd53e18 --- /dev/null +++ b/packages/api/example/ExampleExtension.ts @@ -0,0 +1,17 @@ +import type { StorageExtension } from "../src"; + +export interface MyExampleExtension extends StorageExtension { + double: (num: number) => Promise; + + uppercase: (text: string) => string; + + key: string; +} + +export class ExampleExtension implements MyExampleExtension { + key = "my-example-storage"; + + double = async (num: number) => num * 2; + + uppercase = (text: string): string => text.toUpperCase(); +} diff --git a/packages/api/example/ExampleStorage.ts b/packages/api/example/ExampleStorage.ts new file mode 100644 index 00000000..bda31d4a --- /dev/null +++ b/packages/api/example/ExampleStorage.ts @@ -0,0 +1,70 @@ +import type { AsyncStorage, StorageKeys, StorageModel } from "../src"; +import type { MyExampleExtension } from "./ExampleExtension"; +import { ExampleExtension } from "./ExampleExtension"; + +type MyModel = StorageModel<{ + age: number; + name: string; + likes: boolean[]; +}>; + +export class ExampleStorage + implements AsyncStorage +{ + private storage: MyModel = { + age: null, + name: null, + likes: null, + }; + + getItem = async (key: K): Promise => { + return this.storage[key]; + }; + + setItem = async >( + key: K, + value: MyModel[K] + ): Promise => { + this.storage[key] = value; + }; + + removeItem = async >( + key: K + ): Promise => { + this.storage[key] = null; + }; + + getMany = async >( + keys: K[] + ): Promise<{ [k in K]: MyModel[k] }> => { + return keys.reduce((entries, key) => { + entries[key] = this.storage[key] ?? null; + return entries; + }, {} as { [k in K]: MyModel[k] }); + }; + + setMany = async >(entries: { + [k in K]: MyModel[k]; + }): Promise => { + Object.entries(entries).forEach((entry) => { + const key = entry[0] as K; + this.storage[key] = entry[1] as MyModel[K]; + }); + }; + + removeMany = async >( + keys: K[] + ): Promise => { + keys.forEach((k) => { + this.storage[k] = null; + }); + }; + + clear = async (): Promise => { + this.storage.age = null; + this.storage.name = null; + this.storage.likes = null; + }; + + ext: MyExampleExtension = new ExampleExtension(); +} diff --git a/packages/api/jest.config.js b/packages/api/jest.config.js new file mode 100644 index 00000000..3abcbd94 --- /dev/null +++ b/packages/api/jest.config.js @@ -0,0 +1,5 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", +}; diff --git a/packages/core/package.json b/packages/api/package.json similarity index 73% rename from packages/core/package.json rename to packages/api/package.json index fd50a246..f7e47d21 100644 --- a/packages/core/package.json +++ b/packages/api/package.json @@ -1,5 +1,5 @@ { - "name": "@react-native-async-storage/core", + "name": "@react-native-async-storage/api", "version": "0.0.0", "description": "Core API of Async Storage", "source": "src/index.ts", @@ -16,8 +16,9 @@ "scripts": { "prepack": "yarn build", "build": "bob build", - "test:lint": "eslint src/**", - "test:ts": "tsc --noEmit" + "test:lint": "eslint $(git ls-files '*.js' '*.ts' '*.tsx')", + "test:ts": "tsc --noEmit", + "test:jest": "jest" }, "keywords": [ "react-native", @@ -30,9 +31,13 @@ "author": "Krzysztof Borowy ", "license": "MIT", "devDependencies": { - "eslint": "8.26.0", + "@types/jest": "29.5.4", + "eslint": "^8.54.0", + "jest": "29.5.0", + "prettier": "^2.8.8", "react-native-builder-bob": "0.20.0", - "typescript": "4.9.5" + "ts-jest": "29.1.1", + "typescript": "^5.3.0" }, "react-native-builder-bob": { "source": "src", diff --git a/packages/api/src/AsyncStorage.ts b/packages/api/src/AsyncStorage.ts new file mode 100644 index 00000000..7ba58c87 --- /dev/null +++ b/packages/api/src/AsyncStorage.ts @@ -0,0 +1,74 @@ +import type { StorageKeys, StorageModel } from "./StorageModel"; +import type { StorageExtension } from "./StorageExtension"; + +/** + * AsyncStorage Interface + * Provides methods for managing asynchronous storage operations. + * @typeParam S - type of the storage model. + * @typeParam E - type of the storage extension, or unknown, if no extension is provided. + */ +export interface AsyncStorage< + S extends StorageModel, + E extends StorageExtension | unknown = unknown +> { + /** + * Retrieves a single item from storage based on the provided key. + * @param key - The key to identify the item within the storage. + * @returns Promise resolving to the value associated with the key, + * or null if the key does not exist. + */ + getItem>(key: K): Promise; + + /** + * Sets the value of the specified item in the storage. + * @param key - The key under which the value should be stored. + * @param value - The value to be stored. + * @returns Promise that resolves when the operation is completed. + */ + setItem>(key: K, value: S[K]): Promise; + + /** + * Removes the item from storage identified by the provided key. + * @param key - The key of the item to be removed. + * @returns Promise that resolves when the operation is completed. + */ + removeItem>(key: K): Promise; + + /** + * Retrieves multiple items from storage based on the provided keys. + * @param keys - An array of keys to identify the items to be retrieved. + * @returns Promise resolving to an object with key-value pairs, + * where the values are associated with the keys, + * or null if a key does not exist. + */ + getMany>(keys: K[]): Promise<{ [k in K]: S[k] }>; + + /** + * Sets multiple items in the storage. + * @param entries - An object containing key-value pairs to be stored. + * @returns Promise that resolves when the operation is completed. + */ + setMany>(entries: { + [k in K]: S[k]; + }): Promise; + + /** + * Removes multiple items from storage based on the provided keys. + * @param keys - An array of keys identifying the items to be removed. + * @returns Promise that resolves when the operation is completed. + */ + removeMany>(keys: K[]): Promise; + + /** + * Clears all the data from the storage. + * @returns Promise that resolves when the operation is completed. + */ + clear(): Promise; + + /** + * Represents the extension for providing additional functionality + * beyond the standard storage interface. + * See {@link StorageExtension} for more details. + */ + ext: E; +} diff --git a/packages/api/src/StorageExtension.ts b/packages/api/src/StorageExtension.ts new file mode 100644 index 00000000..55a03bb9 --- /dev/null +++ b/packages/api/src/StorageExtension.ts @@ -0,0 +1,7 @@ +/** + * The StorageExtension type serves as a means to extend the functionalities of the + * core interface beyond its operations. It acts as a placeholder for implementing + * additional methods. + */ +// eslint-disable-next-line @typescript-eslint/ban-types +export type StorageExtension = {}; diff --git a/packages/api/src/StorageModel.ts b/packages/api/src/StorageModel.ts new file mode 100644 index 00000000..5f35b115 --- /dev/null +++ b/packages/api/src/StorageModel.ts @@ -0,0 +1,13 @@ +/** + * A type used to define the structure and shape of the data to be stored. + */ +export type StorageModel< + T extends Record | unknown = unknown +> = { + [K in keyof T]: NonNullable | null; +}; + +/** + * A utility type to extract key. + */ +export type StorageKeys = keyof T; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts new file mode 100644 index 00000000..1c1405b8 --- /dev/null +++ b/packages/api/src/index.ts @@ -0,0 +1,3 @@ +export type { AsyncStorage } from "./AsyncStorage"; +export type { StorageExtension } from "./StorageExtension"; +export type { StorageKeys, StorageModel } from "./StorageModel"; diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json new file mode 100644 index 00000000..0d50e36e --- /dev/null +++ b/packages/api/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../.config/tsconfig.base.json", + "compilerOptions": { + "types": ["jest"] + }, + "include": ["example", "src"] +} diff --git a/packages/core/.eslintrc b/packages/core/.eslintrc deleted file mode 100644 index 3178779f..00000000 --- a/packages/core/.eslintrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../.config/.eslintrc" -} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts deleted file mode 100644 index df7e5ecd..00000000 --- a/packages/core/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -function double(i: number) { - return i * i; -} - -double(6); diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json deleted file mode 100644 index aff25780..00000000 --- a/packages/core/tsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "../../.config/tsconfig.base.json", - "include": ["./src/**/*"] -} diff --git a/packages/default-storage-backend/.eslintrc b/packages/default-storage-backend/.eslintrc deleted file mode 100644 index 610f6bae..00000000 --- a/packages/default-storage-backend/.eslintrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": [ - "../../.config/.eslintrc", - "plugin:wdio/recommended" - ], - "plugins": ["wdio"], - "rules": { - "dot-notation": "off" - } -} diff --git a/packages/default-storage-backend/android/build.gradle b/packages/default-storage-backend/android/build.gradle deleted file mode 100644 index 9f2c0cfd..00000000 --- a/packages/default-storage-backend/android/build.gradle +++ /dev/null @@ -1,185 +0,0 @@ -import java.nio.file.Paths - -def resolveModulePath(packageName) { - def basePath = rootDir.toPath().normalize() - - // Node's module resolution algorithm searches up to the root directory, - // after which the base path will be null - while (basePath) { - def candidatePath = Paths.get(basePath.toString(), 'node_modules', packageName) - if (candidatePath.toFile().exists()) { - return candidatePath.toString() - } - - basePath = basePath.getParent() - } - - return null -} - -def safeExtGet(prop, fallback) { - rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback -} - -def getFlagOrDefault(flagName, defaultValue) { - rootProject.hasProperty(flagName) ? rootProject.properties[flagName] == "true" : defaultValue -} - -def getVersionOrDefault(String flagName, String defaultVersion) { - rootProject.hasProperty(flagName) ? rootProject.properties[flagName] : defaultVersion -} - -def isNewArchitectureEnabled() { - // To opt-in for the New Architecture, you can either: - // - Set `newArchEnabled` to true inside the `gradle.properties` file - // - Invoke gradle with `-newArchEnabled=true` - // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true` - return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" -} - -configurations { - compileClasspath -} - -buildscript { - // kotlin version is dictated by rootProject extension or property in gradle.properties - ext.asyncStorageKtVersion = rootProject.ext.has('kotlinVersion') - ? rootProject.ext['kotlinVersion'] - : rootProject.hasProperty('AsyncStorage_kotlinVersion') - ? rootProject.properties['AsyncStorage_kotlinVersion'] - : '1.8.10' - - repositories { - mavenCentral() - google() - } - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$asyncStorageKtVersion" - } -} - -// AsyncStorage has default size of 6MB. -// This is a sane limit to protect the user from the app storing too much data in the database. -// This also protects the database from filling up the disk cache and becoming malformed. -// If you really need bigger size, please keep in mind the potential consequences. -long dbSizeInMB = 6L -def newDbSize = rootProject.properties['AsyncStorage_db_size_in_MB'] -if (newDbSize != null && newDbSize.isLong()) { - dbSizeInMB = newDbSize.toLong() -} - -// Instead of reusing AsyncTask thread pool, AsyncStorage can use its own executor -def useDedicatedExecutor = getFlagOrDefault('AsyncStorage_dedicatedExecutor', false) - -// Use next storage implementation -def useNextStorage = getFlagOrDefault("AsyncStorage_useNextStorage", false) - -apply plugin: 'com.android.library' -if (useNextStorage) { - apply plugin: 'kotlin-android' - apply plugin: 'kotlin-kapt' - apply from: './testresults.gradle' -} - -if (isNewArchitectureEnabled()) { - apply plugin: "com.facebook.react" -} - -android { - def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION - if (agpVersion.tokenize('.')[0].toInteger() >= 7) { - namespace "com.reactnativecommunity.asyncstorage" - buildFeatures { - buildConfig true - } - } - - compileSdkVersion safeExtGet('compileSdkVersion', 32) - // Used to override the NDK path/version by allowing users to customize - // the NDK path/version from their root project (e.g. for M1 support) - if (rootProject.hasProperty("ndkPath")) { - ndkPath rootProject.ext.ndkPath - } - if (rootProject.hasProperty("ndkVersion")) { - ndkVersion rootProject.ext.ndkVersion - } - - - defaultConfig { - minSdkVersion safeExtGet('minSdkVersion', 23) - targetSdkVersion safeExtGet('targetSdkVersion', 32) - buildConfigField "Long", "AsyncStorage_db_size", "${dbSizeInMB}L" - buildConfigField "boolean", "AsyncStorage_useDedicatedExecutor", "${useDedicatedExecutor}" - buildConfigField "boolean", "AsyncStorage_useNextStorage", "${useNextStorage}" - } - lintOptions { - abortOnError false - } - - if (useNextStorage) { - testOptions { - unitTests { - returnDefaultValues = true - includeAndroidResources = true - } - } - } - - sourceSets.main { - java { - if (useNextStorage) { - srcDirs += 'src/kotlinPackage/java' - } else { - srcDirs += 'src/javaPackage/java' - } - - if (!isNewArchitectureEnabled()) { - srcDirs += 'src/oldarch/java' - } - } - } -} - -repositories { - maven { - // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm - url "${resolveModulePath("react-native")}/android" - } - google() - mavenCentral() -} - -dependencies { - - if (useNextStorage) { - def room_version = getVersionOrDefault('AsyncStorage_next_roomVersion', '2.4.3') - def coroutines_version = "1.6.4" - def coroutinesTest_version = "1.6.4" - // if we don't provide explicit dependency on reflection, kotlin plugin - // would add one automatically, probably a version that is not compatible with - // used kotlin - def kotlinReflect_version = project.ext.asyncStorageKtVersion - def junit_version = "4.13.2" - def robolectric_version = "4.7.3" - def truth_version = "1.1.3" - def androidxtest_version = "1.4.0" - def androidtest_junit_version = "1.1.3" - - implementation "androidx.room:room-runtime:$room_version" - implementation "androidx.room:room-ktx:$room_version" - implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinReflect_version" - - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" - kapt "androidx.room:room-compiler:$room_version" - - testImplementation "junit:junit:$junit_version" - testImplementation "androidx.test:runner:$androidxtest_version" - testImplementation "androidx.test:rules:$androidxtest_version" - testImplementation "androidx.test.ext:junit:$androidtest_junit_version" - testImplementation "org.robolectric:robolectric:$robolectric_version" - testImplementation "com.google.truth:truth:$truth_version" - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesTest_version" - } - - implementation 'com.facebook.react:react-native:+' // from node_modules -} diff --git a/packages/default-storage-backend/babel.config.js b/packages/default-storage-backend/babel.config.js deleted file mode 100644 index f842b77f..00000000 --- a/packages/default-storage-backend/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: ['module:metro-react-native-babel-preset'], -}; diff --git a/packages/default-storage-backend/src/NativeAsyncStorageModule.ts b/packages/default-storage-backend/src/NativeAsyncStorageModule.ts deleted file mode 100644 index 699cc553..00000000 --- a/packages/default-storage-backend/src/NativeAsyncStorageModule.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { TurboModuleRegistry, TurboModule } from "react-native"; - -export interface Spec extends TurboModule { - multiGet: ( - keys: string[], - callback: (error?: Object[], result?: [string, string][]) => void - ) => void; - multiSet: ( - kvPairs: [string, string][], - callback: (error?: Object[]) => void - ) => void; - multiRemove: ( - keys: readonly string[], - callback: (error?: Object[]) => void - ) => void; - multiMerge: ( - kvPairs: [string, string][], - callback: (error?: Object[]) => void - ) => void; - getAllKeys: ( - callback: (error?: Object[], result?: [string, string][]) => void - ) => void; - clear: (callback: (error?: Object[]) => void) => void; -} - -export default TurboModuleRegistry.get("RNCAsyncStorage"); diff --git a/packages/default-storage-backend/webpack.config.js b/packages/default-storage-backend/webpack.config.js deleted file mode 100644 index dca3d8d6..00000000 --- a/packages/default-storage-backend/webpack.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const createExpoWebpackConfigAsync = require('@expo/webpack-config'); - -module.exports = async function (env, argv) { - const config = await createExpoWebpackConfigAsync(env, argv); - config.resolve.alias['@react-native-async-storage/async-storage'] = __dirname; - return config; -}; diff --git a/packages/default-storage-backend/.ccache/ccache.conf b/packages/default-storage/.ccache/ccache.conf similarity index 100% rename from packages/default-storage-backend/.ccache/ccache.conf rename to packages/default-storage/.ccache/ccache.conf diff --git a/packages/default-storage-backend/.gitignore b/packages/default-storage/.gitignore similarity index 100% rename from packages/default-storage-backend/.gitignore rename to packages/default-storage/.gitignore diff --git a/packages/default-storage-backend/.npmignore b/packages/default-storage/.npmignore similarity index 100% rename from packages/default-storage-backend/.npmignore rename to packages/default-storage/.npmignore diff --git a/packages/default-storage-backend/CHANGELOG.md b/packages/default-storage/CHANGELOG.md similarity index 85% rename from packages/default-storage-backend/CHANGELOG.md rename to packages/default-storage/CHANGELOG.md index 8700f1a0..2f12856d 100644 --- a/packages/default-storage-backend/CHANGELOG.md +++ b/packages/default-storage/CHANGELOG.md @@ -1,3 +1,43 @@ +# [1.21.0](https://github.com/react-native-async-storage/async-storage/compare/v1.20.0...v1.21.0) (2023-11-29) + + +### Bug Fixes + +* missing `kotlinVersion` property ([#1042](https://github.com/react-native-async-storage/async-storage/issues/1042)) ([cff03e8](https://github.com/react-native-async-storage/async-storage/commit/cff03e8fa76e268002017e18349a0b462547df87)) + + +### Features + +* **windows:** bump minimum target platform version to 10.0.17763.0 ([#1031](https://github.com/react-native-async-storage/async-storage/issues/1031)) ([5682e8c](https://github.com/react-native-async-storage/async-storage/commit/5682e8ce2548ff423d978b0317e1b70de7a8a76f)) + +# [1.20.0](https://github.com/react-native-async-storage/async-storage/compare/v1.19.8...v1.20.0) (2023-11-28) + + +### Features + +* **android:** Bump versions for Next storage ([#1028](https://github.com/react-native-async-storage/async-storage/issues/1028)) ([14489a7](https://github.com/react-native-async-storage/async-storage/commit/14489a79fbb3d6fc31171e82a826cb4df6317cb8)) + +## [1.19.8](https://github.com/react-native-async-storage/async-storage/compare/v1.19.7...v1.19.8) (2023-11-22) + + +### Bug Fixes + +* add missing `README.md` (merge) ([#1032](https://github.com/react-native-async-storage/async-storage/issues/1032)) ([f974728](https://github.com/react-native-async-storage/async-storage/commit/f974728b7bee9911a32eaa0b8215c7c894436ea5)) + +## [1.19.7](https://github.com/react-native-async-storage/async-storage/compare/v1.19.6...v1.19.7) (2023-11-22) + + +### Bug Fixes + +* add missing `README.md` ([#1030](https://github.com/react-native-async-storage/async-storage/issues/1030)) ([821eb01](https://github.com/react-native-async-storage/async-storage/commit/821eb01b1a7326db592e80018246cdc662c6dc5d)) + +## [1.19.6](https://github.com/react-native-async-storage/async-storage/compare/v1.19.5...v1.19.6) (2023-11-21) + + +### Bug Fixes + +* widen supported version range ([#1029](https://github.com/react-native-async-storage/async-storage/issues/1029)) ([921f24a](https://github.com/react-native-async-storage/async-storage/commit/921f24a82597af6e88d5be7ccf2cceccc70da554)) + ## [1.19.5](https://github.com/react-native-async-storage/async-storage/compare/v1.19.4...v1.19.5) (2023-11-10) diff --git a/packages/default-storage-backend/LICENSE b/packages/default-storage/LICENSE similarity index 100% rename from packages/default-storage-backend/LICENSE rename to packages/default-storage/LICENSE diff --git a/packages/default-storage/README.md b/packages/default-storage/README.md new file mode 100644 index 00000000..b1776f0d --- /dev/null +++ b/packages/default-storage/README.md @@ -0,0 +1,51 @@ +# React Native Async Storage + +An asynchronous, unencrypted, persistent, key-value storage system for React +Native. + +## Supported platforms + +- Android +- iOS +- [macOS](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.8.1) +- [Web](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.9.0) +- [Windows](https://github.com/react-native-async-storage/async-storage/releases/tag/v1.10.0) + +## Getting Started + +Head over to the +[documentation](https://react-native-async-storage.github.io/async-storage/docs/install) +to learn more. + +## Running E2E locally + +### Android + +1. Create and start Android Emulator with Play services, API level 29 +2. Build app and run tests + ```shell + yarn bundle:android + yarn build:e2e:android + yarn test:e2e:android + ``` + +### iOS + +1. Create and start iPhone 14 simulator with iOS version 16.4 +2. Build app and run tests + ```shell + yarn bundle:ios + yarn build:e2e:ios + yarn test:e2e:ios + ``` + +## Contribution + +Pull requests are welcome. Please open an issue first to discuss what you would +like to change. + +See the [CONTRIBUTING](.github/CONTRIBUTING.md) file for more information. + +## License + +MIT diff --git a/packages/default-storage-backend/RNCAsyncStorage.podspec b/packages/default-storage/RNCAsyncStorage.podspec similarity index 100% rename from packages/default-storage-backend/RNCAsyncStorage.podspec rename to packages/default-storage/RNCAsyncStorage.podspec diff --git a/packages/default-storage/android/build.gradle b/packages/default-storage/android/build.gradle new file mode 100644 index 00000000..f620adb4 --- /dev/null +++ b/packages/default-storage/android/build.gradle @@ -0,0 +1,123 @@ +configurations { + compileClasspath +} + +buildscript { + apply from: "config.gradle" + def kotlinVersion = ext.AsyncStorageConfig.kotlinVersion + def kspVersion = ext.AsyncStorageConfig.kspVersion + + repositories { + mavenCentral() + google() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" + classpath "com.google.devtools.ksp:symbol-processing-gradle-plugin:$kspVersion" + } +} + + +apply plugin: 'com.android.library' +apply from: 'config.gradle' + +boolean isNewArchitectureEnabled = ext.AsyncStorageConfig.isNewArchitectureEnabled +boolean useNextStorage = ext.AsyncStorageConfig.useNextStorage + +logger.info("[AsyncStorage] Config used: {}", ext.AsyncStorageConfig) + +if (useNextStorage) { + apply plugin: 'com.google.devtools.ksp' + apply plugin: 'kotlin-android' + apply from: './testresults.gradle' +} + +if (isNewArchitectureEnabled) { + apply plugin: "com.facebook.react" +} + +android { + def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION + if (agpVersion.tokenize('.')[0].toInteger() >= 7) { + namespace "com.reactnativecommunity.asyncstorage" + buildFeatures { + buildConfig true + } + } + + compileSdkVersion project.ext.AsyncStorageConfig.compileSdkVersion + // Used to override the NDK path/version by allowing users to customize + // the NDK path/version from their root project (e.g. for M1 support) + if (rootProject.hasProperty("ndkPath")) { + ndkPath rootProject.ext.ndkPath + } + if (rootProject.hasProperty("ndkVersion")) { + ndkVersion rootProject.ext.ndkVersion + } + + + defaultConfig { + minSdkVersion project.ext.AsyncStorageConfig.minSdkVersion + targetSdkVersion project.ext.AsyncStorageConfig.targetSdkVersion + buildConfigField "Long", "AsyncStorage_db_size", "${project.ext.AsyncStorageConfig.databaseSizeMB}L" + buildConfigField "boolean", "AsyncStorage_useDedicatedExecutor", "${project.ext.AsyncStorageConfig.useDedicatedExecutor}" + buildConfigField "boolean", "AsyncStorage_useNextStorage", "${useNextStorage}" + } + lintOptions { + abortOnError false + } + + if (useNextStorage) { + testOptions { + unitTests { + returnDefaultValues = true + includeAndroidResources = true + } + } + } + + sourceSets.main { + java { + if (useNextStorage) { + srcDirs += 'src/kotlinPackage/java' + } else { + srcDirs += 'src/javaPackage/java' + } + + if (!isNewArchitectureEnabled) { + srcDirs += 'src/oldarch/java' + } + } + } +} + +repositories { + maven { + // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm + url "${project.ext.resolveModulePath("react-native")}/android" + } + google() + mavenCentral() +} + +dependencies { + if (useNextStorage) { + def room_version = project.ext.AsyncStorageConfig.roomVersion + + implementation "androidx.room:room-runtime:$room_version" + implementation "androidx.room:room-ktx:$room_version" + ksp "androidx.room:room-compiler:$room_version" + + implementation project.ext.AsyncStorageLibs.coroutines + + testImplementation project.ext.AsyncStorageLibs.testCoroutines + testImplementation project.ext.AsyncStorageLibs.testJunit + testImplementation project.ext.AsyncStorageLibs.testExtJunit + testImplementation project.ext.AsyncStorageLibs.testRunner + testImplementation project.ext.AsyncStorageLibs.testRules + testImplementation project.ext.AsyncStorageLibs.testRobolectric + testImplementation project.ext.AsyncStorageLibs.testTruth + } + + implementation 'com.facebook.react:react-native:+' // from node_modules +} \ No newline at end of file diff --git a/packages/default-storage/android/config.gradle b/packages/default-storage/android/config.gradle new file mode 100644 index 00000000..c8971b72 --- /dev/null +++ b/packages/default-storage/android/config.gradle @@ -0,0 +1,121 @@ +import java.nio.file.Paths + +def DEFAULT_KOTLIN_VERSION = "1.9.20" +def DEFAULT_ROOM_VERSION = "2.4.3" + +def kotlinVersion = getKotlinVersion(DEFAULT_KOTLIN_VERSION) + +project.ext.AsyncStorageConfig = [ + kotlinVersion : kotlinVersion, + kspVersion : getKspVersion(kotlinVersion), + roomVersion : getPropertyOfDefault('AsyncStorage_next_roomVersion', DEFAULT_ROOM_VERSION), + minSdkVersion : safeExtGet('minSdkVersion', 23), + targetSdkVersion : safeExtGet('targetSdkVersion', 32), + compileSdkVersion : safeExtGet('compileSdkVersion', 32), + useNextStorage : getFlagOrDefault("AsyncStorage_useNextStorage", false), + databaseSizeMB : getDatabaseSize(), + isNewArchitectureEnabled: isNewArchitectureEnabled(), + useDedicatedExecutor : getFlagOrDefault('AsyncStorage_dedicatedExecutor', false), +] + +project.ext.AsyncStorageLibs = [ + coroutines : "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3", + testCoroutines : "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3", + testJunit : "junit:junit:4.13.2", + testRunner : "androidx.test:runner:1.4.0", + testRules : "androidx.test:rules:1.4.0", + testExtJunit : "androidx.test.ext:junit:1.1.3", + testRobolectric: "org.robolectric:robolectric:4.11.1", + testTruth : "com.google.truth:truth:1.1.3", +] + + +def getKotlinVersion(String defaultVersion) { + return rootProject.ext.has('kotlinVersion') + ? rootProject.ext['kotlinVersion'] + : rootProject.hasProperty('AsyncStorage_kotlinVersion') + ? rootProject.properties['AsyncStorage_kotlinVersion'] + : defaultVersion +} + +def isNewArchitectureEnabled() { + // To opt-in for the New Architecture, you can either: + // - Set `newArchEnabled` to true inside the `gradle.properties` file + // - Invoke gradle with `-newArchEnabled=true` + // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true` + return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" +} + +String getKspVersion(String kotlinVersion) { + + String overriddenKspVersion = getPropertyOfDefault("AsyncStorage_next_kspVersion", null) + if (overriddenKspVersion != null) { + return overriddenKspVersion + } + // https://github.com/google/ksp/releases + def kspVersions = [ + "1.9.20-1.0.14", + "1.9.10-1.0.13", + "1.9.0-1.0.13", + "1.8.22-1.0.11", + "1.8.21-1.0.11", + "1.8.20-1.0.11", + "1.8.10-1.0.9", + "1.8.0-1.0.9", + "1.7.22-1.0.8", + "1.7.21-1.0.8", + "1.7.20-1.0.8", + "1.7.10-1.0.6", + "1.7.0-1.0.6", + "1.6.21-1.0.6", + "1.6.20-1.0.5", + "1.6.10-1.0.4", + "1.6.0-1.0.2", + "1.5.31-1.0.1", + "1.5.30-1.0.0", + ] + + return kspVersions.find { it.startsWith(kotlinVersion) } ?: kspVersions.first() +} + +// AsyncStorage has default size of 6MB. +// This is a sane limit to protect the user from the app storing too much data in the database. +// This also protects the database from filling up the disk cache and becoming malformed. +// If you really need bigger size, please keep in mind the potential consequences. +long getDatabaseSize() { + long dbSizeInMB = 6L + def newDbSize = getPropertyOfDefault('AsyncStorage_db_size_in_MB', null) + if (newDbSize != null && newDbSize.isLong()) { + dbSizeInMB = newDbSize.toLong() + } + return dbSizeInMB +} + +def safeExtGet(prop, fallback) { + rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback +} + +def getFlagOrDefault(flagName, defaultValue) { + rootProject.hasProperty(flagName) ? rootProject.properties[flagName] == "true" : defaultValue +} + +def getPropertyOfDefault(String flagName, String defaultVersion) { + rootProject.hasProperty(flagName) ? rootProject.properties[flagName] : defaultVersion +} + +ext.resolveModulePath = { packageName -> + def basePath = rootDir.toPath().normalize() + + // Node's module resolution algorithm searches up to the root directory, + // after which the base path will be null + while (basePath) { + def candidatePath = Paths.get(basePath.toString(), 'node_modules', packageName) + if (candidatePath.toFile().exists()) { + return candidatePath.toString() + } + + basePath = basePath.getParent() + } + + return null +} diff --git a/packages/default-storage-backend/android/gradle.properties b/packages/default-storage/android/gradle.properties similarity index 100% rename from packages/default-storage-backend/android/gradle.properties rename to packages/default-storage/android/gradle.properties diff --git a/packages/default-storage-backend/android/src/javaPackage/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.java b/packages/default-storage/android/src/javaPackage/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.java similarity index 100% rename from packages/default-storage-backend/android/src/javaPackage/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.java rename to packages/default-storage/android/src/javaPackage/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.java diff --git a/packages/default-storage-backend/android/src/kotlinPackage/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.kt b/packages/default-storage/android/src/kotlinPackage/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.kt similarity index 100% rename from packages/default-storage-backend/android/src/kotlinPackage/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.kt rename to packages/default-storage/android/src/kotlinPackage/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.kt diff --git a/packages/default-storage-backend/android/src/main/AndroidManifest.xml b/packages/default-storage/android/src/main/AndroidManifest.xml similarity index 100% rename from packages/default-storage-backend/android/src/main/AndroidManifest.xml rename to packages/default-storage/android/src/main/AndroidManifest.xml diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncLocalStorageUtil.java b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncLocalStorageUtil.java similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncLocalStorageUtil.java rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncLocalStorageUtil.java diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageErrorUtil.java b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageErrorUtil.java similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageErrorUtil.java rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageErrorUtil.java diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageExpoMigration.java b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageExpoMigration.java similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageExpoMigration.java rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageExpoMigration.java diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/ReactDatabaseSupplier.java diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/SerialExecutor.java b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/SerialExecutor.java similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/SerialExecutor.java rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/SerialExecutor.java diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpers.kt b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpers.kt similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpers.kt rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpers.kt diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ErrorHelpers.kt b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ErrorHelpers.kt similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ErrorHelpers.kt rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/ErrorHelpers.kt diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageModule.kt b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageModule.kt similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageModule.kt rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageModule.kt diff --git a/packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageSupplier.kt b/packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageSupplier.kt similarity index 100% rename from packages/default-storage-backend/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageSupplier.kt rename to packages/default-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/next/StorageSupplier.kt diff --git a/packages/default-storage-backend/android/src/oldarch/java/com/reactnativecommunity/asyncstorage/NativeAsyncStorageModuleSpec.java b/packages/default-storage/android/src/oldarch/java/com/reactnativecommunity/asyncstorage/NativeAsyncStorageModuleSpec.java similarity index 100% rename from packages/default-storage-backend/android/src/oldarch/java/com/reactnativecommunity/asyncstorage/NativeAsyncStorageModuleSpec.java rename to packages/default-storage/android/src/oldarch/java/com/reactnativecommunity/asyncstorage/NativeAsyncStorageModuleSpec.java diff --git a/packages/default-storage-backend/android/src/test/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpersTest.kt b/packages/default-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpersTest.kt similarity index 100% rename from packages/default-storage-backend/android/src/test/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpersTest.kt rename to packages/default-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/ArgumentHelpersTest.kt diff --git a/packages/default-storage-backend/android/src/test/java/com/reactnativecommunity/asyncstorage/next/StorageTest.kt b/packages/default-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/StorageTest.kt similarity index 100% rename from packages/default-storage-backend/android/src/test/java/com/reactnativecommunity/asyncstorage/next/StorageTest.kt rename to packages/default-storage/android/src/test/java/com/reactnativecommunity/asyncstorage/next/StorageTest.kt diff --git a/packages/default-storage-backend/android/testresults.gradle b/packages/default-storage/android/testresults.gradle similarity index 100% rename from packages/default-storage-backend/android/testresults.gradle rename to packages/default-storage/android/testresults.gradle diff --git a/packages/default-storage-backend/app.json b/packages/default-storage/app.json similarity index 100% rename from packages/default-storage-backend/app.json rename to packages/default-storage/app.json diff --git a/packages/default-storage/babel.config.js b/packages/default-storage/babel.config.js new file mode 100644 index 00000000..5ae49c32 --- /dev/null +++ b/packages/default-storage/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ["module:metro-react-native-babel-preset"], +}; diff --git a/packages/default-storage/eslint.config.js b/packages/default-storage/eslint.config.js new file mode 100644 index 00000000..c1a16e2d --- /dev/null +++ b/packages/default-storage/eslint.config.js @@ -0,0 +1 @@ +module.exports = require("@react-native-async-storage/eslint-config/recommended-wdio"); diff --git a/packages/default-storage-backend/example/.gitignore b/packages/default-storage/example/.gitignore similarity index 97% rename from packages/default-storage-backend/example/.gitignore rename to packages/default-storage/example/.gitignore index ffa7fa18..aa4aed32 100644 --- a/packages/default-storage-backend/example/.gitignore +++ b/packages/default-storage/example/.gitignore @@ -29,6 +29,7 @@ build/ .gradle local.properties *.iml +!android/gradlew* # Visual Studio # diff --git a/packages/default-storage-backend/example/App.tsx b/packages/default-storage/example/App.tsx similarity index 81% rename from packages/default-storage-backend/example/App.tsx rename to packages/default-storage/example/App.tsx index 5a17df16..706dfc0f 100644 --- a/packages/default-storage-backend/example/App.tsx +++ b/packages/default-storage/example/App.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useState } from "react"; import { Button, Keyboard, @@ -14,11 +14,11 @@ import { Text, TouchableOpacity, View, -} from 'react-native'; -import Basic from './examples/Basic'; -import Functional from './examples/Functional'; -import GetSetClear from './examples/GetSetClear'; -import MergeItem from './examples/MergeItem'; +} from "react-native"; +import Basic from "./examples/Basic"; +import Functional from "./examples/Functional"; +import GetSetClear from "./examples/GetSetClear"; +import MergeItem from "./examples/MergeItem"; const SCREENS = { Functional, @@ -86,13 +86,13 @@ export default function App(): JSX.Element { const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#F5FCFF', + backgroundColor: "#F5FCFF", padding: 8, }, exampleContainer: { padding: 4, - backgroundColor: '#FFF', - borderColor: '#EEE', + backgroundColor: "#FFF", + borderColor: "#EEE", borderTopWidth: 1, borderBottomWidth: 1, flex: 1, @@ -101,11 +101,11 @@ const styles = StyleSheet.create({ fontSize: 18, }, exampleDescription: { - color: '#333333', + color: "#333333", marginBottom: 16, }, exampleInnerContainer: { - borderColor: '#EEE', + borderColor: "#EEE", borderTopWidth: 1, paddingTop: 10, flex: 1, @@ -113,17 +113,17 @@ const styles = StyleSheet.create({ restartButton: { padding: 6, borderRadius: 5, - backgroundColor: '#F3F3F3', - alignItems: 'center', - justifyContent: 'center', - alignSelf: 'flex-end', + backgroundColor: "#F3F3F3", + alignItems: "center", + justifyContent: "center", + alignSelf: "flex-end", }, closeKeyboardView: { width: 5, height: 5, }, testPickerContainer: { - flexDirection: 'row', - flexWrap: 'wrap', + flexDirection: "row", + flexWrap: "wrap", }, }); diff --git a/packages/default-storage-backend/example/AsyncStorageExample.podspec b/packages/default-storage/example/AsyncStorageExample.podspec similarity index 100% rename from packages/default-storage-backend/example/AsyncStorageExample.podspec rename to packages/default-storage/example/AsyncStorageExample.podspec diff --git a/packages/default-storage-backend/example/__tests__/android.conf.ts b/packages/default-storage/example/__tests__/android.conf.ts similarity index 100% rename from packages/default-storage-backend/example/__tests__/android.conf.ts rename to packages/default-storage/example/__tests__/android.conf.ts diff --git a/packages/default-storage-backend/example/__tests__/asyncstorage.spec.ts b/packages/default-storage/example/__tests__/asyncstorage.spec.ts similarity index 100% rename from packages/default-storage-backend/example/__tests__/asyncstorage.spec.ts rename to packages/default-storage/example/__tests__/asyncstorage.spec.ts diff --git a/packages/default-storage-backend/example/__tests__/commands.ts b/packages/default-storage/example/__tests__/commands.ts similarity index 100% rename from packages/default-storage-backend/example/__tests__/commands.ts rename to packages/default-storage/example/__tests__/commands.ts diff --git a/packages/default-storage-backend/example/__tests__/common.conf.ts b/packages/default-storage/example/__tests__/common.conf.ts similarity index 100% rename from packages/default-storage-backend/example/__tests__/common.conf.ts rename to packages/default-storage/example/__tests__/common.conf.ts diff --git a/packages/default-storage-backend/example/__tests__/ios.conf.ts b/packages/default-storage/example/__tests__/ios.conf.ts similarity index 100% rename from packages/default-storage-backend/example/__tests__/ios.conf.ts rename to packages/default-storage/example/__tests__/ios.conf.ts diff --git a/packages/default-storage-backend/example/android/build.gradle b/packages/default-storage/example/android/build.gradle similarity index 100% rename from packages/default-storage-backend/example/android/build.gradle rename to packages/default-storage/example/android/build.gradle diff --git a/packages/default-storage-backend/example/android/debug.keystore b/packages/default-storage/example/android/debug.keystore similarity index 100% rename from packages/default-storage-backend/example/android/debug.keystore rename to packages/default-storage/example/android/debug.keystore diff --git a/packages/default-storage-backend/example/android/gradle.properties b/packages/default-storage/example/android/gradle.properties similarity index 98% rename from packages/default-storage-backend/example/android/gradle.properties rename to packages/default-storage/example/android/gradle.properties index a2bce5df..f73e007e 100644 --- a/packages/default-storage-backend/example/android/gradle.properties +++ b/packages/default-storage/example/android/gradle.properties @@ -42,7 +42,7 @@ newArchEnabled=true #ANDROID_NDK_VERSION=21.4.7075529 # Version of Kotlin to build against. -KOTLIN_VERSION=1.8.10 +KOTLIN_VERSION=1.9.20 # This is an example of how you can change default DB size (6MB) to 10MB #AsyncStorage_db_size_in_MB=10 diff --git a/packages/default-storage-backend/example/android/gradle/wrapper/gradle-wrapper.jar b/packages/default-storage/example/android/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from packages/default-storage-backend/example/android/gradle/wrapper/gradle-wrapper.jar rename to packages/default-storage/example/android/gradle/wrapper/gradle-wrapper.jar diff --git a/packages/default-storage-backend/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/default-storage/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from packages/default-storage-backend/example/android/gradle/wrapper/gradle-wrapper.properties rename to packages/default-storage/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/packages/default-storage-backend/example/android/gradlew b/packages/default-storage/example/android/gradlew similarity index 100% rename from packages/default-storage-backend/example/android/gradlew rename to packages/default-storage/example/android/gradlew diff --git a/packages/default-storage-backend/example/android/gradlew.bat b/packages/default-storage/example/android/gradlew.bat similarity index 100% rename from packages/default-storage-backend/example/android/gradlew.bat rename to packages/default-storage/example/android/gradlew.bat diff --git a/packages/default-storage-backend/example/android/settings.gradle b/packages/default-storage/example/android/settings.gradle similarity index 100% rename from packages/default-storage-backend/example/android/settings.gradle rename to packages/default-storage/example/android/settings.gradle diff --git a/packages/default-storage-backend/example/app.json b/packages/default-storage/example/app.json similarity index 100% rename from packages/default-storage-backend/example/app.json rename to packages/default-storage/example/app.json diff --git a/packages/default-storage-backend/example/examples/Basic.tsx b/packages/default-storage/example/examples/Basic.tsx similarity index 78% rename from packages/default-storage-backend/example/examples/Basic.tsx rename to packages/default-storage/example/examples/Basic.tsx index f3ef0b70..c605d44c 100644 --- a/packages/default-storage-backend/example/examples/Basic.tsx +++ b/packages/default-storage/example/examples/Basic.tsx @@ -1,6 +1,6 @@ -// @ts-ignore -import AsyncStorage from '@react-native-async-storage/async-storage'; -import React from 'react'; +// @ts-expect-error cannot find module +import AsyncStorage from "@react-native-async-storage/async-storage"; +import React from "react"; import { Button, ScrollView, @@ -8,7 +8,7 @@ import { Text, TextInput, View, -} from 'react-native'; +} from "react-native"; type DataType = { deeper?: DataType; @@ -17,45 +17,45 @@ type DataType = { }; const mergeInitialValue = { - initial: 'keep', - override1: 'override', + initial: "keep", + override1: "override", nested: { - nestedValue: 'keep', - override2: 'override', + nestedValue: "keep", + override2: "override", deeper: { - deeperValue: 'keep', - override3: 'override', + deeperValue: "keep", + override3: "override", }, }, }; function hasMessage(e: unknown): e is { message: string } { - return Boolean(typeof e === 'object' && e && 'message' in e); + return Boolean(typeof e === "object" && e && "message" in e); } function NextExample() { const [keys, setKeys] = React.useState([]); - const [error, setError] = React.useState(''); - const [inputKey, setInputKey] = React.useState(''); - const [inputValue, setInputValue] = React.useState(''); + const [error, setError] = React.useState(""); + const [inputKey, setInputKey] = React.useState(""); + const [inputValue, setInputValue] = React.useState(""); const [value, setValue] = React.useState(); const [mergedValue, setMergedValue] = React.useState(); const [overrideValue, setOverrideValue] = React.useState({ - override1: '', - override2: '', - override3: '', + override1: "", + override2: "", + override3: "", }); function runWithCatch(block: () => Promise) { return async () => { try { - setError(''); + setError(""); await block(); } catch (e) { if (hasMessage(e)) { - setError('Caught error: ' + (e.message || e)); + setError("Caught error: " + (e.message || e)); } else { - setError('Unknown error: ' + e); + setError("Unknown error: " + e); } } }; @@ -76,15 +76,15 @@ function NextExample() { } async function crashValueType() { - await AsyncStorage.setItem('CRASH', 435345); + await AsyncStorage.setItem("CRASH", 435345); } async function crashKeyNull() { - await AsyncStorage.setItem(null, '435345'); + await AsyncStorage.setItem(null, "435345"); } async function crashKeyNotString() { - await AsyncStorage.setItem(432, '435345'); + await AsyncStorage.setItem(432, "435345"); } async function removeValue() { @@ -96,13 +96,13 @@ function NextExample() { } async function resetMergedValue() { - await AsyncStorage.setItem('MERGER', JSON.stringify(mergeInitialValue)); - const saved = await AsyncStorage.getItem('MERGER'); + await AsyncStorage.setItem("MERGER", JSON.stringify(mergeInitialValue)); + const saved = await AsyncStorage.getItem("MERGER"); setMergedValue(JSON.parse(saved)); } async function readMergedValue() { - const saved = await AsyncStorage.getItem('MERGER'); + const saved = await AsyncStorage.getItem("MERGER"); setMergedValue(saved ? JSON.parse(saved) : {}); } @@ -112,7 +112,7 @@ function NextExample() { // leave out empty inputs const toMerge: DataType = {}; if (override1) { - toMerge['override1'] = override1; + toMerge["override1"] = override1; } if (override2) { toMerge.nested = { @@ -132,7 +132,7 @@ function NextExample() { }; } } - await AsyncStorage.mergeItem('MERGER', JSON.stringify(toMerge)); + await AsyncStorage.mergeItem("MERGER", JSON.stringify(toMerge)); } return ( @@ -226,7 +226,7 @@ function NextExample() {