react-native-nitro-sse 0.1.0-beta.1 → 0.1.0-beta.3
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/NitroSse.podspec +1 -1
- package/android/src/main/java/com/margelo/nitro/nitrosse/NitroSse.kt +14 -0
- package/ios/NitroSse.swift +32 -7
- package/lib/module/index.js +10 -15
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/NitroSse.nitro.d.ts +14 -0
- package/lib/typescript/src/NitroSse.nitro.d.ts.map +1 -1
- package/lib/typescript/src/SseInterface.d.ts +45 -0
- package/lib/typescript/src/SseInterface.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridNitroSseSpec.cpp +13 -0
- package/nitrogen/generated/android/c++/JHybridNitroSseSpec.hpp +3 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrosse/HybridNitroSseSpec.kt +12 -0
- package/nitrogen/generated/ios/NitroSse-Swift-Cxx-Bridge.hpp +9 -0
- package/nitrogen/generated/ios/c++/HybridNitroSseSpecSwift.hpp +20 -0
- package/nitrogen/generated/ios/swift/HybridNitroSseSpec.swift +3 -0
- package/nitrogen/generated/ios/swift/HybridNitroSseSpec_cxx.swift +34 -0
- package/nitrogen/generated/shared/c++/HybridNitroSseSpec.cpp +3 -0
- package/nitrogen/generated/shared/c++/HybridNitroSseSpec.hpp +3 -0
- package/package.json +1 -1
- package/src/NitroSse.nitro.ts +16 -0
- package/src/SseInterface.ts +45 -0
- package/src/index.tsx +14 -18
package/NitroSse.podspec
CHANGED
|
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
|
|
|
11
11
|
s.authors = package["author"]
|
|
12
12
|
|
|
13
13
|
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
-
s.source = { :git => "https://github.com/
|
|
14
|
+
s.source = { :git => "https://github.com/IAmTester35/react-native-nitro-sse.git", :tag => "#{s.version}" }
|
|
15
15
|
|
|
16
16
|
s.source_files = [
|
|
17
17
|
"ios/**/*.{swift}",
|
|
@@ -266,6 +266,19 @@ class NitroSse : HybridNitroSseSpec() {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
override fun flush() {
|
|
270
|
+
flushBufferToJs()
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
override fun restart() {
|
|
274
|
+
stop()
|
|
275
|
+
start()
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
override fun isConnected(): Boolean {
|
|
279
|
+
return isRunning.get()
|
|
280
|
+
}
|
|
281
|
+
|
|
269
282
|
override fun stop() {
|
|
270
283
|
isRunning.set(false)
|
|
271
284
|
backoffCounter = 0
|
|
@@ -275,5 +288,6 @@ class NitroSse : HybridNitroSseSpec() {
|
|
|
275
288
|
synchronized(eventBuffer) {
|
|
276
289
|
eventBuffer.clear()
|
|
277
290
|
}
|
|
291
|
+
isFlushPending.set(false)
|
|
278
292
|
}
|
|
279
293
|
}
|
package/ios/NitroSse.swift
CHANGED
|
@@ -183,13 +183,38 @@ class NitroSse: HybridNitroSseSpec, EventHandler {
|
|
|
183
183
|
|
|
184
184
|
func stop() {
|
|
185
185
|
sseQueue.async {
|
|
186
|
-
self.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
186
|
+
self.stopInternal()
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private func stopInternal() {
|
|
191
|
+
self.isRunning = false
|
|
192
|
+
self.eventSource?.stop()
|
|
193
|
+
self.eventSource = nil
|
|
194
|
+
self.backoffCounter = 0
|
|
195
|
+
self.eventBuffer.removeAll()
|
|
196
|
+
self.isFlushPending = false
|
|
197
|
+
self.cleanupBackgroundTask()
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
func flush() {
|
|
201
|
+
sseQueue.async {
|
|
202
|
+
self.flushEventsToJs()
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
func restart() {
|
|
207
|
+
sseQueue.async {
|
|
208
|
+
self.stopInternal()
|
|
209
|
+
guard !self.isRunning else { return } // Should be false now
|
|
210
|
+
self.isRunning = true
|
|
211
|
+
self.establishConnection()
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
func isConnected() -> Bool {
|
|
216
|
+
return sseQueue.sync {
|
|
217
|
+
return isRunning
|
|
193
218
|
}
|
|
194
219
|
}
|
|
195
220
|
|
package/lib/module/index.js
CHANGED
|
@@ -3,20 +3,15 @@
|
|
|
3
3
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
4
4
|
export * from "./SseInterface.js";
|
|
5
5
|
export * from "./NitroSse.nitro.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* Public interface to use SSE.
|
|
17
|
-
*/
|
|
18
|
-
if (!realNitroSse || !realNitroSse.setup) {
|
|
19
|
-
throw new Error('NitroSse: Native module not found. Ensure you have linked the library and built the app for iOS/Android.');
|
|
6
|
+
export function createNitroSse() {
|
|
7
|
+
let nativeSse;
|
|
8
|
+
try {
|
|
9
|
+
nativeSse = NitroModules.createHybridObject('NitroSse');
|
|
10
|
+
} catch {}
|
|
11
|
+
if (!nativeSse) {
|
|
12
|
+
console.debug('Native NitroSse not found. This might be a test environment or web.');
|
|
13
|
+
throw new Error('NitroSse: Native module not found. Ensure you have linked the library and built the app for iOS/Android.');
|
|
14
|
+
}
|
|
15
|
+
return nativeSse;
|
|
20
16
|
}
|
|
21
|
-
export const NitroSseModule = realNitroSse;
|
|
22
17
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NitroModules","
|
|
1
|
+
{"version":3,"names":["NitroModules","createNitroSse","nativeSse","createHybridObject","console","debug","Error"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,4BAA4B;AAGzD,cAAc,mBAAgB;AAC9B,cAAc,qBAAkB;AAEhC,OAAO,SAASC,cAAcA,CAAA,EAAa;EACzC,IAAIC,SAA+B;EACnC,IAAI;IACFA,SAAS,GAAGF,YAAY,CAACG,kBAAkB,CAAW,UAAU,CAAC;EACnE,CAAC,CAAC,MAAM,CAAC;EAET,IAAI,CAACD,SAAS,EAAE;IACdE,OAAO,CAACC,KAAK,CACX,qEACF,CAAC;IACD,MAAM,IAAIC,KAAK,CACb,0GACF,CAAC;EACH;EACA,OAAOJ,SAAS;AAClB","ignoreList":[]}
|
|
@@ -30,5 +30,19 @@ export interface NitroSse extends HybridObject<{
|
|
|
30
30
|
* Get connection statistics.
|
|
31
31
|
*/
|
|
32
32
|
getStats(): SseStats;
|
|
33
|
+
/**
|
|
34
|
+
* Manually flush the event buffer.
|
|
35
|
+
* Useful when batching is enabled but you need to process pending events immediately.
|
|
36
|
+
*/
|
|
37
|
+
flush(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Force a reconnection.
|
|
40
|
+
* This resets the connection state and attempts to reconnect immediately.
|
|
41
|
+
*/
|
|
42
|
+
restart(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Check if the connection is currently active.
|
|
45
|
+
*/
|
|
46
|
+
isConnected(): boolean;
|
|
33
47
|
}
|
|
34
48
|
//# sourceMappingURL=NitroSse.nitro.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NitroSse.nitro.d.ts","sourceRoot":"","sources":["../../../src/NitroSse.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEpE,MAAM,WAAW,QACf,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;IACzD;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAEtE;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;;OAGG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAErC;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAErD;;OAEG;IACH,QAAQ,IAAI,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"NitroSse.nitro.d.ts","sourceRoot":"","sources":["../../../src/NitroSse.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEpE,MAAM,WAAW,QACf,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;IACzD;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAEtE;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;;OAGG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAErC;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAErD;;OAEG;IACH,QAAQ,IAAI,QAAQ,CAAC;IACrB;;;OAGG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;;OAGG;IACH,OAAO,IAAI,IAAI,CAAC;IAEhB;;OAEG;IACH,WAAW,IAAI,OAAO,CAAC;CACxB"}
|
|
@@ -1,25 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP method to use for the SSE connection.
|
|
3
|
+
*/
|
|
1
4
|
export type HttpMethod = 'get' | 'post';
|
|
5
|
+
/**
|
|
6
|
+
* Type of event received from the SSE stream.
|
|
7
|
+
* - `open`: Connection established.
|
|
8
|
+
* - `message`: Standard data message.
|
|
9
|
+
* - `error`: Connection error or other failure.
|
|
10
|
+
* - `close`: Connection closed (not typical for SSE, but used for cleanup).
|
|
11
|
+
* - `heartbeat`: Ping/Keep-alive signal.
|
|
12
|
+
*/
|
|
2
13
|
export type SseEventType = 'open' | 'message' | 'error' | 'close' | 'heartbeat';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for the SSE connection.
|
|
16
|
+
*/
|
|
3
17
|
export interface SseConfig {
|
|
18
|
+
/** The URL of the SSE endpoint. */
|
|
4
19
|
url: string;
|
|
20
|
+
/** HTTP method (default: 'GET'). */
|
|
5
21
|
method?: HttpMethod;
|
|
22
|
+
/** Custom HTTP headers to include in the request. */
|
|
6
23
|
headers?: Record<string, string>;
|
|
24
|
+
/** Body for POST requests. */
|
|
7
25
|
body?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Whether to continue processing events when the app is in the background.
|
|
28
|
+
* Note: OS limitations may restrict background execution time.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
8
31
|
backgroundExecution?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Interval in milliseconds to batch events before sending them to JS.
|
|
34
|
+
* Set to 0 to disable batching (real-time mode).
|
|
35
|
+
*/
|
|
9
36
|
batchingIntervalMs?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Maximum number of events to hold in the buffer before forced flushing.
|
|
39
|
+
*/
|
|
10
40
|
maxBufferSize?: number;
|
|
11
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Represents a single SSE event.
|
|
44
|
+
*/
|
|
12
45
|
export interface SseEvent {
|
|
46
|
+
/** The type of the event. */
|
|
13
47
|
type: SseEventType;
|
|
48
|
+
/** The data payload of the event. */
|
|
14
49
|
data?: string;
|
|
50
|
+
/** The event ID, if provided. */
|
|
15
51
|
id?: string;
|
|
52
|
+
/** The event name, if provided (internal 'event' field in SSE). */
|
|
16
53
|
event?: string;
|
|
54
|
+
/** System message or error description. */
|
|
17
55
|
message?: string;
|
|
18
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Statistics about the SSE connection.
|
|
59
|
+
*/
|
|
19
60
|
export interface SseStats {
|
|
61
|
+
/** Total bytes received so far. */
|
|
20
62
|
totalBytesReceived: number;
|
|
63
|
+
/** Number of times the connection has been re-established. */
|
|
21
64
|
reconnectCount: number;
|
|
65
|
+
/** Timestamp of the last error event. */
|
|
22
66
|
lastErrorTime?: number;
|
|
67
|
+
/** Error code of the last error. */
|
|
23
68
|
lastErrorCode?: string;
|
|
24
69
|
}
|
|
25
70
|
//# sourceMappingURL=SseInterface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SseInterface.d.ts","sourceRoot":"","sources":["../../../src/SseInterface.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,CAAC;AAExC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,CAAC;AAEhF,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
|
|
1
|
+
{"version":3,"file":"SseInterface.d.ts","sourceRoot":"","sources":["../../../src/SseInterface.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,mCAAmC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,6BAA6B;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,mCAAmC;IACnC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,cAAc,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AAEjC,wBAAgB,cAAc,IAAI,QAAQ,CAezC"}
|
|
@@ -106,5 +106,18 @@ namespace margelo::nitro::nitrosse {
|
|
|
106
106
|
auto __result = method(_javaPart);
|
|
107
107
|
return __result->toCpp();
|
|
108
108
|
}
|
|
109
|
+
void JHybridNitroSseSpec::flush() {
|
|
110
|
+
static const auto method = javaClassStatic()->getMethod<void()>("flush");
|
|
111
|
+
method(_javaPart);
|
|
112
|
+
}
|
|
113
|
+
void JHybridNitroSseSpec::restart() {
|
|
114
|
+
static const auto method = javaClassStatic()->getMethod<void()>("restart");
|
|
115
|
+
method(_javaPart);
|
|
116
|
+
}
|
|
117
|
+
bool JHybridNitroSseSpec::isConnected() {
|
|
118
|
+
static const auto method = javaClassStatic()->getMethod<jboolean()>("isConnected");
|
|
119
|
+
auto __result = method(_javaPart);
|
|
120
|
+
return static_cast<bool>(__result);
|
|
121
|
+
}
|
|
109
122
|
|
|
110
123
|
} // namespace margelo::nitro::nitrosse
|
|
@@ -61,6 +61,9 @@ namespace margelo::nitro::nitrosse {
|
|
|
61
61
|
void setLastProcessedId(const std::string& id) override;
|
|
62
62
|
void updateHeaders(const std::unordered_map<std::string, std::string>& headers) override;
|
|
63
63
|
SseStats getStats() override;
|
|
64
|
+
void flush() override;
|
|
65
|
+
void restart() override;
|
|
66
|
+
bool isConnected() override;
|
|
64
67
|
|
|
65
68
|
private:
|
|
66
69
|
friend HybridBase;
|
|
@@ -73,6 +73,18 @@ abstract class HybridNitroSseSpec: HybridObject() {
|
|
|
73
73
|
@DoNotStrip
|
|
74
74
|
@Keep
|
|
75
75
|
abstract fun getStats(): SseStats
|
|
76
|
+
|
|
77
|
+
@DoNotStrip
|
|
78
|
+
@Keep
|
|
79
|
+
abstract fun flush(): Unit
|
|
80
|
+
|
|
81
|
+
@DoNotStrip
|
|
82
|
+
@Keep
|
|
83
|
+
abstract fun restart(): Unit
|
|
84
|
+
|
|
85
|
+
@DoNotStrip
|
|
86
|
+
@Keep
|
|
87
|
+
abstract fun isConnected(): Boolean
|
|
76
88
|
|
|
77
89
|
private external fun initHybrid(): HybridData
|
|
78
90
|
|
|
@@ -206,5 +206,14 @@ namespace margelo::nitro::nitrosse::bridge::swift {
|
|
|
206
206
|
inline Result_SseStats_ create_Result_SseStats_(const std::exception_ptr& error) noexcept {
|
|
207
207
|
return Result<SseStats>::withError(error);
|
|
208
208
|
}
|
|
209
|
+
|
|
210
|
+
// pragma MARK: Result<bool>
|
|
211
|
+
using Result_bool_ = Result<bool>;
|
|
212
|
+
inline Result_bool_ create_Result_bool_(bool value) noexcept {
|
|
213
|
+
return Result<bool>::withValue(std::move(value));
|
|
214
|
+
}
|
|
215
|
+
inline Result_bool_ create_Result_bool_(const std::exception_ptr& error) noexcept {
|
|
216
|
+
return Result<bool>::withError(error);
|
|
217
|
+
}
|
|
209
218
|
|
|
210
219
|
} // namespace margelo::nitro::nitrosse::bridge::swift
|
|
@@ -122,6 +122,26 @@ namespace margelo::nitro::nitrosse {
|
|
|
122
122
|
auto __value = std::move(__result.value());
|
|
123
123
|
return __value;
|
|
124
124
|
}
|
|
125
|
+
inline void flush() override {
|
|
126
|
+
auto __result = _swiftPart.flush();
|
|
127
|
+
if (__result.hasError()) [[unlikely]] {
|
|
128
|
+
std::rethrow_exception(__result.error());
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
inline void restart() override {
|
|
132
|
+
auto __result = _swiftPart.restart();
|
|
133
|
+
if (__result.hasError()) [[unlikely]] {
|
|
134
|
+
std::rethrow_exception(__result.error());
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
inline bool isConnected() override {
|
|
138
|
+
auto __result = _swiftPart.isConnected();
|
|
139
|
+
if (__result.hasError()) [[unlikely]] {
|
|
140
|
+
std::rethrow_exception(__result.error());
|
|
141
|
+
}
|
|
142
|
+
auto __value = std::move(__result.value());
|
|
143
|
+
return __value;
|
|
144
|
+
}
|
|
125
145
|
|
|
126
146
|
private:
|
|
127
147
|
NitroSse::HybridNitroSseSpec_cxx _swiftPart;
|
|
@@ -19,6 +19,9 @@ public protocol HybridNitroSseSpec_protocol: HybridObject {
|
|
|
19
19
|
func setLastProcessedId(id: String) throws -> Void
|
|
20
20
|
func updateHeaders(headers: Dictionary<String, String>) throws -> Void
|
|
21
21
|
func getStats() throws -> SseStats
|
|
22
|
+
func flush() throws -> Void
|
|
23
|
+
func restart() throws -> Void
|
|
24
|
+
func isConnected() throws -> Bool
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
public extension HybridNitroSseSpec_protocol {
|
|
@@ -209,4 +209,38 @@ open class HybridNitroSseSpec_cxx {
|
|
|
209
209
|
return bridge.create_Result_SseStats_(__exceptionPtr)
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
|
+
|
|
213
|
+
@inline(__always)
|
|
214
|
+
public final func flush() -> bridge.Result_void_ {
|
|
215
|
+
do {
|
|
216
|
+
try self.__implementation.flush()
|
|
217
|
+
return bridge.create_Result_void_()
|
|
218
|
+
} catch (let __error) {
|
|
219
|
+
let __exceptionPtr = __error.toCpp()
|
|
220
|
+
return bridge.create_Result_void_(__exceptionPtr)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@inline(__always)
|
|
225
|
+
public final func restart() -> bridge.Result_void_ {
|
|
226
|
+
do {
|
|
227
|
+
try self.__implementation.restart()
|
|
228
|
+
return bridge.create_Result_void_()
|
|
229
|
+
} catch (let __error) {
|
|
230
|
+
let __exceptionPtr = __error.toCpp()
|
|
231
|
+
return bridge.create_Result_void_(__exceptionPtr)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@inline(__always)
|
|
236
|
+
public final func isConnected() -> bridge.Result_bool_ {
|
|
237
|
+
do {
|
|
238
|
+
let __result = try self.__implementation.isConnected()
|
|
239
|
+
let __resultCpp = __result
|
|
240
|
+
return bridge.create_Result_bool_(__resultCpp)
|
|
241
|
+
} catch (let __error) {
|
|
242
|
+
let __exceptionPtr = __error.toCpp()
|
|
243
|
+
return bridge.create_Result_bool_(__exceptionPtr)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
212
246
|
}
|
|
@@ -20,6 +20,9 @@ namespace margelo::nitro::nitrosse {
|
|
|
20
20
|
prototype.registerHybridMethod("setLastProcessedId", &HybridNitroSseSpec::setLastProcessedId);
|
|
21
21
|
prototype.registerHybridMethod("updateHeaders", &HybridNitroSseSpec::updateHeaders);
|
|
22
22
|
prototype.registerHybridMethod("getStats", &HybridNitroSseSpec::getStats);
|
|
23
|
+
prototype.registerHybridMethod("flush", &HybridNitroSseSpec::flush);
|
|
24
|
+
prototype.registerHybridMethod("restart", &HybridNitroSseSpec::restart);
|
|
25
|
+
prototype.registerHybridMethod("isConnected", &HybridNitroSseSpec::isConnected);
|
|
23
26
|
});
|
|
24
27
|
}
|
|
25
28
|
|
|
@@ -65,6 +65,9 @@ namespace margelo::nitro::nitrosse {
|
|
|
65
65
|
virtual void setLastProcessedId(const std::string& id) = 0;
|
|
66
66
|
virtual void updateHeaders(const std::unordered_map<std::string, std::string>& headers) = 0;
|
|
67
67
|
virtual SseStats getStats() = 0;
|
|
68
|
+
virtual void flush() = 0;
|
|
69
|
+
virtual void restart() = 0;
|
|
70
|
+
virtual bool isConnected() = 0;
|
|
68
71
|
|
|
69
72
|
protected:
|
|
70
73
|
// Hybrid Setup
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-sse",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.3",
|
|
4
4
|
"description": "High-performance Server-Sent Events (SSE) for React Native, powered by Nitro Modules.",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
package/src/NitroSse.nitro.ts
CHANGED
|
@@ -34,4 +34,20 @@ export interface NitroSse
|
|
|
34
34
|
* Get connection statistics.
|
|
35
35
|
*/
|
|
36
36
|
getStats(): SseStats;
|
|
37
|
+
/**
|
|
38
|
+
* Manually flush the event buffer.
|
|
39
|
+
* Useful when batching is enabled but you need to process pending events immediately.
|
|
40
|
+
*/
|
|
41
|
+
flush(): void;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Force a reconnection.
|
|
45
|
+
* This resets the connection state and attempts to reconnect immediately.
|
|
46
|
+
*/
|
|
47
|
+
restart(): void;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Check if the connection is currently active.
|
|
51
|
+
*/
|
|
52
|
+
isConnected(): boolean;
|
|
37
53
|
}
|
package/src/SseInterface.ts
CHANGED
|
@@ -1,28 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP method to use for the SSE connection.
|
|
3
|
+
*/
|
|
1
4
|
export type HttpMethod = 'get' | 'post';
|
|
2
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Type of event received from the SSE stream.
|
|
8
|
+
* - `open`: Connection established.
|
|
9
|
+
* - `message`: Standard data message.
|
|
10
|
+
* - `error`: Connection error or other failure.
|
|
11
|
+
* - `close`: Connection closed (not typical for SSE, but used for cleanup).
|
|
12
|
+
* - `heartbeat`: Ping/Keep-alive signal.
|
|
13
|
+
*/
|
|
3
14
|
export type SseEventType = 'open' | 'message' | 'error' | 'close' | 'heartbeat';
|
|
4
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Configuration for the SSE connection.
|
|
18
|
+
*/
|
|
5
19
|
export interface SseConfig {
|
|
20
|
+
/** The URL of the SSE endpoint. */
|
|
6
21
|
url: string;
|
|
22
|
+
/** HTTP method (default: 'GET'). */
|
|
7
23
|
method?: HttpMethod;
|
|
24
|
+
/** Custom HTTP headers to include in the request. */
|
|
8
25
|
headers?: Record<string, string>;
|
|
26
|
+
/** Body for POST requests. */
|
|
9
27
|
body?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Whether to continue processing events when the app is in the background.
|
|
30
|
+
* Note: OS limitations may restrict background execution time.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
10
33
|
backgroundExecution?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Interval in milliseconds to batch events before sending them to JS.
|
|
36
|
+
* Set to 0 to disable batching (real-time mode).
|
|
37
|
+
*/
|
|
11
38
|
batchingIntervalMs?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Maximum number of events to hold in the buffer before forced flushing.
|
|
41
|
+
*/
|
|
12
42
|
maxBufferSize?: number;
|
|
13
43
|
}
|
|
14
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Represents a single SSE event.
|
|
47
|
+
*/
|
|
15
48
|
export interface SseEvent {
|
|
49
|
+
/** The type of the event. */
|
|
16
50
|
type: SseEventType;
|
|
51
|
+
/** The data payload of the event. */
|
|
17
52
|
data?: string;
|
|
53
|
+
/** The event ID, if provided. */
|
|
18
54
|
id?: string;
|
|
55
|
+
/** The event name, if provided (internal 'event' field in SSE). */
|
|
19
56
|
event?: string;
|
|
57
|
+
/** System message or error description. */
|
|
20
58
|
message?: string;
|
|
21
59
|
}
|
|
22
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Statistics about the SSE connection.
|
|
63
|
+
*/
|
|
23
64
|
export interface SseStats {
|
|
65
|
+
/** Total bytes received so far. */
|
|
24
66
|
totalBytesReceived: number;
|
|
67
|
+
/** Number of times the connection has been re-established. */
|
|
25
68
|
reconnectCount: number;
|
|
69
|
+
/** Timestamp of the last error event. */
|
|
26
70
|
lastErrorTime?: number;
|
|
71
|
+
/** Error code of the last error. */
|
|
27
72
|
lastErrorCode?: string;
|
|
28
73
|
}
|
package/src/index.tsx
CHANGED
|
@@ -4,23 +4,19 @@ import type { NitroSse } from './NitroSse.nitro';
|
|
|
4
4
|
export * from './SseInterface';
|
|
5
5
|
export * from './NitroSse.nitro';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
let
|
|
9
|
-
try {
|
|
10
|
-
|
|
11
|
-
} catch {
|
|
12
|
-
console.debug(
|
|
13
|
-
'Native NitroSse not found. This might be a test environment or web.'
|
|
14
|
-
);
|
|
15
|
-
}
|
|
7
|
+
export function createNitroSse(): NitroSse {
|
|
8
|
+
let nativeSse: NitroSse | undefined;
|
|
9
|
+
try {
|
|
10
|
+
nativeSse = NitroModules.createHybridObject<NitroSse>('NitroSse');
|
|
11
|
+
} catch {}
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
if (!nativeSse) {
|
|
14
|
+
console.debug(
|
|
15
|
+
'Native NitroSse not found. This might be a test environment or web.'
|
|
16
|
+
);
|
|
17
|
+
throw new Error(
|
|
18
|
+
'NitroSse: Native module not found. Ensure you have linked the library and built the app for iOS/Android.'
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return nativeSse;
|
|
24
22
|
}
|
|
25
|
-
|
|
26
|
-
export const NitroSseModule: NitroSse = realNitroSse;
|