@qumra/jisr 1.0.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.
Files changed (51) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +430 -0
  3. package/dist/hooks/context.d.ts +41 -0
  4. package/dist/hooks/context.d.ts.map +1 -0
  5. package/dist/hooks/context.js +52 -0
  6. package/dist/hooks/context.js.map +1 -0
  7. package/dist/hooks/useAppBridge.d.ts +31 -0
  8. package/dist/hooks/useAppBridge.d.ts.map +1 -0
  9. package/dist/hooks/useAppBridge.js +33 -0
  10. package/dist/hooks/useAppBridge.js.map +1 -0
  11. package/dist/hooks/useAuthenticatedFetch.d.ts +27 -0
  12. package/dist/hooks/useAuthenticatedFetch.d.ts.map +1 -0
  13. package/dist/hooks/useAuthenticatedFetch.js +43 -0
  14. package/dist/hooks/useAuthenticatedFetch.js.map +1 -0
  15. package/dist/hooks/useFullscreen.d.ts +39 -0
  16. package/dist/hooks/useFullscreen.d.ts.map +1 -0
  17. package/dist/hooks/useFullscreen.js +42 -0
  18. package/dist/hooks/useFullscreen.js.map +1 -0
  19. package/dist/hooks/useModal.d.ts +46 -0
  20. package/dist/hooks/useModal.d.ts.map +1 -0
  21. package/dist/hooks/useModal.js +48 -0
  22. package/dist/hooks/useModal.js.map +1 -0
  23. package/dist/hooks/useNavigate.d.ts +26 -0
  24. package/dist/hooks/useNavigate.d.ts.map +1 -0
  25. package/dist/hooks/useNavigate.js +33 -0
  26. package/dist/hooks/useNavigate.js.map +1 -0
  27. package/dist/hooks/useSaveBar.d.ts +48 -0
  28. package/dist/hooks/useSaveBar.d.ts.map +1 -0
  29. package/dist/hooks/useSaveBar.js +50 -0
  30. package/dist/hooks/useSaveBar.js.map +1 -0
  31. package/dist/hooks/useTitleBar.d.ts +40 -0
  32. package/dist/hooks/useTitleBar.d.ts.map +1 -0
  33. package/dist/hooks/useTitleBar.js +41 -0
  34. package/dist/hooks/useTitleBar.js.map +1 -0
  35. package/dist/hooks/useToast.d.ts +42 -0
  36. package/dist/hooks/useToast.d.ts.map +1 -0
  37. package/dist/hooks/useToast.js +45 -0
  38. package/dist/hooks/useToast.js.map +1 -0
  39. package/dist/index.d.ts +59 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +55 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/utils/actions.d.ts +161 -0
  44. package/dist/utils/actions.d.ts.map +1 -0
  45. package/dist/utils/actions.js +188 -0
  46. package/dist/utils/actions.js.map +1 -0
  47. package/dist/utils/app-bridge.d.ts +90 -0
  48. package/dist/utils/app-bridge.d.ts.map +1 -0
  49. package/dist/utils/app-bridge.js +143 -0
  50. package/dist/utils/app-bridge.js.map +1 -0
  51. package/package.json +62 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2025, Qumra
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,430 @@
1
+ # @qumra/jisr
2
+
3
+ React hooks and utilities for communicating with the Qumra Admin from embedded apps running in an iframe.
4
+
5
+ This package mirrors the functionality of Shopify's `@shopify/app-bridge-react` and provides a seamless integration layer for apps running within the Qumra Admin environment.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @qumra/jisr react react-dom
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ### Setup the Provider
16
+
17
+ Wrap your application with `QumraAppBridgeProvider` at the root level:
18
+
19
+ ```tsx
20
+ import React from 'react';
21
+ import { QumraAppBridgeProvider } from '@qumra/jisr';
22
+ import { App } from './App';
23
+
24
+ export default function Root() {
25
+ return (
26
+ <QumraAppBridgeProvider config={{ apiKey: 'your-app-api-key' }}>
27
+ <App />
28
+ </QumraAppBridgeProvider>
29
+ );
30
+ }
31
+ ```
32
+
33
+ ### Using Hooks in Your Components
34
+
35
+ Once the provider is set up, you can use any of the available hooks in your components:
36
+
37
+ ```tsx
38
+ import React from 'react';
39
+ import {
40
+ useNavigate,
41
+ useToast,
42
+ useSaveBar,
43
+ } from '@qumra/jisr';
44
+
45
+ export function ProductSettings() {
46
+ const navigate = useNavigate();
47
+ const toast = useToast();
48
+ const saveBar = useSaveBar();
49
+ const [hasChanges, setHasChanges] = React.useState(false);
50
+
51
+ const handleChange = () => {
52
+ setHasChanges(true);
53
+ saveBar.show({
54
+ saveLabel: 'Save Changes',
55
+ discardLabel: 'Discard',
56
+ });
57
+ };
58
+
59
+ const handleSave = async () => {
60
+ try {
61
+ toast.show({ message: 'Saving...' });
62
+ // Save your data here
63
+ await new Promise(resolve => setTimeout(resolve, 1000));
64
+ toast.show({ message: 'Saved successfully!' });
65
+ saveBar.hide();
66
+ setHasChanges(false);
67
+ } catch (error) {
68
+ toast.show({
69
+ message: 'Error saving changes',
70
+ isError: true,
71
+ });
72
+ }
73
+ };
74
+
75
+ return (
76
+ <div>
77
+ <input
78
+ type="text"
79
+ placeholder="Product name"
80
+ onChange={handleChange}
81
+ />
82
+ <button onClick={handleSave}>Save</button>
83
+ <button onClick={() => navigate('/products')}>
84
+ Back to Products
85
+ </button>
86
+ </div>
87
+ );
88
+ }
89
+ ```
90
+
91
+ ## Available Hooks
92
+
93
+ ### useAppBridge()
94
+
95
+ Get direct access to the AppBridge instance for advanced use cases:
96
+
97
+ ```tsx
98
+ import { useAppBridge } from '@qumra/jisr';
99
+
100
+ export function MyComponent() {
101
+ const bridge = useAppBridge();
102
+
103
+ const handleCustomAction = () => {
104
+ bridge.dispatch({
105
+ type: 'APP::CUSTOM_ACTION',
106
+ payload: { /* your data */ },
107
+ });
108
+
109
+ // Subscribe to events
110
+ const unsubscribe = bridge.subscribe('HOST::RESPONSE', (data) => {
111
+ console.log('Received:', data);
112
+ });
113
+
114
+ return () => unsubscribe();
115
+ };
116
+
117
+ return <button onClick={handleCustomAction}>Custom Action</button>;
118
+ }
119
+ ```
120
+
121
+ ### useNavigate()
122
+
123
+ Navigate within the Qumra Admin:
124
+
125
+ ```tsx
126
+ import { useNavigate } from '@qumra/jisr';
127
+
128
+ export function NavigationComponent() {
129
+ const navigate = useNavigate();
130
+
131
+ return (
132
+ <div>
133
+ <button onClick={() => navigate('/products')}>
134
+ View Products
135
+ </button>
136
+ <button
137
+ onClick={() => navigate('https://example.com', {
138
+ external: true,
139
+ })}
140
+ >
141
+ Open External Site
142
+ </button>
143
+ </div>
144
+ );
145
+ }
146
+ ```
147
+
148
+ ### useToast()
149
+
150
+ Show and hide toast notifications:
151
+
152
+ ```tsx
153
+ import { useToast } from '@qumra/jisr';
154
+
155
+ export function ToastExample() {
156
+ const toast = useToast();
157
+
158
+ return (
159
+ <div>
160
+ <button
161
+ onClick={() =>
162
+ toast.show({
163
+ message: 'Operation completed successfully!',
164
+ duration: 3000,
165
+ })
166
+ }
167
+ >
168
+ Show Success Toast
169
+ </button>
170
+ <button
171
+ onClick={() =>
172
+ toast.show({
173
+ message: 'An error occurred',
174
+ isError: true,
175
+ duration: 5000,
176
+ })
177
+ }
178
+ >
179
+ Show Error Toast
180
+ </button>
181
+ <button onClick={() => toast.hide()}>
182
+ Hide Toast
183
+ </button>
184
+ </div>
185
+ );
186
+ }
187
+ ```
188
+
189
+ ### useModal()
190
+
191
+ Open and close modal dialogs:
192
+
193
+ ```tsx
194
+ import { useModal } from '@qumra/jisr';
195
+
196
+ export function ModalExample() {
197
+ const modal = useModal();
198
+
199
+ const handleOpenSettings = () => {
200
+ modal.open({
201
+ title: 'App Settings',
202
+ url: '/settings',
203
+ size: 'large',
204
+ primaryAction: {
205
+ content: 'Save',
206
+ onAction: () => {
207
+ console.log('Save clicked');
208
+ modal.close();
209
+ },
210
+ },
211
+ secondaryActions: [
212
+ {
213
+ content: 'Cancel',
214
+ onAction: () => {
215
+ modal.close();
216
+ },
217
+ },
218
+ ],
219
+ });
220
+ };
221
+
222
+ return <button onClick={handleOpenSettings}>Open Settings</button>;
223
+ }
224
+ ```
225
+
226
+ ### useSaveBar()
227
+
228
+ Show a save bar for unsaved changes:
229
+
230
+ ```tsx
231
+ import { useSaveBar } from '@qumra/jisr';
232
+
233
+ export function FormWithSaveBar() {
234
+ const saveBar = useSaveBar();
235
+ const [isDirty, setIsDirty] = React.useState(false);
236
+
237
+ const handleChange = () => {
238
+ if (!isDirty) {
239
+ setIsDirty(true);
240
+ saveBar.show();
241
+ }
242
+ };
243
+
244
+ const handleSave = async () => {
245
+ await saveData();
246
+ setIsDirty(false);
247
+ saveBar.hide();
248
+ };
249
+
250
+ return (
251
+ <form>
252
+ <input onChange={handleChange} />
253
+ <button onClick={handleSave}>Save</button>
254
+ </form>
255
+ );
256
+ }
257
+ ```
258
+
259
+ ### useTitleBar()
260
+
261
+ Update the title bar:
262
+
263
+ ```tsx
264
+ import { useTitleBar } from '@qumra/jisr';
265
+
266
+ export function PageWithTitle() {
267
+ const titleBar = useTitleBar();
268
+
269
+ React.useEffect(() => {
270
+ titleBar.update({
271
+ title: 'Products',
272
+ subtitle: 'Manage your store products',
273
+ breadcrumbs: [
274
+ { content: 'Admin', url: '/' },
275
+ { content: 'Products' },
276
+ ],
277
+ });
278
+ }, [titleBar]);
279
+
280
+ return <div>Products page content</div>;
281
+ }
282
+ ```
283
+
284
+ ### useFullscreen()
285
+
286
+ Enter and exit fullscreen mode:
287
+
288
+ ```tsx
289
+ import { useFullscreen } from '@qumra/jisr';
290
+
291
+ export function FullscreenComponent() {
292
+ const fullscreen = useFullscreen();
293
+
294
+ return (
295
+ <div>
296
+ <button onClick={() => fullscreen.enter()}>
297
+ Enter Fullscreen
298
+ </button>
299
+ <button onClick={() => fullscreen.exit()}>
300
+ Exit Fullscreen
301
+ </button>
302
+ </div>
303
+ );
304
+ }
305
+ ```
306
+
307
+ ### useAuthenticatedFetch()
308
+
309
+ Make authenticated API requests with automatic session token injection:
310
+
311
+ ```tsx
312
+ import { useAuthenticatedFetch } from '@qumra/jisr';
313
+
314
+ export function DataFetcher() {
315
+ const authenticatedFetch = useAuthenticatedFetch();
316
+ const [data, setData] = React.useState(null);
317
+
318
+ const loadData = async () => {
319
+ try {
320
+ const response = await authenticatedFetch('/api/products');
321
+ const result = await response.json();
322
+ setData(result);
323
+ } catch (error) {
324
+ console.error('Error fetching data:', error);
325
+ }
326
+ };
327
+
328
+ React.useEffect(() => {
329
+ loadData();
330
+ }, []);
331
+
332
+ return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
333
+ }
334
+ ```
335
+
336
+ ## API Reference
337
+
338
+ ### ActionType
339
+
340
+ Constants for all available action types:
341
+
342
+ ```typescript
343
+ import { ActionType } from '@qumra/jisr';
344
+
345
+ const actions = {
346
+ NAVIGATE: ActionType.NAVIGATE,
347
+ TOAST_SHOW: ActionType.TOAST_SHOW,
348
+ TOAST_HIDE: ActionType.TOAST_HIDE,
349
+ MODAL_OPEN: ActionType.MODAL_OPEN,
350
+ MODAL_CLOSE: ActionType.MODAL_CLOSE,
351
+ SAVE_BAR_SHOW: ActionType.SAVE_BAR_SHOW,
352
+ SAVE_BAR_HIDE: ActionType.SAVE_BAR_HIDE,
353
+ TITLE_BAR_UPDATE: ActionType.TITLE_BAR_UPDATE,
354
+ LOADING_START: ActionType.LOADING_START,
355
+ LOADING_STOP: ActionType.LOADING_STOP,
356
+ FULLSCREEN_ENTER: ActionType.FULLSCREEN_ENTER,
357
+ FULLSCREEN_EXIT: ActionType.FULLSCREEN_EXIT,
358
+ };
359
+ ```
360
+
361
+ ### Action Creator Functions
362
+
363
+ Helper functions to create properly formatted actions:
364
+
365
+ ```typescript
366
+ import {
367
+ navigate,
368
+ showToast,
369
+ hideToast,
370
+ openModal,
371
+ closeModal,
372
+ showSaveBar,
373
+ hideSaveBar,
374
+ updateTitleBar,
375
+ startLoading,
376
+ stopLoading,
377
+ enterFullscreen,
378
+ exitFullscreen,
379
+ } from '@qumra/jisr';
380
+
381
+ // Use with useAppBridge()
382
+ const bridge = useAppBridge();
383
+ bridge.dispatch(navigate('/products'));
384
+ bridge.dispatch(showToast('Success!'));
385
+ ```
386
+
387
+ ## Type Definitions
388
+
389
+ All types are exported for TypeScript projects:
390
+
391
+ ```typescript
392
+ import type {
393
+ AppBridgeConfig,
394
+ AppBridgeAction,
395
+ AppBridgeState,
396
+ AppContext,
397
+ NavigateOptions,
398
+ ToastOptions,
399
+ ModalOptions,
400
+ SaveBarOptions,
401
+ TitleBarOptions,
402
+ UseToastResult,
403
+ UseModalResult,
404
+ UseSaveBarResult,
405
+ UseFullscreenResult,
406
+ UseTitleBarResult,
407
+ } from '@qumra/jisr';
408
+ ```
409
+
410
+ ## Error Handling
411
+
412
+ All hooks require the `QumraAppBridgeProvider` to be set up. Using them outside the provider will throw an error:
413
+
414
+ ```
415
+ Error: useAppBridge must be used within a QumraAppBridgeProvider
416
+ ```
417
+
418
+ Make sure your component is wrapped with the provider or is a child of a component that is wrapped.
419
+
420
+ ## Best Practices
421
+
422
+ 1. **Always set up the provider at the root level** of your application
423
+ 2. **Use the specific hooks** instead of `useAppBridge()` for most use cases
424
+ 3. **Handle errors gracefully** when making API calls
425
+ 4. **Clean up subscriptions** if you use direct subscriptions via `useAppBridge()`
426
+ 5. **Use TypeScript** for better type safety and IDE autocomplete
427
+
428
+ ## License
429
+
430
+ ISC
@@ -0,0 +1,41 @@
1
+ /**
2
+ * React Context and Provider for AppBridge.
3
+ * Provides the AppBridge instance to all child components.
4
+ */
5
+ import React from 'react';
6
+ import { AppBridge, type AppBridgeConfig } from '../utils/app-bridge.js';
7
+ /**
8
+ * Props for QumraAppBridgeProvider
9
+ */
10
+ export interface QumraAppBridgeProviderProps {
11
+ /** Child components that will have access to the AppBridge */
12
+ children: React.ReactNode;
13
+ /** Configuration for the AppBridge instance */
14
+ config: AppBridgeConfig;
15
+ }
16
+ /**
17
+ * Provider component for AppBridge
18
+ * Must wrap your application to provide the AppBridge to all hooks
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * import { QumraAppBridgeProvider } from '@qumra/app-bridge-react';
23
+ *
24
+ * export default function App() {
25
+ * return (
26
+ * <QumraAppBridgeProvider config={{ apiKey: 'your-api-key' }}>
27
+ * <YourApp />
28
+ * </QumraAppBridgeProvider>
29
+ * );
30
+ * }
31
+ * ```
32
+ */
33
+ export declare function QumraAppBridgeProvider({ children, config, }: QumraAppBridgeProviderProps): JSX.Element;
34
+ /**
35
+ * Internal hook to get the AppBridge context
36
+ * @internal
37
+ * @returns The AppBridge instance from context
38
+ * @throws Error if used outside of QumraAppBridgeProvider
39
+ */
40
+ export declare function useAppBridgeContext(): AppBridge;
41
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/hooks/context.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAKzE;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,8DAA8D;IAC9D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,+CAA+C;IAC/C,MAAM,EAAE,eAAe,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,MAAM,GACP,EAAE,2BAA2B,GAAG,GAAG,CAAC,OAAO,CAkB3C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,CAU/C"}
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * React Context and Provider for AppBridge.
4
+ * Provides the AppBridge instance to all child components.
5
+ */
6
+ import React from 'react';
7
+ import { AppBridge } from '../utils/app-bridge.js';
8
+ /** React Context for AppBridge instance */
9
+ const AppBridgeContext = React.createContext(null);
10
+ /**
11
+ * Provider component for AppBridge
12
+ * Must wrap your application to provide the AppBridge to all hooks
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * import { QumraAppBridgeProvider } from '@qumra/app-bridge-react';
17
+ *
18
+ * export default function App() {
19
+ * return (
20
+ * <QumraAppBridgeProvider config={{ apiKey: 'your-api-key' }}>
21
+ * <YourApp />
22
+ * </QumraAppBridgeProvider>
23
+ * );
24
+ * }
25
+ * ```
26
+ */
27
+ export function QumraAppBridgeProvider({ children, config, }) {
28
+ const [bridge] = React.useState(() => new AppBridge(config));
29
+ React.useEffect(() => {
30
+ // Signal to the host that the app is ready
31
+ bridge.ready();
32
+ // Cleanup on unmount
33
+ return () => {
34
+ bridge.destroy();
35
+ };
36
+ }, [bridge]);
37
+ return (_jsx(AppBridgeContext.Provider, { value: bridge, children: children }));
38
+ }
39
+ /**
40
+ * Internal hook to get the AppBridge context
41
+ * @internal
42
+ * @returns The AppBridge instance from context
43
+ * @throws Error if used outside of QumraAppBridgeProvider
44
+ */
45
+ export function useAppBridgeContext() {
46
+ const context = React.useContext(AppBridgeContext);
47
+ if (!context) {
48
+ throw new Error('useAppBridge must be used within a QumraAppBridgeProvider');
49
+ }
50
+ return context;
51
+ }
52
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/hooks/context.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAwB,MAAM,wBAAwB,CAAC;AAEzE,2CAA2C;AAC3C,MAAM,gBAAgB,GAAG,KAAK,CAAC,aAAa,CAAmB,IAAI,CAAC,CAAC;AAYrE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,QAAQ,EACR,MAAM,GACsB;IAC5B,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAE7D,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,2CAA2C;QAC3C,MAAM,CAAC,KAAK,EAAE,CAAC;QAEf,qBAAqB;QACrB,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,OAAO,CACL,KAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YACrC,QAAQ,GACiB,CAC7B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAEnD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Hook to access the AppBridge instance
3
+ */
4
+ import type { AppBridge } from '../utils/app-bridge.js';
5
+ /**
6
+ * Get the AppBridge instance from context
7
+ * Must be used within a QumraAppBridgeProvider
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useAppBridge } from '@qumra/app-bridge-react';
12
+ *
13
+ * export function MyComponent() {
14
+ * const bridge = useAppBridge();
15
+ *
16
+ * const handleClick = () => {
17
+ * bridge.dispatch({
18
+ * type: 'APP::NAVIGATE',
19
+ * payload: { url: '/page' }
20
+ * });
21
+ * };
22
+ *
23
+ * return <button onClick={handleClick}>Navigate</button>;
24
+ * }
25
+ * ```
26
+ *
27
+ * @returns The AppBridge instance
28
+ * @throws Error if used outside of QumraAppBridgeProvider
29
+ */
30
+ export declare function useAppBridge(): AppBridge;
31
+ //# sourceMappingURL=useAppBridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAppBridge.d.ts","sourceRoot":"","sources":["../../src/hooks/useAppBridge.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAExC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Hook to access the AppBridge instance
3
+ */
4
+ import { useAppBridgeContext } from './context.js';
5
+ /**
6
+ * Get the AppBridge instance from context
7
+ * Must be used within a QumraAppBridgeProvider
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useAppBridge } from '@qumra/app-bridge-react';
12
+ *
13
+ * export function MyComponent() {
14
+ * const bridge = useAppBridge();
15
+ *
16
+ * const handleClick = () => {
17
+ * bridge.dispatch({
18
+ * type: 'APP::NAVIGATE',
19
+ * payload: { url: '/page' }
20
+ * });
21
+ * };
22
+ *
23
+ * return <button onClick={handleClick}>Navigate</button>;
24
+ * }
25
+ * ```
26
+ *
27
+ * @returns The AppBridge instance
28
+ * @throws Error if used outside of QumraAppBridgeProvider
29
+ */
30
+ export function useAppBridge() {
31
+ return useAppBridgeContext();
32
+ }
33
+ //# sourceMappingURL=useAppBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAppBridge.js","sourceRoot":"","sources":["../../src/hooks/useAppBridge.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGnD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,mBAAmB,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Hook for making authenticated fetch requests
3
+ */
4
+ /**
5
+ * Hook to make authenticated fetch requests with automatic session token injection
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { useAuthenticatedFetch } from '@qumra/app-bridge-react';
10
+ *
11
+ * export function MyComponent() {
12
+ * const authenticatedFetch = useAuthenticatedFetch();
13
+ *
14
+ * const handleLoadData = async () => {
15
+ * const response = await authenticatedFetch('/api/products');
16
+ * const data = await response.json();
17
+ * console.log(data);
18
+ * };
19
+ *
20
+ * return <button onClick={handleLoadData}>Load Data</button>;
21
+ * }
22
+ * ```
23
+ *
24
+ * @returns A fetch function that automatically adds Authorization header
25
+ */
26
+ export declare function useAuthenticatedFetch(): (url: string, init?: RequestInit) => Promise<Response>;
27
+ //# sourceMappingURL=useAuthenticatedFetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAuthenticatedFetch.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuthenticatedFetch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,IAAI,CACvC,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAqBrB"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Hook for making authenticated fetch requests
3
+ */
4
+ import { useCallback } from 'react';
5
+ import { useAppBridge } from './useAppBridge.js';
6
+ /**
7
+ * Hook to make authenticated fetch requests with automatic session token injection
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import { useAuthenticatedFetch } from '@qumra/app-bridge-react';
12
+ *
13
+ * export function MyComponent() {
14
+ * const authenticatedFetch = useAuthenticatedFetch();
15
+ *
16
+ * const handleLoadData = async () => {
17
+ * const response = await authenticatedFetch('/api/products');
18
+ * const data = await response.json();
19
+ * console.log(data);
20
+ * };
21
+ *
22
+ * return <button onClick={handleLoadData}>Load Data</button>;
23
+ * }
24
+ * ```
25
+ *
26
+ * @returns A fetch function that automatically adds Authorization header
27
+ */
28
+ export function useAuthenticatedFetch() {
29
+ const bridge = useAppBridge();
30
+ return useCallback(async (url, init) => {
31
+ const state = bridge.getState();
32
+ const sessionToken = state.context?.sessionToken;
33
+ const headers = new Headers(init?.headers || {});
34
+ if (sessionToken) {
35
+ headers.set('Authorization', `Bearer ${sessionToken}`);
36
+ }
37
+ return fetch(url, {
38
+ ...init,
39
+ headers,
40
+ });
41
+ }, [bridge]);
42
+ }
43
+ //# sourceMappingURL=useAuthenticatedFetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAuthenticatedFetch.js","sourceRoot":"","sources":["../../src/hooks/useAuthenticatedFetch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,qBAAqB;IAInC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAE9B,OAAO,WAAW,CAChB,KAAK,EAAE,GAAW,EAAE,IAAkB,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,EAAE,YAAY,CAAC;QAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAEjD,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,YAAY,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,KAAK,CAAC,GAAG,EAAE;YAChB,GAAG,IAAI;YACP,OAAO;SACR,CAAC,CAAC;IACL,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;AACJ,CAAC"}