@logbrew/react-native 0.1.9 → 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.
@@ -6,9 +6,17 @@ const AUTOMATIC_MESSAGE = "Unhandled Promise rejection";
6
6
  const DEFAULT_MAX_TRACKED_REJECTIONS = 128;
7
7
  const MAX_TRACKED_REJECTIONS = 1024;
8
8
  const MAX_STRING_ID_LENGTH = 128;
9
+ const activeTrackerInstallations = new WeakMap();
9
10
  let nextEventSequence = 0;
10
11
 
11
12
  function createLogBrewReactNativePromiseRejectionHandlers(options = {}) {
13
+ return createPromiseRejectionHandlers(
14
+ options,
15
+ "app_owned_promise_rejection_tracker"
16
+ );
17
+ }
18
+
19
+ function createPromiseRejectionHandlers(options, mechanism) {
12
20
  const input = isObjectLike(options) ? options : {};
13
21
  const client = safeReadProperty(input, "client");
14
22
  const issue = safeFunction(client, "issue");
@@ -92,7 +100,7 @@ function createLogBrewReactNativePromiseRejectionHandlers(options = {}) {
92
100
  if (key === undefined) {
93
101
  emitStateDiagnostic(state, onDiagnostic, "promise_rejection_id_unavailable");
94
102
  }
95
- const event = createEvent();
103
+ const event = createEvent(mechanism);
96
104
  issue.call(client, event.id, event.timestamp, event.attributes);
97
105
  state.capturedEvents = incrementBounded(state.capturedEvents);
98
106
 
@@ -124,7 +132,93 @@ function createLogBrewReactNativePromiseRejectionHandlers(options = {}) {
124
132
  });
125
133
  }
126
134
 
