diff --git a/docs/DataSync/remote-sync-gateway.md b/docs/DataSync/remote-sync-gateway.md index 6b8b578..8986995 100644 --- a/docs/DataSync/remote-sync-gateway.md +++ b/docs/DataSync/remote-sync-gateway.md @@ -130,37 +130,97 @@ If you’re using a Sync Gateway release that is older than version 3.1, you won #### Example 1. Replication configuration and initialization ```typescript -//assumes you are running sync gateway locally, if you are - //running app services, replace enpoint with proper url and creditentials - const target = new URLEndpoint('ws://localhost:4984/projects'); - const auth = new BasicAuthenticator('demo@example.com', 'P@ssw0rd12'); - const config = new ReplicatorConfiguration(target); - config.addCollection(collectionName); - config.setAuthenticator(auth); - - const replicator = await Replicator.create(config); - - //listen to the replicator change events - const token = await replicator.addChangeListener((change) => { - //check to see if there was an error - const error = change.status.getError(); - if (error !== undefined) { - //do something with the error - } - //get the status of the replicator using ReplicatorActivityLevel enum - if (change.status.getActivityLevel() === ReplicatorActivityLevel.IDLE) { - //do something because the replicator is now IDLE - } - }); - - // start the replicator without making a new checkpoint - await replicator.start(false); - - //remember you must clean up the replicator when done with it by - //doing the following lines - - //await replicator.removeChangeListener(token); - //await replicator.stop(); +import { + ReplicatorConfiguration, + CollectionConfiguration, + URLEndpoint, + BasicAuthenticator, + Replicator, + ListenerToken +} from 'cbl-reactnative'; + +// Create endpoint and authenticator +const endpoint = new URLEndpoint('ws://localhost:4984/projects'); +const auth = new BasicAuthenticator('demo@example.com', 'P@ssw0rd12'); + +// NEW API: Create collection configuration +const collectionConfig = new CollectionConfiguration(collection); + +// Pass collection configurations in constructor +const config = new ReplicatorConfiguration( + [collectionConfig], // Collections passed during initialization + endpoint +); + +config.setAuthenticator(auth); + +// Create replicator +const replicator = await Replicator.create(config); + +// Listen to replicator change events +const token: ListenerToken = await replicator.addChangeListener((change) => { + // Check for errors + const error = change.status.getError(); + if (error) { + console.error('Replication error:', error); + } + + // Check activity level + if (change.status.getActivityLevel() === 3) { // IDLE + console.log('Replication is idle'); + } +}); + +// Start replication +await replicator.start(false); + +// Remember to clean up when done: +// await token.remove(); +// await replicator.stop(); +``` + +:::important Version 1.0 API Change +Collections are now passed during `ReplicatorConfiguration` construction using `CollectionConfiguration` objects. + +**NEW API (Recommended):** +```typescript +const collectionConfig = new CollectionConfiguration(collection); +const config = new ReplicatorConfiguration([collectionConfig], endpoint); +``` + +**OLD API (Deprecated):** +```typescript +const config = new ReplicatorConfiguration(endpoint); +config.addCollection(collection); // Deprecated +``` + +The `addCollection()` method is deprecated. It remains available for backward compatibility, but new applications should use the new constructor pattern. Existing applications are strongly encouraged to migrate. +::: + +#### Example 1b. Multiple Collections + +The new API allows each collection to have its own replication settings: + +```typescript +import { CollectionConfiguration } from 'cbl-reactnative'; + +// Configure users collection +const usersConfig = new CollectionConfiguration(usersCollection) + .setChannels(['public', 'users']); + +// Configure orders collection with different settings +const ordersConfig = new CollectionConfiguration(ordersCollection) + .setChannels(['orders', 'admin']) + .setDocumentIDs(['order-1', 'order-2']); // Only specific documents + +// Pass both configurations during initialization +const config = new ReplicatorConfiguration( + [usersConfig, ordersConfig], + endpoint +); + +config.setAuthenticator(auth); +const replicator = await Replicator.create(config); ``` ## Configure @@ -662,15 +722,68 @@ The returned *ReplicationStatus* structure comprises: #### Example 14. Monitor replication ```typescript -// Optionally add a change listener -// Retain token for use in deletion -const token = replicator.addChangeListener((change) => { - if (change.status.getActivityLevel() === 'STOPPED') { - console.log("Replication stopped"); - } else { - console.log(`Replicator is currently : ${change.status.getActivityLevel()}`); - } +import { ListenerToken } from 'cbl-reactnative'; + +const token: ListenerToken = await replicator.addChangeListener((change) => { + const status = change.status; + const activityLevel = status.getActivityLevel(); + const progress = status.getProgress(); + + const levelNames = ['stopped', 'offline', 'connecting', 'idle', 'busy']; + console.log(`Status: ${levelNames[activityLevel]}`); + console.log(`Progress: ${progress.getCompleted()}/${progress.getTotal()}`); +}); + +// Remove listener when done +await token.remove(); +``` + +### Replicator Status Data Structure + +When replication status changes, your callback receives a `ReplicatorStatusChange` object: + +```typescript +interface ReplicatorStatusChange { + status: ReplicatorStatus; +} +``` + +**ReplicatorStatus Methods:** +- `getActivityLevel()` - Returns 0-4 (see activity levels table below) +- `getProgress()` - Returns ReplicatorProgress object +- `getError()` - Returns error message string or undefined + +**ReplicatorProgress Methods:** +- `getCompleted()` - Returns number of changes completed +- `getTotal()` - Returns total number of changes + +#### Example 14b. Advanced Replication Status Monitoring + +```typescript +import { ListenerToken, ReplicatorActivityLevel } from 'cbl-reactnative'; + +const token: ListenerToken = await replicator.addChangeListener((change) => { + const status = change.status; + const level = status.getActivityLevel(); + const progress = status.getProgress(); + + console.log(`Activity: ${level}`); + console.log(`Progress: ${progress.getCompleted()}/${progress.getTotal()}`); + + if (status.getError()) { + console.error('Replication error:', status.getError()); + } + + // Check specific states + if (level === ReplicatorActivityLevel.IDLE) { + console.log('Sync complete'); + } else if (level === ReplicatorActivityLevel.BUSY) { + console.log('Syncing data...'); + } }); + +// Remove when done +await token.remove(); ``` ### Replication States @@ -701,37 +814,73 @@ On other platforms, Couchbase Lite doesn’t react to OS backgrounding or foregr You can choose to register for document updates during a replication. +#### When to Use Document Listeners + +- Track which specific documents are syncing +- Detect replication conflicts +- Handle document-level replication errors +- Monitor deleted documents during sync + +#### Document Replication Data Structure + +```typescript +interface DocumentReplicationRepresentation { + isPush: boolean; // true = push, false = pull + documents: ReplicatedDocument[]; +} + +interface ReplicatedDocument { + id: string; // Document ID + scopeName: string; // Scope name + collectionName: string; // Collection name + flags: string[]; // ['DELETED', 'ACCESS_REMOVED'] + error?: { message: string }; // Present if replication failed +} +``` + +**Document Flags:** +- `'DELETED'` - Document was deleted +- `'ACCESS_REMOVED'` - User lost access to document + For example, the code snippet in [Example 15](#example-15-register-a-document-listener) registers a listener to monitor document replication performed by the replicator referenced by the variable `replicator`. It prints the document ID of each document received and sent. Stop the listener as shown in [Example 16](#example-16-stop-document-listener). #### Example 15. Register a document listener ```typescript -const token = await replicator.addDocumentChangeListener((replication) => { - console.log(`Replication type :: ${replication.isPush ? "Push" : "Pull"}`); +import { ListenerToken } from 'cbl-reactnative'; + +const token: ListenerToken = await replicator.addDocumentChangeListener((replication) => { + const direction = replication.isPush ? "Push" : "Pull"; + console.log(`${direction}: ${replication.documents.length} documents`); + for (const document of replication.documents) { if (document.error === undefined) { - console.log(`Doc ID :: ${document.id}`); + console.log(` Doc ID: ${document.id}`); + if (document.flags.includes('DELETED')) { - console.log("Successfully replicated a deleted document"); + console.log(" Successfully replicated a deleted document"); } } else { - console.error("Error replicating document:", document.error); + console.error(` Error: ${document.error.message}`); } } }); -// Start the replicator without resetting the checkpoint +// Start the replicator await replicator.start(false); ``` #### Example 16. Stop document listener -This code snippet shows how to stop the document listener using the token from the previous example. - ```typescript -await this.replicator.removeChangeListener(token); +// Remove listener using new API +await token.remove(); ``` +:::caution Deprecated +The `replicator.removeChangeListener(token)` method is deprecated. It remains available for backward compatibility, but new applications should use `token.remove()`. Existing applications are strongly encouraged to migrate. +::: + ### Document Access Removal Behavior When access to a document is removed on Sync Gateway (see: Sync Gateway’s [Sync Function](https://docs.couchbase.com/sync-gateway/current/sync-function-api.html)), the document replication listener sends a notification with the `AccessRemoved` flag set to `true` and subsequently purges the document from the database. @@ -763,10 +912,10 @@ You can find further information on database operations in [Databases](../databa ```typescript // Remove the change listener -await this.replicator.removeChangeListener(token) +await token.remove() // Stop the replicator -await this.replicator.stop() +await replicator.stop() ``` Here we initiate the stopping of the replication using the `stop()` method. It will stop any active `change listener` once the replication is stopped. @@ -819,15 +968,20 @@ As always, when there is a problem with replication, logging is your friend. You #### Example 21. Set logging verbosity - ```typescript -// Verbose / Replicator -database.setLogLevel(LogDomain.REPLICATOR, Loglevel.VERBOSE); +import { LogSinks, LogLevel, LogDomain } from 'cbl-reactnative'; -// Verbose / Network -database.setLogLevel(LogDomain.NETWORK, Loglevel.VERBOSE); +// Verbose / Replicator and Network +await LogSinks.setConsole({ + level: LogLevel.VERBOSE, + domains: [LogDomain.REPLICATOR, LogDomain.NETWORK] +}); ``` +:::caution +Enable VERBOSE logging only during development or debugging. Avoid using it in production builds. +::: + For more on troubleshooting with logs, see: [Using Logs](../Troubleshooting/using-logs.md). ### Authentication Errors diff --git a/docs/Guides/Migration/_category_.json b/docs/Guides/Migration/_category_.json new file mode 100644 index 0000000..a937a07 --- /dev/null +++ b/docs/Guides/Migration/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Migration", + "position": 1, + "collapsible": true, + "collapsed": false +} + diff --git a/docs/Guides/Migration/v1.md b/docs/Guides/Migration/v1.md new file mode 100644 index 0000000..62f8970 --- /dev/null +++ b/docs/Guides/Migration/v1.md @@ -0,0 +1,259 @@ +--- +id: migration-guide-v1 +sidebar_position: 1 +--- + +# Version 1.0 + +> Description — _Quick reference for all API changes in cbl-reactnative version 1.0_ +> Related Content — [Release Notes](../../ProductNotes/release-notes.md) | [Using Logs](../../Troubleshooting/using-logs.md) + +:::important AT A GLANCE +Version 1.0 introduces several API changes: + +1. **Log Sink API** - Replaces `Database.setLogLevel()` with `LogSinks` API +2. **Listener Token API** - New `token.remove()` replaces `removeChangeListener()` +3. **New ReplicatorConfiguration** - Collections passed in constructor +::: + +## Breaking Changes + +### Listener Token Return Type (TypeScript) + +We changed all `addChangeListener` functions to return a `ListenerToken` instead of a `string`, enabling the new `token.remove()` API and aligning with other platforms. + +This is a breaking change **only for TypeScript code** that explicitly typed the token as `string`. JavaScript users and untyped TypeScript won't be affected. + +**TypeScript Migration Example:** + +```typescript +// BEFORE (TypeScript compilation error in 1.0) +const token: string = await collection.addChangeListener(listener); + +// AFTER +const token: ListenerToken = await collection.addChangeListener(listener); +token.remove(); +``` + +The existing `removeChangeListener(token)` methods remain available for backward compatibility but are deprecated. + +--- + +## Deprecated APIs + +### 1. Logging API + +The old `Database.setLogLevel()` API is deprecated and replaced with the new `LogSinks` API. + +**OLD (Deprecated):** +```typescript +// This API is deprecated +await db.setLogLevel(LogDomain.ALL, LogLevel.VERBOSE); +await Database.setLogLevel(LogDomain.DATABASE, LogLevel.INFO); +``` + +**NEW (Required in 1.0):** +```typescript +import { LogSinks, LogLevel, LogDomain } from 'cbl-reactnative'; + +await LogSinks.setConsole({ + level: LogLevel.VERBOSE, + domains: [LogDomain.ALL] +}); +``` + +:::caution Important +The old and new logging APIs cannot be used in tandem. If you are migrating to version 1.0, you must replace all instances of `Database.setLogLevel()` with `LogSinks.setConsole()`. +::: + +**Migration:** Search your code for `setLogLevel` and replace with `LogSinks.setConsole`. + +See: [Using Logs](../../Troubleshooting/using-logs.md) + +--- + +### 2. ReplicatorConfiguration API + +The old constructor pattern using `addCollection()` is deprecated. + +**OLD (Deprecated):** +```typescript +const config = new ReplicatorConfiguration(endpoint); +config.addCollection(collection); +const replicator = await Replicator.create(config); +``` + +**NEW (Recommended in 1.0):** +```typescript +import { CollectionConfiguration } from 'cbl-reactnative'; + +const collectionConfig = new CollectionConfiguration(collection); +const config = new ReplicatorConfiguration([collectionConfig], endpoint); +const replicator = await Replicator.create(config); +``` + +This method is deprecated. It remains available for backward compatibility, but new applications should use the new constructor pattern. Existing applications are strongly encouraged to migrate. + +See: [Remote Sync](../../DataSync/remote-sync-gateway.md#example-1-replication-configuration-and-initialization) + +--- + +### 3. Listener Removal Methods (Deprecated) + +**OLD (Deprecated in 1.0):** +```typescript +await collection.removeChangeListener(token); +await query.removeChangeListener(token); +await replicator.removeChangeListener(token); +``` + +**NEW (Recommended in 1.0):** +```typescript +await token.remove(); +``` + +This method is deprecated. It remains available for backward compatibility, but new applications should use `token.remove()`. Existing applications are strongly encouraged to migrate. + +--- + +## New Features in 1.0 + +### 1. Three Log Sink Types + +```typescript +// Console Sink - for development +await LogSinks.setConsole({ + level: LogLevel.VERBOSE, + domains: [LogDomain.ALL] +}); + +// File Sink - for production logging +await LogSinks.setFile({ + level: LogLevel.WARNING, + directory: logDir, + maxKeptFiles: 5, + maxFileSize: 1024 * 1024, + usePlaintext: true +}); + +// Custom Sink - for analytics +await LogSinks.setCustom({ + level: LogLevel.ERROR, + domains: [LogDomain.ALL], + callback: (level, domain, message) => { + Analytics.log({ level, domain, message }); + } +}); +``` + +See: [Using Logs](../../Troubleshooting/using-logs.md) + +--- + +### 2. All 5 Change Listener Types + +Now fully documented with examples: + +```typescript +// 1. Collection Change Listener +const token1 = await collection.addChangeListener((change) => { + console.log('Changed docs:', change.documentIDs); // Capital IDs! +}); + +// 2. Document Change Listener +const token2 = await collection.addDocumentChangeListener('doc-id', (change) => { + console.log('Doc changed:', change.documentId); // Lowercase Id! +}); + +// 3. Query Change Listener (Live Query) +const token3 = await query.addChangeListener((change) => { + console.log('Results:', change.results); +}); + +// 4. Replicator Status Listener +const token4 = await replicator.addChangeListener((change) => { + const status = change.status; + console.log('Level:', status.getActivityLevel()); + console.log('Progress:', status.getProgress().getCompleted()); +}); + +// 5. Replicator Document Listener +const token5 = await replicator.addDocumentChangeListener((change) => { + console.log('Direction:', change.isPush ? 'Push' : 'Pull'); +}); + +// All use same removal pattern +await token1.remove(); +``` + +See: [Scopes and Collections](../../scopes-collections.md#collection-change-listeners) | [Documents](../../documents.md#document-change-listeners) | [Live Queries](../../Queries/live-queries.md) | [Remote Sync](../../DataSync/remote-sync-gateway.md#change-listeners) + +--- + +### 3. Collection.fullName() + +```typescript +const fullName = await collection.fullName(); +console.log(fullName); // "production.users" +``` + +See: [Scopes and Collections](../../scopes-collections.md#get-collection-full-name) + +--- + +## Quick Migration Steps + +**Step 1: Update Logging (Required)** + +Find and replace in your code: + +```bash +# Search for old API +grep -r "setLogLevel" . + +# Replace with LogSinks.setConsole +``` + +**Step 2: Update ReplicatorConfiguration (Recommended)** + +```typescript +// Old (deprecated) +const config = new ReplicatorConfiguration(endpoint); +config.addCollection(collection); + +// New (recommended) +const collectionConfig = new CollectionConfiguration(collection); +const config = new ReplicatorConfiguration([collectionConfig], endpoint); +``` + +**Step 3: Update Listener Cleanup (Recommended)** + +```typescript +// Old (deprecated) +await collection.removeChangeListener(token); + +// New (recommended) +await token.remove(); +``` + +--- + +## Important Property Names + +| Listener Type | Property | Correct | Wrong | +|--------------|----------|---------|-------| +| Collection Change | Document IDs | `documentIDs` | `documentIds` | +| Document Change | Document ID | `documentId` | `documentID` | +| Collection Change | Database | `collection.database` | `database` | +| Document Change | Database | `database` | N/A | +| Replicator Progress | Completed | `getCompleted()` | `completed` | +| Replicator Progress | Total | `getTotal()` | `total` | + +--- + +## Need Help? + +- **Log Sink Examples:** [Using Logs](../../Troubleshooting/using-logs.md) +- **Replication Setup:** [Remote Sync](../../DataSync/remote-sync-gateway.md) +- **Full Release Notes:** [Version 1.0](../../ProductNotes/release-notes.md) + diff --git a/docs/Guides/_category_.json b/docs/Guides/_category_.json new file mode 100644 index 0000000..3ced3d2 --- /dev/null +++ b/docs/Guides/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Guides", + "position": 17, + "collapsible": true, + "collapsed": false +} + diff --git a/docs/ProductNotes/_category_.json b/docs/ProductNotes/_category_.json index bc28e72..b1052d5 100644 --- a/docs/ProductNotes/_category_.json +++ b/docs/ProductNotes/_category_.json @@ -1,6 +1,6 @@ { "label": "Product Notes", - "position": 17, + "position": 18, "link": { "type": "generated-index", "description": "Learn more about releases, compatibility, and supported platforms." diff --git a/docs/ProductNotes/release-notes.md b/docs/ProductNotes/release-notes.md index f8b153c..b0514ca 100644 --- a/docs/ProductNotes/release-notes.md +++ b/docs/ProductNotes/release-notes.md @@ -5,6 +5,46 @@ sidebar_position: 1 # Release Notes +**1.0.0** (December 2025) + +New Features: +- Log Sink API - Console, File, and Custom log sinks with configurable levels and domains +- LogDomain.ALL - New domain to enable all log categories at once +- Listener Token Management - New `ListenerToken` class with `token.remove()` API +- Collection Change Listeners - Monitor all documents in a collection +- Document Change Listeners - Monitor specific documents by ID +- Query Change Listeners (Live Queries) - Real-time query results +- Replicator Status Change Listeners - Monitor replication state and progress +- Replicator Document Change Listeners - Track individual document replication +- New ReplicatorConfiguration API - Collections passed during initialization using CollectionConfiguration +- Collection.fullName() method - Get fully qualified collection name (scope.collection) +- Couchbase Lite 3.3.0 - Updated iOS and Android SDKs to Couchbase Lite 3.3.0 + +Breaking Changes: +- TypeScript: ListenerToken type changed from string to ListenerToken object (affects explicitly typed code only) + +Deprecated APIs (Remain available for backward compatibility): +- Database.setLogLevel() - Use LogSinks.setConsole() instead. Note: Old and new logging APIs cannot be used in tandem. +- config.addCollection(collection) - Pass CollectionConfiguration array in constructor instead +- removeChangeListener() methods - Use token.remove() instead +- ListenerToken type changed from string to ListenerToken object (TypeScript breaking change for explicitly typed code) + +Bug Fixes: +- Fixed encryption key crash when key not required +- Fixed Kotlin import paths and enhanced logging methods +- Improved blob data validation and array handling +- Fixed custom delete issues + +Migration from 0.6.x: +1. Replace Database.setLogLevel() with LogSinks.setConsole() (required - APIs cannot be mixed) +2. Update ReplicatorConfiguration to use new constructor pattern (recommended) +3. Update listener cleanup to use token.remove() (recommended) +4. Update TypeScript code that explicitly typed tokens as string to use ListenerToken (required for TypeScript) + +See [Migration Guide](../Guides/Migration/v1.md) for detailed instructions. + +--- + **0.6.3** - Array handling and improve blob data validation in DataAdapter [null-pointer issue](https://github.com/Couchbase-Ecosystem/cbl-reactnative/pull/73) - Fix a crash caused by improper handling of encryption key diff --git a/docs/Queries/live-queries.md b/docs/Queries/live-queries.md index 6f9fd05..6f2059f 100644 --- a/docs/Queries/live-queries.md +++ b/docs/Queries/live-queries.md @@ -23,25 +23,153 @@ Each time you start watching a live query, the query is executed and an initial #### Example 1. Starting a Live Query - Change Listener ```typescript -// Register a change listener and await the Promise returned from the registration call. -const token = await query.addChangeListener((change) => { - if (change.error !== null && change.error !== undefined) { - // deal with error... - } else { - const results = change.results; - //loop through ResultSet - for (const doc of results) { - //do something with doc - } +import { ListenerToken } from 'cbl-reactnative'; + +// Register a change listener +const token: ListenerToken = await query.addChangeListener((change) => { + if (change.error) { + console.error('Query error:', change.error); + return; + } + + const results = change.results; + // results is an array of result objects + for (const doc of results) { + console.log('Result:', doc); } }); ``` -To stop receiving notifications, call `Query.removeChangeListener` with the token that was returned from the registration call. Regardless of the whether the API is synchronous or asynchronous, listeners will stop receiving notifications immediately: +:::note Version 1.0 +Change listeners now return a `ListenerToken` object with a `remove()` method for cleanup. +::: #### Example 2. Stopping a Live Query - Change Listener ```typescript -const token = await query.addChangeListener((change) => { ... }); +// Remove listener using new API +await token.remove(); +``` + +:::caution Deprecated +The `query.removeChangeListener(token)` method is deprecated. It remains available for backward compatibility, but new applications should use `token.remove()`. Existing applications are strongly encouraged to migrate. + +```typescript +// DEPRECATED await query.removeChangeListener(token); + +// RECOMMENDED +await token.remove(); +``` +::: + +## Query Change Data Structure + +When a query result changes, your callback receives a `QueryChange` object: + +```typescript +interface QueryChange { + error: string; // Error message if query failed + query: Query; // Reference to the query + results: ResultSet; // Array of result objects +} +``` + +#### Example 3. Complete Live Query with Error Handling + +```typescript +import { ListenerToken } from 'cbl-reactnative'; + +const query = database.createQuery( + 'SELECT META().id, name, email FROM _default.users WHERE isActive = true' +); + +const token: ListenerToken = await query.addChangeListener((change) => { + if (change.error) { + console.error('Query error:', change.error); + return; + } + + console.log(`Found ${change.results.length} active users`); + change.results.forEach(result => { + console.log(`User: ${result.name} - ${result.email}`); + }); +}); + +// Remove when done +await token.remove(); +``` + +#### Example 4. React Hook Pattern for Live Queries + +```typescript +import { useEffect, useState } from 'react'; +import { ListenerToken } from 'cbl-reactnative'; + +function ActiveUsersScreen({ database }) { + const [users, setUsers] = useState([]); + + useEffect(() => { + if (!database) return; + + let token; + + const setup = async () => { + const query = database.createQuery( + 'SELECT META().id, name FROM _default.users WHERE isActive = true' + ); + + token = await query.addChangeListener((change) => { + if (!change.error) { + setUsers(change.results); + } + }); + }; + setup(); + + // Cleanup on unmount + return () => { + if (token && !token.isRemoved()) { + token.remove(); + } + }; + }, [database]); + + return ( + // Render users list + ); +} +``` + +## Best Practices + +**Always Remove Listeners** + +In React components, use the cleanup function to prevent memory leaks: + +```typescript +useEffect(() => { + let token; + + const setup = async () => { + token = await query.addChangeListener((change) => { + // Handle changes + }); + }; + setup(); + + return () => { + if (token && !token.isRemoved()) { + token.remove(); + } + }; +}, [query]); +``` + +**Check Before Removing** + +```typescript +if (!token.isRemoved()) { + await token.remove(); +} ``` \ No newline at end of file diff --git a/docs/Queries/sqlplusplus.md b/docs/Queries/sqlplusplus.md index 65d1a94..61e0ec8 100644 --- a/docs/Queries/sqlplusplus.md +++ b/docs/Queries/sqlplusplus.md @@ -6,7 +6,7 @@ sidebar_position: 1 # SQL++ for Mobile > Description - _How to use SQL++ Query Strings to build effective queries with Couchbase Lite for React Native_ -> Related Content - [Live Queries](../live-queries.md) | [Indexes](../indexes.md) +> Related Content - [Live Queries](live-queries.md) | [Indexes](../indexes.md) :::info N1QL is Couchbase's implementation of the developing SQL++ standard. As such the terms N1QL and SQL++ are used interchangeably in all Couchbase documentation unless explicitly stated otherwise. diff --git a/docs/Troubleshooting/using-logs.md b/docs/Troubleshooting/using-logs.md index ede2ae0..fdf5cd0 100644 --- a/docs/Troubleshooting/using-logs.md +++ b/docs/Troubleshooting/using-logs.md @@ -5,8 +5,8 @@ sidebar_position: 1 # Using Logs for Troubleshooting -> Description — _Couchbase Lite on React Native — Using Logs for Troubleshooting_ -> Related Content — [Troubleshooting Queries](troubeshoot-queries.md) | [Troubleshooting Crashes](troubleshoot-crashes.md) +> Description — _Couchbase Lite on React Native — Using Logs for Troubleshooting_ +> Related Content — [Troubleshooting Queries](troubeshoot-queries.md) | [Troubleshooting Crashes](troubleshoot-crashes.md) :::note * The retrieval of logs from the device is out of scope of this feature. @@ -14,7 +14,7 @@ sidebar_position: 1 ## Introduction -Couchbase Lite provides a robust Logging API — see: API References for Logging classes — which make debugging and troubleshooting easier during development and in production. It delivers flexibility in terms of how logs are generated and retained, whilst also maintaining the level of logging required by Couchbase Support for investigation of issues. +Couchbase Lite provides a robust Logging API — see: API References for Logging classes — which make debugging and troubleshooting easier during development and in production. It delivers flexibility in terms of how logs are generated and retained, whilst also maintaining the level of logging required by Couchbase Support for investigation of issues. Log output is split into the following streams: @@ -30,16 +30,166 @@ Log output is split into the following streams: For greater flexibility you can implement a custom logging class using the ILogger interface. -## Console based logging +## Log Sink API -Console based logging is often used to facilitate troubleshooting during development. +Version 1.0 introduces the Log Sink API which provides three types of log sinks for flexible logging control. -Console logs are your go-to resource for diagnostic information. You can easily fine-tune their diagnostic content to meet the needs of a particular debugging scenario, perhaps by increasing the verbosity and-or choosing to focus on messages from a specific domain; to better focus on the problem area. +### Log Levels -Changes to console logging are independent of file logging, so you can make change without compromising any files logging streams. It is enabled by default. To change default settings use database’s setLogLevel method to set the required values — see Example 1. +| Level | Value | Description | +|-------|-------|-------------| +| LogLevel.DEBUG | 0 | Most verbose - all logs | +| LogLevel.VERBOSE | 1 | Detailed diagnostic logs | +| LogLevel.INFO | 2 | Informational messages | +| LogLevel.WARNING | 3 | Warning messages only | +| LogLevel.ERROR | 4 | Error messages only | +| LogLevel.NONE | 5 | No logging | -#### Example 1. Change Console Logging Settings +### Log Domains + +| Domain | Description | +|--------|-------------| +| LogDomain.DATABASE | Database operations | +| LogDomain.QUERY | Query execution and planning | +| LogDomain.REPLICATOR | Replication activity | +| LogDomain.NETWORK | Network operations | +| LogDomain.LISTENER | Change listeners | +| LogDomain.ALL | All domains (new in 1.0) | + +## Console Log Sink + +Console based logging outputs logs to the system console (stdout/stderr), useful for development and debugging. + +#### Example 1. Enable Console Logging + +```typescript +import { LogSinks, LogLevel, LogDomain } from 'cbl-reactnative'; + +// Enable verbose logging for all domains +await LogSinks.setConsole({ + level: LogLevel.VERBOSE, + domains: [LogDomain.ALL] +}); +``` + +#### Example 2. Console with Specific Domains + +```typescript +// Log only replication and network activity +await LogSinks.setConsole({ + level: LogLevel.INFO, + domains: [LogDomain.REPLICATOR, LogDomain.NETWORK] +}); +``` + +#### Example 3. Disable Console Logging + +```typescript +// Disable console logging +await LogSinks.setConsole(null); +``` + +## File Log Sink + +File logging writes logs to files on the device with automatic rotation and retention policies. + +#### Example 4. Enable File Logging + +```typescript +import { Platform } from 'react-native'; +import RNFS from 'react-native-fs'; + +// Determine platform-specific log directory +const logDirectory = Platform.OS === 'ios' + ? RNFS.DocumentDirectoryPath + '/logs' + : RNFS.ExternalDirectoryPath + '/logs'; + +await LogSinks.setFile({ + level: LogLevel.INFO, + directory: logDirectory, + maxKeptFiles: 5, // Keep 5 old log files + maxFileSize: 1024 * 1024, // 1MB max file size + usePlaintext: true // Use plaintext format +}); +``` + +:::note File Rotation +When a log file reaches `maxFileSize`, it's closed and a new one is created. Old files exceeding `maxKeptFiles` are automatically deleted. +::: + +#### Example 5. Disable File Logging + +```typescript +await LogSinks.setFile(null); +``` + +## Custom Log Sink + +Custom logging allows you to implement your own logging logic with a callback function. + +#### Example 6. Custom Logging with Callback + +```typescript +await LogSinks.setCustom({ + level: LogLevel.ERROR, + domains: [LogDomain.ALL], + callback: (level, domain, message) => { + const timestamp = new Date().toISOString(); + console.log(`[${timestamp}] [${domain}] ${message}`); + + // You can also send to analytics, log to database, etc. + } +}); +``` + +#### Example 7. Disable Custom Logging ```typescript -Database.setLogLevel(LogDomain.ALL, Loglevel.VERBOSE); +await LogSinks.setCustom(null); ``` + +## Using Multiple Log Sinks + +You can enable multiple log sinks simultaneously for different purposes. + +#### Example 8. Development and Production Configuration + +```typescript +if (__DEV__) { + // Development: Verbose console logging + await LogSinks.setConsole({ + level: LogLevel.VERBOSE, + domains: [LogDomain.ALL] + }); +} else { + // Production: File logging for warnings and errors + await LogSinks.setFile({ + level: LogLevel.WARNING, + directory: logDirectory, + maxKeptFiles: 7, + maxFileSize: 2 * 1024 * 1024, + usePlaintext: true + }); + + // Also send errors to analytics + await LogSinks.setCustom({ + level: LogLevel.ERROR, + domains: [LogDomain.ALL], + callback: (level, domain, message) => { + Analytics.logError({ level, domain, message }); + } + }); +} +``` + +## Platform Considerations + +**iOS:** +- Log files are stored in the app's Documents directory +- Path: `RNFS.DocumentDirectoryPath + '/logs'` +- Accessible via iTunes File Sharing if enabled in Info.plist + +**Android:** +- Log files are stored in the app's external directory +- Path: `RNFS.ExternalDirectoryPath + '/logs'` +- May require storage permissions in AndroidManifest.xml diff --git a/docs/databases.md b/docs/databases.md index 6855fc8..7f85300 100644 --- a/docs/databases.md +++ b/docs/databases.md @@ -176,18 +176,70 @@ You can download and build it from the couchbaselabs [GitHub repository](https:/ ## Troubleshooting -You should use console logs as your first source of diagnostic information. If the information in the default logging level is insufficient you can focus it on database errors and generate more verbose messages. - +You should use console logs as your first source of diagnostic information. If the default logging level is insufficient, you can enable verbose logging scoped specifically to database operations. ```typescript +import { LogSinks, LogLevel, LogDomain } from 'cbl-reactnative'; + try { - await db.setLogLevel(LogDomain.DATABASE, LogLevel.VERBOSE); - console.log('Database log level set to VERBOSE.'); + await LogSinks.setConsole({ + level: LogLevel.VERBOSE, + domains: [LogDomain.DATABASE] + }); + console.log('Database logging enabled.'); } catch (error) { console.error('Setting log level failed:', error); } ``` +:::caution +Enable VERBOSE logging only during development or debugging. Avoid using it in production builds. +::: + +For more on using logs for troubleshooting, see [Using Logs](Troubleshooting/using-logs.md). + +## Listener Token API + +Version 1.0 introduces the `ListenerToken` class for improved listener management across all change listener types. + +All `addChangeListener` methods return a `ListenerToken` object with these methods: + +**remove()** - Removes the listener (recommended) + +```typescript +const token = await collection.addChangeListener(...); +await token.remove(); +``` + +**getUuidToken()** - Gets the internal UUID string (for debugging) + +```typescript +const uuid = token.getUuidToken(); +console.log('Token:', uuid); // "listener-abc-123-def-456" +``` + +**isRemoved()** - Checks if listener was already removed + +```typescript +if (!token.isRemoved()) { + await token.remove(); +} +``` + +:::caution Deprecated Methods +The `removeChangeListener()` methods on Collection, Query, and Replicator are deprecated. This method is deprecated. It remains available for backward compatibility, but new applications should use `token.remove()`. Existing applications are strongly encouraged to migrate. + +```typescript +// DEPRECATED +await collection.removeChangeListener(token); +await query.removeChangeListener(token); +await replicator.removeChangeListener(token); + +// RECOMMENDED +await token.remove(); +``` +::: + diff --git a/docs/documents.md b/docs/documents.md index 35a39b4..3cda1e5 100644 --- a/docs/documents.md +++ b/docs/documents.md @@ -334,20 +334,103 @@ document.setDate('createdAt', new Date()); await collection.save(document); ``` -## Document change events +## Document Change Listeners -It is possible to register for document changes. The following example registers for changes to the document with ID user.john and prints the verified_account property when a change is detected. +Monitor changes to a specific document by ID. Couchbase Lite allows you to register listeners to be notified when documents change. Version 1.0 introduces the `ListenerToken` API for better listener lifecycle management. + +### When to Use + +- Watch a user profile for updates +- Monitor a shopping cart +- Track order status changes +- Real-time document collaboration + +### Data Structure + +```typescript +interface DocumentChange { + documentId: string; // Document ID (lowercase Id) + collection: Collection; // Collection reference + database: Database; // Database reference (available!) +} +``` + +:::note +Unlike collection listeners, document change listeners DO have a direct `database` property. +::: + +#### Example 7. Monitor Specific Document ```typescript -const token = collection.addDocumentChangeListener('user.john', async (change) => { - const document = await collection.document(change.documentID); - if (document !== null) { - console.log(`Status: ${document.getString('verified_account')}`); +import { ListenerToken } from 'cbl-reactnative'; + +const token: ListenerToken = await collection.addDocumentChangeListener( + 'user-123', + async (change) => { + console.log(`Document ${change.documentId} changed`); + + // Fetch latest version + const doc = await collection.document(change.documentId); + if (doc) { + console.log('New data:', doc.getData()); + } else { + console.log('Document was deleted'); + } } +); + +// Remove when done +await token.remove(); +``` + +#### Example 8. Multiple Document Listeners + +```typescript +// Monitor multiple specific documents +const userToken = await collection.addDocumentChangeListener('user-123', (change) => { + console.log('User changed'); +}); + +const cartToken = await collection.addDocumentChangeListener('cart-abc', (change) => { + console.log('Cart changed'); }); -// Remove the change listener when it is no longer needed -await collection.removeDocumentChangeListener(token); +// Cleanup all +await Promise.all([userToken.remove(), cartToken.remove()]); +``` + +:::tip New in Version 1.0 +Change listeners now return a `ListenerToken` object. Use `token.remove()` to remove the listener. +::: + +:::caution Deprecated +The `collection.removeDocumentChangeListener(token)` method is deprecated. It remains available for backward compatibility, but new applications should use `token.remove()`. Existing applications are strongly encouraged to migrate. +::: + +### Common Pitfalls + +:::caution Property Name +```typescript +change.documentId // CORRECT (lowercase Id) +change.documentID // WRONG - will be undefined +``` + +Getting this property name wrong is a common source of errors. +::: + +**Async Handling in Callbacks** + +```typescript +// WRONG - promise not awaited +const token = await collection.addDocumentChangeListener('doc-id', (change) => { + collection.document(change.documentId); // Returns promise, not awaited! +}); + +// CORRECT - proper async handling +const token = await collection.addDocumentChangeListener('doc-id', async (change) => { + const doc = await collection.document(change.documentId); + console.log('Document:', doc); +}); ``` ## Document Expiration diff --git a/docs/intro.md b/docs/intro.md index ff4dea9..7a4db9a 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -50,6 +50,10 @@ Couchbase Lite for React Native is a community provided solution that is activel * Encryption - Full Database +## Upgrading from 0.6.x? + +See the [Migration Guide](Guides/Migration/v1.md) for detailed instructions on upgrading to version 1.0. + ## Limitations Some of the features supported by other platform implementations of Couchbase Lite are currently not supported: @@ -57,6 +61,4 @@ Some of the features supported by other platform implementations of Couchbase Li - This is still in beta for the native platforms and is not yet supported in the plugin. * Peer-to-Peer Sync - - There is no "platform" specific code built into the plugin to allow you to find other peers. - -* Current beta release does not support Event Listeners for changes (Change Notifications). \ No newline at end of file + - There is no "platform" specific code built into the plugin to allow you to find other peers. \ No newline at end of file diff --git a/docs/scopes-collections.md b/docs/scopes-collections.md index e963655..e276d93 100644 --- a/docs/scopes-collections.md +++ b/docs/scopes-collections.md @@ -102,4 +102,115 @@ const scopes = await database.scopes(); // Get Collections of a particular Scope const collections = await database.collections(scopeName); -``` \ No newline at end of file +``` + +## Get Collection Full Name + +The `fullName()` method returns the fully qualified name of a collection in the format "scope.collection". + +The full name is useful for logging, debugging, and displaying collection information in your application. + +**Example 5. Get Collection Full Name** + +```typescript +// User-defined collection +const collection = await database.createCollection('users', 'production'); +const fullName = await collection.fullName(); +console.log(fullName); +// Output: "production.users" + +// Default collection +const defaultCol = await database.defaultCollection(); +const defaultName = await defaultCol.fullName(); +console.log(defaultName); +// Output: "_default._default" +``` + +## Collection Change Listeners + +Monitor all changes to any document in a collection. + +### When to Use + +- Refresh list views when data changes +- Trigger background sync after local updates +- Audit logging of collection activity +- Real-time collaboration features + +### Data Structure + +When a collection changes, your callback receives a `CollectionChange` object: + +```typescript +interface CollectionChange { + documentIDs: string[]; // Array of changed document IDs + collection: Collection; // Reference to the collection +} +``` + +:::caution Property Names +The property is `documentIDs` (capital IDs), not `documentIds`. + +There is NO direct `database` property. Access it via `change.collection.database`. +::: + +#### Example 6. Basic Collection Listener + +```typescript +import { Collection, ListenerToken } from 'cbl-reactnative'; + +const collection = await database.createCollection('users'); + +const token: ListenerToken = await collection.addChangeListener((change) => { + console.log('Collection changed!'); + console.log('Changed documents:', change.documentIDs); + // Example output: ['user-123', 'user-456'] + + console.log('Collection name:', change.collection.name); + // Output: users + + console.log('Database name:', change.collection.database.getName()); + // Output: mydb +}); + +// Remove listener when done +await token.remove(); +``` + +#### Example 7. React Hook Pattern + +```typescript +import { useEffect } from 'react'; +import { ListenerToken } from 'cbl-reactnative'; + +function UserListScreen({ collection }) { + useEffect(() => { + if (!collection) return; + + let token; + + const setup = async () => { + token = await collection.addChangeListener((change) => { + console.log(`${change.documentIDs.length} documents changed`); + refreshUserList(); + }); + }; + setup(); + + // Cleanup on unmount + return () => { + if (token) token.remove(); + }; + }, [collection]); +} +``` + +:::important Limitation +Only ONE collection-wide listener is allowed per collection instance. Calling `addChangeListener` twice will throw an error. + +However, you can have MULTIPLE document listeners on the same collection. +::: + +:::caution Deprecated +The `collection.removeChangeListener(token)` method is deprecated. It remains available for backward compatibility, but new applications should use `token.remove()`. Existing applications are strongly encouraged to migrate. +::: \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index b557435..69aa7b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -100,6 +100,11 @@ resolved "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.15.0.tgz" integrity sha512-IofrVh213VLsDkPoSKMeM9Dshrv28jhDlBDLRcVJQvlL8pzue7PEB1EZ4UoJFYS3NSn7JOcJ/V+olRQzXlJj1w== +"@algolia/client-common@5.46.1": + version "5.46.1" + resolved "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.46.1.tgz" + integrity sha512-3u6AuZ1Kiss6V5JPuZfVIUYfPi8im06QBCgKqLg82GUBJ3SwhiTdSZFIEgz2mzFuitFdW1PQi3c/65zE/3FgIw== + "@algolia/client-insights@5.15.0": version "5.15.0" resolved "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.15.0.tgz" @@ -139,6 +144,16 @@ "@algolia/requester-fetch" "5.15.0" "@algolia/requester-node-http" "5.15.0" +"@algolia/client-search@>= 4.9.1 < 6": + version "5.46.1" + resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.1.tgz" + integrity sha512-NL76o/BoEgU4ObY5oBEC3o6KSPpuXsnSta00tAxTm1iKUWOGR34DQEKhUt8xMHhMKleUNPM/rLPFiIVtfsGU8w== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" + "@algolia/client-search@4.24.0": version "4.24.0" resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz" @@ -236,6 +251,13 @@ dependencies: "@algolia/client-common" "5.15.0" +"@algolia/requester-browser-xhr@5.46.1": + version "5.46.1" + resolved "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.1.tgz" + integrity sha512-3GfCwudeW6/3caKSdmOP6RXZEL4F3GiemCaXEStkTt2Re8f7NcGYAAZnGlHsCzvhlNEuDzPYdYxh4UweY8l/2w== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-common@4.24.0": version "4.24.0" resolved "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz" @@ -248,6 +270,13 @@ dependencies: "@algolia/client-common" "5.15.0" +"@algolia/requester-fetch@5.46.1": + version "5.46.1" + resolved "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.46.1.tgz" + integrity sha512-JUAxYfmnLYTVtAOFxVvXJ4GDHIhMuaP7JGyZXa/nCk3P8RrN5FCNTdRyftSnxyzwSIAd8qH3CjdBS9WwxxqcHQ== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-node-http@4.24.0": version "4.24.0" resolved "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz" @@ -262,6 +291,13 @@ dependencies: "@algolia/client-common" "5.15.0" +"@algolia/requester-node-http@5.46.1": + version "5.46.1" + resolved "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.46.1.tgz" + integrity sha512-VwbhV1xvTGiek3d2pOS6vNBC4dtbNadyRT+i1niZpGhOJWz1XnfhxNboVbXPGAyMJYz7kDrolbDvEzIDT93uUA== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/transporter@4.24.0": version "4.24.0" resolved "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz" @@ -293,7 +329,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz" integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg== -"@babel/core@^7.21.3", "@babel/core@^7.25.9": +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.21.3", "@babel/core@^7.25.9", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": version "7.26.0" resolved "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz" integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== @@ -1718,7 +1754,7 @@ utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-docs@3.6.3": +"@docusaurus/plugin-content-docs@*", "@docusaurus/plugin-content-docs@3.6.3": version "3.6.3" resolved "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.6.3.tgz" integrity sha512-r2wS8y/fsaDcxkm20W5bbYJFPzdWdEaTWVYjNxlHlcmX086eqQR1Fomlg9BHTJ0dLXPzAlbC8EN4XqMr3QzNCQ== @@ -2097,7 +2133,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -2231,7 +2267,7 @@ "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" "@svgr/babel-plugin-transform-svg-component" "8.0.0" -"@svgr/core@8.1.0": +"@svgr/core@*", "@svgr/core@8.1.0": version "8.1.0" resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz" integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== @@ -2542,14 +2578,13 @@ "@types/history" "^4.7.11" "@types/react" "*" -"@types/react@*": - version "18.2.70" - resolved "https://registry.npmjs.org/@types/react/-/react-18.2.70.tgz" - integrity sha512-hjlM2hho2vqklPhopNkXkdkeq6Lv8WSZTpr7956zY+3WS5cfYUewtCzsJLsbW5dEv3lfSeQ4W14ZFeKC437JRQ== +"@types/react@*", "@types/react@>= 16.8.0 < 19.0.0", "@types/react@>=16": + version "18.3.27" + resolved "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz" + integrity sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w== dependencies: "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" + csstype "^3.2.2" "@types/retry@0.12.0": version "0.12.0" @@ -2563,11 +2598,6 @@ dependencies: "@types/node" "*" -"@types/scheduler@*": - version "0.16.8" - resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz" - integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== - "@types/send@*": version "0.17.4" resolved "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz" @@ -2633,7 +2663,7 @@ resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": +"@webassemblyjs/ast@^1.12.1", "@webassemblyjs/ast@1.12.1": version "1.12.1" resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz" integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== @@ -2734,7 +2764,7 @@ "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/wasm-parser" "1.12.1" -"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": +"@webassemblyjs/wasm-parser@^1.12.1", "@webassemblyjs/wasm-parser@1.12.1": version "1.12.1" resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz" integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== @@ -2784,10 +2814,10 @@ acorn-walk@^8.0.0: dependencies: acorn "^8.11.0" -acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.8.2: - version "8.14.0" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz" - integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.8.2: + version "8.15.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== address@^1.0.1, address@^1.1.2: version "1.2.2" @@ -2809,7 +2839,12 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: +ajv-keywords@^3.4.1: + version "3.5.2" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== @@ -2821,7 +2856,7 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.2, ajv@^6.12.5: +ajv@^6.12.2, ajv@^6.12.5, ajv@^6.9.1: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2831,7 +2866,7 @@ ajv@^6.12.2, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.8.2, ajv@^8.9.0: version "8.12.0" resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== @@ -2848,7 +2883,7 @@ algoliasearch-helper@^3.13.3: dependencies: "@algolia/events" "^4.0.1" -algoliasearch@^4.18.0: +algoliasearch@^4.18.0, "algoliasearch@>= 3.1 < 6", "algoliasearch@>= 4.9.1 < 6": version "4.24.0" resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz" integrity sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g== @@ -3124,7 +3159,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.23.0, browserslist@^4.23.1, browserslist@^4.23.3, browserslist@^4.24.0, browserslist@^4.24.2: +browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.23.0, browserslist@^4.23.1, browserslist@^4.23.3, browserslist@^4.24.0, browserslist@^4.24.2, "browserslist@>= 4.21.0": version "4.24.2" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz" integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== @@ -3752,30 +3787,37 @@ csso@^5.0.5: dependencies: css-tree "~2.2.0" -csstype@^3.0.2: - version "3.1.3" - resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" - integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +csstype@^3.2.2: + version "3.2.3" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz" + integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== debounce@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@2.6.9, debug@^2.6.0: +debug@^2.6.0: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: +debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + decode-named-character-reference@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz" @@ -3849,16 +3891,16 @@ del@^6.1.1: rimraf "^3.0.2" slash "^3.0.0" -depd@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - depd@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== +depd@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + dequal@^2.0.0: version "2.0.3" resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" @@ -4374,7 +4416,7 @@ figures@^3.2.0: dependencies: escape-string-regexp "^1.0.5" -file-loader@^6.2.0: +file-loader@*, file-loader@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz" integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== @@ -4668,16 +4710,16 @@ got@^12.1.0: p-cancelable "^3.0.0" responselike "^3.0.0" -graceful-fs@4.2.10: - version "4.2.10" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== +graceful-fs@4.2.10: + version "4.2.10" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz" @@ -4969,6 +5011,16 @@ http-deceiver@^1.2.7: resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + http-errors@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" @@ -4980,16 +5032,6 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - http-parser-js@>=0.5.1: version "0.5.8" resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" @@ -5093,7 +5135,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: +inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@2, inherits@2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -5103,16 +5145,16 @@ inherits@2.0.3: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -ini@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== - ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.8" resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== +ini@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + inline-style-parser@0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz" @@ -5135,16 +5177,16 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - ipaddr.js@^2.0.1: version "2.1.0" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz" integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + is-alphabetical@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz" @@ -5308,16 +5350,16 @@ is-yarn-global@^0.4.0: resolved "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz" integrity sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ== -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - isarray@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -6282,7 +6324,7 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": +"mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== @@ -6292,14 +6334,40 @@ mime-db@~1.33.0: resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz" integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== -mime-types@2.1.18, mime-types@~2.1.17: +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime-types@^2.1.31: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime-types@~2.1.17, mime-types@2.1.18: version "2.1.18" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz" integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== dependencies: mime-db "~1.33.0" -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@~2.1.24: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime-types@~2.1.34: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -6339,7 +6407,7 @@ minimalistic-assert@^1.0.0: resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -6718,6 +6786,13 @@ path-parse@^1.0.7: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" @@ -6728,13 +6803,6 @@ path-to-regexp@3.3.0: resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz" integrity sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw== -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" @@ -7311,7 +7379,7 @@ postcss-zindex@^6.0.2: resolved "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz" integrity sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg== -postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.26, postcss@^8.4.33, postcss@^8.4.38: +"postcss@^7.0.0 || ^8.0.1", postcss@^8, postcss@^8.0.3, postcss@^8.0.9, postcss@^8.1.0, postcss@^8.2.2, postcss@^8.4, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.24, postcss@^8.4.26, postcss@^8.4.31, postcss@^8.4.33, postcss@^8.4.38, postcss@^8.4.6: version "8.4.49" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz" integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== @@ -7429,16 +7497,21 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -range-parser@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz" - integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A== +range-parser@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -range-parser@^1.2.1, range-parser@~1.2.1: +range-parser@~1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== +range-parser@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz" + integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A== + raw-body@2.5.2: version "2.5.2" resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" @@ -7489,7 +7562,7 @@ react-dev-utils@^12.0.1: strip-ansi "^6.0.1" text-table "^0.2.0" -react-dom@^18.3.1: +react-dom@*, "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", react-dom@^18.0.0, react-dom@^18.3.1, "react-dom@>= 16.8.0 < 19.0.0": version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -7535,7 +7608,7 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1: dependencies: "@babel/runtime" "^7.10.3" -"react-loadable@npm:@docusaurus/react-loadable@6.0.0": +react-loadable@*, "react-loadable@npm:@docusaurus/react-loadable@6.0.0": version "6.0.0" resolved "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz" integrity sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ== @@ -7562,7 +7635,7 @@ react-router-dom@^5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-router@5.3.4, react-router@^5.3.4: +react-router@^5.3.4, react-router@>=5, react-router@5.3.4: version "5.3.4" resolved "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz" integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA== @@ -7577,7 +7650,7 @@ react-router@5.3.4, react-router@^5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react@^18.3.1: +react@*, "react@^16.13.1 || ^17.0.0 || ^18.0.0", "react@^16.6.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.3.1, "react@>= 16.8.0 < 19.0.0", react@>=15, react@>=16, react@>=16.0.0: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -7939,15 +8012,20 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== "safer-buffer@>= 2.1.2 < 3": version "2.1.2" @@ -7966,16 +8044,25 @@ scheduler@^0.23.2: dependencies: loose-envify "^1.1.0" -schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== +schema-utils@^3.0.0: + version "3.3.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.1.1: + version "3.3.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" -schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: +schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -7994,6 +8081,20 @@ schema-utils@^4.0.0, schema-utils@^4.0.1: ajv-formats "^2.1.1" ajv-keywords "^5.1.0" +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + +"search-insights@>= 1 < 3": + version "2.17.3" + resolved "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz" + integrity sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ== + section-matter@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz" @@ -8247,7 +8348,7 @@ source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0, source-map@~0.6.0: +source-map@^0.6.0: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -8257,6 +8358,11 @@ source-map@^0.7.0: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== +source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + space-separated-tokens@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" @@ -8295,22 +8401,45 @@ srcset@^4.0.0: resolved "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz" integrity sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw== -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + std-env@^3.7.0: version "3.8.0" resolved "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz" integrity sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w== -string-width@^4.1.0, string-width@^4.2.0: +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +string-width@^4.1.0: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8328,20 +8457,6 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - stringify-entities@^4.0.0: version "4.0.4" resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz" @@ -8565,6 +8680,11 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +"typescript@>= 2.7", typescript@>=4.9.5: + version "5.9.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz" + integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== + undici-types@~5.26.4: version "5.26.5" resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" @@ -8668,7 +8788,7 @@ universalify@^2.0.0: resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@~1.0.0, unpipe@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -8884,7 +9004,7 @@ webpack-sources@^3.2.3: resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.88.1, webpack@^5.95.0: +"webpack@^4.0.0 || ^5.0.0", "webpack@^4.37.0 || ^5.0.0", webpack@^5.0.0, webpack@^5.1.0, webpack@^5.20.0, webpack@^5.88.1, webpack@^5.95.0, "webpack@>= 4", "webpack@>=4.41.1 || 5.x", webpack@>=5, "webpack@3 || 4 || 5": version "5.96.1" resolved "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz" integrity sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA== @@ -8927,7 +9047,7 @@ webpackbar@^6.0.1: std-env "^3.7.0" wrap-ansi "^7.0.0" -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: +websocket-driver@^0.7.4, websocket-driver@>=0.5.1: version "0.7.4" resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==