feat(fetcher): add configureNativeFetcher cross-platform API

Add configureNativeFetcher() plugin method to enable TypeScript configuration
of native fetchers with API credentials. This provides a cross-platform
mechanism for passing configuration from JavaScript to native code without
relying on platform-specific storage.

- Add configure() method to NativeNotificationContentFetcher interface
  (optional, defaults to no-op for fetchers that don't need config)
- Add configureNativeFetcher plugin method in DailyNotificationPlugin
- Add TypeScript definitions and comprehensive JSDoc
- Create NATIVE_FETCHER_CONFIGURATION.md documentation
- Update TestNativeFetcher to use real API endpoint (10.0.2.2:3000)
- Update DemoNativeFetcher Javadoc explaining configure() is optional
- Add configureNativeFetcher() call to demo app's configurePlugin()

Enables host apps to configure native fetchers from TypeScript, keeping
the interface consistent across Android, iOS, and web platforms.
This commit is contained in:
Matthew Raymer
2025-10-30 10:03:47 +00:00
parent 59cd975c24
commit c1cc8802f6
5 changed files with 954 additions and 30 deletions

View File

@@ -314,6 +314,71 @@ export interface DailyNotificationPlugin {
// Configuration methods
configure(options: ConfigureOptions): Promise<void>;
/**
* Configure native fetcher with API credentials (cross-platform)
*
* This method provides a cross-platform mechanism for passing API credentials
* from TypeScript/JavaScript code to native fetcher implementations. The
* configuration is passed directly without using platform-specific storage
* mechanisms, keeping the interface consistent across Android, iOS, and web.
*
* **Why this exists:**
* - Native fetchers run in background workers (WorkManager/BGTaskScheduler)
* - Background workers cannot access JavaScript variables or Capacitor bridge
* - This method provides direct injection without storage dependencies
*
* **When to call:**
* - After app startup, once API credentials are available
* - After user login/authentication, when activeDid changes
* - When API server URL changes (dev/staging/production)
*
* **Prerequisites:**
* - Native fetcher must be registered in `Application.onCreate()` (Android)
* or `AppDelegate.didFinishLaunching()` (iOS) BEFORE calling this method
* - Should be called before any background fetches occur
*
* **Thread Safety:**
* - Safe to call from any thread (main thread or background)
* - Configuration changes take effect immediately for subsequent fetches
* - Native implementations should use `volatile` fields for thread safety
เร็ *
* **Example:**
* ```typescript
* import { DailyNotification } from '@capacitor-community/daily-notification';
*
* await DailyNotification.configureNativeFetcher({
* apiBaseUrl: 'http://10.0.2.2:3000', // Android emulator → host localhost
* activeDid: 'did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F',
* jwtSecret: 'test-jwt-secret-for-development'
* });
* ```
*
* **Error Handling:**
* - Rejects if required parameters are missing
* - Rejects if no native fetcher is registered
* - Rejects if native fetcher's `configure()` throws exception
*
* @param options Configuration options:
* - `apiBaseUrl` (required): Base URL for API server.
* - Android emulator: `"http://10.0.2.2:3000"` (maps to host localhost:3000)
* - iOS simulator: `"http://localhost:3000"`
* - Production: `"https://api.timesafari.com"`
* - `activeDid` (required): Active DID for authentication.
* Format: `"did:ethr:0x..."`. Used as JWT issuer/subject.
* - `jwtSecret` (required): JWT secret for signing tokens.
* **Keep secure in production!** Consider using secure storage.
*
* @throws {Error} If configuration fails (missing params, no fetcher registered, etc.)
*
* @see {@link https://github.com/timesafari/daily-notification-plugin/blob/main/docs/NATIVE_FETCHER_CONFIGURATION.md | Native Fetcher Configuration Guide}
* for complete documentation and examples
*/
configureNativeFetcher(options: {
apiBaseUrl: string;
activeDid: string;
jwtSecret: string;
}): Promise<void>;
// Rolling window management
maintainRollingWindow(): Promise<void>;
getRollingWindowStats(): Promise<{