diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 902911a..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,98 +0,0 @@ -version: 2.1 - -executors: - default: - docker: - - image: circleci/node:16 - working_directory: ~/project - -commands: - attach_project: - steps: - - attach_workspace: - at: ~/project - -jobs: - install-dependencies: - executor: default - steps: - - checkout - - attach_project - - restore_cache: - keys: - - dependencies-{{ checksum "package.json" }} - - dependencies- - - restore_cache: - keys: - - dependencies-example-{{ checksum "example/package.json" }} - - dependencies-example- - - run: - name: Install dependencies - command: | - yarn install --cwd example --frozen-lockfile - yarn install --frozen-lockfile - - save_cache: - key: dependencies-{{ checksum "package.json" }} - paths: node_modules - - save_cache: - key: dependencies-example-{{ checksum "example/package.json" }} - paths: example/node_modules - - persist_to_workspace: - root: . - paths: . - - lint: - executor: default - steps: - - attach_project - - run: - name: Lint files - command: | - yarn lint - - typescript: - executor: default - steps: - - attach_project - - run: - name: Typecheck files - command: | - yarn typescript - - unit-tests: - executor: default - steps: - - attach_project - - run: - name: Run unit tests - command: | - yarn test --coverage - - store_artifacts: - path: coverage - destination: coverage - - build-package: - executor: default - steps: - - attach_project - - run: - name: Build package - command: | - yarn prepare - -workflows: - build-and-test: - jobs: - - install-dependencies - - lint: - requires: - - install-dependencies - - typescript: - requires: - - install-dependencies - - unit-tests: - requires: - - install-dependencies - - build-package: - requires: - - install-dependencies diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 62434d1..c17d659 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,12 +1,13 @@ # These are supported funding model platforms +custom: ["https://www.paypal.com/paypalme/jairajjangle001/usd", "https://github.com/JairajJangle/OpenCV-Catalogue/blob/master/.github/Jairaj_Jangle_Google_Pay_UPI_QR_Code.jpg"] +liberapay: FutureJJ +ko_fi: futurejj + github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username -ko_fi: futurejj tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: FutureJJ issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username -custom: ["https://www.paypal.com/paypalme/jairajjangle001/usd"] \ No newline at end of file diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000..d92d29a --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,78 @@ +name: Setup +description: Setup Node.js and install dependencies + +runs: + using: composite + steps: + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + + # Create a minimal .yarnrc.yml without any plugin references + - name: Create minimal Yarn config + run: | + cat > .yarnrc.yml << EOF + nodeLinker: node-modules + nmHoistingLimits: workspaces + EOF + shell: bash + + # Setup Corepack for proper Yarn version management + - name: Setup Corepack and Yarn + run: | + corepack enable + corepack prepare yarn@3.6.1 --activate + shell: bash + + # Create required directory and install plugins + - name: Setup plugins + run: | + mkdir -p .yarn/plugins + yarn plugin import @yarnpkg/plugin-interactive-tools + yarn plugin import @yarnpkg/plugin-workspace-tools + shell: bash + + # Now update .yarnrc.yml to include the plugins + - name: Update Yarn config with plugins + run: | + cat > .yarnrc.yml << EOF + nodeLinker: node-modules + nmHoistingLimits: workspaces + + plugins: + - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs + spec: "@yarnpkg/plugin-interactive-tools" + - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs + spec: "@yarnpkg/plugin-workspace-tools" + EOF + shell: bash + + - name: Restore cache + uses: actions/cache/restore@v4 + id: yarn-cache + with: + path: | + **/node_modules + .yarn/cache + .yarn/unplugged + .yarn/install-state.gz + key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}-${{ hashFiles('**/package.json', '!node_modules/**') }} + restore-keys: | + ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} + ${{ runner.os }}-yarn- + + - name: Install dependencies + run: yarn install + shell: bash + + - name: Save cache + uses: actions/cache/save@v4 + if: steps.yarn-cache.outputs.cache-hit != 'true' + with: + path: | + **/node_modules + .yarn/cache + .yarn/unplugged + .yarn/install-state.gz + key: ${{ steps.yarn-cache.outputs.cache-primary-key || format('{0}-yarn-{1}-{2}', runner.os, hashFiles('yarn.lock'), hashFiles('**/package.json', '!node_modules/**')) }} \ No newline at end of file diff --git a/.github/assets/Jairaj_Jangle_Google_Pay_UPI_QR_Code.jpg b/.github/assets/Jairaj_Jangle_Google_Pay_UPI_QR_Code.jpg new file mode 100644 index 0000000..f47f6e2 Binary files /dev/null and b/.github/assets/Jairaj_Jangle_Google_Pay_UPI_QR_Code.jpg differ diff --git a/.github/assets/demo_app_ss.png b/.github/assets/demo_app_ss.png new file mode 100644 index 0000000..e88dcd4 Binary files /dev/null and b/.github/assets/demo_app_ss.png differ diff --git a/.github/assets/paypal_donate.png b/.github/assets/paypal_donate.png new file mode 100644 index 0000000..cd140fc Binary files /dev/null and b/.github/assets/paypal_donate.png differ diff --git a/.github/assets/upi.png b/.github/assets/upi.png new file mode 100644 index 0000000..727f3d8 Binary files /dev/null and b/.github/assets/upi.png differ diff --git a/.github/workflows/beta-release.yml b/.github/workflows/beta-release.yml new file mode 100644 index 0000000..5b5243c --- /dev/null +++ b/.github/workflows/beta-release.yml @@ -0,0 +1,115 @@ +name: Beta Release +on: + push: + branches: + - beta + pull_request: + branches: + - beta + merge_group: + types: + - checks_requested + +env: + NODE_OPTIONS: --experimental-vm-modules + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Lint files + run: yarn lint + + - name: Typecheck files + run: yarn typecheck + + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Run unit tests + run: yarn test:cov + + - name: Update Coverage Badge + # GitHub actions: default branch variable + # https://stackoverflow.com/questions/64781462/github-actions-default-branch-variable + if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + uses: we-cli/coverage-badge-action@main + + build-library: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Install missing dependencies + run: yarn add -D @ark/schema || echo "Package already installed or not needed" + + - name: Build package + run: yarn prepare + + build-web: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Prepare library + run: yarn prepare + + - name: Build example for Web + run: | + yarn example expo export --platform web + + publish-beta: + needs: [lint, test, build-library, build-web] + runs-on: ubuntu-latest + permissions: + contents: write # To publish a GitHub release + issues: write # To comment on released issues + pull-requests: write # To comment on released pull requests + id-token: write # To enable use of OIDC for npm provenance + if: github.ref == 'refs/heads/beta' + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Ensures all tags are fetched + + - name: Setup + uses: ./.github/actions/setup + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" # Use the latest LTS version of Node.js + registry-url: 'https://registry.npmjs.org/' # Specify npm registry + + - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies + run: npm audit signatures # Check the signatures to verify integrity + + - name: Release Beta + run: npx semantic-release # Run semantic-release to manage versioning and publishing + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub token for authentication + + # Why NODE_AUTH_TOKEN instead of NPM_TOKEN: https://github.com/semantic-release/semantic-release/issues/2313 + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # npm token for publishing package + \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..fb61054 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,109 @@ +name: CI +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Lint files + run: yarn lint + + - name: Typecheck files + run: yarn typecheck + + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Run unit tests + run: yarn test:cov + + - name: Update Coverage Badge + # GitHub actions: default branch variable + # https://stackoverflow.com/questions/64781462/github-actions-default-branch-variable + if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + uses: we-cli/coverage-badge-action@main + + build-library: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Install missing dependencies + run: yarn add -D @ark/schema || echo "Package already installed or not needed" + + - name: Build package + run: yarn prepare + + build-web: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Prepare library + run: yarn prepare + + - name: Build example for Web + run: | + yarn example expo export --platform web + + publish-npm: + needs: [lint, test, build-library, build-web] + runs-on: ubuntu-latest + permissions: + contents: write # To publish a GitHub release + issues: write # To comment on released issues + pull-requests: write # To comment on released pull requests + id-token: write # To enable use of OIDC for npm provenance + if: github.ref == 'refs/heads/main' + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Ensures all tags are fetched + + - name: Setup + uses: ./.github/actions/setup + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" # Use the latest LTS version of Node.js + registry-url: 'https://registry.npmjs.org/' # Specify npm registry + + - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies + run: npm audit signatures # Check the signatures to verify integrity + + - name: Release + run: npx semantic-release # Run semantic-release to manage versioning and publishing + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub token for authentication + + # Why NODE_AUTH_TOKEN instead of NPM_TOKEN: https://github.com/semantic-release/semantic-release/issues/2313 + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # npm token for publishing package + \ No newline at end of file diff --git a/.gitignore b/.gitignore index 65aa33c..0ae4e5b 100644 --- a/.gitignore +++ b/.gitignore @@ -60,8 +60,15 @@ buck-out/ android/app/libs android/keystores/debug.keystore +# Yarn +.yarn/ +.pnp.* + # Expo .expo/* # generated by bob lib/ + +# Test coverage report +coverage/ \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..5f53e87 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.19.0 diff --git a/.yarnrc b/.yarnrc deleted file mode 100644 index fedc0f1..0000000 --- a/.yarnrc +++ /dev/null @@ -1,3 +0,0 @@ -# Override Yarn command so we can automatically setup the repo on running `yarn` - -yarn-path "scripts/bootstrap.js" diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000..13215d6 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,10 @@ +nodeLinker: node-modules +nmHoistingLimits: workspaces + +plugins: + - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs + spec: "@yarnpkg/plugin-interactive-tools" + - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs + spec: "@yarnpkg/plugin-workspace-tools" + +yarnPath: .yarn/releases/yarn-3.6.1.cjs diff --git a/README.md b/README.md index e4a2fde..33a0271 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ # react-native-session-storage -Session Storage like module for React Native for session-bound storage. -[![npm version](https://img.shields.io/npm/v/react-native-session-storage)](https://badge.fury.io/js/react-native-session-storage) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/react-native-session-storage) [![License](https://img.shields.io/github/license/JairajJangle/react-native-session-storage)](https://github.com/JairajJangle/react-native-session-storage/blob/master/LICENSE) ![Android](https://img.shields.io/badge/-Android-555555?logo=android&logoColor=3DDC84) ![iOS](https://img.shields.io/badge/-iOS-555555?logo=apple&logoColor=white) ![Web](https://img.shields.io/badge/-Web-555555?logo=google-chrome&logoColor=0096FF) [![GitHub issues](https://img.shields.io/github/issues/JairajJangle/react-native-session-storage)](https://github.com/JairajJangle/react-native-session-storage/issues?q=is%3Aopen+is%3Aissue) +Session Storage like module for React Native for session-bound storage. + +[![npm version](https://img.shields.io/npm/v/react-native-session-storage)](https://badge.fury.io/js/react-native-session-storage) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/react-native-session-storage) [![License](https://img.shields.io/github/license/JairajJangle/react-native-session-storage)](https://github.com/JairajJangle/react-native-session-storage/blob/master/LICENSE) [![Workflow Status](https://github.com/JairajJangle/react-native-session-storage/actions/workflows/ci.yml/badge.svg)](https://github.com/JairajJangle/react-native-session-storage/actions/workflows/ci.yml) [![cov](https://raw.githubusercontent.com/JairajJangle/react-native-session-storage/gh-pages/badges/coverage.svg)](https://github.com/JairajJangle/react-native-session-storage/actions/workflows/ci.yml) ![Android](https://img.shields.io/badge/-Android-555555?logo=android&logoColor=3DDC84) ![iOS](https://img.shields.io/badge/-iOS-555555?logo=apple&logoColor=white) ![Web](https://img.shields.io/badge/-Web-555555?logo=google-chrome&logoColor=0096FF) [![GitHub issues](https://img.shields.io/github/issues/JairajJangle/react-native-session-storage)](https://github.com/JairajJangle/react-native-session-storage/issues?q=is%3Aopen+is%3Aissue) ![TS](https://img.shields.io/badge/TypeScript-strict_💪-blue) + +This module is **NOT** an alternative for *Async Storage* which is meant for persistent storage. Instead, this module provides a "volatile" session-bound storage which gets cleared when the app is re-opened. + +Example App Screenshot -This module is **NOT** an alternative for *Async Storage* which is meant for persistent storage. Instead, this module provides a "volatile" session-bound storage which gets cleared when the app is re-opened. ## Installation @@ -21,7 +25,7 @@ yarn add react-native-session-storage With Expo CLI: -``` +```sh expo install react-native-session-storage ``` @@ -33,42 +37,262 @@ expo install react-native-session-storage import SessionStorage from 'react-native-session-storage'; ``` -### Storing data +## API Reference + +### Basic Operations + +| Method | Description | Parameters | Return Type | +| ------------ | ------------------------------------ | ------------------------- | --------------------- | +| `setItem` | Store a key-value pair | `key: string, value: any` | `void` | +| `getItem` | Get value by key | `key: string` | `any or undefined` | +| `removeItem` | Remove value by key | `key: string` | `void` | +| `clear` | Clear all key-value pairs | - | `void` | +| `key` | Get key name by index | `n: number` | `string or undefined` | +| `length` | Get number of stored key-value pairs | - | `number` | -The value can be of `any` type. +### Advanced Operations + +| Method | Description | Parameters | Return Type | +| ------------- | ---------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------- | +| `multiGet` | Get multiple values by their keys | `keys: string[]` | `Record` | +| `getAllItems` | Get all key-value pairs | - | `Record` | +| `multiSet` | Store multiple key-value pairs | `keyValuePairs: [string, any][] | Record` | `void` | +| `mergeItem` | Merge an object with existing value | `key: string, value: Record` | `Record | undefined` | +| `multiMerge` | Merge multiple objects with their values | `keyValuePairs: [string, Record][] | Record>` | `Record | undefined>` | +| `multiRemove` | Remove multiple values by their keys | `keys: string[]` | `void` | +| `getAllKeys` | Get all keys | - | `string[]` | + +## Examples + +### Basic Usage ```typescript -SessionStorage.setItem('@storage_key', value); +// Storing data +SessionStorage.setItem('@storage_key', 'stored value'); +SessionStorage.setItem('@user', { name: 'John', age: 30 }); + +// Reading data +const value = SessionStorage.getItem('@storage_key'); // 'stored value' +const user = SessionStorage.getItem('@user'); // { name: 'John', age: 30 } + +// Removing data +SessionStorage.removeItem('@storage_key'); + +// Clearing all data +SessionStorage.clear(); + +// Get key by index +const firstKey = SessionStorage.key(0); + +// Get storage size +const size = SessionStorage.length; ``` -### Reading data +### Advanced Usage + +```typescript +// Working with multiple items +SessionStorage.multiSet([ + ['@key1', 'value1'], + ['@key2', 'value2'], + ['@key3', { complex: 'object' }] +]); + +// Getting multiple items +const values = SessionStorage.multiGet(['@key1', '@key2', '@key3']); +console.log(values); // { '@key1': 'value1', '@key2': 'value2', '@key3': { complex: 'object' } } + +// Getting all items +const allData = SessionStorage.getAllItems(); + +// Merging objects +SessionStorage.setItem('@user', { name: 'John', age: 30 }); +const merged = SessionStorage.mergeItem('@user', { age: 31, location: 'NYC' }); +console.log(merged); // { name: 'John', age: 31, location: 'NYC' } + +// Multiple merge operations +SessionStorage.multiMerge({ + '@user1': { role: 'admin' }, + '@user2': { status: 'active' } +}); + +// Getting all keys +const allKeys = SessionStorage.getAllKeys(); + +// Removing multiple items +SessionStorage.multiRemove(['@key1', '@key2']); +``` -The return value is of the type of the value which was stored using `setItem(...)` +## TypeScript Support + +The module is written in TypeScript and supports generics for better type safety: ```typescript -const data = SessionStorage.getItem('@storage_key'); +// Type-safe storage +interface User { + name: string; + age: number; + email: string; +} + +// Create a typed storage instance (not available in the default export) +import { Storage } from 'react-native-session-storage'; +const UserStorage = new Storage(); + +// Type-safe operations +UserStorage.setItem('@user1', { name: 'John', age: 30, email: 'john@example.com' }); + +// TypeScript will ensure you get the correct type back +const user: User | undefined = UserStorage.getItem('@user1'); ``` -### Removing data +## Applications + +### API Response Caching ```typescript -SessionStorage.removeItem('@storage_key'); +import SessionStorage from 'react-native-session-storage'; + +const fetchData = async (endpoint) => { + // Check if response is already cached + const cachedResponse = SessionStorage.getItem(`@api_cache_${endpoint}`); + + if (cachedResponse) { + console.log('Using cached response'); + return cachedResponse; + } + + // Fetch new data + try { + const response = await fetch(`https://api.example.com/${endpoint}`); + const data = await response.json(); + + // Cache the response + SessionStorage.setItem(`@api_cache_${endpoint}`, data); + + return data; + } catch (error) { + console.error('Fetch error:', error); + throw error; + } +}; ``` -### Clearing all keys +### Memoization Provider ```typescript -SessionStorage.clear(); +import SessionStorage from 'react-native-session-storage'; + +// Create a memoized function with SessionStorage as cache +const memoize = (fn) => { + return (...args) => { + const key = `@memo_${fn.name}_${JSON.stringify(args)}`; + + // Check if result is already cached + const cachedResult = SessionStorage.getItem(key); + + if (cachedResult !== undefined) { + return cachedResult; + } + + // Calculate and cache result + const result = fn(...args); + SessionStorage.setItem(key, result); + + return result; + }; +}; + +// Example usage +const expensiveCalculation = (a, b) => { + console.log('Performing expensive calculation'); + return a * b; +}; + +const memoizedCalculation = memoize(expensiveCalculation); + +// First call will perform calculation +const result1 = memoizedCalculation(5, 10); // Logs: Performing expensive calculation + +// Second call with same args will use cached result +const result2 = memoizedCalculation(5, 10); // No log, returns cached result + +// Different args will perform calculation again +const result3 = memoizedCalculation(7, 8); // Logs: Performing expensive calculation +``` + +### Form State Persistence + +```typescript +import SessionStorage from 'react-native-session-storage'; +import { useState, useEffect } from 'react'; + +const useSessionForm = (formId, initialState = {}) => { + // Get stored form state or use initial state + const [formState, setFormState] = useState(() => { + const stored = SessionStorage.getItem(`@form_${formId}`); + return stored || initialState; + }); + + // Update storage when state changes + useEffect(() => { + SessionStorage.setItem(`@form_${formId}`, formState); + }, [formId, formState]); + + // Clear form data + const resetForm = () => { + SessionStorage.removeItem(`@form_${formId}`); + setFormState(initialState); + }; + + return [formState, setFormState, resetForm]; +}; + +// Example usage in a component +function SignupForm() { + const [formData, setFormData, resetForm] = useSessionForm('signup', { + email: '', + name: '', + agreed: false + }); + + const handleChange = (field, value) => { + setFormData({ ...formData, [field]: value }); + }; + + // Form state persists during the app session + // Users can navigate away and come back with data intact + + return ( + // Form UI implementation + ); +} ``` ## Contributing -See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. +See the [contributing guide](https://claude.ai/chat/CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. ## License MIT ---- +## 🙏 Support the project + +