127
- function createEvent() {
135
+ function installLogBrewReactNativePromiseRejectionTracker(options = {}) {
136
+ const input = isObjectLike(options) ? options : {};
137
+ const onDiagnostic = safeFunction(input, "onDiagnostic");
138
+ if (safeReadProperty(input, "takeOwnership") !== true) {
139
+ emitDiagnostic(onDiagnostic, "promise_rejection_tracker_ownership_required");
140
+ return inactiveTrackerInstallation("ownership_required");
141
+ }
142
+
143
+ const tracker = safeReadProperty(input, "tracker");
144
+ const enable = safeFunction(tracker, "enable");
145
+ const engine = safeReadProperty(input, "trackerKind") === "hermes"
146
+ ? "hermes"
147
+ : isObjectLike(tracker) ? "custom" : "unavailable";
148
+ if (!isObjectLike(tracker) || !enable) {
149
+ emitDiagnostic(onDiagnostic, "promise_rejection_tracker_unavailable");
150
+ return inactiveTrackerInstallation("tracker_unavailable", engine);
151
+ }
152
+
153
+ const existing = activeTrackerInstallations.get(tracker);
154
+ if (existing?.health().active) {
155
+ return existing;
156
+ }
157
+
158
+ const handlers = createPromiseRejectionHandlers(
159
+ input,
160
+ "logbrew_owned_promise_rejection_tracker"
161
+ );
162
+ if (!handlers.health().available) {
163
+ return inactiveTrackerInstallation("handler_unavailable", engine, handlers);
164
+ }
165
+
166
+ const state = {
167
+ active: true,
168
+ lastOutcome: "installed"
169
+ };
170
+ const trackerOptions = Object.freeze({
171
+ allRejections: true,
172
+ onHandled(runtimeRejectionId) {
173
+ if (state.active) {
174
+ handlers.onHandled(runtimeRejectionId);
175
+ }
176
+ },
177
+ onUnhandled(runtimeRejectionId, rejection) {
178
+ if (state.active) {
179
+ handlers.onUnhandled(runtimeRejectionId, rejection);
180
+ }
181
+ }
182
+ });
183
+
184
+ const installation = Object.freeze({
185
+ deactivate() {
186
+ if (!state.active) {
187
+ return false;
188
+ }
189
+ state.active = false;
190
+ state.lastOutcome = "deactivated";
191
+ if (activeTrackerInstallations.get(tracker) === installation) {
192
+ activeTrackerInstallations.delete(tracker);
193
+ }
194
+ return true;
195
+ },
196
+ health() {
197
+ return trackerHealthSnapshot(state, engine, true);
198
+ },
199
+ rejectionHealth() {
200
+ return handlers.health();
201
+ }
202
+ });
203
+
204
+ try {
205
+ enable.call(tracker, trackerOptions);
206
+ } catch {
207
+ state.active = false;
208
+ state.lastOutcome = "installation_failed";
209
+ emitDiagnostic(onDiagnostic, "promise_rejection_tracker_installation_failed");
210
+ return inactiveTrackerInstallation(
211
+ "installation_failed",
212
+ engine,
213
+ handlers
214
+ );
215
+ }
216
+
217
+ activeTrackerInstallations.set(tracker, installation);
218
+ return installation;
219
+ }
220
+
221
+ function createEvent(mechanism) {
128
222
  const error = new Error(AUTOMATIC_MESSAGE);
129
223
  delete error.stack;
130
224
  const event = createReactNativeErrorEvent(error, {
@@ -142,7 +236,7 @@ function createEvent() {
142
236
  automatic: true,
143
237
  fatal: false,
144
238
  handled: false,
145
- mechanism: "app_owned_promise_rejection_tracker",
239
+ mechanism,
146
240
  source: "react-native.promise_rejection"
147
241
  }
148
242
  }
@@ -224,6 +318,35 @@ function inactiveHandlers() {
224
318
  });
225
319
  }
226
320
 
321
+ function inactiveTrackerInstallation(
322
+ lastOutcome,
323
+ engine = "unavailable",
324
+ handlers = inactiveHandlers()
325
+ ) {
326
+ const snapshot = Object.freeze({
327
+ active: false,
328
+ available: false,
329
+ engine,
330
+ lastOutcome,
331
+ restoration: "deactivate_only"
332
+ });
333
+ return Object.freeze({
334
+ deactivate: () => false,
335
+ health: () => snapshot,
336
+ rejectionHealth: () => handlers.health()
337
+ });
338
+ }
339
+
340
+ function trackerHealthSnapshot(state, engine, available) {
341
+ return Object.freeze({
342
+ active: state.active,
343
+ available,
344
+ engine,
345
+ lastOutcome: state.lastOutcome,
346
+ restoration: "deactivate_only"
347
+ });
348
+ }
349
+
227
350
  function healthSnapshot(state, trackedRejections, maxTrackedRejections) {
228
351
  return Object.freeze({
229
352
  available: true,
@@ -267,5 +390,6 @@ function isObjectLike(value) {
267
390
  }
268
391
 
269
392
  module.exports = {
270
- createLogBrewReactNativePromiseRejectionHandlers
393
+ createLogBrewReactNativePromiseRejectionHandlers,
394
+ installLogBrewReactNativePromiseRejectionTracker
271
395
  };
@@ -6,6 +6,15 @@ export interface Spec extends TurboModule {
6
6
  readFatalRecord(): CodegenTypes.UnsafeObject;
7
7
  acknowledgeFatalRecord(recordId: string): CodegenTypes.UnsafeObject;
8
8
  discardFatalRecord(): CodegenTypes.UnsafeObject;
9
+ loadEventRecords(queueKey: string): CodegenTypes.UnsafeObject;
10
+ appendEventRecord(
11
+ queueKey: string,
12
+ serializedEvent: string,
13
+ eventBytes: number
14
+ ): CodegenTypes.UnsafeObject;
15
+ acknowledgeEventRecords(queueKey: string, count: number): CodegenTypes.UnsafeObject;
16
+ purgeEventRecords(queueKey: string): CodegenTypes.UnsafeObject;
17
+ closeEventStore(queueKey: string): CodegenTypes.UnsafeObject;
9
18
  }
10
19
 
11
20
  export default TurboModuleRegistry.getEnforcing<Spec>("LogBrewFatalStore");