@payabli/components-react 0.2.1 → 0.3.0

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/PayIn.d.ts CHANGED
@@ -2,6 +2,7 @@ import { type ComponentProps, type ComponentRef } from './createComponent.js';
2
2
  export type PayInProps = ComponentProps<'payin'>;
3
3
  export type PayInRef = ComponentRef;
4
4
  export declare const PayIn: import("react").ForwardRefExoticComponent<import("./createComponent.js").ComponentEventProps<"payin"> & {
5
+ componentKey?: string;
5
6
  appearance?: import("@payabli/component-contracts").AppearanceOptions;
6
7
  options?: {
7
8
  initialMethod?: "card" | "ach" | "check" | undefined;
@@ -3,15 +3,14 @@ import type { ReactNode } from 'react';
3
3
  export interface PayabliProviderProps {
4
4
  /**
5
5
  * Session from `POST /api/v2/{slug}/Session/init`, created on your server.
6
- * When the field values change, the provider calls `updateSession()` and all
7
- * mounted components re-bootstrap.
6
+ * A new `sessionId` replaces the instance, so every component mounts again.
8
7
  */
9
8
  session: Session;
10
9
  /** Forwarded to `loadPayabli()` on first mount. Later changes have no effect. */
11
10
  loadOptions?: LoadOptions;
12
11
  /**
13
- * Fires when the session reaches its server-side ceiling, or when auto-refresh
14
- * fails. Create a new session on your server and pass it through the `session` prop.
12
+ * Fires when the session reaches its ceiling. The SDK has removed the components.
13
+ * Create a new session on your server and pass it through the `session` prop.
15
14
  */
16
15
  onSessionExpired?: (payload: SessionEventPayload) => void;
17
16
  onSessionError?: (payload: SessionEventPayload) => void;
@@ -3,14 +3,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { loadPayabli } from '@payabli/components-web';
4
4
  import { useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { PayabliContext } from './context.js';
6
- function isSameSession(a, b) {
7
- return (a !== null &&
8
- a.sessionToken === b.sessionToken &&
9
- a.renderToken === b.renderToken &&
10
- a.entryName === b.entryName &&
11
- a.environment === b.environment &&
12
- a.expiresAt === b.expiresAt);
13
- }
14
6
  export function PayabliProvider({ session, loadOptions, onSessionExpired, onSessionError, onLoadError, children, }) {
15
7
  const [payabli, setPayabli] = useState(null);
16
8
  const [error, setError] = useState(null);
@@ -19,7 +11,7 @@ export function PayabliProvider({ session, loadOptions, onSessionExpired, onSess
19
11
  callbacksRef.current = { onSessionExpired, onSessionError, onLoadError };
20
12
  });
21
13
  const sessionRef = useRef(session);
22
- const appliedSessionRef = useRef(null);
14
+ sessionRef.current = session;
23
15
  const loadOptionsRef = useRef(loadOptions);
24
16
  useEffect(() => {
25
17
  let cancelled = false;
@@ -28,13 +20,16 @@ export function PayabliProvider({ session, loadOptions, onSessionExpired, onSess
28
20
  if (cancelled)
29
21
  return;
30
22
  instance = Payabli({ session: sessionRef.current });
31
- appliedSessionRef.current = sessionRef.current;
23
+ // Both events end the session, and an ended instance rejects create(). Drop it
24
+ // from context, so a component that remounts before the next session waits.
32
25
  instance.on('sessionExpired', (payload) => {
33
26
  var _a, _b;
27
+ setPayabli(null);
34
28
  (_b = (_a = callbacksRef.current).onSessionExpired) === null || _b === void 0 ? void 0 : _b.call(_a, payload);
35
29
  });
36
30
  instance.on('sessionError', (payload) => {
37
31
  var _a, _b;
32
+ setPayabli(null);
38
33
  (_b = (_a = callbacksRef.current).onSessionError) === null || _b === void 0 ? void 0 : _b.call(_a, payload);
39
34
  });
40
35
  setPayabli(instance);
@@ -50,18 +45,9 @@ export function PayabliProvider({ session, loadOptions, onSessionExpired, onSess
50
45
  cancelled = true;
51
46
  instance === null || instance === void 0 ? void 0 : instance.destroy();
52
47
  instance = null;
53
- appliedSessionRef.current = null;
54
48
  setPayabli(null);
55
49
  };
56
- }, []);
57
- useEffect(() => {
58
- sessionRef.current = session;
59
- if (!payabli || isSameSession(appliedSessionRef.current, session)) {
60
- return;
61
- }
62
- appliedSessionRef.current = session;
63
- payabli.updateSession(session);
64
- }, [payabli, session]);
50
+ }, [session.sessionId]);
65
51
  const value = useMemo(() => ({ payabli, error }), [payabli, error]);
66
52
  return _jsx(PayabliContext.Provider, { value: value, children: children });
67
53
  }
package/dist/context.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { PayabliInstance } from '@payabli/components-web';
2
2
  export interface PayabliContextValue {
3
- /** The live instance, or null while the hosted script loads. */
3
+ /** The live instance, or null while the hosted script loads and after the session ends. */
4
4
  payabli: PayabliInstance | null;
5
5
  /** Set when the hosted script fails to load. */
6
6
  error: Error | null;
@@ -7,6 +7,11 @@ export type ComponentEventProps<T extends ComponentType> = {
7
7
  [K in EventName<T> as EventPropName<K>]?: (payload: ComponentEventMap<T>[K]) => void;
8
8
  };
9
9
  export type ComponentProps<T extends ComponentType> = ComponentEventProps<T> & {
10
+ /**
11
+ * The component key from `Session/init`. Required when the session has more than one
12
+ * component. Defaults to the component type. Named `componentKey` because React reserves `key`.
13
+ */
14
+ componentKey?: string;
10
15
  appearance?: AppearanceOptions;
11
16
  options?: ComponentOptions<T>;
12
17
  prefill?: CreateOptions<T>['prefill'];
@@ -43,15 +43,15 @@ export function createComponent(type) {
43
43
  appliedOptionsRef.current = null;
44
44
  component.destroy();
45
45
  };
46
- }, [payabli]);
46
+ }, [payabli, props.componentKey]);
47
47
  const { appearance, options, prefill, locale, timeout } = props;
48
48
  useEffect(() => {
49
49
  const component = componentRef.current;
50
50
  if (!component) {
51
51
  return;
52
52
  }
53
- const next = Object.assign(Object.assign({ appearance,
54
- options }, (prefill === undefined ? {} : { prefill })), { locale,
53
+ const next = Object.assign(Object.assign(Object.assign(Object.assign({}, withKey(propsRef.current.componentKey)), { appearance,
54
+ options }), (prefill === undefined ? {} : { prefill })), { locale,
55
55
  timeout });
56
56
  const serialized = JSON.stringify(next);
57
57
  if (serialized === appliedOptionsRef.current) {
@@ -83,7 +83,11 @@ export function createComponent(type) {
83
83
  return RegisteredComponent;
84
84
  }
85
85
  function toCreateOptions(props) {
86
- return Object.assign(Object.assign({ appearance: props.appearance, options: props.options }, (props.prefill === undefined ? {} : { prefill: props.prefill })), { locale: props.locale, timeout: props.timeout });
86
+ return Object.assign(Object.assign(Object.assign(Object.assign({}, withKey(props.componentKey)), { appearance: props.appearance, options: props.options }), (props.prefill === undefined ? {} : { prefill: props.prefill })), { locale: props.locale, timeout: props.timeout });
87
+ }
88
+ /** The `key` create option, left out when the partner names none. */
89
+ function withKey(componentKey) {
90
+ return componentKey === undefined ? {} : { key: componentKey };
87
91
  }
88
92
  function forwardEvent(component, event, propsRef) {
89
93
  component.on(event, (payload) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payabli/components-react",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "React bindings for the Payabli embedded components SDK.",
5
5
  "private": false,
6
6
  "license": "MIT",
@@ -25,8 +25,8 @@
25
25
  "access": "public"
26
26
  },
27
27
  "dependencies": {
28
- "@payabli/component-contracts": "0.3.0",
29
- "@payabli/components-web": "0.2.1"
28
+ "@payabli/component-contracts": "0.4.0",
29
+ "@payabli/components-web": "0.3.0"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": "^18.0.0 || ^19.0.0"