@@ -428,7 +428,7 @@ export function useNostrSync(options = {}) {
428428 * Initialize the Nostr sync service
429429 */
430430 const initialize = useCallback ( async ( ) => {
431- if ( nostrSyncService ?. isInitialized ) {
431+ if ( nostrSyncService ?. isInitialized && bookmarkSubscriptionRef . current ) {
432432 updateStatus ( )
433433 return
434434 }
@@ -865,13 +865,18 @@ export function useNostrSync(options = {}) {
865865 }
866866 } , [ autoInitialize , initialize ] )
867867
868- // Subscribe to service changes
868+ // Subscribe to service changes - also trigger initialization after pairing
869869 useEffect ( ( ) => {
870- const unsubscribe = subscribeToNostrSync ( ( ) => {
870+ const unsubscribe = subscribeToNostrSync ( ( service ) => {
871871 updateStatus ( )
872+ // When service becomes initialized (e.g., after pairing calls initializeNostrSync),
873+ // trigger full hook initialization to set up subscriptions and observers
874+ if ( service ?. isInitialized && ! bookmarkSubscriptionRef . current ) {
875+ initialize ( )
876+ }
872877 } )
873878 return unsubscribe
874- } , [ updateStatus ] )
879+ } , [ updateStatus , initialize ] )
875880
876881 // Compute error message for display
877882 const errorRelayUrls = Object . keys ( relayErrors )
@@ -917,6 +922,50 @@ export function useNostrSync(options = {}) {
917922 }
918923}
919924
925+ /**
926+ * Publish all existing bookmarks in the Yjs document to Nostr relays.
927+ *
928+ * Called after initial pairing so the responder device can pull bookmarks
929+ * from Nostr relays even if WebRTC sync fails (e.g., iOS Safari).
930+ *
931+ * @returns {Promise<number> } Number of bookmarks queued for publishing
932+ */
933+ export async function publishAllExistingBookmarks ( ) {
934+ if ( ! nostrSyncService ?. isInitialized ) {
935+ console . warn ( '[useNostrSync] Cannot publish bookmarks - service not initialized' )
936+ return 0
937+ }
938+
939+ const ydoc = getYdocInstance ( )
940+ if ( ! ydoc ) return 0
941+
942+ const bookmarksMap = ydoc . getMap ( 'bookmarks' )
943+ let count = 0
944+
945+ bookmarksMap . forEach ( ( bookmark , id ) => {
946+ const bookmarkData = bookmark . get ? {
947+ url : bookmark . get ( 'url' ) ,
948+ title : bookmark . get ( 'title' ) ,
949+ description : bookmark . get ( 'description' ) || '' ,
950+ tags : bookmark . get ( 'tags' ) ?. toArray ?. ( ) || [ ] ,
951+ readLater : bookmark . get ( 'readLater' ) || false ,
952+ inbox : bookmark . get ( 'inbox' ) || false ,
953+ favicon : bookmark . get ( 'favicon' ) || null ,
954+ preview : bookmark . get ( 'preview' ) || null ,
955+ createdAt : bookmark . get ( 'createdAt' ) ,
956+ updatedAt : bookmark . get ( 'updatedAt' ) ,
957+ } : { ...bookmark }
958+
959+ if ( bookmarkData . url && bookmarkData . title ) {
960+ nostrSyncService . queueBookmarkUpdate ( id , bookmarkData )
961+ count ++
962+ }
963+ } )
964+
965+ console . log ( `[useNostrSync] Queued ${ count } existing bookmarks for Nostr publishing` )
966+ return count
967+ }
968+
920969// Re-export performance utilities for external use
921970export {
922971 PERFORMANCE_CONFIG ,
0 commit comments