@sleeperhq/mini-core 1.9.2 → 1.9.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.
@@ -17,7 +17,7 @@
17
17
  "@react-navigation/native": "6.1.3",
18
18
  "@react-navigation/stack": "6.3.12",
19
19
  "@shopify/flash-list": "1.4.1",
20
- "@sleeperhq/mini-core": "1.9.2",
20
+ "@sleeperhq/mini-core": "1.9.3",
21
21
  "amazon-cognito-identity-js": "6.3.2",
22
22
  "crypto-js": "3.3.0",
23
23
  "decimal.js-light": "2.5.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleeperhq/mini-core",
3
- "version": "1.9.2",
3
+ "version": "1.9.3",
4
4
  "description": "Core library frameworks for developing Sleeper Mini Apps.",
5
5
  "main": "index.ts",
6
6
  "types": "index.d.ts",
@@ -50,6 +50,7 @@
50
50
  "react-refresh": "0.14.0",
51
51
  "react-test-renderer": "17.0.2",
52
52
  "regenerator-runtime": "0.13.11",
53
+ "string-replace-loader": "3.1.0",
53
54
  "terser-webpack-plugin": "5.3.6",
54
55
  "webpack": "5.75.0"
55
56
  },
@@ -0,0 +1,79 @@
1
+ class PacketParser {
2
+ constructor(props) {
3
+ this.logsEnabled = props.logsEnabled || false;
4
+ this.messageLength = 0;
5
+ this.messageType = '';
6
+ this.messageLength = 0;
7
+ this.partialMessage = '';
8
+ this.onMessageRecieved = props.onMessageRecieved;
9
+ }
10
+
11
+ parseMessage(msgString) {
12
+ while (msgString.length > 0) {
13
+ if (this.messageLength === 0) {
14
+ const delimit = msgString.indexOf('\n');
15
+ if (delimit === -1) {
16
+ console.log("[Sleeper] Message header not found, throwing out message.");
17
+ return;
18
+ }
19
+
20
+ const header = msgString.substring(0, delimit);
21
+ try {
22
+ const headerObject = JSON.parse(header);
23
+ this.messageType = headerObject.type;
24
+ this.messageLength = headerObject.size;
25
+ } catch (e) {
26
+ console.log("[Sleeper] Message header malformed, throwing out message.");
27
+ this.messageLength = 0;
28
+ this.messageType = '';
29
+ return;
30
+ }
31
+
32
+ msgString = msgString.substring(delimit + 1);
33
+ }
34
+
35
+ const partialLength = this.messageLength - this.partialMessage.length;
36
+ if (partialLength < 0) {
37
+ // We need to wait for more data
38
+ this.partialMessage += msgString;
39
+ return;
40
+ }
41
+
42
+ const remainingLength = msgString.length - partialLength;
43
+ if (remainingLength === 0) {
44
+ // We have the full message
45
+ this.partialMessage += msgString;
46
+ msgString = '';
47
+ if (this.logsEnabled) console.log("[Sleeper] Message built.", this.partialMessage.length);
48
+
49
+ } else {
50
+ // We have more than the full message
51
+ this.partialMessage += msgString.substring(0, partialLength);
52
+ msgString = msgString.substring(partialLength);
53
+
54
+ if (remainingLength <= 0) {
55
+ // We have less than the full message
56
+ if (this.logsEnabled) console.log("[Sleeper] Building message: ", this.partialMessage.length, this.messageLength, remainingLength);
57
+ return;
58
+ }
59
+ }
60
+
61
+ try {
62
+ const json = JSON.parse(this.partialMessage);
63
+ this.partialMessage = '';
64
+ this.messageLength = 0;
65
+
66
+ this.onMessageRecieved({
67
+ type: this.messageType,
68
+ data: json,
69
+ });
70
+ } catch (e) {
71
+ console.log("[Sleeper] Failed to parse message: ", e);
72
+ return;
73
+ }
74
+ }
75
+ }
76
+
77
+ };
78
+
79
+ module.exports = PacketParser;
@@ -1,20 +1,19 @@
1
- import React, {useEffect, useRef, useState} from 'react';
2
- import {Platform, NativeModules} from 'react-native';
3
- import {Config, SocketMessage} from '../types';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { Platform } from 'react-native';
3
+ import { Config, SocketMessage } from '../types';
4
4
  import { ScriptLocatorResolver, ScriptManager } from '@callstack/repack/client';
5
5
  import NetInfo, { NetInfoState } from '@react-native-community/netinfo';
6
6
  import TcpSocket from 'react-native-tcp-socket';
7
7
  import { fetchMainVersionMap, getMainUrl } from './url_resolver';
8
+ import PacketParser from '../common/packet_parser';
8
9
 
