@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 +23 -44
- package/dist/provider-flow-handle-cache.d.ts +24 -0
- package/dist/provider-flow-handle-cache.js +53 -0
- package/dist/version.js +1 -1
- package/package.json +1 -1
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,
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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:
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
6
|
+
export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "1.3.6";
|