0.5.7 • Published 3 months ago

feeef v0.5.7

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

feeefjs

feeefjs is a TypeScript library for managing feeef e-commerce platforms for self-hosted stores. It provides a wrapper for feeef rest api such like send order..., also have frontend srvices like the CartService class for managing cart items, shipping methods, and calculating totals. The library also includes a NotifiableService base class for handling listeners that react to changes in the service state.


CartService & NotifiableService

A TypeScript service for managing shopping carts in e-commerce platforms. It allows developers to manage cart items, handle shipping methods, calculate totals, and notify components of changes in real-time through listeners.

Features

  • Cart management: Add, remove, toggle cart items.
  • Shipping management: Set shipping method and address.
  • Subtotal and total calculation: Calculate total prices with or without shipping.
  • Product offers: Support for product-specific offers with quantity constraints.
  • Reactive updates: Use listeners to react to cart changes, useful in React or other reactive UI frameworks.
  • Customization: Flexible enough to handle product variants and shipping policies.

Getting Started

Installation

To use the CartService and NotifiableService, you can import them into your project.

import { CartService } from './services/cart_service.js'
import { NotifiableService } from './services/notifiable_service.js'

Example Usage in TypeScript

// Importing required entities and services
import { ProductEntity } from './entities/product.js'
import { StoreEntity } from './entities/store.js'
import { ShippingMethodEntity } from './entities/shipping_method.js'
import { CartService } from './services/cart_service.js'

// Create a product and store entity
const product = new ProductEntity('1', 'Laptop', 1000)
const store = new StoreEntity('1', 'TechStore')

// Initialize CartService
const cart = new CartService()

// Add a product to the cart
cart.setCurrentItem({ product, quantity: 2 })
cart.addCurrentItemToCart()

// Apply an offer to the cart item
cart.updateCurrentItemOffer({
  code: "SUMMER2024",
  title: "Summer Sale",
  price: 899.99,
  minQuantity: 2,  // Must buy at least 2
  maxQuantity: 5   // Cannot buy more than 5 with this offer
})

// Set shipping method (from store)
cart.setShippingMethod(store)

// Calculate totals
console.log('Subtotal:', cart.getSubtotal()) // 1799.98 (2 * 899.99)
console.log('Total with shipping:', cart.getTotal()) // Includes shipping if set

// Example listener to track cart changes
const listener = (updatedCart: CartService) => {
  console.log('Cart updated:', updatedCart)
}
cart.addListener(listener)
cart.notify() // Will trigger listener and log the updated cart

// Remove listener when no longer needed
cart.removeListener(listener)

Example Usage with React

CartService integrates well with React using state and effect hooks. Below is an example showing how to update the UI in response to cart changes.

import React, { useEffect, useState } from 'react'
import { CartService } from './services/cart_service.js'

const CartComponent = ({ product, store }: { product: ProductEntity, store: StoreEntity }) => {
  // Initialize state with CartService instance
  const [cart, setCart] = useState<CartService>(new CartService())

  useEffect(() => {
    // Set shipping method based on product or store
    cart.setShippingMethod(product.shippingMethod || store)

    // Define a listener to update component state when the cart changes
    const updateCart = (updatedCart: CartService) => {
      setCart(updatedCart)
      console.log('Cart updated:', updatedCart)
    }

    // Register listener
    cart.addListener(updateCart)

    // Cleanup: Remove listener on component unmount
    return () => {
      cart.removeListener(updateCart)
    }
  }, [cart, product, store])

  return (
    <div>
      <h2>Cart</h2>
      <p>Subtotal: {cart.getSubtotal()}</p>
      <p>Total: {cart.getTotal()}</p>
    </div>
  )
}

export default CartComponent

Listener Pattern in NotifiableService

The NotifiableService base class allows registering functions (listeners) that react to changes in the service state. This is especially useful in reactive frameworks like React.

Add a Listener

const listener = (service: CartService) => {
  console.log('Cart updated:', service)
}

cart.addListener(listener) // Adds listener
cart.notify() // Triggers the listener to print the updated cart

Remove a Listener

cart.removeListener(listener) // Removes the previously added listener

API Reference

CartService

Methods

  • setCurrentItem(item: CartItem): void
    Sets the currently selected cart item.

  • addCurrentItemToCart(): void
    Adds the current item to the cart. Ignores if already present.

  • getSubtotal(withCurrentItem = true): number
    Calculates the subtotal price of the cart items.

  • getTotal(withCurrentItem = true): number
    Calculates the total price of cart items, including shipping if applicable.

  • setShippingMethod(method: ShippingMethodEntity | StoreEntity): void
    Sets the shipping method for the cart.

  • addListener(listener: Listener<CartService>): void
    Registers a listener function that is called when the cart changes.

  • removeListener(listener: Listener<CartService>): void
    Removes a previously registered listener.

  • updateItemOffer(itemId: string, offer?: ProductOffer): void
    Updates or removes an offer for a specific cart item. The offer can include price overrides and quantity constraints.

  • updateCurrentItemOffer(offer?: ProductOffer): void
    Updates or removes an offer for the current cart item.

NotifiableService

Methods

  • addListener(listener: Listener<NotifiableService>): Listener<NotifiableService>
    Adds a listener that is notified on service changes.

  • removeListener(listener: Listener<NotifiableService>): void
    Removes a listener.

  • notify(): void
    Notifies all registered listeners.

ProductOffer Interface

interface ProductOffer {
  code: string           // Unique identifier for the offer
  title: string         // Display title for the offer
  subtitle?: string     // Optional subtitle/description
  price?: number        // Optional fixed price override
  minQuantity?: number  // Minimum quantity required for the offer
  maxQuantity?: number  // Maximum quantity allowed for the offer
}

Best Practices

  1. Use Listeners for UI updates: In reactive frameworks like React, use addListener to trigger state updates or side effects based on changes in the CartService.

  2. Unsubscribe Listeners: Always clean up listeners in your components to prevent memory leaks, especially in React's useEffect.

  3. Optimize with Cached Subtotals: The CartService uses caching for subtotals to avoid recalculations. Rely on getSubtotal() and getTotal() for efficient price calculations.

  4. Handle Offer Constraints: When applying offers with quantity constraints, the cart will automatically adjust quantities to be within the valid range.

  5. Price Overrides: When using offers with fixed prices, they take precedence over regular product pricing and discounts.

Contributing

Feel free to fork this repository and contribute improvements, bug fixes, or additional features. Open a pull request for any major changes!

0.5.7

3 months ago

0.5.4

3 months ago

0.5.3

3 months ago

0.5.6

3 months ago

0.5.5

3 months ago

0.5.2

3 months ago

0.5.1

4 months ago

0.5.0

5 months ago

0.4.15

6 months ago

0.4.13

6 months ago

0.4.14

6 months ago

0.4.11

6 months ago

0.4.12

6 months ago

0.4.9

6 months ago

0.4.8

6 months ago

0.4.10

6 months ago

0.4.7

6 months ago

0.4.5

7 months ago

0.4.4

7 months ago

0.4.1

7 months ago

0.4.3

7 months ago

0.4.2

7 months ago

0.4.0

7 months ago

0.3.18

7 months ago

0.3.17

7 months ago

0.3.16

8 months ago

0.3.15

8 months ago

0.3.14

8 months ago

0.3.13

8 months ago

0.3.12

8 months ago

0.3.11

8 months ago

0.3.10

8 months ago

0.3.0

8 months ago

0.3.6

8 months ago

0.3.5

8 months ago

0.3.8

8 months ago

0.3.7

8 months ago

0.3.2

8 months ago

0.3.1

8 months ago

0.3.3

8 months ago

0.3.9

8 months ago

0.1.0

9 months ago

0.2.1

9 months ago

0.1.2

9 months ago

0.2.0

9 months ago

0.1.1

9 months ago

0.2.7

9 months ago

0.1.8

9 months ago

0.2.6

9 months ago

0.1.7

9 months ago

0.0.27

10 months ago

0.2.9

9 months ago

0.2.3

9 months ago

0.1.4

9 months ago

0.2.2

9 months ago

0.1.3

9 months ago

0.2.5

9 months ago

0.1.6

9 months ago

0.2.4

9 months ago

0.1.5

9 months ago

0.0.24

10 months ago

0.0.25

10 months ago

0.0.23

10 months ago

0.0.22

10 months ago

0.0.20

11 months ago

0.0.21

11 months ago

0.0.19

11 months ago

0.0.15

1 year ago

0.0.16

1 year ago

0.0.17

1 year ago

0.0.18

1 year ago

0.0.14

1 year ago

0.0.13

1 year ago

0.0.12

1 year ago

0.0.10

1 year ago

0.0.9

1 year ago

0.0.8

1 year ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.7

1 year ago

0.0.6

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago