@getuserfeedback/react-native 4.0.31 → 5.0.7
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 +12 -150
- package/dist/client.d.ts +64 -0
- package/dist/client.js +1 -0
- package/dist/core-webview-host.d.ts +0 -1
- package/dist/core-webview-host.js +2 -12
- package/dist/native-core-command-channel.d.ts +1 -0
- package/dist/native-core-command-channel.js +20 -4
- package/dist/native-provider-client-controller.d.ts +11 -0
- package/dist/native-provider-client-controller.js +38 -0
- package/dist/native-provider-client.d.ts +3 -17
- package/dist/native-provider-command-controller.d.ts +19 -0
- package/dist/native-provider-command-controller.js +79 -0
- package/dist/native-provider-flow-registry.d.ts +7 -0
- package/dist/native-provider-flow-registry.js +70 -0
- package/dist/native-provider.d.ts +32 -0
- package/dist/native-provider.js +88 -0
- package/dist/native-runtime-root.d.ts +2 -4
- package/dist/native-runtime-root.js +6 -3
- package/dist/native-view-host-projection.d.ts +1 -2
- package/dist/native-view-host-projection.js +22 -6
- package/dist/native-view-presentation-surface.js +6 -1
- package/dist/native-view-record-controller.d.ts +9 -3
- package/dist/native-view-record-controller.js +276 -50
- package/dist/native-widget-corner-radii.d.ts +1 -2
- package/dist/native-widget-corner-radii.js +1 -1
- package/dist/provider-command-helpers.d.ts +1 -11
- package/dist/provider-command-helpers.js +1 -38
- package/dist/public-api.d.ts +2 -1
- package/dist/public-api.js +2 -1
- package/dist/runtime-endpoints.d.ts +2 -0
- package/dist/runtime-endpoints.js +2 -0
- package/dist/version.js +1 -1
- package/dist/view-orchestration-runtime.js +11 -43
- package/dist/view-webview-host-controller.d.ts +1 -0
- package/dist/view-webview-host-controller.js +1 -0
- package/dist/view-webview-host.d.ts +1 -1
- package/dist/view-webview-host.js +3 -7
- package/dist/webview-document-host.d.ts +2 -3
- package/dist/webview-document-host.js +21 -33
- package/package.json +3 -3
- package/dist/host-viewport.d.ts +0 -3
- package/dist/host-viewport.js +0 -69
- package/dist/index.d.ts +0 -91
- package/dist/index.js +0 -613
- package/dist/provider-command-transport.d.ts +0 -52
- package/dist/provider-command-transport.js +0 -150
- package/dist/provider-message-queue.d.ts +0 -11
- package/dist/provider-message-queue.js +0 -23
- package/dist/provider-pending-commands.d.ts +0 -34
- package/dist/provider-pending-commands.js +0 -58
- package/dist/provider-widget-border-radius.d.ts +0 -11
- package/dist/provider-widget-border-radius.js +0 -102
- package/dist/provider-widget-frame-appearance.d.ts +0 -17
- package/dist/provider-widget-frame-appearance.js +0 -43
- package/dist/provider-widget-host-lifecycle.d.ts +0 -46
- package/dist/provider-widget-host-lifecycle.js +0 -138
- package/dist/provider-widget-host-overlay.d.ts +0 -58
- package/dist/provider-widget-host-overlay.js +0 -616
- package/dist/use-native-direct-command-session-controller.d.ts +0 -2
- package/dist/use-native-direct-command-session-controller.js +0 -21
- package/dist/webview-bridge-script.d.ts +0 -16
- package/dist/webview-bridge-script.js +0 -283
- package/dist/widget-host-lifecycle-machine.d.ts +0 -35
- package/dist/widget-host-lifecycle-machine.js +0 -37
- package/dist/widget-host.d.ts +0 -38
- package/dist/widget-host.js +0 -327
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { coreViewHostActionSchema, } from "@getuserfeedback/protocol/internal/core-view-host-actions";
|
|
2
2
|
import { actionRequestCloseViewSchema, actionViewConnectSchema, buildEventLayoutTransactionCommitted, buildEventViewSize, eventViewSizeSchema, } from "@getuserfeedback/protocol/internal/view-host-control-messages";
|
|
3
|
-
import { buildEventViewClosed, buildEventViewPrerendered, } from "@getuserfeedback/protocol/internal/view-host-lifecycle-events";
|
|
3
|
+
import { buildEventViewActivated, buildEventViewAllocationFailed, buildEventViewClosed, buildEventViewCloseFailed, buildEventViewPrerendered, } from "@getuserfeedback/protocol/internal/view-host-lifecycle-events";
|
|
4
4
|
import { bindViewHostControlEnvelope, bindViewToCoreRelayEnvelope, parseCoreToViewRelayEnvelope, } from "@getuserfeedback/protocol/internal/view-relay-contract";
|
|
5
5
|
import { createViewPreparationReadinessRegistry, createViewPreparationRegistry, } from "./view-orchestration-runtime.js";
|
|
6
6
|
const createNativeViewReadinessRegistry = () => createViewPreparationReadinessRegistry();
|
|
7
|
+
class NativeViewCleanupError extends Error {
|
|
8
|
+
constructor(resourceErrors, observerErrors, viewId) {
|
|
9
|
+
super(`Native view cleanup failed for viewId=${viewId}`);
|
|
10
|
+
this.resourceErrors = resourceErrors;
|
|
11
|
+
this.observerErrors = observerErrors;
|
|
12
|
+
this.name = "NativeViewCleanupError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
7
15
|
export function createNativeViewRecordController(input) {
|
|
8
16
|
const entries = new Map();
|
|
9
17
|
const listeners = new Set();
|
|
@@ -21,7 +29,19 @@ export function createNativeViewRecordController(input) {
|
|
|
21
29
|
}
|
|
22
30
|
};
|
|
23
31
|
const failCoreConnection = (error, fallbackMessage) => {
|
|
32
|
+
if (coreConnectionFailed) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
24
35
|
coreConnectionFailed = true;
|
|
36
|
+
preparations.cancelAll();
|
|
37
|
+
for (const entry of Array.from(entries.values())) {
|
|
38
|
+
try {
|
|
39
|
+
removeEntry(entry);
|
|
40
|
+
}
|
|
41
|
+
catch (cleanupError) {
|
|
42
|
+
reportError(cleanupError, "Native terminal projection cleanup failed");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
25
45
|
try {
|
|
26
46
|
input.coreConnection.disconnect();
|
|
27
47
|
}
|
|
@@ -43,24 +63,158 @@ export function createNativeViewRecordController(input) {
|
|
|
43
63
|
return false;
|
|
44
64
|
}
|
|
45
65
|
const detachViewConnection = entry.viewConnectionDetach;
|
|
66
|
+
const resourceErrors = [];
|
|
67
|
+
const observerErrors = [];
|
|
68
|
+
try {
|
|
69
|
+
detachViewConnection === null || detachViewConnection === void 0 ? void 0 : detachViewConnection();
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error instanceof NativeViewCleanupError) {
|
|
73
|
+
resourceErrors.push(...error.resourceErrors);
|
|
74
|
+
observerErrors.push(...error.observerErrors);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
resourceErrors.push(error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
46
80
|
entry.viewConnectionDetach = null;
|
|
47
|
-
|
|
81
|
+
entry.viewConnection = null;
|
|
82
|
+
entry.isViewConnected = false;
|
|
83
|
+
entry.isViewRelayDraining = false;
|
|
84
|
+
entry.committedLayoutReportOccurrence = null;
|
|
85
|
+
entry.pendingCoreToViewMessages.length = 0;
|
|
86
|
+
entry.size = null;
|
|
48
87
|
entries.delete(entry.viewId);
|
|
49
88
|
if (!disposed) {
|
|
50
|
-
|
|
89
|
+
try {
|
|
90
|
+
notify();
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
observerErrors.push(error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (resourceErrors.length > 0 || observerErrors.length > 0) {
|
|
97
|
+
throw new NativeViewCleanupError(resourceErrors, observerErrors, entry.viewId);
|
|
51
98
|
}
|
|
52
99
|
return true;
|
|
53
100
|
};
|
|
54
101
|
const closeEntry = (entry) => {
|
|
55
102
|
if (entries.get(entry.viewId) !== entry) {
|
|
103
|
+
return { closed: false, resourceErrors: [], observerErrors: [] };
|
|
104
|
+
}
|
|
105
|
+
const resourceErrors = [];
|
|
106
|
+
const observerErrors = [];
|
|
107
|
+
const collectCleanupError = (error) => {
|
|
108
|
+
if (error instanceof NativeViewCleanupError) {
|
|
109
|
+
resourceErrors.push(...error.resourceErrors);
|
|
110
|
+
observerErrors.push(...error.observerErrors);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
resourceErrors.push(error);
|
|
114
|
+
};
|
|
115
|
+
try {
|
|
116
|
+
const cancellation = preparations.cancelWithResult(entry.viewId);
|
|
117
|
+
for (const error of cancellation.cleanupErrors) {
|
|
118
|
+
collectCleanupError(error);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
collectCleanupError(error);
|
|
123
|
+
}
|
|
124
|
+
if (entries.get(entry.viewId) === entry) {
|
|
125
|
+
try {
|
|
126
|
+
removeEntry(entry);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
collectCleanupError(error);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
closed: entries.get(entry.viewId) !== entry,
|
|
134
|
+
resourceErrors,
|
|
135
|
+
observerErrors,
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
const toFailureMessage = (error, fallback) => {
|
|
139
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
140
|
+
const trimmed = message.trim() || fallback;
|
|
141
|
+
return trimmed.slice(0, 255);
|
|
142
|
+
};
|
|
143
|
+
const toResourceCleanupError = (viewId, errors) => new Error(`Native view resource cleanup failed for viewId=${viewId}`, {
|
|
144
|
+
cause: errors[0],
|
|
145
|
+
});
|
|
146
|
+
const postViewCloseFailure = (action, reason, message) => {
|
|
147
|
+
try {
|
|
148
|
+
input.coreConnection.transport.postMessage(buildEventViewCloseFailed({
|
|
149
|
+
gen: action.gen,
|
|
150
|
+
viewId: action.viewId,
|
|
151
|
+
closeAttemptId: action.closeAttemptId,
|
|
152
|
+
reason,
|
|
153
|
+
message: toFailureMessage(message, "Native view close failed"),
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
failCoreConnection(error, "Native view close failure delivery failed");
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
const failAllocation = (entry, allocationError) => {
|
|
161
|
+
const resourceErrors = [];
|
|
162
|
+
const observerErrors = [];
|
|
163
|
+
const collectCleanupError = (error) => {
|
|
164
|
+
if (error instanceof NativeViewCleanupError) {
|
|
165
|
+
resourceErrors.push(...error.resourceErrors);
|
|
166
|
+
observerErrors.push(...error.observerErrors);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
resourceErrors.push(error);
|
|
170
|
+
};
|
|
171
|
+
try {
|
|
172
|
+
const cancellation = preparations.cancelWithResult(entry.viewId);
|
|
173
|
+
for (const error of cancellation.cleanupErrors) {
|
|
174
|
+
collectCleanupError(error);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
collectCleanupError(error);
|
|
179
|
+
}
|
|
180
|
+
if (entries.get(entry.viewId) === entry) {
|
|
181
|
+
try {
|
|
182
|
+
removeEntry(entry);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
collectCleanupError(error);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
for (const error of observerErrors) {
|
|
189
|
+
reportError(error, "Native view allocation cleanup observer failed");
|
|
190
|
+
}
|
|
191
|
+
if (resourceErrors.length > 0 ||
|
|
192
|
+
entries.get(entry.viewId) === entry ||
|
|
193
|
+
preparations.has(entry.viewId)) {
|
|
194
|
+
failCoreConnection(new Error(`Native view allocation cleanup failed for viewId=${entry.viewId}: ${allocationError instanceof Error
|
|
195
|
+
? allocationError.message
|
|
196
|
+
: String(allocationError)}`), "Native view allocation cleanup failed");
|
|
56
197
|
return;
|
|
57
198
|
}
|
|
58
|
-
|
|
59
|
-
|
|
199
|
+
try {
|
|
200
|
+
input.coreConnection.transport.postMessage(buildEventViewAllocationFailed({
|
|
201
|
+
gen: entry.generation,
|
|
202
|
+
viewId: entry.viewId,
|
|
203
|
+
flowRunId: entry.flowRunId,
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
failCoreConnection(error, "Native view allocation failure delivery failed");
|
|
60
208
|
}
|
|
61
209
|
};
|
|
62
210
|
const handlePrerender = (action) => {
|
|
63
|
-
|
|
211
|
+
const existing = entries.get(action.viewId);
|
|
212
|
+
if (existing) {
|
|
213
|
+
if (existing.generation !== action.gen ||
|
|
214
|
+
existing.instanceId !== action.instanceId ||
|
|
215
|
+
existing.flowRunId !== action.flowRunId) {
|
|
216
|
+
failCoreConnection(new Error(`Conflicting native projection binding ${action.viewId}`), "Conflicting native projection binding");
|
|
217
|
+
}
|
|
64
218
|
return;
|
|
65
219
|
}
|
|
66
220
|
const preparation = preparations.claim(action.viewId);
|
|
@@ -71,14 +225,15 @@ export function createNativeViewRecordController(input) {
|
|
|
71
225
|
const entry = {
|
|
72
226
|
allocationId: nextAllocationId,
|
|
73
227
|
generation: action.gen,
|
|
228
|
+
flowRunId: action.flowRunId,
|
|
74
229
|
instanceId: action.instanceId,
|
|
75
230
|
isActive: false,
|
|
76
231
|
isClosing: false,
|
|
77
232
|
isPreparationCommitted: false,
|
|
233
|
+
isPresentationAcknowledged: false,
|
|
78
234
|
isViewConnected: false,
|
|
79
235
|
isViewRelayDraining: false,
|
|
80
236
|
layoutReportRevision: 0,
|
|
81
|
-
openRequest: toOpenRequestMetadata(action.openRequest),
|
|
82
237
|
pendingCoreToViewMessages: [],
|
|
83
238
|
preparation,
|
|
84
239
|
size: null,
|
|
@@ -89,28 +244,58 @@ export function createNativeViewRecordController(input) {
|
|
|
89
244
|
viewId: action.viewId,
|
|
90
245
|
};
|
|
91
246
|
entries.set(action.viewId, entry);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
247
|
+
try {
|
|
248
|
+
preparation.addCleanup(() => {
|
|
249
|
+
removeEntry(entry);
|
|
250
|
+
});
|
|
251
|
+
notify();
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
failAllocation(entry, error);
|
|
255
|
+
}
|
|
96
256
|
};
|
|
97
257
|
const handleActivate = (action) => {
|
|
98
258
|
const entry = entries.get(action.viewId);
|
|
99
|
-
if (!entry
|
|
259
|
+
if (!entry ||
|
|
260
|
+
entry.instanceId !== action.instanceId ||
|
|
261
|
+
entry.flowRunId !== action.flowRunId) {
|
|
262
|
+
failCoreConnection(new Error(`Unknown native projection binding ${action.viewId}`), "Unknown native projection binding");
|
|
100
263
|
return;
|
|
101
264
|
}
|
|
102
|
-
|
|
103
|
-
const openRequestChanged = !areOpenRequestsEqual(entry.openRequest, openRequest);
|
|
104
|
-
entry.openRequest = openRequest;
|
|
105
|
-
if (!entry.isActive || openRequestChanged) {
|
|
265
|
+
if (!entry.isActive) {
|
|
106
266
|
entry.isActive = true;
|
|
107
267
|
notify();
|
|
108
268
|
}
|
|
109
269
|
};
|
|
110
270
|
const handleClose = (action) => {
|
|
111
271
|
const entry = entries.get(action.viewId);
|
|
112
|
-
if (entry) {
|
|
113
|
-
|
|
272
|
+
if (!entry) {
|
|
273
|
+
postViewCloseFailure(action, "unknown-occurrence", `Unknown native view occurrence ${action.viewId}`);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
entry.isClosing = true;
|
|
277
|
+
const closeResult = closeEntry(entry);
|
|
278
|
+
if (!closeResult.closed || closeResult.resourceErrors.length > 0) {
|
|
279
|
+
if (closeResult.resourceErrors.length > 0) {
|
|
280
|
+
failCoreConnection(toResourceCleanupError(entry.viewId, closeResult.resourceErrors), "Native view resource cleanup failed");
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
postViewCloseFailure(action, "close-failed", "Native view occurrence could not be retired");
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
input.coreConnection.transport.postMessage(buildEventViewClosed({
|
|
288
|
+
gen: action.gen,
|
|
289
|
+
reason: "user",
|
|
290
|
+
viewId: action.viewId,
|
|
291
|
+
}));
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
failCoreConnection(error, "Native view close delivery failed");
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (closeResult.observerErrors.length > 0) {
|
|
298
|
+
reportError(closeResult.observerErrors[0], "Native view close cleanup failed");
|
|
114
299
|
}
|
|
115
300
|
};
|
|
116
301
|
const drainCoreToViewMessages = (entry) => {
|
|
@@ -197,6 +382,19 @@ export function createNativeViewRecordController(input) {
|
|
|
197
382
|
entry.isClosing = true;
|
|
198
383
|
try {
|
|
199
384
|
input.coreConnection.transport.postMessage(Object.assign(Object.assign({}, request), { viewId: entry.viewId }));
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
failCoreConnection(error, "Native view close delivery failed");
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const closeResult = closeEntry(entry);
|
|
391
|
+
if (!closeResult.closed || closeResult.resourceErrors.length > 0) {
|
|
392
|
+
if (closeResult.resourceErrors.length > 0) {
|
|
393
|
+
failCoreConnection(toResourceCleanupError(entry.viewId, closeResult.resourceErrors), "Native view resource cleanup failed");
|
|
394
|
+
}
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
try {
|
|
200
398
|
input.coreConnection.transport.postMessage(buildEventViewClosed({
|
|
201
399
|
gen: entry.generation,
|
|
202
400
|
reason: "user",
|
|
@@ -207,15 +405,23 @@ export function createNativeViewRecordController(input) {
|
|
|
207
405
|
failCoreConnection(error, "Native view close delivery failed");
|
|
208
406
|
return;
|
|
209
407
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
catch (error) {
|
|
214
|
-
reportError(error, "Native view close cleanup failed");
|
|
408
|
+
if (closeResult.observerErrors.length > 0) {
|
|
409
|
+
reportError(closeResult.observerErrors[0], "Native view close cleanup failed");
|
|
215
410
|
}
|
|
216
411
|
};
|
|
217
412
|
const stopCoreTransport = input.coreConnection.transport.subscribe(handleCoreMessage);
|
|
218
413
|
return {
|
|
414
|
+
failViewAllocation({ allocationId, error, viewId }) {
|
|
415
|
+
const entry = entries.get(viewId);
|
|
416
|
+
if (!entry || entry.allocationId !== allocationId) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
if (entry.isPreparationCommitted) {
|
|
420
|
+
failCoreConnection(error, "Native view failed after allocation completed");
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
failAllocation(entry, error);
|
|
424
|
+
},
|
|
219
425
|
commitViewLayoutTransaction({ allocationId, layoutReportRevision, layoutTransactionId, viewId, }) {
|
|
220
426
|
var _a, _b;
|
|
221
427
|
if (coreConnectionFailed || disposed) {
|
|
@@ -249,6 +455,34 @@ export function createNativeViewRecordController(input) {
|
|
|
249
455
|
failCoreConnection(error, "Native view layout commit delivery failed");
|
|
250
456
|
}
|
|
251
457
|
},
|
|
458
|
+
acknowledgeViewPresentation({ allocationId, viewId }) {
|
|
459
|
+
if (coreConnectionFailed || disposed) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
const entry = entries.get(viewId);
|
|
463
|
+
if (!entry ||
|
|
464
|
+
entry.allocationId !== allocationId ||
|
|
465
|
+
entry.isClosing ||
|
|
466
|
+
!entry.isActive ||
|
|
467
|
+
!entry.isPreparationCommitted ||
|
|
468
|
+
!entry.isViewConnected ||
|
|
469
|
+
entry.viewConnection === null ||
|
|
470
|
+
entry.viewConnectionDetach === null ||
|
|
471
|
+
entry.size === null ||
|
|
472
|
+
entry.isPresentationAcknowledged) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
entry.isPresentationAcknowledged = true;
|
|
476
|
+
try {
|
|
477
|
+
input.coreConnection.transport.postMessage(buildEventViewActivated({
|
|
478
|
+
gen: entry.generation,
|
|
479
|
+
viewId: entry.viewId,
|
|
480
|
+
}));
|
|
481
|
+
}
|
|
482
|
+
catch (error) {
|
|
483
|
+
reportError(error, "Native view activation delivery failed");
|
|
484
|
+
}
|
|
485
|
+
},
|
|
252
486
|
attachViewConnection({ allocationId, connection }) {
|
|
253
487
|
if (coreConnectionFailed || disposed) {
|
|
254
488
|
return null;
|
|
@@ -281,7 +515,12 @@ export function createNativeViewRecordController(input) {
|
|
|
281
515
|
if (entry.size !== null) {
|
|
282
516
|
entry.size = null;
|
|
283
517
|
if (!disposed && entries.get(viewId) === entry) {
|
|
284
|
-
|
|
518
|
+
try {
|
|
519
|
+
notify();
|
|
520
|
+
}
|
|
521
|
+
catch (error) {
|
|
522
|
+
throw new NativeViewCleanupError([], [error], viewId);
|
|
523
|
+
}
|
|
285
524
|
}
|
|
286
525
|
}
|
|
287
526
|
}
|
|
@@ -313,8 +552,15 @@ export function createNativeViewRecordController(input) {
|
|
|
313
552
|
if (connected.success) {
|
|
314
553
|
if (connected.data.gen === input.coreConnection.generation &&
|
|
315
554
|
connected.data.viewId === viewId) {
|
|
555
|
+
const wasViewConnected = entry.isViewConnected;
|
|
316
556
|
entry.isViewConnected = true;
|
|
317
557
|
drainCoreToViewMessages(entry);
|
|
558
|
+
if (!wasViewConnected &&
|
|
559
|
+
!coreConnectionFailed &&
|
|
560
|
+
!disposed &&
|
|
561
|
+
entries.get(viewId) === entry) {
|
|
562
|
+
notify();
|
|
563
|
+
}
|
|
318
564
|
}
|
|
319
565
|
return;
|
|
320
566
|
}
|
|
@@ -417,7 +663,12 @@ export function createNativeViewRecordController(input) {
|
|
|
417
663
|
stopCoreTransport();
|
|
418
664
|
preparations.cancelAll();
|
|
419
665
|
for (const entry of Array.from(entries.values())) {
|
|
420
|
-
|
|
666
|
+
try {
|
|
667
|
+
removeEntry(entry);
|
|
668
|
+
}
|
|
669
|
+
catch (error) {
|
|
670
|
+
reportError(error, "Native view disposal cleanup failed");
|
|
671
|
+
}
|
|
421
672
|
}
|
|
422
673
|
if (hadEntries) {
|
|
423
674
|
snapshot = Object.freeze([]);
|
|
@@ -441,38 +692,13 @@ function toRecord(entry) {
|
|
|
441
692
|
return Object.freeze({
|
|
442
693
|
allocationId: entry.allocationId,
|
|
443
694
|
generation: entry.generation,
|
|
444
|
-
instanceId: entry.instanceId,
|
|
445
695
|
isActive: entry.isActive,
|
|
446
696
|
layoutReportRevision: entry.layoutReportRevision,
|
|
447
|
-
openRequest: entry.openRequest,
|
|
448
697
|
size: entry.size,
|
|
449
698
|
srcdoc: entry.srcdoc,
|
|
450
699
|
viewId: entry.viewId,
|
|
451
700
|
});
|
|
452
701
|
}
|
|
453
|
-
function toOpenRequestMetadata(openRequest) {
|
|
454
|
-
return openRequest === undefined
|
|
455
|
-
? undefined
|
|
456
|
-
: Object.freeze(Object.assign({}, openRequest));
|
|
457
|
-
}
|
|
458
|
-
function areOpenRequestsEqual(left, right) {
|
|
459
|
-
if (left === right) {
|
|
460
|
-
return true;
|
|
461
|
-
}
|
|
462
|
-
if (!left || !right || left.source !== right.source) {
|
|
463
|
-
return false;
|
|
464
|
-
}
|
|
465
|
-
if (left.source === "targeting" && right.source === "targeting") {
|
|
466
|
-
return left.flowId === right.flowId;
|
|
467
|
-
}
|
|
468
|
-
if (left.source !== "command" || right.source !== "command") {
|
|
469
|
-
return false;
|
|
470
|
-
}
|
|
471
|
-
return (left.flowId === right.flowId &&
|
|
472
|
-
left.requestId === right.requestId &&
|
|
473
|
-
left.flowHandleId === right.flowHandleId &&
|
|
474
|
-
left.hideCloseButton === right.hideCloseButton);
|
|
475
|
-
}
|
|
476
702
|
function toViewSizeReport(event) {
|
|
477
703
|
return {
|
|
478
704
|
width: event.width,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WidgetFrameAppearance
|
|
1
|
+
import type { WidgetFrameAppearance } from "@getuserfeedback/protocol/host";
|
|
2
2
|
export type NativeWidgetCornerRadii = {
|
|
3
3
|
bottomLeft: number;
|
|
4
4
|
bottomRight: number;
|
|
@@ -6,5 +6,4 @@ export type NativeWidgetCornerRadii = {
|
|
|
6
6
|
topRight: number;
|
|
7
7
|
};
|
|
8
8
|
export declare function safeParseNativeWidgetCanonicalRadii(value: string): NativeWidgetCornerRadii | undefined;
|
|
9
|
-
export declare function toNativeWidgetConservativeResolvedCornerRadii(resolved: WidgetFrameResolvedBorderRadius): NativeWidgetCornerRadii;
|
|
10
9
|
export declare function toNativeWidgetCornerRadii(appearance?: WidgetFrameAppearance): NativeWidgetCornerRadii;
|
|
@@ -31,7 +31,7 @@ export function safeParseNativeWidgetCanonicalRadii(value) {
|
|
|
31
31
|
}
|
|
32
32
|
return { bottomLeft, bottomRight, topLeft, topRight };
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
function toNativeWidgetConservativeResolvedCornerRadii(resolved) {
|
|
35
35
|
// React Native exposes one scalar per corner, so use a smaller circle that
|
|
36
36
|
// does not exceed the authored ellipse on either axis.
|
|
37
37
|
return {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ClientMeta } from "@getuserfeedback/protocol";
|
|
2
|
-
import {
|
|
3
|
-
import type { WebViewCommandEnvelope, WebViewTransportHostEvent } from "@getuserfeedback/protocol/webview-transport";
|
|
2
|
+
import type { WebViewCommandEnvelope } from "@getuserfeedback/protocol/webview-transport";
|
|
4
3
|
type ReactNativeWidgetCommand = WebViewCommandEnvelope["command"];
|
|
5
4
|
type ReactNativeInitCommand = Extract<ReactNativeWidgetCommand, {
|
|
6
5
|
kind: "init";
|
|
@@ -9,7 +8,6 @@ type ReactNativeConfigureCommand = Extract<ReactNativeWidgetCommand, {
|
|
|
9
8
|
kind: "configure";
|
|
10
9
|
}>;
|
|
11
10
|
export declare const REACT_NATIVE_CLIENT_META: ClientMeta;
|
|
12
|
-
export declare const REACT_NATIVE_LOADER_CLIENT_META: ClientMeta;
|
|
13
11
|
type CreateProviderCommandEnvelopeInput = {
|
|
14
12
|
clientMeta?: ClientMeta;
|
|
15
13
|
command: ReactNativeWidgetCommand;
|
|
@@ -28,12 +26,4 @@ export declare function createProviderCommandEnvelope(input: CreateProviderComma
|
|
|
28
26
|
command: ReactNativeConfigureCommand;
|
|
29
27
|
};
|
|
30
28
|
export declare function createProviderCommandEnvelope(input: CreateProviderCommandEnvelopeInput): WebViewCommandEnvelope;
|
|
31
|
-
export type CommandSettledEvent = Extract<WebViewTransportHostEvent, {
|
|
32
|
-
name: "instance:command:settled";
|
|
33
|
-
}>;
|
|
34
|
-
export type CommandSettledSuccessDetail = Extract<CommandSettledEvent["detail"], {
|
|
35
|
-
ok: true;
|
|
36
|
-
}>;
|
|
37
|
-
export declare function toReactNativeOneShotCommand(command: ReactNativeWidgetCommand): ReactNativeWidgetCommand;
|
|
38
|
-
export declare function toCommandSettlementError(event: CommandSettledEvent): CommandSettlementError | null;
|
|
39
29
|
export {};
|
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
|
|
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
|
-
};
|
|
12
|
-
import { CommandSettlementError, createCommandEnvelopeWithInstanceId, REACT_NATIVE_WEBVIEW_TRANSPORT_CAPABILITIES, } from "@getuserfeedback/protocol/host";
|
|
1
|
+
import { createCommandEnvelopeWithInstanceId, REACT_NATIVE_WEBVIEW_TRANSPORT_CAPABILITIES, } from "@getuserfeedback/protocol/host";
|
|
13
2
|
import { REACT_NATIVE_SDK_VERSION } from "./version.js";
|
|
14
3
|
export const REACT_NATIVE_CLIENT_META = {
|
|
15
4
|
clientName: "@getuserfeedback/react-native",
|
|
@@ -20,7 +9,6 @@ export const REACT_NATIVE_CLIENT_META = {
|
|
|
20
9
|
REACT_NATIVE_WEBVIEW_TRANSPORT_CAPABILITIES.LAYOUT_TRANSITION_SCHEDULE,
|
|
21
10
|
],
|
|
22
11
|
};
|
|
23
|
-
export const REACT_NATIVE_LOADER_CLIENT_META = Object.assign(Object.assign({}, REACT_NATIVE_CLIENT_META), { transport: "loader" });
|
|
24
12
|
export function createProviderCommandEnvelope({ clientMeta, command, idempotencyKey, instanceId, requestId, }) {
|
|
25
13
|
const resolvedCommand = command.kind === "init" && clientMeta !== undefined
|
|
26
14
|
? Object.assign(Object.assign({}, command), { opts: Object.assign(Object.assign({}, command.opts), { clientMeta }) }) : command;
|
|
@@ -32,28 +20,3 @@ export function createProviderCommandEnvelope({ clientMeta, command, idempotency
|
|
|
32
20
|
requestId,
|
|
33
21
|
});
|
|
34
22
|
}
|
|
35
|
-
function isReactNativeFlowCommand(command) {
|
|
36
|
-
return (command.kind === "open" ||
|
|
37
|
-
command.kind === "prefetch" ||
|
|
38
|
-
command.kind === "prerender");
|
|
39
|
-
}
|
|
40
|
-
export function toReactNativeOneShotCommand(command) {
|
|
41
|
-
if (!isReactNativeFlowCommand(command) ||
|
|
42
|
-
command.flowHandleId === undefined) {
|
|
43
|
-
return command;
|
|
44
|
-
}
|
|
45
|
-
const { flowHandleId: _flowHandleId } = command, commandWithoutFlowHandle = __rest(command, ["flowHandleId"]);
|
|
46
|
-
return commandWithoutFlowHandle;
|
|
47
|
-
}
|
|
48
|
-
export function toCommandSettlementError(event) {
|
|
49
|
-
if (event.detail.ok) {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return new CommandSettlementError({
|
|
53
|
-
code: event.detail.error.code,
|
|
54
|
-
instanceId: event.detail.instanceId,
|
|
55
|
-
kind: event.detail.kind,
|
|
56
|
-
message: event.detail.error.message,
|
|
57
|
-
requestId: event.detail.requestId,
|
|
58
|
-
});
|
|
59
|
-
}
|
package/dist/public-api.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./native-provider.js";
|
|
2
|
+
export { REACT_NATIVE_SDK_VERSION } from "./version.js";
|
package/dist/public-api.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./native-provider.js";
|
|
2
|
+
export { REACT_NATIVE_SDK_VERSION } from "./version.js";
|
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 : "
|
|
6
|
+
export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "5.0.7";
|
|
@@ -1,37 +1,3 @@
|
|
|
1
|
-
// ../view-orchestration/src/active-view-snapshot-list.ts
|
|
2
|
-
import {
|
|
3
|
-
areViewHostSnapshotsEqual,
|
|
4
|
-
cloneViewHostSnapshots
|
|
5
|
-
} from "@getuserfeedback/protocol/host";
|
|
6
|
-
function areActiveViewSnapshotListsEqual(a, b) {
|
|
7
|
-
return a.length === b.length && a.every((left, index) => {
|
|
8
|
-
const right = b[index];
|
|
9
|
-
return areViewHostSnapshotsEqual(left, right);
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
function createActiveViewSnapshotListController() {
|
|
13
|
-
let initialized = false;
|
|
14
|
-
let current = [];
|
|
15
|
-
return {
|
|
16
|
-
clear: () => {
|
|
17
|
-
if (!initialized && current.length === 0) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
initialized = false;
|
|
21
|
-
current = [];
|
|
22
|
-
return true;
|
|
23
|
-
},
|
|
24
|
-
getSnapshots: () => cloneViewHostSnapshots(current),
|
|
25
|
-
replace: (snapshots) => {
|
|
26
|
-
if (initialized && areActiveViewSnapshotListsEqual(current, snapshots)) {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
initialized = true;
|
|
30
|
-
current = cloneViewHostSnapshots(snapshots);
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
1
|
// ../view-orchestration/src/pending-command-tracker.ts
|
|
36
2
|
var createDeferred = () => {
|
|
37
3
|
let resolve;
|
|
@@ -141,12 +107,16 @@ class ViewPreparationCancelledError extends Error {
|
|
|
141
107
|
}
|
|
142
108
|
}
|
|
143
109
|
function runCleanups(entry) {
|
|
110
|
+
const cleanupErrors = [];
|
|
144
111
|
for (const cleanup of Array.from(entry.cleanups)) {
|
|
145
112
|
entry.cleanups.delete(cleanup);
|
|
146
113
|
try {
|
|
147
114
|
cleanup();
|
|
148
|
-
} catch {
|
|
115
|
+
} catch (error) {
|
|
116
|
+
cleanupErrors.push(error);
|
|
117
|
+
}
|
|
149
118
|
}
|
|
119
|
+
return cleanupErrors;
|
|
150
120
|
}
|
|
151
121
|
function createViewPreparationRegistry() {
|
|
152
122
|
const entries = new Map;
|
|
@@ -190,14 +160,16 @@ function createViewPreparationRegistry() {
|
|
|
190
160
|
};
|
|
191
161
|
},
|
|
192
162
|
cancel(viewId) {
|
|
163
|
+
return this.cancelWithResult(viewId).cancelled;
|
|
164
|
+
},
|
|
165
|
+
cancelWithResult(viewId) {
|
|
193
166
|
const entry = entries.get(viewId);
|
|
194
167
|
if (!entry) {
|
|
195
|
-
return false;
|
|
168
|
+
return { cancelled: false, cleanupErrors: [] };
|
|
196
169
|
}
|
|
197
170
|
entries.delete(viewId);
|
|
198
171
|
entry.controller.abort(new ViewPreparationCancelledError(viewId));
|
|
199
|
-
runCleanups(entry);
|
|
200
|
-
return true;
|
|
172
|
+
return { cancelled: true, cleanupErrors: runCleanups(entry) };
|
|
201
173
|
},
|
|
202
174
|
cancelAll() {
|
|
203
175
|
const viewIds = Array.from(entries.keys());
|
|
@@ -219,9 +191,6 @@ function createViewPreparationRegistry() {
|
|
|
219
191
|
function createPendingCommandTracker() {
|
|
220
192
|
return new PendingCommandTracker;
|
|
221
193
|
}
|
|
222
|
-
function createActiveViewSnapshotListController2() {
|
|
223
|
-
return createActiveViewSnapshotListController();
|
|
224
|
-
}
|
|
225
194
|
function createViewPreparationRegistry2() {
|
|
226
195
|
return createViewPreparationRegistry();
|
|
227
196
|
}
|
|
@@ -231,6 +200,5 @@ function createViewPreparationReadinessRegistry2() {
|
|
|
231
200
|
export {
|
|
232
201
|
createViewPreparationRegistry2 as createViewPreparationRegistry,
|
|
233
202
|
createViewPreparationReadinessRegistry2 as createViewPreparationReadinessRegistry,
|
|
234
|
-
createPendingCommandTracker
|
|
235
|
-
createActiveViewSnapshotListController2 as createActiveViewSnapshotListController
|
|
203
|
+
createPendingCommandTracker
|
|
236
204
|
};
|