9
10
  let config: Config;
10
11
  const RETRY_TIMER = 5000;
11
12
 
12
13
  const DevServer = props => {
13
14
  const connection = useRef<TcpSocket.Socket>();
14
- const partialMessage = useRef('');
15
- const messageLength = useRef(0);
16
- const messageType = useRef('');
17
15
  const _retryTimer = useRef<NodeJS.Timeout>();
16
+ const packetParser = useRef<PacketParser>();
18
17
 
19
18
  const [data, setData] = useState({
20
19
  platform: '',
@@ -29,92 +28,6 @@ const DevServer = props => {
29
28
  props.onConnected(value);
30
29
  };
31
30
 
32
- const onSocket = (handler) => msg => {
33
- let msgString: string = msg.toString();
34
- while (msgString.length > 0) {
35
- if (messageLength.current === 0) {
36
- const delimit = msgString.indexOf('\n');
37
- if (delimit === -1) {
38
- console.log("[Sleeper] Message header not found, throwing out message.");
39
- return;
40
- }
41
-
42
- const header = msgString.substring(0, delimit);
43
- try {
44
- const headerObject = JSON.parse(header);
45
- messageType.current = headerObject.type;
46
- messageLength.current = headerObject.size;
47
- } catch (e) {
48
- console.log("[Sleeper] Message header malformed, throwing out message.");
49
- messageLength.current = 0;
50
- messageType.current = '';
51
- return;
52
- }
53
-
54
- msgString = msgString.substring(delimit + 1);
55
- }
56
-
57
- const partialLength = messageLength.current - partialMessage.current.length;
58
- if (partialLength < 0) {
59
- // We need to wait for more data
60
- partialMessage.current += msgString;
61
- return;
62
- }
63
-
64
- const remainingLength = msgString.length - partialLength;
65
- if (remainingLength === 0) {
66
- // We have the full message
67
- partialMessage.current += msgString;
68
- msgString = '';
69
- if (config.logsEnabled) console.log("[Sleeper] Message built.", partialMessage.current.length);
70
-
71
- } else {
72
- // We have more than the full message
73
- partialMessage.current += msgString.substring(0, partialLength);
74
- msgString = msgString.substring(partialLength);
75
-
76
- if (remainingLength <= 0) {
77
- // We have less than the full message
78
- if (config.logsEnabled) console.log("[Sleeper] Building message: ", partialMessage.current.length, messageLength.current, remainingLength);
79
- return;
80
- }
81
- }
82
-
83
- try {
84
- const json = JSON.parse(partialMessage.current);
85
- partialMessage.current = '';
86
- messageLength.current = 0;
87
-
88
- // Set connection data
89
- if (json._platform || json._binaryVersion || json._dist || json._isStaging) {
90
- if (config.logsEnabled) console.log("[Sleeper] Processing context data:", json._platform, json._binaryVersion, json._dist, json._isStaging);
91
- setData({
92
- platform: json._platform,
93
- binaryVersion: json._binaryVersion,
94
- dist: json._dist,
95
- isStaging: json._isStaging,
96
- });
97
- }
98
-
99
- if (messageType.current === 'context') {
100
- // We should have a context object now
101
- const context = new Proxy(json._context, handler);
102
- props.onContextChanged(context, json._entitlements);
103
- } else if (messageType.current === `partialContext`) {
104
- // We are updating a partial Context
105
- props.onContextUpdated(json._context);
106
- } else if (messageType.current === 'entitlements') {
107
- props.onEntitlementsUpdated(json._entitlements);
108
- }
109
-
110
- messageType.current = '';
111
- } catch (e) {
112
- console.log("[Sleeper] Failed to parse message: ", e);
113
- return;
114
- }
115
- }
116
- };
117
-
118
31
  const sendContextRequest = (socket, propertyPath) => {
119
32
  const message: SocketMessage = {_contextGet: propertyPath};
120
33
  const json = JSON.stringify(message);
@@ -187,9 +100,35 @@ const DevServer = props => {
187
100
  // @ts-ignore
188
101
  const ipAddress = netInfoDetails?.ipAddress;
189
102
 
190
- const scriptURL = NativeModules.SourceCode.scriptURL;
191
- const address = scriptURL.split('://')[1].split('/')[0];
192
- const packagerIP = address.split(':')[0];
103
+ const createPacketParser = (handler) => {
104
+ return new PacketParser({
105
+ logsEnabled: false,
106
+ onMessageRecieved: (msg) => {
107
+ const json = msg.data;
108
+ // Set connection data
109
+ if (json._platform || json._binaryVersion || json._dist || json._isStaging) {
110
+ if (config.logsEnabled) console.log("[Sleeper] Processing context data:", json._platform, json._binaryVersion, json._dist, json._isStaging);
111
+ setData({
112
+ platform: json._platform,
113
+ binaryVersion: json._binaryVersion,
114
+ dist: json._dist,
115
+ isStaging: json._isStaging,
116
+ });
117
+ }
118
+
119
+ if (msg.type === 'context') {
120
+ // We should have a context object now
121
+ const context = new Proxy(json._context, handler);
122
+ props.onContextChanged(context, json._entitlements);
123
+ } else if (msg.type === `partialContext`) {
124
+ // We are updating a partial Context
125
+ props.onContextUpdated(json._context);
126
+ } else if (msg.type === 'entitlements') {
127
+ props.onEntitlementsUpdated(json._entitlements);
128
+ }
129
+ }
130
+ });
131
+ };
193
132
 
194
133
  if (!netInfoDetails || !('ipAddress' in netInfoDetails)) {
195
134
  console.error('[Sleeper] Failed to determine local IP address.');
@@ -203,15 +142,17 @@ const DevServer = props => {
203
142
  reuseAddress: true,
204
143
  }, () => {
205
144
  console.log('[Sleeper] Connected to the Sleeper App.');
145
+ const handler = proxyHandler(connection.current);
146
+ packetParser.current = createPacketParser(handler);
147
+
206
148
  // When we establish a connection, request context
207
149
  sendContextRequest(connection.current, "");
208
150
  _onConnected(true);
209
151
  });
210
152
 
211
- connection.current.on('data', (data, ...args) => {
212
- const handler = proxyHandler(connection.current);
213
- const onSocketHandler = onSocket(handler);
214
- onSocketHandler(data);
153
+ connection.current.on('data', (data) => {
154
+ const msgString: string = data.toString();
155
+ packetParser.current?.parseMessage(msgString);
215
156
  });
216
157
  connection.current.on('error', err => {
217
158
  return stopSocket();
@@ -223,6 +164,7 @@ const DevServer = props => {
223
164
 
224
165
  const stopSocket = (retry = true) => {
225
166
  _onConnected(false);
167
+ packetParser.current = undefined;
226
168
 
227
169
  if (connection.current) {
228
170
  connection.current.destroy();
@@ -1,5 +1,6 @@
1
1
  import { Socket } from 'net';
2
2
  import path from 'path';
3
+ import PacketParser from '../common/packet_parser.js';
3
4
 
4
5
  const appJsonFilename = 'app.json';
5
6
  const packagerConnectPort = 9092;
@@ -20,6 +21,18 @@ const packagerConnect = async (rootPath) => {
20
21
  console.log('Attempting to connect to Sleeper App at ', appConfig.remoteIP);
21
22
 
22
23
  const client = new Socket();
24
+ const packetParser = new PacketParser({
25
+ logsEnabled: false,
26
+ onMessageRecieved: (msg) => {
27
+ switch (msg?.type) {
28
+ case 'consoleLog':
29
+ console.log('[MiniLog]', msg.data?._consoleLog);
30
+ break;
31
+ default:
32
+ break;
33
+ }
34
+ }
35
+ });
23
36
 
24
37
  client.on('connect', () => {
25
38
  console.log('Connected to Sleeper App at ', appConfig.remoteIP);
@@ -51,9 +64,8 @@ const packagerConnect = async (rootPath) => {
51
64
  });
52
65
 
53
66
  client.on('data', (data) => {
54
- // const json = JSON.parse(data);
55
- // switch (json?.type) {
56
- // }
67
+ const msgString = data.toString();
68
+ packetParser.parseMessage(msgString);
57
69
  });
58
70
 
59
71
  client.on('close', (hadError) => {
package/start.tsx CHANGED
@@ -9,6 +9,10 @@ import {
9
9
  } from 'react-native';
10
10
  import {DevServer, Types} from '.';
11
11
 
12
+ const console_modified = global.console as any;
13
+ console_modified.log_mini = (...args: any[]) => { console.log('[MiniLog]', ...args); }
14
+ global.console = console_modified;
15
+
12
16
  import 'root/package_list';
13
17
  import config from 'root/app.json';
14
18
  import Project from 'app';
package/webpack.config.js CHANGED
@@ -221,6 +221,15 @@ module.exports = env => {
221
221
  },
222
222
  },
223
223
  },
224
+ {
225
+ test: /\.[jt]sx?$/,
226
+ include: /src/,
227
+ loader: 'string-replace-loader',
228
+ options: {
229
+ search: 'console.log',
230
+ replace: 'console.log_mini',
231
+ }
232
+ },
224
233
  /**
225
234
  * This loader handles all static assets (images, video, audio and others), so that you can
226
235
  * use (reference) them inside your application.