From 23eae67db91a0af0eb2ca281e9a63eb552511a24 Mon Sep 17 00:00:00 2001 From: Jay Giang Date: Tue, 11 Feb 2025 13:11:49 -0800 Subject: [PATCH 1/2] Update application container documentation --- .../application-container.md | 163 ++++++++++++++++-- 1 file changed, 146 insertions(+), 17 deletions(-) diff --git a/docs/design-system/custom-components/application-container.md b/docs/design-system/custom-components/application-container.md index 19c3996..17d097d 100644 --- a/docs/design-system/custom-components/application-container.md +++ b/docs/design-system/custom-components/application-container.md @@ -4,35 +4,144 @@ sidebar_position: 1 # Application Container -The `Application` container handles network status changes and displays appropriate toast notifications. It has **built-in** functionality that automatically handles these changes. +The Application container manages global application concerns such as: + +- **Service Worker** setup (online/offline capabilities) +- **Custom Storage** with IndexedDB (Dexie-based) or LocalStorage +- **Network Status** changes and corresponding toast notifications +- **Application Lifecycle** through an `on("ready")` event ## Features -- **Built-in Offline/Online Notifications**: The `Application` component monitors the network status. It shows toast messages when the app goes offline or comes back online. -- **Custom Hooks**: It leverages the `useToasts` and `useOfflineStatus` hooks from within `@nmfs-radfish/react-radfish` package. +1. **Service Worker for Offline Caching** + + The Application container supports service worker integration, enabling offline capabilities by caching static assets and handling API requests when the network is unavailable. + +2. **Pluggable Storage** + + Pass in IndexedDB or LocalStorage storage methods. + +3. **Offline/Online Detection** + + Automatically detects network changes and displays toast notifications: + + - Offline: Shows a warning toast with "Application is offline". + - Online: Shows an informational toast with "Application is online". + +4. **Lifecycle Hooks** + + You can listen for the `on("ready")` to run initialization code (e.g., seeding a database, hooking into Dexie events, etc.). + +## Usage + +### Setting up Application instance + +1. Use a service worker to enable offline caching or other PWA features. +2. Provide a custom storage engine (e.g. IndexedDB or LocalStorage). +3. Hook into the `on("ready")` lifecycle to run setup logic once the application is fully initialized. + +```jsx +// index.js + +import React from "react"; +import ReactDOM from "react-dom/client"; +import { Application } from "@nmfs-radfish/radfish"; +import App from "./App"; +import store from "./db/store.js"; // Your custom IndexedDBMethod or LocalStorageMethod config + +// 1. Create a root element for React +const root = ReactDOM.createRoot(document.getElementById("root")); + +// 2. Instantiate the Application container +// Pass in options like a service worker URL or mock handlers +const app = new Application({ + serviceWorker: { + url: + import.meta.env.MODE === "development" + ? "/mockServiceWorker.js" + : "/service-worker.js", + }, + mocks: { + handlers: import("../mocks/browser.js"), // Optional mock server in dev + }, + storage: store, // This is your IndexedDBMethod or LocalStorageMethod instance +}); + +// 3. Use the "ready" event to run custom setup code +app.on("ready", async () => { + const { db } = app?.storage; + + // Add setup code here (like DB seeding, Dexie debug handling, etc.) + + // 4. Finally, render your React app, passing "app" + root.render( + + + , + ); +}); +``` + +### The Custom Storage + +In this setup, `storage` is an `IndexedDBMethod` from `@nmfs-radfish/radfish`. This example is in `store.js`: + +```jsx +// store.js + +import { IndexedDBMethod } from "@nmfs-radfish/radfish"; + +// 1. Provide your DB name and version from environment variables +const name = import.meta.env.VITE_INDEXED_DB_NAME; +const version = import.meta.env.VITE_INDEXED_DB_VERSION; + +// 2. Define the object stores (Dexie tables) +const stores = { + species: "id, name", + cruises: "id, cruiseName, startDate", + stations: "id, cruiseId, stationName", +}; + +// 3. Export a new IndexedDBMethod instance +export default new IndexedDBMethod(name, version, stores); +``` + +Or, alternatively, set up `LocalStorageMethod`: -## How It Works +```jsx +// store.js -### Built-in Offline/Online Notifications +import { LocalStorageMethod } from "@nmfs-radfish/radfish"; -The `Application` component has **built-in** functionality to check the application's network status. It displays toast notifications when the state changes: +// 1. Provide a storage key +const name = import.meta.env.VITE_LOCAL_STORAGE_KEY; + +// 2. Export a new LocalStorageMethod instance +export default new LocalStorageMethod(name); +``` -- **When the application goes offline**: A warning toast is displayed with the message `"Application is offline"`. -- **When the application comes back online**: An info toast is displayed with the message `"Application is online"`. +When you pass `storage: store` into the Application constructor, it knows how to read/write data from the Dexie-based IndexedDB or LocalStorage. -This feature is provided **out of the box** and requires no additional setup from your side. +For more information about configuiring offline storage, see: [State Management - Offline Storage](/building-your-application/patterns/state-management#offline-storage). -### Example Usage +### Using `` in Your React App -To use the `Application` component, wrap it around your app in the entry file (e.g. `index.js` or `index.jsx`): +When you render your React app, you can wrap everything in the `` component. + +By passing the `application` prop to ``, you’re effectively telling the container: + +> “Here’s my initialized Application instance. Use it to set up offline support, register service workers, coordinate data storage, and etc..” ```jsx +// App.jsx + +import React from "react"; import { Application } from "@nmfs-radfish/react-radfish"; -function App () { +function App({ application }) { return ( - - { /* Your application code */ } + + {/* ...the rest of your app... */} ); } @@ -40,8 +149,28 @@ function App () { export default App; ``` - +- **`@nmfs-radfish/radfish`** = the **engine** (all the logic). +- **`@nmfs-radfish/react-radfish`** = the **React car** that sits on top of the engine, making it easy to drive your offline-ready web app in React. From b66a8677f40ff5cc51d82d11370489945a54dba1 Mon Sep 17 00:00:00 2001 From: Jay Giang Date: Wed, 12 Feb 2025 11:29:48 -0800 Subject: [PATCH 2/2] Make updates based on feedback --- .../application-container.md | 119 ++---------------- 1 file changed, 10 insertions(+), 109 deletions(-) diff --git a/docs/design-system/custom-components/application-container.md b/docs/design-system/custom-components/application-container.md index 17d097d..8b42e3a 100644 --- a/docs/design-system/custom-components/application-container.md +++ b/docs/design-system/custom-components/application-container.md @@ -4,12 +4,7 @@ sidebar_position: 1 # Application Container -The Application container manages global application concerns such as: - -- **Service Worker** setup (online/offline capabilities) -- **Custom Storage** with IndexedDB (Dexie-based) or LocalStorage -- **Network Status** changes and corresponding toast notifications -- **Application Lifecycle** through an `on("ready")` event +The Application container handles core application-wide functionality, including service worker integration, custom storage management, and network status detection. It provides a centralized way to manage these features within your app. ## Features @@ -28,125 +23,34 @@ The Application container manages global application concerns such as: - Offline: Shows a warning toast with "Application is offline". - Online: Shows an informational toast with "Application is online". -4. **Lifecycle Hooks** - - You can listen for the `on("ready")` to run initialization code (e.g., seeding a database, hooking into Dexie events, etc.). - ## Usage ### Setting up Application instance -1. Use a service worker to enable offline caching or other PWA features. -2. Provide a custom storage engine (e.g. IndexedDB or LocalStorage). -3. Hook into the `on("ready")` lifecycle to run setup logic once the application is fully initialized. +To use the `Application` container, instantiate it with your desired configuration: ```jsx -// index.js - -import React from "react"; -import ReactDOM from "react-dom/client"; import { Application } from "@nmfs-radfish/radfish"; -import App from "./App"; -import store from "./db/store.js"; // Your custom IndexedDBMethod or LocalStorageMethod config - -// 1. Create a root element for React -const root = ReactDOM.createRoot(document.getElementById("root")); -// 2. Instantiate the Application container -// Pass in options like a service worker URL or mock handlers -const app = new Application({ +const myApp = new Application({ serviceWorker: { url: import.meta.env.MODE === "development" ? "/mockServiceWorker.js" : "/service-worker.js", }, - mocks: { - handlers: import("../mocks/browser.js"), // Optional mock server in dev - }, - storage: store, // This is your IndexedDBMethod or LocalStorageMethod instance + storage: store, // Use IndexedDBMethod or LocalStorageMethod for offline storage }); - -// 3. Use the "ready" event to run custom setup code -app.on("ready", async () => { - const { db } = app?.storage; - - // Add setup code here (like DB seeding, Dexie debug handling, etc.) - - // 4. Finally, render your React app, passing "app" - root.render( - - - , - ); -}); -``` - -### The Custom Storage - -In this setup, `storage` is an `IndexedDBMethod` from `@nmfs-radfish/radfish`. This example is in `store.js`: - -```jsx -// store.js - -import { IndexedDBMethod } from "@nmfs-radfish/radfish"; - -// 1. Provide your DB name and version from environment variables -const name = import.meta.env.VITE_INDEXED_DB_NAME; -const version = import.meta.env.VITE_INDEXED_DB_VERSION; - -// 2. Define the object stores (Dexie tables) -const stores = { - species: "id, name", - cruises: "id, cruiseName, startDate", - stations: "id, cruiseId, stationName", -}; - -// 3. Export a new IndexedDBMethod instance -export default new IndexedDBMethod(name, version, stores); -``` - -Or, alternatively, set up `LocalStorageMethod`: - -```jsx -// store.js - -import { LocalStorageMethod } from "@nmfs-radfish/radfish"; - -// 1. Provide a storage key -const name = import.meta.env.VITE_LOCAL_STORAGE_KEY; - -// 2. Export a new LocalStorageMethod instance -export default new LocalStorageMethod(name); ``` -When you pass `storage: store` into the Application constructor, it knows how to read/write data from the Dexie-based IndexedDB or LocalStorage. +### Using `` -For more information about configuiring offline storage, see: [State Management - Offline Storage](/building-your-application/patterns/state-management#offline-storage). - -### Using `` in Your React App - -When you render your React app, you can wrap everything in the `` component. - -By passing the `application` prop to ``, you’re effectively telling the container: - -> “Here’s my initialized Application instance. Use it to set up offline support, register service workers, coordinate data storage, and etc..” +Once instantiated, the `Application` instance should be passed to the `` component. ```jsx -// App.jsx - -import React from "react"; import { Application } from "@nmfs-radfish/react-radfish"; -function App({ application }) { - return ( - - {/* ...the rest of your app... */} - - ); -} - -export default App; +; ``` ## Distinguishing `Application` from `@nmfs-radfish/radfish` vs. `@nmfs-radfish/react-radfish` @@ -157,20 +61,17 @@ export default App; - **Offline support** - **Service workers** - **Storage (IndexedDB, LocalStorage)** - - **Lifecycle event `on("ready")`** ### `@nmfs-radfish/react-radfish` (React Integration) -- Offers **React components and hooks** that make it easy to integrate `Application` into a React app. +- Offers **React components and hooks** that make it easy to integrate `Application` container into a React app. - Provides: - `` component for wrapping your app with offline support. - Hooks like `useOfflineStatus` for checking network connectivity. - `useOfflineStorage` for managing offline storage state within React components. -- This package is **React-specific** and simplifies working with `Application` in a React project. - ---- +- This package is **React-specific** and simplifies working with the `Application` container in a React project. -### In Other Words: +#### In Other Words: - **`@nmfs-radfish/radfish`** = the **engine** (all the logic). - **`@nmfs-radfish/react-radfish`** = the **React car** that sits on top of the engine, making it easy to drive your offline-ready web app in React.