@getuserfeedback/react-native 1.3.5 → 1.3.6

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/dist/index.js CHANGED
@@ -13,7 +13,8 @@ import { assertNoSegmentExternalIdsInValueArgument, CommandSettlementTimeoutErro
13
13
  import { parseWebViewTransportNativeMessage } from "@getuserfeedback/protocol/webview-transport";
14
14
  import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
15
15
  import { useResolvedHostViewport } from "./host-viewport.js";
16
- import { toCommandFlowId, toCommandSettlementError, toRetryWithoutFlowHandle, toSettledFlowHandleId, } from "./provider-command-helpers.js";
16
+ import { toCommandFlowId, toCommandSettlementError, toRetryWithoutFlowHandle, } from "./provider-command-helpers.js";
17
+ import { clearProviderFlowHandleCache, createProviderFlowHandleCache, deleteCachedProviderFlowHandleId, deleteCachedProviderFlowId, getCachedProviderFlowHandleId, snapshotProviderFlowCommand, writeSettledProviderFlowHandleId, } from "./provider-flow-handle-cache.js";
17
18
  import { applyProviderOverlayFlowState, applyProviderOverlayHandleInvalidated, createDefaultProviderOverlayState, DEFAULT_PROVIDER_OVERLAY_VISIBILITY, updateProviderOverlayReadySequence, } from "./provider-overlay-state.js";
18
19
  import { ProviderWidgetHostOverlay, toProviderWidgetHostStyle, toProviderWidgetSheetHostViewport, } from "./provider-widget-host-overlay.js";
19
20
  import { REACT_NATIVE_SDK_VERSION } from "./version.js";
@@ -115,9 +116,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
115
116
  const nativeMessagesRef = useRef([]);
116
117
  const pendingCommandsRef = useRef(new Map());
117
118
  const hostEpochRef = useRef(0);
118
- const flowHandleCacheEpochRef = useRef(0);
119
- const flowHandleIdsByFlowIdRef = useRef(new Map());
120
- const flowCommandSequencesByFlowIdRef = useRef(new Map());
119
+ const flowHandleCacheRef = useRef(createProviderFlowHandleCache());
121
120
  const providerOverlayStateRef = useRef(createDefaultProviderOverlayState());
122
121
  const initOptionsRef = useRef(initOptions);
123
122
  const configureOptionsRef = useRef(configureOptions);
@@ -143,8 +142,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
143
142
  }
144
143
  lastReadyRef.current = null;
145
144
  startupQueuedKeyRef.current = null;
146
- flowHandleCacheEpochRef.current += 1;
147
- flowHandleIdsByFlowIdRef.current.clear();
145
+ clearProviderFlowHandleCache(flowHandleCacheRef.current);
148
146
  providerOverlayStateRef.current = createDefaultProviderOverlayState();
149
147
  }
150
148
  initOptionsRef.current = initOptions;
@@ -203,7 +201,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
203
201
  }
204
202
  }, []);
