@sleeperhq/mini-core 0.0.2
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/.github/pull_request_template.md +8 -0
- package/README.md +9 -0
- package/bin/build_mini.js +189 -0
- package/bin/preload_packages.js +58 -0
- package/declarations/avatar/index.d.ts +23 -0
- package/declarations/button/index.d.ts +37 -0
- package/declarations/index.d.ts +5 -0
- package/declarations/jersey/index.d.ts +9 -0
- package/declarations/navigation/index.d.ts +35 -0
- package/declarations/sleeper_actions.d.ts +8 -0
- package/declarations/sleeper_context.d.ts +28 -0
- package/declarations/sleeper_message.d.ts +12 -0
- package/declarations/switch/index.d.ts +3 -0
- package/declarations/text/index.d.ts +14 -0
- package/declarations/types/components/app_icon_switch.d.ts +24 -0
- package/declarations/types/components/jersey.d.ts +3 -0
- package/declarations/types/index.d.ts +33 -0
- package/declarations/types/minis/index.d.ts +71 -0
- package/declarations/types/shared/graphql.d.ts +258 -0
- package/declarations/types/utils/toast_helper.d.ts +9 -0
- package/index.ts +7 -0
- package/mini_packages.json +109 -0
- package/package.json +87 -0
- package/src/common/packet_parser.js +79 -0
- package/src/components/MiniLogger.ts +18 -0
- package/src/components/index.tsx +85 -0
- package/src/dev_server/index.tsx +253 -0
- package/src/dev_server/url_resolver.tsx +72 -0
- package/src/plugins/rebuildNotifyPlugin.js +37 -0
- package/src/plugins/send_events.mjs +87 -0
- package/src/styles/fonts.ts +139 -0
- package/src/styles/index.ts +2 -0
- package/src/styles/theme.ts +69 -0
- package/src/types/index.ts +17 -0
- package/start.tsx +105 -0
- package/webpack.config.js +325 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { Platform } from 'react-native';
|
|
3
|
+
import { Config, SocketMessage } from '../types';
|
|
4
|
+
import { ScriptLocatorResolver, ScriptManager } from '@callstack/repack/client';
|
|
5
|
+
import NetInfo, { NetInfoState } from '@react-native-community/netinfo';
|
|
6
|
+
import TcpSocket from 'react-native-tcp-socket';
|
|
7
|
+
import { fetchMainVersionMap, getMainUrl } from './url_resolver';
|
|
8
|
+
import PacketParser from '../common/packet_parser';
|
|
9
|
+
|
|
10
|
+
let config: Config;
|
|
11
|
+
const RETRY_TIMER = 5000;
|
|
12
|
+
|
|
13
|
+
const DevServer = props => {
|
|
14
|
+
const connection = useRef<TcpSocket.Socket>();
|
|
15
|
+
const _retryTimer = useRef<NodeJS.Timeout>();
|
|
16
|
+
const packetParser = useRef<PacketParser>();
|
|
17
|
+
|
|
18
|
+
const [data, setData] = useState({
|
|
19
|
+
platform: '',
|
|
20
|
+
binaryVersion: '',
|
|
21
|
+
dist: '',
|
|
22
|
+
isStaging: false,
|
|
23
|
+
});
|
|
24
|
+
const _dataRef = useRef<typeof data>();
|
|
25
|
+
const _versionMap = useRef<Record<string, string>>();
|
|
26
|
+
|
|
27
|
+
const _onConnected = async (value: boolean) => {
|
|
28
|
+
props.onConnected(value);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const sendContextRequest = (socket, propertyPath) => {
|
|
32
|
+
const message: SocketMessage = {_contextGet: propertyPath};
|
|
33
|
+
const json = JSON.stringify(message);
|
|
34
|
+
try {
|
|
35
|
+
socket?.write(json + '\n');
|
|
36
|
+
} catch (e) {
|
|
37
|
+
console.log("[Sleeper] Failed to send context request: ", e);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const proxyHandler = (socket) => {
|
|
42
|
+
return {
|
|
43
|
+
get: (target, property) => {
|
|
44
|
+
let value = Reflect.get(target, property);
|
|
45
|
+
|
|
46
|
+
// Check if we need to add a proxy to this object
|
|
47
|
+
if (!!value && typeof value === 'object' && !value._isProxy && value._isProxyInternal) {
|
|
48
|
+
const isLeaf = !value._continueProxy;
|
|
49
|
+
// Adding proxies to objects
|
|
50
|
+
const handler = proxyHandlerChild(socket, property, isLeaf);
|
|
51
|
+
const proxiedValue = new Proxy(value, handler);
|
|
52
|
+
Reflect.set(target, property, proxiedValue);
|
|
53
|
+
value = proxiedValue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const proxyHandlerChild = (socket, path, isLeaf) => {
|
|
62
|
+
return {
|
|
63
|
+
get: (target, property) => {
|
|
64
|
+
// Check if a proxy was already added to this object
|
|
65
|
+
if (property === '_isProxy') {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const value = Reflect.get(target, property);
|
|
70
|
+
const fullPropertyPath = `${path}.${property}`;
|
|
71
|
+
|
|
72
|
+
// If the value is undefined, we need to request it from the server
|
|
73
|
+
if (value === undefined && isLeaf) {
|
|
74
|
+
if (config.logsEnabled) console.log("[Sleeper] Requesting context value: ", fullPropertyPath);
|
|
75
|
+
sendContextRequest(socket, fullPropertyPath);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check if we need to add a second layer proxy to this object
|
|
79
|
+
if (!isLeaf && !value?._isProxy) {
|
|
80
|
+
const nextLeaf = true; // Currently we only support 2 layers of proxies
|
|
81
|
+
// Adding proxies to objects
|
|
82
|
+
// These proxies aren't stored in the context object so we will regenerate them every time
|
|
83
|
+
const handler = proxyHandlerChild(socket, fullPropertyPath, nextLeaf);
|
|
84
|
+
if (value === undefined) {
|
|
85
|
+
return new Proxy({}, handler);
|
|
86
|
+
} else {
|
|
87
|
+
return new Proxy(value, handler);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const startSocket = async () => {
|
|
97
|
+
const netInfo: NetInfoState = await NetInfo.fetch();
|
|
98
|
+
|
|
99
|
+
const netInfoDetails = netInfo?.details;
|
|
100
|
+
// @ts-ignore
|
|
101
|
+
const ipAddress = netInfoDetails?.ipAddress;
|
|
102
|
+
|
|
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
|
+
};
|
|
132
|
+
|
|
133
|
+
if (!netInfoDetails || !('ipAddress' in netInfoDetails)) {
|
|
134
|
+
console.error('[Sleeper] Failed to determine local IP address.');
|
|
135
|
+
return stopSocket();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
connection.current = TcpSocket.createConnection({
|
|
139
|
+
port: config.remoteSocketPort || 9092,
|
|
140
|
+
host: config.remoteIP,
|
|
141
|
+
localAddress: ipAddress,
|
|
142
|
+
reuseAddress: true,
|
|
143
|
+
}, () => {
|
|
144
|
+
console.log('[Sleeper] Connected to the Sleeper App.');
|
|
145
|
+
const handler = proxyHandler(connection.current);
|
|
146
|
+
packetParser.current = createPacketParser(handler);
|
|
147
|
+
|
|
148
|
+
// When we establish a connection, request context
|
|
149
|
+
sendContextRequest(connection.current, "");
|
|
150
|
+
_onConnected(true);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
connection.current.on('data', (data) => {
|
|
154
|
+
const msgString: string = data.toString();
|
|
155
|
+
packetParser.current?.parseMessage(msgString);
|
|
156
|
+
});
|
|
157
|
+
connection.current.on('error', err => {
|
|
158
|
+
return stopSocket();
|
|
159
|
+
});
|
|
160
|
+
connection.current.on('close', (hadError) => {
|
|
161
|
+
return stopSocket();
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const stopSocket = (retry = true) => {
|
|
166
|
+
_onConnected(false);
|
|
167
|
+
packetParser.current = undefined;
|
|
168
|
+
|
|
169
|
+
if (connection.current) {
|
|
170
|
+
connection.current.destroy();
|
|
171
|
+
connection.current = undefined;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Any time the socket is closed, attempt to connect again.
|
|
175
|
+
if (retry) {
|
|
176
|
+
clearTimeout(_retryTimer.current);
|
|
177
|
+
_retryTimer.current = setTimeout(() => {
|
|
178
|
+
console.log('[Sleeper] Unable to connect to sleeper, retrying...');
|
|
179
|
+
startSocket();
|
|
180
|
+
}, RETRY_TIMER);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const _waitForInitialization = () => {
|
|
185
|
+
return new Promise<void>((resolve) => {
|
|
186
|
+
(function checkData() {
|
|
187
|
+
let isInitialized = !!_dataRef.current?.dist;
|
|
188
|
+
|
|
189
|
+
// Non-staging builds also require a version map to be defined.
|
|
190
|
+
if (!_dataRef.current?.isStaging && !config.dev) {
|
|
191
|
+
isInitialized = !!_versionMap.current;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (isInitialized) return resolve();
|
|
195
|
+
setTimeout(checkData, 1000);
|
|
196
|
+
})();
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const _resolveRemoteChunk: ScriptLocatorResolver = async (scriptId: string, caller: string) => {
|
|
201
|
+
await _waitForInitialization();
|
|
202
|
+
|
|
203
|
+
const bundleName = !caller ? `${scriptId}.container.bundle` : `${scriptId}.chunk.bundle`;
|
|
204
|
+
|
|
205
|
+
// Try to resolve URL based on scriptId and caller
|
|
206
|
+
const url = getMainUrl(scriptId, caller, {
|
|
207
|
+
platform: _dataRef.current?.platform,
|
|
208
|
+
bundleVersion: _versionMap.current?.[bundleName],
|
|
209
|
+
binaryVersion: _dataRef.current?.binaryVersion,
|
|
210
|
+
dist: _dataRef.current?.dist,
|
|
211
|
+
isStaging: _dataRef.current?.isStaging,
|
|
212
|
+
remoteIP: config.remoteIP,
|
|
213
|
+
dev: config.dev,
|
|
214
|
+
});
|
|
215
|
+
const query = config.dev ? {platform: Platform.OS} : undefined;
|
|
216
|
+
|
|
217
|
+
if (config.logsEnabled) console.log('[Sleeper] load script:', scriptId, caller, url);
|
|
218
|
+
return {url, query};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const _fetchVersionMap = async (platform, binaryVersion, dist) => {
|
|
222
|
+
_versionMap.current = await fetchMainVersionMap(platform, binaryVersion, dist);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
useEffect(() => {
|
|
226
|
+
_dataRef.current = data;
|
|
227
|
+
if (!data.platform || !data.binaryVersion || !data.dist) return;
|
|
228
|
+
|
|
229
|
+
_fetchVersionMap(data.platform, data.binaryVersion, data.dist);
|
|
230
|
+
}, [data.platform, data.binaryVersion, data.dist, data.isStaging]);
|
|
231
|
+
|
|
232
|
+
useEffect(() => {
|
|
233
|
+
if (!config) {
|
|
234
|
+
console.error('[Sleeper] No config file specified. Please make sure you call DevServer.init() early in the app lifecycle.');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
ScriptManager.shared.addResolver(_resolveRemoteChunk.bind(this));
|
|
239
|
+
startSocket();
|
|
240
|
+
|
|
241
|
+
return () => {
|
|
242
|
+
stopSocket(false);
|
|
243
|
+
};
|
|
244
|
+
}, []);
|
|
245
|
+
|
|
246
|
+
return <></>;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
DevServer.init = (_config: Config) => {
|
|
250
|
+
config = _config;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export default DevServer;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import axios, { AxiosPromise, AxiosRequestConfig } from 'axios';
|
|
2
|
+
import {
|
|
3
|
+
getWebpackContext,
|
|
4
|
+
Federated,
|
|
5
|
+
} from '@callstack/repack/client';
|
|
6
|
+
import { Platform } from 'react-native';
|
|
7
|
+
|
|
8
|
+
export type MainPlatformData = {
|
|
9
|
+
// Received from socket
|
|
10
|
+
platform?: string,
|
|
11
|
+
bundleVersion?: string,
|
|
12
|
+
binaryVersion?: string,
|
|
13
|
+
dist?: string,
|
|
14
|
+
isStaging?: boolean,
|
|
15
|
+
|
|
16
|
+
// From app.json
|
|
17
|
+
remoteIP: string,
|
|
18
|
+
dev?: boolean,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const PROD_CDN = "https://sleepercdn.com/bundles";
|
|
22
|
+
const TEST_CDN = "https://test.sleepercdn.com/bundles";
|
|
23
|
+
|
|
24
|
+
// Query a list of urls, and grab the first one that returns a 200 response.
|
|
25
|
+
const _fetchFirstAvailable = (config: AxiosRequestConfig, ...urls: string[]) => {
|
|
26
|
+
return new Promise<any>((resolve) => {
|
|
27
|
+
(async function fetchMap() {
|
|
28
|
+
const promises = urls.map((url) => axios.get(url, config).catch(() => null));
|
|
29
|
+
const responses = await Promise.all<AxiosPromise>(promises);
|
|
30
|
+
|
|
31
|
+
const successfulResponse = responses.find((response) => response?.status === 200);
|
|
32
|
+
if (config?.method === 'HEAD') {
|
|
33
|
+
successfulResponse ? resolve({ url: successfulResponse.config.url }) : setTimeout(fetchMap, 5000);
|
|
34
|
+
} else {
|
|
35
|
+
successfulResponse ? resolve(successfulResponse.data) : setTimeout(fetchMap, 5000);
|
|
36
|
+
}
|
|
37
|
+
})();
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const fetchMainVersionMap = (platform: string, binaryVersion: string, dist: string) => {
|
|
42
|
+
const baseUrl = `${PROD_CDN}/version_maps/${platform}/${binaryVersion}/${dist}.json`;
|
|
43
|
+
const codepushUrl = `${PROD_CDN}/version_maps/${platform}/codepush/${dist}.json`;
|
|
44
|
+
|
|
45
|
+
return _fetchFirstAvailable({}, baseUrl, codepushUrl);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const getMainUrl = (scriptId: string, caller: string, config: MainPlatformData) => {
|
|
49
|
+
let sleeper: string;
|
|
50
|
+
|
|
51
|
+
if (config.dev) {
|
|
52
|
+
sleeper = `http://${config.remoteIP}:8081/`;
|
|
53
|
+
} else if (config.isStaging) {
|
|
54
|
+
if (config.dist === '0') {
|
|
55
|
+
sleeper = `${TEST_CDN}/${config.platform}/${config.binaryVersion}/${config.dist}/`;
|
|
56
|
+
} else {
|
|
57
|
+
sleeper = `${TEST_CDN}/${config.platform}/codepush/${config.dist}/`;
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
const platform = config.platform?.split('-')[0];
|
|
61
|
+
sleeper = `${PROD_CDN}/data/${platform}/${config.bundleVersion}/`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const resolveURL = Federated.createURLResolver({
|
|
65
|
+
containers: {
|
|
66
|
+
sleeper: `${sleeper}[name][ext]`,
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const bundleLocation = resolveURL(scriptId, caller);
|
|
70
|
+
|
|
71
|
+
return bundleLocation;
|
|
72
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var net = require('net');
|
|
2
|
+
/**
|
|
3
|
+
* @category Webpack Plugin
|
|
4
|
+
*/
|
|
5
|
+
class RebuildNotifyPlugin {
|
|
6
|
+
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Apply the plugin.
|
|
12
|
+
*
|
|
13
|
+
* @param compiler Webpack compiler instance.
|
|
14
|
+
*/
|
|
15
|
+
apply(compiler) {
|
|
16
|
+
compiler.hooks.done.tap('RebuildNotifyPlugin', (stats) => {
|
|
17
|
+
if (stats.hasErrors()) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log('Rebuild finished. Notifying the app...');
|
|
22
|
+
// Notify the app that the rebuild has finished
|
|
23
|
+
|
|
24
|
+
const client = new net.Socket();
|
|
25
|
+
client.connect(9093, this.config.remoteIP, () => {
|
|
26
|
+
const json = JSON.stringify({ _webpack: 'built' });
|
|
27
|
+
client.write(json);
|
|
28
|
+
client.destroy();
|
|
29
|
+
});
|
|
30
|
+
client.on('error', () => {
|
|
31
|
+
client.destroy();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
exports.RebuildNotifyPlugin = RebuildNotifyPlugin;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Socket } from 'net';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import PacketParser from '../common/packet_parser.js';
|
|
4
|
+
|
|
5
|
+
const appJsonFilename = 'app.json';
|
|
6
|
+
const packagerConnectPort = 9092;
|
|
7
|
+
const refreshTimeout = 5000; //milliseconds
|
|
8
|
+
|
|
9
|
+
const socketConnect = (client, appConfig) => {
|
|
10
|
+
client.connect(packagerConnectPort, appConfig.remoteIP);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const packagerConnect = async (rootPath) => {
|
|
14
|
+
const appJsonPath = path.join(rootPath, appJsonFilename);
|
|
15
|
+
const { default: appConfig } = await import(appJsonPath, { assert: { type: "json" } });
|
|
16
|
+
|
|
17
|
+
if (!appConfig.remoteIP) {
|
|
18
|
+
throw new Error(appJsonFilename + ' is missing remoteIP field');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log('Attempting to connect to Sleeper App at ', appConfig.remoteIP);
|
|
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
|
+
});
|
|
36
|
+
|
|
37
|
+
client.on('connect', () => {
|
|
38
|
+
console.log('Connected to Sleeper App at ', appConfig.remoteIP);
|
|
39
|
+
|
|
40
|
+
client.setEncoding('utf8');
|
|
41
|
+
client.setKeepAlive(true);
|
|
42
|
+
|
|
43
|
+
const json = JSON.stringify({
|
|
44
|
+
_webpack: 'packager_connect',
|
|
45
|
+
_name: appConfig.name ?? '',
|
|
46
|
+
_entitlements: appConfig.entitlements,
|
|
47
|
+
_headerOptions: appConfig.headerOptions,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
client.write(json, (err) => {
|
|
51
|
+
if (err) {
|
|
52
|
+
console.log('Error sending message to Sleeper App:', err);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
client.on('error', (error) => {
|
|
58
|
+
if (error?.code === 'ECONNREFUSED' && error?.syscall === 'connect') {
|
|
59
|
+
// We don't care about this error since we will retry the connection
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log('Socket Error: ', error);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
client.on('data', (data) => {
|
|
67
|
+
const msgString = data.toString();
|
|
68
|
+
packetParser.parseMessage(msgString);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
client.on('close', (hadError) => {
|
|
72
|
+
if (!hadError) {
|
|
73
|
+
console.log('Connection to Sleeper App closed, retrying...');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Retry connection
|
|
77
|
+
setTimeout(socketConnect, refreshTimeout, client, appConfig);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
socketConnect(client, appConfig);
|
|
81
|
+
|
|
82
|
+
return () => {
|
|
83
|
+
client.destroy();
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export default packagerConnect;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const SHARED = {
|
|
2
|
+
INTER_REGULAR: 'Inter-Regular',
|
|
3
|
+
INTER_MEDIUM: 'Inter-Medium',
|
|
4
|
+
INTER_SEMIBOLD: 'Inter-SemiBold',
|
|
5
|
+
INTER_BOLD: 'Inter-Bold',
|
|
6
|
+
INTER_BLACK: 'Inter-Black',
|
|
7
|
+
|
|
8
|
+
POPPINS_REGULAR: 'Poppins-Regular',
|
|
9
|
+
POPPINS_MEDIUM: 'Poppins-Medium',
|
|
10
|
+
POPPINS_SEMIBOLD: 'Poppins-SemiBold',
|
|
11
|
+
POPPINS_BOLD: 'Poppins-Bold',
|
|
12
|
+
POPPINS_BLACK: 'Poppins-Black',
|
|
13
|
+
POPPINS_EXTRABOLD: 'Poppins-ExtraBold',
|
|
14
|
+
|
|
15
|
+
OSWALD_MEDIUM: 'Oswald-Medium',
|
|
16
|
+
OSWALD_BOLD: 'Oswald-Bold',
|
|
17
|
+
} as const;
|
|
18
|
+
|
|
19
|
+
const Fonts = {
|
|
20
|
+
DRUK_SUPERITALIC: 'Druk-SuperItalic',
|
|
21
|
+
DRUK_REGULAR: 'Druk-Medium',
|
|
22
|
+
CHANEY_EXTENDED: 'Chaney-Extended',
|
|
23
|
+
|
|
24
|
+
...SHARED,
|
|
25
|
+
|
|
26
|
+
Styles: {
|
|
27
|
+
H1: {
|
|
28
|
+
fontFamily: SHARED.POPPINS_EXTRABOLD,
|
|
29
|
+
fontSize: 32,
|
|
30
|
+
},
|
|
31
|
+
H2: {
|
|
32
|
+
fontFamily: SHARED.POPPINS_EXTRABOLD,
|
|
33
|
+
fontSize: 28,
|
|
34
|
+
},
|
|
35
|
+
H3: {
|
|
36
|
+
fontFamily: SHARED.POPPINS_BOLD,
|
|
37
|
+
fontSize: 24,
|
|
38
|
+
},
|
|
39
|
+
H4: {
|
|
40
|
+
fontFamily: SHARED.POPPINS_BOLD,
|
|
41
|
+
fontSize: 20,
|
|
42
|
+
},
|
|
43
|
+
Title: {
|
|
44
|
+
fontFamily: SHARED.POPPINS_SEMIBOLD,
|
|
45
|
+
fontSize: 18,
|
|
46
|
+
},
|
|
47
|
+
Subhead: {
|
|
48
|
+
fontFamily: SHARED.POPPINS_SEMIBOLD,
|
|
49
|
+
fontSize: 16,
|
|
50
|
+
},
|
|
51
|
+
Menu: {
|
|
52
|
+
fontFamily: SHARED.POPPINS_SEMIBOLD,
|
|
53
|
+
fontSize: 12,
|
|
54
|
+
letterSpacing: 0.5,
|
|
55
|
+
},
|
|
56
|
+
ButtonLarge: {
|
|
57
|
+
fontFamily: SHARED.POPPINS_SEMIBOLD,
|
|
58
|
+
fontSize: 14,
|
|
59
|
+
letterSpacing: 1,
|
|
60
|
+
},
|
|
61
|
+
ButtonXLarge: {
|
|
62
|
+
fontFamily: SHARED.POPPINS_SEMIBOLD,
|
|
63
|
+
fontSize: 16,
|
|
64
|
+
letterSpacing: 1,
|
|
65
|
+
},
|
|
66
|
+
ButtonSmall: {
|
|
67
|
+
fontFamily: SHARED.POPPINS_SEMIBOLD,
|
|
68
|
+
fontSize: 12,
|
|
69
|
+
letterSpacing: 1,
|
|
70
|
+
},
|
|
71
|
+
TextCtaLarge: {
|
|
72
|
+
fontFamily: SHARED.POPPINS_SEMIBOLD,
|
|
73
|
+
fontSize: 14,
|
|
74
|
+
letterSpacing: 1,
|
|
75
|
+
},
|
|
76
|
+
TextCtaSmall: {
|
|
77
|
+
fontFamily: SHARED.POPPINS_SEMIBOLD,
|
|
78
|
+
fontSize: 12,
|
|
79
|
+
letterSpacing: 1,
|
|
80
|
+
},
|
|
81
|
+
Body1: {
|
|
82
|
+
fontFamily: SHARED.INTER_REGULAR,
|
|
83
|
+
fontSize: 16,
|
|
84
|
+
letterSpacing: -0.15,
|
|
85
|
+
},
|
|
86
|
+
Body1Bold: {
|
|
87
|
+
fontFamily: SHARED.INTER_SEMIBOLD,
|
|
88
|
+
fontSize: 16,
|
|
89
|
+
letterSpacing: -0.15,
|
|
90
|
+
},
|
|
91
|
+
Body2: {
|
|
92
|
+
fontFamily: SHARED.INTER_REGULAR,
|
|
93
|
+
fontSize: 14,
|
|
94
|
+
letterSpacing: -0.25,
|
|
95
|
+
},
|
|
96
|
+
Body2Bold: {
|
|
97
|
+
fontFamily: SHARED.INTER_SEMIBOLD,
|
|
98
|
+
fontSize: 14,
|
|
99
|
+
letterSpacing: -0.25,
|
|
100
|
+
},
|
|
101
|
+
Body3: {
|
|
102
|
+
fontFamily: SHARED.INTER_REGULAR,
|
|
103
|
+
fontSize: 12,
|
|
104
|
+
letterSpacing: -0.15,
|
|
105
|
+
},
|
|
106
|
+
Body3Bold: {
|
|
107
|
+
fontFamily: SHARED.INTER_SEMIBOLD,
|
|
108
|
+
fontSize: 12,
|
|
109
|
+
letterSpacing: -0.25,
|
|
110
|
+
},
|
|
111
|
+
Caption1: {
|
|
112
|
+
fontFamily: SHARED.INTER_REGULAR,
|
|
113
|
+
fontSize: 10,
|
|
114
|
+
letterSpacing: -0.25,
|
|
115
|
+
},
|
|
116
|
+
Caption1Bold: {
|
|
117
|
+
fontFamily: SHARED.INTER_BOLD,
|
|
118
|
+
fontSize: 10,
|
|
119
|
+
letterSpacing: -0.15,
|
|
120
|
+
},
|
|
121
|
+
Overline: {
|
|
122
|
+
fontFamily: SHARED.POPPINS_BOLD,
|
|
123
|
+
fontSize: 10,
|
|
124
|
+
letterSpacing: 0.25,
|
|
125
|
+
},
|
|
126
|
+
Footnote: {
|
|
127
|
+
fontFamily: SHARED.INTER_REGULAR,
|
|
128
|
+
fontSize: 9,
|
|
129
|
+
letterSpacing: -0.25,
|
|
130
|
+
},
|
|
131
|
+
FootnoteBold: {
|
|
132
|
+
fontFamily: SHARED.INTER_BOLD,
|
|
133
|
+
fontSize: 9,
|
|
134
|
+
letterSpacing: -0.25,
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
} as const;
|
|
138
|
+
|
|
139
|
+
export default Fonts;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const Theme = {
|
|
2
|
+
name: 'dark',
|
|
3
|
+
|
|
4
|
+
backgroundBase: '#030616',
|
|
5
|
+
backgroundDark: '#15182d',
|
|
6
|
+
backgroundCard: '#252942',
|
|
7
|
+
backgroundIce: '#fbfbfb',
|
|
8
|
+
backgroundWhite: '#ffffff',
|
|
9
|
+
|
|
10
|
+
primaryText: '#ffffff',
|
|
11
|
+
secondaryText: '#a3bbd3', // gray300
|
|
12
|
+
|
|
13
|
+
gray100: '#eef2f7',
|
|
14
|
+
gray200: '#D8DEED',
|
|
15
|
+
gray300: '#A3B1D3',
|
|
16
|
+
gray400: '#60648C',
|
|
17
|
+
gray500: '#414566',
|
|
18
|
+
gray600: '#343855',
|
|
19
|
+
|
|
20
|
+
aqua: '#00baff',
|
|
21
|
+
blue: '#046ae0',
|
|
22
|
+
cypress: '#019494',
|
|
23
|
+
green: '#45e8a7',
|
|
24
|
+
lavender: '#b8bfff',
|
|
25
|
+
lilac: '#bd66ff',
|
|
26
|
+
mint: '#00ceb8',
|
|
27
|
+
orange: '#ff5c00',
|
|
28
|
+
pink: '#ff7db6',
|
|
29
|
+
purple: '#6e7df5',
|
|
30
|
+
red: '#ff2b6d',
|
|
31
|
+
salmon: '#ff6086',
|
|
32
|
+
yam: '#8e66ff',
|
|
33
|
+
yellow: '#ffae58',
|
|
34
|
+
white: '#ffffff',
|
|
35
|
+
black: '#000000',
|
|
36
|
+
dark: '#022047',
|
|
37
|
+
|
|
38
|
+
gradients: {
|
|
39
|
+
// The `LinearGradient` component explicitly expects an array of color string, so casting in advance.
|
|
40
|
+
primary: ['#4ce2a7', '#00b7b3'] as string[],
|
|
41
|
+
success: ['#4ce2b8', '#07c5ff'] as string[],
|
|
42
|
+
cheer: ['#ffaa7f', '#ff3a6e'] as string[],
|
|
43
|
+
alert: ['#ffae58', '#ff4542'] as string[],
|
|
44
|
+
purple: ['#89a5fb', '#635ee4'] as string[],
|
|
45
|
+
lilac: ['#db84ff', '#9139ff'] as string[],
|
|
46
|
+
blue: ['#7cdaf9', '#5e73e4'] as string[],
|
|
47
|
+
gray: ['#e6effa', '#a3bbd3'] as string[],
|
|
48
|
+
darkgray: ['#a3bbd3', '#3a465b'] as string[],
|
|
49
|
+
background: ['#55609f', '#101c5a'] as string[],
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
getColorForSport(sport: string) {
|
|
53
|
+
if (sport === 'cbb') {
|
|
54
|
+
return Theme.orange;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (sport === 'nba') {
|
|
58
|
+
return Theme.yellow;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (sport === 'lcs' || sport === 'lol') {
|
|
62
|
+
return Theme.aqua;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return Theme.mint;
|
|
66
|
+
},
|
|
67
|
+
} as const;
|
|
68
|
+
|
|
69
|
+
export default Theme;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { HeaderOptions, Entitlement } from '../../declarations/types';
|
|
2
|
+
|
|
3
|
+
export * from '../../declarations/types/index.d';
|
|
4
|
+
export type { default as Context } from '../../declarations/sleeper_context.d';
|
|
5
|
+
export type { default as SocketMessage } from '../../declarations/sleeper_message.d';
|
|
6
|
+
export type { SleeperActions as Actions } from '../../declarations/sleeper_actions.d'
|
|
7
|
+
|
|
8
|
+
export type Config = {
|
|
9
|
+
name: string,
|
|
10
|
+
displayName: string,
|
|
11
|
+
remoteIP: string,
|
|
12
|
+
remoteSocketPort?: number,
|
|
13
|
+
dev?: boolean,
|
|
14
|
+
logsEnabled?: boolean,
|
|
15
|
+
entitlements?: Entitlement[],
|
|
16
|
+
headerOptions?: HeaderOptions,
|
|
17
|
+
};
|