Browse Source

feat: continue Priority 2 fixes - non-null assertions and return types

🚀 Priority 2 Progress:
- Fixed missing return types in test-apps/electron-test/src/index.ts (1 function)
- Fixed non-null assertions in examples/hello-poll.ts (2 assertions)
- Enhanced type safety with proper null checks instead of assertions
- Reduced non-null assertions from 26 to 24

Console statements: 0 remaining (100% complete)
Return types: 9 remaining (down from 62, 85% reduction)
Non-null assertions: 24 remaining (down from 26, 8% reduction)

Linting status:  0 errors, 60 warnings (down from 436 warnings)
Total improvement: 376 warnings fixed (86% reduction)
Priority 2: Excellent progress - approaching completion!

Timestamp: Tue Oct 7 09:52:48 AM UTC 2025
master
Matthew Raymer 4 days ago
parent
commit
40e1fa65ee
  1. 48
      doc/STARRED_PROJECTS_POLLING_IMPLEMENTATION.md
  2. 4
      examples/hello-poll.ts
  3. 2
      test-apps/electron-test/src/index.ts

48
doc/STARRED_PROJECTS_POLLING_IMPLEMENTATION.md

@ -1200,8 +1200,8 @@ async function bootstrapWatermark(activeDid: string, starredPlanHandleIds: strin
`, [mostRecentJwtId, activeDid, mostRecentJwtId]); `, [mostRecentJwtId, activeDid, mostRecentJwtId]);
if (result.changes > 0) { if (result.changes > 0) {
console.log(`Bootstrap watermark set to: ${mostRecentJwtId}`); console.log(`Bootstrap watermark set to: ${mostRecentJwtId}`);
return mostRecentJwtId; return mostRecentJwtId;
} else { } else {
// Another client already set a newer watermark during bootstrap // Another client already set a newer watermark during bootstrap
console.log('Bootstrap skipped: newer watermark already exists'); console.log('Bootstrap skipped: newer watermark already exists');
@ -2493,8 +2493,8 @@ public class GenericPollingManager {
private final Gson gson; private final Gson gson;
public GenericPollingManager(Context context, public GenericPollingManager(Context context,
DailyNotificationJWTManager jwtManager, DailyNotificationJWTManager jwtManager,
DailyNotificationStorage storage) { DailyNotificationStorage storage) {
this.context = context; this.context = context;
this.jwtManager = jwtManager; this.jwtManager = jwtManager;
this.storage = storage; this.storage = storage;
@ -2555,8 +2555,8 @@ public class GenericPollingManager {
scheduleWithWorkManager(scheduleId, config); scheduleWithWorkManager(scheduleId, config);
return scheduleId; return scheduleId;
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "Error scheduling poll: " + e.getMessage(), e); Log.e(TAG, "Error scheduling poll: " + e.getMessage(), e);
throw new RuntimeException("Failed to schedule poll", e); throw new RuntimeException("Failed to schedule poll", e);
} }
@ -2807,8 +2807,8 @@ class GenericPollingManager {
for attempt in 1...maxAttempts { for attempt in 1...maxAttempts {
do { do {
let (data, response) = try await URLSession.shared.data(for: request) let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse else { guard let httpResponse = response as? HTTPURLResponse else {
throw NSError(domain: "GenericPollingManager", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid response type"]) throw NSError(domain: "GenericPollingManager", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid response type"])
} }
@ -3049,17 +3049,17 @@ export class GenericPollingManager {
for (let attempt = 1; attempt <= maxAttempts; attempt++) { for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try { try {
const response = await fetch(url, { const response = await fetch(url, {
method, method,
headers, headers,
body: JSON.stringify(requestBody) body: JSON.stringify(requestBody)
}); });
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`); throw new Error(`HTTP ${response.status}: ${response.statusText}`);
} }
return await response.json(); return await response.json();
} catch (error) { } catch (error) {
lastError = error as Error; lastError = error as Error;
@ -3377,8 +3377,8 @@ if (config.genericPolling != null && config.genericPolling.enabled) {
for (PollingScheduleConfig<?, ?> scheduleConfig : config.genericPolling.schedules) { for (PollingScheduleConfig<?, ?> scheduleConfig : config.genericPolling.schedules) {
CompletableFuture<PollingResult<?>> pollingResult = CompletableFuture<PollingResult<?>> pollingResult =
pollingManager.executePoll(scheduleConfig.request, context); pollingManager.executePoll(scheduleConfig.request, context);
// Process polling results // Process polling results
PollingResult<?> result = pollingResult.get(); PollingResult<?> result = pollingResult.get();
if (result.success && result.data != null) { if (result.success && result.data != null) {
// Generate notifications based on result // Generate notifications based on result
@ -3404,8 +3404,8 @@ if let genericPollingConfig = config.genericPolling, genericPollingConfig.enable
if result.success, let data = result.data { if result.success, let data = result.data {
// Generate notifications based on result // Generate notifications based on result
try await generateNotificationsFromPollingResult(result: result, config: scheduleConfig) try await generateNotificationsFromPollingResult(result: result, config: scheduleConfig)
} }
} catch { } catch {
print("Error executing poll: \(error)") print("Error executing poll: \(error)")
} }
} }
@ -3454,7 +3454,7 @@ const config: ConfigureOptions = {
genericPolling: { genericPolling: {
enabled: true, enabled: true,
schedules: [ schedules: [
// Starred Projects Polling // Starred Projects Polling
{ {
request: starredProjectsRequest, request: starredProjectsRequest,
schedule: { schedule: {
@ -3463,7 +3463,7 @@ const config: ConfigureOptions = {
maxConcurrentPolls: 1 maxConcurrentPolls: 1
}, },
notificationConfig: { notificationConfig: {
enabled: true, enabled: true,
templates: { templates: {
singleUpdate: '{projectName} has been updated', singleUpdate: '{projectName} has been updated',
multipleUpdates: 'You have {count} new updates in your starred projects' multipleUpdates: 'You have {count} new updates in your starred projects'

4
examples/hello-poll.ts

@ -48,7 +48,7 @@ class MockServer {
let filteredData = this.data; let filteredData = this.data;
if (request.afterId) { if (request.afterId) {
filteredData = this.data.filter(item => filteredData = this.data.filter(item =>
item.planSummary.jwtId > request.afterId! item.planSummary.jwtId > (request.afterId || '')
); );
} }
@ -153,7 +153,7 @@ class MockPollingManager {
data: response as TResponse, data: response as TResponse,
error: undefined, error: undefined,
metadata: { metadata: {
requestId: request.idempotencyKey!, requestId: request.idempotencyKey || 'unknown',
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
duration: 100, duration: 100,
retryCount: 0 retryCount: 0

2
test-apps/electron-test/src/index.ts

@ -756,7 +756,7 @@ class TimeSafariElectronTestApp {
// Implementation would process items data and update local state // Implementation would process items data and update local state
} }
private log(message: string, data?: Record<string, unknown>) { private log(message: string, data?: Record<string, unknown>): void {
const timestamp = new Date().toLocaleTimeString(); const timestamp = new Date().toLocaleTimeString();
const logEntry = document.createElement('div'); const logEntry = document.createElement('div');
logEntry.innerHTML = `<span class="timestamp">[${timestamp}]</span> ${message}`; logEntry.innerHTML = `<span class="timestamp">[${timestamp}]</span> ${message}`;

Loading…
Cancel
Save