@trycourier/courier-react-components 1.0.1

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.
@@ -0,0 +1,131 @@
1
+ import React from 'react';
2
+ import { Courier, CourierProps, InboxMessage } from '@trycourier/courier-js';
3
+ import { CourierInboxDatastore, CourierInboxDataStoreListener, CourierInboxFeedType, InboxDataSet } from '@trycourier/courier-ui-inbox';
4
+
5
+ type AuthenticationHooks = {
6
+ userId?: string,
7
+ signIn: (props: CourierProps) => void,
8
+ signOut: () => void
9
+ }
10
+
11
+ type InboxHooks = {
12
+ load: (props?: { feedType: CourierInboxFeedType, canUseCache: boolean }) => Promise<void>,
13
+ fetchNextPageOfMessages: (props: { feedType: CourierInboxFeedType }) => Promise<InboxDataSet | null>,
14
+ setPaginationLimit: (limit: number) => void,
15
+ readMessage: (message: InboxMessage) => Promise<void>,
16
+ unreadMessage: (message: InboxMessage) => Promise<void>,
17
+ clickMessage: (message: InboxMessage) => Promise<void>,
18
+ archiveMessage: (message: InboxMessage) => Promise<void>,
19
+ openMessage: (message: InboxMessage) => Promise<void>,
20
+ unarchiveMessage: (message: InboxMessage) => Promise<void>,
21
+ readAllMessages: () => Promise<void>,
22
+ inbox?: InboxDataSet,
23
+ archive?: InboxDataSet,
24
+ unreadCount?: number,
25
+ error?: Error
26
+ }
27
+
28
+ // A hook for managing the shared state of Courier
29
+ // If you want to use more functions, checkout the Courier JS SDK which
30
+ // can be used directly by importing from '@trycourier/courier-js'
31
+ export const useCourier = () => {
32
+
33
+ // Authentication Functions
34
+ const signIn = (props: CourierProps) => Courier.shared.signIn(props);
35
+ const signOut = () => Courier.shared.signOut();
36
+
37
+ // Inbox Functions
38
+ const loadInbox = (props?: { feedType: CourierInboxFeedType, canUseCache: boolean }) => CourierInboxDatastore.shared.load(props);
39
+ const fetchNextPageOfMessages = (props: { feedType: CourierInboxFeedType }) => CourierInboxDatastore.shared.fetchNextPageOfMessages(props);
40
+ const setPaginationLimit = (limit: number) => Courier.shared.paginationLimit = limit;
41
+ const readMessage = (message: InboxMessage) => CourierInboxDatastore.shared.readMessage({ message });
42
+ const unreadMessage = (message: InboxMessage) => CourierInboxDatastore.shared.unreadMessage({ message });
43
+ const clickMessage = (message: InboxMessage) => CourierInboxDatastore.shared.clickMessage({ message });
44
+ const archiveMessage = (message: InboxMessage) => CourierInboxDatastore.shared.archiveMessage({ message });
45
+ const openMessage = (message: InboxMessage) => CourierInboxDatastore.shared.openMessage({ message });
46
+ const unarchiveMessage = (message: InboxMessage) => CourierInboxDatastore.shared.unarchiveMessage({ message });
47
+ const readAllMessages = () => CourierInboxDatastore.shared.readAllMessages();
48
+
49
+ // State
50
+ const [auth, setAuth] = React.useState<AuthenticationHooks>({
51
+ userId: undefined,
52
+ signIn,
53
+ signOut
54
+ });
55
+
56
+ const [inbox, setInbox] = React.useState<InboxHooks>({
57
+ load: loadInbox,
58
+ fetchNextPageOfMessages,
59
+ setPaginationLimit,
60
+ readMessage,
61
+ unreadMessage,
62
+ clickMessage,
63
+ archiveMessage,
64
+ openMessage,
65
+ unarchiveMessage,
66
+ readAllMessages
67
+ });
68
+
69
+ React.useEffect(() => {
70
+
71
+ // Add a listener to the Courier instance
72
+ const listener = Courier.shared.addAuthenticationListener(() => refreshAuth());
73
+
74
+ // Add inbox data store listener
75
+ const inboxListener = new CourierInboxDataStoreListener({
76
+ onError: (error: Error) => refreshInbox(error),
77
+ onDataSetChange: () => refreshInbox(),
78
+ onPageAdded: () => refreshInbox(),
79
+ onMessageAdd: () => refreshInbox(),
80
+ onMessageRemove: () => refreshInbox(),
81
+ onMessageUpdate: () => refreshInbox(),
82
+ onUnreadCountChange: () => refreshInbox()
83
+ });
84
+ CourierInboxDatastore.shared.addDataStoreListener(inboxListener);
85
+
86
+ // Set initial values
87
+ refreshAuth();
88
+ refreshInbox();
89
+
90
+ // Remove listeners when the component unmounts
91
+ return () => {
92
+ listener.remove();
93
+ inboxListener.remove();
94
+ };
95
+ }, []);
96
+
97
+ const refreshAuth = () => {
98
+ const options = Courier.shared.client?.options;
99
+ setAuth({
100
+ userId: options?.userId,
101
+ signIn,
102
+ signOut
103
+ });
104
+ }
105
+
106
+ const refreshInbox = (error?: Error) => {
107
+ const datastore = CourierInboxDatastore.shared;
108
+ setInbox({
109
+ load: loadInbox,
110
+ fetchNextPageOfMessages,
111
+ setPaginationLimit,
112
+ readMessage,
113
+ unreadMessage,
114
+ clickMessage,
115
+ archiveMessage,
116
+ openMessage,
117
+ unarchiveMessage,
118
+ readAllMessages,
119
+ inbox: datastore.inboxDataSet,
120
+ archive: datastore.archiveDataSet,
121
+ unreadCount: datastore.unreadCount,
122
+ error: error,
123
+ });
124
+ }
125
+
126
+ return {
127
+ shared: Courier.shared,
128
+ auth: auth,
129
+ inbox: inbox,
130
+ };
131
+ };
package/src/index.tsx ADDED
@@ -0,0 +1,21 @@
1
+ // Import core Courier dependencies
2
+ import '@trycourier/courier-js';
3
+ import '@trycourier/courier-ui-inbox';
4
+
5
+ // Export local hooks
6
+ export { useCourier } from './hooks/use-courier';
7
+
8
+ // Export components and their props
9
+ export { CourierInboxComponent } from './components/courier-inbox-component';
10
+ export { CourierInboxPopupMenuComponent } from './components/courier-inbox-popup-menu-component';
11
+
12
+ export type {
13
+ CourierInboxProps
14
+ } from './components/courier-inbox-component';
15
+
16
+ export type {
17
+ CourierInboxPopupMenuProps,
18
+ } from './components/courier-inbox-popup-menu-component';
19
+
20
+ // Export render context, to be provided by dependent components
21
+ export { CourierRenderContext } from './context/render-context';
package/vite.config.ts ADDED
@@ -0,0 +1,94 @@
1
+ import { defineConfig, PluginOption } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+ import dts from "vite-plugin-dts";
4
+ import { resolve, dirname } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import visualizer from "rollup-plugin-visualizer";
7
+
8
+ // Get the root directory path of the current file
9
+ const root = dirname(fileURLToPath(import.meta.url));
10
+
11
+ // Helper function to resolve paths relative to node_modules
12
+ const fromRoot = (p: string) => resolve(root, "../../node_modules", p);
13
+
14
+ export default defineConfig({
15
+ // Define environment variables and constants for production build
16
+ define: {
17
+ "process.env.NODE_ENV": '"production"',
18
+ "__DEV__": "false",
19
+ "import.meta.env.DEV": "false",
20
+ },
21
+
22
+ // Configure module resolution and aliases
23
+ resolve: {
24
+ alias: {
25
+ // Ensure we use the same React instance from node_modules
26
+ react: fromRoot("react"),
27
+ "react-dom": fromRoot("react-dom"),
28
+ },
29
+ // Prevent duplicate React instances
30
+ dedupe: ["react", "react-dom"],
31
+ },
32
+
33
+ // Library build configuration
34
+ build: {
35
+ lib: {
36
+ entry: resolve(__dirname, "src/index.tsx"),
37
+ name: "CourierReactComponents",
38
+ // Output format: .mjs for ES modules, .cjs for CommonJS
39
+ fileName: (format) => `index.${format === "es" ? "mjs" : "cjs"}`,
40
+ formats: ["es", "cjs"],
41
+ },
42
+ rollupOptions: {
43
+ // External dependencies that should not be bundled
44
+ external: [
45
+ // Explicitly exclude Courier dependencies _except_ courier-react-components,
46
+ // which is not distributed independently.
47
+ /^@trycourier\/.*/,
48
+ "react",
49
+ "react-dom",
50
+ "react-dom/client",
51
+ "react/jsx-runtime",
52
+ ],
53
+ output: {
54
+ // Global variable names for external dependencies
55
+ globals: {
56
+ react: "React",
57
+ "react-dom": "ReactDOM",
58
+ "react-dom/client": "ReactDOMClient",
59
+ "@trycourier/courier-js": "CourierJS",
60
+ "@trycourier/courier-ui-inbox": "CourierInboxUI",
61
+ },
62
+ },
63
+ },
64
+ sourcemap: true,
65
+ minify: "terser",
66
+ terserOptions: {
67
+ compress: {
68
+ drop_console: false,
69
+ drop_debugger: false
70
+ }
71
+ }
72
+ },
73
+
74
+ // Build plugins configuration
75
+ plugins: [
76
+ // React plugin for JSX support
77
+ react(),
78
+ // TypeScript declaration files generation
79
+ dts({
80
+ insertTypesEntry: true,
81
+ include: ["src/**/*.tsx"],
82
+ exclude: ["src/__tests__/**"],
83
+ }) as PluginOption,
84
+ // Bundle size visualization
85
+ visualizer({
86
+ open: false,
87
+ gzipSize: true,
88
+ brotliSize: true,
89
+ template: "treemap",
90
+ sourcemap: true,
91
+ filename: "stats.html",
92
+ }) as PluginOption,
93
+ ],
94
+ });