@dutchiesdk/ecommerce-extensions-sdk 0.8.3 → 0.9.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/README.md CHANGED
@@ -103,7 +103,7 @@ const ProductList = () => {
103
103
 
104
104
  ### `CommerceComponentsDataInterface`
105
105
 
106
- The main interface providing access to all platform data and functionality.
106
+ The main interface providing access to all platform data and functionality. [Full interface can be found here](./src/types/interface.ts).
107
107
 
108
108
  ```typescript
109
109
  interface CommerceComponentsDataInterface {
@@ -120,17 +120,17 @@ interface CommerceComponentsDataInterface {
120
120
 
121
121
  ### `RemoteBoundaryComponent`
122
122
 
123
- The base type for all extension components that integrate with the Dutchie platform.
124
-
125
- ```typescript
126
- type RemoteBoundaryComponent = React.FC & {
127
- DataBridgeVersion: string;
128
- };
129
- ```
123
+ All extension components that integrate with the Dutchie platform should satisfy the `RemoteBoundaryComponent` type.
130
124
 
131
125
  **Example:**
132
126
 
133
127
  ```tsx
128
+ import {
129
+ RemoteBoundaryComponent,
130
+ useDataBridge,
131
+ DataBridgeVersion,
132
+ } from "@dutchie/ecommerce-extensions-sdk";
133
+
134
134
  const MyCustomHeader: RemoteBoundaryComponent = () => {
135
135
  const { location, user, actions } = useDataBridge();
136
136
 
@@ -146,7 +146,7 @@ const MyCustomHeader: RemoteBoundaryComponent = () => {
146
146
  );
147
147
  };
148
148
 
149
- MyCustomHeader.DataBridgeVersion = "0.2";
149
+ MyCustomHeader.DataBridgeVersion = DataBridgeVersion;
150
150
  ```
151
151
 
152
152
  ## Actions API
@@ -189,26 +189,26 @@ const currentLocations = await dataLoaders.locations(); // Current context locat
189
189
 
190
190
  ## Best Practices
191
191
 
192
- ### Error Handling
192
+ ### Data Loading
193
193
 
194
- Always wrap `useDataBridge()` calls in error boundaries and handle loading states:
194
+ When using the `useDataBridge()` hook in a component, always handle loading states:
195
195
 
196
196
  ```tsx
197
- const SafeComponent = () => {
198
- try {
199
- const { dataLoaders } = useDataBridge();
200
- const { data, isLoading } = useAsyncLoader(dataLoaders.products);
197
+ const MyComponent = () => {
198
+ const { dataLoaders } = useDataBridge();
199
+ const { data, isLoading } = useAsyncLoader(dataLoaders.products);
201
200
 
202
- if (isLoading) return <LoadingSpinner />;
203
- if (!data) return <ErrorMessage message="Failed to load products" />;
201
+ if (isLoading) return <LoadingSpinner />;
202
+ if (!data) return <EmptyProducts message="No products found" />;
204
203
 
205
- return <ProductList products={data} />;
206
- } catch (error) {
207
- return <ErrorFallback error={error} />;
208
- }
204
+ return <ProductList products={data} />;
209
205
  };
210
206
  ```
211
207
 
208
+ ### Error Handling
209
+
210
+ Any uncaught errors will be caught by a Dutchie error boundary, and the fallback will be rendered.
211
+
212
212
  ### TypeScript Best Practices
213
213
 
214
214
  Leverage the provided types for better development experience:
@@ -292,31 +292,6 @@ test("renders extension correctly", () => {
292
292
  });
293
293
  ```
294
294
 
295
- ### Performance Optimization
296
-
297
- Use `React.memo` and `useMemo` for expensive operations:
298
-
299
- ```tsx
300
- const ProductCard = React.memo(({ product, onAddToCart }) => {
301
- const formattedPrice = React.useMemo(
302
- () =>
303
- new Intl.NumberFormat("en-US", {
304
- style: "currency",
305
- currency: "USD",
306
- }).format(product.price),
307
- [product.price]
308
- );
309
-
310
- return (
311
- <div className="product-card">
312
- <h3>{product.name}</h3>
313
- <p>{formattedPrice}</p>
314
- <button onClick={() => onAddToCart(product.id, 1)}>Add to Cart</button>
315
- </div>
316
- );
317
- });
318
- ```
319
-
320
295
  ## Core Concepts
321
296
 
322
297
  The Dutchie Ecommerce Extensions SDK is built around several key concepts:
@@ -30,7 +30,7 @@ __webpack_require__.d(__webpack_exports__, {
30
30
  useDataBridge: ()=>useDataBridge
31
31
  });
32
32
  const external_react_namespaceObject = require("react");
33
- const DataBridgeVersion = '0.8.3';
33
+ const DataBridgeVersion = '0.9.0';
34
34
  const DataBridgeContext = (0, external_react_namespaceObject.createContext)(void 0);
35
35
  const useDataBridge = ()=>{
36
36
  const context = (0, external_react_namespaceObject.useContext)(DataBridgeContext);
@@ -1,5 +1,5 @@
1
1
  import { createContext, useContext, useEffect, useState } from "react";
2
- const DataBridgeVersion = '0.8.3';
2
+ const DataBridgeVersion = '0.9.0';
3
3
  const DataBridgeContext = createContext(void 0);
4
4
  const useDataBridge = ()=>{
5
5
  const context = useContext(DataBridgeContext);
@@ -1,3 +1,4 @@
1
+ import type { CartItem } from './data';
1
2
  type AuthenticationActions = {
2
3
  /**
3
4
  * Navigate to login
@@ -8,13 +9,15 @@ type AuthenticationActions = {
8
9
  */
9
10
  goToRegister: () => void;
10
11
  };
12
+ type GoToIdOrCnameParameters = {
13
+ id?: string;
14
+ cname?: string;
15
+ };
11
16
  type CartActions = {
12
17
  /**
13
18
  * Add product to cart
14
- * @param productId - The product ID
15
- * @param quantity - The quantity
16
19
  */
17
- addToCart: (productId: string, quantity: number) => void;
20
+ addToCart: (item: CartItem) => Promise<void>;
18
21
  /**
19
22
  * Clear cart
20
23
  */
@@ -29,19 +32,23 @@ type CartActions = {
29
32
  goToCheckout: () => void;
30
33
  /**
31
34
  * Remove product from cart
32
- * @param productId - The product ID
33
35
  */
34
- removeFromCart: (productId: string) => void;
36
+ removeFromCart: (item: CartItem) => void;
35
37
  /**
36
38
  * Show cart sidebar/modal
37
39
  */
38
40
  showCart: () => void;
39
41
  /**
40
42
  * Update product quantity in cart
41
- * @param productId - The product ID
42
- * @param quantity - The quantity
43
+ * @param existingItem - The existing item
44
+ * @param newItem - The new item
45
+ */
46
+ updateCartItem: (existingItem: CartItem, newItem: CartItem) => void;
47
+ /**
48
+ * Update pricing type
49
+ * @param pricingType - The pricing type
43
50
  */
44
- updateCartItem: (productId: string, quantity: number) => void;
51
+ updatePricingType: (pricingType: 'med' | 'rec') => void;
45
52
  };
46
53
  type ComponentActions = {
47
54
  /**
@@ -60,33 +67,27 @@ type ComponentActions = {
60
67
  };
61
68
  type DetailPageActions = {
62
69
  /**
63
- * Navigate to category page
64
- * @param categoryId - The category ID
65
- * @param categoryCname - The category CNAME
70
+ * Navigate to brand page
66
71
  */
67
- goToCategory: (categoryId?: string, categoryCname?: string) => void;
72
+ goToBrand: (params: GoToIdOrCnameParameters) => void;
68
73
  /**
69
- * Navigate to brand page
74
+ * Navigate to category page. Only one parameter is required.
70
75
  */
71
- goToBrand: (brandId?: string, brandCname?: string) => void;
76
+ goToCategory: (params: GoToIdOrCnameParameters) => void;
72
77
  /**
73
- * Navigate to product details
74
- * @param productId - The product ID
75
- * @param productCname - The product CNAME
78
+ * Navigate to collection page. Only one parameter is required.
76
79
  */
77
- goToProductDetails: (productId?: string, productCname?: string) => void;
80
+ goToCollection: (params: GoToIdOrCnameParameters) => void;
81
+ /**
82
+ * Navigate to product details. Only one parameter is required.
83
+ */
84
+ goToProductDetails: (params: GoToIdOrCnameParameters) => void;
78
85
  };
79
86
  type ListPageActions = {
80
87
  /**
81
88
  * Navigate to brand list
82
- * @param brandId - The brand ID
83
- * @param brandCname - The brand CNAME
84
- */
85
- goToBrandList: (brandId?: string, brandCname?: string) => void;
86
- /**
87
- * Navigate to collection list
88
89
  */
89
- goToCollectionList: (collectionId?: string, collectionCname?: string) => void;
90
+ goToBrandList: () => void;
90
91
  /**
91
92
  * Navigate to product list
92
93
  * @param categoryId - The category ID
@@ -4,7 +4,12 @@ export type Brand = {
4
4
  name: string;
5
5
  };
6
6
  export type CartItem = {
7
+ /**
8
+ * Generally, use [option] instead. This is advanced use only.
9
+ */
10
+ additionalOption?: string;
7
11
  name: string;
12
+ option?: string;
8
13
  price: number;
9
14
  productId: string;
10
15
  quantity: number;
@@ -134,11 +139,7 @@ export type DataLoaders = {
134
139
  */
135
140
  collections: () => Promise<Collection[] | []>;
136
141
  /**
137
- * All dispensary locations
138
- */
139
- getAllLocations: () => Promise<Dispensary[] | []>;
140
- /**
141
- * Current context locations
142
+ * All dispensary locations of the chain
142
143
  */
143
144
  locations: () => Promise<Dispensary[] | []>;
144
145
  /**
@@ -1,3 +1,4 @@
1
+ import type { CartItem } from './data';
1
2
  type AuthenticationActions = {
2
3
  /**
3
4
  * Navigate to login
@@ -8,13 +9,15 @@ type AuthenticationActions = {
8
9
  */
9
10
  goToRegister: () => void;
10
11
  };
12
+ type GoToIdOrCnameParameters = {
13
+ id?: string;
14
+ cname?: string;
15
+ };
11
16
  type CartActions = {
12
17
  /**
13
18
  * Add product to cart
14
- * @param productId - The product ID
15
- * @param quantity - The quantity
16
19
  */
17
- addToCart: (productId: string, quantity: number) => void;
20
+ addToCart: (item: CartItem) => Promise<void>;
18
21
  /**
19
22
  * Clear cart
20
23
  */
@@ -29,19 +32,23 @@ type CartActions = {
29
32
  goToCheckout: () => void;
30
33
  /**
31
34
  * Remove product from cart
32
- * @param productId - The product ID
33
35
  */
34
- removeFromCart: (productId: string) => void;
36
+ removeFromCart: (item: CartItem) => void;
35
37
  /**
36
38
  * Show cart sidebar/modal
37
39
  */
38
40
  showCart: () => void;
39
41
  /**
40
42
  * Update product quantity in cart
41
- * @param productId - The product ID
42
- * @param quantity - The quantity
43
+ * @param existingItem - The existing item
44
+ * @param newItem - The new item
45
+ */
46
+ updateCartItem: (existingItem: CartItem, newItem: CartItem) => void;
47
+ /**
48
+ * Update pricing type
49
+ * @param pricingType - The pricing type
43
50
  */
44
- updateCartItem: (productId: string, quantity: number) => void;
51
+ updatePricingType: (pricingType: 'med' | 'rec') => void;
45
52
  };
46
53
  type ComponentActions = {
47
54
  /**
@@ -60,33 +67,27 @@ type ComponentActions = {
60
67
  };
61
68
  type DetailPageActions = {
62
69
  /**
63
- * Navigate to category page
64
- * @param categoryId - The category ID
65
- * @param categoryCname - The category CNAME
70
+ * Navigate to brand page
66
71
  */
67
- goToCategory: (categoryId?: string, categoryCname?: string) => void;
72
+ goToBrand: (params: GoToIdOrCnameParameters) => void;
68
73
  /**
69
- * Navigate to brand page
74
+ * Navigate to category page. Only one parameter is required.
70
75
  */
71
- goToBrand: (brandId?: string, brandCname?: string) => void;
76
+ goToCategory: (params: GoToIdOrCnameParameters) => void;
72
77
  /**
73
- * Navigate to product details
74
- * @param productId - The product ID
75
- * @param productCname - The product CNAME
78
+ * Navigate to collection page. Only one parameter is required.
76
79
  */
77
- goToProductDetails: (productId?: string, productCname?: string) => void;
80
+ goToCollection: (params: GoToIdOrCnameParameters) => void;
81
+ /**
82
+ * Navigate to product details. Only one parameter is required.
83
+ */
84
+ goToProductDetails: (params: GoToIdOrCnameParameters) => void;
78
85
  };
79
86
  type ListPageActions = {
80
87
  /**
81
88
  * Navigate to brand list
82
- * @param brandId - The brand ID
83
- * @param brandCname - The brand CNAME
84
- */
85
- goToBrandList: (brandId?: string, brandCname?: string) => void;
86
- /**
87
- * Navigate to collection list
88
89
  */
89
- goToCollectionList: (collectionId?: string, collectionCname?: string) => void;
90
+ goToBrandList: () => void;
90
91
  /**
91
92
  * Navigate to product list
92
93
  * @param categoryId - The category ID
@@ -4,7 +4,12 @@ export type Brand = {
4
4
  name: string;
5
5
  };
6
6
  export type CartItem = {
7
+ /**
8
+ * Generally, use [option] instead. This is advanced use only.
9
+ */
10
+ additionalOption?: string;
7
11
  name: string;
12
+ option?: string;
8
13
  price: number;
9
14
  productId: string;
10
15
  quantity: number;
@@ -134,11 +139,7 @@ export type DataLoaders = {
134
139
  */
135
140
  collections: () => Promise<Collection[] | []>;
136
141
  /**
137
- * All dispensary locations
138
- */
139
- getAllLocations: () => Promise<Dispensary[] | []>;
140
- /**
141
- * Current context locations
142
+ * All dispensary locations of the chain
142
143
  */
143
144
  locations: () => Promise<Dispensary[] | []>;
144
145
  /**
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.8.3",
7
+ "version": "0.9.0",
8
8
  "license": "MIT",
9
9
  "type": "module",
10
10
  "module": "./dist/esm/index.js",