Skip to content

Add nostr event provider#220

Merged
joshr4 merged 14 commits intomainfrom
add-nostr-provider
Jan 29, 2025
Merged

Add nostr event provider#220
joshr4 merged 14 commits intomainfrom
add-nostr-provider

Conversation

@joshr4
Copy link
Collaborator

@joshr4 joshr4 commented Jan 28, 2025

Description by Korbit AI

What change is being made?

Add a NostrEventProvider to the application to manage Nostr events globally, refactor components to utilize the new provider for event data, and update caching strategies for improved performance and integration.

Why are these changes being made?

This change improves the scalability and maintainability of the codebase by centralizing Nostr event logic, reducing redundant API calls through caching, and streamlining the integration process of Nostr events across the application. By leveraging context and the NostrEventProvider, various components can now seamlessly access event data, leading to better data consistency and performance optimization. Furthermore, this refactor supports future expansions in functionality and provides a clearer structure for managing event types within the app.

Is this description stale? Ask me to generate a new description by commenting /korbit-generate-pr-description

@joshr4
Copy link
Collaborator Author

joshr4 commented Jan 28, 2025

/korbit-review

Copy link

@korbit-ai korbit-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review by Korbit AI

Korbit automatically attempts to detect when you fix issues in new commits.
Category Issue Fix Detected
Functionality Unused subscription management ▹ view
Functionality Non-functional followsActivity feature ▹ view
Functionality Incorrect useEffect syntax and missing error handling ▹ view
Performance Missing Cache Duration Configuration ▹ view
Functionality Broken Unread Messages Notification ▹ view
Performance Inefficient Array Spread in Render Cycle ▹ view
Functionality Missing return value for unsupported event kinds ▹ view

Need a new review? Comment /korbit-review on this PR and I'll review your latest changes.

Korbit Guide: Usage and Customization

Interacting with Korbit

  • You can manually ask Korbit to review your PR using the /korbit-review command in a comment at the root of your PR.
  • You can ask Korbit to generate a new PR description using the /korbit-generate-pr-description command in any comment on your PR.
  • Too many Korbit comments? I can resolve all my comment threads if you use the /korbit-resolve command in any comment on your PR.
  • Chat with Korbit on issues we post by tagging @korbit-ai in your reply.
  • Help train Korbit to improve your reviews by giving a 👍 or 👎 on the comments Korbit posts.

Customizing Korbit

  • Check out our docs on how you can make Korbit work best for you and your team.
  • Customize Korbit for your organization through the Korbit Console.

Feedback and Support

@joshr4
Copy link
Collaborator Author

joshr4 commented Jan 29, 2025

/korbit-review

Copy link

@korbit-ai korbit-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review by Korbit AI

Korbit automatically attempts to detect when you fix issues in new commits.
Category Issue Fix Detected
Error Handling Silent Error Swallowing ▹ view
Error Handling Silent JSON Parse Error in Profile Metadata ▹ view
Error Handling Missing AsyncStorage Error Handling ▹ view
Functionality Inflexible Timestamp Setting ▹ view
Performance Unbounded Persisted Query Storage ▹ view
Functionality Unsafe Async Event Processing ▹ view

Need a new review? Comment /korbit-review on this PR and I'll review your latest changes.

Korbit Guide: Usage and Customization

Interacting with Korbit

  • You can manually ask Korbit to review your PR using the /korbit-review command in a comment at the root of your PR.
  • You can ask Korbit to generate a new PR description using the /korbit-generate-pr-description command in any comment on your PR.
  • Too many Korbit comments? I can resolve all my comment threads if you use the /korbit-resolve command in any comment on your PR.
  • Chat with Korbit on issues we post by tagging @korbit-ai in your reply.
  • Help train Korbit to improve your reviews by giving a 👍 or 👎 on the comments Korbit posts.

Customizing Korbit

  • Check out our docs on how you can make Korbit work best for you and your team.
  • Customize Korbit for your organization through the Korbit Console.

Feedback and Support

utils/cache.ts Outdated
Comment on lines +163 to +168
try {
const stored = await AsyncStorage.getItem(LAST_FETCH_PREFIX + queryKey);
return stored ? parseInt(stored, 10) : 0;
} catch {
return 0;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silent Error Swallowing category Error Handling

Tell me more
What is the issue?

Empty catch block silently swallows errors from AsyncStorage.getItem() without logging or providing context about the failure.

Why this matters

Silent error handling makes it difficult to diagnose issues when AsyncStorage operations fail unexpectedly in production.

Suggested change ∙ Feature Preview

Add error logging to provide context:

try {
    const stored = await AsyncStorage.getItem(LAST_FETCH_PREFIX + queryKey);
    return stored ? parseInt(stored, 10) : 0;
  } catch (error) {
    console.error(`Failed to get last fetch time for ${queryKey}:`, error);
    return 0;
  }

💡 Does this comment miss the mark? Tell us why and Korbit will adapt to your team’s feedback.
💬 Chat with Korbit by mentioning @korbit-ai.

Comment on lines +201 to +250
setTimeout(() => {
const kind1: string[] = [];
const kind6: string[] = [];
const kind7: string[] = [];
const kind16: string[] = [];
const kind9735: string[] = [];

socialEvents.forEach((event) => {
queryClient.setQueryData(nostrQueryKeys.event(event.id), event);

switch (event.kind) {
case 1:
kind1.push(event.id);
break;
case 6:
kind6.push(event.id);
break;
case 7:
kind7.push(event.id);
break;
case 16:
kind16.push(event.id);
break;
case 9735:
kind9735.push(event.id);
break;
}
});
// Update queries in batches
queryClient.setQueryData<string[]>(
nostrQueryKeys.comments(pubkey),
(old) => [...kind1, ...(old ?? [])],
);
queryClient.setQueryData<string[]>(
nostrQueryKeys.reposts(pubkey),
(old) => [...kind6, ...(old ?? [])],
);
queryClient.setQueryData<string[]>(
nostrQueryKeys.reactions(pubkey),
(old) => [...kind7, ...(old ?? [])],
);
queryClient.setQueryData<string[]>(
nostrQueryKeys.genericReposts(pubkey),
(old) => [...kind16, ...(old ?? [])],
);
queryClient.setQueryData<string[]>(
nostrQueryKeys.zapReceipts(pubkey),
(old) => [...kind9735, ...(old ?? [])],
);
}, 0);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsafe Async Event Processing category Functionality

Tell me more
What is the issue?

The setTimeout with 0ms delay is used to process and update event data, which could lead to race conditions and inconsistent state updates.

Why this matters

Processing events asynchronously without proper coordination can result in missed updates or inconsistent data state when multiple events are being processed simultaneously.

Suggested change ∙ Feature Preview

Replace the setTimeout with a more reliable synchronous processing approach:

const processEvents = () => {
  const kind1: string[] = [];
  const kind6: string[] = [];
  const kind7: string[] = [];
  const kind16: string[] = [];
  const kind9735: string[] = [];

  socialEvents.forEach((event) => {
    queryClient.setQueryData(nostrQueryKeys.event(event.id), event);
    
    switch (event.kind) {
      case 1: kind1.push(event.id); break;
      case 6: kind6.push(event.id); break;
      case 7: kind7.push(event.id); break;
      case 16: kind16.push(event.id); break;
      case 9735: kind9735.push(event.id); break;
    }
  });

  // Batch update queries
  queryClient.setQueriesData({
    queries: [
      { queryKey: nostrQueryKeys.comments(pubkey), updater: (old: string[] = []) => [...kind1, ...old] },
      { queryKey: nostrQueryKeys.reposts(pubkey), updater: (old: string[] = []) => [...kind6, ...old] },
      { queryKey: nostrQueryKeys.reactions(pubkey), updater: (old: string[] = []) => [...kind7, ...old] },
      { queryKey: nostrQueryKeys.genericReposts(pubkey), updater: (old: string[] = []) => [...kind16, ...old] },
      { queryKey: nostrQueryKeys.zapReceipts(pubkey), updater: (old: string[] = []) => [...kind9735, ...old] }
    ]
  });
};

processEvents();

💡 Does this comment miss the mark? Tell us why and Korbit will adapt to your team’s feedback.
💬 Chat with Korbit by mentioning @korbit-ai.

Comment on lines +171 to +174
export const setLastFetchTime = async (queryKey: string): Promise<void> => {
const now = Math.floor(Date.now() / 1000); // Unix timestamp in seconds
await AsyncStorage.setItem(LAST_FETCH_PREFIX + queryKey, now.toString());
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inflexible Timestamp Setting category Functionality

Tell me more
What is the issue?

The setLastFetchTime function is called with just a queryKey parameter but doesn't allow setting a custom timestamp, which could lead to race conditions in certain scenarios.

Why this matters

If multiple operations need to be synchronized or if we need to record a specific event's timestamp, the current implementation forces the use of the current time, potentially creating inconsistencies in the event timeline.

Suggested change ∙ Feature Preview

Modify the function to accept an optional timestamp parameter:

export const setLastFetchTime = async (
  queryKey: string,
  timestamp?: number
): Promise<void> => {
  const now = timestamp ?? Math.floor(Date.now() / 1000);
  await AsyncStorage.setItem(LAST_FETCH_PREFIX + queryKey, now.toString());
};

💡 Does this comment miss the mark? Tell us why and Korbit will adapt to your team’s feedback.
💬 Chat with Korbit by mentioning @korbit-ai.

Comment on lines +367 to +369
} catch {
return null;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silent JSON Parse Error in Profile Metadata category Error Handling

Tell me more
What is the issue?

The decodeProfileMetadata function catches JSON parse errors silently without logging or providing context about the failure.

Why this matters

Silently returning null on parse errors makes debugging profile metadata issues difficult and could mask underlying data corruption problems.

Suggested change ∙ Feature Preview

Add error logging and context to the catch block:

catch (error) {
  console.error(`Failed to parse profile metadata: ${error.message}`, { eventId: event.id });
  return null;
}

💡 Does this comment miss the mark? Tell us why and Korbit will adapt to your team’s feedback.
💬 Chat with Korbit by mentioning @korbit-ai.

persistOptions={{
persister: asyncStoragePersister,
maxAge: TWENTY_FOUR_HOURS,
maxAge: Infinity,

This comment was marked as resolved.

@joshr4 joshr4 merged commit 4f8d305 into main Jan 29, 2025
@joshr4 joshr4 deleted the add-nostr-provider branch January 29, 2025 00:43
@korbit-ai korbit-ai bot mentioned this pull request Feb 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant