@shopify/hydrogen-react
Version:
React components, hooks, and utilities for creating custom Shopify storefronts
366 lines (365 loc) • 12.7 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const useMachine = require("./useMachine.js");
const fsm = require("@xstate/fsm");
const flattenConnection = require("./flatten-connection.js");
const useCartActions = require("./useCartActions.js");
const React = require("react");
function invokeCart(action, options) {
return {
entry: [
...(options == null ? void 0 : options.entryActions) || [],
fsm.assign({
lastValidCart: (context) => context == null ? void 0 : context.cart
}),
"onCartActionEntry",
"onCartActionOptimisticUI",
action
],
on: {
RESOLVE: {
target: (options == null ? void 0 : options.resolveTarget) || "idle",
actions: [
fsm.assign({
prevCart: (context) => context == null ? void 0 : context.lastValidCart,
cart: (_, event) => {
var _a;
return (_a = event == null ? void 0 : event.payload) == null ? void 0 : _a.cart;
},
rawCartResult: (_, event) => {
var _a;
return (_a = event == null ? void 0 : event.payload) == null ? void 0 : _a.rawCartResult;
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
errors: (_) => void 0
})
]
},
ERROR: {
target: (options == null ? void 0 : options.errorTarget) || "error",
actions: [
fsm.assign({
prevCart: (context) => context == null ? void 0 : context.lastValidCart,
cart: (context) => context == null ? void 0 : context.lastValidCart,
errors: (_, event) => {
var _a;
return (_a = event == null ? void 0 : event.payload) == null ? void 0 : _a.errors;
}
})
]
},
CART_COMPLETED: {
target: "cartCompleted",
actions: fsm.assign({
// eslint-disable-next-line @typescript-eslint/no-unused-vars
prevCart: (_) => void 0,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
cart: (_) => void 0,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
lastValidCart: (_) => void 0,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
rawCartResult: (_) => void 0,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
errors: (_) => void 0
})
}
},
exit: ["onCartActionComplete", ...(options == null ? void 0 : options.exitActions) || []]
};
}
const INITIALIZING_CART_EVENTS = {
CART_FETCH: {
target: "cartFetching"
},
CART_CREATE: {
target: "cartCreating"
},
CART_SET: {
target: "idle",
actions: [
fsm.assign({
rawCartResult: (_, event) => event.payload.cart,
cart: (_, event) => cartFromGraphQL(event.payload.cart)
})
]
}
};
const UPDATING_CART_EVENTS = {
CARTLINE_ADD: {
target: "cartLineAdding"
},
CARTLINE_UPDATE: {
target: "cartLineUpdating"
},
CARTLINE_REMOVE: {
target: "cartLineRemoving"
},
NOTE_UPDATE: {
target: "noteUpdating"
},
BUYER_IDENTITY_UPDATE: {
target: "buyerIdentityUpdating"
},
CART_ATTRIBUTES_UPDATE: {
target: "cartAttributesUpdating"
},
DISCOUNT_CODES_UPDATE: {
target: "discountCodesUpdating"
}
};
function createCartMachine(initialCart) {
return fsm.createMachine({
id: "Cart",
initial: initialCart ? "idle" : "uninitialized",
context: {
cart: initialCart && cartFromGraphQL(initialCart)
},
states: {
uninitialized: {
on: INITIALIZING_CART_EVENTS
},
cartCompleted: {
on: INITIALIZING_CART_EVENTS
},
initializationError: {
on: INITIALIZING_CART_EVENTS
},
idle: {
on: { ...INITIALIZING_CART_EVENTS, ...UPDATING_CART_EVENTS }
},
error: {
on: { ...INITIALIZING_CART_EVENTS, ...UPDATING_CART_EVENTS }
},
cartFetching: invokeCart("cartFetchAction", {
errorTarget: "initializationError"
}),
cartCreating: invokeCart("cartCreateAction", {
errorTarget: "initializationError"
}),
cartLineRemoving: invokeCart("cartLineRemoveAction"),
cartLineUpdating: invokeCart("cartLineUpdateAction"),
cartLineAdding: invokeCart("cartLineAddAction"),
noteUpdating: invokeCart("noteUpdateAction"),
buyerIdentityUpdating: invokeCart("buyerIdentityUpdateAction"),
cartAttributesUpdating: invokeCart("cartAttributesUpdateAction"),
discountCodesUpdating: invokeCart("discountCodesUpdateAction")
}
});
}
function useCartAPIStateMachine({
numCartLines,
onCartActionEntry,
onCartActionOptimisticUI,
onCartActionComplete,
data: cart,
cartFragment,
countryCode,
languageCode
}) {
const {
cartFetch,
cartCreate,
cartLineAdd,
cartLineUpdate,
cartLineRemove,
noteUpdate,
buyerIdentityUpdate,
cartAttributesUpdate,
discountCodesUpdate
} = useCartActions.useCartActions({
numCartLines,
cartFragment,
countryCode,
languageCode
});
const cartMachine = React.useMemo(() => createCartMachine(cart), [cart]);
const [state, send, service] = useMachine.useMachine(cartMachine, {
actions: {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
cartFetchAction: async (_, event) => {
var _a;
if (event.type !== "CART_FETCH") return;
const { data, errors } = await cartFetch((_a = event == null ? void 0 : event.payload) == null ? void 0 : _a.cartId);
const resultEvent = eventFromFetchResult(event, data == null ? void 0 : data.cart, errors);
send(resultEvent);
},
// eslint-disable-next-line @typescript-eslint/no-misused-promises
cartCreateAction: async (_, event) => {
var _a;
if (event.type !== "CART_CREATE") return;
const { data, errors } = await cartCreate(event == null ? void 0 : event.payload);
const resultEvent = eventFromFetchResult(
event,
(_a = data == null ? void 0 : data.cartCreate) == null ? void 0 : _a.cart,
errors
);
send(resultEvent);
},
// eslint-disable-next-line @typescript-eslint/no-misused-promises
cartLineAddAction: async (context, event) => {
var _a, _b;
if (event.type !== "CARTLINE_ADD" || !((_a = context == null ? void 0 : context.cart) == null ? void 0 : _a.id)) return;
const { data, errors } = await cartLineAdd(
context.cart.id,
event.payload.lines
);
const resultEvent = eventFromFetchResult(
event,
(_b = data == null ? void 0 : data.cartLinesAdd) == null ? void 0 : _b.cart,
errors
);
send(resultEvent);
},
// eslint-disable-next-line @typescript-eslint/no-misused-promises
cartLineUpdateAction: async (context, event) => {
var _a, _b;
if (event.type !== "CARTLINE_UPDATE" || !((_a = context == null ? void 0 : context.cart) == null ? void 0 : _a.id)) return;
const { data, errors } = await cartLineUpdate(
context.cart.id,
event.payload.lines
);
const resultEvent = eventFromFetchResult(
event,
(_b = data == null ? void 0 : data.cartLinesUpdate) == null ? void 0 : _b.cart,
errors
);
send(resultEvent);
},
// eslint-disable-next-line @typescript-eslint/no-misused-promises
cartLineRemoveAction: async (context, event) => {
var _a, _b;
if (event.type !== "CARTLINE_REMOVE" || !((_a = context == null ? void 0 : context.cart) == null ? void 0 : _a.id)) return;
const { data, errors } = await cartLineRemove(
context.cart.id,
event.payload.lines
);
const resultEvent = eventFromFetchResult(
event,
(_b = data == null ? void 0 : data.cartLinesRemove) == null ? void 0 : _b.cart,
errors
);
send(resultEvent);
},
// eslint-disable-next-line @typescript-eslint/no-misused-promises
noteUpdateAction: async (context, event) => {
var _a, _b;
if (event.type !== "NOTE_UPDATE" || !((_a = context == null ? void 0 : context.cart) == null ? void 0 : _a.id)) return;
const { data, errors } = await noteUpdate(
context.cart.id,
event.payload.note
);
const resultEvent = eventFromFetchResult(
event,
(_b = data == null ? void 0 : data.cartNoteUpdate) == null ? void 0 : _b.cart,
errors
);
send(resultEvent);
},
// eslint-disable-next-line @typescript-eslint/no-misused-promises
buyerIdentityUpdateAction: async (context, event) => {
var _a, _b;
if (event.type !== "BUYER_IDENTITY_UPDATE" || !((_a = context == null ? void 0 : context.cart) == null ? void 0 : _a.id))
return;
const { data, errors } = await buyerIdentityUpdate(
context.cart.id,
event.payload.buyerIdentity
);
const resultEvent = eventFromFetchResult(
event,
(_b = data == null ? void 0 : data.cartBuyerIdentityUpdate) == null ? void 0 : _b.cart,
errors
);
send(resultEvent);
},
// eslint-disable-next-line @typescript-eslint/no-misused-promises
cartAttributesUpdateAction: async (context, event) => {
var _a, _b;
if (event.type !== "CART_ATTRIBUTES_UPDATE" || !((_a = context == null ? void 0 : context.cart) == null ? void 0 : _a.id))
return;
const { data, errors } = await cartAttributesUpdate(
context.cart.id,
event.payload.attributes
);
const resultEvent = eventFromFetchResult(
event,
(_b = data == null ? void 0 : data.cartAttributesUpdate) == null ? void 0 : _b.cart,
errors
);
send(resultEvent);
},
// eslint-disable-next-line @typescript-eslint/no-misused-promises
discountCodesUpdateAction: async (context, event) => {
var _a, _b;
if (event.type !== "DISCOUNT_CODES_UPDATE" || !((_a = context == null ? void 0 : context.cart) == null ? void 0 : _a.id))
return;
const { data, errors } = await discountCodesUpdate(
context.cart.id,
event.payload.discountCodes
);
const resultEvent = eventFromFetchResult(
event,
(_b = data == null ? void 0 : data.cartDiscountCodesUpdate) == null ? void 0 : _b.cart,
errors
);
send(resultEvent);
},
...onCartActionEntry && {
onCartActionEntry: (context, event) => {
if (isCartActionEvent(event)) {
onCartActionEntry(context, event);
}
}
},
...onCartActionOptimisticUI && {
onCartActionOptimisticUI: fsm.assign((context, event) => {
return onCartActionOptimisticUI(context, event);
})
},
...onCartActionComplete && {
onCartActionComplete: (context, event) => {
if (isCartFetchResultEvent(event)) {
onCartActionComplete(context, event);
}
}
}
}
});
return React.useMemo(() => [state, send, service], [state, send, service]);
}
function cartFromGraphQL(cart) {
return {
...cart,
lines: flattenConnection.flattenConnection(cart == null ? void 0 : cart.lines),
note: cart.note ?? void 0
};
}
function eventFromFetchResult(cartActionEvent, cart, errors) {
if (errors) {
return { type: "ERROR", payload: { errors, cartActionEvent } };
}
if (!cart) {
return {
type: "CART_COMPLETED",
payload: {
cartActionEvent
}
};
}
return {
type: "RESOLVE",
payload: {
cart: cartFromGraphQL(cart),
rawCartResult: cart,
cartActionEvent
}
};
}
function isCartActionEvent(event) {
return event.type === "CART_CREATE" || event.type === "CARTLINE_ADD" || event.type === "CARTLINE_UPDATE" || event.type === "CARTLINE_REMOVE" || event.type === "NOTE_UPDATE" || event.type === "BUYER_IDENTITY_UPDATE" || event.type === "CART_ATTRIBUTES_UPDATE" || event.type === "DISCOUNT_CODES_UPDATE";
}
function isCartFetchResultEvent(event) {
return event.type === "RESOLVE" || event.type === "ERROR" || event.type === "CART_COMPLETED";
}
exports.cartFromGraphQL = cartFromGraphQL;
exports.useCartAPIStateMachine = useCartAPIStateMachine;
//# sourceMappingURL=useCartAPIStateMachine.js.map