@getuserfeedback/react-native 2.0.11 → 2.0.12

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,9 +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, } from "./provider-command-helpers.js";
16
+ import { toCommandSettlementError, toReactNativeOneShotCommand, } from "./provider-command-helpers.js";
17
17
  import { useProviderCommandTransport } from "./provider-command-transport.js";
18
- import { clearProviderFlowHandleCache, createProviderFlowHandleCache, deleteCachedProviderFlowHandleId, deleteCachedProviderFlowId, getCachedProviderFlowHandleId, snapshotProviderFlowCommand, writeSettledProviderFlowHandleId, } from "./provider-flow-handle-cache.js";
19
18
  import { createProviderWidgetHostLifecycleController, HIDDEN_PROVIDER_WIDGET_HOST_VISIBILITY, } from "./provider-widget-host-lifecycle.js";
20
19
  import { ProviderWidgetHostOverlay, toProviderWidgetHostStyle, toProviderWidgetSheetHostLayoutPlan, } from "./provider-widget-host-overlay.js";
21
20
  import { REACT_NATIVE_SDK_VERSION } from "./version.js";
@@ -117,7 +116,6 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
117
116
  const [instanceId] = useState(() => { var _a; return (_a = normalizeOptionalString(instanceIdProp)) !== null && _a !== void 0 ? _a : createUniqueId("rn"); });
118
117
  const [widgetHostVisibility, setWidgetHostVisibility] = useState(HIDDEN_PROVIDER_WIDGET_HOST_VISIBILITY);
119
118
  const resolvedHostViewport = useResolvedHostViewport(hostViewport);
120
- const flowHandleCacheRef = useRef(createProviderFlowHandleCache());
121
119
  const initOptionsRef = useRef(initOptions);
122
120
  const configureOptionsRef = useRef(configureOptions);
123
121
  const initOptionsKey = useMemo(() => toJsonKey(initOptions), [initOptions]);
@@ -138,7 +136,6 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
138
136
  if (syncHostSourceKey(hostSourceKey)) {
139
137
  pausePendingCommandTimeouts();
140
138
  clearStartupQueuedKey();
141
- clearProviderFlowHandleCache(flowHandleCacheRef.current);
142
139
  }
143
140
  initOptionsRef.current = initOptions;
144
141
  configureOptionsRef.current = configureOptions;
@@ -165,7 +162,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
165
162
  requestId,
166
163
  idempotencyKey,
167
164
  clientMeta: CLIENT_META,
168
- command,
165
+ command: toReactNativeOneShotCommand(command),
169
166
  };
170
167
  const message = {
171
168
  kind: "enqueueCommand",
@@ -186,10 +183,7 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
186
183
  envelope: validatedMessage.envelope,
187
184
  message: validatedMessage,
188
185
  };
189
- const flowCommandSnapshot = snapshotProviderFlowCommand(flowHandleCacheRef.current, validatedMessage.envelope.command);
190
186
  const promise = createPendingCommandPromise({
191
- flowCommandSequence: flowCommandSnapshot.flowCommandSequence,
192
- flowHandleCacheEpoch: flowCommandSnapshot.flowHandleCacheEpoch,
193
187
  isStartup,
194
188
  message: validatedMessage,
195
189
  requestId,
@@ -204,7 +198,6 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
204
198
  registerNativeMessage,
205
199
  ]);
