@getuserfeedback/react-native 5.0.7 → 5.0.9
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/native-core-command-channel.js +45 -7
- package/dist/native-provider-client-controller.d.ts +1 -1
- package/dist/native-provider-client.d.ts +7 -36
- package/dist/native-runtime-root.d.ts +6 -13
- package/dist/native-runtime-root.js +13 -32
- package/dist/version.js +1 -1
- package/package.json +4 -4
- package/dist/runtime-endpoints.d.ts +0 -2
- package/dist/runtime-endpoints.js +0 -2
|
@@ -1,22 +1,60 @@
|
|
|
1
|
-
import { coreCommandEnvelopeSchema, } from "@getuserfeedback/protocol";
|
|
1
|
+
import { appEventPayloadSchema, coreCommandEnvelopeSchema, } from "@getuserfeedback/protocol";
|
|
2
2
|
import { eventHandleInvalidatedSchema, } from "@getuserfeedback/protocol/internal/core-handle-invalidation";
|
|
3
3
|
import { eventCommandSettledSchema, } from "@getuserfeedback/protocol/internal/core-host-command-settlement";
|
|
4
4
|
import { CORE_SESSION_FAILED_CODE, eventCoreSessionFailedSchema, } from "@getuserfeedback/protocol/internal/core-session-failure";
|
|
5
|
+
import { buildRpcResponse, rpcRequestSchema, } from "@getuserfeedback/protocol/internal/v3-rpc-messages";
|
|
5
6
|
const DISPOSED_MESSAGE = "Core command channel is disposed";
|
|
7
|
+
const TRAFFIC_APP_EVENT_RPC_METHOD = "traffic.appEvent";
|
|
6
8
|
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
7
9
|
export function createNativeCoreCommandChannel(input) {
|
|
8
10
|
const listeners = new Set();
|
|
9
11
|
let disposed = false;
|
|
10
12
|
const handleMessage = (value) => {
|
|
11
|
-
var _a, _b, _c, _d, _e;
|
|
13
|
+
var _a, _b, _c, _d, _e, _f;
|
|
12
14
|
if (disposed || !isRecord(value)) {
|
|
13
15
|
return;
|
|
14
16
|
}
|
|
17
|
+
if (value.t === "getuserfeedback:rpc:request") {
|
|
18
|
+
const parsed = rpcRequestSchema.safeParse(value);
|
|
19
|
+
if (!parsed.success ||
|
|
20
|
+
parsed.data.gen !== input.coreConnection.generation ||
|
|
21
|
+
parsed.data.method !== TRAFFIC_APP_EVENT_RPC_METHOD) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const params = isRecord(parsed.data.params) ? parsed.data.params : null;
|
|
25
|
+
const instanceId = params && typeof params.instanceId === "string"
|
|
26
|
+
? params.instanceId.trim()
|
|
27
|
+
: "";
|
|
28
|
+
const payload = params
|
|
29
|
+
? appEventPayloadSchema.safeParse(params.payload)
|
|
30
|
+
: { success: false };
|
|
31
|
+
const result = instanceId.length > 0 && payload.success
|
|
32
|
+
? { allowed: true, payload: payload.data }
|
|
33
|
+
: { allowed: false };
|
|
34
|
+
try {
|
|
35
|
+
input.coreConnection.transport.postMessage(buildRpcResponse({
|
|
36
|
+
gen: parsed.data.gen,
|
|
37
|
+
rpcId: parsed.data.rpcId,
|
|
38
|
+
ok: true,
|
|
39
|
+
result,
|
|
40
|
+
viewId: parsed.data.viewId,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
try {
|
|
45
|
+
(_a = input.onInvalidMessage) === null || _a === void 0 ? void 0 : _a.call(input, error instanceof Error ? error : new Error(String(error)), value);
|
|
46
|
+
}
|
|
47
|
+
catch (_g) {
|
|
48
|
+
// Best-effort analytics and diagnostics cannot fail the Core session.
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
15
53
|
if (value.t === "getuserfeedback:event:error" &&
|
|
16
54
|
value.code === CORE_SESSION_FAILED_CODE) {
|
|
17
55
|
const parsed = eventCoreSessionFailedSchema.safeParse(value);
|
|
18
56
|
if (!parsed.success) {
|
|
19
|
-
(
|
|
57
|
+
(_b = input.onInvalidMessage) === null || _b === void 0 ? void 0 : _b.call(input, parsed.error instanceof Error
|
|
20
58
|
? parsed.error
|
|
21
59
|
: new Error("Invalid Core session failure message"), value);
|
|
22
60
|
return;
|
|
@@ -24,13 +62,13 @@ export function createNativeCoreCommandChannel(input) {
|
|
|
24
62
|
if (parsed.data.gen !== input.coreConnection.generation) {
|
|
25
63
|
return;
|
|
26
64
|
}
|
|
27
|
-
(
|
|
65
|
+
(_c = input.onSessionFailure) === null || _c === void 0 ? void 0 : _c.call(input, new Error(parsed.data.details.message));
|
|
28
66
|
return;
|
|
29
67
|
}
|
|
30
68
|
if (value.t === "getuserfeedback:event:commandSettled") {
|
|
31
69
|
const parsed = eventCommandSettledSchema.safeParse(value);
|
|
32
70
|
if (!parsed.success) {
|
|
33
|
-
(
|
|
71
|
+
(_d = input.onInvalidMessage) === null || _d === void 0 ? void 0 : _d.call(input, parsed.error instanceof Error
|
|
34
72
|
? parsed.error
|
|
35
73
|
: new Error("Invalid core command settlement message"), value);
|
|
36
74
|
return;
|
|
@@ -48,7 +86,7 @@ export function createNativeCoreCommandChannel(input) {
|
|
|
48
86
|
}
|
|
49
87
|
const parsed = eventHandleInvalidatedSchema.safeParse(value);
|
|
50
88
|
if (!parsed.success) {
|
|
51
|
-
(
|
|
89
|
+
(_e = input.onInvalidMessage) === null || _e === void 0 ? void 0 : _e.call(input, parsed.error instanceof Error
|
|
52
90
|
? parsed.error
|
|
53
91
|
: new Error("Invalid core handle invalidation message"), value);
|
|
54
92
|
return;
|
|
@@ -56,7 +94,7 @@ export function createNativeCoreCommandChannel(input) {
|
|
|
56
94
|
if (parsed.data.gen !== input.coreConnection.generation) {
|
|
57
95
|
return;
|
|
58
96
|
}
|
|
59
|
-
(
|
|
97
|
+
(_f = input.onHandleInvalidated) === null || _f === void 0 ? void 0 : _f.call(input, parsed.data);
|
|
60
98
|
};
|
|
61
99
|
const unsubscribeTransport = input.coreConnection.transport.subscribe(handleMessage);
|
|
62
100
|
const channel = {
|
|
@@ -3,7 +3,7 @@ export declare function createNativeProviderClientController(input: {
|
|
|
3
3
|
instanceId: string;
|
|
4
4
|
onError?: (error: Error) => void;
|
|
5
5
|
}): {
|
|
6
|
-
client: import("./
|
|
6
|
+
client: import("./client.js").Client;
|
|
7
7
|
directSessionController: import("./native-direct-command-session-controller.js").NativeDirectCommandSessionController;
|
|
8
8
|
dispose: () => void;
|
|
9
9
|
onHandleInvalidated: (message: EventHandleInvalidated) => void;
|
|
@@ -1,43 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type { FlowRun } from "./client.js";
|
|
4
|
-
type IdentifyTraits = Record<string, unknown>;
|
|
5
|
-
type TrackProperties = Record<string, AppEventJsonValue>;
|
|
1
|
+
import type { PublicCommandPayload } from "@getuserfeedback/protocol";
|
|
2
|
+
import type { Client } from "./client.js";
|
|
6
3
|
type NativeProviderClientCommand = Extract<PublicCommandPayload, {
|
|
7
4
|
kind: "configure" | "identify" | "track" | "close" | "reset" | "updateHostContext" | "emitHostSignal";
|
|
8
5
|
}>;
|
|
9
|
-
type
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
externalIds?: AppEventExternalId[];
|
|
14
|
-
};
|
|
15
|
-
type HostContext = Extract<PublicCommandPayload, {
|
|
16
|
-
kind: "updateHostContext";
|
|
17
|
-
}>["context"];
|
|
18
|
-
interface NativeProviderCommandOptions {
|
|
19
|
-
idempotencyKey?: string;
|
|
20
|
-
}
|
|
21
|
-
export interface NativeProviderClient<TResult> {
|
|
22
|
-
readonly instanceId: string;
|
|
23
|
-
configure: (opts: ConfigureOptions, options?: NativeProviderCommandOptions) => Promise<TResult>;
|
|
24
|
-
identify: {
|
|
25
|
-
(userId: string, traits?: IdentifyTraits, options?: IdentifyOptions): Promise<TResult>;
|
|
26
|
-
(traits: IdentifyTraits, placeholder: undefined, options?: IdentifyOptions): Promise<TResult>;
|
|
27
|
-
(traits: IdentifyTraits, options?: IdentifyOptions): Promise<TResult>;
|
|
28
|
-
};
|
|
29
|
-
track: (eventName: string, properties?: TrackProperties, options?: TrackOptions) => Promise<TResult>;
|
|
30
|
-
flow: (flowId: string) => FlowRun;
|
|
31
|
-
close: () => Promise<TResult>;
|
|
32
|
-
reset: (options?: NativeProviderCommandOptions) => Promise<TResult>;
|
|
33
|
-
updateHostContext: (context: HostContext, options?: NativeProviderCommandOptions) => Promise<TResult>;
|
|
34
|
-
emitHostSignal: (name: string, data?: unknown, options?: NativeProviderCommandOptions) => Promise<TResult>;
|
|
35
|
-
}
|
|
36
|
-
type NativeProviderClientOptions<TResult> = {
|
|
37
|
-
dispatchCommand: (command: NativeProviderClientCommand, options?: NativeProviderCommandOptions) => Promise<TResult>;
|
|
38
|
-
flow: (flowId: string) => FlowRun;
|
|
6
|
+
type NativeProviderCommandOptions = NonNullable<Parameters<Client["configure"]>[1]>;
|
|
7
|
+
type NativeProviderClientOptions = {
|
|
8
|
+
dispatchCommand: (command: NativeProviderClientCommand, options?: NativeProviderCommandOptions) => Promise<void>;
|
|
9
|
+
flow: Client["flow"];
|
|
39
10
|
instanceId: string;
|
|
40
11
|
};
|
|
41
12
|
export declare const parseRequiredString: (name: string, value?: string) => string;
|
|
42
|
-
export declare function createNativeProviderClient
|
|
13
|
+
export declare function createNativeProviderClient({ dispatchCommand, flow, instanceId, }: NativeProviderClientOptions): Client;
|
|
43
14
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CoreCommandEnvelope } from "@getuserfeedback/protocol";
|
|
2
2
|
import type { EventHandleInvalidated } from "@getuserfeedback/protocol/internal/core-handle-invalidation";
|
|
3
|
-
import type {
|
|
3
|
+
import type { InitOptions } from "@getuserfeedback/sdk";
|
|
4
4
|
import { type ReactElement } from "react";
|
|
5
5
|
import { type CoreWebViewHostProps } from "./core-webview-host.js";
|
|
6
6
|
import { type NativeCoreCommandSession } from "./native-core-command-session.js";
|
|
@@ -8,9 +8,9 @@ import { type NativeDirectCommandSession } from "./native-direct-command-session
|
|
|
8
8
|
import type { NativeDirectCommandSessionController } from "./native-direct-command-session-controller.js";
|
|
9
9
|
import { type NativeViewHostProjectionProps } from "./native-view-host-projection.js";
|
|
10
10
|
export type NativeRuntimeRootProps = {
|
|
11
|
-
coreUrl
|
|
11
|
+
coreUrl: string;
|
|
12
12
|
coreWebViewComponent?: CoreWebViewHostProps["webViewComponent"];
|
|
13
|
-
|
|
13
|
+
startupCommand?: NativeRuntimeInitCommand;
|
|
14
14
|
onCommandSessionChange?: (session: NativeCoreCommandSession | null) => void;
|
|
15
15
|
onError?: (error: Error) => void;
|
|
16
16
|
onHandleInvalidated?: (message: EventHandleInvalidated) => void;
|
|
@@ -25,20 +25,13 @@ type NativeRuntimeInitCommand = Omit<CoreCommandEnvelope, "command"> & {
|
|
|
25
25
|
kind: "init";
|
|
26
26
|
}>;
|
|
27
27
|
};
|
|
28
|
-
type
|
|
29
|
-
command: Extract<CoreCommandEnvelope["command"], {
|
|
30
|
-
kind: "configure";
|
|
31
|
-
}>;
|
|
32
|
-
};
|
|
33
|
-
type NativeRuntimeStartupCommands = readonly [NativeRuntimeInitCommand] | readonly [NativeRuntimeInitCommand, NativeRuntimeConfigureCommand];
|
|
34
|
-
type NativeProviderRuntimeProps = Omit<NativeRuntimeRootProps, "onCommandSessionChange" | "onStartupTerminalError" | "startupCommands"> & {
|
|
28
|
+
type NativeProviderRuntimeProps = Omit<NativeRuntimeRootProps, "onCommandSessionChange" | "onStartupTerminalError" | "startupCommand"> & {
|
|
35
29
|
/** Stable, exclusive controller retained and disposed by the component that owns this runtime's mounted lifetime. */
|
|
36
30
|
directSessionController: NativeDirectCommandSessionController;
|
|
37
|
-
initialConfigureOptions?: ConfigureOptions;
|
|
38
31
|
initOptions: InitOptions;
|
|
39
32
|
instanceId: string;
|
|
40
33
|
onCommandSessionChange?: (session: NativeDirectCommandSession | null) => void;
|
|
41
34
|
};
|
|
42
|
-
export declare function NativeRuntimeRoot({ coreUrl, coreWebViewComponent, onCommandSessionChange, onError, onHandleInvalidated, onInvalidMessage, onStartupTerminalError, startupCommandSettlementTimeoutMs,
|
|
43
|
-
export declare function NativeProviderRuntime({ directSessionController, initOptions,
|
|
35
|
+
export declare function NativeRuntimeRoot({ coreUrl, coreWebViewComponent, onCommandSessionChange, onError, onHandleInvalidated, onInvalidMessage, onStartupTerminalError, startupCommandSettlementTimeoutMs, startupCommand, viewNativeViewComponent, viewWebViewComponent, }: NativeRuntimeRootProps): ReactElement;
|
|
36
|
+
export declare function NativeProviderRuntime({ directSessionController, initOptions, instanceId, onCommandSessionChange, onError, ...runtimeProps }: NativeProviderRuntimeProps): ReactElement;
|
|
44
37
|
export {};
|
|
@@ -18,16 +18,8 @@ import { createNativeDirectCommandSession, } from "./native-direct-command-sessi
|
|
|
18
18
|
import { NativeViewHostProjection, } from "./native-view-host-projection.js";
|
|
19
19
|
import { createNativeViewRecordController, } from "./native-view-record-controller.js";
|
|
20
20
|
import { createProviderCommandEnvelope, REACT_NATIVE_CLIENT_META, } from "./provider-command-helpers.js";
|
|
21
|
-
import { REACT_NATIVE_DEFAULT_CORE_URL } from "./runtime-endpoints.js";
|
|
22
21
|
const DEFAULT_STARTUP_COMMAND_SETTLEMENT_TIMEOUT_MS = 30000;
|
|
23
|
-
|
|
24
|
-
for (const command of input.commands) {
|
|
25
|
-
await input.commandSession.dispatch(command, {
|
|
26
|
-
settlementTimeoutMs: input.timeoutMs,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
export function NativeRuntimeRoot({ coreUrl = REACT_NATIVE_DEFAULT_CORE_URL, coreWebViewComponent, onCommandSessionChange, onError, onHandleInvalidated, onInvalidMessage, onStartupTerminalError, startupCommandSettlementTimeoutMs = DEFAULT_STARTUP_COMMAND_SETTLEMENT_TIMEOUT_MS, startupCommands, viewNativeViewComponent, viewWebViewComponent, }) {
|
|
22
|
+
export function NativeRuntimeRoot({ coreUrl, coreWebViewComponent, onCommandSessionChange, onError, onHandleInvalidated, onInvalidMessage, onStartupTerminalError, startupCommandSettlementTimeoutMs = DEFAULT_STARTUP_COMMAND_SETTLEMENT_TIMEOUT_MS, startupCommand, viewNativeViewComponent, viewWebViewComponent, }) {
|
|
31
23
|
const [coreHostRevision, setCoreHostRevision] = useState(0);
|
|
32
24
|
const [session, setSession] = useState(null);
|
|
33
25
|
const sessionRef = useRef(null);
|
|
@@ -43,8 +35,8 @@ export function NativeRuntimeRoot({ coreUrl = REACT_NATIVE_DEFAULT_CORE_URL, cor
|
|
|
43
35
|
onInvalidMessageRef.current = onInvalidMessage;
|
|
44
36
|
const onStartupTerminalErrorRef = useRef(onStartupTerminalError);
|
|
45
37
|
onStartupTerminalErrorRef.current = onStartupTerminalError;
|
|
46
|
-
const
|
|
47
|
-
|
|
38
|
+
const startupCommandRef = useRef(startupCommand);
|
|
39
|
+
startupCommandRef.current = startupCommand;
|
|
48
40
|
const reportError = useCallback((error) => {
|
|
49
41
|
var _a;
|
|
50
42
|
try {
|
|
@@ -127,12 +119,11 @@ export function NativeRuntimeRoot({ coreUrl = REACT_NATIVE_DEFAULT_CORE_URL, cor
|
|
|
127
119
|
setSession(nextSession);
|
|
128
120
|
notifyCommandSessionObserver(nextSession.commandSessionObserver, commandSessionOwner.session);
|
|
129
121
|
};
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
132
|
-
void
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
timeoutMs: startupCommandSettlementTimeoutMs,
|
|
122
|
+
const startupCommand = startupCommandRef.current;
|
|
123
|
+
if (startupCommand) {
|
|
124
|
+
void commandSessionOwner.session
|
|
125
|
+
.dispatch(startupCommand, {
|
|
126
|
+
settlementTimeoutMs: startupCommandSettlementTimeoutMs,
|
|
136
127
|
})
|
|
137
128
|
.then(commitSession)
|
|
138
129
|
.catch((error) => {
|
|
@@ -226,7 +217,7 @@ export function NativeRuntimeRoot({ coreUrl = REACT_NATIVE_DEFAULT_CORE_URL, cor
|
|
|
226
217
|
}));
|
|
227
218
|
}
|
|
228
219
|
export function NativeProviderRuntime(_a) {
|
|
229
|
-
var { directSessionController, initOptions,
|
|
220
|
+
var { directSessionController, initOptions, instanceId, onCommandSessionChange, onError } = _a, runtimeProps = __rest(_a, ["directSessionController", "initOptions", "instanceId", "onCommandSessionChange", "onError"]);
|
|
230
221
|
const directSessionRef = useRef(null);
|
|
231
222
|
useLayoutEffect(() => {
|
|
232
223
|
directSessionController.beginAttachmentAttempt();
|
|
@@ -255,22 +246,12 @@ export function NativeProviderRuntime(_a) {
|
|
|
255
246
|
}
|
|
256
247
|
onCommandSessionChange === null || onCommandSessionChange === void 0 ? void 0 : onCommandSessionChange(directSessionController.session);
|
|
257
248
|
}, [directSessionController, onCommandSessionChange]);
|
|
258
|
-
const
|
|
259
|
-
|
|
249
|
+
const startupCommand = useMemo(() => {
|
|
250
|
+
return createProviderCommandEnvelope({
|
|
260
251
|
clientMeta: REACT_NATIVE_CLIENT_META,
|
|
261
252
|
command: { kind: "init", opts: initOptions },
|
|
262
253
|
instanceId,
|
|
263
254
|
});
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
return [
|
|
268
|
-
initCommand,
|
|
269
|
-
createProviderCommandEnvelope({
|
|
270
|
-
command: { kind: "configure", opts: initialConfigureOptions },
|
|
271
|
-
instanceId,
|
|
272
|
-
}),
|
|
273
|
-
];
|
|
274
|
-
}, [initialConfigureOptions, initOptions, instanceId]);
|
|
275
|
-
return createElement(NativeRuntimeRoot, Object.assign(Object.assign({}, runtimeProps), { onCommandSessionChange: handleCommandSessionChange, onError, onStartupTerminalError: handleStartupTerminalError, startupCommands }));
|
|
255
|
+
}, [initOptions, instanceId]);
|
|
256
|
+
return createElement(NativeRuntimeRoot, Object.assign(Object.assign({}, runtimeProps), { onCommandSessionChange: handleCommandSessionChange, onError, onStartupTerminalError: handleStartupTerminalError, startupCommand }));
|
|
276
257
|
}
|
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 : "5.0.
|
|
6
|
+
export const REACT_NATIVE_SDK_VERSION = reactNativeSdkVersion.length > 0 ? reactNativeSdkVersion : "5.0.9";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getuserfeedback/react-native",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.9",
|
|
4
4
|
"description": "getuserfeedback React Native SDK",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"getuserfeedback",
|
|
@@ -38,14 +38,14 @@
|
|
|
38
38
|
"publish:dry-run": "node ../../scripts/publish-package.cjs . --verify-packed-runtime scripts/verify-packed-runtime.ts --expect-dependency @getuserfeedback/protocol:../protocol/package.json --expect-dependency @getuserfeedback/sdk:../sdk/package.json -- --dry-run",
|
|
39
39
|
"publish:npm": "node ../../scripts/publish-package.cjs . --verify-packed-runtime scripts/verify-packed-runtime.ts --expect-dependency @getuserfeedback/protocol:../protocol/package.json --expect-dependency @getuserfeedback/sdk:../sdk/package.json",
|
|
40
40
|
"build": "bun scripts/build.ts",
|
|
41
|
-
"typecheck": "tsc -p tsconfig.json --noEmit --
|
|
41
|
+
"typecheck": "tsc -p tsconfig.json --noEmit --composite false --incremental false && tsc -p tsconfig-scripts.json --noEmit --composite false --incremental false",
|
|
42
42
|
"test": "bun test --dots",
|
|
43
43
|
"test:changed": "bun test --changed=${TEST_CHANGED_BASE:-HEAD} --pass-with-no-tests --dots",
|
|
44
44
|
"lint": "biome check ."
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@getuserfeedback/protocol": "^3.31.
|
|
48
|
-
"@getuserfeedback/sdk": "^0.12.
|
|
47
|
+
"@getuserfeedback/protocol": "^3.31.1",
|
|
48
|
+
"@getuserfeedback/sdk": "^0.12.36",
|
|
49
49
|
"robot3": "^1.2.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|