@hot-updater/react-native 0.0.1 → 0.0.3

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/README.md CHANGED
@@ -5,6 +5,9 @@ React Native OTA solution for internal infrastructure
5
5
  * as-is
6
6
  ```objective-c
7
7
  // filename: ios/MyApp/AppDelegate.mm
8
+ // ...
9
+ #import <HotUpdater/HotUpdater.h>
10
+
8
11
  // ...
9
12
 
10
13
  - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
@@ -29,5 +32,5 @@ React Native OTA solution for internal infrastructure
29
32
  return [HotUpdater bundleURL];
30
33
  }
31
34
 
32
- / ...
35
+ // ...
33
36
  ```
@@ -5,19 +5,33 @@
5
5
  RCT_EXPORT_MODULE();
6
6
 
7
7
  static NSURL *_bundleURL = nil;
8
- static dispatch_once_t setBundleURLOnceToken;
9
8
 
10
9
  #pragma mark - Bundle URL Management
11
10
 
12
- + (void)setBundleURL:(NSURL *)url {
13
- dispatch_once(&setBundleURLOnceToken, ^{
14
- NSString *path = [self pathFromURL:url];
15
-
16
- if (![self downloadDataFromURL:url andSaveToPath:path]) {
17
- return;
18
- }
11
+ + (void)setVersionId:(NSString*)versionId {
12
+ static dispatch_once_t onceToken;
13
+ dispatch_once(&onceToken, ^{
14
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
15
+ [defaults setObject:versionId forKey:@"HotUpdaterVersionId"];
16
+ [defaults synchronize];
17
+ });
18
+ }
19
+
20
+ + (NSString *)getVersionId {
21
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
22
+ NSString *versionId = [defaults objectForKey:@"HotUpdaterVersionId"];
23
+ if (versionId && ![versionId isKindOfClass:[NSNull class]] && versionId.length > 0) {
24
+ return versionId;
25
+ } else {
26
+ return nil;
27
+ }
28
+ }
29
+
19
30
 
20
- _bundleURL = [NSURL fileURLWithPath:path];
31
+ + (void)setBundleURL:(NSString *)localPath {
32
+ static dispatch_once_t onceToken;
33
+ dispatch_once(&onceToken, ^{
34
+ _bundleURL = [NSURL fileURLWithPath:localPath];
21
35
  [[NSUserDefaults standardUserDefaults] setObject:[_bundleURL absoluteString] forKey:@"HotUpdaterBundleURL"];
22
36
  [[NSUserDefaults standardUserDefaults] synchronize];
23
37
  });
@@ -54,66 +68,95 @@ static dispatch_once_t setBundleURLOnceToken;
54
68
 
55
69
  #pragma mark - Utility Methods
56
70
 
57
- + (NSString *)pathForFilename:(NSString *)filename {
58
- return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:filename];
71
+ + (NSString *)convertFileSystemPathFromBasePath:(NSString *)basePath {
72
+ return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:basePath];
59
73
  }
60
74
 
61
- + (NSString *)pathFromURL:(NSURL *)url {
62
- NSString *pathComponent = url.path;
63
-
64
- if ([pathComponent hasPrefix:@"/"]) {
65
- pathComponent = [pathComponent substringFromIndex:1];
75
+ + (NSString *)removePrefixFromPath:(NSString *)path prefix:(NSString *)prefix {
76
+ if ([path hasPrefix:[NSString stringWithFormat:@"/%@/", prefix]]) {
77
+ return [path stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"/%@/", prefix] withString:@""];
66
78
  }
67
-
68
- return [self pathForFilename:pathComponent];
79
+ return path;
69
80
  }
70
81
 
71
- + (BOOL)downloadDataFromURL:(NSURL *)url andSaveToPath:(NSString *)path {
72
- NSData *data = [NSData dataWithContentsOfURL:url];
73
-
74
- if (!data) {
75
- NSLog(@"Failed to download data from URL: %@", url);
76
- return NO;
82
+ + (BOOL)downloadFilesFromURLs:(NSArray<NSURL *> *)urls prefix:(NSString *)prefix {
83
+ NSOperationQueue *queue = [[NSOperationQueue alloc] init];
84
+ queue.maxConcurrentOperationCount = urls.count;
85
+
86
+ __block BOOL allSuccess = YES;
87
+ dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
88
+
89
+ for (NSURL *url in urls) {
90
+ NSString *filename = [url lastPathComponent];
91
+ NSString *basePath = [self removePrefixFromPath:[url path] prefix:prefix];
92
+ NSString *path = [self convertFileSystemPathFromBasePath:basePath];
93
+
94
+ [queue addOperationWithBlock:^{
95
+ NSData *data = [NSData dataWithContentsOfURL:url];
96
+
97
+ if (!data) {
98
+ NSLog(@"Failed to download data from URL: %@", url);
99
+ allSuccess = NO;
100
+ dispatch_semaphore_signal(semaphore);
101
+ return;
102
+ }
103
+
104
+ NSFileManager *fileManager = [NSFileManager defaultManager];
105
+ NSError *folderError;
106
+ if (![fileManager createDirectoryAtPath:[path stringByDeletingLastPathComponent]
107
+ withIntermediateDirectories:YES
108
+ attributes:nil
109
+ error:&folderError]) {
110
+ NSLog(@"Failed to create folder: %@", folderError);
111
+ allSuccess = NO;
112
+ dispatch_semaphore_signal(semaphore);
113
+ return;
114
+ }
115
+
116
+ NSError *error;
117
+ [data writeToFile:path options:NSDataWritingAtomic error:&error];
118
+
119
+ if (error) {
120
+ NSLog(@"Failed to save data: %@", error);
121
+ allSuccess = NO;
122
+ }
123
+
124
+ if ([filename hasPrefix:@"index"] && [filename hasSuffix:@".bundle"]) {
125
+ [self setBundleURL:path];
126
+ }
127
+ dispatch_semaphore_signal(semaphore);
128
+ }];
77
129
  }
78
130
 
79
- NSFileManager *fileManager = [NSFileManager defaultManager];
80
- NSError *folderError;
81
- if (![fileManager createDirectoryAtPath:[path stringByDeletingLastPathComponent]
82
- withIntermediateDirectories:YES
83
- attributes:nil
84
- error:&folderError]) {
85
- NSLog(@"Failed to create folder: %@", folderError);
86
- return NO;
131
+ for (int i = 0; i < urls.count; i++) {
132
+ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
87
133
  }
88
-
89
- NSError *error;
90
- [data writeToFile:path options:NSDataWritingAtomic error:&error];
91
-
92
- if (error) {
93
- NSLog(@"Failed to save data: %@", error);
94
- return NO;
134
+
135
+ if (allSuccess) {
136
+ [self setVersionId:prefix];
137
+ NSLog(@"Downloaded all files.");
95
138
  }
96
-
97
- return YES;
139
+ return allSuccess;
98
140
  }
99
141
 
100
142
  #pragma mark - React Native Exports
101
143
 
102
- RCT_EXPORT_METHOD(getBundleURL:(RCTResponseSenderBlock)callback) {
103
- NSString *urlString = [HotUpdater.bundleURL absoluteString];
104
- callback(@[urlString]);
144
+ RCT_EXPORT_METHOD(getAppVersionId:(RCTResponseSenderBlock)callback) {
145
+ NSString *versionId = [HotUpdater getVersionId];
146
+ callback(@[versionId ?: [NSNull null]]);
105
147
  }
106
148
 
107
- RCT_EXPORT_METHOD(setBundleURL:(NSString *)urlString) {
108
- [HotUpdater setBundleURL:[NSURL URLWithString:urlString]];
109
- }
149
+ RCT_EXPORT_METHOD(downloadFilesFromURLs:(NSArray<NSString *> *)urlStrings prefix:(NSString *)prefix callback:(RCTResponseSenderBlock)callback) {
150
+ NSMutableArray<NSURL *> *urls = [NSMutableArray array];
151
+ for (NSString *urlString in urlStrings) {
152
+ NSURL *url = [NSURL URLWithString:urlString];
110
153
 
111
- RCT_EXPORT_METHOD(downloadAndSave:(NSString *)urlString callback:(RCTResponseSenderBlock)callback) {
112
- NSURL *url = [NSURL URLWithString:urlString];
113
- NSString *path = [HotUpdater pathFromURL:url];
114
- NSLog(@"Downloading %@ to %@", url, path);
115
- BOOL success = [HotUpdater downloadDataFromURL:url andSaveToPath:path];
116
- callback(@[@(success)]);
117
- }
154
+ if (url) {
155
+ [urls addObject:url];
156
+ }
157
+ }
118
158
 
159
+ BOOL result = [HotUpdater downloadFilesFromURLs:urls prefix:prefix];
160
+ callback(@[@(result)]);
161
+ }
119
162
  @end
package/lib/error.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ export declare class HotUpdaterDownloadError extends Error {
2
+ constructor();
3
+ }
4
+ export declare class HotUpdaterPlatformError extends Error {
5
+ constructor();
6
+ }
7
+ export declare class HotUpdaterMetadataError extends Error {
8
+ constructor();
9
+ }
10
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,qBAAa,uBAAwB,SAAQ,KAAK;;CAKjD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;;CAKjD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;;CAKjD"}
package/lib/error.js ADDED
@@ -0,0 +1,45 @@
1
+ var __extends = (this && this.__extends) || (function () {
2
+ var extendStatics = function (d, b) {
3
+ extendStatics = Object.setPrototypeOf ||
4
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6
+ return extendStatics(d, b);
7
+ };
8
+ return function (d, b) {
9
+ if (typeof b !== "function" && b !== null)
10
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
11
+ extendStatics(d, b);
12
+ function __() { this.constructor = d; }
13
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14
+ };
15
+ })();
16
+ var HotUpdaterDownloadError = /** @class */ (function (_super) {
17
+ __extends(HotUpdaterDownloadError, _super);
18
+ function HotUpdaterDownloadError() {
19
+ var _this = _super.call(this, "HotUpdater failed to download") || this;
20
+ _this.name = "HotUpdaterDownloadError";
21
+ return _this;
22
+ }
23
+ return HotUpdaterDownloadError;
24
+ }(Error));
25
+ export { HotUpdaterDownloadError };
26
+ var HotUpdaterPlatformError = /** @class */ (function (_super) {
27
+ __extends(HotUpdaterPlatformError, _super);
28
+ function HotUpdaterPlatformError() {
29
+ var _this = _super.call(this, "HotUpdater is only supported on iOS and Android") || this;
30
+ _this.name = "HotUpdaterPlatformError";
31
+ return _this;
32
+ }
33
+ return HotUpdaterPlatformError;
34
+ }(Error));
35
+ export { HotUpdaterPlatformError };
36
+ var HotUpdaterMetadataError = /** @class */ (function (_super) {
37
+ __extends(HotUpdaterMetadataError, _super);
38
+ function HotUpdaterMetadataError() {
39
+ var _this = _super.call(this, "HotUpdater metadata is not defined") || this;
40
+ _this.name = "HotUpdaterMetadataError";
41
+ return _this;
42
+ }
43
+ return HotUpdaterMetadataError;
44
+ }(Error));
45
+ export { HotUpdaterMetadataError };
package/lib/index.d.ts CHANGED
@@ -1,22 +1,25 @@
1
+ import { HotUpdaterMetaData } from "./types";
1
2
  /**
2
- * Retrieves the bundle URL.
3
+ * Fetches the current app version id.
3
4
  *
4
- * @returns {Promise<string>} A promise that resolves to the bundle URL.
5
+ * @async
6
+ * @returns {Promise<string|null>} Resolves with the current version id or null if not available.
5
7
  */
6
- export declare const getBundleURL: () => Promise<string>;
8
+ export declare const getAppVersionId: () => Promise<string | null>;
7
9
  /**
8
- * Sets the bundle URL.
10
+ * Downloads files from given URLs.
9
11
  *
10
- * @param {string} url - The URL to be set as the bundle URL.
11
- * @returns {void} No return value.
12
+ * @async
13
+ * @param {string[]} urlStrings - An array of URL strings to download files from.
14
+ * @param {string} prefix - The prefix to be added to each file name.
15
+ * @returns {Promise<boolean>} Resolves with true if download was successful, otherwise rejects with an error.
12
16
  */
13
- export declare const setBundleURL: (url: string) => any;
14
- /**
15
- * Downloads and saves data from the given URL.
16
- *
17
- * @param {string} url - The URL to download data from.
18
- * @returns {Promise<boolean>} Resolves with `true` if the operation is successful, otherwise rejects with `false`.
19
- *
20
- */
21
- export declare const downloadAndSave: (url: string) => Promise<boolean>;
17
+ export declare const downloadFilesFromURLs: (urlStrings: string[], prefix: string) => Promise<boolean>;
18
+ export type HotUpdaterStatus = "INSTALLING_UPDATE" | "UP_TO_DATE";
19
+ export interface HotUpdaterInit {
20
+ metadata: HotUpdaterMetaData | (() => HotUpdaterMetaData) | (() => Promise<HotUpdaterMetaData>);
21
+ onSuccess?: (status: HotUpdaterStatus) => void;
22
+ onFailure?: (e: unknown) => void;
23
+ }
24
+ export declare const init: ({ metadata, onSuccess, onFailure, }: HotUpdaterInit) => Promise<void>;
22
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,eAAO,MAAM,YAAY,uBAIxB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,QAAS,MAAM,QAEvC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,qBAM1C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAM7C;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAa,QAAQ,MAAM,GAAG,IAAI,CAM7D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,eACpB,MAAM,EAAE,UACZ,MAAM,KACb,QAAQ,OAAO,CAqBjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,YAAY,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EACJ,kBAAkB,GAClB,CAAC,MAAM,kBAAkB,CAAC,GAC1B,CAAC,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAExC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC;AAED,eAAO,MAAM,IAAI,wCAId,cAAc,kBA6BhB,CAAC"}
package/lib/index.js CHANGED
@@ -1,35 +1,133 @@
1
- import { NativeModules } from "react-native";
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import { URL } from "react-native-url-polyfill";
38
+ import { NativeModules, Platform } from "react-native";
39
+ import { HotUpdaterDownloadError, HotUpdaterPlatformError } from "./error";
40
+ import { wrapNetworkError } from "./wrapNetworkError";
2
41
  var HotUpdater = NativeModules.HotUpdater;
3
42
  /**
4
- * Retrieves the bundle URL.
43
+ * Fetches the current app version id.
5
44
  *
6
- * @returns {Promise<string>} A promise that resolves to the bundle URL.
45
+ * @async
46
+ * @returns {Promise<string|null>} Resolves with the current version id or null if not available.
7
47
  */
8
- export var getBundleURL = function () {
9
- return new Promise(function (resolve) {
10
- return HotUpdater.getBundleURL(function (url) { return resolve(url); });
48
+ export var getAppVersionId = function () { return __awaiter(void 0, void 0, void 0, function () {
49
+ return __generator(this, function (_a) {
50
+ return [2 /*return*/, new Promise(function (resolve) {
51
+ HotUpdater.getAppVersionId(function (versionId) {
52
+ resolve(versionId);
53
+ });
54
+ })];
11
55
  });
12
- };
56
+ }); };
13
57
  /**
14
- * Sets the bundle URL.
58
+ * Downloads files from given URLs.
15
59
  *
16
- * @param {string} url - The URL to be set as the bundle URL.
17
- * @returns {void} No return value.
60
+ * @async
61
+ * @param {string[]} urlStrings - An array of URL strings to download files from.
62
+ * @param {string} prefix - The prefix to be added to each file name.
63
+ * @returns {Promise<boolean>} Resolves with true if download was successful, otherwise rejects with an error.
18
64
  */
19
- export var setBundleURL = function (url) {
20
- return HotUpdater.setBundleURL(url);
65
+ export var downloadFilesFromURLs = function (urlStrings, prefix) {
66
+ return new Promise(function (resolve) {
67
+ var encodedURLs = urlStrings.map(function (urlString) {
68
+ var url = new URL(urlString);
69
+ return [
70
+ url.host,
71
+ url.pathname
72
+ .split("/")
73
+ .map(function (pathname) { return encodeURIComponent(pathname); })
74
+ .join("/"),
75
+ ].join("/");
76
+ });
77
+ HotUpdater.downloadFilesFromURLs(encodedURLs, prefix, function (success) {
78
+ resolve(success);
79
+ });
80
+ });
21
81
  };
22
- /**
23
- * Downloads and saves data from the given URL.
24
- *
25
- * @param {string} url - The URL to download data from.
26
- * @returns {Promise<boolean>} Resolves with `true` if the operation is successful, otherwise rejects with `false`.
27
- *
28
- */
29
- export var downloadAndSave = function (url) {
30
- return new Promise(function (resolve, reject) {
31
- return HotUpdater.downloadAndSave(url, function (isSuccess) {
32
- return isSuccess ? resolve(true) : reject(false);
82
+ export var init = function (_a) {
83
+ var metadata = _a.metadata, onSuccess = _a.onSuccess, onFailure = _a.onFailure;
84
+ return __awaiter(void 0, void 0, void 0, function () {
85
+ var _b, files, id, _c, appVersionId, allDownloadFiles, e_1;
86
+ return __generator(this, function (_d) {
87
+ switch (_d.label) {
88
+ case 0:
89
+ if (!["ios", "android"].includes(Platform.OS)) {
90
+ throw new HotUpdaterPlatformError();
91
+ }
92
+ _d.label = 1;
93
+ case 1:
94
+ _d.trys.push([1, 8, , 9]);
95
+ if (!(typeof metadata === "function")) return [3 /*break*/, 3];
96
+ return [4 /*yield*/, wrapNetworkError(metadata)];
97
+ case 2:
98
+ _c = _d.sent();
99
+ return [3 /*break*/, 4];
100
+ case 3:
101
+ _c = metadata;
102
+ _d.label = 4;
103
+ case 4:
104
+ _b = _c, files = _b.files, id = _b.id;
105
+ return [4 /*yield*/, getAppVersionId()];
106
+ case 5:
107
+ appVersionId = _d.sent();
108
+ if (!(id !== appVersionId)) return [3 /*break*/, 7];
109
+ return [4 /*yield*/, downloadFilesFromURLs(files, id)];
110
+ case 6:
111
+ allDownloadFiles = _d.sent();
112
+ if (allDownloadFiles) {
113
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess("INSTALLING_UPDATE");
114
+ }
115
+ else {
116
+ throw new HotUpdaterDownloadError();
117
+ }
118
+ return [2 /*return*/];
119
+ case 7:
120
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess("UP_TO_DATE");
121
+ return [3 /*break*/, 9];
122
+ case 8:
123
+ e_1 = _d.sent();
124
+ if (onFailure) {
125
+ onFailure(e_1);
126
+ return [2 /*return*/];
127
+ }
128
+ throw e_1;
129
+ case 9: return [2 /*return*/];
130
+ }
33
131
  });
34
132
  });
35
133
  };
package/lib/types.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export type Version = `${number}.${number}.${number}` | `${number}.${number}` | `${number}`;
2
+ export type HotUpdaterMetaData = {
3
+ files: string[];
4
+ version: Version;
5
+ id: string;
6
+ };
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GACf,GAAG,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,GAC/B,GAAG,MAAM,IAAI,MAAM,EAAE,GACrB,GAAG,MAAM,EAAE,CAAC;AAEhB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC"}
package/lib/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare function wrapNetworkError<T>(metadata: (() => Promise<T>) | (() => T)): Promise<T>;
2
+ //# sourceMappingURL=wrapNetworkError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapNetworkError.d.ts","sourceRoot":"","sources":["../src/wrapNetworkError.ts"],"names":[],"mappings":"AAEA,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,QAAQ,EAAE,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GACvC,OAAO,CAAC,CAAC,CAAC,CAMZ"}
@@ -0,0 +1,54 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import { HotUpdaterMetadataError } from "./error";
38
+ export function wrapNetworkError(metadata) {
39
+ return __awaiter(this, void 0, void 0, function () {
40
+ var error_1;
41
+ return __generator(this, function (_a) {
42
+ switch (_a.label) {
43
+ case 0:
44
+ _a.trys.push([0, 2, , 3]);
45
+ return [4 /*yield*/, metadata()];
46
+ case 1: return [2 /*return*/, _a.sent()];
47
+ case 2:
48
+ error_1 = _a.sent();
49
+ throw new HotUpdaterMetadataError();
50
+ case 3: return [2 /*return*/];
51
+ }
52
+ });
53
+ });
54
+ }
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@hot-updater/react-native",
3
- "version": "0.0.1",
4
- "description": "React Native OTA solution for internal infrastructure",
3
+ "version": "0.0.3",
4
+ "description": "React Native OTA solution for self-hosted",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [
8
- "src",
9
8
  "lib",
10
9
  "android",
11
10
  "ios",
@@ -22,7 +21,13 @@
22
21
  "!**/__mocks__",
23
22
  "!**/.*"
24
23
  ],
25
- "keywords": [],
24
+ "keywords": [
25
+ "react-native",
26
+ "code",
27
+ "push",
28
+ "code-push",
29
+ "self-hosted"
30
+ ],
26
31
  "license": "MIT",
27
32
  "repository": "https://github.com/gronxb/hot-updater",
28
33
  "author": "gronxb <gron1gh1@gmail.com> (https://github.com/gronxb)",
@@ -43,8 +48,12 @@
43
48
  "react": "^18.2.0",
44
49
  "react-native": "^0.72.6"
45
50
  },
51
+ "dependencies": {
52
+ "react-native-url-polyfill": "^2.0.0"
53
+ },
46
54
  "scripts": {
47
55
  "preinstall": "npx only-allow pnpm",
56
+ "typecheck": "tsc --noEmit",
48
57
  "build": "tsc"
49
58
  }
50
59
  }
package/src/index.ts DELETED
@@ -1,39 +0,0 @@
1
- import { NativeModules } from "react-native";
2
-
3
- const { HotUpdater } = NativeModules;
4
-
5
- /**
6
- * Retrieves the bundle URL.
7
- *
8
- * @returns {Promise<string>} A promise that resolves to the bundle URL.
9
- */
10
- export const getBundleURL = () => {
11
- return new Promise<string>((resolve) =>
12
- HotUpdater.getBundleURL((url: string) => resolve(url))
13
- );
14
- };
15
-
16
- /**
17
- * Sets the bundle URL.
18
- *
19
- * @param {string} url - The URL to be set as the bundle URL.
20
- * @returns {void} No return value.
21
- */
22
- export const setBundleURL = (url: string) => {
23
- return HotUpdater.setBundleURL(url);
24
- };
25
-
26
- /**
27
- * Downloads and saves data from the given URL.
28
- *
29
- * @param {string} url - The URL to download data from.
30
- * @returns {Promise<boolean>} Resolves with `true` if the operation is successful, otherwise rejects with `false`.
31
- *
32
- */
33
- export const downloadAndSave = (url: string) => {
34
- return new Promise<boolean>((resolve, reject) =>
35
- HotUpdater.downloadAndSave(url, (isSuccess: boolean) =>
36
- isSuccess ? resolve(true) : reject(false)
37
- )
38
- );
39
- };