205
203
  const enqueueTransportCommand = useCallback((command, options, { isStartup = false, prioritizeStartup = false, } = {}) => {
206
- var _a, _b;
204
+ var _a;
207
205
  const requestId = createCommandRequestId();
208
206
  const idempotencyKey = (_a = normalizeOptionalString(options === null || options === void 0 ? void 0 : options.idempotencyKey)) !== null && _a !== void 0 ? _a : requestId;
209
207
  const envelope = {
@@ -233,17 +231,11 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
233
231
  envelope: validatedMessage.envelope,
234
232
  message: validatedMessage,
235
233
  };
236
- const flowId = toCommandFlowId(validatedMessage.envelope.command);
237
- const flowCommandSequence = flowId === undefined
238
- ? null
239
- : ((_b = flowCommandSequencesByFlowIdRef.current.get(flowId)) !== null && _b !== void 0 ? _b : 0) + 1;
240
- if (flowId !== undefined && flowCommandSequence !== null) {
241
- flowCommandSequencesByFlowIdRef.current.set(flowId, flowCommandSequence);
242
- }
234
+ const flowCommandSnapshot = snapshotProviderFlowCommand(flowHandleCacheRef.current, validatedMessage.envelope.command);
243
235
  const promise = new Promise((resolve, reject) => {
244
236
  pendingCommandsRef.current.set(requestId, {
245
- flowCommandSequence,
246
- flowHandleCacheEpoch: flowHandleCacheEpochRef.current,
237
+ flowCommandSequence: flowCommandSnapshot.flowCommandSequence,
238
+ flowHandleCacheEpoch: flowCommandSnapshot.flowHandleCacheEpoch,
247
239
  hostEpoch: null,
248
240
  isStartup,
249
241
  messageId: validatedMessage.id,
@@ -297,7 +289,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
297
289
  envelope: nextEnvelope,
298
290
  });
299
291
  const previousMessageId = pendingCommand.messageId;
300
- pendingCommand.flowHandleCacheEpoch = flowHandleCacheEpochRef.current;
292
+ pendingCommand.flowHandleCacheEpoch = flowHandleCacheRef.current.epoch;
301
293
  pendingCommand.hostEpoch = null;
302
294
  pendingCommand.messageId = nextMessage.id;
303
295
  pendingCommand.result = {
@@ -375,8 +367,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
375
367
  if (previous !== null || hasDeliveredPendingCommands) {
376
368
  hostEpochRef.current += 1;
377
369
  startupQueuedKeyRef.current = null;
378
- flowHandleCacheEpochRef.current += 1;
379
- flowHandleIdsByFlowIdRef.current.clear();
370
+ clearProviderFlowHandleCache(flowHandleCacheRef.current);
380
371
  didReissueDeliveredCommands = reissueDeliveredPendingActionCommands();
381
372
  }
382
373
  lastReadyRef.current = Object.assign(Object.assign({}, event), { hostEpoch: hostEpochRef.current });
@@ -411,8 +402,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
411
402
  if (lastReadyRef.current !== null) {
412
403
  hostEpochRef.current += 1;
413
404
  startupQueuedKeyRef.current = null;
414
- flowHandleCacheEpochRef.current += 1;
415
- flowHandleIdsByFlowIdRef.current.clear();
405
+ clearProviderFlowHandleCache(flowHandleCacheRef.current);
416
406
  reissueDeliveredPendingActionCommands();
417
407
  }
418
408
  lastReadyRef.current = null;
@@ -425,12 +415,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
425
415
  reissueDeliveredPendingActionCommands,
426
416
  ]);
427
417
  const deleteCachedFlowHandleId = useCallback((flowHandleId) => {
428
- for (const [flowId, cachedFlowHandleId,] of flowHandleIdsByFlowIdRef.current) {
429
- if (cachedFlowHandleId === flowHandleId) {
430
- flowHandleIdsByFlowIdRef.current.delete(flowId);
431
- }
432
- }
433
- flowHandleCacheEpochRef.current += 1;
418
+ deleteCachedProviderFlowHandleId(flowHandleCacheRef.current, flowHandleId);
434
419
  }, []);
435
420
  const handleFlowHandleInvalidated = useCallback((flowHandleId) => {
436
421
  deleteCachedFlowHandleId(flowHandleId);
@@ -500,7 +485,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
500
485
  const isStaleFlowHandleError = error.code === "STALE_HANDLE" ||
501
486
  error.message.includes("flowHandleId is stale");
502
487
  if (flowId && isStaleFlowHandleError) {
503
- flowHandleIdsByFlowIdRef.current.delete(flowId);
488
+ deleteCachedProviderFlowId(flowHandleCacheRef.current, flowId);
504
489
  }
505
490
  const retryCommand = isStaleFlowHandleError
506
491
  ? toRetryWithoutFlowHandle(pendingCommand.result.envelope.command)
@@ -514,20 +499,14 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
514
499
  else {
515
500
  const settlement = message.event
516
501
  .detail;
517
- const flowId = toCommandFlowId(pendingCommand.result.envelope.command);
518
- const flowHandleId = toSettledFlowHandleId(settlement.result);
519
- const canWriteFlowHandle = flowId &&
520
- flowHandleId &&
521
- pendingCommand.flowHandleCacheEpoch ===
522
- flowHandleCacheEpochRef.current &&
523
- pendingCommand.flowCommandSequence ===
524
- flowCommandSequencesByFlowIdRef.current.get(flowId);
525
- if (canWriteFlowHandle) {
526
- flowHandleIdsByFlowIdRef.current.set(flowId, flowHandleId);
527
- }
502
+ writeSettledProviderFlowHandleId(flowHandleCacheRef.current, {
503
+ command: pendingCommand.result.envelope.command,
504
+ flowCommandSequence: pendingCommand.flowCommandSequence,
505
+ flowHandleCacheEpoch: pendingCommand.flowHandleCacheEpoch,
506
+ settlementResult: settlement.result,
507
+ });
528
508
  if (pendingCommand.result.envelope.command.kind === "reset") {
529
- flowHandleCacheEpochRef.current += 1;
530
- flowHandleIdsByFlowIdRef.current.clear();
509
+ clearProviderFlowHandleCache(flowHandleCacheRef.current);
531
510
  }
532
511
  const settledResult = Object.assign(Object.assign({}, pendingCommand.result), { settlement, settlementResult: settlement.result });
533
512
  pendingCommand.resolve(settledResult);
@@ -582,7 +561,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
582
561
  return enqueueCommand({
583
562
  kind: "open",
584
563
  flowId: normalizedFlowId,
585
- flowHandleId: flowHandleIdsByFlowIdRef.current.get(normalizedFlowId),
564
+ flowHandleId: getCachedProviderFlowHandleId(flowHandleCacheRef.current, normalizedFlowId),
586
565
  hideCloseButton: options === null || options === void 0 ? void 0 : options.hideCloseButton,
587
566
  }, commandOptions);
588
567
  },
@@ -591,7 +570,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
591
570
  return enqueueCommand({
592
571
  kind: "prefetch",
593
572
  flowId: normalizedFlowId,
594
- flowHandleId: flowHandleIdsByFlowIdRef.current.get(normalizedFlowId),
573
+ flowHandleId: getCachedProviderFlowHandleId(flowHandleCacheRef.current, normalizedFlowId),
595
574
  }, options);
596
575
  },
597
576
  prerender: (flowId, options, commandOptions) => {
@@ -599,7 +578,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
599
578
  return enqueueCommand({
600
579
  kind: "prerender",
601
580
  flowId: normalizedFlowId,
602
- flowHandleId: flowHandleIdsByFlowIdRef.current.get(normalizedFlowId),
581
+ flowHandleId: getCachedProviderFlowHandleId(flowHandleCacheRef.current, normalizedFlowId),
603
582
  hideCloseButton: options === null || options === void 0 ? void 0 : options.hideCloseButton,
604
583
  }, commandOptions);
605
584
  },
@@ -0,0 +1,24 @@
1
+ import type { WebViewCommandEnvelope } from "@getuserfeedback/protocol/webview-transport";
2
+ type ReactNativeWidgetCommand = WebViewCommandEnvelope["command"];
3
+ export type ProviderFlowCommandSnapshot = {
4
+ flowCommandSequence: number | null;
5
+ flowHandleCacheEpoch: number;
6
+ };
7
+ export type ProviderFlowHandleCache = {
8
+ epoch: number;
9
+ flowCommandSequencesByFlowId: Map<string, number>;
10
+ flowHandleIdsByFlowId: Map<string, string>;
11
+ };
12
+ export declare function createProviderFlowHandleCache(): ProviderFlowHandleCache;
13
+ export declare function clearProviderFlowHandleCache(cache: ProviderFlowHandleCache): void;
14
+ export declare function deleteCachedProviderFlowHandleId(cache: ProviderFlowHandleCache, flowHandleId: string): void;
15
+ export declare function deleteCachedProviderFlowId(cache: ProviderFlowHandleCache, flowId: string): void;
16
+ export declare function getCachedProviderFlowHandleId(cache: ProviderFlowHandleCache, flowId: string): string | undefined;
17
+ export declare function snapshotProviderFlowCommand(cache: ProviderFlowHandleCache, command: ReactNativeWidgetCommand): ProviderFlowCommandSnapshot;
18
+ export declare function writeSettledProviderFlowHandleId(cache: ProviderFlowHandleCache, { command, flowCommandSequence, flowHandleCacheEpoch, settlementResult, }: {
19
+ command: ReactNativeWidgetCommand;
20
+ flowCommandSequence: number | null;
21
+ flowHandleCacheEpoch: number;
22
+ settlementResult: unknown;
23
+ }): boolean;
24
+ export {};
@@ -0,0 +1,53 @@
1
+ import { toCommandFlowId, toSettledFlowHandleId, } from "./provider-command-helpers.js";
2
+ export function createProviderFlowHandleCache() {
3
+ return {
4
+ epoch: 0,
5
+ flowCommandSequencesByFlowId: new Map(),
6
+ flowHandleIdsByFlowId: new Map(),
7
+ };
8
+ }
9
+ export function clearProviderFlowHandleCache(cache) {
10
+ cache.epoch += 1;
11
+ cache.flowHandleIdsByFlowId.clear();
12
+ }
13
+ export function deleteCachedProviderFlowHandleId(cache, flowHandleId) {
14
+ for (const [flowId, cachedFlowHandleId] of cache.flowHandleIdsByFlowId) {
15
+ if (cachedFlowHandleId === flowHandleId) {
16
+ cache.flowHandleIdsByFlowId.delete(flowId);
17
+ }
18
+ }
19
+ cache.epoch += 1;
20
+ }
21
+ export function deleteCachedProviderFlowId(cache, flowId) {
22
+ cache.flowHandleIdsByFlowId.delete(flowId);
23
+ }
24
+ export function getCachedProviderFlowHandleId(cache, flowId) {
25
+ return cache.flowHandleIdsByFlowId.get(flowId);
26
+ }
27
+ export function snapshotProviderFlowCommand(cache, command) {
28
+ var _a;
29
+ const flowId = toCommandFlowId(command);
30
+ const flowCommandSequence = flowId === undefined
31
+ ? null
32
+ : ((_a = cache.flowCommandSequencesByFlowId.get(flowId)) !== null && _a !== void 0 ? _a : 0) + 1;
33
+ if (flowId !== undefined && flowCommandSequence !== null) {
34
+ cache.flowCommandSequencesByFlowId.set(flowId, flowCommandSequence);
35
+ }
36
+ return {
37
+ flowCommandSequence,
38
+ flowHandleCacheEpoch: cache.epoch,
39
+ };
40
+ }
41
+ export function writeSettledProviderFlowHandleId(cache, { command, flowCommandSequence, flowHandleCacheEpoch, settlementResult, }) {
42
+ const flowId = toCommandFlowId(command);
43
+ const flowHandleId = toSettledFlowHandleId(settlementResult);
44
+ const canWriteFlowHandle = flowId &&
45
+ flowHandleId &&
46
+ flowHandleCacheEpoch === cache.epoch &&
47
+ flowCommandSequence === cache.flowCommandSequencesByFlowId.get(flowId);
48
+ if (!canWriteFlowHandle) {
49
+ return false;
50
+ }
51
+ cache.flowHandleIdsByFlowId.set(flowId, flowHandleId);
52
+ return true;
53
+ }
package/dist/version.js CHANGED
@@ -3,4 +3,4 @@ const reactNativeSdkVersion = typeof __GX_REACT_NATIVE_SDK_VERSION__ === "string
3
3
  : "";
4
4
  // Build scripts patch this fallback to the package version for published artifacts.
5
5
  // Source-linked workspace usage keeps the local fallback.
6
- export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "1.3.5";
6
+ export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "1.3.6";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getuserfeedback/react-native",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "description": "getuserfeedback React Native SDK",
5
5
  "keywords": [
6
6
  "getuserfeedback",