@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
|
@@ -8,9 +8,18 @@
|
|
|
8
8
|
#include <vector>
|
|
9
9
|
|
|
10
10
|
extern "C" void nipworker_handle_message(void* handle, const uint8_t* ptr, size_t len);
|
|
11
|
+
extern "C" bool nipworker_subscribe_message(void* handle, const uint8_t* ptr, size_t len);
|
|
12
|
+
extern "C" bool nipworker_publish_message(void* handle, const uint8_t* ptr, size_t len);
|
|
11
13
|
extern "C" void nipworker_set_private_key(void* handle, const char* ptr);
|
|
12
14
|
extern "C" void nipworker_wake(void* handle);
|
|
13
15
|
extern "C" void nipworker_deinit(void* handle);
|
|
16
|
+
extern "C" bool nipworker_register_subscription(void* handle, const char* sub_id, size_t buffer_size);
|
|
17
|
+
extern "C" bool nipworker_register_publish_buffer(void* handle, const char* publish_id, size_t buffer_size);
|
|
18
|
+
extern "C" bool nipworker_retain_subscription(void* handle, const char* sub_id);
|
|
19
|
+
extern "C" void nipworker_release_subscription(void* handle, const char* sub_id);
|
|
20
|
+
extern "C" uint8_t* nipworker_subscription_buffer_ptr(void* handle, const char* sub_id);
|
|
21
|
+
extern "C" size_t nipworker_subscription_buffer_len(void* handle, const char* sub_id);
|
|
22
|
+
extern "C" void nipworker_cleanup_subscriptions(void* handle);
|
|
14
23
|
|
|
15
24
|
namespace {
|
|
16
25
|
using facebook::jsi::Array;
|
|
@@ -39,6 +48,23 @@ private:
|
|
|
39
48
|
std::vector<uint8_t> bytes_;
|
|
40
49
|
};
|
|
41
50
|
|
|
51
|
+
class ExternalMutableBuffer final : public MutableBuffer {
|
|
52
|
+
public:
|
|
53
|
+
ExternalMutableBuffer(uint8_t* ptr, size_t len) : ptr_(ptr), len_(len) {}
|
|
54
|
+
|
|
55
|
+
size_t size() const override {
|
|
56
|
+
return len_;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
uint8_t* data() override {
|
|
60
|
+
return ptr_;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private:
|
|
64
|
+
uint8_t* ptr_;
|
|
65
|
+
size_t len_;
|
|
66
|
+
};
|
|
67
|
+
|
|
42
68
|
std::mutex gQueueMutex;
|
|
43
69
|
std::vector<std::vector<uint8_t>> gQueuedPackets;
|
|
44
70
|
bool gInstalled = false;
|
|
@@ -78,6 +104,153 @@ Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativeQueue
|
|
|
78
104
|
return JNI_TRUE;
|
|
79
105
|
}
|
|
80
106
|
|
|
107
|
+
extern "C" JNIEXPORT jobject JNICALL
|
|
108
|
+
Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativeSubscribeMessage(
|
|
109
|
+
JNIEnv* env,
|
|
110
|
+
jclass,
|
|
111
|
+
jlong handle,
|
|
112
|
+
jbyteArray bytes,
|
|
113
|
+
jstring subId
|
|
114
|
+
) {
|
|
115
|
+
if (handle == 0 || bytes == nullptr || subId == nullptr) return nullptr;
|
|
116
|
+
jsize len = env->GetArrayLength(bytes);
|
|
117
|
+
jbyte* ptr = env->GetByteArrayElements(bytes, nullptr);
|
|
118
|
+
if (ptr == nullptr) return nullptr;
|
|
119
|
+
auto* engineHandle = reinterpret_cast<void*>(handle);
|
|
120
|
+
bool ok = nipworker_subscribe_message(
|
|
121
|
+
engineHandle,
|
|
122
|
+
reinterpret_cast<const uint8_t*>(ptr),
|
|
123
|
+
static_cast<size_t>(len)
|
|
124
|
+
);
|
|
125
|
+
env->ReleaseByteArrayElements(bytes, ptr, JNI_ABORT);
|
|
126
|
+
if (!ok) return nullptr;
|
|
127
|
+
|
|
128
|
+
const char* subIdChars = env->GetStringUTFChars(subId, nullptr);
|
|
129
|
+
if (subIdChars == nullptr) return nullptr;
|
|
130
|
+
uint8_t* bufferPtr = nipworker_subscription_buffer_ptr(engineHandle, subIdChars);
|
|
131
|
+
size_t bufferLen = nipworker_subscription_buffer_len(engineHandle, subIdChars);
|
|
132
|
+
env->ReleaseStringUTFChars(subId, subIdChars);
|
|
133
|
+
if (bufferPtr == nullptr || bufferLen == 0) return nullptr;
|
|
134
|
+
return env->NewDirectByteBuffer(bufferPtr, static_cast<jlong>(bufferLen));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
extern "C" JNIEXPORT jobject JNICALL
|
|
138
|
+
Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativePublishMessage(
|
|
139
|
+
JNIEnv* env,
|
|
140
|
+
jclass,
|
|
141
|
+
jlong handle,
|
|
142
|
+
jbyteArray bytes,
|
|
143
|
+
jstring publishId
|
|
144
|
+
) {
|
|
145
|
+
if (handle == 0 || bytes == nullptr || publishId == nullptr) return nullptr;
|
|
146
|
+
jsize len = env->GetArrayLength(bytes);
|
|
147
|
+
jbyte* ptr = env->GetByteArrayElements(bytes, nullptr);
|
|
148
|
+
if (ptr == nullptr) return nullptr;
|
|
149
|
+
auto* engineHandle = reinterpret_cast<void*>(handle);
|
|
150
|
+
bool ok = nipworker_publish_message(
|
|
151
|
+
engineHandle,
|
|
152
|
+
reinterpret_cast<const uint8_t*>(ptr),
|
|
153
|
+
static_cast<size_t>(len)
|
|
154
|
+
);
|
|
155
|
+
env->ReleaseByteArrayElements(bytes, ptr, JNI_ABORT);
|
|
156
|
+
if (!ok) return nullptr;
|
|
157
|
+
|
|
158
|
+
const char* publishIdChars = env->GetStringUTFChars(publishId, nullptr);
|
|
159
|
+
if (publishIdChars == nullptr) return nullptr;
|
|
160
|
+
uint8_t* bufferPtr = nipworker_subscription_buffer_ptr(engineHandle, publishIdChars);
|
|
161
|
+
size_t bufferLen = nipworker_subscription_buffer_len(engineHandle, publishIdChars);
|
|
162
|
+
env->ReleaseStringUTFChars(publishId, publishIdChars);
|
|
163
|
+
if (bufferPtr == nullptr || bufferLen == 0) return nullptr;
|
|
164
|
+
return env->NewDirectByteBuffer(bufferPtr, static_cast<jlong>(bufferLen));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
extern "C" JNIEXPORT jboolean JNICALL
|
|
168
|
+
Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativeRegisterSubscription(
|
|
169
|
+
JNIEnv* env,
|
|
170
|
+
jclass,
|
|
171
|
+
jlong handle,
|
|
172
|
+
jstring subId,
|
|
173
|
+
jint bufferSize
|
|
174
|
+
) {
|
|
175
|
+
if (handle == 0 || subId == nullptr || bufferSize <= 0) return JNI_FALSE;
|
|
176
|
+
const char* subIdChars = env->GetStringUTFChars(subId, nullptr);
|
|
177
|
+
if (subIdChars == nullptr) return JNI_FALSE;
|
|
178
|
+
bool ok = nipworker_register_subscription(
|
|
179
|
+
reinterpret_cast<void*>(handle),
|
|
180
|
+
subIdChars,
|
|
181
|
+
static_cast<size_t>(bufferSize)
|
|
182
|
+
);
|
|
183
|
+
env->ReleaseStringUTFChars(subId, subIdChars);
|
|
184
|
+
return ok ? JNI_TRUE : JNI_FALSE;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
extern "C" JNIEXPORT jboolean JNICALL
|
|
188
|
+
Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativeRegisterPublishBuffer(
|
|
189
|
+
JNIEnv* env,
|
|
190
|
+
jclass,
|
|
191
|
+
jlong handle,
|
|
192
|
+
jstring publishId,
|
|
193
|
+
jint bufferSize
|
|
194
|
+
) {
|
|
195
|
+
if (handle == 0 || publishId == nullptr || bufferSize <= 0) return JNI_FALSE;
|
|
196
|
+
const char* publishIdChars = env->GetStringUTFChars(publishId, nullptr);
|
|
197
|
+
if (publishIdChars == nullptr) return JNI_FALSE;
|
|
198
|
+
bool ok = nipworker_register_publish_buffer(
|
|
199
|
+
reinterpret_cast<void*>(handle),
|
|
200
|
+
publishIdChars,
|
|
201
|
+
static_cast<size_t>(bufferSize)
|
|
202
|
+
);
|
|
203
|
+
env->ReleaseStringUTFChars(publishId, publishIdChars);
|
|
204
|
+
return ok ? JNI_TRUE : JNI_FALSE;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
extern "C" JNIEXPORT jboolean JNICALL
|
|
208
|
+
Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativeRetainSubscription(
|
|
209
|
+
JNIEnv* env,
|
|
210
|
+
jclass,
|
|
211
|
+
jlong handle,
|
|
212
|
+
jstring subId
|
|
213
|
+
) {
|
|
214
|
+
if (handle == 0 || subId == nullptr) return JNI_FALSE;
|
|
215
|
+
const char* subIdChars = env->GetStringUTFChars(subId, nullptr);
|
|
216
|
+
if (subIdChars == nullptr) return JNI_FALSE;
|
|
217
|
+
bool ok = nipworker_retain_subscription(reinterpret_cast<void*>(handle), subIdChars);
|
|
218
|
+
env->ReleaseStringUTFChars(subId, subIdChars);
|
|
219
|
+
return ok ? JNI_TRUE : JNI_FALSE;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
extern "C" JNIEXPORT void JNICALL
|
|
223
|
+
Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativeReleaseSubscription(
|
|
224
|
+
JNIEnv* env,
|
|
225
|
+
jclass,
|
|
226
|
+
jlong handle,
|
|
227
|
+
jstring subId
|
|
228
|
+
) {
|
|
229
|
+
if (handle == 0 || subId == nullptr) return;
|
|
230
|
+
const char* subIdChars = env->GetStringUTFChars(subId, nullptr);
|
|
231
|
+
if (subIdChars == nullptr) return;
|
|
232
|
+
nipworker_release_subscription(reinterpret_cast<void*>(handle), subIdChars);
|
|
233
|
+
env->ReleaseStringUTFChars(subId, subIdChars);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
extern "C" JNIEXPORT jobject JNICALL
|
|
237
|
+
Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativeGetSubscriptionBuffer(
|
|
238
|
+
JNIEnv* env,
|
|
239
|
+
jclass,
|
|
240
|
+
jlong handle,
|
|
241
|
+
jstring subId
|
|
242
|
+
) {
|
|
243
|
+
if (handle == 0 || subId == nullptr) return nullptr;
|
|
244
|
+
const char* subIdChars = env->GetStringUTFChars(subId, nullptr);
|
|
245
|
+
if (subIdChars == nullptr) return nullptr;
|
|
246
|
+
auto* engineHandle = reinterpret_cast<void*>(handle);
|
|
247
|
+
uint8_t* ptr = nipworker_subscription_buffer_ptr(engineHandle, subIdChars);
|
|
248
|
+
size_t len = nipworker_subscription_buffer_len(engineHandle, subIdChars);
|
|
249
|
+
env->ReleaseStringUTFChars(subId, subIdChars);
|
|
250
|
+
if (ptr == nullptr || len == 0) return nullptr;
|
|
251
|
+
return env->NewDirectByteBuffer(ptr, static_cast<jlong>(len));
|
|
252
|
+
}
|
|
253
|
+
|
|
81
254
|
extern "C" JNIEXPORT jboolean JNICALL
|
|
82
255
|
Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativeIsByteRuntimeInstalled(
|
|
83
256
|
JNIEnv*,
|
|
@@ -158,6 +331,181 @@ Java_com_candypoets_nipworker_reactnative_NipworkerReactNativeModule_nativeInsta
|
|
|
158
331
|
)
|
|
159
332
|
);
|
|
160
333
|
|
|
334
|
+
byteRuntime.setProperty(
|
|
335
|
+
runtime,
|
|
336
|
+
"registerSubscription",
|
|
337
|
+
Function::createFromHostFunction(
|
|
338
|
+
runtime,
|
|
339
|
+
PropNameID::forAscii(runtime, "registerSubscription"),
|
|
340
|
+
2,
|
|
341
|
+
[engineHandle](Runtime& runtime, const Value&, const Value* args, size_t count) -> Value {
|
|
342
|
+
if (count < 2 || !args[0].isString() || !args[1].isNumber()) return Value(false);
|
|
343
|
+
std::string subId = args[0].asString(runtime).utf8(runtime);
|
|
344
|
+
auto bufferSize = static_cast<size_t>(args[1].asNumber());
|
|
345
|
+
return Value(nipworker_register_subscription(engineHandle, subId.c_str(), bufferSize));
|
|
346
|
+
}
|
|
347
|
+
)
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
byteRuntime.setProperty(
|
|
351
|
+
runtime,
|
|
352
|
+
"subscribe",
|
|
353
|
+
Function::createFromHostFunction(
|
|
354
|
+
runtime,
|
|
355
|
+
PropNameID::forAscii(runtime, "subscribe"),
|
|
356
|
+
2,
|
|
357
|
+
[engineHandle](Runtime& runtime, const Value&, const Value* args, size_t count) -> Value {
|
|
358
|
+
if (count < 2 || !isArrayBuffer(runtime, args[0]) || !args[1].isString()) {
|
|
359
|
+
return Value::undefined();
|
|
360
|
+
}
|
|
361
|
+
ArrayBuffer message = args[0].asObject(runtime).getArrayBuffer(runtime);
|
|
362
|
+
std::string subId = args[1].asString(runtime).utf8(runtime);
|
|
363
|
+
if (!nipworker_subscribe_message(engineHandle, message.data(runtime), message.size(runtime))) {
|
|
364
|
+
return Value::undefined();
|
|
365
|
+
}
|
|
366
|
+
uint8_t* ptr = nipworker_subscription_buffer_ptr(engineHandle, subId.c_str());
|
|
367
|
+
size_t len = nipworker_subscription_buffer_len(engineHandle, subId.c_str());
|
|
368
|
+
if (ptr == nullptr || len == 0) return Value::undefined();
|
|
369
|
+
auto nativeBuffer = std::make_shared<ExternalMutableBuffer>(ptr, len);
|
|
370
|
+
ArrayBuffer buffer(runtime, std::move(nativeBuffer));
|
|
371
|
+
return Value(runtime, std::move(buffer));
|
|
372
|
+
}
|
|
373
|
+
)
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
byteRuntime.setProperty(
|
|
377
|
+
runtime,
|
|
378
|
+
"registerPublishBuffer",
|
|
379
|
+
Function::createFromHostFunction(
|
|
380
|
+
runtime,
|
|
381
|
+
PropNameID::forAscii(runtime, "registerPublishBuffer"),
|
|
382
|
+
2,
|
|
383
|
+
[engineHandle](Runtime& runtime, const Value&, const Value* args, size_t count) -> Value {
|
|
384
|
+
if (count < 2 || !args[0].isString() || !args[1].isNumber()) return Value(false);
|
|
385
|
+
std::string publishId = args[0].asString(runtime).utf8(runtime);
|
|
386
|
+
auto bufferSize = static_cast<size_t>(args[1].asNumber());
|
|
387
|
+
return Value(nipworker_register_publish_buffer(engineHandle, publishId.c_str(), bufferSize));
|
|
388
|
+
}
|
|
389
|
+
)
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
byteRuntime.setProperty(
|
|
393
|
+
runtime,
|
|
394
|
+
"publish",
|
|
395
|
+
Function::createFromHostFunction(
|
|
396
|
+
runtime,
|
|
397
|
+
PropNameID::forAscii(runtime, "publish"),
|
|
398
|
+
2,
|
|
399
|
+
[engineHandle](Runtime& runtime, const Value&, const Value* args, size_t count) -> Value {
|
|
400
|
+
if (count < 2 || !isArrayBuffer(runtime, args[0]) || !args[1].isString()) {
|
|
401
|
+
return Value::undefined();
|
|
402
|
+
}
|
|
403
|
+
ArrayBuffer message = args[0].asObject(runtime).getArrayBuffer(runtime);
|
|
404
|
+
std::string publishId = args[1].asString(runtime).utf8(runtime);
|
|
405
|
+
if (!nipworker_publish_message(engineHandle, message.data(runtime), message.size(runtime))) {
|
|
406
|
+
return Value::undefined();
|
|
407
|
+
}
|
|
408
|
+
uint8_t* ptr = nipworker_subscription_buffer_ptr(engineHandle, publishId.c_str());
|
|
409
|
+
size_t len = nipworker_subscription_buffer_len(engineHandle, publishId.c_str());
|
|
410
|
+
if (ptr == nullptr || len == 0) return Value::undefined();
|
|
411
|
+
auto nativeBuffer = std::make_shared<ExternalMutableBuffer>(ptr, len);
|
|
412
|
+
ArrayBuffer buffer(runtime, std::move(nativeBuffer));
|
|
413
|
+
return Value(runtime, std::move(buffer));
|
|
414
|
+
}
|
|
415
|
+
)
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
byteRuntime.setProperty(
|
|
419
|
+
runtime,
|
|
420
|
+
"retainSubscription",
|
|
421
|
+
Function::createFromHostFunction(
|
|
422
|
+
runtime,
|
|
423
|
+
PropNameID::forAscii(runtime, "retainSubscription"),
|
|
424
|
+
1,
|
|
425
|
+
[engineHandle](Runtime& runtime, const Value&, const Value* args, size_t count) -> Value {
|
|
426
|
+
if (count < 1 || !args[0].isString()) return Value(false);
|
|
427
|
+
std::string subId = args[0].asString(runtime).utf8(runtime);
|
|
428
|
+
return Value(nipworker_retain_subscription(engineHandle, subId.c_str()));
|
|
429
|
+
}
|
|
430
|
+
)
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
byteRuntime.setProperty(
|
|
434
|
+
runtime,
|
|
435
|
+
"retainSubscriptionBuffer",
|
|
436
|
+
Function::createFromHostFunction(
|
|
437
|
+
runtime,
|
|
438
|
+
PropNameID::forAscii(runtime, "retainSubscriptionBuffer"),
|
|
439
|
+
1,
|
|
440
|
+
[engineHandle](Runtime& runtime, const Value&, const Value* args, size_t count) -> Value {
|
|
441
|
+
if (count < 1 || !args[0].isString()) return Value::undefined();
|
|
442
|
+
std::string subId = args[0].asString(runtime).utf8(runtime);
|
|
443
|
+
if (!nipworker_retain_subscription(engineHandle, subId.c_str())) {
|
|
444
|
+
return Value::undefined();
|
|
445
|
+
}
|
|
446
|
+
uint8_t* ptr = nipworker_subscription_buffer_ptr(engineHandle, subId.c_str());
|
|
447
|
+
size_t len = nipworker_subscription_buffer_len(engineHandle, subId.c_str());
|
|
448
|
+
if (ptr == nullptr || len == 0) {
|
|
449
|
+
nipworker_release_subscription(engineHandle, subId.c_str());
|
|
450
|
+
return Value::undefined();
|
|
451
|
+
}
|
|
452
|
+
auto nativeBuffer = std::make_shared<ExternalMutableBuffer>(ptr, len);
|
|
453
|
+
ArrayBuffer buffer(runtime, std::move(nativeBuffer));
|
|
454
|
+
return Value(runtime, std::move(buffer));
|
|
455
|
+
}
|
|
456
|
+
)
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
byteRuntime.setProperty(
|
|
460
|
+
runtime,
|
|
461
|
+
"releaseSubscription",
|
|
462
|
+
Function::createFromHostFunction(
|
|
463
|
+
runtime,
|
|
464
|
+
PropNameID::forAscii(runtime, "releaseSubscription"),
|
|
465
|
+
1,
|
|
466
|
+
[engineHandle](Runtime& runtime, const Value&, const Value* args, size_t count) -> Value {
|
|
467
|
+
if (count < 1 || !args[0].isString()) return Value::undefined();
|
|
468
|
+
std::string subId = args[0].asString(runtime).utf8(runtime);
|
|
469
|
+
nipworker_release_subscription(engineHandle, subId.c_str());
|
|
470
|
+
return Value::undefined();
|
|
471
|
+
}
|
|
472
|
+
)
|
|
473
|
+
);
|
|
474
|
+
|
|
475
|
+
byteRuntime.setProperty(
|
|
476
|
+
runtime,
|
|
477
|
+
"getSubscriptionBuffer",
|
|
478
|
+
Function::createFromHostFunction(
|
|
479
|
+
runtime,
|
|
480
|
+
PropNameID::forAscii(runtime, "getSubscriptionBuffer"),
|
|
481
|
+
1,
|
|
482
|
+
[engineHandle](Runtime& runtime, const Value&, const Value* args, size_t count) -> Value {
|
|
483
|
+
if (count < 1 || !args[0].isString()) return Value::undefined();
|
|
484
|
+
std::string subId = args[0].asString(runtime).utf8(runtime);
|
|
485
|
+
uint8_t* ptr = nipworker_subscription_buffer_ptr(engineHandle, subId.c_str());
|
|
486
|
+
size_t len = nipworker_subscription_buffer_len(engineHandle, subId.c_str());
|
|
487
|
+
if (ptr == nullptr || len == 0) return Value::undefined();
|
|
488
|
+
auto nativeBuffer = std::make_shared<ExternalMutableBuffer>(ptr, len);
|
|
489
|
+
ArrayBuffer buffer(runtime, std::move(nativeBuffer));
|
|
490
|
+
return Value(runtime, std::move(buffer));
|
|
491
|
+
}
|
|
492
|
+
)
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
byteRuntime.setProperty(
|
|
496
|
+
runtime,
|
|
497
|
+
"cleanupSubscriptions",
|
|
498
|
+
Function::createFromHostFunction(
|
|
499
|
+
runtime,
|
|
500
|
+
PropNameID::forAscii(runtime, "cleanupSubscriptions"),
|
|
501
|
+
0,
|
|
502
|
+
[engineHandle](Runtime&, const Value&, const Value*, size_t) -> Value {
|
|
503
|
+
nipworker_cleanup_subscriptions(engineHandle);
|
|
504
|
+
return Value::undefined();
|
|
505
|
+
}
|
|
506
|
+
)
|
|
507
|
+
);
|
|
508
|
+
|
|
161
509
|
byteRuntime.setProperty(
|
|
162
510
|
runtime,
|
|
163
511
|
"deinit",
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
package com.candypoets.nipworker.reactnative
|
|
2
|
+
|
|
3
|
+
import com.google.flatbuffers.FlatBufferBuilder
|
|
4
|
+
import java.io.Closeable
|
|
5
|
+
import java.nio.ByteBuffer
|
|
6
|
+
import java.nio.ByteOrder
|
|
7
|
+
import nostr.fb.MainContent
|
|
8
|
+
import nostr.fb.MainMessage
|
|
9
|
+
import nostr.fb.MessageType
|
|
10
|
+
import nostr.fb.MuteFilterPipeConfig
|
|
11
|
+
import nostr.fb.ParsePipeConfig
|
|
12
|
+
import nostr.fb.Pipe
|
|
13
|
+
import nostr.fb.PipeConfig
|
|
14
|
+
import nostr.fb.PipelineConfig
|
|
15
|
+
import nostr.fb.Publish
|
|
16
|
+
import nostr.fb.Request
|
|
17
|
+
import nostr.fb.SaveToDbPipeConfig
|
|
18
|
+
import nostr.fb.SerializeEventsPipeConfig
|
|
19
|
+
import nostr.fb.StringVec
|
|
20
|
+
import nostr.fb.Subscribe
|
|
21
|
+
import nostr.fb.SubscriptionConfig
|
|
22
|
+
import nostr.fb.Template
|
|
23
|
+
import nostr.fb.WorkerMessage
|
|
24
|
+
|
|
25
|
+
data class NipworkerRequest(
|
|
26
|
+
val ids: List<String> = emptyList(),
|
|
27
|
+
val authors: List<String> = emptyList(),
|
|
28
|
+
val kinds: List<Int> = emptyList(),
|
|
29
|
+
val tags: Map<String, List<String>> = emptyMap(),
|
|
30
|
+
val since: Int = 0,
|
|
31
|
+
val until: Int = 0,
|
|
32
|
+
val limit: Int = 0,
|
|
33
|
+
val search: String? = null,
|
|
34
|
+
val relays: List<String> = emptyList(),
|
|
35
|
+
val closeOnEose: Boolean = false,
|
|
36
|
+
val cacheFirst: Boolean = true,
|
|
37
|
+
val noCache: Boolean = false,
|
|
38
|
+
val maxRelays: Int = 0,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
data class NipworkerSubscriptionOptions(
|
|
42
|
+
val closeOnEose: Boolean = false,
|
|
43
|
+
val cacheFirst: Boolean = true,
|
|
44
|
+
val timeoutMs: Long = 0,
|
|
45
|
+
val maxEvents: Long = 0,
|
|
46
|
+
val skipCache: Boolean = false,
|
|
47
|
+
val force: Boolean = false,
|
|
48
|
+
val bytesPerEvent: Long = 3072,
|
|
49
|
+
val isSlow: Boolean = false,
|
|
50
|
+
val pagination: String? = null,
|
|
51
|
+
val cacheOnly: Boolean = false,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
data class NipworkerEventTemplate(
|
|
55
|
+
val kind: Int,
|
|
56
|
+
val content: String,
|
|
57
|
+
val tags: List<List<String>> = emptyList(),
|
|
58
|
+
val createdAt: Int = 0,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
class NipworkerWorkerMessage(private val bytes: ByteArray) {
|
|
62
|
+
private val buffer: ByteBuffer =
|
|
63
|
+
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN)
|
|
64
|
+
|
|
65
|
+
val message: WorkerMessage = WorkerMessage.getRootAsWorkerMessage(buffer)
|
|
66
|
+
val subId: String? get() = message.subId()
|
|
67
|
+
val url: String? get() = message.url()
|
|
68
|
+
val type: Long get() = message.type()
|
|
69
|
+
val contentType: Byte get() = message.contentType()
|
|
70
|
+
|
|
71
|
+
fun bytes(): ByteArray = bytes
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
class NipworkerHookHandle internal constructor(private val cancelAction: () -> Unit) : Closeable {
|
|
75
|
+
@Volatile
|
|
76
|
+
private var closed = false
|
|
77
|
+
|
|
78
|
+
override fun close() {
|
|
79
|
+
if (!closed) {
|
|
80
|
+
closed = true
|
|
81
|
+
cancelAction()
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
fun cancel() = close()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
fun NipworkerRuntime.useSubscription(
|
|
89
|
+
subscriptionId: String,
|
|
90
|
+
requests: List<NipworkerRequest>,
|
|
91
|
+
options: NipworkerSubscriptionOptions = NipworkerSubscriptionOptions(),
|
|
92
|
+
onMessages: (List<NipworkerWorkerMessage>) -> Unit,
|
|
93
|
+
): NipworkerHookHandle {
|
|
94
|
+
val buffer = retainSubscriptionBuffer(subscriptionId)
|
|
95
|
+
?: subscribe(buildSubscribeMessage(subscriptionId, requests, options), subscriptionId)
|
|
96
|
+
var lastReadPosition = 4
|
|
97
|
+
|
|
98
|
+
fun drain() {
|
|
99
|
+
val messages = buffer?.readWorkerMessages(lastReadPosition).orEmpty()
|
|
100
|
+
if (messages.isNotEmpty()) {
|
|
101
|
+
lastReadPosition += messages.sumOf { it.bytes().size + 4 }
|
|
102
|
+
onMessages(messages)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
val listener = addListener(subscriptionId) {
|
|
107
|
+
drain()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
drain()
|
|
111
|
+
|
|
112
|
+
return NipworkerHookHandle {
|
|
113
|
+
listener()
|
|
114
|
+
releaseSubscription(subscriptionId)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
fun NipworkerRuntime.usePublish(
|
|
119
|
+
publishId: String,
|
|
120
|
+
event: NipworkerEventTemplate,
|
|
121
|
+
defaultRelays: List<String> = emptyList(),
|
|
122
|
+
optimisticSubIds: List<String> = emptyList(),
|
|
123
|
+
onStatus: (NipworkerWorkerMessage) -> Unit,
|
|
124
|
+
): NipworkerHookHandle {
|
|
125
|
+
val buffer = publish(buildPublishMessage(publishId, event, defaultRelays, optimisticSubIds), publishId)
|
|
126
|
+
var lastReadPosition = 4
|
|
127
|
+
|
|
128
|
+
fun drain() {
|
|
129
|
+
val messages = buffer?.readWorkerMessages(lastReadPosition).orEmpty()
|
|
130
|
+
if (messages.isNotEmpty()) {
|
|
131
|
+
lastReadPosition += messages.sumOf { it.bytes().size + 4 }
|
|
132
|
+
messages
|
|
133
|
+
.filter { it.type != MessageType.ParsedNostrEvent }
|
|
134
|
+
.forEach(onStatus)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
val listener = addListener(publishId) {
|
|
139
|
+
drain()
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
drain()
|
|
143
|
+
|
|
144
|
+
return NipworkerHookHandle {
|
|
145
|
+
listener()
|
|
146
|
+
releaseSubscription(publishId)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private fun ByteBuffer.readWorkerMessages(fromPosition: Int): List<NipworkerWorkerMessage> {
|
|
151
|
+
val source = duplicate().order(ByteOrder.LITTLE_ENDIAN)
|
|
152
|
+
if (source.capacity() < 4) return emptyList()
|
|
153
|
+
val writePosition = source.getInt(0).coerceAtMost(source.capacity())
|
|
154
|
+
var position = fromPosition
|
|
155
|
+
val messages = mutableListOf<NipworkerWorkerMessage>()
|
|
156
|
+
while (position + 4 <= writePosition) {
|
|
157
|
+
val messageLength = source.getInt(position)
|
|
158
|
+
if (messageLength <= 0 || position + 4 + messageLength > writePosition) break
|
|
159
|
+
val bytes = ByteArray(messageLength)
|
|
160
|
+
source.position(position + 4)
|
|
161
|
+
source.get(bytes)
|
|
162
|
+
messages.add(NipworkerWorkerMessage(bytes))
|
|
163
|
+
position += 4 + messageLength
|
|
164
|
+
}
|
|
165
|
+
return messages
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
private fun buildSubscribeMessage(
|
|
169
|
+
subId: String,
|
|
170
|
+
requests: List<NipworkerRequest>,
|
|
171
|
+
options: NipworkerSubscriptionOptions,
|
|
172
|
+
): ByteArray {
|
|
173
|
+
val builder = FlatBufferBuilder(2048)
|
|
174
|
+
val requestOffsets = requests.map { request -> buildRequest(builder, request, options) }.toIntArray()
|
|
175
|
+
val requestsOffset = Subscribe.createRequestsVector(builder, requestOffsets)
|
|
176
|
+
val pipelineOffset = buildDefaultPipeline(builder, subId)
|
|
177
|
+
val paginationOffset = options.pagination?.let { builder.createString(it) } ?: 0
|
|
178
|
+
val configOffset = SubscriptionConfig.createSubscriptionConfig(
|
|
179
|
+
builder,
|
|
180
|
+
pipelineOffset,
|
|
181
|
+
options.closeOnEose,
|
|
182
|
+
options.cacheFirst,
|
|
183
|
+
options.timeoutMs,
|
|
184
|
+
options.maxEvents,
|
|
185
|
+
options.skipCache,
|
|
186
|
+
options.force,
|
|
187
|
+
options.bytesPerEvent,
|
|
188
|
+
options.isSlow,
|
|
189
|
+
paginationOffset,
|
|
190
|
+
options.cacheOnly,
|
|
191
|
+
)
|
|
192
|
+
val subscribeOffset = Subscribe.createSubscribe(
|
|
193
|
+
builder,
|
|
194
|
+
builder.createString(subId),
|
|
195
|
+
requestsOffset,
|
|
196
|
+
configOffset,
|
|
197
|
+
)
|
|
198
|
+
val root = MainMessage.createMainMessage(builder, MainContent.Subscribe, subscribeOffset)
|
|
199
|
+
builder.finish(root)
|
|
200
|
+
return builder.sizedByteArray()
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private fun buildRequest(
|
|
204
|
+
builder: FlatBufferBuilder,
|
|
205
|
+
request: NipworkerRequest,
|
|
206
|
+
options: NipworkerSubscriptionOptions,
|
|
207
|
+
): Int {
|
|
208
|
+
val idsOffset = stringVector(builder, request.ids)
|
|
209
|
+
val authorsOffset = stringVector(builder, request.authors)
|
|
210
|
+
val kindsOffset = if (request.kinds.isEmpty()) 0 else Request.createKindsVector(builder, request.kinds.toIntArray())
|
|
211
|
+
val tagOffsets = request.tags.map { (key, values) ->
|
|
212
|
+
StringVec.createStringVec(builder, stringVector(builder, listOf(key) + values))
|
|
213
|
+
}.toIntArray()
|
|
214
|
+
val tagsOffset = if (tagOffsets.isEmpty()) 0 else Request.createTagsVector(builder, tagOffsets)
|
|
215
|
+
val searchOffset = request.search?.let { builder.createString(it) } ?: 0
|
|
216
|
+
val relaysOffset = stringVector(builder, request.relays)
|
|
217
|
+
return Request.createRequest(
|
|
218
|
+
builder,
|
|
219
|
+
idsOffset,
|
|
220
|
+
authorsOffset,
|
|
221
|
+
kindsOffset,
|
|
222
|
+
tagsOffset,
|
|
223
|
+
request.limit,
|
|
224
|
+
request.since,
|
|
225
|
+
request.until,
|
|
226
|
+
searchOffset,
|
|
227
|
+
relaysOffset,
|
|
228
|
+
request.closeOnEose,
|
|
229
|
+
request.cacheFirst,
|
|
230
|
+
request.noCache,
|
|
231
|
+
request.maxRelays,
|
|
232
|
+
options.cacheOnly,
|
|
233
|
+
)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private fun buildDefaultPipeline(builder: FlatBufferBuilder, subId: String): Int {
|
|
237
|
+
val muteStart = MuteFilterPipeConfig.startMuteFilterPipeConfig(builder)
|
|
238
|
+
val muteConfig = MuteFilterPipeConfig.endMuteFilterPipeConfig(builder)
|
|
239
|
+
val mutePipe = Pipe.createPipe(builder, PipeConfig.MuteFilterPipeConfig, muteConfig)
|
|
240
|
+
|
|
241
|
+
val parseStart = ParsePipeConfig.startParsePipeConfig(builder)
|
|
242
|
+
val parseConfig = ParsePipeConfig.endParsePipeConfig(builder)
|
|
243
|
+
val parsePipe = Pipe.createPipe(builder, PipeConfig.ParsePipeConfig, parseConfig)
|
|
244
|
+
|
|
245
|
+
val saveStart = SaveToDbPipeConfig.startSaveToDbPipeConfig(builder)
|
|
246
|
+
val saveConfig = SaveToDbPipeConfig.endSaveToDbPipeConfig(builder)
|
|
247
|
+
val savePipe = Pipe.createPipe(builder, PipeConfig.SaveToDbPipeConfig, saveConfig)
|
|
248
|
+
|
|
249
|
+
val serializeConfig = SerializeEventsPipeConfig.createSerializeEventsPipeConfig(builder, builder.createString(subId))
|
|
250
|
+
val serializePipe = Pipe.createPipe(builder, PipeConfig.SerializeEventsPipeConfig, serializeConfig)
|
|
251
|
+
|
|
252
|
+
return PipelineConfig.createPipelineConfig(
|
|
253
|
+
builder,
|
|
254
|
+
PipelineConfig.createPipesVector(builder, intArrayOf(mutePipe, parsePipe, savePipe, serializePipe)),
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private fun buildPublishMessage(
|
|
259
|
+
publishId: String,
|
|
260
|
+
event: NipworkerEventTemplate,
|
|
261
|
+
defaultRelays: List<String>,
|
|
262
|
+
optimisticSubIds: List<String>,
|
|
263
|
+
): ByteArray {
|
|
264
|
+
val builder = FlatBufferBuilder(1024)
|
|
265
|
+
val tags = event.tags.map { tag ->
|
|
266
|
+
StringVec.createStringVec(builder, stringVector(builder, tag))
|
|
267
|
+
}.toIntArray()
|
|
268
|
+
val tagsOffset = Template.createTagsVector(builder, tags)
|
|
269
|
+
val templateOffset = Template.createTemplate(
|
|
270
|
+
builder,
|
|
271
|
+
event.kind,
|
|
272
|
+
event.createdAt,
|
|
273
|
+
builder.createString(event.content),
|
|
274
|
+
tagsOffset,
|
|
275
|
+
)
|
|
276
|
+
val publishOffset = Publish.createPublish(
|
|
277
|
+
builder,
|
|
278
|
+
builder.createString(publishId),
|
|
279
|
+
templateOffset,
|
|
280
|
+
stringVector(builder, defaultRelays),
|
|
281
|
+
stringVector(builder, optimisticSubIds),
|
|
282
|
+
)
|
|
283
|
+
val root = MainMessage.createMainMessage(builder, MainContent.Publish, publishOffset)
|
|
284
|
+
builder.finish(root)
|
|
285
|
+
return builder.sizedByteArray()
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private fun stringVector(builder: FlatBufferBuilder, values: List<String>): Int {
|
|
289
|
+
if (values.isEmpty()) return 0
|
|
290
|
+
val offsets = values.map { builder.createString(it) }.toIntArray()
|
|
291
|
+
return builder.createVectorOfTables(offsets)
|
|
292
|
+
}
|