### Install Dependencies for Expo Stable ID
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Installs the necessary packages for using @nauverse/expo-stable-id, including cloud settings, secure storage, and crypto modules. This command should be run in your project's root directory.
```bash
npx expo install @nauverse/expo-stable-id @nauverse/expo-cloud-settings expo-secure-store expo-crypto
```
--------------------------------
### Basic StableIdProvider and useStableId Hook Usage
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Demonstrates the basic setup of the StableIdProvider to wrap the application and the useStableId hook to access the stable ID and its associated functions. This allows components to retrieve the ID and trigger actions like generating a new ID or identifying a user.
```tsx
import React from 'react';
import { View, Text, Button } from 'react-native';
import { StableIdProvider, useStableId } from '@nauverse/expo-stable-id';
function MyComponent() {
const [id, { identify, generateNewId }] = useStableId();
return (
Stable ID: {id ?? 'Loading...'}
);
}
export default function App() {
return (
);
}
```
--------------------------------
### Expo Config Plugin Setup for iCloud KVS
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Configures the Expo project to include the @nauverse/expo-stable-id plugin, which is necessary for enabling iCloud Key-Value Storage (KVS) entitlements. This allows for cross-device synchronization of the stable ID on iOS.
```typescript
// app.config.ts
export default {
expo: {
name: "MyApp",
plugins: ['@nauverse/expo-stable-id'],
},
};
```
```typescript
// app.config.ts - with custom iCloud container
export default {
expo: {
name: "MyApp",
plugins: [
['@nauverse/expo-stable-id', { containerIdentifier: 'com.example.shared' }],
],
},
};
```
--------------------------------
### Integrate Expo Stable ID with PostHog and RevenueCat
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Shows a practical example of using the stable ID across different services like PostHog for analytics and RevenueCat for in-app purchases. This ensures consistent user tracking and identification across your application's features.
```tsx
import { StableIdProvider, useStableId } from '@nauverse/expo-stable-id';
import PostHog from 'posthog-react-native';
import Purchases from 'react-native-purchases';
import { useEffect } from 'react';
function App() {
return (
{/* rest of your app */}
);
}
function IdentifyProviders() {
const [id] = useStableId();
useEffect(() => {
if (!id) return;
// Same ID in both services
PostHog.identify(id);
Purchases.logIn(id);
}, [id]);
return null;
}
```
--------------------------------
### Custom ID Generator Implementation (TypeScript)
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Demonstrates how to create a custom ID generator by implementing the `IDGenerator` interface. This allows for flexible ID generation strategies beyond the defaults. The example shows a generator that prefixes the current timestamp.
```typescript
import type { IDGenerator } from '@nauverse/expo-stable-id';
const myGenerator: IDGenerator = {
generate: () => `prefix-${Date.now()}`,
};
```
--------------------------------
### Generate Short Alphanumeric IDs with ShortIDGenerator
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
The ShortIDGenerator creates compact 8-character alphanumeric strings, which are useful for scenarios where shorter IDs are preferred for display or storage efficiency. This generator can be configured during the setup process.
```typescript
import { configure, generateNewId, ShortIDGenerator } from '@nauverse/expo-stable-id';
async function example() {
await configure({ generator: new ShortIDGenerator() });
const id = generateNewId();
console.log('Short ID:', id);
// Output: Short ID: xK9mP2nQ
}
// Direct usage
const generator = new ShortIDGenerator();
console.log(generator.generate()); // 8-char alphanumeric
// Output: yL8nQ3pR
```
--------------------------------
### configure() - Initialize Stable ID System
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Initializes the stable ID system. This function should be called once at app startup before using other methods. It returns a Promise that resolves with the stable ID.
```APIDOC
## POST /configure
### Description
Initializes the stable ID system using the functional API. Call once at app startup before using other methods. Returns a Promise that resolves with the stable ID.
### Method
POST
### Endpoint
/configure
### Parameters
#### Request Body
- **generator** (ShortIDGenerator) - Optional - A custom ID generator.
- **id** (string) - Optional - A fallback ID to use if no stored ID exists.
- **policy** (string) - Optional - The policy for resolving IDs ('preferStored' or 'preferNew'). Defaults to 'preferStored'.
### Request Example
```json
{
"generator": "new ShortIDGenerator()",
"id": "fallback-user-id",
"policy": "preferStored"
}
```
### Response
#### Success Response (200)
- **id** (string) - The resolved stable ID.
#### Response Example
```json
{
"id": "a1b2c3d4-e5f6-4789-abcd-ef0123456789"
}
```
```
--------------------------------
### Initialize Stable ID System with configure()
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Initializes the stable ID system using the functional API. This should be called once at app startup before using other methods. It returns a Promise that resolves with the stable ID. Options include specifying a custom ID generator or a fallback ID.
```typescript
import {
configure,
getId,
isConfigured,
ShortIDGenerator,
} from '@nauverse/expo-stable-id';
// Basic initialization - generates UUID if no stored ID exists
async function initializeApp() {
const id = await configure();
console.log('Stable ID:', id);
// Output: Stable ID: a1b2c3d4-e5f6-4789-abcd-ef0123456789
}
// Initialize with short ID generator
async function initializeWithShortIds() {
const id = await configure({
generator: new ShortIDGenerator(),
});
console.log('Short ID:', id);
// Output: Short ID: xK9mP2nQ
}
// Initialize with fallback ID and prefer stored policy
async function initializeWithFallback() {
const id = await configure({
id: 'fallback-user-id',
policy: 'preferStored', // Use stored ID if available
});
console.log('Resolved ID:', id);
// Output: Stored ID if exists, otherwise 'fallback-user-id'
}
// Check configuration status
function checkStatus() {
console.log('Is configured:', isConfigured()); // true after configure()
console.log('Current ID:', getId()); // Synchronous cached read
}
```
--------------------------------
### Configuring StableIdProvider with Custom Generators and Policies
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Shows how to configure the StableIdProvider with custom options, including different ID generators (StandardGenerator, ShortIDGenerator) and storage policies ('forceUpdate', 'preferStored'). This allows for fine-grained control over ID generation and persistence behavior.
```tsx
import React from 'react';
import { View, Text } from 'react-native';
import {
StableIdProvider,
useStableId,
StandardGenerator,
ShortIDGenerator
} from '@nauverse/expo-stable-id';
function DisplayId() {
const [id] = useStableId();
return ID: {id ?? 'Loading...'};
}
// Use short 8-character IDs instead of UUIDs
function AppWithShortIds() {
return (
);
}
// Force a specific known ID (overwrites any stored value)
function AppWithKnownId() {
return (
);
}
// Use stored ID if available, fall back to provided ID
function AppWithFallbackId() {
return (
);
}
```
--------------------------------
### Expo Stable ID Provider Configuration Options
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Shows how to configure the `StableIdProvider` with custom options, such as using a different ID generator (e.g., `ShortIDGenerator`) or specifying an initial ID with a particular update policy (`forceUpdate` or `preferStored`).
```tsx
import { StableIdProvider, ShortIDGenerator } from '@nauverse/expo-stable-id';
// Use short 8-char IDs instead of UUIDs
// Provide a known ID, force it even if one exists
// Provide a fallback ID, prefer any stored value
```
--------------------------------
### Functional API for Expo Stable ID
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Illustrates the functional API for interacting with the stable ID, including initialization (`configure`), retrieving the current ID (`getId`), modifying the ID (`identify`, `generateNewId`), checking its state (`isConfigured`, `hasStoredId`), and managing change listeners (`addChangeListener`, `setWillChangeHandler`).
```typescript
import {
configure,
getId,
identify,
generateNewId,
isConfigured,
hasStoredId,
addChangeListener,
setWillChangeHandler,
} from '@nauverse/expo-stable-id';
// Initialize (call once at app startup)
const id = await configure();
// Or with options
const id = await configure({
id: 'fallback-id',
policy: 'preferStored',
generator: new ShortIDGenerator(),
});
// Read current ID (sync, from cache)
const currentId = getId();
// Change ID
identify('new-user-id');
// Generate a new random ID
const newId = generateNewId();
// Check state
isConfigured(); // boolean
await hasStoredId(); // boolean
// Listen for changes
const subscription = addChangeListener((event) => {
console.log(`ID changed: ${event.previousId} -> ${event.newId} (${event.source})`);
});
subscription.remove();
// Intercept changes before they apply (identify, generateNewId, cloud sync)
setWillChangeHandler((currentId, candidateId) => {
// Return modified ID, or null to accept candidate as-is
return candidateId;
});
```
--------------------------------
### useStableId Hook for ID Management and Actions
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Illustrates the use of the useStableId hook within a component to access the current stable ID and perform actions like setting a custom ID or generating a new one. It also shows how to handle the ID being null while it's loading.
```tsx
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { StableIdProvider, useStableId } from '@nauverse/expo-stable-id';
function StableIdDemo() {
const [id, { identify, generateNewId }] = useStableId();
const handleSetCustomId = () => {
// Set a specific user ID (e.g., after authentication)
identify('custom-user-123');
};
const handleGenerateNew = () => {
// Generate and persist a new random ID
const newId = generateNewId();
console.log('Generated new ID:', newId);
};
return (
Current Stable ID:{id ?? 'Loading...'}
);
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
label: { fontSize: 14, color: '#666', marginTop: 20 },
value: { fontSize: 16, fontFamily: 'monospace', marginTop: 4, marginBottom: 10 },
});
export default function App() {
return (
);
}
```
--------------------------------
### Stable ID Configuration Interface (TypeScript)
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Defines the structure for configuring the stable ID system. This includes optional parameters for an initial ID, a custom generator, and the ID policy.
```typescript
interface StableIdConfig {
readonly id?: string;
readonly generator?: IDGenerator;
readonly policy?: IDPolicy;
}
```
--------------------------------
### Retrieve Current Stable ID with getId()
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Synchronously retrieves the current cached stable ID. Returns null if `configure()` hasn't been called yet. This is a fast, synchronous operation that reads from memory.
```typescript
import { configure, getId } from '@nauverse/expo-stable-id';
async function example() {
// Before configure() - returns null
console.log('Before configure:', getId()); // null
await configure();
// After configure() - returns the stable ID
const currentId = getId();
console.log('Current ID:', currentId);
// Output: Current ID: a1b2c3d4-e5f6-4789-abcd-ef0123456789
}
```
--------------------------------
### identify() - Set Specific ID
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Sets a specific ID, overwriting any existing stored value. This is useful for associating the device with a known user ID after authentication.
```APIDOC
## POST /identify
### Description
Set a specific ID, overwriting any existing stored value. Useful for associating the device with a known user ID after authentication.
### Method
POST
### Endpoint
/identify
### Parameters
#### Request Body
- **userId** (string) - Required - The user ID to set as the stable ID.
### Request Example
```json
{
"userId": "user_abc123"
}
```
### Response
#### Success Response (200)
- **message** (string) - Confirmation message.
#### Response Example
```json
{
"message": "Stable ID updated successfully."
}
```
```
--------------------------------
### getId() - Retrieve Current Stable ID
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Synchronously retrieves the current cached stable ID. Returns null if `configure()` hasn't been called yet. This is a fast, synchronous operation that reads from memory.
```APIDOC
## GET /getId
### Description
Synchronously retrieve the current cached stable ID. Returns null if `configure()` hasn't been called yet. This is a fast, synchronous operation that reads from memory.
### Method
GET
### Endpoint
/getId
### Response
#### Success Response (200)
- **id** (string | null) - The current stable ID or null if not configured.
#### Response Example
```json
{
"id": "a1b2c3d4-e5f6-4789-abcd-ef0123456789"
}
```
```
--------------------------------
### React Hooks Usage for Expo Stable ID
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Demonstrates how to use the `StableIdProvider` and `useStableId` hook to manage and access the stable user ID within a React Native/Expo application. The hook provides the current ID and functions to identify or generate new IDs.
```tsx
import { StableIdProvider, useStableId } from '@nauverse/expo-stable-id';
function App() {
return (
);
}
function MyComponent() {
const [id, { identify, generateNewId }] = useStableId();
return (
Stable ID: {id ?? 'Loading...'} generateNewId()} />
identify('user-123')} />
);
}
```
--------------------------------
### addChangeListener() - Subscribe to ID Changes
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Subscribes to ID change events. These events are triggered when the ID changes via `identify()`, `generateNewId()`, or cloud synchronization from another device.
```APIDOC
## POST /addChangeListener
### Description
Subscribe to ID change events. Triggered when the ID changes via `identify()`, `generateNewId()`, or cloud sync from another device.
### Method
POST
### Endpoint
/addChangeListener
### Parameters
#### Request Body
- **callback** (function) - Required - The function to call when the ID changes. It receives an event object with `previousId`, `newId`, and `source`.
### Response
#### Success Response (200)
- **subscription** (object) - An object with a `remove()` method to unsubscribe from changes.
#### Response Example
```json
{
"subscription": {
"remove": "() => void"
}
}
```
```
--------------------------------
### Create Custom ID Generators
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
You can implement the IDGenerator interface to create custom ID generators tailored to specific needs, such as unique ID formats or integration with existing systems. This allows for flexible ID generation strategies.
```typescript
import { configure, generateNewId } from '@nauverse/expo-stable-id';
import type { IDGenerator } from '@nauverse/expo-stable-id';
// Custom generator with timestamp prefix
const timestampGenerator: IDGenerator = {
generate: () => `ts_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
};
// Custom generator with sequential numbering
let counter = 0;
const sequentialGenerator: IDGenerator = {
generate: () => `user_${++counter}_${Date.now()}`,
};
async function example() {
await configure({ generator: timestampGenerator });
const id = generateNewId();
console.log('Timestamped ID:', id);
// Output: Timestamped ID: ts_1699876543210_a3b2c1
}
```
--------------------------------
### Set Specific ID with identify()
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Sets a specific ID, overwriting any existing stored value. This is useful for associating the device with a known user ID after authentication. It requires the `configure()` function to have been called previously.
```typescript
import { configure, identify, getId } from '@nauverse/expo-stable-id';
async function handleUserLogin(userId: string) {
await configure();
// Before: auto-generated ID
console.log('Before login:', getId());
// Output: Before login: a1b2c3d4-e5f6-4789-abcd-ef0123456789
// Set the authenticated user's ID
identify(userId);
// After: user's ID is now the stable ID
console.log('After login:', getId());
// Output: After login: user_abc123
}
// Usage
handleUserLogin('user_abc123');
```
--------------------------------
### generateNewId() - Generate New ID
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Generates a new random ID using the configured generator and persists it to storage. Returns the newly generated ID.
```APIDOC
## POST /generateNewId
### Description
Generate a new random ID using the configured generator and persist it to storage. Returns the newly generated ID.
### Method
POST
### Endpoint
/generateNewId
### Response
#### Success Response (200)
- **newId** (string) - The newly generated stable ID.
#### Response Example
```json
{
"newId": "b2c3d4e5-f6a7-4890-bcde-f01234567890"
}
```
```
--------------------------------
### Configure Expo Stable ID Plugin in app.config.ts
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Adds the @nauverse/expo-stable-id plugin to your app configuration file. This is required to enable the iCloud KVS entitlement for cloud synchronization. An optional custom container identifier can also be provided.
```typescript
export default {
plugins: ['@nauverse/expo-stable-id'],
};
// With custom container:
export default {
plugins: [
['@nauverse/expo-stable-id', { containerIdentifier: 'com.example.shared' }],
],
};
```
--------------------------------
### Change Source Type Definition (TypeScript)
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Defines the possible sources of changes for the stable ID. This helps in understanding where an ID update originated from, such as cloud synchronization or manual user intervention.
```typescript
type ChangeSource = 'cloud' | 'manual';
```
--------------------------------
### Generate UUID v4 IDs with StandardGenerator
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
The StandardGenerator is the default ID generator, producing cryptographically random, universally unique identifiers in UUID v4 format. It can be used directly or configured explicitly.
```typescript
import { configure, generateNewId, StandardGenerator } from '@nauverse/expo-stable-id';
async function example() {
// StandardGenerator is used by default
await configure();
// Or explicitly specify it
await configure({ generator: new StandardGenerator() });
const id = generateNewId();
console.log('UUID:', id);
// Output: UUID: a1b2c3d4-e5f6-4789-abcd-ef0123456789
}
// Direct usage
const generator = new StandardGenerator();
console.log(generator.generate());
// Output: b2c3d4e5-f6a7-4890-bcde-f01234567890
```
--------------------------------
### Generate New ID with generateNewId()
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Generates a new random ID using the configured generator and persists it to storage. Returns the newly generated ID. This function can be used with the default UUID generator or a custom one like `ShortIDGenerator`.
```typescript
import { configure, generateNewId, getId, ShortIDGenerator } from '@nauverse/expo-stable-id';
async function example() {
// With default StandardGenerator (UUID)
await configure();
console.log('Initial ID:', getId());
// Output: Initial ID: a1b2c3d4-e5f6-4789-abcd-ef0123456789
const newId = generateNewId();
console.log('New ID:', newId);
// Output: New ID: b2c3d4e5-f6a7-4890-bcde-f01234567890
}
async function exampleWithShortIds() {
// With ShortIDGenerator
await configure({ generator: new ShortIDGenerator() });
const newId = generateNewId();
console.log('New short ID:', newId);
// Output: New short ID: yL8nQ3pR
}
```
--------------------------------
### ID Policy Type Definition (TypeScript)
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Defines the possible policies for handling stable IDs. These policies determine how the library behaves when an ID is provided versus when an ID already exists in storage.
```typescript
type IDPolicy = 'preferStored' | 'forceUpdate';
```
--------------------------------
### Subscribe to ID Changes with addChangeListener()
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Subscribes to ID change events. These events are triggered when the stable ID changes via `identify()`, `generateNewId()`, or cloud synchronization from another device. The listener receives an event object with `previousId`, `newId`, and `source` properties.
```typescript
import { configure, addChangeListener, identify, generateNewId } from '@nauverse/expo-stable-id';
async function example() {
await configure();
// Subscribe to changes
const subscription = addChangeListener((event) => {
console.log('ID Changed:');
console.log(' Previous:', event.previousId);
console.log(' New:', event.newId);
console.log(' Source:', event.source); // 'manual' or 'cloud'
});
// Trigger a change
identify('new-user-id');
// Output:
// ID Changed:
// Previous: a1b2c3d4-e5f6-4789-abcd-ef0123456789
// New: new-user-id
// Source: manual
generateNewId();
// Output:
// ID Changed:
// Previous: new-user-id
// New: c3d4e5f6-a7b8-4901-cdef-012345678901
// Source: manual
// Clean up when done
subscription.remove();
}
```
--------------------------------
### Check for Stored ID with hasStoredId()
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Checks if an ID already exists in storage without initializing the system. This is useful for determining the first-launch state of the application. It returns a Promise that resolves to a boolean.
```typescript
import { hasStoredId, configure } from '@nauverse/expo-stable-id';
async function checkFirstLaunch() {
const hasId = await hasStoredId();
if (hasId) {
console.log('Returning user - ID exists in storage');
} else {
console.log('First launch - no stored ID');
}
// Now configure (will use stored ID or generate new one)
const id = await configure();
console.log('Stable ID:', id);
}
```
--------------------------------
### hasStoredId() - Check for Stored ID
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
Checks if an ID already exists in storage without initializing the system. This is useful for determining the first-launch state of the application.
```APIDOC
## GET /hasStoredId
### Description
Check if an ID already exists in storage without initializing the system. Useful for determining first-launch state.
### Method
GET
### Endpoint
/hasStoredId
### Response
#### Success Response (200)
- **hasId** (boolean) - True if an ID exists in storage, false otherwise.
#### Response Example
```json
{
"hasId": true
}
```
```
--------------------------------
### ID Generator Interface Definition (TypeScript)
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Defines the contract for custom ID generators. Any object implementing this interface must provide a `generate` method that returns a unique string identifier.
```typescript
interface IDGenerator {
generate(): string;
}
```
--------------------------------
### Intercept and Modify ID Changes with setWillChangeHandler()
Source: https://context7.com/thenaubit/expo-stable-id/llms.txt
The setWillChangeHandler function allows you to intercept and optionally modify ID changes before they are applied. The handler receives the current and candidate IDs, and can return a modified ID or null to accept the candidate. This is useful for adding prefixes, suffixes, or blocking specific ID changes.
```typescript
import { configure, setWillChangeHandler, identify, generateNewId, getId } from '@nauverse/expo-stable-id';
async function example() {
await configure();
// Intercept all ID changes
setWillChangeHandler((currentId, candidateId) => {
console.log(`ID change requested: ${currentId} -> ${candidateId}`);
// Example: Add a prefix to all IDs
return `app_${candidateId}`;
});
identify('user-123');
console.log('Final ID:', getId());
// Output: Final ID: app_user-123
// Example: Block certain ID changes
setWillChangeHandler((currentId, candidateId) => {
if (candidateId.startsWith('blocked_')) {
console.log('Blocked ID change');
return currentId; // Keep current ID
}
return null; // Accept candidate as-is
});
// Remove handler
setWillChangeHandler(null);
}
```
--------------------------------
### Stable ID Change Event Interface (TypeScript)
Source: https://github.com/thenaubit/expo-stable-id/blob/main/README.md
Defines the structure of the event object passed to change listeners. It includes the previous ID, the new ID, and the source of the change.
```typescript
interface StableIdChangeEvent {
readonly previousId: string | null;
readonly newId: string;
readonly source: ChangeSource;
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.