@expensify/react-native-live-markdown 0.1.191 → 0.1.193

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
@@ -20,7 +20,7 @@ npm install @expensify/react-native-live-markdown react-native-reanimated expens
20
20
  npx expo install @expensify/react-native-live-markdown react-native-reanimated expensify-common
21
21
  ```
22
22
 
23
- React Native Live Markdown requires [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) 3.16.3 or newer and [expensify-common](https://github.com/Expensify/expensify-common) 2.0.106 or newer.
23
+ React Native Live Markdown requires [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) 3.16.3 or newer and [expensify-common](https://github.com/Expensify/expensify-common) 2.0.108 or newer.
24
24
 
25
25
  Then, install the iOS dependencies with CocoaPods:
26
26
 
@@ -0,0 +1,12 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import <RNLiveMarkdown/MarkdownRange.h>
3
+
4
+ NS_ASSUME_NONNULL_BEGIN
5
+
6
+ @interface MarkdownParser : NSObject
7
+
8
+ - (NSArray<MarkdownRange *> *)parse:(NSString *)text withParserId:(NSNumber *)parserId;
9
+
10
+ NS_ASSUME_NONNULL_END
11
+
12
+ @end
@@ -0,0 +1,68 @@
1
+ #import "MarkdownParser.h"
2
+ #import <RNLiveMarkdown/MarkdownGlobal.h>
3
+ #import <React/RCTLog.h>
4
+ #import <mutex>
5
+
6
+ @implementation MarkdownParser {
7
+ NSString *_prevText;
8
+ NSNumber *_prevParserId;
9
+ NSArray<MarkdownRange *> *_prevMarkdownRanges;
10
+ }
11
+
12
+ - (NSArray<MarkdownRange *> *)parse:(NSString *)text withParserId:(nonnull NSNumber *)parserId {
13
+ @synchronized (self) {
14
+ if ([text isEqualToString:_prevText] && [parserId isEqualToNumber:_prevParserId]) {
15
+ return _prevMarkdownRanges;
16
+ }
17
+
18
+ static std::mutex workletRuntimeMutex; // this needs to be global since the worklet runtime is also global
19
+ const auto lock = std::lock_guard<std::mutex>(workletRuntimeMutex);
20
+
21
+ const auto &markdownRuntime = expensify::livemarkdown::getMarkdownRuntime();
22
+ jsi::Runtime &rt = markdownRuntime->getJSIRuntime();
23
+
24
+ const auto &markdownWorklet = expensify::livemarkdown::getMarkdownWorklet([parserId intValue]);
25
+
26
+ const auto &input = jsi::String::createFromUtf8(rt, [text UTF8String]);
27
+
28
+ jsi::Value output;
29
+ try {
30
+ output = markdownRuntime->runGuarded(markdownWorklet, input);
31
+ } catch (const jsi::JSError &error) {
32
+ // Skip formatting, runGuarded will show the error in LogBox
33
+ _prevText = text;
34
+ _prevParserId = parserId;
35
+ _prevMarkdownRanges = @[];
36
+ return _prevMarkdownRanges;
37
+ }
38
+
39
+ NSMutableArray<MarkdownRange *> *markdownRanges = [[NSMutableArray alloc] init];
40
+ try {
41
+ const auto &ranges = output.asObject(rt).asArray(rt);
42
+ for (size_t i = 0, n = ranges.size(rt); i < n; ++i) {
43
+ const auto &item = ranges.getValueAtIndex(rt, i).asObject(rt);
44
+ const auto &type = item.getProperty(rt, "type").asString(rt).utf8(rt);
45
+ const auto &start = static_cast<int>(item.getProperty(rt, "start").asNumber());
46
+ const auto &length = static_cast<int>(item.getProperty(rt, "length").asNumber());
47
+ const auto &depth = item.hasProperty(rt, "depth") ? static_cast<int>(item.getProperty(rt, "depth").asNumber()) : 1;
48
+
49
+ NSRange range = NSMakeRange(start, length);
50
+ MarkdownRange *markdownRange = [[MarkdownRange alloc] initWithType:@(type.c_str()) range:range depth:depth];
51
+ [markdownRanges addObject:markdownRange];
52
+ }
53
+ } catch (const jsi::JSError &error) {
54
+ RCTLogWarn(@"[react-native-live-markdown] Incorrect schema of worklet parser output: %s", error.getMessage().c_str());
55
+ _prevText = text;
56
+ _prevParserId = parserId;
57
+ _prevMarkdownRanges = @[];
58
+ return _prevMarkdownRanges;
59
+ }
60
+
61
+ _prevText = text;
62
+ _prevParserId = parserId;
63
+ _prevMarkdownRanges = markdownRanges;
64
+ return _prevMarkdownRanges;
65
+ }
66
+ }
67
+
68
+ @end
@@ -1,12 +1,13 @@
1
1
  #import <RNLiveMarkdown/RCTMarkdownUtils.h>
2
2
  #import <RNLiveMarkdown/MarkdownGlobal.h>
3
- #import <RNLiveMarkdown/MarkdownRange.h>
3
+ #import <RNLiveMarkdown/MarkdownParser.h>
4
4
  #import "react_native_assert.h"
5
5
  #import <React/RCTAssert.h>
6
6
  #import <React/RCTFont.h>
7
7
  #include <jsi/jsi.h>
8
8
 
9
9
  @implementation RCTMarkdownUtils {
10
+ MarkdownParser *_markdownParser;
10
11
  NSString *_prevInputString;
11
12
  NSAttributedString *_prevAttributedString;
12
13
  NSDictionary<NSAttributedStringKey, id> *_prevTextAttributes;
@@ -14,6 +15,15 @@
14
15
  __weak NSNumber *_prevParserId;
15
16
  }
16
17
 
18
+ - (instancetype)init
19
+ {
20
+ if (self = [super init]) {
21
+ _markdownParser = [MarkdownParser new];
22
+ }
23
+
24
+ return self;
25
+ }
26
+
17
27
  - (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input withAttributes:(nullable NSDictionary<NSAttributedStringKey,id> *)attributes
18
28
  {
19
29
  @synchronized (self) {
@@ -26,43 +36,8 @@
26
36
  return _prevAttributedString;
27
37
  }
28
38
 
29
- static std::mutex runtimeMutex;
30
- auto lock = std::lock_guard<std::mutex>(runtimeMutex);
31
-
32
- auto markdownRuntime = expensify::livemarkdown::getMarkdownRuntime();
33
- jsi::Runtime &rt = markdownRuntime->getJSIRuntime();
34
-
35
- auto markdownWorklet = expensify::livemarkdown::getMarkdownWorklet([_parserId intValue]);
36
-
37
- NSMutableArray *markdownRanges = [[NSMutableArray alloc] init];
38
-
39
- try {
40
- const auto &text = jsi::String::createFromUtf8(rt, [inputString UTF8String]);
41
- const auto &output = markdownRuntime->runGuarded(markdownWorklet, text);
42
- const auto &ranges = output.asObject(rt).asArray(rt);
43
-
44
- for (size_t i = 0, n = ranges.size(rt); i < n; ++i) {
45
- const auto &item = ranges.getValueAtIndex(rt, i).asObject(rt);
46
- const auto &type = item.getProperty(rt, "type").asString(rt).utf8(rt);
47
- const auto &start = static_cast<int>(item.getProperty(rt, "start").asNumber());
48
- const auto &length = static_cast<int>(item.getProperty(rt, "length").asNumber());
49
- const auto &depth = item.hasProperty(rt, "depth") ? static_cast<int>(item.getProperty(rt, "depth").asNumber()) : 1;
50
-
51
- NSRange range = NSMakeRange(start, length);
52
- MarkdownRange *markdownRange = [[MarkdownRange alloc] initWithType:@(type.c_str()) range:range depth:depth];
53
- [markdownRanges addObject:markdownRange];
54
- }
55
- } catch (const jsi::JSError &error) {
56
- RCTLogWarn(@"[react-native-live-markdown] Incorrect schema of worklet parser output: %s", error.getMessage().c_str());
57
- NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:inputString attributes:attributes];
58
- _prevInputString = inputString;
59
- _prevAttributedString = attributedString;
60
- _prevTextAttributes = attributes;
61
- _prevMarkdownStyle = _markdownStyle;
62
- _prevParserId = _parserId;
63
- return attributedString;
64
- }
65
-
39
+ NSArray<MarkdownRange *> *markdownRanges = [_markdownParser parse:inputString withParserId:_parserId];
40
+
66
41
  NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:inputString attributes:attributes];
67
42
  [attributedString beginEditing];
68
43
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expensify/react-native-live-markdown",
3
- "version": "0.1.191",
3
+ "version": "0.1.193",
4
4
  "description": "Drop-in replacement for React Native's TextInput component with Markdown formatting.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -84,7 +84,7 @@
84
84
  "eslint-plugin-prettier": "^4.0.0",
85
85
  "eslint-plugin-promise": "^6.1.1",
86
86
  "eslint-plugin-tsdoc": "^0.2.17",
87
- "expensify-common": "2.0.106",
87
+ "expensify-common": "2.0.108",
88
88
  "jest": "^29.6.3",
89
89
  "jest-environment-jsdom": "^29.7.0",
90
90
  "nodemon": "^3.1.3",
@@ -100,7 +100,7 @@
100
100
  "typescript": "~5.3.3"
101
101
  },
102
102
  "peerDependencies": {
103
- "expensify-common": ">=2.0.106",
103
+ "expensify-common": ">=2.0.108",
104
104
  "react": "*",
105
105
  "react-native": "*",
106
106
  "react-native-reanimated": ">=3.16.3"