@candypoets/nipworker 0.96.3 → 0.96.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +206 -73
- package/crates/native-ffi/README.md +14 -151
- package/crates/native-ffi/ios/README.md +4 -50
- package/crates/native-ffi/react-native/README.md +8 -7
- package/crates/native-ffi/react-native/android/build.gradle +1 -0
- package/crates/native-ffi/react-native/android/src/main/cpp/NipworkerByteRuntime.cpp +348 -0
- package/crates/native-ffi/react-native/android/src/main/java/com/candypoets/nipworker/reactnative/NipworkerHooks.kt +292 -0
- package/crates/native-ffi/react-native/android/src/main/java/com/candypoets/nipworker/reactnative/NipworkerReactNativeModule.kt +283 -89
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/AddressPointer.java +75 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleBlock.java +102 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleBlockType.java +23 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleEntity.java +80 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleInline.java +85 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleInlineType.java +24 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/BadgeAwardRecipient.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/BufferFull.java +52 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CacheInput.java +16 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CacheInputMessage.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CacheRequest.java +84 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CacheResponse.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CashuData.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ChatLimiterPipeConfig.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CodeData.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ConnectionStatus.java +68 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Contact.java +70 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ContentBlock.java +70 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ContentData.java +23 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Coordinate.java +75 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CountResponse.java +60 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CounterPipeConfig.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/DLEQProof.java +69 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Emoji.java +62 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/EmojiData.java +68 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Eoce.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/EventPointer.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/GetPublicKey.java +43 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/HTLCWitness.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/HashtagData.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/HistoryTag.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ImageData.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ImetaTag.java +100 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind0Parsed.java +168 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind10002Parsed.java +59 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind10019Parsed.java +73 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1018Parsed.java +79 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1068Parsed.java +107 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1111Parsed.java +159 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1311Parsed.java +91 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind17375Parsed.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind17Parsed.java +81 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1Parsed.java +109 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind20Parsed.java +107 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind22Parsed.java +111 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind30023Parsed.java +113 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind3Parsed.java +59 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind4Parsed.java +78 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind6Parsed.java +53 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind7374Parsed.java +66 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind7375Parsed.java +79 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind7376Parsed.java +100 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind7Parsed.java +81 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind8Parsed.java +78 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind9321Parsed.java +117 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind9735Parsed.java +119 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/KindFilterPipeConfig.java +60 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/LinkPreviewData.java +73 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ListParsed.java +123 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/LiveActivityRef.java +72 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/LiveChatParticipant.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/LiveChatThreadRef.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MainContent.java +20 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MainMessage.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MediaGroupData.java +58 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MediaItem.java +58 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Message.java +24 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MessageType.java +19 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MintInfo.java +65 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MintProofs.java +66 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MuteFilterPipeConfig.java +84 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Nip07.java +43 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Nip46Bunker.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Nip46QR.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/NostrData.java +81 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/NostrEvent.java +95 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/NpubLimiterKey.java +15 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/NpubLimiterPipeConfig.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/P2PKWitness.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ParsePipeConfig.java +43 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ParsedData.java +39 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ParsedDataUnion.java +35 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ParsedEvent.java +108 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Pipe.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PipeConfig.java +23 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PipelineConfig.java +59 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PollOption.java +62 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PollType.java +15 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PreGenericParsed.java +213 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PreParticipant.java +73 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PreRefEvent.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PrivateKey.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ProfilePointer.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Proof.java +90 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ProofVerificationPipeConfig.java +52 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Pubkey.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Publish.java +80 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Raw.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ReactionType.java +17 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/RelayInfo.java +63 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Request.java +134 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SaveToDbPipeConfig.java +43 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SerializeEventsPipeConfig.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SetSigner.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignEvent.java +54 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignedEvent.java +54 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignerOp.java +19 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignerRequest.java +80 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignerResponse.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignerType.java +18 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/StringVec.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Subscribe.java +72 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SubscribeKind.java +19 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SubscriptionConfig.java +95 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Tag.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Template.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Unsubscribe.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ValidProofs.java +59 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/VideoData.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/VideoVariant.java +102 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Witness.java +17 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/WitnessString.java +54 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/WorkerMessage.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ZapRequest.java +83 -0
- package/crates/native-ffi/react-native/ios/NipworkerReactNativeModule.h +18 -0
- package/crates/native-ffi/react-native/ios/NipworkerReactNativeModule.mm +263 -8
- package/dist/EngineManager.d.ts +1 -0
- package/dist/EngineManager.d.ts.map +1 -1
- package/dist/EngineManager.js +143 -137
- package/dist/NostrManager.d.ts +1 -0
- package/dist/NostrManager.d.ts.map +1 -1
- package/dist/NostrManager.js +49 -44
- package/dist/connections/index.js +87 -87
- package/dist/engine/index.js +119 -119
- package/dist/engine.d.ts.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +27 -26
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/legacy.d.ts.map +1 -1
- package/dist/lib/ArrayBufferReader.d.ts +2 -1
- package/dist/lib/ArrayBufferReader.d.ts.map +1 -1
- package/dist/lib/BaseBackend.d.ts +5 -3
- package/dist/lib/BaseBackend.d.ts.map +1 -1
- package/dist/manager.d.ts +2 -6
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +10 -28
- package/dist/react-native.d.ts +33 -4
- package/dist/react-native.d.ts.map +1 -1
- package/dist/react-native.js +400 -122
- package/dist/scheduleMicrotask.js +58 -50
- package/package.json +13 -11
- package/swift/Package.swift +36 -0
- package/swift/README.md +438 -0
- package/swift/Sources/NipworkerSwift/ArrayBufferReader.swift +136 -0
- package/swift/Sources/NipworkerSwift/AuthSession.swift +24 -0
- package/swift/Sources/NipworkerSwift/FFI.swift +94 -0
- package/swift/Sources/NipworkerSwift/FlatBufferHelpers.swift +273 -0
- package/swift/Sources/NipworkerSwift/Generated/message_generated.swift +6530 -0
- package/swift/Sources/NipworkerSwift/Hooks.swift +300 -0
- package/swift/Sources/NipworkerSwift/Models.swift +156 -0
- package/swift/Sources/NipworkerSwift/NostrManager.swift +594 -0
- package/swift/Sources/NipworkerSwift/PublishTracker.swift +40 -0
- package/swift/Sources/NipworkerSwift/Subscription.swift +44 -0
- package/swift/Sources/NipworkerSwift/WorkerMessageView.swift +145 -0
- package/dist/NativeBackend.d.ts +0 -53
- package/dist/NativeBackend.d.ts.map +0 -1
- package/dist/NativeBackend.js +0 -464
- package/dist/native.d.ts +0 -29
- package/dist/native.d.ts.map +0 -1
- package/dist/native.js +0 -273
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public final class NipworkerHookHandle {
|
|
4
|
+
private let onCancel: () -> Void
|
|
5
|
+
private var isCancelled = false
|
|
6
|
+
|
|
7
|
+
public init(_ onCancel: @escaping () -> Void) {
|
|
8
|
+
self.onCancel = onCancel
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public func cancel() {
|
|
12
|
+
guard !isCancelled else { return }
|
|
13
|
+
isCancelled = true
|
|
14
|
+
onCancel()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
deinit {
|
|
18
|
+
cancel()
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// MARK: - Callback-based subscription helpers
|
|
23
|
+
|
|
24
|
+
/// Subscribe through the React Native shared runtime. Returns an unsubscribe function.
|
|
25
|
+
public func useSubscription(
|
|
26
|
+
subscriptionId: String,
|
|
27
|
+
requests: [RequestObject],
|
|
28
|
+
callback: @escaping ([WorkerMessageView]) -> Void,
|
|
29
|
+
options: SubscriptionConfig = SubscriptionConfig()
|
|
30
|
+
) -> () -> Void {
|
|
31
|
+
useSubscription(
|
|
32
|
+
manager: NostrManager.reactNativeShared(),
|
|
33
|
+
subscriptionId: subscriptionId,
|
|
34
|
+
requests: requests,
|
|
35
|
+
callback: callback,
|
|
36
|
+
options: options
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// Subscribe with a callback closure. Returns an unsubscribe function.
|
|
41
|
+
/// Mirrors the JS `useSubscription` hook pattern.
|
|
42
|
+
public func useSubscription(
|
|
43
|
+
manager: NostrManager,
|
|
44
|
+
subscriptionId: String,
|
|
45
|
+
requests: [RequestObject],
|
|
46
|
+
callback: @escaping ([WorkerMessageView]) -> Void,
|
|
47
|
+
options: SubscriptionConfig = SubscriptionConfig()
|
|
48
|
+
) -> () -> Void {
|
|
49
|
+
var notificationToken: NSObjectProtocol?
|
|
50
|
+
var lastReadPosition = 4
|
|
51
|
+
var isActive = true
|
|
52
|
+
let canonicalSubscriptionId = subscriptionId
|
|
53
|
+
|
|
54
|
+
func readAvailableMessages() {
|
|
55
|
+
Task {
|
|
56
|
+
var position = lastReadPosition
|
|
57
|
+
var allMessages: [WorkerMessageView] = []
|
|
58
|
+
|
|
59
|
+
while true {
|
|
60
|
+
let result = await manager.readWorkerMessages(for: canonicalSubscriptionId, from: position)
|
|
61
|
+
if result.messages.isEmpty {
|
|
62
|
+
break
|
|
63
|
+
}
|
|
64
|
+
allMessages.append(contentsOf: result.messages)
|
|
65
|
+
position = result.newPosition
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
lastReadPosition = position
|
|
69
|
+
if isActive, !allMessages.isEmpty {
|
|
70
|
+
callback(allMessages)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
Task {
|
|
76
|
+
notificationToken = NotificationCenter.default.addObserver(
|
|
77
|
+
forName: .nipworkerSubscriptionUpdated(subId: canonicalSubscriptionId),
|
|
78
|
+
object: nil,
|
|
79
|
+
queue: .main
|
|
80
|
+
) { _ in
|
|
81
|
+
guard isActive else { return }
|
|
82
|
+
readAvailableMessages()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
_ = await manager.subscribe(subscriptionId: subscriptionId, requests: requests, options: options)
|
|
86
|
+
readAvailableMessages()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
isActive = false
|
|
91
|
+
if let token = notificationToken {
|
|
92
|
+
NotificationCenter.default.removeObserver(token)
|
|
93
|
+
}
|
|
94
|
+
Task {
|
|
95
|
+
await manager.unsubscribe(subscriptionId: canonicalSubscriptionId)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/// Subscribe through the React Native shared runtime. Returns a cancellable handle.
|
|
101
|
+
public func useSubscriptionHandle(
|
|
102
|
+
subscriptionId: String,
|
|
103
|
+
requests: [RequestObject],
|
|
104
|
+
callback: @escaping ([WorkerMessageView]) -> Void,
|
|
105
|
+
options: SubscriptionConfig = SubscriptionConfig()
|
|
106
|
+
) -> NipworkerHookHandle {
|
|
107
|
+
NipworkerHookHandle(
|
|
108
|
+
useSubscription(
|
|
109
|
+
subscriptionId: subscriptionId,
|
|
110
|
+
requests: requests,
|
|
111
|
+
callback: callback,
|
|
112
|
+
options: options
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// Subscribe with a callback closure. Returns a cancellable handle.
|
|
118
|
+
/// This is the native component-friendly form of the JS `useSubscription` API.
|
|
119
|
+
public func useSubscriptionHandle(
|
|
120
|
+
manager: NostrManager,
|
|
121
|
+
subscriptionId: String,
|
|
122
|
+
requests: [RequestObject],
|
|
123
|
+
callback: @escaping ([WorkerMessageView]) -> Void,
|
|
124
|
+
options: SubscriptionConfig = SubscriptionConfig()
|
|
125
|
+
) -> NipworkerHookHandle {
|
|
126
|
+
NipworkerHookHandle(
|
|
127
|
+
useSubscription(
|
|
128
|
+
manager: manager,
|
|
129
|
+
subscriptionId: subscriptionId,
|
|
130
|
+
requests: requests,
|
|
131
|
+
callback: callback,
|
|
132
|
+
options: options
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/// Publish through the React Native shared runtime. Returns an unsubscribe function.
|
|
138
|
+
public func usePublish(
|
|
139
|
+
publishId: String,
|
|
140
|
+
event: NostrEvent,
|
|
141
|
+
callback: @escaping ([String: PublishStatus]) -> Void,
|
|
142
|
+
defaultRelays: [String] = [],
|
|
143
|
+
optimisticSubIds: [String] = []
|
|
144
|
+
) -> () -> Void {
|
|
145
|
+
usePublish(
|
|
146
|
+
manager: NostrManager.reactNativeShared(),
|
|
147
|
+
publishId: publishId,
|
|
148
|
+
event: event,
|
|
149
|
+
callback: callback,
|
|
150
|
+
defaultRelays: defaultRelays,
|
|
151
|
+
optimisticSubIds: optimisticSubIds
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// Publish with a callback for status updates. Returns an unsubscribe function.
|
|
156
|
+
/// Mirrors the JS `usePublish` hook pattern.
|
|
157
|
+
public func usePublish(
|
|
158
|
+
manager: NostrManager,
|
|
159
|
+
publishId: String,
|
|
160
|
+
event: NostrEvent,
|
|
161
|
+
callback: @escaping ([String: PublishStatus]) -> Void,
|
|
162
|
+
defaultRelays: [String] = [],
|
|
163
|
+
optimisticSubIds: [String] = []
|
|
164
|
+
) -> () -> Void {
|
|
165
|
+
var notificationToken: NSObjectProtocol?
|
|
166
|
+
var lastReadPosition = 4
|
|
167
|
+
var isActive = true
|
|
168
|
+
|
|
169
|
+
Task {
|
|
170
|
+
_ = await manager.publish(
|
|
171
|
+
publishId: publishId,
|
|
172
|
+
event: event,
|
|
173
|
+
defaultRelays: defaultRelays,
|
|
174
|
+
optimisticSubIds: optimisticSubIds
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
notificationToken = NotificationCenter.default.addObserver(
|
|
178
|
+
forName: .nipworkerSubscriptionUpdated(subId: publishId),
|
|
179
|
+
object: nil,
|
|
180
|
+
queue: .main
|
|
181
|
+
) { [weak manager] _ in
|
|
182
|
+
guard isActive,
|
|
183
|
+
let manager = manager else { return }
|
|
184
|
+
|
|
185
|
+
Task {
|
|
186
|
+
var position = lastReadPosition
|
|
187
|
+
var merged: [String: PublishStatus] = [:]
|
|
188
|
+
|
|
189
|
+
while true {
|
|
190
|
+
let result = await manager.readPublishStatuses(for: publishId, from: position)
|
|
191
|
+
if result.statuses.isEmpty {
|
|
192
|
+
break
|
|
193
|
+
}
|
|
194
|
+
for (url, status) in result.statuses {
|
|
195
|
+
merged[url] = status
|
|
196
|
+
}
|
|
197
|
+
position = result.newPosition
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
lastReadPosition = position
|
|
201
|
+
if !merged.isEmpty {
|
|
202
|
+
callback(merged)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
isActive = false
|
|
210
|
+
if let token = notificationToken {
|
|
211
|
+
NotificationCenter.default.removeObserver(token)
|
|
212
|
+
}
|
|
213
|
+
Task {
|
|
214
|
+
await manager.releasePublish(publishId: publishId)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/// Publish through the React Native shared runtime. Returns a cancellable handle.
|
|
220
|
+
public func usePublishHandle(
|
|
221
|
+
publishId: String,
|
|
222
|
+
event: NostrEvent,
|
|
223
|
+
callback: @escaping ([String: PublishStatus]) -> Void,
|
|
224
|
+
defaultRelays: [String] = [],
|
|
225
|
+
optimisticSubIds: [String] = []
|
|
226
|
+
) -> NipworkerHookHandle {
|
|
227
|
+
NipworkerHookHandle(
|
|
228
|
+
usePublish(
|
|
229
|
+
publishId: publishId,
|
|
230
|
+
event: event,
|
|
231
|
+
callback: callback,
|
|
232
|
+
defaultRelays: defaultRelays,
|
|
233
|
+
optimisticSubIds: optimisticSubIds
|
|
234
|
+
)
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/// Publish with a callback for status updates. Returns a cancellable handle.
|
|
239
|
+
/// This is the native component-friendly form of the JS `usePublish` API.
|
|
240
|
+
public func usePublishHandle(
|
|
241
|
+
manager: NostrManager,
|
|
242
|
+
publishId: String,
|
|
243
|
+
event: NostrEvent,
|
|
244
|
+
callback: @escaping ([String: PublishStatus]) -> Void,
|
|
245
|
+
defaultRelays: [String] = [],
|
|
246
|
+
optimisticSubIds: [String] = []
|
|
247
|
+
) -> NipworkerHookHandle {
|
|
248
|
+
NipworkerHookHandle(
|
|
249
|
+
usePublish(
|
|
250
|
+
manager: manager,
|
|
251
|
+
publishId: publishId,
|
|
252
|
+
event: event,
|
|
253
|
+
callback: callback,
|
|
254
|
+
defaultRelays: defaultRelays,
|
|
255
|
+
optimisticSubIds: optimisticSubIds
|
|
256
|
+
)
|
|
257
|
+
)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/// Relay status helper using the React Native shared runtime.
|
|
261
|
+
public func useRelayStatus(
|
|
262
|
+
onStatus: @escaping (String, RelayStatus) -> Void
|
|
263
|
+
) -> () -> Void {
|
|
264
|
+
useRelayStatus(manager: NostrManager.reactNativeShared(), onStatus: onStatus)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/// Relay status helper. Immediately calls handler with current statuses,
|
|
268
|
+
/// then subscribes to updates. Returns a stop function.
|
|
269
|
+
public func useRelayStatus(
|
|
270
|
+
manager: NostrManager,
|
|
271
|
+
onStatus: @escaping (String, RelayStatus) -> Void
|
|
272
|
+
) -> () -> Void {
|
|
273
|
+
var notificationToken: NSObjectProtocol?
|
|
274
|
+
var isActive = true
|
|
275
|
+
|
|
276
|
+
Task {
|
|
277
|
+
let statuses = await manager.getRelayStatuses()
|
|
278
|
+
for (url, status) in statuses {
|
|
279
|
+
onStatus(url, status)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
notificationToken = NotificationCenter.default.addObserver(
|
|
283
|
+
forName: .nipworkerRelayStatusUpdated,
|
|
284
|
+
object: nil,
|
|
285
|
+
queue: .main
|
|
286
|
+
) { notification in
|
|
287
|
+
guard isActive,
|
|
288
|
+
let url = notification.userInfo?["url"] as? String,
|
|
289
|
+
let status = notification.userInfo?["status"] as? RelayStatus else { return }
|
|
290
|
+
onStatus(url, status)
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
isActive = false
|
|
296
|
+
if let token = notificationToken {
|
|
297
|
+
NotificationCenter.default.removeObserver(token)
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public struct RequestObject {
|
|
4
|
+
public var ids: [String]?
|
|
5
|
+
public var authors: [String]?
|
|
6
|
+
public var kinds: [UInt16]?
|
|
7
|
+
public var tags: [String: [String]]?
|
|
8
|
+
public var since: Int?
|
|
9
|
+
public var until: Int?
|
|
10
|
+
public var limit: Int?
|
|
11
|
+
public var search: String?
|
|
12
|
+
public var relays: [String]
|
|
13
|
+
public var closeOnEOSE: Bool?
|
|
14
|
+
public var cacheFirst: Bool?
|
|
15
|
+
public var noCache: Bool?
|
|
16
|
+
public var maxRelays: UInt16?
|
|
17
|
+
|
|
18
|
+
public init(
|
|
19
|
+
ids: [String]? = nil,
|
|
20
|
+
authors: [String]? = nil,
|
|
21
|
+
kinds: [UInt16]? = nil,
|
|
22
|
+
tags: [String: [String]]? = nil,
|
|
23
|
+
since: Int? = nil,
|
|
24
|
+
until: Int? = nil,
|
|
25
|
+
limit: Int? = nil,
|
|
26
|
+
search: String? = nil,
|
|
27
|
+
relays: [String] = [],
|
|
28
|
+
closeOnEOSE: Bool? = nil,
|
|
29
|
+
cacheFirst: Bool? = nil,
|
|
30
|
+
noCache: Bool? = nil,
|
|
31
|
+
maxRelays: UInt16? = nil
|
|
32
|
+
) {
|
|
33
|
+
self.ids = ids
|
|
34
|
+
self.authors = authors
|
|
35
|
+
self.kinds = kinds
|
|
36
|
+
self.tags = tags
|
|
37
|
+
self.since = since
|
|
38
|
+
self.until = until
|
|
39
|
+
self.limit = limit
|
|
40
|
+
self.search = search
|
|
41
|
+
self.relays = relays
|
|
42
|
+
self.closeOnEOSE = closeOnEOSE
|
|
43
|
+
self.cacheFirst = cacheFirst
|
|
44
|
+
self.noCache = noCache
|
|
45
|
+
self.maxRelays = maxRelays
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public struct PipeConfig {
|
|
50
|
+
public enum Kind {
|
|
51
|
+
case muteFilter
|
|
52
|
+
case parse
|
|
53
|
+
case saveToDb
|
|
54
|
+
case serializeEvents(subId: String)
|
|
55
|
+
case kindFilter(kinds: [UInt16])
|
|
56
|
+
case counter(kinds: [UInt16], pubkey: String)
|
|
57
|
+
case npubLimiter(kind: UInt16, limitPerNpub: UInt32, maxTotalNpubs: UInt32)
|
|
58
|
+
case proofVerification(maxProofs: UInt32)
|
|
59
|
+
}
|
|
60
|
+
public var kind: Kind
|
|
61
|
+
public init(_ kind: Kind) { self.kind = kind }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public struct SubscriptionConfig {
|
|
65
|
+
public var pipeline: [PipeConfig]?
|
|
66
|
+
public var closeOnEose: Bool
|
|
67
|
+
public var cacheFirst: Bool
|
|
68
|
+
public var timeoutMs: UInt64?
|
|
69
|
+
public var maxEvents: UInt32?
|
|
70
|
+
public var skipCache: Bool
|
|
71
|
+
public var force: Bool
|
|
72
|
+
public var bytesPerEvent: UInt32
|
|
73
|
+
public var isSlow: Bool
|
|
74
|
+
public var pagination: String?
|
|
75
|
+
public var cacheOnly: Bool
|
|
76
|
+
|
|
77
|
+
public init(
|
|
78
|
+
pipeline: [PipeConfig]? = nil,
|
|
79
|
+
closeOnEose: Bool = false,
|
|
80
|
+
cacheFirst: Bool = true,
|
|
81
|
+
timeoutMs: UInt64? = nil,
|
|
82
|
+
maxEvents: UInt32? = nil,
|
|
83
|
+
skipCache: Bool = false,
|
|
84
|
+
force: Bool = false,
|
|
85
|
+
bytesPerEvent: UInt32 = 3072,
|
|
86
|
+
isSlow: Bool = false,
|
|
87
|
+
pagination: String? = nil,
|
|
88
|
+
cacheOnly: Bool = false
|
|
89
|
+
) {
|
|
90
|
+
self.pipeline = pipeline
|
|
91
|
+
self.closeOnEose = closeOnEose
|
|
92
|
+
self.cacheFirst = cacheFirst
|
|
93
|
+
self.timeoutMs = timeoutMs
|
|
94
|
+
self.maxEvents = maxEvents
|
|
95
|
+
self.skipCache = skipCache
|
|
96
|
+
self.force = force
|
|
97
|
+
self.bytesPerEvent = bytesPerEvent
|
|
98
|
+
self.isSlow = isSlow
|
|
99
|
+
self.pagination = pagination
|
|
100
|
+
self.cacheOnly = cacheOnly
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public struct EventTemplate {
|
|
105
|
+
public var kind: UInt16
|
|
106
|
+
public var content: String
|
|
107
|
+
public var tags: [[String]]
|
|
108
|
+
|
|
109
|
+
public init(kind: UInt16, content: String, tags: [[String]] = []) {
|
|
110
|
+
self.kind = kind
|
|
111
|
+
self.content = content
|
|
112
|
+
self.tags = tags
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public struct NostrEvent: Identifiable, Equatable, Sendable {
|
|
117
|
+
public var id: String
|
|
118
|
+
public var pubkey: String
|
|
119
|
+
public var kind: UInt16
|
|
120
|
+
public var content: String
|
|
121
|
+
public var tags: [[String]]
|
|
122
|
+
public var createdAt: Int
|
|
123
|
+
public var sig: String
|
|
124
|
+
|
|
125
|
+
public init(id: String, pubkey: String, kind: UInt16, content: String, tags: [[String]], createdAt: Int, sig: String) {
|
|
126
|
+
self.id = id
|
|
127
|
+
self.pubkey = pubkey
|
|
128
|
+
self.kind = kind
|
|
129
|
+
self.content = content
|
|
130
|
+
self.tags = tags
|
|
131
|
+
self.createdAt = createdAt
|
|
132
|
+
self.sig = sig
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
public struct NostrManagerConfig {
|
|
137
|
+
public var logLevel: String?
|
|
138
|
+
public init(logLevel: String? = nil) { self.logLevel = logLevel }
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public enum SignerTypeName: Sendable {
|
|
142
|
+
case pubkey(String)
|
|
143
|
+
case privkey(String)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public enum RelayStatus: Equatable, Sendable {
|
|
147
|
+
case connected
|
|
148
|
+
case failed
|
|
149
|
+
case closed(String?)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public enum PublishStatus: Equatable, Sendable {
|
|
153
|
+
case pending
|
|
154
|
+
case success(String)
|
|
155
|
+
case failed(String)
|
|
156
|
+
}
|