@swishapp/react 0.130.0 → 0.131.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/index.d.mts +20 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +57 -109
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ApiError, ApiResponse, EditItemListsSuccessResponse, EditItemVariantSuccessResponse, EventName, Intent, IntentResponse, IntentToData, Item, PageInfo, PaginatedApiResponse, SaveItemSuccessResponse, SwishApp, SwishOptionsInput, UnsaveItemSuccessResponse } from "@swishapp/sdk";
|
|
1
|
+
import { ApiError, ApiResponse, EditItemListsSuccessResponse, EditItemVariantSuccessResponse, EventName, Intent, IntentResponse, IntentToData, Item, ItemMatch, PageInfo, PaginatedApiResponse, SaveItemSuccessResponse, SwishApp, SwishOptionsInput, UnsaveItemSuccessResponse } from "@swishapp/sdk";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
3
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
|
-
import * as
|
|
4
|
+
import * as _swishapp_api_client3 from "@swishapp/api-client";
|
|
5
5
|
export * from "@swishapp/sdk";
|
|
6
6
|
|
|
7
7
|
//#region src/types.d.ts
|
|
@@ -57,8 +57,8 @@ declare const useSwishIntent: <I extends Intent = Intent>(intent: I, ...args: In
|
|
|
57
57
|
//#region src/hooks/use-swish-lists.d.ts
|
|
58
58
|
declare const useSwishLists: () => {
|
|
59
59
|
loading: boolean;
|
|
60
|
-
lists:
|
|
61
|
-
error:
|
|
60
|
+
lists: _swishapp_api_client3.ListDetail[] | null;
|
|
61
|
+
error: _swishapp_api_client3.ApiError | null;
|
|
62
62
|
reset: () => void;
|
|
63
63
|
};
|
|
64
64
|
//#endregion
|
|
@@ -73,8 +73,8 @@ declare const useSwishItems: ({
|
|
|
73
73
|
}?: UseSwishItemsOptions) => {
|
|
74
74
|
loading: boolean;
|
|
75
75
|
data: Item[];
|
|
76
|
-
pageInfo:
|
|
77
|
-
error:
|
|
76
|
+
pageInfo: _swishapp_api_client3.PageInfo | null;
|
|
77
|
+
error: _swishapp_api_client3.ApiError | null;
|
|
78
78
|
reset: () => void;
|
|
79
79
|
hasMore: boolean;
|
|
80
80
|
loadMore: () => void;
|
|
@@ -85,6 +85,13 @@ interface UseSwishItemProps {
|
|
|
85
85
|
productId: string | number;
|
|
86
86
|
variantId?: string | number;
|
|
87
87
|
itemId?: string;
|
|
88
|
+
/**
|
|
89
|
+
* How to interpret saved state when `variantId` is set:
|
|
90
|
+
* - `"variant"`: only saved if the variant matches.
|
|
91
|
+
* - `"product"`: saved if any variant of the product is saved.
|
|
92
|
+
* - `"auto"` (default): variant-match when `variantId` is set, product-match otherwise.
|
|
93
|
+
*/
|
|
94
|
+
match?: ItemMatch;
|
|
88
95
|
onSave?: (data: SaveItemSuccessResponse["data"]) => void;
|
|
89
96
|
onUnsave?: (data: UnsaveItemSuccessResponse["data"]) => void;
|
|
90
97
|
onListsUpdate?: (data: EditItemListsSuccessResponse["data"]) => void;
|
|
@@ -94,6 +101,7 @@ declare const useSwishItem: ({
|
|
|
94
101
|
productId,
|
|
95
102
|
variantId,
|
|
96
103
|
itemId,
|
|
104
|
+
match,
|
|
97
105
|
onSave,
|
|
98
106
|
onUnsave,
|
|
99
107
|
onListsUpdate,
|
|
@@ -101,7 +109,11 @@ declare const useSwishItem: ({
|
|
|
101
109
|
}: UseSwishItemProps) => {
|
|
102
110
|
saved: boolean;
|
|
103
111
|
loading: boolean;
|
|
104
|
-
|
|
112
|
+
saving: boolean;
|
|
113
|
+
unsaving: boolean;
|
|
114
|
+
error: _swishapp_api_client3.ApiError | null;
|
|
115
|
+
savedItemId: string | null;
|
|
116
|
+
savedItemIds: string[];
|
|
105
117
|
save: () => Promise<void>;
|
|
106
118
|
unsave: () => Promise<void>;
|
|
107
119
|
updateLists: () => Promise<void>;
|
|
@@ -113,7 +125,7 @@ declare const useSwishItem: ({
|
|
|
113
125
|
declare const useSwishItemCount: () => {
|
|
114
126
|
count: number;
|
|
115
127
|
loading: boolean;
|
|
116
|
-
error:
|
|
128
|
+
error: _swishapp_api_client3.ApiError | null;
|
|
117
129
|
};
|
|
118
130
|
//#endregion
|
|
119
131
|
export { SwishContextValue, SwishProvider, type SwishProviderProps, useSwish, useSwishIntent, useSwishItem, useSwishItemCount, useSwishItems, useSwishLists, useSwishQuery };
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/context.tsx","../src/hooks/use-swish.ts","../src/hooks/use-swish-query.ts","../src/hooks/use-swish-intent.ts","../src/hooks/use-swish-lists.ts","../src/hooks/use-swish-items.ts","../src/hooks/use-swish-item.ts","../src/hooks/use-swish-item-count.ts"],"sourcesContent":[],"mappings":";;;;;;;UAEiB,iBAAA;SACR;;SAEA;;;;UCKQ,kBAAA;YACL;WACD;;EDVM,CAAA;;iBCaD,aAAA;;;;;;GAGb,qBAAkB,kBAAA,CAAA,GAAA,CAAA;;;iBCdL,QAAA,CAAA,GAAY;;;KCOhB,yCACH,6BACK,eACT,QAAQ;KAeR,YAAY;;;cAEJ,kCACO,mBAAmB,8CAG9B,QAAQ,WAAW;cAEZ;;EHnCC,OAAA,CAAA,EAAA,OAAA,GGqCO,SHrCU,EACzB;;;;ECOQ,KAAA,UAAA,GAAA,IAAkB;EAKnB,OAAA,EAAA,OAAa;EAC3B,KAAA,EAAA,GAAA,GAAA,IAAA;EACW,OAAA,EAAA,GAAA,GAAA,IAAA;EACV,UAAA,EAAA,OAAA;CAAkB;;;cGdR,2BAA4B,SAAS,gBACxC,YACC,aAAa,sCAAsC,aAAa;gBAUpC,QAAQ,eAAe;;;;;cCbjD;;SAyBZ,qBAAA,CAAA,UAAA;SAAA,qBAAA,CAAA,QAAA;;;;;UCxBgB,oBAAA;;;;cAKJ;;;IAGV;;;ENVc,QAAA,mCAGH,IAAA;;;;ECKG,QAAA,EAAA,GAAA,GAAA,IAAA;AAKjB,CAAA;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/context.tsx","../src/hooks/use-swish.ts","../src/hooks/use-swish-query.ts","../src/hooks/use-swish-intent.ts","../src/hooks/use-swish-lists.ts","../src/hooks/use-swish-items.ts","../src/hooks/use-swish-item.ts","../src/hooks/use-swish-item-count.ts"],"sourcesContent":[],"mappings":";;;;;;;UAEiB,iBAAA;SACR;;SAEA;;;;UCKQ,kBAAA;YACL;WACD;;EDVM,CAAA;;iBCaD,aAAA;;;;;;GAGb,qBAAkB,kBAAA,CAAA,GAAA,CAAA;;;iBCdL,QAAA,CAAA,GAAY;;;KCOhB,yCACH,6BACK,eACT,QAAQ;KAeR,YAAY;;;cAEJ,kCACO,mBAAmB,8CAG9B,QAAQ,WAAW;cAEZ;;EHnCC,OAAA,CAAA,EAAA,OAAA,GGqCO,SHrCU,EACzB;;;;ECOQ,KAAA,UAAA,GAAA,IAAkB;EAKnB,OAAA,EAAA,OAAa;EAC3B,KAAA,EAAA,GAAA,GAAA,IAAA;EACW,OAAA,EAAA,GAAA,GAAA,IAAA;EACV,UAAA,EAAA,OAAA;CAAkB;;;cGdR,2BAA4B,SAAS,gBACxC,YACC,aAAa,sCAAsC,aAAa;gBAUpC,QAAQ,eAAe;;;;;cCbjD;;SAyBZ,qBAAA,CAAA,UAAA;SAAA,qBAAA,CAAA,QAAA;;;;;UCxBgB,oBAAA;;;;cAKJ;;;IAGV;;;ENVc,QAAA,mCAGH,IAAA;;;;ECKG,QAAA,EAAA,GAAA,GAAA,IAAA;AAKjB,CAAA;;;UMAU,iBAAA;;;;;;;APbV;;;UOuBU;ENfO,MAAA,CAAA,EAAA,CAAA,IAAA,EMgBC,uBNfN,CAAA,MACD,CAAA,EAAA,GAAA,IAAA;EAGK,QAAA,CAAA,EAAA,CAAA,IAAa,EMYT,yBNZS,CAAA,MAAA,CAAA,EAAA,GAAA,IAAA;EAC3B,aAAA,CAAA,EAAA,CAAA,IAAA,EMYuB,4BNZvB,CAAA,MAAA,CAAA,EAAA,GAAA,IAAA;EACW,eAAA,CAAA,EAAA,CAAA,IAAA,EMYc,8BNZd,CAAA,MAAA,CAAA,EAAA,GAAA,IAAA;;AACQ,cM6BR,YN7BQ,EAAA,CAAA;EAAA,SAAA;EAAA,SAAA;EAAA,MAAA;EAAA,KAAA;EAAA,MAAA;EAAA,QAAA;EAAA,aAAA;EAAA;AAAA,CAAA,EMsClB,iBNtCkB,EAAA,GAAA;EAAA,KAAA,EAAA,OAAA;;;;ECdL,KAAA,EKoDI,qBAAA,CAAA,QAAA,GLpDgB,IAAA;;;;ECOxB,MAAA,EAAA,GAAO,UAAA,CAAA,IAAA,CAAA;EACV,WAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EACK,aAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;EACD,MAAA,EAAA,GAAA,UAAA,CAAA,IAAA,CAAA;CAAR;;;cKXQ;;;SAYZ,qBAAA,CAAA,QAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { swishSdkUrl } from "@swishapp/sdk";
|
|
2
|
-
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
|
|
5
5
|
//#region src/context.tsx
|
|
@@ -227,122 +227,70 @@ const useSwishItems = ({ listId, limit = 24 } = {}) => {
|
|
|
227
227
|
]);
|
|
228
228
|
};
|
|
229
229
|
|
|
230
|
-
//#endregion
|
|
231
|
-
//#region src/utils/shopify-utils.ts
|
|
232
|
-
const gidToId = (gid) => {
|
|
233
|
-
return gid?.split("/").pop();
|
|
234
|
-
};
|
|
235
|
-
|
|
236
230
|
//#endregion
|
|
237
231
|
//#region src/hooks/use-swish-item.ts
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const
|
|
253
|
-
const
|
|
254
|
-
|
|
232
|
+
const NOT_READY_SNAPSHOT = {
|
|
233
|
+
status: "unsaved",
|
|
234
|
+
saved: false,
|
|
235
|
+
saving: false,
|
|
236
|
+
unsaving: false,
|
|
237
|
+
loading: true,
|
|
238
|
+
submitting: false,
|
|
239
|
+
savedItemId: null,
|
|
240
|
+
savedItemIds: [],
|
|
241
|
+
error: null
|
|
242
|
+
};
|
|
243
|
+
const noop = () => {};
|
|
244
|
+
const noopAsync = async () => {};
|
|
245
|
+
const useSwishItem = ({ productId, variantId, itemId, match, onSave, onUnsave, onListsUpdate, onVariantUpdate }) => {
|
|
246
|
+
const swish = useSwish();
|
|
247
|
+
const state = useMemo(() => {
|
|
248
|
+
if (!swish) return null;
|
|
249
|
+
const context = swish.state.itemContextFromIds({
|
|
250
|
+
productId,
|
|
251
|
+
variantId,
|
|
252
|
+
itemId
|
|
253
|
+
});
|
|
254
|
+
return swish.state.itemState(context);
|
|
255
|
+
}, [
|
|
256
|
+
swish,
|
|
255
257
|
productId,
|
|
256
|
-
variantId
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
variables: {
|
|
266
|
-
limit: 1,
|
|
267
|
-
query: useMemo(() => {
|
|
268
|
-
if (variantId) return `variant:${gidToId(variantId.toString())}`;
|
|
269
|
-
return `product:${gidToId(productId.toString())}`;
|
|
270
|
-
}, [productId, variantId])
|
|
271
|
-
},
|
|
272
|
-
skip: Boolean(itemId) || !productId
|
|
258
|
+
variantId,
|
|
259
|
+
itemId
|
|
260
|
+
]);
|
|
261
|
+
if (state) state.setOptions({
|
|
262
|
+
onSave,
|
|
263
|
+
onUnsave,
|
|
264
|
+
onListsUpdate,
|
|
265
|
+
onVariantUpdate,
|
|
266
|
+
match
|
|
273
267
|
});
|
|
274
|
-
const saved = useMemo(() => Boolean(savedItemId), [savedItemId]);
|
|
275
|
-
const error = useMemo(() => savedItemsError, [savedItemsError]);
|
|
276
|
-
const loading = useMemo(() => savedItemsLoading || creatingItem, [savedItemsLoading, creatingItem]);
|
|
277
268
|
useEffect(() => {
|
|
278
|
-
if (
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
onUnsaveRef.current?.(data);
|
|
288
|
-
}
|
|
289
|
-
}, [unsaveItem]);
|
|
290
|
-
const updateLists = useCallback(async () => {
|
|
291
|
-
const response = await editItemLists();
|
|
292
|
-
if (response.code !== "ok") return;
|
|
293
|
-
if (response.intent === "unsave:item") {
|
|
294
|
-
const data = response.data;
|
|
295
|
-
setSavedItemId(null);
|
|
296
|
-
onUnsaveRef.current?.(data);
|
|
297
|
-
} else {
|
|
298
|
-
const data = response.data;
|
|
299
|
-
onListsUpdateRef.current?.(data);
|
|
300
|
-
}
|
|
301
|
-
}, [editItemLists]);
|
|
302
|
-
const updateVariant = useCallback(async () => {
|
|
303
|
-
const response = await editItemVariant();
|
|
304
|
-
if (response.code === "ok") {
|
|
305
|
-
const data = response.data;
|
|
306
|
-
onVariantUpdateRef.current?.(data);
|
|
307
|
-
}
|
|
308
|
-
}, [editItemVariant]);
|
|
309
|
-
const save = useCallback(async () => {
|
|
310
|
-
const response = await saveItem();
|
|
311
|
-
if (response.code === "ok") {
|
|
312
|
-
const data = response.data;
|
|
313
|
-
setSavedItemId(data.item.id);
|
|
314
|
-
onSaveRef.current?.(data);
|
|
315
|
-
}
|
|
316
|
-
}, [saveItem]);
|
|
317
|
-
const toggle = useCallback(async () => {
|
|
318
|
-
if (saved) await unsave();
|
|
319
|
-
else await save();
|
|
320
|
-
}, [
|
|
321
|
-
saved,
|
|
322
|
-
save,
|
|
323
|
-
unsave
|
|
324
|
-
]);
|
|
269
|
+
if (!state) return;
|
|
270
|
+
return () => state.dispose();
|
|
271
|
+
}, [state]);
|
|
272
|
+
const subscribe = useCallback((notify) => {
|
|
273
|
+
if (!state) return noop;
|
|
274
|
+
return state.subscribe(() => notify());
|
|
275
|
+
}, [state]);
|
|
276
|
+
const getSnapshot = useCallback(() => state ? state.peek() : NOT_READY_SNAPSHOT, [state]);
|
|
277
|
+
const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
325
278
|
return useMemo(() => {
|
|
326
279
|
return {
|
|
327
|
-
saved,
|
|
328
|
-
loading,
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
280
|
+
saved: snapshot.saved,
|
|
281
|
+
loading: snapshot.loading,
|
|
282
|
+
saving: snapshot.saving,
|
|
283
|
+
unsaving: snapshot.unsaving,
|
|
284
|
+
error: snapshot.error,
|
|
285
|
+
savedItemId: snapshot.savedItemId,
|
|
286
|
+
savedItemIds: snapshot.savedItemIds,
|
|
287
|
+
save: state?.save ?? noopAsync,
|
|
288
|
+
unsave: state?.unsave ?? noopAsync,
|
|
289
|
+
updateLists: state?.updateLists ?? noopAsync,
|
|
290
|
+
updateVariant: state?.updateVariant ?? noopAsync,
|
|
291
|
+
toggle: state?.toggle ?? noopAsync
|
|
335
292
|
};
|
|
336
|
-
}, [
|
|
337
|
-
saved,
|
|
338
|
-
loading,
|
|
339
|
-
error,
|
|
340
|
-
save,
|
|
341
|
-
unsave,
|
|
342
|
-
updateLists,
|
|
343
|
-
updateVariant,
|
|
344
|
-
toggle
|
|
345
|
-
]);
|
|
293
|
+
}, [snapshot, state]);
|
|
346
294
|
};
|
|
347
295
|
|
|
348
296
|
//#endregion
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["defaultSwishSdkUrl","swishSdkUrl","swish","value: SwishContextValue","defaultRefetchEvents: EventName[]","tokenUpdateEvent: EventName","error"],"sources":["../src/context.tsx","../src/hooks/use-swish.ts","../src/hooks/use-swish-query.ts","../src/hooks/use-swish-intent.ts","../src/hooks/use-swish-lists.ts","../src/hooks/use-swish-items.ts","../src/utils/shopify-utils.ts","../src/hooks/use-swish-item.ts","../src/hooks/use-swish-item-count.ts"],"sourcesContent":["import {\n type SwishApp,\n type SwishOptionsInput,\n swishSdkUrl as defaultSwishSdkUrl,\n} from \"@swishapp/sdk\";\nimport { createContext, ReactNode, useEffect, useRef, useState } from \"react\";\nimport type { SwishContextValue } from \"./types\";\n\nexport const SwishContext = createContext<SwishContextValue | null>(null);\n\nexport interface SwishProviderProps {\n children: ReactNode;\n options: SwishOptionsInput & { swishSdkUrl?: string };\n}\n\nexport function SwishProvider({\n children,\n options: { swishSdkUrl = defaultSwishSdkUrl, ...options },\n}: SwishProviderProps) {\n const [swish, setSwish] = useState<SwishApp | null>(null);\n const [isLoading, setIsLoading] = useState(typeof window !== \"undefined\");\n const [error, setError] = useState<Error | null>(null);\n const optionsRef = useRef<SwishOptionsInput>(options);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n let cancelled = false;\n\n const initializeSdk = async () => {\n try {\n setIsLoading(true);\n setError(null);\n\n const { createSwish } = await import(\n /* webpackIgnore: true */\n swishSdkUrl\n );\n const swish = await createSwish(optionsRef.current);\n\n if (!cancelled) {\n setSwish(swish);\n }\n } catch (err) {\n console.error(\"Failed to initialize Swish\", err);\n if (!cancelled) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to initialize Swish\")\n );\n }\n } finally {\n if (!cancelled) {\n setIsLoading(false);\n }\n }\n };\n\n initializeSdk();\n\n return () => {\n cancelled = true;\n };\n }, []);\n\n const value: SwishContextValue = {\n swish,\n isLoading,\n error,\n };\n\n return (\n <SwishContext.Provider value={value}>{children}</SwishContext.Provider>\n );\n}\n","import type { SwishApp } from \"@swishapp/sdk\";\nimport { useContext } from \"react\";\nimport { SwishContext } from \"../context\";\n\nexport function useSwish(): SwishApp | null {\n const context = useContext(SwishContext);\n\n if (typeof window !== \"undefined\" && window.swish) {\n return window.swish;\n }\n\n if (!context) {\n throw new Error(\"useSwish must be used within a SwishProvider\");\n }\n\n return context.swish;\n}\n","import type {\n ApiError,\n ApiResponse,\n EventName,\n PageInfo,\n PaginatedApiResponse,\n SwishApp,\n} from \"@swishapp/sdk\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useSwish } from \"./use-swish\";\n\nexport type FetchFn<TResponse, TVariables> = (\n swish: SwishApp[\"api\"],\n variables?: TVariables,\n) => Promise<TResponse>;\n\nconst defaultRefetchEvents: EventName[] = [\n \"item-create\",\n \"item-update\",\n \"item-delete\",\n \"item-lists-update\",\n \"list-create\",\n \"list-update\",\n \"list-delete\",\n \"token-update\",\n];\n\nconst tokenUpdateEvent: EventName = \"token-update\";\n\ntype DataOf<T> = T extends { data: infer D } ? D : never;\n\nexport const useSwishQuery = <\n TResponse extends ApiResponse<any> | PaginatedApiResponse<any>,\n TVariables,\n>(\n fetch: FetchFn<TResponse, TVariables>,\n options?: {\n variables?: TVariables;\n skip?: boolean;\n refetch?: boolean | EventName[];\n },\n) => {\n const swish = useSwish();\n const fetchRef = useRef<FetchFn<TResponse, TVariables>>(fetch);\n\n const [data, setData] = useState<DataOf<TResponse> | null>(null);\n const [pageInfo, setPageInfo] = useState<PageInfo | null>(null);\n const [error, setError] = useState<ApiError | null>(null);\n const [loading, setLoading] = useState(!options?.skip);\n const [initialized, setInitialized] = useState(false);\n const refetching = loading && initialized;\n\n const reset = useCallback(() => {\n setData(null);\n setPageInfo(null);\n setError(null);\n setLoading(false);\n setInitialized(false);\n }, []);\n\n const deps = options?.variables ? Object.values(options.variables) : [];\n const skip = !!options?.skip;\n const refetchEvents =\n options?.refetch === true ? defaultRefetchEvents\n : Array.isArray(options?.refetch) ? [...options.refetch, tokenUpdateEvent]\n : [];\n\n const refetchEventsRef = useRef(refetchEvents);\n refetchEventsRef.current = refetchEvents;\n\n // Stable string key so the effect re-subscribes only when events actually change\n const refetchEventsKey = refetchEvents.join(\",\");\n\n const executeFetch = useCallback(() => {\n if (!swish || skip) {\n return;\n }\n\n setLoading(true);\n\n fetchRef\n .current(swish.api, options?.variables)\n .then((response) => {\n setError(\"error\" in response ? response.error : null);\n setData(\"data\" in response ? response.data : null);\n setPageInfo(\"pageInfo\" in response ? response.pageInfo : null);\n })\n .catch((error) => setError(error))\n .finally(() => {\n setLoading(false);\n setInitialized(true);\n });\n }, [swish, skip, ...deps]);\n\n const refetch = useCallback(() => {\n executeFetch();\n }, [executeFetch]);\n\n useEffect(() => {\n if (!swish) {\n return;\n }\n\n executeFetch();\n\n const unsubscribe = swish.events.subscribe(refetchEventsRef.current, () => {\n refetch();\n });\n\n return () => unsubscribe();\n }, [executeFetch, refetch, refetchEventsKey]);\n\n return useMemo(\n () => ({\n data,\n pageInfo,\n error,\n loading,\n reset,\n refetch,\n refetching,\n }),\n [data, pageInfo, error, loading, reset, refetch, refetching],\n );\n};\n","import type { Intent, IntentResponse, IntentToData } from \"@swishapp/sdk\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useSwish } from \"./use-swish\";\n\nexport const useSwishIntent = <I extends Intent = Intent>(\n intent: I,\n ...args: IntentToData<I> extends void ? [] | [undefined] : [IntentToData<I>]\n) => {\n const swish = useSwish();\n const [pending, setPending] = useState(false);\n const dataRef = useRef(args);\n\n useEffect(() => {\n dataRef.current = args;\n }, [args]);\n\n const invoke = useCallback(async (): Promise<IntentResponse<I>> => {\n if (!swish) {\n throw new Error(\"Swish SDK not initialized\");\n }\n\n setPending(true);\n try {\n const activity = await swish.intents.invoke(intent, ...dataRef.current);\n const response = await activity.complete;\n return response as IntentResponse<I>;\n } finally {\n setPending(false);\n }\n }, [swish]);\n\n return { invoke, pending };\n};\n","import { useMemo } from \"react\";\nimport { useSwishQuery } from \"./use-swish-query\";\n\nexport const useSwishLists = () => {\n const {\n data: lists,\n loading,\n error,\n reset,\n } = useSwishQuery((api) => api.lists.list(), {\n refetch: [\n \"item-lists-update\",\n \"item-delete\",\n \"list-create\",\n \"list-update\",\n \"list-delete\",\n ],\n });\n\n return useMemo(\n () => ({\n loading,\n lists,\n error,\n reset,\n }),\n [lists, loading, error, reset]\n );\n};\n","import type { Item } from \"@swishapp/sdk\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useSwishQuery } from \"./use-swish-query\";\n\nexport interface UseSwishItemsOptions {\n listId?: string;\n limit?: number;\n}\n\nexport const useSwishItems = ({\n listId,\n limit = 24,\n}: UseSwishItemsOptions = {}) => {\n const [nextPage, setNextPage] = useState<string | null>(null);\n const [data, setData] = useState<Item[]>([]);\n\n const {\n data: remoteData,\n pageInfo,\n loading,\n error,\n reset: resetRemoteData,\n } = useSwishQuery((api, variables) => api.items.list(variables), {\n variables: {\n page: nextPage ?? undefined,\n limit,\n listId,\n },\n refetch: false,\n });\n\n const reset = useCallback(() => {\n setData([]);\n setNextPage(null);\n resetRemoteData();\n }, [resetRemoteData]);\n\n useEffect(() => {\n if (remoteData) {\n setData((prev) => [...prev, ...remoteData]);\n }\n }, [remoteData]);\n\n const loadMore = useCallback(() => {\n if (pageInfo?.next) {\n setNextPage(pageInfo.next);\n }\n }, [pageInfo?.next]);\n\n return useMemo(\n () => ({\n loading,\n data,\n pageInfo,\n error,\n reset,\n hasMore: !!pageInfo?.next,\n loadMore,\n }),\n [data, pageInfo, loading, error, reset, loadMore]\n );\n};\n","export const gidToId = (gid: string) => {\n return gid?.split(\"/\").pop();\n};\n","import type {\n SaveItemSuccessResponse,\n UnsaveItemSuccessResponse,\n EditItemListsSuccessResponse,\n EditItemVariantSuccessResponse,\n} from \"@swishapp/sdk\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { gidToId } from \"../utils/shopify-utils\";\nimport { useSwishIntent } from \"./use-swish-intent\";\nimport { useSwishQuery } from \"./use-swish-query\";\n\ninterface UseSwishItemProps {\n productId: string | number;\n variantId?: string | number;\n itemId?: string;\n onSave?: (data: SaveItemSuccessResponse[\"data\"]) => void;\n onUnsave?: (data: UnsaveItemSuccessResponse[\"data\"]) => void;\n onListsUpdate?: (data: EditItemListsSuccessResponse[\"data\"]) => void;\n onVariantUpdate?: (data: EditItemVariantSuccessResponse[\"data\"]) => void;\n}\n\nexport const useSwishItem = ({\n productId,\n variantId,\n itemId,\n onSave,\n onUnsave,\n onListsUpdate,\n onVariantUpdate,\n}: UseSwishItemProps) => {\n const [savedItemId, setSavedItemId] = useState<string | null>(itemId ?? null);\n\n const onUnsaveRef =\n useRef<NonNullable<UseSwishItemProps[\"onUnsave\"]>>(onUnsave);\n const onSaveRef = useRef<NonNullable<UseSwishItemProps[\"onSave\"]>>(onSave);\n const onListsUpdateRef =\n useRef<NonNullable<UseSwishItemProps[\"onListsUpdate\"]>>(onListsUpdate);\n const onVariantUpdateRef =\n useRef<NonNullable<UseSwishItemProps[\"onVariantUpdate\"]>>(onVariantUpdate);\n\n onUnsaveRef.current = onUnsave;\n onSaveRef.current = onSave;\n onListsUpdateRef.current = onListsUpdate;\n onVariantUpdateRef.current = onVariantUpdate;\n\n const { invoke: saveItem, pending: creatingItem } = useSwishIntent(\n \"save:item\",\n {\n productId,\n variantId,\n }\n );\n\n const { invoke: editItemLists } = useSwishIntent(\"edit:item-lists\", {\n itemId: savedItemId ?? \"\",\n });\n\n const { invoke: editItemVariant } = useSwishIntent(\"edit:item-variant\", {\n itemId: savedItemId ?? \"\",\n productId,\n variantId,\n });\n\n const { invoke: unsaveItem } = useSwishIntent(\"unsave:item\", {\n itemId: savedItemId ?? \"\",\n });\n\n const query = useMemo(() => {\n if (variantId) {\n return `variant:${gidToId(variantId.toString())}`;\n }\n return `product:${gidToId(productId.toString())}`;\n }, [productId, variantId]);\n\n // Load saved items for the product or variant\n const {\n data: savedItems,\n loading: savedItemsLoading,\n error: savedItemsError,\n } = useSwishQuery((api, variables) => api.items.list(variables), {\n refetch: [\"item-create\", \"item-update\", \"item-delete\"],\n variables: {\n limit: 1,\n query,\n },\n skip: Boolean(itemId) || !productId,\n });\n\n const saved = useMemo(() => Boolean(savedItemId), [savedItemId]);\n const error = useMemo(() => savedItemsError, [savedItemsError]);\n const loading = useMemo(\n () => savedItemsLoading || creatingItem,\n [savedItemsLoading, creatingItem]\n );\n\n useEffect(() => {\n if (itemId) return;\n\n if (savedItems?.[0]) {\n setSavedItemId(savedItems[0].id);\n } else {\n setSavedItemId(null);\n }\n }, [savedItems, itemId]);\n\n const unsave = useCallback(async () => {\n const response = await unsaveItem();\n\n if (response.code === \"ok\") {\n const data = response.data;\n setSavedItemId(null);\n onUnsaveRef.current?.(data);\n }\n }, [unsaveItem]);\n\n const updateLists = useCallback(async () => {\n const response = await editItemLists();\n if (response.code !== \"ok\") {\n return;\n }\n if (response.intent === \"unsave:item\") {\n // Item was unsaved from list-select\n const data = response.data as UnsaveItemSuccessResponse[\"data\"];\n setSavedItemId(null);\n onUnsaveRef.current?.(data);\n } else {\n const data = response.data as EditItemListsSuccessResponse[\"data\"];\n onListsUpdateRef.current?.(data);\n }\n }, [editItemLists]);\n\n const updateVariant = useCallback(async () => {\n const response = await editItemVariant();\n if (response.code === \"ok\") {\n const data = response.data;\n onVariantUpdateRef.current?.(data);\n }\n }, [editItemVariant]);\n\n const save = useCallback(async () => {\n const response = await saveItem();\n\n if (response.code === \"ok\") {\n const data = response.data;\n setSavedItemId(data.item.id);\n onSaveRef.current?.(data);\n }\n }, [saveItem]);\n\n const toggle = useCallback(async () => {\n if (saved) {\n await unsave();\n } else {\n await save();\n }\n }, [saved, save, unsave]);\n\n return useMemo(() => {\n return {\n saved,\n loading,\n error,\n save,\n unsave,\n updateLists,\n updateVariant,\n toggle,\n };\n }, [saved, loading, error, save, unsave, updateLists, updateVariant, toggle]);\n};\n","import { useMemo } from \"react\";\nimport { useSwishQuery } from \"./use-swish-query\";\n\nexport const useSwishItemCount = () => {\n const { data, loading, error } = useSwishQuery((api) => api.items.count(), {\n refetch: [\"item-create\", \"item-delete\"],\n });\n\n return useMemo(() => {\n return {\n count: data?.count ?? 0,\n loading,\n error,\n };\n }, [data, loading, error]);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["defaultSwishSdkUrl","swishSdkUrl","swish","value: SwishContextValue","defaultRefetchEvents: EventName[]","tokenUpdateEvent: EventName","error"],"sources":["../src/context.tsx","../src/hooks/use-swish.ts","../src/hooks/use-swish-query.ts","../src/hooks/use-swish-intent.ts","../src/hooks/use-swish-lists.ts","../src/hooks/use-swish-items.ts","../src/hooks/use-swish-item.ts","../src/hooks/use-swish-item-count.ts"],"sourcesContent":["import {\n type SwishApp,\n type SwishOptionsInput,\n swishSdkUrl as defaultSwishSdkUrl,\n} from \"@swishapp/sdk\";\nimport { createContext, ReactNode, useEffect, useRef, useState } from \"react\";\nimport type { SwishContextValue } from \"./types\";\n\nexport const SwishContext = createContext<SwishContextValue | null>(null);\n\nexport interface SwishProviderProps {\n children: ReactNode;\n options: SwishOptionsInput & { swishSdkUrl?: string };\n}\n\nexport function SwishProvider({\n children,\n options: { swishSdkUrl = defaultSwishSdkUrl, ...options },\n}: SwishProviderProps) {\n const [swish, setSwish] = useState<SwishApp | null>(null);\n const [isLoading, setIsLoading] = useState(typeof window !== \"undefined\");\n const [error, setError] = useState<Error | null>(null);\n const optionsRef = useRef<SwishOptionsInput>(options);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n let cancelled = false;\n\n const initializeSdk = async () => {\n try {\n setIsLoading(true);\n setError(null);\n\n const { createSwish } = await import(\n /* webpackIgnore: true */\n swishSdkUrl\n );\n const swish = await createSwish(optionsRef.current);\n\n if (!cancelled) {\n setSwish(swish);\n }\n } catch (err) {\n console.error(\"Failed to initialize Swish\", err);\n if (!cancelled) {\n setError(\n err instanceof Error ? err : new Error(\"Failed to initialize Swish\")\n );\n }\n } finally {\n if (!cancelled) {\n setIsLoading(false);\n }\n }\n };\n\n initializeSdk();\n\n return () => {\n cancelled = true;\n };\n }, []);\n\n const value: SwishContextValue = {\n swish,\n isLoading,\n error,\n };\n\n return (\n <SwishContext.Provider value={value}>{children}</SwishContext.Provider>\n );\n}\n","import type { SwishApp } from \"@swishapp/sdk\";\nimport { useContext } from \"react\";\nimport { SwishContext } from \"../context\";\n\nexport function useSwish(): SwishApp | null {\n const context = useContext(SwishContext);\n\n if (typeof window !== \"undefined\" && window.swish) {\n return window.swish;\n }\n\n if (!context) {\n throw new Error(\"useSwish must be used within a SwishProvider\");\n }\n\n return context.swish;\n}\n","import type {\n ApiError,\n ApiResponse,\n EventName,\n PageInfo,\n PaginatedApiResponse,\n SwishApp,\n} from \"@swishapp/sdk\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useSwish } from \"./use-swish\";\n\nexport type FetchFn<TResponse, TVariables> = (\n swish: SwishApp[\"api\"],\n variables?: TVariables,\n) => Promise<TResponse>;\n\nconst defaultRefetchEvents: EventName[] = [\n \"item-create\",\n \"item-update\",\n \"item-delete\",\n \"item-lists-update\",\n \"list-create\",\n \"list-update\",\n \"list-delete\",\n \"token-update\",\n];\n\nconst tokenUpdateEvent: EventName = \"token-update\";\n\ntype DataOf<T> = T extends { data: infer D } ? D : never;\n\nexport const useSwishQuery = <\n TResponse extends ApiResponse<any> | PaginatedApiResponse<any>,\n TVariables,\n>(\n fetch: FetchFn<TResponse, TVariables>,\n options?: {\n variables?: TVariables;\n skip?: boolean;\n refetch?: boolean | EventName[];\n },\n) => {\n const swish = useSwish();\n const fetchRef = useRef<FetchFn<TResponse, TVariables>>(fetch);\n\n const [data, setData] = useState<DataOf<TResponse> | null>(null);\n const [pageInfo, setPageInfo] = useState<PageInfo | null>(null);\n const [error, setError] = useState<ApiError | null>(null);\n const [loading, setLoading] = useState(!options?.skip);\n const [initialized, setInitialized] = useState(false);\n const refetching = loading && initialized;\n\n const reset = useCallback(() => {\n setData(null);\n setPageInfo(null);\n setError(null);\n setLoading(false);\n setInitialized(false);\n }, []);\n\n const deps = options?.variables ? Object.values(options.variables) : [];\n const skip = !!options?.skip;\n const refetchEvents =\n options?.refetch === true ? defaultRefetchEvents\n : Array.isArray(options?.refetch) ? [...options.refetch, tokenUpdateEvent]\n : [];\n\n const refetchEventsRef = useRef(refetchEvents);\n refetchEventsRef.current = refetchEvents;\n\n // Stable string key so the effect re-subscribes only when events actually change\n const refetchEventsKey = refetchEvents.join(\",\");\n\n const executeFetch = useCallback(() => {\n if (!swish || skip) {\n return;\n }\n\n setLoading(true);\n\n fetchRef\n .current(swish.api, options?.variables)\n .then((response) => {\n setError(\"error\" in response ? response.error : null);\n setData(\"data\" in response ? response.data : null);\n setPageInfo(\"pageInfo\" in response ? response.pageInfo : null);\n })\n .catch((error) => setError(error))\n .finally(() => {\n setLoading(false);\n setInitialized(true);\n });\n }, [swish, skip, ...deps]);\n\n const refetch = useCallback(() => {\n executeFetch();\n }, [executeFetch]);\n\n useEffect(() => {\n if (!swish) {\n return;\n }\n\n executeFetch();\n\n const unsubscribe = swish.events.subscribe(refetchEventsRef.current, () => {\n refetch();\n });\n\n return () => unsubscribe();\n }, [executeFetch, refetch, refetchEventsKey]);\n\n return useMemo(\n () => ({\n data,\n pageInfo,\n error,\n loading,\n reset,\n refetch,\n refetching,\n }),\n [data, pageInfo, error, loading, reset, refetch, refetching],\n );\n};\n","import type { Intent, IntentResponse, IntentToData } from \"@swishapp/sdk\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useSwish } from \"./use-swish\";\n\nexport const useSwishIntent = <I extends Intent = Intent>(\n intent: I,\n ...args: IntentToData<I> extends void ? [] | [undefined] : [IntentToData<I>]\n) => {\n const swish = useSwish();\n const [pending, setPending] = useState(false);\n const dataRef = useRef(args);\n\n useEffect(() => {\n dataRef.current = args;\n }, [args]);\n\n const invoke = useCallback(async (): Promise<IntentResponse<I>> => {\n if (!swish) {\n throw new Error(\"Swish SDK not initialized\");\n }\n\n setPending(true);\n try {\n const activity = await swish.intents.invoke(intent, ...dataRef.current);\n const response = await activity.complete;\n return response as IntentResponse<I>;\n } finally {\n setPending(false);\n }\n }, [swish]);\n\n return { invoke, pending };\n};\n","import { useMemo } from \"react\";\nimport { useSwishQuery } from \"./use-swish-query\";\n\nexport const useSwishLists = () => {\n const {\n data: lists,\n loading,\n error,\n reset,\n } = useSwishQuery((api) => api.lists.list(), {\n refetch: [\n \"item-lists-update\",\n \"item-delete\",\n \"list-create\",\n \"list-update\",\n \"list-delete\",\n ],\n });\n\n return useMemo(\n () => ({\n loading,\n lists,\n error,\n reset,\n }),\n [lists, loading, error, reset]\n );\n};\n","import type { Item } from \"@swishapp/sdk\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useSwishQuery } from \"./use-swish-query\";\n\nexport interface UseSwishItemsOptions {\n listId?: string;\n limit?: number;\n}\n\nexport const useSwishItems = ({\n listId,\n limit = 24,\n}: UseSwishItemsOptions = {}) => {\n const [nextPage, setNextPage] = useState<string | null>(null);\n const [data, setData] = useState<Item[]>([]);\n\n const {\n data: remoteData,\n pageInfo,\n loading,\n error,\n reset: resetRemoteData,\n } = useSwishQuery((api, variables) => api.items.list(variables), {\n variables: {\n page: nextPage ?? undefined,\n limit,\n listId,\n },\n refetch: false,\n });\n\n const reset = useCallback(() => {\n setData([]);\n setNextPage(null);\n resetRemoteData();\n }, [resetRemoteData]);\n\n useEffect(() => {\n if (remoteData) {\n setData((prev) => [...prev, ...remoteData]);\n }\n }, [remoteData]);\n\n const loadMore = useCallback(() => {\n if (pageInfo?.next) {\n setNextPage(pageInfo.next);\n }\n }, [pageInfo?.next]);\n\n return useMemo(\n () => ({\n loading,\n data,\n pageInfo,\n error,\n reset,\n hasMore: !!pageInfo?.next,\n loadMore,\n }),\n [data, pageInfo, loading, error, reset, loadMore]\n );\n};\n","import type {\n EditItemListsSuccessResponse,\n EditItemVariantSuccessResponse,\n ItemMatch,\n SaveItemSuccessResponse,\n UnsaveItemSuccessResponse,\n} from \"@swishapp/sdk\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useSyncExternalStore,\n} from \"react\";\nimport { useSwish } from \"./use-swish\";\n\ninterface UseSwishItemProps {\n productId: string | number;\n variantId?: string | number;\n itemId?: string;\n /**\n * How to interpret saved state when `variantId` is set:\n * - `\"variant\"`: only saved if the variant matches.\n * - `\"product\"`: saved if any variant of the product is saved.\n * - `\"auto\"` (default): variant-match when `variantId` is set, product-match otherwise.\n */\n match?: ItemMatch;\n onSave?: (data: SaveItemSuccessResponse[\"data\"]) => void;\n onUnsave?: (data: UnsaveItemSuccessResponse[\"data\"]) => void;\n onListsUpdate?: (data: EditItemListsSuccessResponse[\"data\"]) => void;\n onVariantUpdate?: (data: EditItemVariantSuccessResponse[\"data\"]) => void;\n}\n\nconst NOT_READY_SNAPSHOT = {\n status: \"unsaved\" as const,\n saved: false,\n saving: false,\n unsaving: false,\n loading: true,\n submitting: false,\n savedItemId: null,\n savedItemIds: [] as string[],\n error: null,\n};\n\nconst noop = () => {};\nconst noopAsync = async () => {};\n\nexport const useSwishItem = ({\n productId,\n variantId,\n itemId,\n match,\n onSave,\n onUnsave,\n onListsUpdate,\n onVariantUpdate,\n}: UseSwishItemProps) => {\n const swish = useSwish();\n\n const state = useMemo(() => {\n if (!swish) return null;\n const context = swish.state.itemContextFromIds({\n productId,\n variantId,\n itemId,\n });\n return swish.state.itemState(context);\n }, [swish, productId, variantId, itemId]);\n\n if (state) {\n state.setOptions({\n onSave,\n onUnsave,\n onListsUpdate,\n onVariantUpdate,\n match,\n });\n }\n\n useEffect(() => {\n if (!state) return;\n return () => state.dispose();\n }, [state]);\n\n const subscribe = useCallback(\n (notify: () => void) => {\n if (!state) return noop;\n return state.subscribe(() => notify());\n },\n [state],\n );\n const getSnapshot = useCallback(\n () => (state ? state.peek() : NOT_READY_SNAPSHOT),\n [state],\n );\n\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return useMemo(() => {\n return {\n saved: snapshot.saved,\n loading: snapshot.loading,\n saving: snapshot.saving,\n unsaving: snapshot.unsaving,\n error: snapshot.error,\n savedItemId: snapshot.savedItemId,\n savedItemIds: snapshot.savedItemIds,\n save: state?.save ?? noopAsync,\n unsave: state?.unsave ?? noopAsync,\n updateLists: state?.updateLists ?? noopAsync,\n updateVariant: state?.updateVariant ?? noopAsync,\n toggle: state?.toggle ?? noopAsync,\n };\n }, [snapshot, state]);\n};\n","import { useMemo } from \"react\";\nimport { useSwishQuery } from \"./use-swish-query\";\n\nexport const useSwishItemCount = () => {\n const { data, loading, error } = useSwishQuery((api) => api.items.count(), {\n refetch: [\"item-create\", \"item-delete\"],\n });\n\n return useMemo(() => {\n return {\n count: data?.count ?? 0,\n loading,\n error,\n };\n }, [data, loading, error]);\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swishapp/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.131.0",
|
|
4
4
|
"description": "React bindings for Swish SDK",
|
|
5
5
|
"author": "Swish",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@swishapp/sdk": "0.
|
|
13
|
+
"@swishapp/sdk": "0.131.0"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
16
|
"react": ">=16.8.0 || >=17.0.0 || >=18.0.0",
|