+ + LiberPay_Donation_Button + +           + + Paypal_Donation_Button + +           + + Paypal_Donation_Button + +

+ +------ Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob) diff --git a/babel.config.js b/babel.config.js index f842b77..5ae49c3 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,3 +1,3 @@ module.exports = { - presets: ['module:metro-react-native-babel-preset'], + presets: ["module:metro-react-native-babel-preset"], }; diff --git a/eslint.config.js b/eslint.config.js index 3d938db..ddfadb6 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,35 +1,118 @@ -const { ESLint } = require("eslint"); - -module.exports = new ESLint({ - baseConfig: { - env: { - browser: true, - es2021: true, - }, - extends: [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:react-native/all", +module.exports = [ + { + ignores: [ + "node_modules/**", + "coverage/**", + "lib/**", + "example/.expo/**", + "**/*.d.ts", + "babel.config.js", + "example/babel.config.js", + "eslint.config.js", + "scripts/bootstrap.js", + "package.json" ], - parserOptions: { - ecmaFeatures: { - jsx: true, + }, + // Config for TypeScript files in src/ + { + files: ["src/**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: "latest", + sourceType: "module", + parser: require("@typescript-eslint/parser"), + globals: { + browser: true, + es2021: true, + }, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + project: "./tsconfig.json", }, + }, + plugins: { + react: require("eslint-plugin-react"), + "react-native": require("eslint-plugin-react-native"), + import: require("eslint-plugin-import"), + prettier: require("eslint-plugin-prettier"), + "@typescript-eslint": require("@typescript-eslint/eslint-plugin"), + }, + settings: { + react: { + version: "detect", + }, + }, + rules: { + ...require("eslint-config-prettier").rules, + "react-native/no-unused-styles": "warn", + "react-native/split-platform-components": "warn", + "react-native/no-inline-styles": "warn", + "react-native/no-color-literals": "warn", + "react-native/no-single-element-style-arrays": "warn", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], + "@typescript-eslint/explicit-module-boundary-types": "warn", + "@typescript-eslint/no-explicit-any": "warn", // Enforce for src/ + }, + }, + // Config for TypeScript files in example/ + { + files: ["example/**/*.{ts,tsx}"], + languageOptions: { ecmaVersion: "latest", sourceType: "module", + parser: require("@typescript-eslint/parser"), + globals: { + browser: true, + es2021: true, + }, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + project: "./example/tsconfig.json", + }, + }, + plugins: { + react: require("eslint-plugin-react"), + "react-native": require("eslint-plugin-react-native"), + import: require("eslint-plugin-import"), + prettier: require("eslint-plugin-prettier"), + "@typescript-eslint": require("@typescript-eslint/eslint-plugin"), }, - plugins: ["react", "react-native", "import"], settings: { react: { version: "detect", }, }, rules: { + ...require("eslint-config-prettier").rules, "react-native/no-unused-styles": "warn", "react-native/split-platform-components": "warn", "react-native/no-inline-styles": "warn", "react-native/no-color-literals": "warn", "react-native/no-single-element-style-arrays": "warn", + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], + "@typescript-eslint/explicit-module-boundary-types": "warn", + "@typescript-eslint/no-explicit-any": "off", // Disable for example/ + }, + }, + // Config for JavaScript files + { + files: ["**/*.js", "!src/**/*.js", "!example/**/*.js"], + languageOptions: { + ecmaVersion: "latest", + sourceType: "module", + globals: { + node: true, + }, + }, + plugins: { + prettier: require("eslint-plugin-prettier"), + import: require("eslint-plugin-import"), + }, + rules: { + ...require("eslint-config-prettier").rules, }, }, -}); +]; \ No newline at end of file diff --git a/example/app.json b/example/app.json index dddf149..2260e6b 100644 --- a/example/app.json +++ b/example/app.json @@ -14,24 +14,29 @@ "backgroundColor": "#ffffff" }, "ios": { - "supportsTablet": true + "supportsTablet": true, + "infoPlist": { + "UIViewControllerBasedStatusBarAppearance": true + }, + "statusBar": { + "style": "dark-content", + "backgroundColor": "transparent", + "hidden": false, + "translucent": true + } }, "android": { "adaptiveIcon": { "foregroundImage": "./assets/images/adaptive-icon.png", "backgroundColor": "#ffffff" - } + }, + "edgeToEdgeEnabled": true }, "web": { - "bundler": "metro", - "output": "static", "favicon": "./assets/images/favicon.png" }, - "plugins": [ - "expo-router" - ], "experiments": { - "typedRoutes": true + "reactCompiler": true } } } diff --git a/example/app/index.tsx b/example/app/index.tsx deleted file mode 100644 index cb4dcd1..0000000 --- a/example/app/index.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import * as React from 'react'; -import { - StyleSheet, - View, - Text, - TextInput, - Button, - SafeAreaView -} from 'react-native'; -import SessionStorage from 'react-native-session-storage'; - -export default function App() { - const [storedVal, updateStoredVal] = React.useState(); - const [inputText, setInputText] = React.useState(""); - - const setVal = React.useCallback(() => { - SessionStorage.setItem("my_key", inputText); - }, [inputText]); - - function getVal(): any { - const val = SessionStorage.getItem("my_key"); - updateStoredVal(val); - } - - return ( - - Input Value to Store - - - - -