refactor: remove dead code and unused files
- Remove duplicate web implementation (src/web.ts - 1,129 lines) - Remove unused DailyNotification wrapper class (src/daily-notification.ts - 288 lines) - Remove unused callback registry (src/callback-registry.ts - 413 lines) - Remove unused example files (5 files, ~1,500 lines) - Remove unused TypeScript modules (moved to test-apps/shared/typescript/) - Remove unused interfaces (ContentHandler, ScheduleOptions) - Remove outdated documentation files (VERIFICATION_*, GLOSSARY, etc.) - Update import paths in test apps to use moved TypeScript modules - Clean up README and USAGE.md references to deleted files Total cleanup: ~3,330+ lines of dead code removed Files deleted: 20 files Files modified: 6 files (import path updates and documentation cleanup) This significantly reduces codebase complexity and maintenance burden.
This commit is contained in:
@@ -1,259 +0,0 @@
|
||||
/**
|
||||
* Advanced usage examples for the Daily Notification plugin
|
||||
* Demonstrates complex scenarios and best practices
|
||||
*/
|
||||
|
||||
import { registerPlugin } from '@capacitor/core';
|
||||
import { DailyNotificationPlugin, NotificationOptions, NotificationSettings } from '../src/definitions';
|
||||
|
||||
const DailyNotification = registerPlugin<DailyNotificationPlugin>('DailyNotification');
|
||||
|
||||
/**
|
||||
* Example of handling multiple notification schedules
|
||||
*/
|
||||
async function handleMultipleSchedules() {
|
||||
try {
|
||||
// Morning notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/morning-content',
|
||||
time: '08:00',
|
||||
title: 'Morning Briefing',
|
||||
body: 'Your morning briefing is ready',
|
||||
priority: 'high'
|
||||
});
|
||||
|
||||
// Evening notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/evening-content',
|
||||
time: '20:00',
|
||||
title: 'Evening Summary',
|
||||
body: 'Your daily summary is ready',
|
||||
priority: 'normal'
|
||||
});
|
||||
|
||||
console.log('Multiple schedules set up successfully');
|
||||
} catch (error) {
|
||||
console.error('Failed to setup multiple schedules:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of handling timezone changes
|
||||
*/
|
||||
async function handleTimezoneChanges() {
|
||||
try {
|
||||
// Get user's timezone
|
||||
const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
|
||||
// Schedule notification with timezone consideration
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/timezone-aware-content',
|
||||
time: '09:00',
|
||||
title: 'Timezone-Aware Update',
|
||||
body: 'Your timezone-aware content is ready',
|
||||
timezone: userTimezone
|
||||
});
|
||||
|
||||
// Listen for timezone changes
|
||||
window.addEventListener('timezonechange', async () => {
|
||||
const newTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
await DailyNotification.updateSettings({
|
||||
timezone: newTimezone
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to handle timezone changes:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of implementing retry logic with exponential backoff
|
||||
*/
|
||||
async function implementRetryLogic() {
|
||||
const maxRetries = 3;
|
||||
const baseDelay = 1000; // 1 second
|
||||
|
||||
async function fetchWithRetry(url: string, retryCount = 0): Promise<Response> {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error('Network response was not ok');
|
||||
return response;
|
||||
} catch (error) {
|
||||
if (retryCount >= maxRetries) throw error;
|
||||
|
||||
const delay = baseDelay * Math.pow(2, retryCount);
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
return fetchWithRetry(url, retryCount + 1);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/unstable-content',
|
||||
time: '10:00',
|
||||
title: 'Retry-Enabled Update',
|
||||
body: 'Your content with retry logic is ready',
|
||||
retryCount: maxRetries,
|
||||
retryInterval: baseDelay / 1000, // Convert to seconds
|
||||
contentHandler: async (response) => {
|
||||
const data = await response.json();
|
||||
return {
|
||||
title: data.title,
|
||||
body: data.content,
|
||||
data: data.metadata
|
||||
};
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to implement retry logic:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of implementing offline support
|
||||
*/
|
||||
async function implementOfflineSupport() {
|
||||
try {
|
||||
// Check if we're online
|
||||
const isOnline = navigator.onLine;
|
||||
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/offline-aware-content',
|
||||
time: '11:00',
|
||||
title: 'Offline-Aware Update',
|
||||
body: 'Your offline-aware content is ready',
|
||||
offlineFallback: true,
|
||||
cacheDuration: 24, // Cache for 24 hours
|
||||
contentHandler: async (response) => {
|
||||
const data = await response.json();
|
||||
|
||||
// Store in IndexedDB for offline access
|
||||
if ('indexedDB' in window) {
|
||||
const db = await openDB('notificationCache', 1, {
|
||||
upgrade(db) {
|
||||
db.createObjectStore('content');
|
||||
}
|
||||
});
|
||||
await db.put('content', data, 'latest');
|
||||
}
|
||||
|
||||
return {
|
||||
title: data.title,
|
||||
body: data.content,
|
||||
data: data.metadata
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for online/offline events
|
||||
window.addEventListener('online', () => {
|
||||
console.log('Back online, syncing content...');
|
||||
// Trigger content sync
|
||||
});
|
||||
|
||||
window.addEventListener('offline', () => {
|
||||
console.log('Offline, using cached content...');
|
||||
// Use cached content
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to implement offline support:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of implementing user preferences
|
||||
*/
|
||||
async function implementUserPreferences() {
|
||||
try {
|
||||
// Get user preferences from storage
|
||||
const preferences = {
|
||||
notificationTime: '12:00',
|
||||
soundEnabled: true,
|
||||
priority: 'high' as const,
|
||||
categories: ['news', 'weather', 'tasks']
|
||||
};
|
||||
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/personalized-content',
|
||||
time: preferences.notificationTime,
|
||||
title: 'Personalized Update',
|
||||
body: 'Your personalized content is ready',
|
||||
sound: preferences.soundEnabled,
|
||||
priority: preferences.priority,
|
||||
headers: {
|
||||
'X-User-Categories': preferences.categories.join(',')
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for preference changes
|
||||
window.addEventListener('storage', (event) => {
|
||||
if (event.key === 'notificationPreferences') {
|
||||
const newPreferences = JSON.parse(event.newValue || '{}');
|
||||
DailyNotification.updateSettings({
|
||||
time: newPreferences.notificationTime,
|
||||
sound: newPreferences.soundEnabled,
|
||||
priority: newPreferences.priority
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to implement user preferences:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of implementing analytics and monitoring
|
||||
*/
|
||||
async function implementAnalytics() {
|
||||
try {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/analytics-enabled-content',
|
||||
time: '13:00',
|
||||
title: 'Analytics-Enabled Update',
|
||||
body: 'Your analytics-enabled content is ready',
|
||||
contentHandler: async (response) => {
|
||||
const data = await response.json();
|
||||
|
||||
// Track notification delivery
|
||||
await trackEvent('notification_delivered', {
|
||||
timestamp: new Date().toISOString(),
|
||||
contentId: data.id,
|
||||
contentType: data.type
|
||||
});
|
||||
|
||||
return {
|
||||
title: data.title,
|
||||
body: data.content,
|
||||
data: data.metadata
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Track notification interactions
|
||||
document.addEventListener('notification_clicked', async (event) => {
|
||||
await trackEvent('notification_clicked', {
|
||||
timestamp: new Date().toISOString(),
|
||||
notificationId: event.detail.id,
|
||||
action: event.detail.action
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to implement analytics:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for analytics
|
||||
async function trackEvent(eventName: string, properties: Record<string, any>) {
|
||||
// Implement your analytics tracking logic here
|
||||
console.log(`Tracking event: ${eventName}`, properties);
|
||||
}
|
||||
|
||||
// Export all advanced example functions
|
||||
export {
|
||||
handleMultipleSchedules,
|
||||
handleTimezoneChanges,
|
||||
implementRetryLogic,
|
||||
implementOfflineSupport,
|
||||
implementUserPreferences,
|
||||
implementAnalytics
|
||||
};
|
||||
@@ -1,262 +0,0 @@
|
||||
/**
|
||||
* Enterprise-level usage examples for the Daily Notification plugin
|
||||
* Demonstrates advanced features and best practices for large-scale applications
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
import { NotificationOptions, NotificationSettings } from '../src/definitions';
|
||||
|
||||
/**
|
||||
* Example of implementing a notification queue system
|
||||
*/
|
||||
async function implementNotificationQueue() {
|
||||
const plugin = new DailyNotification();
|
||||
const queue: NotificationOptions[] = [];
|
||||
let isProcessing = false;
|
||||
|
||||
async function processQueue() {
|
||||
if (isProcessing || queue.length === 0) return;
|
||||
|
||||
isProcessing = true;
|
||||
try {
|
||||
const notification = queue.shift();
|
||||
if (notification) {
|
||||
await plugin.scheduleDailyNotification(notification);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to process notification:', error);
|
||||
// Retry logic here
|
||||
} finally {
|
||||
isProcessing = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add to queue
|
||||
queue.push({
|
||||
url: 'https://api.example.com/enterprise/updates',
|
||||
time: '09:00',
|
||||
title: 'Enterprise Update',
|
||||
priority: 'high',
|
||||
retryCount: 3,
|
||||
retryInterval: 5000,
|
||||
});
|
||||
|
||||
// Process queue
|
||||
await processQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of implementing A/B testing for notifications
|
||||
*/
|
||||
async function implementABTesting() {
|
||||
const plugin = new DailyNotification();
|
||||
|
||||
async function scheduleABTest() {
|
||||
const variants = [
|
||||
{
|
||||
title: 'Version A: Direct Call-to-Action',
|
||||
body: 'Click here to view your daily report',
|
||||
priority: 'high',
|
||||
},
|
||||
{
|
||||
title: 'Version B: Value Proposition',
|
||||
body: 'Your daily insights are ready to help you succeed',
|
||||
priority: 'normal',
|
||||
},
|
||||
];
|
||||
|
||||
// Randomly select a variant
|
||||
const variant = variants[Math.floor(Math.random() * variants.length)];
|
||||
|
||||
await plugin.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/ab-test-content',
|
||||
time: '10:00',
|
||||
...variant,
|
||||
data: {
|
||||
variant: variant === variants[0] ? 'A' : 'B',
|
||||
timestamp: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
await scheduleABTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of implementing notification analytics and tracking
|
||||
*/
|
||||
async function implementAnalyticsTracking() {
|
||||
const plugin = new DailyNotification();
|
||||
|
||||
// Track notification delivery
|
||||
plugin.on('notification', async (event) => {
|
||||
await trackAnalytics({
|
||||
event: 'notification_delivered',
|
||||
notificationId: event.detail.id,
|
||||
timestamp: new Date().toISOString(),
|
||||
platform: navigator.platform,
|
||||
userAgent: navigator.userAgent,
|
||||
});
|
||||
});
|
||||
|
||||
// Track notification interactions
|
||||
document.addEventListener('notification_clicked', async (event) => {
|
||||
await trackAnalytics({
|
||||
event: 'notification_clicked',
|
||||
notificationId: event.detail.id,
|
||||
timestamp: new Date().toISOString(),
|
||||
action: event.detail.action,
|
||||
data: event.detail.data,
|
||||
});
|
||||
});
|
||||
|
||||
async function trackAnalytics(data: Record<string, any>) {
|
||||
// Implement your analytics tracking logic here
|
||||
console.log('Analytics Event:', data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of implementing notification preferences management
|
||||
*/
|
||||
async function implementPreferencesManagement() {
|
||||
const plugin = new DailyNotification();
|
||||
|
||||
interface UserPreferences {
|
||||
notificationTimes: string[];
|
||||
categories: string[];
|
||||
priority: 'low' | 'normal' | 'high';
|
||||
sound: boolean;
|
||||
timezone: string;
|
||||
}
|
||||
|
||||
async function updateUserPreferences(preferences: UserPreferences) {
|
||||
// Update all scheduled notifications
|
||||
for (const time of preferences.notificationTimes) {
|
||||
await plugin.updateSettings({
|
||||
time,
|
||||
priority: preferences.priority,
|
||||
sound: preferences.sound,
|
||||
timezone: preferences.timezone,
|
||||
});
|
||||
}
|
||||
|
||||
// Schedule new notifications for each category
|
||||
for (const category of preferences.categories) {
|
||||
await plugin.scheduleDailyNotification({
|
||||
url: `https://api.example.com/categories/${category}`,
|
||||
time: preferences.notificationTimes[0],
|
||||
title: `${category} Update`,
|
||||
priority: preferences.priority,
|
||||
sound: preferences.sound,
|
||||
timezone: preferences.timezone,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Example usage
|
||||
await updateUserPreferences({
|
||||
notificationTimes: ['09:00', '12:00', '18:00'],
|
||||
categories: ['news', 'tasks', 'updates'],
|
||||
priority: 'high',
|
||||
sound: true,
|
||||
timezone: 'America/New_York',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of implementing notification content personalization
|
||||
*/
|
||||
async function implementContentPersonalization() {
|
||||
const plugin = new DailyNotification();
|
||||
|
||||
interface UserProfile {
|
||||
id: string;
|
||||
name: string;
|
||||
preferences: {
|
||||
language: string;
|
||||
timezone: string;
|
||||
categories: string[];
|
||||
};
|
||||
}
|
||||
|
||||
async function schedulePersonalizedNotification(profile: UserProfile) {
|
||||
await plugin.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/personalized-content',
|
||||
time: '09:00',
|
||||
title: `Good morning, ${profile.name}!`,
|
||||
priority: 'high',
|
||||
timezone: profile.preferences.timezone,
|
||||
headers: {
|
||||
'X-User-ID': profile.id,
|
||||
'X-Language': profile.preferences.language,
|
||||
'X-Categories': profile.preferences.categories.join(','),
|
||||
},
|
||||
contentHandler: async (response) => {
|
||||
const data = await response.json();
|
||||
return {
|
||||
title: data.title,
|
||||
body: data.content,
|
||||
data: {
|
||||
...data.metadata,
|
||||
userId: profile.id,
|
||||
timestamp: new Date().toISOString(),
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Example usage
|
||||
await schedulePersonalizedNotification({
|
||||
id: 'user123',
|
||||
name: 'John Doe',
|
||||
preferences: {
|
||||
language: 'en-US',
|
||||
timezone: 'America/New_York',
|
||||
categories: ['news', 'weather', 'tasks'],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of implementing notification rate limiting
|
||||
*/
|
||||
async function implementRateLimiting() {
|
||||
const plugin = new DailyNotification();
|
||||
|
||||
class RateLimiter {
|
||||
private lastNotificationTime = 0;
|
||||
private minInterval = 60000; // 1 minute
|
||||
|
||||
async scheduleWithRateLimit(options: NotificationOptions): Promise<void> {
|
||||
const now = Date.now();
|
||||
if (now - this.lastNotificationTime < this.minInterval) {
|
||||
throw new Error('Rate limit exceeded. Please wait before scheduling another notification.');
|
||||
}
|
||||
|
||||
await plugin.scheduleDailyNotification(options);
|
||||
this.lastNotificationTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
const rateLimiter = new RateLimiter();
|
||||
|
||||
// Example usage
|
||||
await rateLimiter.scheduleWithRateLimit({
|
||||
url: 'https://api.example.com/rate-limited-content',
|
||||
time: '11:00',
|
||||
title: 'Rate Limited Update',
|
||||
priority: 'normal',
|
||||
});
|
||||
}
|
||||
|
||||
// Export all enterprise example functions
|
||||
export {
|
||||
implementNotificationQueue,
|
||||
implementABTesting,
|
||||
implementAnalyticsTracking,
|
||||
implementPreferencesManagement,
|
||||
implementContentPersonalization,
|
||||
implementRateLimiting,
|
||||
};
|
||||
@@ -1,173 +0,0 @@
|
||||
/**
|
||||
* Phase 1.2 TTL-at-Fire Enforcement Usage Example
|
||||
*
|
||||
* Demonstrates TTL enforcement functionality
|
||||
* Shows how stale notifications are automatically skipped
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
/**
|
||||
* Example: Configure TTL enforcement
|
||||
*/
|
||||
async function configureTTLEnforcement() {
|
||||
try {
|
||||
console.log('Configuring TTL enforcement...');
|
||||
|
||||
// Configure with TTL settings
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800, // 30 minutes TTL
|
||||
prefetchLeadMinutes: 15
|
||||
});
|
||||
|
||||
console.log('✅ TTL enforcement configured (30 minutes)');
|
||||
|
||||
// Now the plugin will automatically skip notifications with stale content
|
||||
// Content older than 30 minutes at fire time will not be armed
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ TTL configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Schedule notification with TTL enforcement
|
||||
*/
|
||||
async function scheduleWithTTLEnforcement() {
|
||||
try {
|
||||
// Configure TTL enforcement first
|
||||
await configureTTLEnforcement();
|
||||
|
||||
// Schedule a notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready',
|
||||
sound: true
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with TTL enforcement');
|
||||
|
||||
// The plugin will now:
|
||||
// 1. Check content freshness before arming
|
||||
// 2. Skip notifications with stale content
|
||||
// 3. Log TTL violations for debugging
|
||||
// 4. Store violation statistics
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Scheduling with TTL enforcement failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate TTL violation scenario
|
||||
*/
|
||||
async function demonstrateTTLViolation() {
|
||||
try {
|
||||
console.log('Demonstrating TTL violation scenario...');
|
||||
|
||||
// Configure with short TTL for demonstration
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 300, // 5 minutes TTL (very short for demo)
|
||||
prefetchLeadMinutes: 2
|
||||
});
|
||||
|
||||
// Schedule notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with 5-minute TTL');
|
||||
|
||||
// If content is fetched more than 5 minutes before 09:00,
|
||||
// the notification will be skipped due to TTL violation
|
||||
|
||||
console.log('ℹ️ If content is older than 5 minutes at 09:00, notification will be skipped');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ TTL violation demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Check TTL violation statistics
|
||||
*/
|
||||
async function checkTTLStats() {
|
||||
try {
|
||||
console.log('Checking TTL violation statistics...');
|
||||
|
||||
// Configure TTL enforcement
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800, // 30 minutes
|
||||
prefetchLeadMinutes: 15
|
||||
});
|
||||
|
||||
// The plugin automatically tracks TTL violations
|
||||
// You can check the logs for TTL_VIOLATION entries
|
||||
// or implement a method to retrieve violation statistics
|
||||
|
||||
console.log('✅ TTL enforcement active - violations will be logged');
|
||||
console.log('ℹ️ Check logs for "TTL_VIOLATION" entries');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ TTL stats check failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Different TTL configurations for different use cases
|
||||
*/
|
||||
async function configureDifferentTTLScenarios() {
|
||||
try {
|
||||
console.log('Configuring different TTL scenarios...');
|
||||
|
||||
// Scenario 1: Real-time notifications (short TTL)
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 300, // 5 minutes
|
||||
prefetchLeadMinutes: 2
|
||||
});
|
||||
|
||||
console.log('✅ Real-time notifications: 5-minute TTL');
|
||||
|
||||
// Scenario 2: Daily digest (longer TTL)
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 7200, // 2 hours
|
||||
prefetchLeadMinutes: 30
|
||||
});
|
||||
|
||||
console.log('✅ Daily digest: 2-hour TTL');
|
||||
|
||||
// Scenario 3: Weekly summary (very long TTL)
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 86400, // 24 hours
|
||||
prefetchLeadMinutes: 60
|
||||
});
|
||||
|
||||
console.log('✅ Weekly summary: 24-hour TTL');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ TTL scenario configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export examples for use
|
||||
export {
|
||||
configureTTLEnforcement,
|
||||
scheduleWithTTLEnforcement,
|
||||
demonstrateTTLViolation,
|
||||
checkTTLStats,
|
||||
configureDifferentTTLScenarios
|
||||
};
|
||||
@@ -1,224 +0,0 @@
|
||||
/**
|
||||
* Phase 1.3 Rolling Window Safety Usage Example
|
||||
*
|
||||
* Demonstrates rolling window safety functionality
|
||||
* Shows how notifications are maintained for today and tomorrow
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
/**
|
||||
* Example: Configure rolling window safety
|
||||
*/
|
||||
async function configureRollingWindowSafety() {
|
||||
try {
|
||||
console.log('Configuring rolling window safety...');
|
||||
|
||||
// Configure with rolling window settings
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800, // 30 minutes TTL
|
||||
prefetchLeadMinutes: 15,
|
||||
maxNotificationsPerDay: 20 // iOS limit
|
||||
});
|
||||
|
||||
console.log('✅ Rolling window safety configured');
|
||||
|
||||
// The plugin will now automatically:
|
||||
// - Keep today's remaining notifications armed
|
||||
// - Arm tomorrow's notifications if within iOS caps
|
||||
// - Maintain window state every 15 minutes
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Rolling window configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Manual rolling window maintenance
|
||||
*/
|
||||
async function manualRollingWindowMaintenance() {
|
||||
try {
|
||||
console.log('Triggering manual rolling window maintenance...');
|
||||
|
||||
// Force window maintenance (useful for testing)
|
||||
await DailyNotification.maintainRollingWindow();
|
||||
|
||||
console.log('✅ Rolling window maintenance completed');
|
||||
|
||||
// This will:
|
||||
// - Arm today's remaining notifications
|
||||
// - Arm tomorrow's notifications if within capacity
|
||||
// - Update window state and statistics
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Manual maintenance failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Check rolling window statistics
|
||||
*/
|
||||
async function checkRollingWindowStats() {
|
||||
try {
|
||||
console.log('Checking rolling window statistics...');
|
||||
|
||||
// Get rolling window statistics
|
||||
const stats = await DailyNotification.getRollingWindowStats();
|
||||
|
||||
console.log('📊 Rolling Window Statistics:');
|
||||
console.log(` Stats: ${stats.stats}`);
|
||||
console.log(` Maintenance Needed: ${stats.maintenanceNeeded}`);
|
||||
console.log(` Time Until Next Maintenance: ${stats.timeUntilNextMaintenance}ms`);
|
||||
|
||||
// Example output:
|
||||
// Stats: Rolling window stats: pending=5/100, daily=3/50, platform=Android
|
||||
// Maintenance Needed: false
|
||||
// Time Until Next Maintenance: 450000ms (7.5 minutes)
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Rolling window stats check failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Schedule multiple notifications with rolling window
|
||||
*/
|
||||
async function scheduleMultipleNotifications() {
|
||||
try {
|
||||
console.log('Scheduling multiple notifications with rolling window...');
|
||||
|
||||
// Configure rolling window safety
|
||||
await configureRollingWindowSafety();
|
||||
|
||||
// Schedule notifications for different times
|
||||
const notifications = [
|
||||
{ time: '08:00', title: 'Morning Update', body: 'Good morning!' },
|
||||
{ time: '12:00', title: 'Lunch Reminder', body: 'Time for lunch!' },
|
||||
{ time: '18:00', title: 'Evening Summary', body: 'End of day summary' },
|
||||
{ time: '22:00', title: 'Good Night', body: 'Time to rest' }
|
||||
];
|
||||
|
||||
for (const notification of notifications) {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: notification.time,
|
||||
title: notification.title,
|
||||
body: notification.body
|
||||
});
|
||||
}
|
||||
|
||||
console.log('✅ Multiple notifications scheduled');
|
||||
|
||||
// The rolling window will ensure:
|
||||
// - All future notifications today are armed
|
||||
// - Tomorrow's notifications are armed if within iOS caps
|
||||
// - Window state is maintained automatically
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Multiple notification scheduling failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate iOS capacity limits
|
||||
*/
|
||||
async function demonstrateIOSCapacityLimits() {
|
||||
try {
|
||||
console.log('Demonstrating iOS capacity limits...');
|
||||
|
||||
// Configure with iOS-like limits
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 3600, // 1 hour TTL
|
||||
prefetchLeadMinutes: 30,
|
||||
maxNotificationsPerDay: 20 // iOS limit
|
||||
});
|
||||
|
||||
// Schedule many notifications to test capacity
|
||||
const notifications = [];
|
||||
for (let i = 0; i < 25; i++) {
|
||||
notifications.push({
|
||||
time: `${8 + i}:00`,
|
||||
title: `Notification ${i + 1}`,
|
||||
body: `This is notification number ${i + 1}`
|
||||
});
|
||||
}
|
||||
|
||||
for (const notification of notifications) {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: notification.time,
|
||||
title: notification.title,
|
||||
body: notification.body
|
||||
});
|
||||
}
|
||||
|
||||
console.log('✅ Many notifications scheduled');
|
||||
|
||||
// Check statistics to see capacity management
|
||||
const stats = await DailyNotification.getRollingWindowStats();
|
||||
console.log('📊 Capacity Management:', stats.stats);
|
||||
|
||||
// The rolling window will:
|
||||
// - Arm notifications up to the daily limit
|
||||
// - Skip additional notifications if at capacity
|
||||
// - Log capacity violations for debugging
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ iOS capacity demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Monitor rolling window over time
|
||||
*/
|
||||
async function monitorRollingWindowOverTime() {
|
||||
try {
|
||||
console.log('Monitoring rolling window over time...');
|
||||
|
||||
// Configure rolling window
|
||||
await configureRollingWindowSafety();
|
||||
|
||||
// Schedule some notifications
|
||||
await scheduleMultipleNotifications();
|
||||
|
||||
// Monitor window state over time
|
||||
const monitorInterval = setInterval(async () => {
|
||||
try {
|
||||
const stats = await DailyNotification.getRollingWindowStats();
|
||||
console.log('📊 Window State:', stats.stats);
|
||||
|
||||
if (stats.maintenanceNeeded) {
|
||||
console.log('⚠️ Maintenance needed, triggering...');
|
||||
await DailyNotification.maintainRollingWindow();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Monitoring error:', error);
|
||||
}
|
||||
}, 60000); // Check every minute
|
||||
|
||||
// Stop monitoring after 5 minutes
|
||||
setTimeout(() => {
|
||||
clearInterval(monitorInterval);
|
||||
console.log('✅ Monitoring completed');
|
||||
}, 300000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Rolling window monitoring failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export examples for use
|
||||
export {
|
||||
configureRollingWindowSafety,
|
||||
manualRollingWindowMaintenance,
|
||||
checkRollingWindowStats,
|
||||
scheduleMultipleNotifications,
|
||||
demonstrateIOSCapacityLimits,
|
||||
monitorRollingWindowOverTime
|
||||
};
|
||||
@@ -1,121 +0,0 @@
|
||||
/**
|
||||
* Phase 1.1 Usage Example
|
||||
*
|
||||
* Demonstrates SQLite database sharing configuration and usage
|
||||
* Shows how to configure the plugin for shared storage mode
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
/**
|
||||
* Example: Configure plugin for shared SQLite storage
|
||||
*/
|
||||
async function configureSharedStorage() {
|
||||
try {
|
||||
console.log('Configuring plugin for shared SQLite storage...');
|
||||
|
||||
// Configure the plugin with shared storage mode
|
||||
await DailyNotification.configure({
|
||||
dbPath: '/data/data/com.yourapp/databases/daily_notifications.db',
|
||||
storage: 'shared',
|
||||
ttlSeconds: 3600, // 1 hour TTL
|
||||
prefetchLeadMinutes: 15, // 15 minutes before notification
|
||||
maxNotificationsPerDay: 5,
|
||||
retentionDays: 7
|
||||
});
|
||||
|
||||
console.log('✅ Plugin configured successfully for shared storage');
|
||||
|
||||
// Now the plugin will use SQLite database instead of SharedPreferences
|
||||
// The database will be shared between app and plugin
|
||||
// WAL mode enables concurrent reads during writes
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Configure plugin for tiered storage (current implementation)
|
||||
*/
|
||||
async function configureTieredStorage() {
|
||||
try {
|
||||
console.log('Configuring plugin for tiered storage...');
|
||||
|
||||
// Configure the plugin with tiered storage mode (default)
|
||||
await DailyNotification.configure({
|
||||
storage: 'tiered',
|
||||
ttlSeconds: 1800, // 30 minutes TTL
|
||||
prefetchLeadMinutes: 10, // 10 minutes before notification
|
||||
maxNotificationsPerDay: 3,
|
||||
retentionDays: 5
|
||||
});
|
||||
|
||||
console.log('✅ Plugin configured successfully for tiered storage');
|
||||
|
||||
// Plugin will continue using SharedPreferences + in-memory cache
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Schedule notification with new configuration
|
||||
*/
|
||||
async function scheduleWithNewConfig() {
|
||||
try {
|
||||
// First configure for shared storage
|
||||
await configureSharedStorage();
|
||||
|
||||
// Then schedule a notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready',
|
||||
sound: true,
|
||||
priority: 'high'
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with shared storage configuration');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Scheduling failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Check migration status
|
||||
*/
|
||||
async function checkMigrationStatus() {
|
||||
try {
|
||||
// Configure for shared storage to trigger migration
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
dbPath: '/data/data/com.yourapp/databases/daily_notifications.db'
|
||||
});
|
||||
|
||||
// The plugin will automatically:
|
||||
// 1. Create SQLite database with WAL mode
|
||||
// 2. Migrate existing SharedPreferences data
|
||||
// 3. Validate migration success
|
||||
// 4. Log migration statistics
|
||||
|
||||
console.log('✅ Migration completed automatically during configuration');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Migration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export examples for use
|
||||
export {
|
||||
configureSharedStorage,
|
||||
configureTieredStorage,
|
||||
scheduleWithNewConfig,
|
||||
checkMigrationStatus
|
||||
};
|
||||
@@ -1,285 +0,0 @@
|
||||
/**
|
||||
* Phase 2.1 iOS Background Tasks Usage Example
|
||||
*
|
||||
* Demonstrates iOS background task functionality
|
||||
* Shows T–lead prefetch with BGTaskScheduler integration
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
/**
|
||||
* Example: Configure iOS background tasks
|
||||
*/
|
||||
async function configureIOSBackgroundTasks() {
|
||||
try {
|
||||
console.log('Configuring iOS background tasks...');
|
||||
|
||||
// Configure with background task settings
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800, // 30 minutes TTL
|
||||
prefetchLeadMinutes: 15, // T–lead prefetch 15 minutes before
|
||||
maxNotificationsPerDay: 20 // iOS limit
|
||||
});
|
||||
|
||||
console.log('✅ iOS background tasks configured');
|
||||
|
||||
// The plugin will now:
|
||||
// - Register BGTaskScheduler tasks
|
||||
// - Schedule T–lead prefetch automatically
|
||||
// - Handle background execution constraints
|
||||
// - Respect ETag/304 caching
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ iOS background task configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Schedule notification with background prefetch
|
||||
*/
|
||||
async function scheduleWithBackgroundPrefetch() {
|
||||
try {
|
||||
// Configure background tasks first
|
||||
await configureIOSBackgroundTasks();
|
||||
|
||||
// Schedule a notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready',
|
||||
sound: true
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with background prefetch');
|
||||
|
||||
// The plugin will now:
|
||||
// - Schedule notification for 09:00
|
||||
// - Schedule background task for 08:45 (T–lead)
|
||||
// - Perform single-attempt prefetch with 12s timeout
|
||||
// - Re-arm notification if content is fresh
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Scheduling with background prefetch failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Check background task status
|
||||
*/
|
||||
async function checkBackgroundTaskStatus() {
|
||||
try {
|
||||
console.log('Checking background task status...');
|
||||
|
||||
// Get background task status
|
||||
const status = await DailyNotification.getBackgroundTaskStatus();
|
||||
|
||||
console.log('📱 Background Task Status:');
|
||||
console.log(` Available: ${status.available}`);
|
||||
console.log(` Identifier: ${status.identifier}`);
|
||||
console.log(` Timeout: ${status.timeout}s`);
|
||||
console.log(` Expiration: ${status.expiration}s`);
|
||||
|
||||
// Example output:
|
||||
// Available: true
|
||||
// Identifier: com.timesafari.dailynotification.prefetch
|
||||
// Timeout: 12s
|
||||
// Expiration: 30s
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Background task status check failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Manual background task scheduling
|
||||
*/
|
||||
async function manualBackgroundTaskScheduling() {
|
||||
try {
|
||||
console.log('Manually scheduling background task...');
|
||||
|
||||
// Configure background tasks
|
||||
await configureIOSBackgroundTasks();
|
||||
|
||||
// Manually schedule background task for specific time
|
||||
await DailyNotification.scheduleBackgroundTask({
|
||||
scheduledTime: '10:30' // Schedule for 10:30
|
||||
});
|
||||
|
||||
console.log('✅ Background task manually scheduled for 10:30');
|
||||
|
||||
// This will:
|
||||
// - Schedule background task for 10:15 (T–lead)
|
||||
// - Perform prefetch when iOS allows background execution
|
||||
// - Handle ETag/304 responses appropriately
|
||||
// - Update notification content if fresh
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Manual background task scheduling failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate ETag caching
|
||||
*/
|
||||
async function demonstrateETagCaching() {
|
||||
try {
|
||||
console.log('Demonstrating ETag caching...');
|
||||
|
||||
// Configure with short TTL for demonstration
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 300, // 5 minutes TTL
|
||||
prefetchLeadMinutes: 2 // Very short lead time
|
||||
});
|
||||
|
||||
// Schedule notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with ETag caching');
|
||||
|
||||
// The background task will:
|
||||
// - Send If-None-Match header with stored ETag
|
||||
// - Receive 304 if content unchanged
|
||||
// - Receive 200 with new ETag if content updated
|
||||
// - Update stored content and ETag accordingly
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ ETag caching demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Handle background task limitations
|
||||
*/
|
||||
async function handleBackgroundTaskLimitations() {
|
||||
try {
|
||||
console.log('Handling background task limitations...');
|
||||
|
||||
// Configure background tasks
|
||||
await configureIOSBackgroundTasks();
|
||||
|
||||
// Schedule multiple notifications to test limits
|
||||
const notifications = [
|
||||
{ time: '08:00', title: 'Morning Update' },
|
||||
{ time: '12:00', title: 'Lunch Reminder' },
|
||||
{ time: '18:00', title: 'Evening Summary' },
|
||||
{ time: '22:00', title: 'Good Night' }
|
||||
];
|
||||
|
||||
for (const notification of notifications) {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: notification.time,
|
||||
title: notification.title,
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
}
|
||||
|
||||
console.log('✅ Multiple notifications scheduled');
|
||||
|
||||
// iOS will:
|
||||
// - Limit background task execution time
|
||||
// - Provide 30-second expiration window
|
||||
// - Cancel tasks if they exceed limits
|
||||
// - Handle task failures gracefully
|
||||
|
||||
// Check status to see current state
|
||||
const status = await DailyNotification.getBackgroundTaskStatus();
|
||||
console.log('📱 Current Status:', status);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Background task limitations handling failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Monitor background task execution
|
||||
*/
|
||||
async function monitorBackgroundTaskExecution() {
|
||||
try {
|
||||
console.log('Monitoring background task execution...');
|
||||
|
||||
// Configure background tasks
|
||||
await configureIOSBackgroundTasks();
|
||||
|
||||
// Schedule notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
// Monitor execution over time
|
||||
const monitorInterval = setInterval(async () => {
|
||||
try {
|
||||
const status = await DailyNotification.getBackgroundTaskStatus();
|
||||
console.log('📱 Background Task Status:', status);
|
||||
|
||||
// Check if background task is available and active
|
||||
if (status.available) {
|
||||
console.log('✅ Background tasks are available');
|
||||
} else {
|
||||
console.log('⚠️ Background tasks not available:', status.reason);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Monitoring error:', error);
|
||||
}
|
||||
}, 60000); // Check every minute
|
||||
|
||||
// Stop monitoring after 5 minutes
|
||||
setTimeout(() => {
|
||||
clearInterval(monitorInterval);
|
||||
console.log('✅ Background task monitoring completed');
|
||||
}, 300000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Background task monitoring failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Cancel background tasks
|
||||
*/
|
||||
async function cancelBackgroundTasks() {
|
||||
try {
|
||||
console.log('Cancelling background tasks...');
|
||||
|
||||
// Cancel all background tasks
|
||||
await DailyNotification.cancelAllBackgroundTasks();
|
||||
|
||||
console.log('✅ All background tasks cancelled');
|
||||
|
||||
// This will:
|
||||
// - Cancel all pending BGTaskScheduler tasks
|
||||
// - Stop T–lead prefetch scheduling
|
||||
// - Clear background task queue
|
||||
// - Maintain existing notifications
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Background task cancellation failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export examples for use
|
||||
export {
|
||||
configureIOSBackgroundTasks,
|
||||
scheduleWithBackgroundPrefetch,
|
||||
checkBackgroundTaskStatus,
|
||||
manualBackgroundTaskScheduling,
|
||||
demonstrateETagCaching,
|
||||
handleBackgroundTaskLimitations,
|
||||
monitorBackgroundTaskExecution,
|
||||
cancelBackgroundTasks
|
||||
};
|
||||
@@ -1,321 +0,0 @@
|
||||
/**
|
||||
* Phase 2.2 Android Fallback Completion Usage Example
|
||||
*
|
||||
* Demonstrates Android exact alarm fallback functionality
|
||||
* Shows permission handling, windowed alarms, and reboot recovery
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
/**
|
||||
* Example: Configure Android exact alarm fallback
|
||||
*/
|
||||
async function configureAndroidExactAlarmFallback() {
|
||||
try {
|
||||
console.log('Configuring Android exact alarm fallback...');
|
||||
|
||||
// Configure with fallback settings
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800, // 30 minutes TTL
|
||||
prefetchLeadMinutes: 15,
|
||||
maxNotificationsPerDay: 50 // Android limit
|
||||
});
|
||||
|
||||
console.log('✅ Android exact alarm fallback configured');
|
||||
|
||||
// The plugin will now:
|
||||
// - Request SCHEDULE_EXACT_ALARM permission
|
||||
// - Fall back to windowed alarms (±10m) if denied
|
||||
// - Handle reboot and time-change recovery
|
||||
// - Provide deep-link to enable exact alarms
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Android exact alarm fallback configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Check exact alarm status
|
||||
*/
|
||||
async function checkExactAlarmStatus() {
|
||||
try {
|
||||
console.log('Checking exact alarm status...');
|
||||
|
||||
// Get exact alarm status
|
||||
const status = await DailyNotification.getExactAlarmStatus();
|
||||
|
||||
console.log('📱 Exact Alarm Status:');
|
||||
console.log(` Supported: ${status.supported}`);
|
||||
console.log(` Enabled: ${status.enabled}`);
|
||||
console.log(` Can Schedule: ${status.canSchedule}`);
|
||||
console.log(` Fallback Window: ${status.fallbackWindow}`);
|
||||
|
||||
// Example output:
|
||||
// Supported: true
|
||||
// Enabled: false
|
||||
// Can Schedule: false
|
||||
// Fallback Window: ±10 minutes
|
||||
|
||||
if (!status.enabled && status.supported) {
|
||||
console.log('⚠️ Exact alarms are supported but not enabled');
|
||||
console.log('💡 Consider requesting permission or opening settings');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Exact alarm status check failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Request exact alarm permission
|
||||
*/
|
||||
async function requestExactAlarmPermission() {
|
||||
try {
|
||||
console.log('Requesting exact alarm permission...');
|
||||
|
||||
// Request exact alarm permission
|
||||
await DailyNotification.requestExactAlarmPermission();
|
||||
|
||||
console.log('✅ Exact alarm permission request initiated');
|
||||
|
||||
// This will:
|
||||
// - Open the exact alarm settings screen
|
||||
// - Allow user to enable exact alarms
|
||||
// - Fall back to windowed alarms if denied
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Exact alarm permission request failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Open exact alarm settings
|
||||
*/
|
||||
async function openExactAlarmSettings() {
|
||||
try {
|
||||
console.log('Opening exact alarm settings...');
|
||||
|
||||
// Open exact alarm settings
|
||||
await DailyNotification.openExactAlarmSettings();
|
||||
|
||||
console.log('✅ Exact alarm settings opened');
|
||||
|
||||
// This will:
|
||||
// - Navigate to exact alarm settings
|
||||
// - Allow user to enable exact alarms
|
||||
// - Provide fallback information if needed
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Opening exact alarm settings failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Schedule notification with fallback handling
|
||||
*/
|
||||
async function scheduleWithFallbackHandling() {
|
||||
try {
|
||||
console.log('Scheduling notification with fallback handling...');
|
||||
|
||||
// Configure fallback
|
||||
await configureAndroidExactAlarmFallback();
|
||||
|
||||
// Check status first
|
||||
const status = await DailyNotification.getExactAlarmStatus();
|
||||
|
||||
if (!status.canSchedule) {
|
||||
console.log('⚠️ Exact alarms not available, will use windowed fallback');
|
||||
}
|
||||
|
||||
// Schedule notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready',
|
||||
sound: true
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with fallback handling');
|
||||
|
||||
// The plugin will:
|
||||
// - Use exact alarms if available
|
||||
// - Fall back to windowed alarms (±10m) if not
|
||||
// - Handle permission changes gracefully
|
||||
// - Provide appropriate user feedback
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Scheduling with fallback handling failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Check reboot recovery status
|
||||
*/
|
||||
async function checkRebootRecoveryStatus() {
|
||||
try {
|
||||
console.log('Checking reboot recovery status...');
|
||||
|
||||
// Get reboot recovery status
|
||||
const status = await DailyNotification.getRebootRecoveryStatus();
|
||||
|
||||
console.log('🔄 Reboot Recovery Status:');
|
||||
console.log(` In Progress: ${status.inProgress}`);
|
||||
console.log(` Last Recovery Time: ${new Date(status.lastRecoveryTime)}`);
|
||||
console.log(` Time Since Last Recovery: ${status.timeSinceLastRecovery}ms`);
|
||||
console.log(` Recovery Needed: ${status.recoveryNeeded}`);
|
||||
|
||||
// Example output:
|
||||
// In Progress: false
|
||||
// Last Recovery Time: Mon Sep 08 2025 10:30:00 GMT+0000
|
||||
// Time Since Last Recovery: 120000ms
|
||||
// Recovery Needed: false
|
||||
|
||||
if (status.recoveryNeeded) {
|
||||
console.log('⚠️ Recovery is needed - system may have rebooted');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Reboot recovery status check failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate fallback scenarios
|
||||
*/
|
||||
async function demonstrateFallbackScenarios() {
|
||||
try {
|
||||
console.log('Demonstrating fallback scenarios...');
|
||||
|
||||
// Configure fallback
|
||||
await configureAndroidExactAlarmFallback();
|
||||
|
||||
// Check initial status
|
||||
const initialStatus = await DailyNotification.getExactAlarmStatus();
|
||||
console.log('📱 Initial Status:', initialStatus);
|
||||
|
||||
// Schedule notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled');
|
||||
|
||||
// Check status after scheduling
|
||||
const afterStatus = await DailyNotification.getExactAlarmStatus();
|
||||
console.log('📱 Status After Scheduling:', afterStatus);
|
||||
|
||||
// The plugin will handle:
|
||||
// - Exact alarms if permission granted
|
||||
// - Windowed alarms (±10m) if permission denied
|
||||
// - Graceful degradation based on Android version
|
||||
// - Appropriate user feedback and guidance
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Fallback scenarios demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Monitor exact alarm changes
|
||||
*/
|
||||
async function monitorExactAlarmChanges() {
|
||||
try {
|
||||
console.log('Monitoring exact alarm changes...');
|
||||
|
||||
// Configure fallback
|
||||
await configureAndroidExactAlarmFallback();
|
||||
|
||||
// Monitor changes over time
|
||||
const monitorInterval = setInterval(async () => {
|
||||
try {
|
||||
const status = await DailyNotification.getExactAlarmStatus();
|
||||
console.log('📱 Exact Alarm Status:', status);
|
||||
|
||||
if (status.enabled && !status.canSchedule) {
|
||||
console.log('⚠️ Exact alarms enabled but cannot schedule - may need app restart');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Monitoring error:', error);
|
||||
}
|
||||
}, 30000); // Check every 30 seconds
|
||||
|
||||
// Stop monitoring after 5 minutes
|
||||
setTimeout(() => {
|
||||
clearInterval(monitorInterval);
|
||||
console.log('✅ Exact alarm monitoring completed');
|
||||
}, 300000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Exact alarm monitoring failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Handle permission denial gracefully
|
||||
*/
|
||||
async function handlePermissionDenialGracefully() {
|
||||
try {
|
||||
console.log('Handling permission denial gracefully...');
|
||||
|
||||
// Configure fallback
|
||||
await configureAndroidExactAlarmFallback();
|
||||
|
||||
// Check status
|
||||
const status = await DailyNotification.getExactAlarmStatus();
|
||||
|
||||
if (!status.enabled) {
|
||||
console.log('⚠️ Exact alarms not enabled, using windowed fallback');
|
||||
|
||||
// Schedule with fallback
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready (windowed fallback)'
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with windowed fallback');
|
||||
|
||||
// Provide user guidance
|
||||
console.log('💡 To enable exact alarms:');
|
||||
console.log(' 1. Call requestExactAlarmPermission()');
|
||||
console.log(' 2. Or call openExactAlarmSettings()');
|
||||
console.log(' 3. Enable exact alarms in settings');
|
||||
|
||||
} else {
|
||||
console.log('✅ Exact alarms enabled, scheduling normally');
|
||||
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready (exact timing)'
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Permission denial handling failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export examples for use
|
||||
export {
|
||||
configureAndroidExactAlarmFallback,
|
||||
checkExactAlarmStatus,
|
||||
requestExactAlarmPermission,
|
||||
openExactAlarmSettings,
|
||||
scheduleWithFallbackHandling,
|
||||
checkRebootRecoveryStatus,
|
||||
demonstrateFallbackScenarios,
|
||||
monitorExactAlarmChanges,
|
||||
handlePermissionDenialGracefully
|
||||
};
|
||||
@@ -1,317 +0,0 @@
|
||||
/**
|
||||
* Phase 3.1 ETag Support Implementation Usage Example
|
||||
*
|
||||
* Demonstrates ETag-based conditional requests for efficient content fetching
|
||||
* Shows 304 Not Modified handling, cache management, and network metrics
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
/**
|
||||
* Example: Configure ETag support for efficient fetching
|
||||
*/
|
||||
async function configureETagSupport() {
|
||||
try {
|
||||
console.log('Configuring ETag support for efficient fetching...');
|
||||
|
||||
// Configure with ETag support
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800, // 30 minutes TTL
|
||||
prefetchLeadMinutes: 15,
|
||||
enableETagSupport: true // Enable ETag conditional requests
|
||||
});
|
||||
|
||||
console.log('✅ ETag support configured');
|
||||
|
||||
// The plugin will now:
|
||||
// - Send If-None-Match headers with cached ETags
|
||||
// - Handle 304 Not Modified responses efficiently
|
||||
// - Cache ETag values for future requests
|
||||
// - Track network efficiency metrics
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ ETag support configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate ETag conditional requests
|
||||
*/
|
||||
async function demonstrateETagConditionalRequests() {
|
||||
try {
|
||||
console.log('Demonstrating ETag conditional requests...');
|
||||
|
||||
// Configure ETag support
|
||||
await configureETagSupport();
|
||||
|
||||
// First request - will fetch content and cache ETag
|
||||
console.log('📡 First request (no ETag cached)...');
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log('✅ First request completed - ETag cached');
|
||||
|
||||
// Second request - will use conditional request
|
||||
console.log('📡 Second request (ETag cached)...');
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:15',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log('✅ Second request completed - conditional request used');
|
||||
|
||||
// The plugin will:
|
||||
// - Send If-None-Match header with cached ETag
|
||||
// - Receive 304 Not Modified if content unchanged
|
||||
// - Use cached content instead of downloading
|
||||
// - Update metrics to track efficiency
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ ETag conditional requests demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Check network efficiency metrics
|
||||
*/
|
||||
async function checkNetworkEfficiencyMetrics() {
|
||||
try {
|
||||
console.log('Checking network efficiency metrics...');
|
||||
|
||||
// Configure ETag support
|
||||
await configureETagSupport();
|
||||
|
||||
// Make some requests to generate metrics
|
||||
await demonstrateETagConditionalRequests();
|
||||
|
||||
// Get network metrics
|
||||
const metrics = await DailyNotification.getNetworkMetrics();
|
||||
|
||||
console.log('📊 Network Efficiency Metrics:');
|
||||
console.log(` Total Requests: ${metrics.totalRequests}`);
|
||||
console.log(` Cached Responses: ${metrics.cachedResponses}`);
|
||||
console.log(` Network Responses: ${metrics.networkResponses}`);
|
||||
console.log(` Errors: ${metrics.errors}`);
|
||||
console.log(` Cache Hit Ratio: ${(metrics.cacheHitRatio * 100).toFixed(1)}%`);
|
||||
|
||||
// Example output:
|
||||
// Total Requests: 4
|
||||
// Cached Responses: 2
|
||||
// Network Responses: 2
|
||||
// Errors: 0
|
||||
// Cache Hit Ratio: 50.0%
|
||||
|
||||
if (metrics.cacheHitRatio > 0.5) {
|
||||
console.log('✅ Good cache efficiency - ETag support is working well');
|
||||
} else {
|
||||
console.log('⚠️ Low cache efficiency - content may be changing frequently');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Network efficiency metrics check failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Manage ETag cache
|
||||
*/
|
||||
async function manageETagCache() {
|
||||
try {
|
||||
console.log('Managing ETag cache...');
|
||||
|
||||
// Configure ETag support
|
||||
await configureETagSupport();
|
||||
|
||||
// Get cache statistics
|
||||
const cacheStats = await DailyNotification.getCacheStatistics();
|
||||
|
||||
console.log('🗄️ ETag Cache Statistics:');
|
||||
console.log(` Total ETags: ${cacheStats.totalETags}`);
|
||||
console.log(` Valid ETags: ${cacheStats.validETags}`);
|
||||
console.log(` Expired ETags: ${cacheStats.expiredETags}`);
|
||||
|
||||
// Clean expired ETags
|
||||
if (cacheStats.expiredETags > 0) {
|
||||
console.log('🧹 Cleaning expired ETags...');
|
||||
await DailyNotification.cleanExpiredETags();
|
||||
console.log('✅ Expired ETags cleaned');
|
||||
}
|
||||
|
||||
// Reset metrics
|
||||
console.log('🔄 Resetting network metrics...');
|
||||
await DailyNotification.resetNetworkMetrics();
|
||||
console.log('✅ Network metrics reset');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ ETag cache management failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Handle ETag failures gracefully
|
||||
*/
|
||||
async function handleETagFailuresGracefully() {
|
||||
try {
|
||||
console.log('Handling ETag failures gracefully...');
|
||||
|
||||
// Configure ETag support
|
||||
await configureETagSupport();
|
||||
|
||||
// Schedule notification with potential ETag issues
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/unreliable-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with ETag fallback');
|
||||
|
||||
// The plugin will handle ETag failures by:
|
||||
// - Falling back to full content fetch if ETag fails
|
||||
// - Logging ETag errors for debugging
|
||||
// - Continuing with notification scheduling
|
||||
// - Updating error metrics
|
||||
|
||||
// Check metrics after potential failures
|
||||
const metrics = await DailyNotification.getNetworkMetrics();
|
||||
|
||||
if (metrics.errors > 0) {
|
||||
console.log(`⚠️ ${metrics.errors} ETag errors occurred - fallback used`);
|
||||
} else {
|
||||
console.log('✅ No ETag errors - all requests successful');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ ETag failure handling failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Monitor ETag performance over time
|
||||
*/
|
||||
async function monitorETagPerformance() {
|
||||
try {
|
||||
console.log('Monitoring ETag performance over time...');
|
||||
|
||||
// Configure ETag support
|
||||
await configureETagSupport();
|
||||
|
||||
// Monitor performance over multiple requests
|
||||
const monitoringInterval = setInterval(async () => {
|
||||
try {
|
||||
const metrics = await DailyNotification.getNetworkMetrics();
|
||||
const cacheStats = await DailyNotification.getCacheStatistics();
|
||||
|
||||
console.log('📊 Performance Snapshot:');
|
||||
console.log(` Cache Hit Ratio: ${(metrics.cacheHitRatio * 100).toFixed(1)}%`);
|
||||
console.log(` Total Requests: ${metrics.totalRequests}`);
|
||||
console.log(` Errors: ${metrics.errors}`);
|
||||
console.log(` Valid ETags: ${cacheStats.validETags}`);
|
||||
|
||||
// Stop monitoring if we have enough data
|
||||
if (metrics.totalRequests >= 10) {
|
||||
clearInterval(monitoringInterval);
|
||||
console.log('✅ Performance monitoring completed');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Performance monitoring error:', error);
|
||||
}
|
||||
}, 5000); // Check every 5 seconds
|
||||
|
||||
// Make some requests to generate data
|
||||
for (let i = 0; i < 5; i++) {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: `09:${i.toString().padStart(2, '0')}`,
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
// Wait between requests
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ ETag performance monitoring failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Optimize content fetching with ETags
|
||||
*/
|
||||
async function optimizeContentFetchingWithETags() {
|
||||
try {
|
||||
console.log('Optimizing content fetching with ETags...');
|
||||
|
||||
// Configure ETag support
|
||||
await configureETagSupport();
|
||||
|
||||
// Schedule multiple notifications for the same content
|
||||
const notifications = [
|
||||
{ time: '09:00', title: 'Morning Update' },
|
||||
{ time: '12:00', title: 'Midday Update' },
|
||||
{ time: '15:00', title: 'Afternoon Update' },
|
||||
{ time: '18:00', title: 'Evening Update' }
|
||||
];
|
||||
|
||||
for (const notification of notifications) {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content', // Same URL
|
||||
time: notification.time,
|
||||
title: notification.title,
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log(`✅ Scheduled ${notification.title} at ${notification.time}`);
|
||||
}
|
||||
|
||||
// Check final metrics
|
||||
const metrics = await DailyNotification.getNetworkMetrics();
|
||||
|
||||
console.log('📊 Optimization Results:');
|
||||
console.log(` Total Requests: ${metrics.totalRequests}`);
|
||||
console.log(` Cached Responses: ${metrics.cachedResponses}`);
|
||||
console.log(` Cache Hit Ratio: ${(metrics.cacheHitRatio * 100).toFixed(1)}%`);
|
||||
|
||||
// With ETag support, we should see:
|
||||
// - First request: Network response (200 OK)
|
||||
// - Subsequent requests: Cached responses (304 Not Modified)
|
||||
// - High cache hit ratio (75%+)
|
||||
// - Reduced bandwidth usage
|
||||
// - Faster response times
|
||||
|
||||
if (metrics.cacheHitRatio >= 0.75) {
|
||||
console.log('✅ Excellent optimization - ETag support is highly effective');
|
||||
} else if (metrics.cacheHitRatio >= 0.5) {
|
||||
console.log('✅ Good optimization - ETag support is working well');
|
||||
} else {
|
||||
console.log('⚠️ Limited optimization - content may be changing frequently');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Content fetching optimization failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export examples for use
|
||||
export {
|
||||
configureETagSupport,
|
||||
demonstrateETagConditionalRequests,
|
||||
checkNetworkEfficiencyMetrics,
|
||||
manageETagCache,
|
||||
handleETagFailuresGracefully,
|
||||
monitorETagPerformance,
|
||||
optimizeContentFetchingWithETags
|
||||
};
|
||||
@@ -1,423 +0,0 @@
|
||||
/**
|
||||
* Phase 3.2 Advanced Error Handling Usage Example
|
||||
*
|
||||
* Demonstrates comprehensive error handling with categorization, retry logic, and telemetry
|
||||
* Shows error classification, exponential backoff, and debugging information
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
/**
|
||||
* Example: Configure advanced error handling
|
||||
*/
|
||||
async function configureAdvancedErrorHandling() {
|
||||
try {
|
||||
console.log('Configuring advanced error handling...');
|
||||
|
||||
// Configure with error handling
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800, // 30 minutes TTL
|
||||
prefetchLeadMinutes: 15,
|
||||
enableErrorHandling: true,
|
||||
maxRetries: 3,
|
||||
baseRetryDelay: 1000, // 1 second
|
||||
maxRetryDelay: 30000, // 30 seconds
|
||||
backoffMultiplier: 2.0
|
||||
});
|
||||
|
||||
console.log('✅ Advanced error handling configured');
|
||||
|
||||
// The plugin will now:
|
||||
// - Categorize errors by type, code, and severity
|
||||
// - Implement exponential backoff retry logic
|
||||
// - Track error metrics and telemetry
|
||||
// - Provide comprehensive debugging information
|
||||
// - Manage retry state and limits
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Advanced error handling configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate error categorization
|
||||
*/
|
||||
async function demonstrateErrorCategorization() {
|
||||
try {
|
||||
console.log('Demonstrating error categorization...');
|
||||
|
||||
// Configure error handling
|
||||
await configureAdvancedErrorHandling();
|
||||
|
||||
// Simulate different types of errors
|
||||
const errorScenarios = [
|
||||
{
|
||||
name: 'Network Error',
|
||||
url: 'https://unreachable-api.example.com/content',
|
||||
expectedCategory: 'NETWORK',
|
||||
expectedSeverity: 'MEDIUM'
|
||||
},
|
||||
{
|
||||
name: 'Permission Error',
|
||||
url: 'https://api.example.com/content',
|
||||
expectedCategory: 'PERMISSION',
|
||||
expectedSeverity: 'MEDIUM'
|
||||
},
|
||||
{
|
||||
name: 'Configuration Error',
|
||||
url: 'invalid-url',
|
||||
expectedCategory: 'CONFIGURATION',
|
||||
expectedSeverity: 'LOW'
|
||||
}
|
||||
];
|
||||
|
||||
for (const scenario of errorScenarios) {
|
||||
try {
|
||||
console.log(`📡 Testing ${scenario.name}...`);
|
||||
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: scenario.url,
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.log(`✅ ${scenario.name} handled:`, error.message);
|
||||
// The error handler will:
|
||||
// - Categorize the error by type
|
||||
// - Assign appropriate severity level
|
||||
// - Generate unique error codes
|
||||
// - Track metrics for analysis
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error categorization demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate retry logic with exponential backoff
|
||||
*/
|
||||
async function demonstrateRetryLogic() {
|
||||
try {
|
||||
console.log('Demonstrating retry logic with exponential backoff...');
|
||||
|
||||
// Configure error handling
|
||||
await configureAdvancedErrorHandling();
|
||||
|
||||
// Schedule notification with unreliable endpoint
|
||||
console.log('📡 Scheduling notification with unreliable endpoint...');
|
||||
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://unreliable-api.example.com/content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with retry logic');
|
||||
|
||||
// The plugin will:
|
||||
// - Attempt the request
|
||||
// - If it fails, categorize the error
|
||||
// - If retryable, wait with exponential backoff
|
||||
// - Retry up to maxRetries times
|
||||
// - Track retry attempts and delays
|
||||
|
||||
// Check retry statistics
|
||||
const retryStats = await DailyNotification.getRetryStatistics();
|
||||
console.log('📊 Retry Statistics:', retryStats);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Retry logic demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Check error metrics and telemetry
|
||||
*/
|
||||
async function checkErrorMetricsAndTelemetry() {
|
||||
try {
|
||||
console.log('Checking error metrics and telemetry...');
|
||||
|
||||
// Configure error handling
|
||||
await configureAdvancedErrorHandling();
|
||||
|
||||
// Generate some errors to create metrics
|
||||
await demonstrateErrorCategorization();
|
||||
|
||||
// Get error metrics
|
||||
const errorMetrics = await DailyNotification.getErrorMetrics();
|
||||
|
||||
console.log('📊 Error Metrics:');
|
||||
console.log(` Total Errors: ${errorMetrics.totalErrors}`);
|
||||
console.log(` Network Errors: ${errorMetrics.networkErrors}`);
|
||||
console.log(` Storage Errors: ${errorMetrics.storageErrors}`);
|
||||
console.log(` Scheduling Errors: ${errorMetrics.schedulingErrors}`);
|
||||
console.log(` Permission Errors: ${errorMetrics.permissionErrors}`);
|
||||
console.log(` Configuration Errors: ${errorMetrics.configurationErrors}`);
|
||||
console.log(` System Errors: ${errorMetrics.systemErrors}`);
|
||||
console.log(` Unknown Errors: ${errorMetrics.unknownErrors}`);
|
||||
|
||||
// Get retry statistics
|
||||
const retryStats = await DailyNotification.getRetryStatistics();
|
||||
console.log('🔄 Retry Statistics:');
|
||||
console.log(` Total Operations: ${retryStats.totalOperations}`);
|
||||
console.log(` Active Retries: ${retryStats.activeRetries}`);
|
||||
console.log(` Total Retries: ${retryStats.totalRetries}`);
|
||||
|
||||
// Analyze error patterns
|
||||
if (errorMetrics.networkErrors > 0) {
|
||||
console.log('⚠️ Network errors detected - check connectivity');
|
||||
}
|
||||
|
||||
if (errorMetrics.permissionErrors > 0) {
|
||||
console.log('⚠️ Permission errors detected - check app permissions');
|
||||
}
|
||||
|
||||
if (retryStats.totalRetries > retryStats.totalOperations * 2) {
|
||||
console.log('⚠️ High retry rate - system may be unstable');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error metrics check failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Handle custom retry configurations
|
||||
*/
|
||||
async function handleCustomRetryConfigurations() {
|
||||
try {
|
||||
console.log('Handling custom retry configurations...');
|
||||
|
||||
// Configure error handling
|
||||
await configureAdvancedErrorHandling();
|
||||
|
||||
// Schedule notification with custom retry config
|
||||
console.log('📡 Scheduling with custom retry configuration...');
|
||||
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready',
|
||||
retryConfig: {
|
||||
maxRetries: 5,
|
||||
baseRetryDelay: 2000, // 2 seconds
|
||||
maxRetryDelay: 60000, // 60 seconds
|
||||
backoffMultiplier: 1.5
|
||||
}
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with custom retry config');
|
||||
|
||||
// The plugin will:
|
||||
// - Use custom retry limits (5 instead of 3)
|
||||
// - Use custom base delay (2s instead of 1s)
|
||||
// - Use custom max delay (60s instead of 30s)
|
||||
// - Use custom backoff multiplier (1.5 instead of 2.0)
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Custom retry configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Monitor error patterns over time
|
||||
*/
|
||||
async function monitorErrorPatternsOverTime() {
|
||||
try {
|
||||
console.log('Monitoring error patterns over time...');
|
||||
|
||||
// Configure error handling
|
||||
await configureAdvancedErrorHandling();
|
||||
|
||||
// Monitor errors over multiple operations
|
||||
const monitoringInterval = setInterval(async () => {
|
||||
try {
|
||||
const errorMetrics = await DailyNotification.getErrorMetrics();
|
||||
const retryStats = await DailyNotification.getRetryStatistics();
|
||||
|
||||
console.log('📊 Error Pattern Snapshot:');
|
||||
console.log(` Total Errors: ${errorMetrics.totalErrors}`);
|
||||
console.log(` Network Errors: ${errorMetrics.networkErrors}`);
|
||||
console.log(` Active Retries: ${retryStats.activeRetries}`);
|
||||
console.log(` Total Retries: ${retryStats.totalRetries}`);
|
||||
|
||||
// Stop monitoring if we have enough data
|
||||
if (errorMetrics.totalErrors >= 10) {
|
||||
clearInterval(monitoringInterval);
|
||||
console.log('✅ Error pattern monitoring completed');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error pattern monitoring error:', error);
|
||||
}
|
||||
}, 5000); // Check every 5 seconds
|
||||
|
||||
// Make some requests to generate data
|
||||
for (let i = 0; i < 5; i++) {
|
||||
try {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/content',
|
||||
time: `09:${i.toString().padStart(2, '0')}`,
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
} catch (error) {
|
||||
// Errors will be handled by the error handler
|
||||
console.log(`Request ${i + 1} failed:`, error.message);
|
||||
}
|
||||
|
||||
// Wait between requests
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error pattern monitoring failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Reset error metrics and retry states
|
||||
*/
|
||||
async function resetErrorMetricsAndRetryStates() {
|
||||
try {
|
||||
console.log('Resetting error metrics and retry states...');
|
||||
|
||||
// Configure error handling
|
||||
await configureAdvancedErrorHandling();
|
||||
|
||||
// Get current metrics
|
||||
const beforeMetrics = await DailyNotification.getErrorMetrics();
|
||||
const beforeRetryStats = await DailyNotification.getRetryStatistics();
|
||||
|
||||
console.log('📊 Before Reset:');
|
||||
console.log(` Total Errors: ${beforeMetrics.totalErrors}`);
|
||||
console.log(` Active Retries: ${beforeRetryStats.activeRetries}`);
|
||||
|
||||
// Reset metrics
|
||||
await DailyNotification.resetErrorMetrics();
|
||||
console.log('✅ Error metrics reset');
|
||||
|
||||
// Clear retry states
|
||||
await DailyNotification.clearRetryStates();
|
||||
console.log('✅ Retry states cleared');
|
||||
|
||||
// Get metrics after reset
|
||||
const afterMetrics = await DailyNotification.getErrorMetrics();
|
||||
const afterRetryStats = await DailyNotification.getRetryStatistics();
|
||||
|
||||
console.log('📊 After Reset:');
|
||||
console.log(` Total Errors: ${afterMetrics.totalErrors}`);
|
||||
console.log(` Active Retries: ${afterRetryStats.activeRetries}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error metrics reset failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Debug error handling information
|
||||
*/
|
||||
async function debugErrorHandlingInformation() {
|
||||
try {
|
||||
console.log('Debugging error handling information...');
|
||||
|
||||
// Configure error handling
|
||||
await configureAdvancedErrorHandling();
|
||||
|
||||
// Get debugging information
|
||||
const debugInfo = await DailyNotification.getErrorDebugInfo();
|
||||
|
||||
console.log('🐛 Error Debug Information:');
|
||||
console.log(` Error Handler Status: ${debugInfo.handlerStatus}`);
|
||||
console.log(` Configuration: ${JSON.stringify(debugInfo.configuration)}`);
|
||||
console.log(` Recent Errors: ${debugInfo.recentErrors.length}`);
|
||||
console.log(` Retry States: ${debugInfo.retryStates.length}`);
|
||||
|
||||
// Display recent errors
|
||||
if (debugInfo.recentErrors.length > 0) {
|
||||
console.log('📋 Recent Errors:');
|
||||
debugInfo.recentErrors.forEach((error, index) => {
|
||||
console.log(` ${index + 1}. ${error.category} - ${error.severity} - ${error.errorCode}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Display retry states
|
||||
if (debugInfo.retryStates.length > 0) {
|
||||
console.log('🔄 Retry States:');
|
||||
debugInfo.retryStates.forEach((state, index) => {
|
||||
console.log(` ${index + 1}. Operation: ${state.operationId} - Attempts: ${state.attemptCount}`);
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error debugging failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Optimize error handling for production
|
||||
*/
|
||||
async function optimizeErrorHandlingForProduction() {
|
||||
try {
|
||||
console.log('Optimizing error handling for production...');
|
||||
|
||||
// Configure production-optimized error handling
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800,
|
||||
prefetchLeadMinutes: 15,
|
||||
enableErrorHandling: true,
|
||||
maxRetries: 3,
|
||||
baseRetryDelay: 1000,
|
||||
maxRetryDelay: 30000,
|
||||
backoffMultiplier: 2.0,
|
||||
enableErrorTelemetry: true,
|
||||
errorReportingEndpoint: 'https://api.example.com/errors'
|
||||
});
|
||||
|
||||
console.log('✅ Production error handling configured');
|
||||
|
||||
// The plugin will now:
|
||||
// - Use production-optimized retry settings
|
||||
// - Enable error telemetry and reporting
|
||||
// - Send error data to monitoring endpoint
|
||||
// - Provide comprehensive debugging information
|
||||
// - Handle errors gracefully without user impact
|
||||
|
||||
// Schedule notification with production error handling
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with production error handling');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Production error handling optimization failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export examples for use
|
||||
export {
|
||||
configureAdvancedErrorHandling,
|
||||
demonstrateErrorCategorization,
|
||||
demonstrateRetryLogic,
|
||||
checkErrorMetricsAndTelemetry,
|
||||
handleCustomRetryConfigurations,
|
||||
monitorErrorPatternsOverTime,
|
||||
resetErrorMetricsAndRetryStates,
|
||||
debugErrorHandlingInformation,
|
||||
optimizeErrorHandlingForProduction
|
||||
};
|
||||
@@ -1,413 +0,0 @@
|
||||
/**
|
||||
* Phase 3.3 Performance Optimization Usage Example
|
||||
*
|
||||
* Demonstrates comprehensive performance optimization including database, memory, and battery
|
||||
* Shows query optimization, memory management, object pooling, and performance monitoring
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
/**
|
||||
* Example: Configure performance optimization
|
||||
*/
|
||||
async function configurePerformanceOptimization() {
|
||||
try {
|
||||
console.log('Configuring performance optimization...');
|
||||
|
||||
// Configure with performance optimization
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800, // 30 minutes TTL
|
||||
prefetchLeadMinutes: 15,
|
||||
enablePerformanceOptimization: true,
|
||||
enableDatabaseIndexes: true,
|
||||
enableObjectPooling: true,
|
||||
enableMemoryMonitoring: true,
|
||||
enableBatteryOptimization: true,
|
||||
memoryWarningThreshold: 50, // MB
|
||||
memoryCriticalThreshold: 100, // MB
|
||||
objectPoolSize: 10,
|
||||
maxObjectPoolSize: 50
|
||||
});
|
||||
|
||||
console.log('✅ Performance optimization configured');
|
||||
|
||||
// The plugin will now:
|
||||
// - Add database indexes for query optimization
|
||||
// - Implement object pooling for frequently used objects
|
||||
// - Monitor memory usage with automatic cleanup
|
||||
// - Optimize battery usage and background CPU
|
||||
// - Track performance metrics and provide reports
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Performance optimization configuration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate database optimization
|
||||
*/
|
||||
async function demonstrateDatabaseOptimization() {
|
||||
try {
|
||||
console.log('Demonstrating database optimization...');
|
||||
|
||||
// Configure performance optimization
|
||||
await configurePerformanceOptimization();
|
||||
|
||||
// Optimize database
|
||||
console.log('🗄️ Optimizing database...');
|
||||
await DailyNotification.optimizeDatabase();
|
||||
|
||||
// The plugin will:
|
||||
// - Add indexes for common queries (slot_id, fetched_at, status, etc.)
|
||||
// - Optimize query performance with PRAGMA settings
|
||||
// - Implement connection pooling with cache optimization
|
||||
// - Analyze database performance and update metrics
|
||||
|
||||
console.log('✅ Database optimization completed');
|
||||
|
||||
// Check database performance metrics
|
||||
const dbMetrics = await DailyNotification.getDatabaseMetrics();
|
||||
console.log('📊 Database Metrics:');
|
||||
console.log(` Page Count: ${dbMetrics.pageCount}`);
|
||||
console.log(` Page Size: ${dbMetrics.pageSize}`);
|
||||
console.log(` Cache Size: ${dbMetrics.cacheSize}`);
|
||||
console.log(` Query Performance: ${dbMetrics.queryPerformance}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Database optimization demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate memory optimization
|
||||
*/
|
||||
async function demonstrateMemoryOptimization() {
|
||||
try {
|
||||
console.log('Demonstrating memory optimization...');
|
||||
|
||||
// Configure performance optimization
|
||||
await configurePerformanceOptimization();
|
||||
|
||||
// Check initial memory usage
|
||||
const initialMemory = await DailyNotification.getMemoryUsage();
|
||||
console.log(`📊 Initial Memory Usage: ${initialMemory.usage}MB`);
|
||||
|
||||
// Optimize memory
|
||||
console.log('🧠 Optimizing memory...');
|
||||
await DailyNotification.optimizeMemory();
|
||||
|
||||
// The plugin will:
|
||||
// - Check current memory usage
|
||||
// - Perform cleanup if thresholds exceeded
|
||||
// - Optimize object pools
|
||||
// - Clear old caches
|
||||
// - Update memory metrics
|
||||
|
||||
console.log('✅ Memory optimization completed');
|
||||
|
||||
// Check memory after optimization
|
||||
const optimizedMemory = await DailyNotification.getMemoryUsage();
|
||||
console.log(`📊 Optimized Memory Usage: ${optimizedMemory.usage}MB`);
|
||||
console.log(`📊 Memory Reduction: ${initialMemory.usage - optimizedMemory.usage}MB`);
|
||||
|
||||
// Check memory metrics
|
||||
const memoryMetrics = await DailyNotification.getMemoryMetrics();
|
||||
console.log('📊 Memory Metrics:');
|
||||
console.log(` Average Usage: ${memoryMetrics.averageUsage}MB`);
|
||||
console.log(` Peak Usage: ${memoryMetrics.peakUsage}MB`);
|
||||
console.log(` Cleanup Count: ${memoryMetrics.cleanupCount}`);
|
||||
console.log(` Critical Cleanups: ${memoryMetrics.criticalCleanupCount}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Memory optimization demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate object pooling
|
||||
*/
|
||||
async function demonstrateObjectPooling() {
|
||||
try {
|
||||
console.log('Demonstrating object pooling...');
|
||||
|
||||
// Configure performance optimization
|
||||
await configurePerformanceOptimization();
|
||||
|
||||
// Get objects from pool
|
||||
console.log('🔄 Using object pooling...');
|
||||
|
||||
const objects = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const obj = await DailyNotification.getPooledObject('String');
|
||||
objects.push(obj);
|
||||
console.log(` Got object ${i + 1} from pool`);
|
||||
}
|
||||
|
||||
// Return objects to pool
|
||||
for (let i = 0; i < objects.length; i++) {
|
||||
await DailyNotification.returnPooledObject('String', objects[i]);
|
||||
console.log(` Returned object ${i + 1} to pool`);
|
||||
}
|
||||
|
||||
// The plugin will:
|
||||
// - Reuse objects from pool instead of creating new ones
|
||||
// - Reduce memory allocation and garbage collection
|
||||
// - Track pool hits and misses
|
||||
// - Optimize pool sizes based on usage patterns
|
||||
|
||||
console.log('✅ Object pooling demonstration completed');
|
||||
|
||||
// Check object pool metrics
|
||||
const poolMetrics = await DailyNotification.getObjectPoolMetrics();
|
||||
console.log('📊 Object Pool Metrics:');
|
||||
console.log(` Pool Hits: ${poolMetrics.poolHits}`);
|
||||
console.log(` Pool Misses: ${poolMetrics.poolMisses}`);
|
||||
console.log(` Hit Ratio: ${(poolMetrics.hitRatio * 100).toFixed(1)}%`);
|
||||
console.log(` Active Pools: ${poolMetrics.activePools}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Object pooling demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Demonstrate battery optimization
|
||||
*/
|
||||
async function demonstrateBatteryOptimization() {
|
||||
try {
|
||||
console.log('Demonstrating battery optimization...');
|
||||
|
||||
// Configure performance optimization
|
||||
await configurePerformanceOptimization();
|
||||
|
||||
// Optimize battery usage
|
||||
console.log('🔋 Optimizing battery usage...');
|
||||
await DailyNotification.optimizeBattery();
|
||||
|
||||
// The plugin will:
|
||||
// - Minimize background CPU usage
|
||||
// - Optimize network requests for efficiency
|
||||
// - Track battery usage patterns
|
||||
// - Adjust behavior based on battery level
|
||||
// - Reduce task frequency during low battery
|
||||
|
||||
console.log('✅ Battery optimization completed');
|
||||
|
||||
// Check battery metrics
|
||||
const batteryMetrics = await DailyNotification.getBatteryMetrics();
|
||||
console.log('📊 Battery Metrics:');
|
||||
console.log(` Background CPU Usage: ${batteryMetrics.backgroundCpuUsage}%`);
|
||||
console.log(` Network Efficiency: ${batteryMetrics.networkEfficiency}%`);
|
||||
console.log(` Battery Level: ${batteryMetrics.batteryLevel}%`);
|
||||
console.log(` Power Saving Mode: ${batteryMetrics.powerSavingMode ? 'Enabled' : 'Disabled'}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Battery optimization demonstration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Monitor performance metrics
|
||||
*/
|
||||
async function monitorPerformanceMetrics() {
|
||||
try {
|
||||
console.log('Monitoring performance metrics...');
|
||||
|
||||
// Configure performance optimization
|
||||
await configurePerformanceOptimization();
|
||||
|
||||
// Get comprehensive performance metrics
|
||||
const performanceMetrics = await DailyNotification.getPerformanceMetrics();
|
||||
|
||||
console.log('📊 Performance Metrics:');
|
||||
console.log(` Overall Score: ${performanceMetrics.overallScore}/100`);
|
||||
console.log(` Database Performance: ${performanceMetrics.databasePerformance}/100`);
|
||||
console.log(` Memory Efficiency: ${performanceMetrics.memoryEfficiency}/100`);
|
||||
console.log(` Battery Efficiency: ${performanceMetrics.batteryEfficiency}/100`);
|
||||
console.log(` Object Pool Efficiency: ${performanceMetrics.objectPoolEfficiency}/100`);
|
||||
|
||||
// Detailed metrics
|
||||
console.log('📊 Detailed Metrics:');
|
||||
console.log(` Database Queries: ${performanceMetrics.totalDatabaseQueries}`);
|
||||
console.log(` Memory Usage: ${performanceMetrics.averageMemoryUsage}MB`);
|
||||
console.log(` Object Pool Hits: ${performanceMetrics.objectPoolHits}`);
|
||||
console.log(` Background CPU: ${performanceMetrics.backgroundCpuUsage}%`);
|
||||
console.log(` Network Requests: ${performanceMetrics.totalNetworkRequests}`);
|
||||
|
||||
// Performance recommendations
|
||||
if (performanceMetrics.recommendations.length > 0) {
|
||||
console.log('💡 Performance Recommendations:');
|
||||
performanceMetrics.recommendations.forEach((rec, index) => {
|
||||
console.log(` ${index + 1}. ${rec}`);
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Performance metrics monitoring failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Performance optimization for production
|
||||
*/
|
||||
async function optimizeForProduction() {
|
||||
try {
|
||||
console.log('Optimizing for production...');
|
||||
|
||||
// Configure production-optimized settings
|
||||
await DailyNotification.configure({
|
||||
storage: 'shared',
|
||||
ttlSeconds: 1800,
|
||||
prefetchLeadMinutes: 15,
|
||||
enablePerformanceOptimization: true,
|
||||
enableDatabaseIndexes: true,
|
||||
enableObjectPooling: true,
|
||||
enableMemoryMonitoring: true,
|
||||
enableBatteryOptimization: true,
|
||||
memoryWarningThreshold: 30, // Lower threshold for production
|
||||
memoryCriticalThreshold: 60, // Lower threshold for production
|
||||
objectPoolSize: 20, // Larger pool for production
|
||||
maxObjectPoolSize: 100, // Larger max pool for production
|
||||
enablePerformanceReporting: true,
|
||||
performanceReportInterval: 3600000 // 1 hour
|
||||
});
|
||||
|
||||
console.log('✅ Production optimization configured');
|
||||
|
||||
// Run all optimizations
|
||||
console.log('🚀 Running production optimizations...');
|
||||
|
||||
await DailyNotification.optimizeDatabase();
|
||||
await DailyNotification.optimizeMemory();
|
||||
await DailyNotification.optimizeBattery();
|
||||
|
||||
console.log('✅ Production optimizations completed');
|
||||
|
||||
// Schedule notifications with optimized performance
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily notification is ready'
|
||||
});
|
||||
|
||||
console.log('✅ Notification scheduled with production optimization');
|
||||
|
||||
// The plugin will now:
|
||||
// - Use optimized database queries with indexes
|
||||
// - Manage memory efficiently with automatic cleanup
|
||||
// - Pool objects to reduce allocation overhead
|
||||
// - Monitor battery usage and adjust behavior
|
||||
// - Provide comprehensive performance reporting
|
||||
// - Handle high load scenarios gracefully
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Production optimization failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Performance stress testing
|
||||
*/
|
||||
async function performanceStressTesting() {
|
||||
try {
|
||||
console.log('Running performance stress testing...');
|
||||
|
||||
// Configure performance optimization
|
||||
await configurePerformanceOptimization();
|
||||
|
||||
// Stress test with multiple operations
|
||||
const operations = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
operations.push(
|
||||
DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: `09:${i.toString().padStart(2, '0')}`,
|
||||
title: `Daily Update ${i + 1}`,
|
||||
body: 'Your daily notification is ready'
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
console.log('📡 Executing 10 concurrent operations...');
|
||||
const startTime = Date.now();
|
||||
|
||||
await Promise.all(operations);
|
||||
|
||||
const endTime = Date.now();
|
||||
const duration = endTime - startTime;
|
||||
|
||||
console.log(`✅ Stress test completed in ${duration}ms`);
|
||||
|
||||
// Check performance under load
|
||||
const stressMetrics = await DailyNotification.getPerformanceMetrics();
|
||||
console.log('📊 Stress Test Results:');
|
||||
console.log(` Operations Completed: 10`);
|
||||
console.log(` Total Duration: ${duration}ms`);
|
||||
console.log(` Average per Operation: ${duration / 10}ms`);
|
||||
console.log(` Performance Score: ${stressMetrics.overallScore}/100`);
|
||||
console.log(` Memory Usage: ${stressMetrics.averageMemoryUsage}MB`);
|
||||
|
||||
// Performance should remain stable under load
|
||||
if (stressMetrics.overallScore >= 80) {
|
||||
console.log('✅ Excellent performance under load');
|
||||
} else if (stressMetrics.overallScore >= 60) {
|
||||
console.log('✅ Good performance under load');
|
||||
} else {
|
||||
console.log('⚠️ Performance degradation under load detected');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Performance stress testing failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Reset performance metrics
|
||||
*/
|
||||
async function resetPerformanceMetrics() {
|
||||
try {
|
||||
console.log('Resetting performance metrics...');
|
||||
|
||||
// Configure performance optimization
|
||||
await configurePerformanceOptimization();
|
||||
|
||||
// Get metrics before reset
|
||||
const beforeMetrics = await DailyNotification.getPerformanceMetrics();
|
||||
console.log('📊 Before Reset:');
|
||||
console.log(` Overall Score: ${beforeMetrics.overallScore}/100`);
|
||||
console.log(` Database Queries: ${beforeMetrics.totalDatabaseQueries}`);
|
||||
console.log(` Memory Usage: ${beforeMetrics.averageMemoryUsage}MB`);
|
||||
|
||||
// Reset metrics
|
||||
await DailyNotification.resetPerformanceMetrics();
|
||||
console.log('✅ Performance metrics reset');
|
||||
|
||||
// Get metrics after reset
|
||||
const afterMetrics = await DailyNotification.getPerformanceMetrics();
|
||||
console.log('📊 After Reset:');
|
||||
console.log(` Overall Score: ${afterMetrics.overallScore}/100`);
|
||||
console.log(` Database Queries: ${afterMetrics.totalDatabaseQueries}`);
|
||||
console.log(` Memory Usage: ${afterMetrics.averageMemoryUsage}MB`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Performance metrics reset failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export examples for use
|
||||
export {
|
||||
configurePerformanceOptimization,
|
||||
demonstrateDatabaseOptimization,
|
||||
demonstrateMemoryOptimization,
|
||||
demonstrateObjectPooling,
|
||||
demonstrateBatteryOptimization,
|
||||
monitorPerformanceMetrics,
|
||||
optimizeForProduction,
|
||||
performanceStressTesting,
|
||||
resetPerformanceMetrics
|
||||
};
|
||||
@@ -1,342 +0,0 @@
|
||||
/**
|
||||
* Static Daily Reminders Examples
|
||||
*
|
||||
* Examples demonstrating the static daily reminder functionality
|
||||
* that works without network content or content caching.
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
/**
|
||||
* Basic Daily Reminder
|
||||
*
|
||||
* Schedule a simple daily reminder with default settings
|
||||
*/
|
||||
export async function scheduleBasicReminder() {
|
||||
try {
|
||||
await DailyNotification.scheduleDailyReminder({
|
||||
id: 'morning_checkin',
|
||||
title: 'Good Morning!',
|
||||
body: 'Time to check your TimeSafari community updates',
|
||||
time: '09:00'
|
||||
});
|
||||
|
||||
console.log('✅ Basic reminder scheduled for 9:00 AM daily');
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to schedule basic reminder:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Customized Daily Reminder
|
||||
*
|
||||
* Schedule a reminder with custom sound, vibration, and priority
|
||||
*/
|
||||
export async function scheduleCustomizedReminder() {
|
||||
try {
|
||||
await DailyNotification.scheduleDailyReminder({
|
||||
id: 'evening_reflection',
|
||||
title: 'Evening Reflection',
|
||||
body: 'Take a moment to reflect on your day and plan for tomorrow',
|
||||
time: '20:00',
|
||||
sound: true,
|
||||
vibration: true,
|
||||
priority: 'high',
|
||||
repeatDaily: true
|
||||
});
|
||||
|
||||
console.log('✅ Customized reminder scheduled for 8:00 PM daily');
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to schedule customized reminder:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiple Daily Reminders
|
||||
*
|
||||
* Schedule multiple reminders throughout the day
|
||||
*/
|
||||
export async function scheduleMultipleReminders() {
|
||||
const reminders = [
|
||||
{
|
||||
id: 'morning_motivation',
|
||||
title: 'Morning Motivation',
|
||||
body: 'Start your day with positive energy!',
|
||||
time: '07:00',
|
||||
priority: 'high' as const
|
||||
},
|
||||
{
|
||||
id: 'lunch_break',
|
||||
title: 'Lunch Break',
|
||||
body: 'Time for a well-deserved break',
|
||||
time: '12:30',
|
||||
priority: 'normal' as const
|
||||
},
|
||||
{
|
||||
id: 'evening_gratitude',
|
||||
title: 'Evening Gratitude',
|
||||
body: 'What are you grateful for today?',
|
||||
time: '19:00',
|
||||
priority: 'normal' as const
|
||||
}
|
||||
];
|
||||
|
||||
try {
|
||||
for (const reminder of reminders) {
|
||||
await DailyNotification.scheduleDailyReminder(reminder);
|
||||
console.log(`✅ Scheduled reminder: ${reminder.id} at ${reminder.time}`);
|
||||
}
|
||||
|
||||
console.log('✅ All reminders scheduled successfully');
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to schedule multiple reminders:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get All Scheduled Reminders
|
||||
*
|
||||
* Retrieve and display all currently scheduled reminders
|
||||
*/
|
||||
export async function getAllScheduledReminders() {
|
||||
try {
|
||||
const result = await DailyNotification.getScheduledReminders();
|
||||
|
||||
if (result.reminders && result.reminders.length > 0) {
|
||||
console.log(`📋 Found ${result.reminders.length} scheduled reminders:`);
|
||||
|
||||
result.reminders.forEach((reminder, index) => {
|
||||
console.log(`${index + 1}. ${reminder.title} (${reminder.id})`);
|
||||
console.log(` Time: ${reminder.time}`);
|
||||
console.log(` Priority: ${reminder.priority}`);
|
||||
console.log(` Repeat Daily: ${reminder.repeatDaily}`);
|
||||
console.log(` Scheduled: ${reminder.isScheduled ? 'Yes' : 'No'}`);
|
||||
console.log('');
|
||||
});
|
||||
} else {
|
||||
console.log('📋 No scheduled reminders found');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to get scheduled reminders:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Existing Reminder
|
||||
*
|
||||
* Update an existing reminder with new settings
|
||||
*/
|
||||
export async function updateExistingReminder() {
|
||||
try {
|
||||
// Update the morning check-in reminder
|
||||
await DailyNotification.updateDailyReminder('morning_checkin', {
|
||||
title: 'Updated Morning Check-in',
|
||||
body: 'Time to check your TimeSafari community updates and plan your day',
|
||||
time: '08:30',
|
||||
priority: 'high'
|
||||
});
|
||||
|
||||
console.log('✅ Morning check-in reminder updated to 8:30 AM with high priority');
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to update reminder:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel Specific Reminder
|
||||
*
|
||||
* Cancel a specific reminder by ID
|
||||
*/
|
||||
export async function cancelSpecificReminder() {
|
||||
try {
|
||||
await DailyNotification.cancelDailyReminder('evening_reflection');
|
||||
console.log('✅ Evening reflection reminder cancelled');
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to cancel reminder:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel All Reminders
|
||||
*
|
||||
* Cancel all scheduled reminders
|
||||
*/
|
||||
export async function cancelAllReminders() {
|
||||
try {
|
||||
const result = await DailyNotification.getScheduledReminders();
|
||||
|
||||
if (result.reminders && result.reminders.length > 0) {
|
||||
for (const reminder of result.reminders) {
|
||||
await DailyNotification.cancelDailyReminder(reminder.id);
|
||||
console.log(`✅ Cancelled reminder: ${reminder.id}`);
|
||||
}
|
||||
|
||||
console.log('✅ All reminders cancelled successfully');
|
||||
} else {
|
||||
console.log('📋 No reminders to cancel');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to cancel all reminders:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reminder Management Workflow
|
||||
*
|
||||
* Complete workflow demonstrating reminder management
|
||||
*/
|
||||
export async function reminderManagementWorkflow() {
|
||||
console.log('🚀 Starting reminder management workflow...\n');
|
||||
|
||||
try {
|
||||
// 1. Schedule initial reminders
|
||||
console.log('1. Scheduling initial reminders...');
|
||||
await scheduleMultipleReminders();
|
||||
console.log('');
|
||||
|
||||
// 2. Get all reminders
|
||||
console.log('2. Getting all scheduled reminders...');
|
||||
await getAllScheduledReminders();
|
||||
console.log('');
|
||||
|
||||
// 3. Update a reminder
|
||||
console.log('3. Updating morning check-in reminder...');
|
||||
await updateExistingReminder();
|
||||
console.log('');
|
||||
|
||||
// 4. Get updated reminders
|
||||
console.log('4. Getting updated reminders...');
|
||||
await getAllScheduledReminders();
|
||||
console.log('');
|
||||
|
||||
// 5. Cancel a specific reminder
|
||||
console.log('5. Cancelling evening reflection reminder...');
|
||||
await cancelSpecificReminder();
|
||||
console.log('');
|
||||
|
||||
// 6. Final reminder list
|
||||
console.log('6. Final reminder list...');
|
||||
await getAllScheduledReminders();
|
||||
|
||||
console.log('🎉 Reminder management workflow completed successfully!');
|
||||
} catch (error) {
|
||||
console.error('❌ Reminder management workflow failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Format Validation Examples
|
||||
*
|
||||
* Examples of valid and invalid time formats
|
||||
*/
|
||||
export function timeFormatExamples() {
|
||||
console.log('⏰ Time Format Examples:');
|
||||
console.log('');
|
||||
|
||||
const validTimes = [
|
||||
'00:00', // Midnight
|
||||
'06:30', // 6:30 AM
|
||||
'12:00', // Noon
|
||||
'18:45', // 6:45 PM
|
||||
'23:59' // 11:59 PM
|
||||
];
|
||||
|
||||
const invalidTimes = [
|
||||
'24:00', // Invalid hour
|
||||
'12:60', // Invalid minute
|
||||
'9:00', // Missing leading zero
|
||||
'12:0', // Missing trailing zero
|
||||
'12', // Missing minutes
|
||||
'abc' // Non-numeric
|
||||
];
|
||||
|
||||
console.log('✅ Valid time formats:');
|
||||
validTimes.forEach(time => {
|
||||
console.log(` "${time}" - Valid`);
|
||||
});
|
||||
|
||||
console.log('');
|
||||
console.log('❌ Invalid time formats:');
|
||||
invalidTimes.forEach(time => {
|
||||
console.log(` "${time}" - Invalid`);
|
||||
});
|
||||
|
||||
console.log('');
|
||||
console.log('📝 Time format rules:');
|
||||
console.log(' - Use HH:mm format (24-hour)');
|
||||
console.log(' - Hours: 00-23');
|
||||
console.log(' - Minutes: 00-59');
|
||||
console.log(' - Always use leading zeros');
|
||||
}
|
||||
|
||||
/**
|
||||
* Platform-Specific Considerations
|
||||
*
|
||||
* Important notes for different platforms
|
||||
*/
|
||||
export function platformConsiderations() {
|
||||
console.log('📱 Platform-Specific Considerations:');
|
||||
console.log('');
|
||||
|
||||
console.log('🤖 Android:');
|
||||
console.log(' - Uses AlarmManager for precise scheduling');
|
||||
console.log(' - Requires POST_NOTIFICATIONS permission');
|
||||
console.log(' - May be affected by battery optimization');
|
||||
console.log(' - Survives device reboots');
|
||||
console.log('');
|
||||
|
||||
console.log('🍎 iOS:');
|
||||
console.log(' - Uses UNUserNotificationCenter');
|
||||
console.log(' - Requires notification permissions');
|
||||
console.log(' - Limited to 64 scheduled notifications');
|
||||
console.log(' - May be affected by Background App Refresh');
|
||||
console.log('');
|
||||
|
||||
console.log('🌐 Web:');
|
||||
console.log(' - Uses setTimeout for scheduling');
|
||||
console.log(' - Requires notification permissions');
|
||||
console.log(' - Limited by browser tab lifecycle');
|
||||
console.log(' - May not persist across browser restarts');
|
||||
console.log('');
|
||||
|
||||
console.log('💡 Best Practices:');
|
||||
console.log(' - Always request notification permissions first');
|
||||
console.log(' - Handle permission denials gracefully');
|
||||
console.log(' - Test on actual devices, not just simulators');
|
||||
console.log(' - Consider platform limitations in your app design');
|
||||
}
|
||||
|
||||
// Export all functions for easy importing
|
||||
export const StaticReminderExamples = {
|
||||
scheduleBasicReminder,
|
||||
scheduleCustomizedReminder,
|
||||
scheduleMultipleReminders,
|
||||
getAllScheduledReminders,
|
||||
updateExistingReminder,
|
||||
cancelSpecificReminder,
|
||||
cancelAllReminders,
|
||||
reminderManagementWorkflow,
|
||||
timeFormatExamples,
|
||||
platformConsiderations
|
||||
};
|
||||
|
||||
// Example usage
|
||||
if (require.main === module) {
|
||||
console.log('📚 Static Daily Reminders Examples');
|
||||
console.log('=====================================\n');
|
||||
|
||||
// Show time format examples
|
||||
timeFormatExamples();
|
||||
console.log('');
|
||||
|
||||
// Show platform considerations
|
||||
platformConsiderations();
|
||||
console.log('');
|
||||
|
||||
console.log('💡 To run the examples, import and call the functions:');
|
||||
console.log(' import { StaticReminderExamples } from "./static-daily-reminders";');
|
||||
console.log(' await StaticReminderExamples.reminderManagementWorkflow();');
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,165 +0,0 @@
|
||||
/**
|
||||
* Example usage of the Daily Notification plugin
|
||||
* Demonstrates various features and best practices
|
||||
*/
|
||||
|
||||
import { registerPlugin } from '@capacitor/core';
|
||||
import { DailyNotificationPlugin } from '../src/definitions';
|
||||
|
||||
const DailyNotification = registerPlugin<DailyNotificationPlugin>('DailyNotification');
|
||||
|
||||
/**
|
||||
* Basic setup for daily notifications
|
||||
*/
|
||||
async function setupBasicNotifications() {
|
||||
try {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '08:00', // 8 AM
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily content is ready!'
|
||||
});
|
||||
console.log('Daily notifications scheduled successfully');
|
||||
} catch (error) {
|
||||
console.error('Failed to schedule notifications:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Advanced setup with custom options
|
||||
*/
|
||||
async function setupAdvancedNotifications() {
|
||||
try {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '09:00', // 9 AM
|
||||
title: 'Daily Digest',
|
||||
body: 'Your personalized daily digest is ready',
|
||||
sound: true,
|
||||
vibrate: true,
|
||||
priority: 'high',
|
||||
retryCount: 3,
|
||||
retryInterval: 15, // minutes
|
||||
cacheDuration: 24, // hours
|
||||
headers: {
|
||||
'Authorization': 'Bearer your-token'
|
||||
}
|
||||
});
|
||||
console.log('Advanced notification setup completed');
|
||||
} catch (error) {
|
||||
console.error('Failed to setup advanced notifications:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle notification response
|
||||
*/
|
||||
async function handleNotificationResponse() {
|
||||
try {
|
||||
const response = await DailyNotification.getLastNotification();
|
||||
if (response) {
|
||||
console.log('Last notification:', response);
|
||||
// Handle the notification data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to get last notification:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel all scheduled notifications
|
||||
*/
|
||||
async function cancelNotifications() {
|
||||
try {
|
||||
await DailyNotification.cancelAllNotifications();
|
||||
console.log('All notifications cancelled');
|
||||
} catch (error) {
|
||||
console.error('Failed to cancel notifications:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check notification status
|
||||
*/
|
||||
async function checkNotificationStatus() {
|
||||
try {
|
||||
const status = await DailyNotification.getNotificationStatus();
|
||||
console.log('Notification status:', status);
|
||||
return status;
|
||||
} catch (error) {
|
||||
console.error('Failed to get notification status:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update notification settings
|
||||
*/
|
||||
async function updateNotificationSettings() {
|
||||
try {
|
||||
await DailyNotification.updateSettings({
|
||||
time: '10:00', // Change to 10 AM
|
||||
sound: false, // Disable sound
|
||||
priority: 'normal'
|
||||
});
|
||||
console.log('Notification settings updated');
|
||||
} catch (error) {
|
||||
console.error('Failed to update settings:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of handling network errors
|
||||
*/
|
||||
async function handleNetworkErrors() {
|
||||
try {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '08:00',
|
||||
retryCount: 3,
|
||||
retryInterval: 15,
|
||||
offlineFallback: true
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.code === 'NETWORK_ERROR') {
|
||||
console.log('Network error, will retry later');
|
||||
} else {
|
||||
console.error('Unexpected error:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of using custom content handlers
|
||||
*/
|
||||
async function useCustomContentHandler() {
|
||||
try {
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/daily-content',
|
||||
time: '08:00',
|
||||
contentHandler: async (response) => {
|
||||
// Custom processing of the API response
|
||||
const data = await response.json();
|
||||
return {
|
||||
title: data.title,
|
||||
body: data.summary,
|
||||
data: data.details
|
||||
};
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to setup custom content handler:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export all example functions
|
||||
export {
|
||||
setupBasicNotifications,
|
||||
setupAdvancedNotifications,
|
||||
handleNotificationResponse,
|
||||
cancelNotifications,
|
||||
checkNotificationStatus,
|
||||
updateNotificationSettings,
|
||||
handleNetworkErrors,
|
||||
useCustomContentHandler
|
||||
};
|
||||
Reference in New Issue
Block a user