@betterstore/react 0.1.1 → 0.1.3
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/CHANGELOG.md +12 -0
- package/dist/components/cart/useCart.d.ts +31 -0
- package/dist/components/checkout-embed/index.d.ts +8 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/index.cjs.js +301 -54
- package/dist/index.d.ts +1 -3
- package/dist/index.esm.js +300 -54
- package/package.json +1 -1
- package/dist/checkout-embed/index.d.ts +0 -6
- /package/dist/{checkout-embed → components/checkout-embed}/summary/index.d.ts +0 -0
- /package/dist/{checkout → components/payment-element}/appearance.d.ts +0 -0
- /package/dist/{checkout → components/payment-element}/checkout-form.d.ts +0 -0
- /package/dist/{checkout/payment-element.d.ts → components/payment-element/index.d.ts} +0 -0
- /package/dist/{checkout → components/payment-element}/useCheckout.d.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface LineItem {
|
|
2
|
+
id: string;
|
|
3
|
+
quantity: number;
|
|
4
|
+
productId: string;
|
|
5
|
+
variantOptions: {
|
|
6
|
+
name: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}[];
|
|
9
|
+
metadata?: string;
|
|
10
|
+
}
|
|
11
|
+
type LineItemWithoutId = Omit<LineItem, "id">;
|
|
12
|
+
interface Cart {
|
|
13
|
+
lineItems: LineItem[];
|
|
14
|
+
addItem: (item: LineItemWithoutId) => void;
|
|
15
|
+
removeItem: (id: string) => void;
|
|
16
|
+
updateQuantity: (id: string, quantity: number) => void;
|
|
17
|
+
getProductQuantity: (productId: string) => number;
|
|
18
|
+
clearCart: () => void;
|
|
19
|
+
}
|
|
20
|
+
export declare const useCart: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<Cart>, "persist"> & {
|
|
21
|
+
persist: {
|
|
22
|
+
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<Cart, Cart>>) => void;
|
|
23
|
+
clearStorage: () => void;
|
|
24
|
+
rehydrate: () => Promise<void> | void;
|
|
25
|
+
hasHydrated: () => boolean;
|
|
26
|
+
onHydrate: (fn: (state: Cart) => void) => () => void;
|
|
27
|
+
onFinishHydration: (fn: (state: Cart) => void) => () => void;
|
|
28
|
+
getOptions: () => Partial<import("zustand/middleware").PersistOptions<Cart, Cart>>;
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import BetterStore from "@betterstore/sdk";
|
|
2
|
+
import React from "react";
|
|
3
|
+
declare function CheckoutEmbed({ betterStore, checkoutId, }: {
|
|
4
|
+
betterStore: InstanceType<typeof BetterStore>;
|
|
5
|
+
checkoutId: string;
|
|
6
|
+
}): React.JSX.Element;
|
|
7
|
+
declare const _default: React.MemoExoticComponent<typeof CheckoutEmbed>;
|
|
8
|
+
export default _default;
|
package/dist/index.cjs.js
CHANGED
|
@@ -2,6 +2,273 @@
|
|
|
2
2
|
|
|
3
3
|
var React = require('react');
|
|
4
4
|
|
|
5
|
+
const createStoreImpl = (createState) => {
|
|
6
|
+
let state;
|
|
7
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
8
|
+
const setState = (partial, replace) => {
|
|
9
|
+
const nextState = typeof partial === "function" ? partial(state) : partial;
|
|
10
|
+
if (!Object.is(nextState, state)) {
|
|
11
|
+
const previousState = state;
|
|
12
|
+
state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
|
|
13
|
+
listeners.forEach((listener) => listener(state, previousState));
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const getState = () => state;
|
|
17
|
+
const getInitialState = () => initialState;
|
|
18
|
+
const subscribe = (listener) => {
|
|
19
|
+
listeners.add(listener);
|
|
20
|
+
return () => listeners.delete(listener);
|
|
21
|
+
};
|
|
22
|
+
const api = { setState, getState, getInitialState, subscribe };
|
|
23
|
+
const initialState = state = createState(setState, getState, api);
|
|
24
|
+
return api;
|
|
25
|
+
};
|
|
26
|
+
const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
|
|
27
|
+
|
|
28
|
+
const identity = (arg) => arg;
|
|
29
|
+
function useStore(api, selector = identity) {
|
|
30
|
+
const slice = React.useSyncExternalStore(
|
|
31
|
+
api.subscribe,
|
|
32
|
+
() => selector(api.getState()),
|
|
33
|
+
() => selector(api.getInitialState())
|
|
34
|
+
);
|
|
35
|
+
React.useDebugValue(slice);
|
|
36
|
+
return slice;
|
|
37
|
+
}
|
|
38
|
+
const createImpl = (createState) => {
|
|
39
|
+
const api = createStore(createState);
|
|
40
|
+
const useBoundStore = (selector) => useStore(api, selector);
|
|
41
|
+
Object.assign(useBoundStore, api);
|
|
42
|
+
return useBoundStore;
|
|
43
|
+
};
|
|
44
|
+
const create = (createState) => createState ? createImpl(createState) : createImpl;
|
|
45
|
+
|
|
46
|
+
function createJSONStorage(getStorage, options) {
|
|
47
|
+
let storage;
|
|
48
|
+
try {
|
|
49
|
+
storage = getStorage();
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const persistStorage = {
|
|
54
|
+
getItem: (name) => {
|
|
55
|
+
var _a;
|
|
56
|
+
const parse = (str2) => {
|
|
57
|
+
if (str2 === null) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return JSON.parse(str2, undefined );
|
|
61
|
+
};
|
|
62
|
+
const str = (_a = storage.getItem(name)) != null ? _a : null;
|
|
63
|
+
if (str instanceof Promise) {
|
|
64
|
+
return str.then(parse);
|
|
65
|
+
}
|
|
66
|
+
return parse(str);
|
|
67
|
+
},
|
|
68
|
+
setItem: (name, newValue) => storage.setItem(
|
|
69
|
+
name,
|
|
70
|
+
JSON.stringify(newValue, undefined )
|
|
71
|
+
),
|
|
72
|
+
removeItem: (name) => storage.removeItem(name)
|
|
73
|
+
};
|
|
74
|
+
return persistStorage;
|
|
75
|
+
}
|
|
76
|
+
const toThenable = (fn) => (input) => {
|
|
77
|
+
try {
|
|
78
|
+
const result = fn(input);
|
|
79
|
+
if (result instanceof Promise) {
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
then(onFulfilled) {
|
|
84
|
+
return toThenable(onFulfilled)(result);
|
|
85
|
+
},
|
|
86
|
+
catch(_onRejected) {
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
} catch (e) {
|
|
91
|
+
return {
|
|
92
|
+
then(_onFulfilled) {
|
|
93
|
+
return this;
|
|
94
|
+
},
|
|
95
|
+
catch(onRejected) {
|
|
96
|
+
return toThenable(onRejected)(e);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const persistImpl = (config, baseOptions) => (set, get, api) => {
|
|
102
|
+
let options = {
|
|
103
|
+
storage: createJSONStorage(() => localStorage),
|
|
104
|
+
partialize: (state) => state,
|
|
105
|
+
version: 0,
|
|
106
|
+
merge: (persistedState, currentState) => ({
|
|
107
|
+
...currentState,
|
|
108
|
+
...persistedState
|
|
109
|
+
}),
|
|
110
|
+
...baseOptions
|
|
111
|
+
};
|
|
112
|
+
let hasHydrated = false;
|
|
113
|
+
const hydrationListeners = /* @__PURE__ */ new Set();
|
|
114
|
+
const finishHydrationListeners = /* @__PURE__ */ new Set();
|
|
115
|
+
let storage = options.storage;
|
|
116
|
+
if (!storage) {
|
|
117
|
+
return config(
|
|
118
|
+
(...args) => {
|
|
119
|
+
console.warn(
|
|
120
|
+
`[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
|
|
121
|
+
);
|
|
122
|
+
set(...args);
|
|
123
|
+
},
|
|
124
|
+
get,
|
|
125
|
+
api
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
const setItem = () => {
|
|
129
|
+
const state = options.partialize({ ...get() });
|
|
130
|
+
return storage.setItem(options.name, {
|
|
131
|
+
state,
|
|
132
|
+
version: options.version
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
const savedSetState = api.setState;
|
|
136
|
+
api.setState = (state, replace) => {
|
|
137
|
+
savedSetState(state, replace);
|
|
138
|
+
void setItem();
|
|
139
|
+
};
|
|
140
|
+
const configResult = config(
|
|
141
|
+
(...args) => {
|
|
142
|
+
set(...args);
|
|
143
|
+
void setItem();
|
|
144
|
+
},
|
|
145
|
+
get,
|
|
146
|
+
api
|
|
147
|
+
);
|
|
148
|
+
api.getInitialState = () => configResult;
|
|
149
|
+
let stateFromStorage;
|
|
150
|
+
const hydrate = () => {
|
|
151
|
+
var _a, _b;
|
|
152
|
+
if (!storage) return;
|
|
153
|
+
hasHydrated = false;
|
|
154
|
+
hydrationListeners.forEach((cb) => {
|
|
155
|
+
var _a2;
|
|
156
|
+
return cb((_a2 = get()) != null ? _a2 : configResult);
|
|
157
|
+
});
|
|
158
|
+
const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? undefined : _b.call(options, (_a = get()) != null ? _a : configResult)) || undefined;
|
|
159
|
+
return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {
|
|
160
|
+
if (deserializedStorageValue) {
|
|
161
|
+
if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
|
|
162
|
+
if (options.migrate) {
|
|
163
|
+
const migration = options.migrate(
|
|
164
|
+
deserializedStorageValue.state,
|
|
165
|
+
deserializedStorageValue.version
|
|
166
|
+
);
|
|
167
|
+
if (migration instanceof Promise) {
|
|
168
|
+
return migration.then((result) => [true, result]);
|
|
169
|
+
}
|
|
170
|
+
return [true, migration];
|
|
171
|
+
}
|
|
172
|
+
console.error(
|
|
173
|
+
`State loaded from storage couldn't be migrated since no migrate function was provided`
|
|
174
|
+
);
|
|
175
|
+
} else {
|
|
176
|
+
return [false, deserializedStorageValue.state];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return [false, undefined];
|
|
180
|
+
}).then((migrationResult) => {
|
|
181
|
+
var _a2;
|
|
182
|
+
const [migrated, migratedState] = migrationResult;
|
|
183
|
+
stateFromStorage = options.merge(
|
|
184
|
+
migratedState,
|
|
185
|
+
(_a2 = get()) != null ? _a2 : configResult
|
|
186
|
+
);
|
|
187
|
+
set(stateFromStorage, true);
|
|
188
|
+
if (migrated) {
|
|
189
|
+
return setItem();
|
|
190
|
+
}
|
|
191
|
+
}).then(() => {
|
|
192
|
+
postRehydrationCallback == null ? undefined : postRehydrationCallback(stateFromStorage, undefined);
|
|
193
|
+
stateFromStorage = get();
|
|
194
|
+
hasHydrated = true;
|
|
195
|
+
finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
|
|
196
|
+
}).catch((e) => {
|
|
197
|
+
postRehydrationCallback == null ? undefined : postRehydrationCallback(undefined, e);
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
api.persist = {
|
|
201
|
+
setOptions: (newOptions) => {
|
|
202
|
+
options = {
|
|
203
|
+
...options,
|
|
204
|
+
...newOptions
|
|
205
|
+
};
|
|
206
|
+
if (newOptions.storage) {
|
|
207
|
+
storage = newOptions.storage;
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
clearStorage: () => {
|
|
211
|
+
storage == null ? undefined : storage.removeItem(options.name);
|
|
212
|
+
},
|
|
213
|
+
getOptions: () => options,
|
|
214
|
+
rehydrate: () => hydrate(),
|
|
215
|
+
hasHydrated: () => hasHydrated,
|
|
216
|
+
onHydrate: (cb) => {
|
|
217
|
+
hydrationListeners.add(cb);
|
|
218
|
+
return () => {
|
|
219
|
+
hydrationListeners.delete(cb);
|
|
220
|
+
};
|
|
221
|
+
},
|
|
222
|
+
onFinishHydration: (cb) => {
|
|
223
|
+
finishHydrationListeners.add(cb);
|
|
224
|
+
return () => {
|
|
225
|
+
finishHydrationListeners.delete(cb);
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
if (!options.skipHydration) {
|
|
230
|
+
hydrate();
|
|
231
|
+
}
|
|
232
|
+
return stateFromStorage || configResult;
|
|
233
|
+
};
|
|
234
|
+
const persist = persistImpl;
|
|
235
|
+
|
|
236
|
+
const generateLineItemId = (item) => {
|
|
237
|
+
return btoa(JSON.stringify({
|
|
238
|
+
productId: item.productId,
|
|
239
|
+
variantOptions: item.variantOptions,
|
|
240
|
+
metadata: item.metadata,
|
|
241
|
+
}));
|
|
242
|
+
};
|
|
243
|
+
const useCart = create()(persist((set, get) => ({
|
|
244
|
+
lineItems: [],
|
|
245
|
+
addItem: (newItem) => set((state) => {
|
|
246
|
+
const id = generateLineItemId(newItem);
|
|
247
|
+
const existingItemIndex = state.lineItems.findIndex((item) => item.id === id);
|
|
248
|
+
if (existingItemIndex !== -1) {
|
|
249
|
+
const updatedItems = [...state.lineItems];
|
|
250
|
+
updatedItems[existingItemIndex] = Object.assign(Object.assign({}, updatedItems[existingItemIndex]), { quantity: updatedItems[existingItemIndex].quantity + newItem.quantity });
|
|
251
|
+
return { lineItems: updatedItems };
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
lineItems: [...state.lineItems, Object.assign(Object.assign({}, newItem), { id })],
|
|
255
|
+
};
|
|
256
|
+
}),
|
|
257
|
+
removeItem: (id) => set((state) => ({
|
|
258
|
+
lineItems: state.lineItems.filter((i) => i.id !== id),
|
|
259
|
+
})),
|
|
260
|
+
updateQuantity: (id, quantity) => set((state) => ({
|
|
261
|
+
lineItems: state.lineItems.map((i) => i.id === id ? Object.assign(Object.assign({}, i), { quantity }) : i),
|
|
262
|
+
})),
|
|
263
|
+
getProductQuantity: (productId) => {
|
|
264
|
+
const items = get().lineItems.filter((item) => item.productId === productId);
|
|
265
|
+
return items.reduce((acc, item) => acc + item.quantity, 0);
|
|
266
|
+
},
|
|
267
|
+
clearCart: () => set({ lineItems: [] }),
|
|
268
|
+
}), {
|
|
269
|
+
name: "cart",
|
|
270
|
+
}));
|
|
271
|
+
|
|
5
272
|
/******************************************************************************
|
|
6
273
|
Copyright (c) Microsoft Corporation.
|
|
7
274
|
|
|
@@ -76,18 +343,38 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, }) {
|
|
|
76
343
|
React.createElement("span", { className: "text-2xl font-bold" }, formatPrice(total)))))));
|
|
77
344
|
}
|
|
78
345
|
|
|
79
|
-
function CheckoutEmbed(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
346
|
+
function CheckoutEmbed({ betterStore, checkoutId, }) {
|
|
347
|
+
const [checkout, setCheckout] = React.useState(null);
|
|
348
|
+
const [loading, setLoading] = React.useState(true);
|
|
349
|
+
React.useEffect(() => {
|
|
350
|
+
function fetchCheckout() {
|
|
351
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
352
|
+
try {
|
|
353
|
+
const data = yield betterStore.checkout.retrieve(checkoutId);
|
|
354
|
+
setCheckout(data);
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
console.error("Failed to fetch checkout:", error);
|
|
358
|
+
}
|
|
359
|
+
finally {
|
|
360
|
+
setLoading(false);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
84
363
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
364
|
+
fetchCheckout();
|
|
365
|
+
}, [betterStore, checkoutId]);
|
|
366
|
+
if (loading) {
|
|
367
|
+
return React.createElement("div", null, "Loading...");
|
|
368
|
+
}
|
|
369
|
+
if (!checkout) {
|
|
370
|
+
return React.createElement("div", null, "Checkout not found");
|
|
371
|
+
}
|
|
372
|
+
return (React.createElement("div", { className: "grid md:grid-cols-2 gap-4" },
|
|
373
|
+
React.createElement("div", null, "forms here"),
|
|
374
|
+
React.createElement("div", null,
|
|
375
|
+
React.createElement(CheckoutSummary, { currency: checkout.currency, lineItems: checkout.lineItems, shipping: checkout === null || checkout === void 0 ? void 0 : checkout.shipping, tax: checkout === null || checkout === void 0 ? void 0 : checkout.tax }))));
|
|
90
376
|
}
|
|
377
|
+
var index$1 = React.memo(CheckoutEmbed);
|
|
91
378
|
|
|
92
379
|
function getDefaultExportFromCjs (x) {
|
|
93
380
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -2196,47 +2483,6 @@ var loadStripe = function loadStripe() {
|
|
|
2196
2483
|
});
|
|
2197
2484
|
};
|
|
2198
2485
|
|
|
2199
|
-
const createStoreImpl = (createState) => {
|
|
2200
|
-
let state;
|
|
2201
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
2202
|
-
const setState = (partial, replace) => {
|
|
2203
|
-
const nextState = typeof partial === "function" ? partial(state) : partial;
|
|
2204
|
-
if (!Object.is(nextState, state)) {
|
|
2205
|
-
const previousState = state;
|
|
2206
|
-
state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
|
|
2207
|
-
listeners.forEach((listener) => listener(state, previousState));
|
|
2208
|
-
}
|
|
2209
|
-
};
|
|
2210
|
-
const getState = () => state;
|
|
2211
|
-
const getInitialState = () => initialState;
|
|
2212
|
-
const subscribe = (listener) => {
|
|
2213
|
-
listeners.add(listener);
|
|
2214
|
-
return () => listeners.delete(listener);
|
|
2215
|
-
};
|
|
2216
|
-
const api = { setState, getState, getInitialState, subscribe };
|
|
2217
|
-
const initialState = state = createState(setState, getState, api);
|
|
2218
|
-
return api;
|
|
2219
|
-
};
|
|
2220
|
-
const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
|
|
2221
|
-
|
|
2222
|
-
const identity = (arg) => arg;
|
|
2223
|
-
function useStore(api, selector = identity) {
|
|
2224
|
-
const slice = React.useSyncExternalStore(
|
|
2225
|
-
api.subscribe,
|
|
2226
|
-
() => selector(api.getState()),
|
|
2227
|
-
() => selector(api.getInitialState())
|
|
2228
|
-
);
|
|
2229
|
-
React.useDebugValue(slice);
|
|
2230
|
-
return slice;
|
|
2231
|
-
}
|
|
2232
|
-
const createImpl = (createState) => {
|
|
2233
|
-
const api = createStore(createState);
|
|
2234
|
-
const useBoundStore = (selector) => useStore(api, selector);
|
|
2235
|
-
Object.assign(useBoundStore, api);
|
|
2236
|
-
return useBoundStore;
|
|
2237
|
-
};
|
|
2238
|
-
const create = (createState) => createState ? createImpl(createState) : createImpl;
|
|
2239
|
-
|
|
2240
2486
|
const useCheckout = create((set) => ({
|
|
2241
2487
|
isSubmitting: false,
|
|
2242
2488
|
setIsSubmitting: (isSubmitting) => set({ isSubmitting }),
|
|
@@ -2285,8 +2531,9 @@ function PaymentElement({ paymentSecret, checkoutAppearance, onSuccess, onError,
|
|
|
2285
2531
|
return (React.createElement(Elements, { stripe: stripePromise, options: options },
|
|
2286
2532
|
React.createElement(CheckoutForm$1, { onSuccess: onSuccess, onError: onError, children: children })));
|
|
2287
2533
|
}
|
|
2288
|
-
var
|
|
2534
|
+
var index = React.memo(PaymentElement);
|
|
2289
2535
|
|
|
2290
|
-
exports.CheckoutEmbed =
|
|
2291
|
-
exports.PaymentElement =
|
|
2536
|
+
exports.CheckoutEmbed = index$1;
|
|
2537
|
+
exports.PaymentElement = index;
|
|
2538
|
+
exports.useCart = useCart;
|
|
2292
2539
|
exports.useCheckout = useCheckout;
|
package/dist/index.d.ts
CHANGED
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,271 @@
|
|
|
1
|
-
import React, { memo, useState } from 'react';
|
|
1
|
+
import React, { memo, useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
const createStoreImpl = (createState) => {
|
|
4
|
+
let state;
|
|
5
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
const setState = (partial, replace) => {
|
|
7
|
+
const nextState = typeof partial === "function" ? partial(state) : partial;
|
|
8
|
+
if (!Object.is(nextState, state)) {
|
|
9
|
+
const previousState = state;
|
|
10
|
+
state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
|
|
11
|
+
listeners.forEach((listener) => listener(state, previousState));
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const getState = () => state;
|
|
15
|
+
const getInitialState = () => initialState;
|
|
16
|
+
const subscribe = (listener) => {
|
|
17
|
+
listeners.add(listener);
|
|
18
|
+
return () => listeners.delete(listener);
|
|
19
|
+
};
|
|
20
|
+
const api = { setState, getState, getInitialState, subscribe };
|
|
21
|
+
const initialState = state = createState(setState, getState, api);
|
|
22
|
+
return api;
|
|
23
|
+
};
|
|
24
|
+
const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
|
|
25
|
+
|
|
26
|
+
const identity = (arg) => arg;
|
|
27
|
+
function useStore(api, selector = identity) {
|
|
28
|
+
const slice = React.useSyncExternalStore(
|
|
29
|
+
api.subscribe,
|
|
30
|
+
() => selector(api.getState()),
|
|
31
|
+
() => selector(api.getInitialState())
|
|
32
|
+
);
|
|
33
|
+
React.useDebugValue(slice);
|
|
34
|
+
return slice;
|
|
35
|
+
}
|
|
36
|
+
const createImpl = (createState) => {
|
|
37
|
+
const api = createStore(createState);
|
|
38
|
+
const useBoundStore = (selector) => useStore(api, selector);
|
|
39
|
+
Object.assign(useBoundStore, api);
|
|
40
|
+
return useBoundStore;
|
|
41
|
+
};
|
|
42
|
+
const create = (createState) => createState ? createImpl(createState) : createImpl;
|
|
43
|
+
|
|
44
|
+
function createJSONStorage(getStorage, options) {
|
|
45
|
+
let storage;
|
|
46
|
+
try {
|
|
47
|
+
storage = getStorage();
|
|
48
|
+
} catch (e) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const persistStorage = {
|
|
52
|
+
getItem: (name) => {
|
|
53
|
+
var _a;
|
|
54
|
+
const parse = (str2) => {
|
|
55
|
+
if (str2 === null) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return JSON.parse(str2, undefined );
|
|
59
|
+
};
|
|
60
|
+
const str = (_a = storage.getItem(name)) != null ? _a : null;
|
|
61
|
+
if (str instanceof Promise) {
|
|
62
|
+
return str.then(parse);
|
|
63
|
+
}
|
|
64
|
+
return parse(str);
|
|
65
|
+
},
|
|
66
|
+
setItem: (name, newValue) => storage.setItem(
|
|
67
|
+
name,
|
|
68
|
+
JSON.stringify(newValue, undefined )
|
|
69
|
+
),
|
|
70
|
+
removeItem: (name) => storage.removeItem(name)
|
|
71
|
+
};
|
|
72
|
+
return persistStorage;
|
|
73
|
+
}
|
|
74
|
+
const toThenable = (fn) => (input) => {
|
|
75
|
+
try {
|
|
76
|
+
const result = fn(input);
|
|
77
|
+
if (result instanceof Promise) {
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
then(onFulfilled) {
|
|
82
|
+
return toThenable(onFulfilled)(result);
|
|
83
|
+
},
|
|
84
|
+
catch(_onRejected) {
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
} catch (e) {
|
|
89
|
+
return {
|
|
90
|
+
then(_onFulfilled) {
|
|
91
|
+
return this;
|
|
92
|
+
},
|
|
93
|
+
catch(onRejected) {
|
|
94
|
+
return toThenable(onRejected)(e);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const persistImpl = (config, baseOptions) => (set, get, api) => {
|
|
100
|
+
let options = {
|
|
101
|
+
storage: createJSONStorage(() => localStorage),
|
|
102
|
+
partialize: (state) => state,
|
|
103
|
+
version: 0,
|
|
104
|
+
merge: (persistedState, currentState) => ({
|
|
105
|
+
...currentState,
|
|
106
|
+
...persistedState
|
|
107
|
+
}),
|
|
108
|
+
...baseOptions
|
|
109
|
+
};
|
|
110
|
+
let hasHydrated = false;
|
|
111
|
+
const hydrationListeners = /* @__PURE__ */ new Set();
|
|
112
|
+
const finishHydrationListeners = /* @__PURE__ */ new Set();
|
|
113
|
+
let storage = options.storage;
|
|
114
|
+
if (!storage) {
|
|
115
|
+
return config(
|
|
116
|
+
(...args) => {
|
|
117
|
+
console.warn(
|
|
118
|
+
`[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`
|
|
119
|
+
);
|
|
120
|
+
set(...args);
|
|
121
|
+
},
|
|
122
|
+
get,
|
|
123
|
+
api
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
const setItem = () => {
|
|
127
|
+
const state = options.partialize({ ...get() });
|
|
128
|
+
return storage.setItem(options.name, {
|
|
129
|
+
state,
|
|
130
|
+
version: options.version
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
const savedSetState = api.setState;
|
|
134
|
+
api.setState = (state, replace) => {
|
|
135
|
+
savedSetState(state, replace);
|
|
136
|
+
void setItem();
|
|
137
|
+
};
|
|
138
|
+
const configResult = config(
|
|
139
|
+
(...args) => {
|
|
140
|
+
set(...args);
|
|
141
|
+
void setItem();
|
|
142
|
+
},
|
|
143
|
+
get,
|
|
144
|
+
api
|
|
145
|
+
);
|
|
146
|
+
api.getInitialState = () => configResult;
|
|
147
|
+
let stateFromStorage;
|
|
148
|
+
const hydrate = () => {
|
|
149
|
+
var _a, _b;
|
|
150
|
+
if (!storage) return;
|
|
151
|
+
hasHydrated = false;
|
|
152
|
+
hydrationListeners.forEach((cb) => {
|
|
153
|
+
var _a2;
|
|
154
|
+
return cb((_a2 = get()) != null ? _a2 : configResult);
|
|
155
|
+
});
|
|
156
|
+
const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? undefined : _b.call(options, (_a = get()) != null ? _a : configResult)) || undefined;
|
|
157
|
+
return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {
|
|
158
|
+
if (deserializedStorageValue) {
|
|
159
|
+
if (typeof deserializedStorageValue.version === "number" && deserializedStorageValue.version !== options.version) {
|
|
160
|
+
if (options.migrate) {
|
|
161
|
+
const migration = options.migrate(
|
|
162
|
+
deserializedStorageValue.state,
|
|
163
|
+
deserializedStorageValue.version
|
|
164
|
+
);
|
|
165
|
+
if (migration instanceof Promise) {
|
|
166
|
+
return migration.then((result) => [true, result]);
|
|
167
|
+
}
|
|
168
|
+
return [true, migration];
|
|
169
|
+
}
|
|
170
|
+
console.error(
|
|
171
|
+
`State loaded from storage couldn't be migrated since no migrate function was provided`
|
|
172
|
+
);
|
|
173
|
+
} else {
|
|
174
|
+
return [false, deserializedStorageValue.state];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return [false, undefined];
|
|
178
|
+
}).then((migrationResult) => {
|
|
179
|
+
var _a2;
|
|
180
|
+
const [migrated, migratedState] = migrationResult;
|
|
181
|
+
stateFromStorage = options.merge(
|
|
182
|
+
migratedState,
|
|
183
|
+
(_a2 = get()) != null ? _a2 : configResult
|
|
184
|
+
);
|
|
185
|
+
set(stateFromStorage, true);
|
|
186
|
+
if (migrated) {
|
|
187
|
+
return setItem();
|
|
188
|
+
}
|
|
189
|
+
}).then(() => {
|
|
190
|
+
postRehydrationCallback == null ? undefined : postRehydrationCallback(stateFromStorage, undefined);
|
|
191
|
+
stateFromStorage = get();
|
|
192
|
+
hasHydrated = true;
|
|
193
|
+
finishHydrationListeners.forEach((cb) => cb(stateFromStorage));
|
|
194
|
+
}).catch((e) => {
|
|
195
|
+
postRehydrationCallback == null ? undefined : postRehydrationCallback(undefined, e);
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
api.persist = {
|
|
199
|
+
setOptions: (newOptions) => {
|
|
200
|
+
options = {
|
|
201
|
+
...options,
|
|
202
|
+
...newOptions
|
|
203
|
+
};
|
|
204
|
+
if (newOptions.storage) {
|
|
205
|
+
storage = newOptions.storage;
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
clearStorage: () => {
|
|
209
|
+
storage == null ? undefined : storage.removeItem(options.name);
|
|
210
|
+
},
|
|
211
|
+
getOptions: () => options,
|
|
212
|
+
rehydrate: () => hydrate(),
|
|
213
|
+
hasHydrated: () => hasHydrated,
|
|
214
|
+
onHydrate: (cb) => {
|
|
215
|
+
hydrationListeners.add(cb);
|
|
216
|
+
return () => {
|
|
217
|
+
hydrationListeners.delete(cb);
|
|
218
|
+
};
|
|
219
|
+
},
|
|
220
|
+
onFinishHydration: (cb) => {
|
|
221
|
+
finishHydrationListeners.add(cb);
|
|
222
|
+
return () => {
|
|
223
|
+
finishHydrationListeners.delete(cb);
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
if (!options.skipHydration) {
|
|
228
|
+
hydrate();
|
|
229
|
+
}
|
|
230
|
+
return stateFromStorage || configResult;
|
|
231
|
+
};
|
|
232
|
+
const persist = persistImpl;
|
|
233
|
+
|
|
234
|
+
const generateLineItemId = (item) => {
|
|
235
|
+
return btoa(JSON.stringify({
|
|
236
|
+
productId: item.productId,
|
|
237
|
+
variantOptions: item.variantOptions,
|
|
238
|
+
metadata: item.metadata,
|
|
239
|
+
}));
|
|
240
|
+
};
|
|
241
|
+
const useCart = create()(persist((set, get) => ({
|
|
242
|
+
lineItems: [],
|
|
243
|
+
addItem: (newItem) => set((state) => {
|
|
244
|
+
const id = generateLineItemId(newItem);
|
|
245
|
+
const existingItemIndex = state.lineItems.findIndex((item) => item.id === id);
|
|
246
|
+
if (existingItemIndex !== -1) {
|
|
247
|
+
const updatedItems = [...state.lineItems];
|
|
248
|
+
updatedItems[existingItemIndex] = Object.assign(Object.assign({}, updatedItems[existingItemIndex]), { quantity: updatedItems[existingItemIndex].quantity + newItem.quantity });
|
|
249
|
+
return { lineItems: updatedItems };
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
lineItems: [...state.lineItems, Object.assign(Object.assign({}, newItem), { id })],
|
|
253
|
+
};
|
|
254
|
+
}),
|
|
255
|
+
removeItem: (id) => set((state) => ({
|
|
256
|
+
lineItems: state.lineItems.filter((i) => i.id !== id),
|
|
257
|
+
})),
|
|
258
|
+
updateQuantity: (id, quantity) => set((state) => ({
|
|
259
|
+
lineItems: state.lineItems.map((i) => i.id === id ? Object.assign(Object.assign({}, i), { quantity }) : i),
|
|
260
|
+
})),
|
|
261
|
+
getProductQuantity: (productId) => {
|
|
262
|
+
const items = get().lineItems.filter((item) => item.productId === productId);
|
|
263
|
+
return items.reduce((acc, item) => acc + item.quantity, 0);
|
|
264
|
+
},
|
|
265
|
+
clearCart: () => set({ lineItems: [] }),
|
|
266
|
+
}), {
|
|
267
|
+
name: "cart",
|
|
268
|
+
}));
|
|
2
269
|
|
|
3
270
|
/******************************************************************************
|
|
4
271
|
Copyright (c) Microsoft Corporation.
|
|
@@ -74,18 +341,38 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, }) {
|
|
|
74
341
|
React.createElement("span", { className: "text-2xl font-bold" }, formatPrice(total)))))));
|
|
75
342
|
}
|
|
76
343
|
|
|
77
|
-
function CheckoutEmbed(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
344
|
+
function CheckoutEmbed({ betterStore, checkoutId, }) {
|
|
345
|
+
const [checkout, setCheckout] = useState(null);
|
|
346
|
+
const [loading, setLoading] = useState(true);
|
|
347
|
+
useEffect(() => {
|
|
348
|
+
function fetchCheckout() {
|
|
349
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
350
|
+
try {
|
|
351
|
+
const data = yield betterStore.checkout.retrieve(checkoutId);
|
|
352
|
+
setCheckout(data);
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
console.error("Failed to fetch checkout:", error);
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
setLoading(false);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
82
361
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
362
|
+
fetchCheckout();
|
|
363
|
+
}, [betterStore, checkoutId]);
|
|
364
|
+
if (loading) {
|
|
365
|
+
return React.createElement("div", null, "Loading...");
|
|
366
|
+
}
|
|
367
|
+
if (!checkout) {
|
|
368
|
+
return React.createElement("div", null, "Checkout not found");
|
|
369
|
+
}
|
|
370
|
+
return (React.createElement("div", { className: "grid md:grid-cols-2 gap-4" },
|
|
371
|
+
React.createElement("div", null, "forms here"),
|
|
372
|
+
React.createElement("div", null,
|
|
373
|
+
React.createElement(CheckoutSummary, { currency: checkout.currency, lineItems: checkout.lineItems, shipping: checkout === null || checkout === void 0 ? void 0 : checkout.shipping, tax: checkout === null || checkout === void 0 ? void 0 : checkout.tax }))));
|
|
88
374
|
}
|
|
375
|
+
var index$1 = memo(CheckoutEmbed);
|
|
89
376
|
|
|
90
377
|
function getDefaultExportFromCjs (x) {
|
|
91
378
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -2194,47 +2481,6 @@ var loadStripe = function loadStripe() {
|
|
|
2194
2481
|
});
|
|
2195
2482
|
};
|
|
2196
2483
|
|
|
2197
|
-
const createStoreImpl = (createState) => {
|
|
2198
|
-
let state;
|
|
2199
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
2200
|
-
const setState = (partial, replace) => {
|
|
2201
|
-
const nextState = typeof partial === "function" ? partial(state) : partial;
|
|
2202
|
-
if (!Object.is(nextState, state)) {
|
|
2203
|
-
const previousState = state;
|
|
2204
|
-
state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
|
|
2205
|
-
listeners.forEach((listener) => listener(state, previousState));
|
|
2206
|
-
}
|
|
2207
|
-
};
|
|
2208
|
-
const getState = () => state;
|
|
2209
|
-
const getInitialState = () => initialState;
|
|
2210
|
-
const subscribe = (listener) => {
|
|
2211
|
-
listeners.add(listener);
|
|
2212
|
-
return () => listeners.delete(listener);
|
|
2213
|
-
};
|
|
2214
|
-
const api = { setState, getState, getInitialState, subscribe };
|
|
2215
|
-
const initialState = state = createState(setState, getState, api);
|
|
2216
|
-
return api;
|
|
2217
|
-
};
|
|
2218
|
-
const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
|
|
2219
|
-
|
|
2220
|
-
const identity = (arg) => arg;
|
|
2221
|
-
function useStore(api, selector = identity) {
|
|
2222
|
-
const slice = React.useSyncExternalStore(
|
|
2223
|
-
api.subscribe,
|
|
2224
|
-
() => selector(api.getState()),
|
|
2225
|
-
() => selector(api.getInitialState())
|
|
2226
|
-
);
|
|
2227
|
-
React.useDebugValue(slice);
|
|
2228
|
-
return slice;
|
|
2229
|
-
}
|
|
2230
|
-
const createImpl = (createState) => {
|
|
2231
|
-
const api = createStore(createState);
|
|
2232
|
-
const useBoundStore = (selector) => useStore(api, selector);
|
|
2233
|
-
Object.assign(useBoundStore, api);
|
|
2234
|
-
return useBoundStore;
|
|
2235
|
-
};
|
|
2236
|
-
const create = (createState) => createState ? createImpl(createState) : createImpl;
|
|
2237
|
-
|
|
2238
2484
|
const useCheckout = create((set) => ({
|
|
2239
2485
|
isSubmitting: false,
|
|
2240
2486
|
setIsSubmitting: (isSubmitting) => set({ isSubmitting }),
|
|
@@ -2283,6 +2529,6 @@ function PaymentElement({ paymentSecret, checkoutAppearance, onSuccess, onError,
|
|
|
2283
2529
|
return (React.createElement(Elements, { stripe: stripePromise, options: options },
|
|
2284
2530
|
React.createElement(CheckoutForm$1, { onSuccess: onSuccess, onError: onError, children: children })));
|
|
2285
2531
|
}
|
|
2286
|
-
var
|
|
2532
|
+
var index = memo(PaymentElement);
|
|
2287
2533
|
|
|
2288
|
-
export { CheckoutEmbed,
|
|
2534
|
+
export { index$1 as CheckoutEmbed, index as PaymentElement, useCart, useCheckout };
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|