@nebula-rn/host 0.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.
Files changed (37) hide show
  1. package/NebulaHost.podspec +23 -0
  2. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  3. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  4. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  5. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  6. package/android/.gradle/8.9/gc.properties +0 -0
  7. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  8. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  9. package/android/.gradle/vcs-1/gc.properties +0 -0
  10. package/android/build.gradle +27 -0
  11. package/android/consumer-rules.pro +1 -0
  12. package/android/src/main/AndroidManifest.xml +1 -0
  13. package/android/src/main/java/com/hectorzhuang/nebula/NebulaActivity.kt +290 -0
  14. package/android/src/main/java/com/hectorzhuang/nebula/NebulaAppManager.kt +134 -0
  15. package/android/src/main/java/com/hectorzhuang/nebula/NebulaConfig.kt +324 -0
  16. package/android/src/main/java/com/hectorzhuang/nebula/NebulaEventHub.kt +49 -0
  17. package/android/src/main/java/com/hectorzhuang/nebula/NebulaHost.kt +145 -0
  18. package/android/src/main/java/com/hectorzhuang/nebula/NebulaHostModalActivity.kt +178 -0
  19. package/android/src/main/java/com/hectorzhuang/nebula/NebulaManifestManager.kt +130 -0
  20. package/android/src/main/java/com/hectorzhuang/nebula/NebulaNativeModule.kt +604 -0
  21. package/android/src/main/java/com/hectorzhuang/nebula/NebulaPackage.kt +16 -0
  22. package/android/src/main/java/com/hectorzhuang/nebula/NebulaRouter.kt +300 -0
  23. package/ios/Nebula/NebulaAppManager.swift +355 -0
  24. package/ios/Nebula/NebulaConfig.swift +549 -0
  25. package/ios/Nebula/NebulaContainerController.swift +580 -0
  26. package/ios/Nebula/NebulaDevLoading.swift +333 -0
  27. package/ios/Nebula/NebulaHost.swift +611 -0
  28. package/ios/Nebula/NebulaManifest.swift +214 -0
  29. package/ios/Nebula/NebulaNativeModule.swift +682 -0
  30. package/ios/Nebula/NebulaNativeModuleBridge.m +364 -0
  31. package/ios/Nebula/NebulaPerformanceMonitor.swift +46 -0
  32. package/ios/Nebula/NebulaRouter.swift +594 -0
  33. package/ios/Nebula/NebulaRouterBridge.m +19 -0
  34. package/ios/Nebula/RNInstanceViewController.swift +52 -0
  35. package/package.json +41 -0
  36. package/react-native.config.js +14 -0
  37. package/src/index.ts +9 -0
