@logbrew/react-native 0.1.10 → 0.1.11
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 +68 -1
- package/android/src/main/java/co/logbrew/reactnative/EventRecordStore.java +611 -0
- package/android/src/main/java/co/logbrew/reactnative/FatalStoreModuleImpl.java +129 -0
- package/android/src/newarch/java/co/logbrew/reactnative/FatalStoreModule.java +26 -0
- package/android/src/oldarch/java/co/logbrew/reactnative/FatalStoreModule.java +26 -0
- package/index.cjs +2 -0
- package/index.d.cts +3 -0
- package/index.d.ts +3 -0
- package/index.js +2 -0
- package/index.native.d.ts +43 -1
- package/index.native.js +68 -1
- package/ios/LBRNEventRecordStore.h +29 -0
- package/ios/LBRNEventRecordStore.m +746 -0
- package/ios/LBRNFatalStoreModule.mm +159 -14
- package/ios/LBRNPrivateStorage.h +7 -0
- package/ios/LBRNPrivateStorage.m +38 -0
- package/package.json +7 -2
- package/persistent-delivery.native.js +282 -0
- package/src/NativeLogBrewFatalStore.ts +9 -0
|
@@ -9,10 +9,15 @@ import com.facebook.react.bridge.ReadableType;
|
|
|
9
9
|
import com.facebook.react.bridge.WritableArray;
|
|
10
10
|
import com.facebook.react.bridge.WritableMap;
|
|
11
11
|
import java.io.File;
|
|
12
|
+
import java.nio.charset.StandardCharsets;
|
|
13
|
+
import java.security.MessageDigest;
|
|
14
|
+
import java.security.NoSuchAlgorithmException;
|
|
12
15
|
import java.util.ArrayList;
|
|
13
16
|
import java.util.Arrays;
|
|
17
|
+
import java.util.HashMap;
|
|
14
18
|
import java.util.HashSet;
|
|
15
19
|
import java.util.List;
|
|
20
|
+
import java.util.Map;
|
|
16
21
|
import java.util.Set;
|
|
17
22
|
|
|
18
23
|
final class FatalStoreModuleImpl {
|
|
@@ -32,9 +37,12 @@ final class FatalStoreModuleImpl {
|
|
|
32
37
|
new HashSet<>(Arrays.asList("filename", "line", "column"));
|
|
33
38
|
|
|
34
39
|
private final FatalRecordStore store;
|
|
40
|
+
private final File eventStoreParent;
|
|
41
|
+
private final Map<String, EventRecordStore> eventStores = new HashMap<>();
|
|
35
42
|
|
|
36
43
|
FatalStoreModuleImpl(ReactApplicationContext context) {
|
|
37
44
|
File root = context.getNoBackupFilesDir();
|
|
45
|
+
eventStoreParent = root;
|
|
38
46
|
store =
|
|
39
47
|
root == null
|
|
40
48
|
? null
|
|
@@ -43,6 +51,66 @@ final class FatalStoreModuleImpl {
|
|
|
43
51
|
new AndroidParentDirectorySync());
|
|
44
52
|
}
|
|
45
53
|
|
|
54
|
+
WritableMap loadEventRecords(String queueKey) {
|
|
55
|
+
try {
|
|
56
|
+
EventRecordStore eventStore = eventStore(queueKey);
|
|
57
|
+
return eventStore == null ? status("storage_error") : eventResultMap(eventStore.load());
|
|
58
|
+
} catch (RuntimeException error) {
|
|
59
|
+
return status("storage_error");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
WritableMap appendEventRecord(String queueKey, String serializedEvent, double eventBytes) {
|
|
64
|
+
try {
|
|
65
|
+
EventRecordStore eventStore = eventStore(queueKey);
|
|
66
|
+
Integer byteCount = integer(eventBytes);
|
|
67
|
+
return eventStore == null || byteCount == null
|
|
68
|
+
? status("storage_error")
|
|
69
|
+
: eventResultMap(eventStore.append(serializedEvent, byteCount));
|
|
70
|
+
} catch (RuntimeException error) {
|
|
71
|
+
return status("storage_error");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
WritableMap acknowledgeEventRecords(String queueKey, double count) {
|
|
76
|
+
try {
|
|
77
|
+
EventRecordStore eventStore = eventStore(queueKey);
|
|
78
|
+
Integer recordCount = integer(count);
|
|
79
|
+
return eventStore == null || recordCount == null
|
|
80
|
+
? status("storage_error")
|
|
81
|
+
: eventResultMap(eventStore.acknowledge(recordCount));
|
|
82
|
+
} catch (RuntimeException error) {
|
|
83
|
+
return status("storage_error");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
WritableMap purgeEventRecords(String queueKey) {
|
|
88
|
+
try {
|
|
89
|
+
EventRecordStore eventStore = eventStore(queueKey);
|
|
90
|
+
return eventStore == null ? status("storage_error") : eventResultMap(eventStore.purge());
|
|
91
|
+
} catch (RuntimeException error) {
|
|
92
|
+
return status("storage_error");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
synchronized WritableMap closeEventStore(String queueKey) {
|
|
97
|
+
String queueHash = queueHash(queueKey);
|
|
98
|
+
if (queueHash == null) {
|
|
99
|
+
return status("storage_error");
|
|
100
|
+
}
|
|
101
|
+
EventRecordStore eventStore = eventStores.get(queueHash);
|
|
102
|
+
if (eventStore == null) {
|
|
103
|
+
return status("closed");
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
return eventResultMap(eventStore.close());
|
|
107
|
+
} catch (RuntimeException error) {
|
|
108
|
+
return status("storage_error");
|
|
109
|
+
} finally {
|
|
110
|
+
eventStores.remove(queueHash);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
46
114
|
WritableMap writeFatalRecord(ReadableMap input) {
|
|
47
115
|
if (store == null) {
|
|
48
116
|
return status("storage_error");
|
|
@@ -227,4 +295,65 @@ final class FatalStoreModuleImpl {
|
|
|
227
295
|
output.putString("status", value);
|
|
228
296
|
return output;
|
|
229
297
|
}
|
|
298
|
+
|
|
299
|
+
private synchronized EventRecordStore eventStore(String queueKey) {
|
|
300
|
+
String queueHash = queueHash(queueKey);
|
|
301
|
+
if (eventStoreParent == null || queueHash == null) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
EventRecordStore existing = eventStores.get(queueHash);
|
|
305
|
+
if (existing != null) {
|
|
306
|
+
return existing;
|
|
307
|
+
}
|
|
308
|
+
EventRecordStore created =
|
|
309
|
+
new EventRecordStore(
|
|
310
|
+
new File(eventStoreParent, "logbrew-events-v1-" + queueHash),
|
|
311
|
+
new AndroidParentDirectorySync());
|
|
312
|
+
eventStores.put(queueHash, created);
|
|
313
|
+
return created;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private static String queueHash(String queueKey) {
|
|
317
|
+
if (queueKey == null || queueKey.trim().isEmpty()) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
byte[] keyBytes = queueKey.getBytes(StandardCharsets.UTF_8);
|
|
321
|
+
if (keyBytes.length == 0 || keyBytes.length > 4096) {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
try {
|
|
325
|
+
byte[] digest = MessageDigest.getInstance("SHA-256").digest(keyBytes);
|
|
326
|
+
StringBuilder value = new StringBuilder(digest.length * 2);
|
|
327
|
+
for (byte item : digest) {
|
|
328
|
+
value.append(String.format(java.util.Locale.ROOT, "%02x", item & 0xff));
|
|
329
|
+
}
|
|
330
|
+
return value.toString();
|
|
331
|
+
} catch (NoSuchAlgorithmException impossible) {
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
private static Integer integer(double value) {
|
|
337
|
+
return Double.isFinite(value)
|
|
338
|
+
&& value >= 0
|
|
339
|
+
&& value <= Integer.MAX_VALUE
|
|
340
|
+
&& value == Math.rint(value)
|
|
341
|
+
? (int) value
|
|
342
|
+
: null;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private static WritableMap eventResultMap(EventRecordStore.Result result) {
|
|
346
|
+
WritableMap output = status(result.status);
|
|
347
|
+
if ("loaded".equals(result.status)) {
|
|
348
|
+
WritableArray records = Arguments.createArray();
|
|
349
|
+
for (EventRecordStore.Record record : result.records) {
|
|
350
|
+
WritableMap value = Arguments.createMap();
|
|
351
|
+
value.putString("serializedEvent", record.serializedEvent);
|
|
352
|
+
value.putInt("eventBytes", record.eventBytes);
|
|
353
|
+
records.pushMap(value);
|
|
354
|
+
}
|
|
355
|
+
output.putArray("records", records);
|
|
356
|
+
}
|
|
357
|
+
return output;
|
|
358
|
+
}
|
|
230
359
|
}
|
|
@@ -36,4 +36,30 @@ final class FatalStoreModule extends NativeLogBrewFatalStoreSpec {
|
|
|
36
36
|
public WritableMap discardFatalRecord() {
|
|
37
37
|
return implementation.discardFatalRecord();
|
|
38
38
|
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
public WritableMap loadEventRecords(String queueKey) {
|
|
42
|
+
return implementation.loadEventRecords(queueKey);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Override
|
|
46
|
+
public WritableMap appendEventRecord(
|
|
47
|
+
String queueKey, String serializedEvent, double eventBytes) {
|
|
48
|
+
return implementation.appendEventRecord(queueKey, serializedEvent, eventBytes);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@Override
|
|
52
|
+
public WritableMap acknowledgeEventRecords(String queueKey, double count) {
|
|
53
|
+
return implementation.acknowledgeEventRecords(queueKey, count);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@Override
|
|
57
|
+
public WritableMap purgeEventRecords(String queueKey) {
|
|
58
|
+
return implementation.purgeEventRecords(queueKey);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@Override
|
|
62
|
+
public WritableMap closeEventStore(String queueKey) {
|
|
63
|
+
return implementation.closeEventStore(queueKey);
|
|
64
|
+
}
|
|
39
65
|
}
|
|
@@ -38,4 +38,30 @@ final class FatalStoreModule extends ReactContextBaseJavaModule {
|
|
|
38
38
|
public WritableMap discardFatalRecord() {
|
|
39
39
|
return implementation.discardFatalRecord();
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
43
|
+
public WritableMap loadEventRecords(String queueKey) {
|
|
44
|
+
return implementation.loadEventRecords(queueKey);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
48
|
+
public WritableMap appendEventRecord(
|
|
49
|
+
String queueKey, String serializedEvent, double eventBytes) {
|
|
50
|
+
return implementation.appendEventRecord(queueKey, serializedEvent, eventBytes);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
54
|
+
public WritableMap acknowledgeEventRecords(String queueKey, double count) {
|
|
55
|
+
return implementation.acknowledgeEventRecords(queueKey, count);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
59
|
+
public WritableMap purgeEventRecords(String queueKey) {
|
|
60
|
+
return implementation.purgeEventRecords(queueKey);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
64
|
+
public WritableMap closeEventStore(String queueKey) {
|
|
65
|
+
return implementation.closeEventStore(queueKey);
|
|
66
|
+
}
|
|
41
67
|
}
|
package/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ function createLogBrewReactNativeClient({
|
|
|
29
29
|
clientKey,
|
|
30
30
|
deliveryIntervalMs,
|
|
31
31
|
deliveryQueueThreshold,
|
|
32
|
+
eventStore,
|
|
32
33
|
maxBatchBytes,
|
|
33
34
|
maxBatchEvents,
|
|
34
35
|
maxQueueBytes,
|
|
@@ -48,6 +49,7 @@ function createLogBrewReactNativeClient({
|
|
|
48
49
|
automaticDelivery,
|
|
49
50
|
deliveryIntervalMs,
|
|
50
51
|
deliveryQueueThreshold,
|
|
52
|
+
eventStore,
|
|
51
53
|
maxBatchBytes,
|
|
52
54
|
maxBatchEvents,
|
|
53
55
|
maxQueueBytes,
|
package/index.d.cts
CHANGED
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
DeliveryHealthSnapshot,
|
|
5
5
|
DroppedEvent,
|
|
6
6
|
EnvironmentAttributes,
|
|
7
|
+
EventStore,
|
|
7
8
|
IssueAttributes,
|
|
8
9
|
LogAttributes,
|
|
9
10
|
LogBrewClient,
|
|
@@ -37,6 +38,8 @@ export type CreateLogBrewReactNativeClientConfig = {
|
|
|
37
38
|
clientKey?: string;
|
|
38
39
|
deliveryIntervalMs?: number;
|
|
39
40
|
deliveryQueueThreshold?: number;
|
|
41
|
+
/** Advanced synchronous persistence seam. React Native apps normally use the native entry's persistentQueue mode. */
|
|
42
|
+
eventStore?: EventStore;
|
|
40
43
|
maxBatchBytes?: number;
|
|
41
44
|
maxBatchEvents?: number;
|
|
42
45
|
maxQueueBytes?: number;
|
package/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
DeliveryHealthSnapshot,
|
|
5
5
|
DroppedEvent,
|
|
6
6
|
EnvironmentAttributes,
|
|
7
|
+
EventStore,
|
|
7
8
|
IssueAttributes,
|
|
8
9
|
LogAttributes,
|
|
9
10
|
LogBrewClient,
|
|
@@ -37,6 +38,8 @@ export type CreateLogBrewReactNativeClientConfig = {
|
|
|
37
38
|
clientKey?: string;
|
|
38
39
|
deliveryIntervalMs?: number;
|
|
39
40
|
deliveryQueueThreshold?: number;
|
|
41
|
+
/** Advanced synchronous persistence seam. React Native apps normally use the native entry's persistentQueue mode. */
|
|
42
|
+
eventStore?: EventStore;
|
|
40
43
|
maxBatchBytes?: number;
|
|
41
44
|
maxBatchEvents?: number;
|
|
42
45
|
maxQueueBytes?: number;
|
package/index.js
CHANGED
|
@@ -29,6 +29,7 @@ export function createLogBrewReactNativeClient({
|
|
|
29
29
|
clientKey,
|
|
30
30
|
deliveryIntervalMs,
|
|
31
31
|
deliveryQueueThreshold,
|
|
32
|
+
eventStore,
|
|
32
33
|
maxBatchBytes,
|
|
33
34
|
maxBatchEvents,
|
|
34
35
|
maxQueueBytes,
|
|
@@ -48,6 +49,7 @@ export function createLogBrewReactNativeClient({
|
|
|
48
49
|
automaticDelivery,
|
|
49
50
|
deliveryIntervalMs,
|
|
50
51
|
deliveryQueueThreshold,
|
|
52
|
+
eventStore,
|
|
51
53
|
maxBatchBytes,
|
|
52
54
|
maxBatchEvents,
|
|
53
55
|
maxQueueBytes,
|
package/index.native.d.ts
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
|
-
|
|
1
|
+
import type { EventStore, LogBrewClient } from "@logbrew/sdk";
|
|
2
|
+
import type { CreateLogBrewReactNativeClientConfig } from "./index.js";
|
|
3
|
+
|
|
4
|
+
export * from "./index.js";
|
|
2
5
|
export {
|
|
3
6
|
installLogBrewReactNativeGlobalErrorHandler,
|
|
4
7
|
installLogBrewReactNativePromiseRejectionTracker
|
|
5
8
|
} from "./global-errors";
|
|
9
|
+
|
|
10
|
+
export type ReactNativePersistentQueueMode = "auto" | "required" | "disabled";
|
|
11
|
+
|
|
12
|
+
export type CreateNativeLogBrewReactNativeClientConfig =
|
|
13
|
+
Omit<CreateLogBrewReactNativeClientConfig, "eventStore"> & ({
|
|
14
|
+
/**
|
|
15
|
+
* `auto` uses the linked app-private native queue when available and otherwise uses memory.
|
|
16
|
+
* `required` fails client creation when the native queue is unavailable. `disabled` uses memory.
|
|
17
|
+
*/
|
|
18
|
+
persistentQueue?: ReactNativePersistentQueueMode;
|
|
19
|
+
eventStore?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
/** Advanced app-owned synchronous persistence adapter. Mutually exclusive with persistentQueue. */
|
|
22
|
+
eventStore: EventStore;
|
|
23
|
+
persistentQueue?: never;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export declare function createLogBrewReactNativeClient(
|
|
27
|
+
config: CreateNativeLogBrewReactNativeClientConfig
|
|
28
|
+
): LogBrewClient;
|
|
29
|
+
|
|
30
|
+
export declare function createDefaultLogBrewReactNativeClient(
|
|
31
|
+
config: CreateNativeLogBrewReactNativeClientConfig
|
|
32
|
+
): LogBrewClient;
|
|
33
|
+
|
|
34
|
+
export declare function purgeLogBrewReactNativePersistentQueue(
|
|
35
|
+
config: { apiKey?: string; clientKey?: string }
|
|
36
|
+
): void;
|
|
37
|
+
|
|
38
|
+
declare const defaultExport: Omit<
|
|
39
|
+
typeof import("./index.js").default,
|
|
40
|
+
"createLogBrewReactNativeClient" | "createDefaultLogBrewReactNativeClient"
|
|
41
|
+
> & {
|
|
42
|
+
createLogBrewReactNativeClient: typeof createLogBrewReactNativeClient;
|
|
43
|
+
createDefaultLogBrewReactNativeClient: typeof createDefaultLogBrewReactNativeClient;
|
|
44
|
+
purgeLogBrewReactNativePersistentQueue: typeof purgeLogBrewReactNativePersistentQueue;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default defaultExport;
|
package/index.native.js
CHANGED
|
@@ -6,9 +6,14 @@ import {
|
|
|
6
6
|
captureReactNativeNetwork,
|
|
7
7
|
captureScreenView,
|
|
8
8
|
createAppStateListener,
|
|
9
|
-
createLogBrewReactNativeClient,
|
|
9
|
+
createLogBrewReactNativeClient as createPlatformNeutralClient,
|
|
10
10
|
getReactNativeContext
|
|
11
11
|
} from "./index.js";
|
|
12
|
+
import baseDefault from "./index.js";
|
|
13
|
+
import {
|
|
14
|
+
purgeReactNativePersistentQueue,
|
|
15
|
+
resolveReactNativePersistentEventStore
|
|
16
|
+
} from "./persistent-delivery.native.js";
|
|
12
17
|
export {
|
|
13
18
|
installLogBrewReactNativeGlobalErrorHandler,
|
|
14
19
|
installLogBrewReactNativePromiseRejectionTracker
|
|
@@ -16,6 +21,52 @@ export {
|
|
|
16
21
|
|
|
17
22
|
export * from "./index.js";
|
|
18
23
|
|
|
24
|
+
export function createLogBrewReactNativeClient(config = {}) {
|
|
25
|
+
const input = config !== null && typeof config === "object" ? config : {};
|
|
26
|
+
const {
|
|
27
|
+
apiKey,
|
|
28
|
+
clientKey,
|
|
29
|
+
eventStore,
|
|
30
|
+
maxQueueBytes,
|
|
31
|
+
maxQueueSize,
|
|
32
|
+
persistentQueue = "auto",
|
|
33
|
+
...forwarded
|
|
34
|
+
} = input;
|
|
35
|
+
const hasExplicitPersistentQueue = Object.prototype.hasOwnProperty.call(
|
|
36
|
+
input,
|
|
37
|
+
"persistentQueue"
|
|
38
|
+
) && input.persistentQueue !== undefined;
|
|
39
|
+
const authKey = clientKey ?? apiKey;
|
|
40
|
+
if (typeof authKey !== "string" || authKey.trim() === "") {
|
|
41
|
+
return createPlatformNeutralClient(input);
|
|
42
|
+
}
|
|
43
|
+
const resolved = resolveReactNativePersistentEventStore({
|
|
44
|
+
authKey,
|
|
45
|
+
eventStore,
|
|
46
|
+
maxQueueBytes,
|
|
47
|
+
maxQueueSize,
|
|
48
|
+
persistentQueue,
|
|
49
|
+
hasExplicitPersistentQueue
|
|
50
|
+
});
|
|
51
|
+
try {
|
|
52
|
+
return createPlatformNeutralClient({
|
|
53
|
+
...forwarded,
|
|
54
|
+
apiKey,
|
|
55
|
+
clientKey,
|
|
56
|
+
eventStore: resolved.eventStore,
|
|
57
|
+
maxQueueBytes,
|
|
58
|
+
maxQueueSize
|
|
59
|
+
});
|
|
60
|
+
} catch (error) {
|
|
61
|
+
resolved.abort();
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function purgeLogBrewReactNativePersistentQueue(config = {}) {
|
|
67
|
+
purgeReactNativePersistentQueue(config);
|
|
68
|
+
}
|
|
69
|
+
|
|
19
70
|
export function createDefaultLogBrewReactNativeClient(config = {}) {
|
|
20
71
|
return createLogBrewReactNativeClient(config);
|
|
21
72
|
}
|
|
@@ -70,3 +121,19 @@ export function createDefaultAppStateListener(client, options = {}) {
|
|
|
70
121
|
...options
|
|
71
122
|
});
|
|
72
123
|
}
|
|
124
|
+
|
|
125
|
+
const defaultExport = {
|
|
126
|
+
...baseDefault,
|
|
127
|
+
captureDefaultAppStateChange,
|
|
128
|
+
captureDefaultReactNativeAction,
|
|
129
|
+
captureDefaultReactNativeError,
|
|
130
|
+
captureDefaultReactNativeNetwork,
|
|
131
|
+
captureDefaultScreenView,
|
|
132
|
+
createDefaultAppStateListener,
|
|
133
|
+
createDefaultLogBrewReactNativeClient,
|
|
134
|
+
createLogBrewReactNativeClient,
|
|
135
|
+
getDefaultReactNativeContext,
|
|
136
|
+
purgeLogBrewReactNativePersistentQueue
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export default defaultExport;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
4
|
+
|
|
5
|
+
FOUNDATION_EXPORT NSString *const LBRNEventRecordPrefix;
|
|
6
|
+
FOUNDATION_EXPORT NSString *const LBRNEventRecordSuffix;
|
|
7
|
+
FOUNDATION_EXPORT NSString *const LBRNEventMarkerPrefix;
|
|
8
|
+
FOUNDATION_EXPORT NSString *const LBRNEventMarkerSuffix;
|
|
9
|
+
|
|
10
|
+
typedef BOOL (^LBRNEventDirectoryPreparation)(NSURL *directoryURL);
|
|
11
|
+
|
|
12
|
+
@interface LBRNEventRecordStore : NSObject
|
|
13
|
+
|
|
14
|
+
- (instancetype)initWithDirectoryURL:(NSURL *)directoryURL;
|
|
15
|
+
- (instancetype)initWithDirectoryURL:(NSURL *)directoryURL
|
|
16
|
+
directoryPreparation:(LBRNEventDirectoryPreparation)directoryPreparation
|
|
17
|
+
NS_DESIGNATED_INITIALIZER;
|
|
18
|
+
- (instancetype)init NS_UNAVAILABLE;
|
|
19
|
+
|
|
20
|
+
- (NSDictionary *)loadRecords;
|
|
21
|
+
- (NSDictionary *)appendSerializedEvent:(NSString *)serializedEvent
|
|
22
|
+
eventBytes:(NSNumber *)eventBytes;
|
|
23
|
+
- (NSDictionary *)acknowledgeRecordCount:(NSNumber *)count;
|
|
24
|
+
- (NSDictionary *)purgeRecords;
|
|
25
|
+
- (NSDictionary *)closeStore;
|
|
26
|
+
|
|
27
|
+
@end
|
|
28
|
+
|
|
29
|
+
NS_ASSUME_NONNULL_END
|