react-native-demo-library-by-rinkal 1.2.7 → 1.3.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/ARCHITECTURE_DIAGRAMS.md +473 -0
- package/COMMUNICATION_DOCS.md +336 -0
- package/CONTAINER_APP_SETUP.md +360 -0
- package/CommunicationExample.tsx +247 -0
- package/ContainerCommunication.ts +91 -0
- package/IMPLEMENTATION_SUMMARY.md +385 -0
- package/INDEX.md +333 -0
- package/MiniAppCommunication.ts +71 -0
- package/OFFICIAL_REFERENCES.md +278 -0
- package/QUICK_REFERENCE.md +298 -0
- package/Readme.md +514 -3
- package/SUMMARY.md +305 -0
- package/TaskCard.tsx +25 -8
- package/index.ts +15 -1
- package/package.json +16 -2
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# MiniApp-Container Communication Patterns
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
This library implements 6 different communication patterns between miniapps and container apps in React Native.
|
|
5
|
+
|
|
6
|
+
## Official Documentation References
|
|
7
|
+
|
|
8
|
+
### 1. **Event Emitter Pattern**
|
|
9
|
+
- **Reference**: [React Native Events](https://reactnative.dev/docs/native-modules-ios#sending-events-to-javascript)
|
|
10
|
+
- **Documentation**: https://reactnative.dev/docs/native-modules-ios#sending-events-to-javascript
|
|
11
|
+
- **Node.js EventEmitter**: https://nodejs.org/api/events.html
|
|
12
|
+
|
|
13
|
+
### 2. **Callback Pattern**
|
|
14
|
+
- **Reference**: [React Native Callbacks](https://reactnative.dev/docs/native-modules-ios#callbacks)
|
|
15
|
+
- **Documentation**: https://reactnative.dev/docs/native-modules-ios#callbacks
|
|
16
|
+
|
|
17
|
+
### 3. **Promise-Based Pattern**
|
|
18
|
+
- **Reference**: [React Native Promises](https://reactnative.dev/docs/native-modules-ios#promises)
|
|
19
|
+
- **Documentation**: https://reactnative.dev/docs/native-modules-ios#promises
|
|
20
|
+
- **JavaScript Promises**: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
|
21
|
+
|
|
22
|
+
### 4. **Shared State Pattern**
|
|
23
|
+
- **Reference**: [Redux State Management](https://redux.js.org/introduction/getting-started)
|
|
24
|
+
- **Documentation**: https://redux.js.org/introduction/getting-started
|
|
25
|
+
- **React Context**: https://react.dev/reference/react/useContext
|
|
26
|
+
|
|
27
|
+
### 5. **Native Bridge Pattern**
|
|
28
|
+
- **Reference**: [React Native Native Modules](https://reactnative.dev/docs/native-modules-intro)
|
|
29
|
+
- **iOS Documentation**: https://reactnative.dev/docs/native-modules-ios
|
|
30
|
+
- **Android Documentation**: https://reactnative.dev/docs/native-modules-android
|
|
31
|
+
- **Communication iOS**: https://reactnative.dev/docs/communication-ios
|
|
32
|
+
- **Communication Android**: https://reactnative.dev/docs/communication-android
|
|
33
|
+
|
|
34
|
+
### 6. **Message Queue Pattern**
|
|
35
|
+
- **Reference**: [Message Queue Pattern](https://en.wikipedia.org/wiki/Message_queue)
|
|
36
|
+
- **Documentation**: https://en.wikipedia.org/wiki/Message_queue
|
|
37
|
+
|
|
38
|
+
### Additional Web-Based References
|
|
39
|
+
- **Window postMessage API**: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
|
|
40
|
+
- **Custom Events**: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent
|
|
41
|
+
- **Web Workers**: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Communication Patterns
|
|
46
|
+
|
|
47
|
+
### 1. Event Emitter Pattern
|
|
48
|
+
**Use Case**: One-way communication, fire-and-forget events
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// MiniApp Side
|
|
52
|
+
import MiniAppCommunication from 'react-native-demo-library-by-rinkal';
|
|
53
|
+
|
|
54
|
+
// Send event
|
|
55
|
+
MiniAppCommunication.sendEvent('userAction', { action: 'buttonClicked' });
|
|
56
|
+
|
|
57
|
+
// Listen to events
|
|
58
|
+
const subscription = MiniAppCommunication.onEvent('containerUpdate', (data) => {
|
|
59
|
+
console.log('Received:', data);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Container Side
|
|
63
|
+
import ContainerCommunication from 'react-native-demo-library-by-rinkal';
|
|
64
|
+
|
|
65
|
+
// Listen to events from miniapp
|
|
66
|
+
ContainerCommunication.onEvent('userAction', (data) => {
|
|
67
|
+
console.log('User action:', data);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Send event to miniapp
|
|
71
|
+
ContainerCommunication.sendEvent('containerUpdate', { message: 'Hello' });
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 2. Callback Pattern
|
|
75
|
+
**Use Case**: Direct function invocation, synchronous communication
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// MiniApp Side
|
|
79
|
+
MiniAppCommunication.registerCallback('onDataReceived', (data) => {
|
|
80
|
+
console.log('Callback invoked:', data);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Container invokes the callback
|
|
84
|
+
MiniAppCallback.invokeCallback('onDataReceived', { result: 'success' });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 3. Promise-Based Pattern
|
|
88
|
+
**Use Case**: Async request-response, waiting for results
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// MiniApp Side
|
|
92
|
+
const result = await MiniAppCommunication.request('getUserData', {
|
|
93
|
+
userId: '123'
|
|
94
|
+
});
|
|
95
|
+
console.log('Result:', result);
|
|
96
|
+
|
|
97
|
+
// Container Side
|
|
98
|
+
ContainerCommunication.registerHandler('getUserData', async (data) => {
|
|
99
|
+
// Fetch user data
|
|
100
|
+
return {
|
|
101
|
+
userId: data.userId,
|
|
102
|
+
name: 'John Doe',
|
|
103
|
+
email: 'john@example.com'
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 4. Shared State Pattern
|
|
109
|
+
**Use Case**: Bidirectional state synchronization
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// MiniApp Side
|
|
113
|
+
// Set state
|
|
114
|
+
MiniAppCommunication.setState('userData', { name: 'John' });
|
|
115
|
+
|
|
116
|
+
// Get state
|
|
117
|
+
const userData = MiniAppCommunication.getState('userData');
|
|
118
|
+
|
|
119
|
+
// Subscribe to changes
|
|
120
|
+
const unsubscribe = MiniAppCommunication.subscribeToState('userData', (newValue) => {
|
|
121
|
+
console.log('State changed:', newValue);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Container Side
|
|
125
|
+
// Set state
|
|
126
|
+
ContainerCommunication.setState('userData', { name: 'Jane' });
|
|
127
|
+
|
|
128
|
+
// Subscribe to changes
|
|
129
|
+
ContainerCommunication.subscribeToState('userData', (newValue) => {
|
|
130
|
+
console.log('State changed:', newValue);
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 5. Native Bridge Pattern
|
|
135
|
+
**Use Case**: Direct native module communication
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// MiniApp Side
|
|
139
|
+
const result = await MiniAppCommunication.callNative(
|
|
140
|
+
'CustomModule',
|
|
141
|
+
'getDeviceInfo',
|
|
142
|
+
{ param1: 'value' }
|
|
143
|
+
);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Note**: You need to create native modules first. See:
|
|
147
|
+
- [iOS Native Modules](https://reactnative.dev/docs/native-modules-ios)
|
|
148
|
+
- [Android Native Modules](https://reactnative.dev/docs/native-modules-android)
|
|
149
|
+
|
|
150
|
+
### 6. Message Queue Pattern
|
|
151
|
+
**Use Case**: Reliable message delivery, offline support
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
// MiniApp Side
|
|
155
|
+
MiniAppCommunication.queueMessage('analyticsEvent', {
|
|
156
|
+
event: 'page_view',
|
|
157
|
+
page: 'home'
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Container Side
|
|
161
|
+
ContainerCommunication.registerMessageHandler('analyticsEvent', (message) => {
|
|
162
|
+
console.log('Analytics:', message.payload);
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Installation & Setup
|
|
169
|
+
|
|
170
|
+
### 1. Install the package
|
|
171
|
+
```bash
|
|
172
|
+
npm install react-native-demo-library-by-rinkal
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 2. Initialize in your app
|
|
176
|
+
|
|
177
|
+
**In MiniApp:**
|
|
178
|
+
```typescript
|
|
179
|
+
import MiniAppCommunication from 'react-native-demo-library-by-rinkal';
|
|
180
|
+
|
|
181
|
+
// Initialize once at app startup
|
|
182
|
+
MiniAppCommunication.initialize();
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**In Container:**
|
|
186
|
+
```typescript
|
|
187
|
+
import ContainerCommunication from 'react-native-demo-library-by-rinkal';
|
|
188
|
+
|
|
189
|
+
// Initialize once at app startup
|
|
190
|
+
ContainerCommunication.initialize();
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### 3. Cleanup on unmount
|
|
194
|
+
```typescript
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
return () => {
|
|
197
|
+
MiniAppCommunication.cleanup();
|
|
198
|
+
// or
|
|
199
|
+
ContainerCommunication.cleanup();
|
|
200
|
+
};
|
|
201
|
+
}, []);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Complete Examples
|
|
207
|
+
|
|
208
|
+
### MiniApp Component
|
|
209
|
+
```typescript
|
|
210
|
+
import React, { useEffect } from 'react';
|
|
211
|
+
import { View, Button } from 'react-native';
|
|
212
|
+
import { MiniAppExample } from 'react-native-demo-library-by-rinkal';
|
|
213
|
+
|
|
214
|
+
const App = () => {
|
|
215
|
+
return <MiniAppExample />;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export default App;
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Container Component
|
|
222
|
+
```typescript
|
|
223
|
+
import React from 'react';
|
|
224
|
+
import { ContainerExample } from 'react-native-demo-library-by-rinkal';
|
|
225
|
+
|
|
226
|
+
const App = () => {
|
|
227
|
+
return <ContainerExample />;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
export default App;
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Communication Pattern Comparison
|
|
236
|
+
|
|
237
|
+
| Pattern | Direction | Async | Reliability | Use Case |
|
|
238
|
+
|---------|-----------|-------|-------------|----------|
|
|
239
|
+
| Event Emitter | Bi-directional | No | Medium | Real-time updates |
|
|
240
|
+
| Callback | Uni-directional | No | High | Direct invocation |
|
|
241
|
+
| Promise | Request-Response | Yes | High | Data fetching |
|
|
242
|
+
| Shared State | Bi-directional | No | High | State sync |
|
|
243
|
+
| Native Bridge | Uni-directional | Yes | Medium | Native features |
|
|
244
|
+
| Message Queue | Uni-directional | Yes | Very High | Offline support |
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Architecture Diagram
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
┌─────────────────────────────────────────────────────────┐
|
|
252
|
+
│ MiniApp │
|
|
253
|
+
│ ┌──────────────────────────────────────────────────┐ │
|
|
254
|
+
│ │ MiniAppCommunication │ │
|
|
255
|
+
│ │ - Event Emitter │ │
|
|
256
|
+
│ │ - Callbacks │ │
|
|
257
|
+
│ │ - Promises │ │
|
|
258
|
+
│ │ - Shared State │ │
|
|
259
|
+
│ │ - Native Bridge │ │
|
|
260
|
+
│ │ - Message Queue │ │
|
|
261
|
+
│ └──────────────────────────────────────────────────┘ │
|
|
262
|
+
└─────────────────┬───────────────────────────────────────┘
|
|
263
|
+
│
|
|
264
|
+
Event Bus / Bridge / Queue
|
|
265
|
+
│
|
|
266
|
+
┌─────────────────┴───────────────────────────────────────┐
|
|
267
|
+
│ Container App │
|
|
268
|
+
│ ┌──────────────────────────────────────────────────┐ │
|
|
269
|
+
│ │ ContainerCommunication │ │
|
|
270
|
+
│ │ - Event Listener │ │
|
|
271
|
+
│ │ - Request Handlers │ │
|
|
272
|
+
│ │ - Shared State Manager │ │
|
|
273
|
+
│ │ - Message Queue Handler │ │
|
|
274
|
+
│ └──────────────────────────────────────────────────┘ │
|
|
275
|
+
└─────────────────────────────────────────────────────────┘
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Best Practices
|
|
281
|
+
|
|
282
|
+
1. **Initialize Early**: Call `initialize()` at app startup
|
|
283
|
+
2. **Cleanup Properly**: Always cleanup in `useEffect` cleanup function
|
|
284
|
+
3. **Error Handling**: Wrap async calls in try-catch
|
|
285
|
+
4. **Type Safety**: Use TypeScript for better type safety
|
|
286
|
+
5. **Logging**: Keep console logs for debugging in development
|
|
287
|
+
6. **Performance**: Use message queue for bulk operations
|
|
288
|
+
7. **Security**: Validate all data from untrusted sources
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Troubleshooting
|
|
293
|
+
|
|
294
|
+
### Events not received
|
|
295
|
+
- Ensure both sides are initialized
|
|
296
|
+
- Check event name spelling
|
|
297
|
+
- Verify listeners are registered before events are sent
|
|
298
|
+
|
|
299
|
+
### Promise timeout
|
|
300
|
+
- Default timeout is 30 seconds
|
|
301
|
+
- Check if container handler is registered
|
|
302
|
+
- Verify network/processing time
|
|
303
|
+
|
|
304
|
+
### State not syncing
|
|
305
|
+
- Initialize shared state manager
|
|
306
|
+
- Check if subscriptions are active
|
|
307
|
+
- Verify state keys match
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Additional Resources
|
|
312
|
+
|
|
313
|
+
### React Native Documentation
|
|
314
|
+
- [Main Documentation](https://reactnative.dev/docs/getting-started)
|
|
315
|
+
- [Native Modules](https://reactnative.dev/docs/native-modules-intro)
|
|
316
|
+
- [Platform Specific Code](https://reactnative.dev/docs/platform-specific-code)
|
|
317
|
+
|
|
318
|
+
### Micro-Frontend Patterns
|
|
319
|
+
- [Micro Frontends](https://micro-frontends.org/)
|
|
320
|
+
- [Module Federation](https://webpack.js.org/concepts/module-federation/)
|
|
321
|
+
|
|
322
|
+
### State Management
|
|
323
|
+
- [Redux](https://redux.js.org/)
|
|
324
|
+
- [MobX](https://mobx.js.org/)
|
|
325
|
+
- [Zustand](https://github.com/pmndrs/zustand)
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## License
|
|
330
|
+
ISC
|
|
331
|
+
|
|
332
|
+
## Author
|
|
333
|
+
Rinkal
|
|
334
|
+
|
|
335
|
+
## Version
|
|
336
|
+
1.2.7
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
# Container App Setup Guide
|
|
2
|
+
|
|
3
|
+
## 📱 How to Receive Events from MiniApp in Your Container App (DemoApp)
|
|
4
|
+
|
|
5
|
+
This guide shows you how to set up your **Container App (DemoApp)** to receive events from the **MiniApp (DemoLib)**.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🎯 Simple Flow
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
MiniApp (DemoLib) ----sends data----> Container App (DemoApp)
|
|
13
|
+
TaskCard Your App
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 📥 Step 1: Install the Library
|
|
19
|
+
|
|
20
|
+
In your Container App (DemoApp), install the library:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install react-native-demo-library-by-rinkal
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 📝 Step 2: Create Container Component
|
|
29
|
+
|
|
30
|
+
In your Container App, create a component to listen for events:
|
|
31
|
+
|
|
32
|
+
### ContainerApp.tsx (in your DemoApp)
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import React, { useEffect, useState } from 'react';
|
|
36
|
+
import { View, Text, StyleSheet, ScrollView } from 'react-native';
|
|
37
|
+
import ContainerCommunication from 'react-native-demo-library-by-rinkal/ContainerCommunication';
|
|
38
|
+
|
|
39
|
+
const ContainerApp = () => {
|
|
40
|
+
const [events, setEvents] = useState<string[]>([]);
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
// Listen to task clicks from miniapp
|
|
44
|
+
const taskSub = ContainerCommunication.onTaskClick((data) => {
|
|
45
|
+
console.log('Task clicked in miniapp:', data);
|
|
46
|
+
setEvents(prev => [...prev,
|
|
47
|
+
`📋 Task: ${data.taskTitle} (ID: ${data.taskId})`
|
|
48
|
+
]);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Listen to user actions from miniapp
|
|
52
|
+
const actionSub = ContainerCommunication.onUserAction((data) => {
|
|
53
|
+
console.log('User action in miniapp:', data);
|
|
54
|
+
setEvents(prev => [...prev,
|
|
55
|
+
`👤 Action: ${data.action}`
|
|
56
|
+
]);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Listen to data updates from miniapp
|
|
60
|
+
const dataSub = ContainerCommunication.onDataUpdate((data) => {
|
|
61
|
+
console.log('Data update in miniapp:', data);
|
|
62
|
+
setEvents(prev => [...prev,
|
|
63
|
+
`📊 Update: ${data.key} = ${JSON.stringify(data.value)}`
|
|
64
|
+
]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Listen to ANY custom event from miniapp
|
|
68
|
+
const customSub = ContainerCommunication.listenFromMiniApp('customEvent', (data) => {
|
|
69
|
+
console.log('Custom event from miniapp:', data);
|
|
70
|
+
setEvents(prev => [...prev,
|
|
71
|
+
`🎯 Custom: ${JSON.stringify(data)}`
|
|
72
|
+
]);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Cleanup when component unmounts
|
|
76
|
+
return () => {
|
|
77
|
+
taskSub.remove();
|
|
78
|
+
actionSub.remove();
|
|
79
|
+
dataSub.remove();
|
|
80
|
+
customSub.remove();
|
|
81
|
+
};
|
|
82
|
+
}, []);
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<ScrollView style={styles.container}>
|
|
86
|
+
<Text style={styles.title}>Container App</Text>
|
|
87
|
+
<Text style={styles.subtitle}>Listening to MiniApp events...</Text>
|
|
88
|
+
|
|
89
|
+
<View style={styles.eventsBox}>
|
|
90
|
+
<Text style={styles.eventsTitle}>Received Events:</Text>
|
|
91
|
+
{events.length === 0 ? (
|
|
92
|
+
<Text style={styles.emptyText}>
|
|
93
|
+
Waiting for events from MiniApp...
|
|
94
|
+
</Text>
|
|
95
|
+
) : (
|
|
96
|
+
events.map((event, index) => (
|
|
97
|
+
<View key={index} style={styles.eventItem}>
|
|
98
|
+
<Text style={styles.eventText}>{event}</Text>
|
|
99
|
+
<Text style={styles.eventTime}>
|
|
100
|
+
{new Date().toLocaleTimeString()}
|
|
101
|
+
</Text>
|
|
102
|
+
</View>
|
|
103
|
+
))
|
|
104
|
+
)}
|
|
105
|
+
</View>
|
|
106
|
+
</ScrollView>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const styles = StyleSheet.create({
|
|
111
|
+
container: {
|
|
112
|
+
flex: 1,
|
|
113
|
+
padding: 16,
|
|
114
|
+
backgroundColor: '#f5f5f5'
|
|
115
|
+
},
|
|
116
|
+
title: {
|
|
117
|
+
fontSize: 24,
|
|
118
|
+
fontWeight: 'bold',
|
|
119
|
+
color: '#333',
|
|
120
|
+
marginBottom: 8
|
|
121
|
+
},
|
|
122
|
+
subtitle: {
|
|
123
|
+
fontSize: 16,
|
|
124
|
+
color: '#666',
|
|
125
|
+
marginBottom: 20
|
|
126
|
+
},
|
|
127
|
+
eventsBox: {
|
|
128
|
+
backgroundColor: 'white',
|
|
129
|
+
padding: 16,
|
|
130
|
+
borderRadius: 8,
|
|
131
|
+
shadowColor: '#000',
|
|
132
|
+
shadowOffset: { width: 0, height: 2 },
|
|
133
|
+
shadowOpacity: 0.1,
|
|
134
|
+
shadowRadius: 4,
|
|
135
|
+
elevation: 3
|
|
136
|
+
},
|
|
137
|
+
eventsTitle: {
|
|
138
|
+
fontSize: 18,
|
|
139
|
+
fontWeight: '600',
|
|
140
|
+
marginBottom: 12,
|
|
141
|
+
color: '#333'
|
|
142
|
+
},
|
|
143
|
+
emptyText: {
|
|
144
|
+
fontSize: 14,
|
|
145
|
+
color: '#999',
|
|
146
|
+
fontStyle: 'italic',
|
|
147
|
+
textAlign: 'center',
|
|
148
|
+
paddingVertical: 20
|
|
149
|
+
},
|
|
150
|
+
eventItem: {
|
|
151
|
+
padding: 12,
|
|
152
|
+
backgroundColor: '#f9f9f9',
|
|
153
|
+
marginBottom: 8,
|
|
154
|
+
borderRadius: 4,
|
|
155
|
+
borderLeftWidth: 3,
|
|
156
|
+
borderLeftColor: '#4CAF50',
|
|
157
|
+
flexDirection: 'row',
|
|
158
|
+
justifyContent: 'space-between',
|
|
159
|
+
alignItems: 'center'
|
|
160
|
+
},
|
|
161
|
+
eventText: {
|
|
162
|
+
fontSize: 14,
|
|
163
|
+
color: '#333',
|
|
164
|
+
flex: 1
|
|
165
|
+
},
|
|
166
|
+
eventTime: {
|
|
167
|
+
fontSize: 12,
|
|
168
|
+
color: '#999',
|
|
169
|
+
marginLeft: 8
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
export default ContainerApp;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 📤 Step 3: Use MiniApp Components
|
|
179
|
+
|
|
180
|
+
In your Container App, use the MiniApp components:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
import React from 'react';
|
|
184
|
+
import { View } from 'react-native';
|
|
185
|
+
import { TaskCard } from 'react-native-demo-library-by-rinkal';
|
|
186
|
+
import ContainerApp from './ContainerApp';
|
|
187
|
+
|
|
188
|
+
const App = () => {
|
|
189
|
+
return (
|
|
190
|
+
<View style={{ flex: 1 }}>
|
|
191
|
+
{/* Display container listener */}
|
|
192
|
+
<ContainerApp />
|
|
193
|
+
|
|
194
|
+
{/* MiniApp components - when clicked, sends events to container */}
|
|
195
|
+
<TaskCard title="Task 1" taskId="task_1" />
|
|
196
|
+
<TaskCard title="Task 2" taskId="task_2" />
|
|
197
|
+
</View>
|
|
198
|
+
);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export default App;
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 🎯 Available Listener Methods
|
|
207
|
+
|
|
208
|
+
### 1. Listen to Task Clicks
|
|
209
|
+
```tsx
|
|
210
|
+
ContainerCommunication.onTaskClick((data) => {
|
|
211
|
+
// data: { taskId: string, taskTitle: string, timestamp: number }
|
|
212
|
+
console.log('Task clicked:', data.taskTitle);
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 2. Listen to User Actions
|
|
217
|
+
```tsx
|
|
218
|
+
ContainerCommunication.onUserAction((data) => {
|
|
219
|
+
// data: { action: string, payload: any, timestamp: number }
|
|
220
|
+
console.log('User action:', data.action);
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### 3. Listen to Data Updates
|
|
225
|
+
```tsx
|
|
226
|
+
ContainerCommunication.onDataUpdate((data) => {
|
|
227
|
+
// data: { key: string, value: any, timestamp: number }
|
|
228
|
+
console.log('Data updated:', data.key, data.value);
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### 4. Listen to Custom Events
|
|
233
|
+
```tsx
|
|
234
|
+
ContainerCommunication.listenFromMiniApp('customEventName', (data) => {
|
|
235
|
+
console.log('Custom event received:', data);
|
|
236
|
+
});
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 🔧 MiniApp Side (Already Done in DemoLib)
|
|
242
|
+
|
|
243
|
+
The MiniApp (DemoLib) already has everything set up. The TaskCard component sends events automatically when clicked:
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
// In DemoLib/TaskCard.tsx (already implemented)
|
|
247
|
+
import MiniAppCommunication from './MiniAppCommunication';
|
|
248
|
+
|
|
249
|
+
const TaskCard = ({ title, taskId }) => {
|
|
250
|
+
const handlePress = () => {
|
|
251
|
+
// This sends event to container automatically
|
|
252
|
+
MiniAppCommunication.sendTaskClick(taskId, title);
|
|
253
|
+
};
|
|
254
|
+
// ... rest of component
|
|
255
|
+
};
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
You can also send custom events from anywhere in your MiniApp:
|
|
259
|
+
|
|
260
|
+
```tsx
|
|
261
|
+
// Send custom event from miniapp
|
|
262
|
+
MiniAppCommunication.sendToContainer('customEvent', {
|
|
263
|
+
type: 'purchase',
|
|
264
|
+
productId: 'prod_123',
|
|
265
|
+
amount: 99.99
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Send user action
|
|
269
|
+
MiniAppCommunication.sendUserAction('formSubmit', {
|
|
270
|
+
formName: 'registration',
|
|
271
|
+
data: { name: 'John', email: 'john@example.com' }
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
// Send data update
|
|
275
|
+
MiniAppCommunication.sendDataUpdate('settings', {
|
|
276
|
+
theme: 'dark',
|
|
277
|
+
notifications: true
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 🔄 Complete Flow Example
|
|
284
|
+
|
|
285
|
+
### In MiniApp (DemoLib):
|
|
286
|
+
```tsx
|
|
287
|
+
// User taps TaskCard
|
|
288
|
+
<TaskCard title="Buy groceries" taskId="task_123" />
|
|
289
|
+
|
|
290
|
+
// TaskCard sends event
|
|
291
|
+
MiniAppCommunication.sendTaskClick('task_123', 'Buy groceries');
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### In Container (DemoApp):
|
|
295
|
+
```tsx
|
|
296
|
+
// Container receives event
|
|
297
|
+
ContainerCommunication.onTaskClick((data) => {
|
|
298
|
+
console.log(data);
|
|
299
|
+
// Output: { taskId: 'task_123', taskTitle: 'Buy groceries', timestamp: 1735462800000 }
|
|
300
|
+
|
|
301
|
+
// Do something with the data
|
|
302
|
+
navigation.navigate('TaskDetail', { taskId: data.taskId });
|
|
303
|
+
});
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## 📖 Official Documentation
|
|
309
|
+
|
|
310
|
+
This implementation uses React Native's DeviceEventEmitter:
|
|
311
|
+
|
|
312
|
+
- **React Native Native Modules**: https://reactnative.dev/docs/native-modules-intro
|
|
313
|
+
- **Native Modules iOS**: https://reactnative.dev/docs/native-modules-ios
|
|
314
|
+
- **Native Modules Android**: https://reactnative.dev/docs/native-modules-android
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## ✅ Checklist
|
|
319
|
+
|
|
320
|
+
- [ ] Install `react-native-demo-library-by-rinkal` in Container App
|
|
321
|
+
- [ ] Import `ContainerCommunication` in Container App
|
|
322
|
+
- [ ] Set up event listeners using `useEffect`
|
|
323
|
+
- [ ] Don't forget to cleanup (`.remove()`) when component unmounts
|
|
324
|
+
- [ ] Use MiniApp components (TaskCard) - they automatically send events
|
|
325
|
+
- [ ] Test by clicking TaskCard and see events in Container
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## 🐛 Troubleshooting
|
|
330
|
+
|
|
331
|
+
### Events not received?
|
|
332
|
+
1. Make sure you're using `ContainerCommunication.listenFromMiniApp()` or the helper methods
|
|
333
|
+
2. Check that the event names match exactly
|
|
334
|
+
3. Verify the listener is set up before the MiniApp sends events
|
|
335
|
+
4. Check console logs for any errors
|
|
336
|
+
|
|
337
|
+
### Multiple events received?
|
|
338
|
+
- Make sure you're cleaning up listeners in the `return` of `useEffect`
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## 💡 Tips
|
|
343
|
+
|
|
344
|
+
1. **Always cleanup listeners** when component unmounts to prevent memory leaks
|
|
345
|
+
2. **Use specific event names** to make debugging easier
|
|
346
|
+
3. **Check console logs** - both MiniApp and Container log all communication
|
|
347
|
+
4. **Test incrementally** - start with one event type, then add more
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## 📞 Need Help?
|
|
352
|
+
|
|
353
|
+
Check the examples in:
|
|
354
|
+
- `CommunicationExample.tsx` - See working examples
|
|
355
|
+
- `QUICK_REFERENCE.md` - Quick code snippets
|
|
356
|
+
- `COMMUNICATION_DOCS.md` - Detailed documentation
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
**Ready to use! 🎉** Copy the code above into your Container App and start receiving events from the MiniApp!
|