@@ -0,0 +1,364 @@
1
+ //
2
+ // NebulaNativeModuleBridge.m
3
+ // SuperApp - Nebula Mini-App Container
4
+ //
5
+ // Objective-C bridge for NebulaNativeModule
6
+ //
7
+
8
+ #import <React/RCTBridgeModule.h>
9
+ #import <React/RCTEventEmitter.h>
10
+ #import <React/RCTViewManager.h>
11
+ #import <React/UIView+React.h>
12
+ #import <objc/message.h>
13
+ #import <objc/runtime.h>
14
+ #import <UIKit/UIKit.h>
15
+
16
+ #if RCT_DEV_MENU
17
+ #import <React/RCTConvert.h>
18
+ #import <React/RCTDevLoadingView.h>
19
+ #import <React/RCTJavaScriptLoader.h>
20
+
21
+ static void NebulaSwizzleInstanceMethod(Class cls, SEL originalSelector, SEL swizzledSelector)
22
+ {
23
+ Method originalMethod = class_getInstanceMethod(cls, originalSelector);
24
+ Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
25
+
26
+ if (originalMethod == NULL || swizzledMethod == NULL) {
27
+ return;
28
+ }
29
+
30
+ BOOL added = class_addMethod(
31
+ cls,
32
+ originalSelector,
33
+ method_getImplementation(swizzledMethod),
34
+ method_getTypeEncoding(swizzledMethod));
35
+ if (added) {
36
+ class_replaceMethod(
37
+ cls,
38
+ swizzledSelector,
39
+ method_getImplementation(originalMethod),
40
+ method_getTypeEncoding(originalMethod));
41
+ } else {
42
+ method_exchangeImplementations(originalMethod, swizzledMethod);
43
+ }
44
+ }
45
+
46
+ static id NebulaSharedDevLoadingPresenter(void)
47
+ {
48
+ Class presenterClass = NSClassFromString(@"NebulaDevLoadingPresenter");
49
+ if (presenterClass == Nil) {
50
+ NSString *moduleName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
51
+ if (moduleName.length > 0) {
52
+ presenterClass = NSClassFromString([NSString stringWithFormat:@"%@.%@", moduleName, @"NebulaDevLoadingPresenter"]);
53
+ }
54
+ }
55
+ if (presenterClass == Nil) {
56
+ NSString *executableName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleExecutable"];
57
+ if (executableName.length > 0) {
58
+ presenterClass = NSClassFromString([NSString stringWithFormat:@"%@.%@", executableName, @"NebulaDevLoadingPresenter"]);
59
+ }
60
+ }
61
+ if (presenterClass == Nil) {
62
+ return nil;
63
+ }
64
+
65
+ SEL sharedSelector = NSSelectorFromString(@"shared");
66
+ if (![presenterClass respondsToSelector:sharedSelector]) {
67
+ return nil;
68
+ }
69
+
70
+ return ((id(*)(id, SEL))objc_msgSend)(presenterClass, sharedSelector);
71
+ }
72
+
73
+ static void NebulaShowDevLoading(
74
+ NSString *title,
75
+ NSString *message,
76
+ NSNumber *progress,
77
+ UIColor *titleColor,
78
+ UIColor *messageColor,
79
+ UIColor *backgroundColor,
80
+ BOOL dismissButton)
81
+ {
82
+ id presenter = NebulaSharedDevLoadingPresenter();
83
+ SEL selector = NSSelectorFromString(@"showWithTitle:message:progress:titleColor:messageColor:backgroundColor:dismissButton:");
84
+ if (presenter == nil || ![presenter respondsToSelector:selector]) {
85
+ return;
86
+ }
87
+
88
+ ((void(*)(id, SEL, NSString *, NSString *, NSNumber *, UIColor *, UIColor *, UIColor *, BOOL))objc_msgSend)(
89
+ presenter,
90
+ selector,
91
+ title,
92
+ message,
93
+ progress,
94
+ titleColor,
95
+ messageColor,
96
+ backgroundColor,
97
+ dismissButton);
98
+ }
99
+
100
+ static void NebulaHideDevLoading(void)
101
+ {
102
+ id presenter = NebulaSharedDevLoadingPresenter();
103
+ SEL selector = NSSelectorFromString(@"hide");
104
+ if (presenter == nil || ![presenter respondsToSelector:selector]) {
105
+ return;
106
+ }
107
+
108
+ ((void(*)(id, SEL))objc_msgSend)(presenter, selector);
109
+ }
110
+
111
+ @interface RCTDevLoadingView (NebulaHook)
112
+ @end
113
+
114
+ @implementation RCTDevLoadingView (NebulaHook)
115
+
116
+ + (void)load
117
+ {
118
+ static dispatch_once_t onceToken;
119
+ dispatch_once(&onceToken, ^{
120
+ NebulaSwizzleInstanceMethod(self, @selector(showWithURL:), @selector(nebula_showWithURL:));
121
+ NebulaSwizzleInstanceMethod(self, @selector(updateProgress:), @selector(nebula_updateProgress:));
122
+ NebulaSwizzleInstanceMethod(
123
+ self,
124
+ @selector(showMessage:color:backgroundColor:),
125
+ @selector(nebula_showMessage:color:backgroundColor:));
126
+ NebulaSwizzleInstanceMethod(self, @selector(hide), @selector(nebula_hide));
127
+ });
128
+ }
129
+
130
+ - (void)nebula_showWithURL:(NSURL *)URL
131
+ {
132
+ if (URL.fileURL) {
133
+ NebulaHideDevLoading();
134
+ return;
135
+ }
136
+
137
+ NebulaShowDevLoading(@"Nebula Bundling", @"Connecting to Metro…", nil, nil, nil, nil, NO);
138
+ }
139
+
140
+ - (void)nebula_updateProgress:(RCTLoadingProgress *)progress
141
+ {
142
+ if (progress == nil) {
143
+ return;
144
+ }
145
+
146
+ NSString *status = progress.status.length > 0 ? progress.status : @"Bundling";
147
+ NSString *message = progress.description.length > 0 ? progress.description : status;
148
+
149
+ CGFloat ratio = -1.0;
150
+ NSInteger total = progress.total.integerValue;
151
+ NSInteger done = progress.done.integerValue;
152
+ if (total > 0) {
153
+ ratio = MIN(MAX((CGFloat)done / (CGFloat)total, 0.0), 1.0);
154
+ }
155
+
156
+ NSNumber *progressValue = ratio >= 0.0 ? @(ratio) : nil;
157
+ NebulaShowDevLoading(status, message, progressValue, nil, nil, nil, NO);
158
+ }
159
+
160
+ - (void)nebula_showMessage:(NSString *)message
161
+ color:(UIColor *)color
162
+ backgroundColor:(UIColor *)backgroundColor
163
+ dismissButton:(BOOL)dismissButton
164
+ {
165
+ NSString *title = dismissButton ? @"Nebula Message" : @"Nebula Bundling";
166
+ NSString *resolvedMessage = message.length > 0 ? message : @"Loading…";
167
+ UIColor *resolvedTextColor = color ?: UIColor.labelColor;
168
+ UIColor *resolvedBackgroundColor = backgroundColor ?: UIColor.systemBackgroundColor;
169
+ NebulaShowDevLoading(
170
+ title,
171
+ resolvedMessage,
172
+ nil,
173
+ resolvedTextColor,
174
+ resolvedTextColor,
175
+ resolvedBackgroundColor,
176
+ dismissButton);
177
+ }
178
+
179
+ - (void)nebula_showMessage:(NSString *)message
180
+ color:(UIColor *)color
181
+ backgroundColor:(UIColor *)backgroundColor
182
+ {
183
+ NSString *resolvedMessage = message.length > 0 ? message : @"Loading…";
184
+ UIColor *resolvedTextColor = color ?: UIColor.labelColor;
185
+ UIColor *resolvedBackgroundColor = backgroundColor ?: UIColor.systemBackgroundColor;
186
+ NebulaShowDevLoading(
187
+ @"Nebula Message",
188
+ resolvedMessage,
189
+ nil,
190
+ resolvedTextColor,
191
+ resolvedTextColor,
192
+ resolvedBackgroundColor,
193
+ false);
194
+ }
195
+
196
+ - (void)nebula_showMessage:(NSString *)message
197
+ withColor:(NSNumber *)color
198
+ withBackgroundColor:(NSNumber *)backgroundColor
199
+ withDismissButton:(NSNumber *)dismissButton
200
+ {
201
+ NSString *title = dismissButton.boolValue ? @"Nebula Message" : @"Nebula Bundling";
202
+ NSString *resolvedMessage = message.length > 0 ? message : @"Loading…";
203
+ UIColor *resolvedTextColor =
204
+ color != nil ? [RCTConvert UIColor:color] : UIColor.labelColor;
205
+ UIColor *resolvedBackgroundColor =
206
+ backgroundColor != nil ? [RCTConvert UIColor:backgroundColor] : UIColor.systemBackgroundColor;
207
+ NebulaShowDevLoading(
208
+ title,
209
+ resolvedMessage,
210
+ nil,
211
+ resolvedTextColor,
212
+ resolvedTextColor,
213
+ resolvedBackgroundColor,
214
+ dismissButton.boolValue);
215
+ }
216
+
217
+ - (void)nebula_hide
218
+ {
219
+ NebulaHideDevLoading();
220
+ }
221
+
222
+ @end
223
+ #endif
224
+
225
+ @interface RCT_EXTERN_MODULE(NebulaNativeModule, RCTEventEmitter)
226
+
227
+ RCT_EXTERN_METHOD(openMiniApp:(NSString *)appId
228
+ initialProps:(NSDictionary *)initialProps
229
+ resolver:(RCTPromiseResolveBlock)resolver
230
+ rejecter:(RCTPromiseRejectBlock)rejecter)
231
+
232
+ RCT_EXTERN_METHOD(openMiniAppWithBundleURL:(NSString *)appId
233
+ bundleURL:(NSString *)bundleURL
234
+ connectToURLMetroServer:(BOOL)connectToURLMetroServer
235
+ initialProps:(NSDictionary *)initialProps
236
+ resolver:(RCTPromiseResolveBlock)resolver
237
+ rejecter:(RCTPromiseRejectBlock)rejecter)
238
+
239
+ RCT_EXTERN_METHOD(preloadMiniApp:(NSString *)appId
240
+ resolver:(RCTPromiseResolveBlock)resolver
241
+ rejecter:(RCTPromiseRejectBlock)rejecter)
242
+
243
+ RCT_EXTERN_METHOD(preloadMiniAppWithBundleURL:(NSString *)appId
244
+ bundleURL:(NSString *)bundleURL
245
+ connectToURLMetroServer:(BOOL)connectToURLMetroServer
246
+ resolver:(RCTPromiseResolveBlock)resolver
247
+ rejecter:(RCTPromiseRejectBlock)rejecter)
248
+
249
+ RCT_EXTERN_METHOD(installMiniApp:(NSString *)appId
250
+ bundleURL:(NSString *)bundleURL
251
+ resolver:(RCTPromiseResolveBlock)resolver
252
+ rejecter:(RCTPromiseRejectBlock)rejecter)
253
+
254
+ RCT_EXTERN_METHOD(installMiniAppWithBundleURL:(NSString *)appId
255
+ bundleURL:(NSString *)bundleURL
256
+ connectToURLMetroServer:(BOOL)connectToURLMetroServer
257
+ resolver:(RCTPromiseResolveBlock)resolver
258
+ rejecter:(RCTPromiseRejectBlock)rejecter)
259
+
260
+ RCT_EXTERN_METHOD(installMiniAppFromURLs:(NSString *)appId
261
+ bundleURL:(NSString *)bundleURL
262
+ manifestURL:(NSString *)manifestURL
263
+ assetsURL:(NSString *)assetsURL
264
+ connectToURLMetroServer:(BOOL)connectToURLMetroServer
265
+ resolver:(RCTPromiseResolveBlock)resolver
266
+ rejecter:(RCTPromiseRejectBlock)rejecter)
267
+
268
+ RCT_EXTERN_METHOD(closeMiniApp:(NSString *)appId
269
+ resolver:(RCTPromiseResolveBlock)resolver
270
+ rejecter:(RCTPromiseRejectBlock)rejecter)
271
+
272
+ RCT_EXTERN_METHOD(uninstallMiniApp:(NSString *)appId
273
+ resolver:(RCTPromiseResolveBlock)resolver
274
+ rejecter:(RCTPromiseRejectBlock)rejecter)
275
+
276
+ RCT_EXTERN_METHOD(registerRoutes:(NSString *)appId
277
+ routes:(NSDictionary *)routes
278
+ resolver:(RCTPromiseResolveBlock)resolver
279
+ rejecter:(RCTPromiseRejectBlock)rejecter)
280
+
281
+ RCT_EXTERN_METHOD(registerManifest:(NSString *)appId
282
+ manifest:(NSDictionary *)manifest
283
+ resolver:(RCTPromiseResolveBlock)resolver
284
+ rejecter:(RCTPromiseRejectBlock)rejecter)
285
+
286
+ RCT_EXTERN_METHOD(postMessageToHost:(NSString *)appId
287
+ message:(NSDictionary *)message
288
+ resolver:(RCTPromiseResolveBlock)resolver
289
+ rejecter:(RCTPromiseRejectBlock)rejecter)
290
+
291
+ RCT_EXTERN_METHOD(postMessageToMiniApp:(NSString *)appId
292
+ message:(NSDictionary *)message
293
+ resolver:(RCTPromiseResolveBlock)resolver
294
+ rejecter:(RCTPromiseRejectBlock)rejecter)
295
+
296
+ RCT_EXTERN_METHOD(getInstalledMiniApps:(RCTPromiseResolveBlock)resolver
297
+ rejecter:(RCTPromiseRejectBlock)rejecter)
298
+
299
+ RCT_EXTERN_METHOD(getInstalledMiniAppInfo:(NSString *)appId
300
+ resolver:(RCTPromiseResolveBlock)resolver
301
+ rejecter:(RCTPromiseRejectBlock)rejecter)
302
+
303
+ RCT_EXTERN_METHOD(getServerBaseURL:(RCTPromiseResolveBlock)resolver
304
+ rejecter:(RCTPromiseRejectBlock)rejecter)
305
+
306
+ RCT_EXTERN_METHOD(setServerBaseURL:(NSString * _Nullable)serverBaseURL
307
+ resolver:(RCTPromiseResolveBlock)resolver
308
+ rejecter:(RCTPromiseRejectBlock)rejecter)
309
+
310
+ RCT_EXTERN_METHOD(setMiniappLoadingDelay:(NSNumber * _Nullable)delayMs
311
+ resolver:(RCTPromiseResolveBlock)resolver
312
+ rejecter:(RCTPromiseRejectBlock)rejecter)
313
+
314
+ RCT_EXTERN_METHOD(setMiniappLoadingEnterContentDelay:(NSNumber * _Nullable)delayMs
315
+ resolver:(RCTPromiseResolveBlock)resolver
316
+ rejecter:(RCTPromiseRejectBlock)rejecter)
317
+
318
+ RCT_EXTERN_METHOD(bringHostToFront:(RCTPromiseResolveBlock)resolver
319
+ rejecter:(RCTPromiseRejectBlock)rejecter)
320
+
321
+ RCT_EXTERN_METHOD(restoreMiniApp:(NSString * _Nullable)token
322
+ resolver:(RCTPromiseResolveBlock)resolver
323
+ rejecter:(RCTPromiseRejectBlock)rejecter)
324
+
325
+ RCT_EXTERN_METHOD(presentHostModal:(NSString *)moduleName
326
+ props:(NSDictionary *)props
327
+ resolver:(RCTPromiseResolveBlock)resolver
328
+ rejecter:(RCTPromiseRejectBlock)rejecter)
329
+
330
+ RCT_EXTERN_METHOD(dismissHostModal:(RCTPromiseResolveBlock)resolver
331
+ rejecter:(RCTPromiseRejectBlock)rejecter)
332
+
333
+ RCT_EXTERN_METHOD(navigateTo:(NSString *)appId
334
+ url:(NSString *)url
335
+ resolver:(RCTPromiseResolveBlock)resolver
336
+ rejecter:(RCTPromiseRejectBlock)rejecter)
337
+
338
+ RCT_EXTERN_METHOD(redirectTo:(NSString *)appId
339
+ url:(NSString *)url
340
+ resolver:(RCTPromiseResolveBlock)resolver
341
+ rejecter:(RCTPromiseRejectBlock)rejecter)
342
+
343
+ RCT_EXTERN_METHOD(reLaunch:(NSString *)appId
344
+ url:(NSString *)url
345
+ resolver:(RCTPromiseResolveBlock)resolver
346
+ rejecter:(RCTPromiseRejectBlock)rejecter)
347
+
348
+ RCT_EXTERN_METHOD(navigateBack:(NSString *)appId
349
+ delta:(NSInteger)delta
350
+ resolver:(RCTPromiseResolveBlock)resolver
351
+ rejecter:(RCTPromiseRejectBlock)rejecter)
352
+
353
+ RCT_EXTERN_METHOD(setPageStyle:(NSString *)appId
354
+ style:(NSDictionary *)style
355
+ resolver:(RCTPromiseResolveBlock)resolver
356
+ rejecter:(RCTPromiseRejectBlock)rejecter)
357
+
358
+ RCT_EXTERN_METHOD(showToast:(NSString *)title
359
+ resolver:(RCTPromiseResolveBlock)resolver
360
+ rejecter:(RCTPromiseRejectBlock)rejecter)
361
+
362
+ RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(getDeviceInfo)
363
+
364
+ @end
@@ -0,0 +1,46 @@
1
+ //
2
+ // NebulaPerformanceMonitor.swift
3
+ // SuperApp - Nebula Mini-App Container
4
+ //
5
+ // Performance monitoring for mini-app lifecycle
6
+ //
7
+
8
+ import Foundation
9
+
10
+ @objc public final class NebulaPerformanceMonitor: NSObject {
11
+
12
+ // MARK: - Singleton
13
+
14
+ @objc public static let shared = NebulaPerformanceMonitor()
15
+
16
+ // MARK: - Properties
17
+
18
+ private var measurements: [String: CFAbsoluteTime] = [:]
19
+ private let queue = DispatchQueue(label: "com.nebula.performance", attributes: .concurrent)
20
+
21
+ // MARK: - Public API
22
+
23
+ @objc public func startMeasure(_ key: String) {
24
+ queue.async(flags: .barrier) { [weak self] in
25
+ self?.measurements[key] = CFAbsoluteTimeGetCurrent()
26
+ }
27
+ }
28
+
29
+ @objc public func endMeasure(_ key: String) {
30
+ queue.async(flags: .barrier) { [weak self] in
31
+ guard let self = self,
32
+ let startTime = self.measurements[key] else {
33
+ return
34
+ }
35
+
36
+ let duration = CFAbsoluteTimeGetCurrent() - startTime
37
+ print("[Nebula:Performance] \(key): \(String(format: "%.3f", duration * 1000))ms")
38
+
39
+ self.measurements.removeValue(forKey: key)
40
+ }
41
+ }
42
+
43
+ private override init() {
44
+ super.init()
45
+ }
46
+ }