206
200
  const reissueDeliveredPendingActionCommands = useCallback(() => {
207
- var _a;
208
201
  const replacements = new Map();
209
202
  for (const [requestId, pendingCommand] of getPendingCommandEntries()) {
210
203
  if (pendingCommand.isStartup || pendingCommand.hostEpoch === null) {
@@ -215,14 +208,13 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
215
208
  pendingCommand.timeout = null;
216
209
  }
217
210
  const command = pendingCommand.result.envelope.command;
218
- const nextEnvelope = Object.assign(Object.assign({}, pendingCommand.result.envelope), { command: (_a = toRetryWithoutFlowHandle(command)) !== null && _a !== void 0 ? _a : command, requestId: createCommandRequestId() });
211
+ const nextEnvelope = Object.assign(Object.assign({}, pendingCommand.result.envelope), { command: toReactNativeOneShotCommand(command), requestId: createCommandRequestId() });
219
212
  const nextMessage = parseWebViewTransportNativeMessage({
220
213
  kind: "enqueueCommand",
221
214
  id: createTransportMessageId(),
222
215
  envelope: nextEnvelope,
223
216
  });
224
217
  const reissuedCommand = reissuePendingCommand({
225
- flowHandleCacheEpoch: flowHandleCacheRef.current.epoch,
226
218
  nextMessage,
227
219
  nextRequestId: nextEnvelope.requestId,
228
220
  nextResult: {
@@ -284,7 +276,6 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
284
276
  let didReissueDeliveredCommands = false;
285
277
  if (readyResult.didResetHostEpoch) {
286
278
  clearStartupQueuedKey();
287
- clearProviderFlowHandleCache(flowHandleCacheRef.current);
288
279
  didReissueDeliveredCommands = reissueDeliveredPendingActionCommands();
289
280
  }
290
281
  setWidgetHostVisibility((visibility) => toReadyVisibility(visibility, event));
@@ -313,7 +304,6 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
313
304
  const notReadyResult = markNotReady();
314
305
  if (notReadyResult.wasReady) {
315
306
  clearStartupQueuedKey();
316
- clearProviderFlowHandleCache(flowHandleCacheRef.current);
317
307
  reissueDeliveredPendingActionCommands();
318
308
  }
319
309
  setWidgetHostVisibility(HIDDEN_PROVIDER_WIDGET_HOST_VISIBILITY);
@@ -325,13 +315,9 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
325
315
  pausePendingCommandTimeouts,
326
316
  reissueDeliveredPendingActionCommands,
327
317
  ]);
328
- const deleteCachedFlowHandleId = useCallback((flowHandleId) => {
329
- deleteCachedProviderFlowHandleId(flowHandleCacheRef.current, flowHandleId);
330
- }, []);
331
318
  const handleFlowHandleInvalidated = useCallback((flowHandleId) => {
332
- deleteCachedFlowHandleId(flowHandleId);
333
319
  setWidgetHostVisibility((visibility) => clearFlowHandleFromVisibility(visibility, flowHandleId));
334
- }, [clearFlowHandleFromVisibility, deleteCachedFlowHandleId]);
320
+ }, [clearFlowHandleFromVisibility]);
335
321
  const handleInstanceFlowStateChanged = useCallback((detail) => {
336
322
  const visibility = toFlowStateVisibility(detail, instanceId);
337
323
  if (!visibility) {
@@ -369,33 +355,11 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
369
355
  if (pendingCommand.isStartup) {
370
356
  clearStartupQueuedKey();
371
357
  }
372
- const flowId = toCommandFlowId(pendingCommand.result.envelope.command);
373
- const isStaleFlowHandleError = error.code === "STALE_HANDLE" ||
374
- error.message.includes("flowHandleId is stale");
375
- if (flowId && isStaleFlowHandleError) {
376
- deleteCachedProviderFlowId(flowHandleCacheRef.current, flowId);
377
- }
378
- const retryCommand = isStaleFlowHandleError
379
- ? toRetryWithoutFlowHandle(pendingCommand.result.envelope.command)
380
- : null;
381
- if (retryCommand) {
382
- enqueueTransportCommand(retryCommand).then(pendingCommand.resolve, pendingCommand.reject);
383
- return;
384
- }
385
358
  pendingCommand.reject(error);
386
359
  }
387
360
  else {
388
361
  const settlement = message.event
389
362
  .detail;
390
- writeSettledProviderFlowHandleId(flowHandleCacheRef.current, {
391
- command: pendingCommand.result.envelope.command,
392
- flowCommandSequence: pendingCommand.flowCommandSequence,
393
- flowHandleCacheEpoch: pendingCommand.flowHandleCacheEpoch,
394
- settlementResult: settlement.result,
395
- });
396
- if (pendingCommand.result.envelope.command.kind === "reset") {
397
- clearProviderFlowHandleCache(flowHandleCacheRef.current);
398
- }
399
363
  const settledResult = Object.assign(Object.assign({}, pendingCommand.result), { settlement, settlementResult: settlement.result });
400
364
  pendingCommand.resolve(settledResult);
401
365
  }
@@ -403,7 +367,6 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
403
367
  }
404
368
  onWebMessage === null || onWebMessage === void 0 ? void 0 : onWebMessage(message);
405
369
  }, [
406
- enqueueTransportCommand,
407
370
  clearStartupQueuedKey,
408
371
  getCurrentHostEpoch,
409
372
  getPendingCommand,
@@ -441,7 +404,6 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
441
404
  return enqueueCommand({
442
405
  kind: "open",
443
406
  flowId: normalizedFlowId,
444
- flowHandleId: getCachedProviderFlowHandleId(flowHandleCacheRef.current, normalizedFlowId),
445
407
  hideCloseButton: options === null || options === void 0 ? void 0 : options.hideCloseButton,
446
408
  }, commandOptions);
447
409
  },
@@ -450,7 +412,6 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
450
412
  return enqueueCommand({
451
413
  kind: "prefetch",
452
414
  flowId: normalizedFlowId,
453
- flowHandleId: getCachedProviderFlowHandleId(flowHandleCacheRef.current, normalizedFlowId),
454
415
  }, options);
455
416
  },
456
417
  prerender: (flowId, options, commandOptions) => {
@@ -458,7 +419,6 @@ export function GetUserFeedbackProvider({ autoInit = true, children, commandTime
458
419
  return enqueueCommand({
459
420
  kind: "prerender",
460
421
  flowId: normalizedFlowId,
461
- flowHandleId: getCachedProviderFlowHandleId(flowHandleCacheRef.current, normalizedFlowId),
462
422
  hideCloseButton: options === null || options === void 0 ? void 0 : options.hideCloseButton,
463
423
  }, commandOptions);
464
424
  },
@@ -7,8 +7,6 @@ export type CommandSettledEvent = Extract<WebViewTransportHostEvent, {
7
7
  export type CommandSettledSuccessDetail = Extract<CommandSettledEvent["detail"], {
8
8
  ok: true;
9
9
  }>;
10
- export declare function toSettledFlowHandleId(result: unknown): string | undefined;
11
- export declare function toCommandFlowId(command: ReactNativeWidgetCommand): string | undefined;
12
- export declare function toRetryWithoutFlowHandle(command: ReactNativeWidgetCommand): ReactNativeWidgetCommand | null;
10
+ export declare function toReactNativeOneShotCommand(command: ReactNativeWidgetCommand): ReactNativeWidgetCommand;
13
11
  export declare function toCommandSettlementError(event: CommandSettledEvent): CommandSettlementError | null;
14
12
  export {};
@@ -1,30 +1,27 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
1
12
  import { CommandSettlementError } from "@getuserfeedback/protocol/host";
2
13
  function isReactNativeFlowCommand(command) {
3
14
  return (command.kind === "open" ||
4
15
  command.kind === "prefetch" ||
5
16
  command.kind === "prerender");
6
17
  }
7
- export function toSettledFlowHandleId(result) {
8
- if (typeof result !== "object" || result === null) {
9
- return undefined;
10
- }
11
- const flowHandleId = result.flowHandleId;
12
- return typeof flowHandleId === "string" && flowHandleId.trim().length > 0
13
- ? flowHandleId
14
- : undefined;
15
- }
16
- export function toCommandFlowId(command) {
17
- if (!isReactNativeFlowCommand(command)) {
18
- return undefined;
19
- }
20
- return command.flowId;
21
- }
22
- export function toRetryWithoutFlowHandle(command) {
18
+ export function toReactNativeOneShotCommand(command) {
23
19
  if (!isReactNativeFlowCommand(command) ||
24
20
  command.flowHandleId === undefined) {
25
- return null;
21
+ return command;
26
22
  }
27
- return Object.assign(Object.assign({}, command), { flowHandleId: undefined });
23
+ const { flowHandleId: _flowHandleId } = command, commandWithoutFlowHandle = __rest(command, ["flowHandleId"]);
24
+ return commandWithoutFlowHandle;
28
25
  }
29
26
  export function toCommandSettlementError(event) {
30
27
  if (event.detail.ok) {
@@ -6,15 +6,12 @@ export type ProviderCommandTransportOptions = {
6
6
  getCurrentHostEpoch: () => number | null;
7
7
  };
8
8
  type ProviderPendingCommandRegistration<Result> = {
9
- flowCommandSequence: number | null;
10
- flowHandleCacheEpoch: number;
11
9
  isStartup: boolean;
12
10
  message: WebViewTransportNativeMessage;
13
11
  requestId: string;
14
12
  result: Result;
15
13
  };
16
14
  type ProviderPendingCommandReissue<Result> = {
17
- flowHandleCacheEpoch: number;
18
15
  nextMessage: WebViewTransportNativeMessage;
19
16
  nextRequestId: string;
20
17
  nextResult: Result;
@@ -56,10 +56,8 @@ export function useProviderCommandTransport({ commandTimeoutMs, createTimeoutErr
56
56
  pendingCommand.timeout = null;
57
57
  }
58
58
  }, []);
59
- const createPendingCommandPromise = useCallback(({ flowCommandSequence, flowHandleCacheEpoch, isStartup, message, requestId, result, }) => new Promise((resolve, reject) => {
59
+ const createPendingCommandPromise = useCallback(({ isStartup, message, requestId, result, }) => new Promise((resolve, reject) => {
60
60
  const pendingCommand = {
61
- flowCommandSequence,
62
- flowHandleCacheEpoch,
63
61
  hostEpoch: null,
64
62
  isStartup,
65
63
  messageId: message.id,
@@ -79,9 +77,8 @@ export function useProviderCommandTransport({ commandTimeoutMs, createTimeoutErr
79
77
  const replaceNativeMessages = useCallback((replacements) => {
80
78
  setNativeMessages((messages) => replaceProviderNativeMessages(messages, replacements));
81
79
  }, []);
82
- const reissuePendingCommand = useCallback(({ flowHandleCacheEpoch, nextMessage, nextRequestId, nextResult, requestId, }) => {
80
+ const reissuePendingCommand = useCallback(({ nextMessage, nextRequestId, nextResult, requestId, }) => {
83
81
  const reissuedCommand = reissueProviderPendingCommand(pendingCommandsRef.current, {
84
- flowHandleCacheEpoch,
85
82
  nextMessageId: nextMessage.id,
86
83
  nextRequestId,
87
84
  nextResult,
@@ -1,6 +1,4 @@
1
1
  export type ProviderPendingCommand<Result> = {
2
- flowCommandSequence: number | null;
3
- flowHandleCacheEpoch: number;
4
2
  hostEpoch: number | null;
5
3
  isStartup: boolean;
6
4
  messageId: string;
@@ -27,8 +25,7 @@ export declare function isProviderPendingMessageStartup<Result>(registry: Provid
27
25
  export declare function getProviderPendingCommandEntries<Result>(registry: ProviderPendingCommandRegistry<Result>): Array<[string, ProviderPendingCommand<Result>]>;
28
26
  export declare function getProviderPendingCommands<Result>(registry: ProviderPendingCommandRegistry<Result>): ProviderPendingCommand<Result>[];
29
27
  export declare function cancelProviderStartupCommands<Result>(registry: ProviderPendingCommandRegistry<Result>): ProviderCanceledStartupCommands<Result>;
30
- export declare function reissueProviderPendingCommand<Result>(registry: ProviderPendingCommandRegistry<Result>, { flowHandleCacheEpoch, nextMessageId, nextRequestId, nextResult, requestId, }: {
31
- flowHandleCacheEpoch: number;
28
+ export declare function reissueProviderPendingCommand<Result>(registry: ProviderPendingCommandRegistry<Result>, { nextMessageId, nextRequestId, nextResult, requestId, }: {
32
29
  nextMessageId: string;
33
30
  nextRequestId: string;
34
31
  nextResult: Result;
@@ -40,14 +40,13 @@ export function cancelProviderStartupCommands(registry) {
40
40
  }
41
41
  return { commands, messageIds };
42
42
  }
43
- export function reissueProviderPendingCommand(registry, { flowHandleCacheEpoch, nextMessageId, nextRequestId, nextResult, requestId, }) {
43
+ export function reissueProviderPendingCommand(registry, { nextMessageId, nextRequestId, nextResult, requestId, }) {
44
44
  const command = registry.get(requestId);
45
45
  if (!command || command.isStartup || command.hostEpoch === null) {
46
46
  return null;
47
47
  }
48
48
  registry.delete(requestId);
49
49
  const previousMessageId = command.messageId;
50
- command.flowHandleCacheEpoch = flowHandleCacheEpoch;
51
50
  command.hostEpoch = null;
52
51
  command.messageId = nextMessageId;
53
52
  command.result = nextResult;
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 : "2.0.11";
6
+ export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "2.0.12";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getuserfeedback/react-native",
3
- "version": "2.0.11",
3
+ "version": "2.0.12",
4
4
  "description": "getuserfeedback React Native SDK",
5
5
  "keywords": [
6
6
  "getuserfeedback",
@@ -44,8 +44,8 @@
44
44
  "lint": "biome check ."
45
45
  },
46
46
  "dependencies": {
47
- "@getuserfeedback/protocol": "^3.1.0",
48
- "@getuserfeedback/sdk": "^0.8.17",
47
+ "@getuserfeedback/protocol": "^3.1.1",
48
+ "@getuserfeedback/sdk": "^0.8.18",
49
49
  "robot3": "^1.2.0"
50
50
  },
51
51
  "peerDependencies": {
@@ -1,24 +0,0 @@
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 {};
@@ -1,53 +0,0 @@
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
- }