@sleeperhq/mini-core 1.0.3 → 1.0.4

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.
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const os = require('os');
5
+ const path = require('path');
6
+
7
+ const isWindows = os.platform() === 'win32';
8
+
9
+ const outputFile = 'mini-app';
10
+ const zipFile = `${outputFile}.zip`;
11
+ const assetsDestPath = {
12
+ ios: path.join(outputFile, 'ios'),
13
+ android: path.join(outputFile, 'android'),
14
+ };
15
+ const bundleOutputPath = {
16
+ ios: path.join(assetsDestPath["ios"], 'index.bundle'),
17
+ android: path.join(assetsDestPath["android"], 'index.bundle'),
18
+ };
19
+ const sourcemapOutputPath = {
20
+ ios: path.join(assetsDestPath["ios"], 'index.bundle.map'),
21
+ android: path.join(assetsDestPath["android"], 'index.bundle.map'),
22
+ };
23
+ const reactNativeCliPath = path.join('node_modules', 'react-native', 'cli.js');
24
+
25
+ const spawnProcess = (command, errorMessage) => {
26
+ return new Promise((resolve) => {
27
+ const child = isWindows
28
+ ? spawn('cmd.exe', ['/c', command])
29
+ : spawn(command, { shell: true });
30
+
31
+ child.stdout.on('data', (data) => {
32
+ process.stdout.write(data); // output the data to the console
33
+ });
34
+
35
+ child.stderr.on('data', (data) => {
36
+ process.stderr.write(data); // output the error to the console
37
+ });
38
+
39
+ child.on('close', (code) => {
40
+ if (code !== 0) {
41
+ printError(errorMessage || `command exited with non-zero code: ${code}`);
42
+ process.exit(1);
43
+ }
44
+ resolve();
45
+ });
46
+ });
47
+ };
48
+
49
+ const printError = (error) => {
50
+ console.error("\n\033[91m" + error + "\033[0m");
51
+ };
52
+
53
+ const printInfo = (message) => {
54
+ console.log("\n\033[96m" + message + "\033[0m");
55
+ };
56
+
57
+ const printComplete = (message) => {
58
+ console.log("\033[92m" + message + "\033[0m");
59
+ };
60
+
61
+ const getBundleCommand = (platform) => {
62
+ return `node ${reactNativeCliPath} webpack-bundle \
63
+ --entry-file index.tsx \
64
+ --platform ${platform} \
65
+ --dev false \
66
+ --reset-cache \
67
+ --bundle-output ${bundleOutputPath[platform]} \
68
+ --sourcemap-output ${sourcemapOutputPath[platform]} \
69
+ --minify false \
70
+ --assets-dest ${assetsDestPath[platform]}`;
71
+ };
72
+
73
+ const deleteCommand = (isWindows ? 'rmdir /s /q ' : 'rm -rf ');
74
+ const zipCommand = isWindows ?
75
+ `powershell Compress-Archive -Path ${outputFile} -DestinationPath ${zipFile}` :
76
+ `zip -r ${zipFile} ${outputFile}`;
77
+ const openCommand = isWindows ? `start .` : `open .`;
78
+ const cleanIndexCommand = `${deleteCommand} ${bundleOutputPath["ios"]} ${bundleOutputPath["android"]} ${sourcemapOutputPath["ios"]} ${sourcemapOutputPath["android"]}`;
79
+ const cleanAllCommand = `${deleteCommand} ${outputFile} ${zipFile}`;
80
+ const cleanBuildCommand = `${deleteCommand} ${outputFile}`;
81
+
82
+ const main = async () => {
83
+ // Clean build folders
84
+ await spawnProcess(cleanAllCommand, "clean command exited with non-zero code");
85
+
86
+ // Build iOS
87
+ printInfo("Building iOS...");
88
+ await spawnProcess(getBundleCommand("ios"), "webpack-bundle ios command exited with non-zero code");
89
+ printComplete("iOS build complete.");
90
+
91
+ // Build Android
92
+ printInfo("Building Android...");
93
+ await spawnProcess(getBundleCommand("android"), "webpack-bundle android command exited with non-zero code");
94
+ printComplete("Android build complete.");
95
+
96
+ // Create Zip Archive
97
+ printInfo("Creating zip archive...");
98
+ await spawnProcess(cleanIndexCommand, "clean command exited with non-zero code");
99
+ await spawnProcess(zipCommand, "zip command exited with non-zero code");
100
+ printComplete("Zip archive created successfully at mini-app.zip.");
101
+
102
+ // Clean build folders
103
+ await spawnProcess(cleanBuildCommand, "clean command exited with non-zero code");
104
+
105
+ // Open output folder
106
+ spawnProcess(openCommand);
107
+ };
108
+
109
+ main();
@@ -1,37 +1,37 @@
1
- /// <reference types="react" />
2
- import { GestureResponderEvent } from 'react-native';
3
- export interface ButtonProps {
4
- height?: number;
5
- gradient?: (string | number)[];
6
- start?: {
7
- x: number;
8
- y: number;
9
- };
10
- end?: {
11
- x: number;
12
- y: number;
13
- };
14
- disable?: boolean;
15
- onPress?: (event: GestureResponderEvent) => void;
16
- text?: string;
17
- }
18
- declare const Button: {
19
- (props: ButtonProps): JSX.Element;
20
- defaultProps: {
21
- height: number;
22
- shadowHeight: number;
23
- gradient: string[];
24
- type: string;
25
- size: string;
26
- isForSmallScreen: boolean;
27
- start: {
28
- x: number;
29
- y: number;
30
- };
31
- end: {
32
- x: number;
33
- y: number;
34
- };
35
- };
36
- };
37
- export default Button;
1
+ /// <reference types="react" />
2
+ import { GestureResponderEvent } from 'react-native';
3
+ export interface ButtonProps {
4
+ height?: number;
5
+ gradient?: (string | number)[];
6
+ start?: {
7
+ x: number;
8
+ y: number;
9
+ };
10
+ end?: {
11
+ x: number;
12
+ y: number;
13
+ };
14
+ disable?: boolean;
15
+ onPress?: (event: GestureResponderEvent) => void;
16
+ text?: string;
17
+ }
18
+ declare const Button: {
19
+ (props: ButtonProps): JSX.Element;
20
+ defaultProps: {
21
+ height: number;
22
+ shadowHeight: number;
23
+ gradient: string[];
24
+ type: string;
25
+ size: string;
26
+ isForSmallScreen: boolean;
27
+ start: {
28
+ x: number;
29
+ y: number;
30
+ };
31
+ end: {
32
+ x: number;
33
+ y: number;
34
+ };
35
+ };
36
+ };
37
+ export default Button;
@@ -1,3 +1,4 @@
1
- export * from './types';
2
- declare const _default: any;
3
- export default _default;
1
+ export * from './types';
2
+ export * from './sleeper_message';
3
+ declare const _default: any;
4
+ export default _default;
@@ -1,9 +1,9 @@
1
- import { ColorValue, ViewStyle } from 'react-native';
2
- import SleeperJersey from 'components/ui/jersey';
3
- export interface JerseyProps {
4
- style: ViewStyle;
5
- sport: 'nfl' | 'nba' | 'cbb' | 'cfb' | 'mlb';
6
- number: string;
7
- fill: ColorValue;
8
- }
9
- export default SleeperJersey;
1
+ import { ColorValue, ViewStyle } from 'react-native';
2
+ import SleeperJersey from 'components/ui/jersey';
3
+ export interface JerseyProps {
4
+ style: ViewStyle;
5
+ sport: 'nfl' | 'nba' | 'cbb' | 'cfb' | 'mlb';
6
+ number: string;
7
+ fill: ColorValue;
8
+ }
9
+ export default SleeperJersey;
@@ -1,5 +1,5 @@
1
- import { NavigationType, NavigationTypeId } from './types';
2
- declare class SleeperActions {
3
- navigate: (navType: NavigationType, navTypeId: NavigationTypeId) => void;
4
- }
5
- export default SleeperActions;
1
+ import { NavigationType, NavigationTypeId } from './types';
2
+ declare class SleeperActions {
3
+ navigate: (navType: NavigationType, navTypeId: NavigationTypeId) => void;
4
+ }
5
+ export default SleeperActions;
@@ -1,10 +1,21 @@
1
- import { User, Navigation, League } from './types';
2
- import SleeperActions from './sleeper_actions';
3
- declare class SleeperContext {
4
- user: User;
5
- navigation: Navigation;
6
- league: League;
7
- actions: SleeperActions;
8
- constructor(user: User, navigation: Navigation, league: League);
9
- }
10
- export default SleeperContext;
1
+ import { User, Navigation, League, LeaguesMap, RostersInLeagueMap } from './types';
2
+ import SleeperActions from './sleeper_actions';
3
+ type SleeperContextConfig = {
4
+ user: User;
5
+ navigation: Navigation;
6
+ league: League;
7
+ userLeagueList: string[];
8
+ leaguesMap: LeaguesMap;
9
+ rostersInLeagueMap: RostersInLeagueMap;
10
+ };
11
+ declare class SleeperContext {
12
+ user: User;
13
+ navigation: Navigation;
14
+ league: League;
15
+ leaguesMap: LeaguesMap;
16
+ userLeagueList: string[];
17
+ rostersInLeagueMap: RostersInLeagueMap;
18
+ actions: SleeperActions;
19
+ constructor(config: SleeperContextConfig);
20
+ }
21
+ export default SleeperContext;
@@ -0,0 +1,6 @@
1
+ type SocketMessage = {
2
+ _ip?: string;
3
+ _webpack?: string;
4
+ _contextGet?: string;
5
+ };
6
+ export default SocketMessage;
@@ -1,13 +1,13 @@
1
- import { PureComponent } from 'react';
2
- import { TextProps } from 'react-native';
3
- declare type Props = {
4
- color?: string;
5
- inheritStyles?: boolean;
6
- screenShrink?: number;
7
- } & TextProps;
8
- export declare type AppTextProps = Props;
9
- export default class AppText extends PureComponent<Props> {
10
- private getStyles;
11
- render(): JSX.Element;
12
- }
13
- export {};
1
+ import { PureComponent } from 'react';
2
+ import { TextProps } from 'react-native';
3
+ type Props = {
4
+ color?: string;
5
+ inheritStyles?: boolean;
6
+ screenShrink?: number;
7
+ } & TextProps;
8
+ export type AppTextProps = Props;
9
+ export default class AppText extends PureComponent<Props> {
10
+ private getStyles;
11
+ render(): JSX.Element;
12
+ }
13
+ export {};
@@ -1,9 +1,15 @@
1
- import { NAVIGATION_ID, NAVIGATION_TYPE } from './redux/native_nav/constants.d';
2
- export declare type NavigationType = typeof NAVIGATION_TYPE[keyof typeof NAVIGATION_TYPE];
3
- export declare type NavigationTypeId = typeof NAVIGATION_ID[keyof typeof NAVIGATION_ID];
4
- export * from './shared/graphql.d';
5
- export declare type Navigation = {
6
- selectedNavType: NavigationType;
7
- selectedNavTypeId: NavigationTypeId;
8
- selectedNavData: {};
9
- };
1
+ import { NAVIGATION_ID, NAVIGATION_TYPE } from './redux/native_nav/constants.d';
2
+ import { League, Roster } from './shared/graphql.d';
3
+ export * from './shared/graphql.d';
4
+ export type NavigationType = typeof NAVIGATION_TYPE[keyof typeof NAVIGATION_TYPE];
5
+ export type NavigationTypeId = typeof NAVIGATION_ID[keyof typeof NAVIGATION_ID];
6
+ export type Navigation = {
7
+ selectedNavType: NavigationType;
8
+ selectedNavTypeId: NavigationTypeId;
9
+ selectedNavData: {};
10
+ };
11
+ export type LeagueId = string;
12
+ export type RosterId = string;
13
+ export type LeaguesMap = Record<LeagueId, League>;
14
+ export type RostersMap = Record<RosterId, Roster>;
15
+ export type RostersInLeagueMap = Record<LeagueId, RostersMap>;
@@ -1,23 +1,23 @@
1
- export declare const NAVIGATION_TYPE: {
2
- readonly DM: "DM";
3
- readonly INBOX: "INBOX";
4
- readonly MY_FEED: "MY_FEED";
5
- readonly FRIENDS: "FRIENDS";
6
- readonly LEAGUE: "LEAGUE";
7
- readonly ASYNC_SPORT: "ASYNC_SPORT";
8
- readonly CREATE_LEAGUE: "CREATE_LEAGUE";
9
- readonly LEAGUE_SYNC: "LEAGUE_SYNC";
10
- readonly DRAFTBOARDS: "DRAFTBOARDS";
11
- readonly SOLO_OVER_UNDER: "SOLO_OVER_UNDER";
12
- readonly CHANNEL: "CHANNEL";
13
- readonly MANAGE_CHANNELS: "MANAGE_CHANNELS";
14
- };
15
- export declare const NAVIGATION_ID: {
16
- readonly DRAFTBOARDS: 1;
17
- readonly CREATE_DM: 2;
18
- readonly DM_SCREEN: 3;
19
- readonly CREATE_LEAGUE: 4;
20
- readonly MY_FEED: 5;
21
- readonly MENTIONS: 6;
22
- readonly FRIENDS: 7;
23
- };
1
+ export declare const NAVIGATION_TYPE: {
2
+ readonly DM: "DM";
3
+ readonly INBOX: "INBOX";
4
+ readonly MY_FEED: "MY_FEED";
5
+ readonly FRIENDS: "FRIENDS";
6
+ readonly LEAGUE: "LEAGUE";
7
+ readonly ASYNC_SPORT: "ASYNC_SPORT";
8
+ readonly CREATE_LEAGUE: "CREATE_LEAGUE";
9
+ readonly LEAGUE_SYNC: "LEAGUE_SYNC";
10
+ readonly DRAFTBOARDS: "DRAFTBOARDS";
11
+ readonly SOLO_OVER_UNDER: "SOLO_OVER_UNDER";
12
+ readonly CHANNEL: "CHANNEL";
13
+ readonly MANAGE_CHANNELS: "MANAGE_CHANNELS";
14
+ };
15
+ export declare const NAVIGATION_ID: {
16
+ readonly DRAFTBOARDS: 1;
17
+ readonly CREATE_DM: 2;
18
+ readonly DM_SCREEN: 3;
19
+ readonly CREATE_LEAGUE: 4;
20
+ readonly MY_FEED: 5;
21
+ readonly MENTIONS: 6;
22
+ readonly FRIENDS: 7;
23
+ };
@@ -1,98 +1,113 @@
1
- export declare type Maybe<T> = T | null;
2
- export declare type InputMaybe<T> = Maybe<T>;
3
- export declare type Exact<T extends {
4
- [key: string]: unknown;
5
- }> = {
6
- [K in keyof T]: T[K];
7
- };
8
- export declare type MakeOptional<T, K extends keyof T> = Omit<T, K> & {
9
- [SubKey in K]?: Maybe<T[SubKey]>;
10
- };
11
- export declare type MakeMaybe<T, K extends keyof T> = Omit<T, K> & {
12
- [SubKey in K]: Maybe<T[SubKey]>;
13
- };
14
- /** All built-in and custom scalars, mapped to their actual values */
15
- export declare type Scalars = {
16
- ID: string;
17
- String: string;
18
- Boolean: boolean;
19
- Int: number;
20
- Float: number;
21
- /** JSON */
22
- Json: {
23
- [key: string]: any;
24
- };
25
- /** Lists */
26
- List: string[];
27
- /** Map / Dictionary */
28
- Map: {
29
- [key: string]: any;
30
- };
31
- MapWithSnowflakeKey: {
32
- [key: string]: any;
33
- };
34
- /** Sets */
35
- Set: string[];
36
- /** Snowflake ID */
37
- Snowflake: string;
38
- SnowflakeList: string[];
39
- SnowflakeSet: string[];
40
- };
41
- export declare type League = {
42
- __typename?: 'League';
43
- avatar?: Maybe<Scalars['String']>;
44
- company_id?: Maybe<Scalars['Snowflake']>;
45
- display_order?: Maybe<Scalars['Int']>;
46
- draft_id?: Maybe<Scalars['Snowflake']>;
47
- group_id?: Maybe<Scalars['Snowflake']>;
48
- last_author_avatar?: Maybe<Scalars['String']>;
49
- last_author_display_name?: Maybe<Scalars['String']>;
50
- last_author_id?: Maybe<Scalars['Snowflake']>;
51
- last_author_is_bot?: Maybe<Scalars['Boolean']>;
52
- last_message_attachment?: Maybe<Scalars['Json']>;
53
- last_message_id?: Maybe<Scalars['Snowflake']>;
54
- last_message_text?: Maybe<Scalars['String']>;
55
- last_message_text_map?: Maybe<Scalars['Json']>;
56
- last_message_time?: Maybe<Scalars['Int']>;
57
- last_pinned_message_id?: Maybe<Scalars['Snowflake']>;
58
- last_read_id?: Maybe<Scalars['Snowflake']>;
59
- last_transaction_id?: Maybe<Scalars['Snowflake']>;
60
- league_id?: Maybe<Scalars['Snowflake']>;
61
- matchup_legs?: Maybe<Scalars['List']>;
62
- metadata?: Maybe<Scalars['Map']>;
63
- name?: Maybe<Scalars['String']>;
64
- previous_league_id?: Maybe<Scalars['Snowflake']>;
65
- roster_positions?: Maybe<Scalars['List']>;
66
- scoring_settings?: Maybe<Scalars['Map']>;
67
- season?: Maybe<Scalars['String']>;
68
- season_type?: Maybe<Scalars['String']>;
69
- settings?: Maybe<Scalars['Map']>;
70
- sport?: Maybe<Scalars['String']>;
71
- status?: Maybe<Scalars['String']>;
72
- total_rosters?: Maybe<Scalars['Int']>;
73
- };
74
- export declare type User = {
75
- __typename?: 'User';
76
- async_bundles?: Maybe<Scalars['List']>;
77
- avatar?: Maybe<Scalars['String']>;
78
- cookies?: Maybe<Scalars['Int']>;
79
- created?: Maybe<Scalars['Int']>;
80
- currencies?: Maybe<Scalars['Map']>;
81
- data_updated?: Maybe<Scalars['Map']>;
82
- deleted?: Maybe<Scalars['Int']>;
83
- display_name?: Maybe<Scalars['String']>;
84
- email?: Maybe<Scalars['String']>;
85
- is_bot?: Maybe<Scalars['Boolean']>;
86
- metadata?: Maybe<Scalars['Json']>;
87
- notifications?: Maybe<Scalars['Map']>;
88
- pending?: Maybe<Scalars['Boolean']>;
89
- phone?: Maybe<Scalars['String']>;
90
- real_name?: Maybe<Scalars['String']>;
91
- solicitable?: Maybe<Scalars['Boolean']>;
92
- summoner_name?: Maybe<Scalars['String']>;
93
- summoner_region?: Maybe<Scalars['String']>;
94
- token?: Maybe<Scalars['String']>;
95
- user_id?: Maybe<Scalars['Snowflake']>;
96
- username?: Maybe<Scalars['String']>;
97
- verification?: Maybe<Scalars['String']>;
98
- };
1
+ export type Maybe<T> = T | null;
2
+ export type InputMaybe<T> = Maybe<T>;
3
+ export type Exact<T extends {
4
+ [key: string]: unknown;
5
+ }> = {
6
+ [K in keyof T]: T[K];
7
+ };
8
+ export type MakeOptional<T, K extends keyof T> = Omit<T, K> & {
9
+ [SubKey in K]?: Maybe<T[SubKey]>;
10
+ };
11
+ export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & {
12
+ [SubKey in K]: Maybe<T[SubKey]>;
13
+ };
14
+ /** All built-in and custom scalars, mapped to their actual values */
15
+ export type Scalars = {
16
+ ID: string;
17
+ String: string;
18
+ Boolean: boolean;
19
+ Int: number;
20
+ Float: number;
21
+ /** JSON */
22
+ Json: {
23
+ [key: string]: any;
24
+ };
25
+ /** Lists */
26
+ List: string[];
27
+ /** Map / Dictionary */
28
+ Map: {
29
+ [key: string]: any;
30
+ };
31
+ MapWithSnowflakeKey: {
32
+ [key: string]: any;
33
+ };
34
+ /** Sets */
35
+ Set: string[];
36
+ /** Snowflake ID */
37
+ Snowflake: string;
38
+ SnowflakeList: string[];
39
+ SnowflakeSet: string[];
40
+ };
41
+ export type League = {
42
+ __typename?: 'League';
43
+ avatar?: Maybe<Scalars['String']>;
44
+ company_id?: Maybe<Scalars['Snowflake']>;
45
+ display_order?: Maybe<Scalars['Int']>;
46
+ draft_id?: Maybe<Scalars['Snowflake']>;
47
+ group_id?: Maybe<Scalars['Snowflake']>;
48
+ last_author_avatar?: Maybe<Scalars['String']>;
49
+ last_author_display_name?: Maybe<Scalars['String']>;
50
+ last_author_id?: Maybe<Scalars['Snowflake']>;
51
+ last_author_is_bot?: Maybe<Scalars['Boolean']>;
52
+ last_message_attachment?: Maybe<Scalars['Json']>;
53
+ last_message_id?: Maybe<Scalars['Snowflake']>;
54
+ last_message_text?: Maybe<Scalars['String']>;
55
+ last_message_text_map?: Maybe<Scalars['Json']>;
56
+ last_message_time?: Maybe<Scalars['Int']>;
57
+ last_pinned_message_id?: Maybe<Scalars['Snowflake']>;
58
+ last_read_id?: Maybe<Scalars['Snowflake']>;
59
+ last_transaction_id?: Maybe<Scalars['Snowflake']>;
60
+ league_id?: Maybe<Scalars['Snowflake']>;
61
+ matchup_legs?: Maybe<Scalars['List']>;
62
+ metadata?: Maybe<Scalars['Map']>;
63
+ name?: Maybe<Scalars['String']>;
64
+ previous_league_id?: Maybe<Scalars['Snowflake']>;
65
+ roster_positions?: Maybe<Scalars['List']>;
66
+ scoring_settings?: Maybe<Scalars['Map']>;
67
+ season?: Maybe<Scalars['String']>;
68
+ season_type?: Maybe<Scalars['String']>;
69
+ settings?: Maybe<Scalars['Map']>;
70
+ sport?: Maybe<Scalars['String']>;
71
+ status?: Maybe<Scalars['String']>;
72
+ total_rosters?: Maybe<Scalars['Int']>;
73
+ };
74
+ export type Roster = {
75
+ __typename?: 'Roster';
76
+ co_owners?: Maybe<Scalars['SnowflakeSet']>;
77
+ keepers?: Maybe<Scalars['Set']>;
78
+ league_id?: Maybe<Scalars['Snowflake']>;
79
+ metadata?: Maybe<Scalars['Map']>;
80
+ owner_id?: Maybe<Scalars['Snowflake']>;
81
+ player_map?: Maybe<Scalars['Map']>;
82
+ players?: Maybe<Scalars['Set']>;
83
+ reserve?: Maybe<Scalars['Set']>;
84
+ roster_id?: Maybe<Scalars['Int']>;
85
+ settings?: Maybe<Scalars['Map']>;
86
+ starters?: Maybe<Scalars['List']>;
87
+ taxi?: Maybe<Scalars['Set']>;
88
+ };
89
+ export type User = {
90
+ __typename?: 'User';
91
+ async_bundles?: Maybe<Scalars['List']>;
92
+ avatar?: Maybe<Scalars['String']>;
93
+ cookies?: Maybe<Scalars['Int']>;
94
+ created?: Maybe<Scalars['Int']>;
95
+ currencies?: Maybe<Scalars['Map']>;
96
+ data_updated?: Maybe<Scalars['Map']>;
97
+ deleted?: Maybe<Scalars['Int']>;
98
+ display_name?: Maybe<Scalars['String']>;
99
+ email?: Maybe<Scalars['String']>;
100
+ is_bot?: Maybe<Scalars['Boolean']>;
101
+ metadata?: Maybe<Scalars['Json']>;
102
+ notifications?: Maybe<Scalars['Map']>;
103
+ pending?: Maybe<Scalars['Boolean']>;
104
+ phone?: Maybe<Scalars['String']>;
105
+ real_name?: Maybe<Scalars['String']>;
106
+ solicitable?: Maybe<Scalars['Boolean']>;
107
+ summoner_name?: Maybe<Scalars['String']>;
108
+ summoner_region?: Maybe<Scalars['String']>;
109
+ token?: Maybe<Scalars['String']>;
110
+ user_id?: Maybe<Scalars['Snowflake']>;
111
+ username?: Maybe<Scalars['String']>;
112
+ verification?: Maybe<Scalars['String']>;
113
+ };
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@sleeperhq/mini-core",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Core library frameworks for developing Sleeper Mini Apps.",
5
5
  "main": "index.ts",
6
6
  "types": "index.d.ts",
7
+ "bin": {
8
+ "build-mini": "./bin/build_mini.js"
9
+ },
7
10
  "scripts": {
8
11
  "test": "jest",
9
12
  "lint": "eslint ."
@@ -30,7 +33,7 @@
30
33
  "access": "public"
31
34
  },
32
35
  "peerDependencies": {
33
- "@callstack/repack": "blitzstudios/repack.git#callstack-repack-v2.5.3-gitpkg",
36
+ "@callstack/repack": "blitzstudios/repack.git#callstack-repack-v2.6.0-gitpkg",
34
37
  "@react-native-community/netinfo": "^9.3.7",
35
38
  "axios": "0.15.3",
36
39
  "lodash": "4.17.21",
@@ -38,7 +41,7 @@
38
41
  "react-native": "0.66.5",
39
42
  "react-native-linear-gradient": "2.5.6",
40
43
  "react-native-svg": "13.7.0",
41
- "react-native-udp": "^4.1.6"
44
+ "react-native-tcp-socket": "^6.0.6"
42
45
  },
43
46
  "devDependencies": {
44
47
  "@babel/core": "^7.12.9",
@@ -1,58 +1,158 @@
1
- import React, {useEffect} from 'react';
1
+ import React, {useEffect, useRef, useState} from 'react';
2
2
  import {Platform} from 'react-native';
3
- import {Config} from '../types';
3
+ import {Config, SocketMessage} from '../types';
4
4
  import {ScriptManager, Federated} from '@callstack/repack/client';
5
5
  import NetInfo from '@react-native-community/netinfo';
6
- import dgram from 'react-native-udp';
6
+ import TcpSocket from 'react-native-tcp-socket';
7
7
  import axios from 'axios';
8
8
 
9
9
  let config: Config;
10
+ const RETRY_TIMER = 5000;
10
11
 
11
12
  const DevServer = props => {
12
- const onSocket = msg => {
13
- const json = JSON.parse(msg.toString());
14
- if (json?._connected) {
15
- return;
16
- }
13
+ const connection = useRef<TcpSocket.Socket>();
14
+ const partialMessage = useRef('');
15
+ const _retryTimer = useRef<NodeJS.Timeout>();
17
16
 
18
- props.onContextChanged(json);
17
+ const _onConnected = async (value: boolean) => {
18
+ props.onConnected(value);
19
19
  };
20
20
 
21
- const onError = err => {
22
- console.error('[Sleeper] Socket error: ' + err);
21
+ const onSocket = (handler) => msg => {
22
+ let json;
23
+ try {
24
+ json = JSON.parse(msg);
25
+ } catch(e) {
26
+ partialMessage.current += msg;
27
+ }
28
+
29
+ if (partialMessage.current.length > 0) {
30
+ try {
31
+ json = JSON.parse(partialMessage.current);
32
+ partialMessage.current = '';
33
+ } catch (e) {
34
+ return;
35
+ }
36
+ }
37
+
38
+ // We should have a context object now
39
+ const context = new Proxy(json, handler);
40
+ props.onContextChanged(context);
23
41
  };
24
42
 
25
- const bindSocket = async socket => {
43
+ const sendContextRequest = (socket, propertyPath) => {
44
+ const message: SocketMessage = {_contextGet: propertyPath};
45
+ const json = JSON.stringify(message);
46
+ try {
47
+ socket?.write(json);
48
+ } catch (e) {
49
+ console.log("[Sleeper] Failed to send context request: ", e);
50
+ }
51
+ }
52
+
53
+ const proxyHandler = (socket) => {
54
+ return {
55
+ get: (target, property) => {
56
+ if (property in target && target[property] !== null) {
57
+ const value = target[property];
58
+
59
+ if (typeof value !== 'object' || value._isProxy) {
60
+ return value;
61
+ }
62
+
63
+ // Adding proxies to objects
64
+ // Intentionally only going 1 level deep
65
+ const handler = proxyHandlerLeaf(socket, property);
66
+ target[property] = new Proxy(value, handler);
67
+ target[property]._isProxy = true;
68
+
69
+ return target[property];
70
+ }
71
+
72
+ // This property is not in the context object yet
73
+ sendContextRequest(socket, property);
74
+ return null;
75
+ }
76
+ };
77
+ }
78
+
79
+ // This handler is for leaf nodes only
80
+ const proxyHandlerLeaf = (socket, path) => {
81
+ return {
82
+ get: (target, property) => {
83
+ if (target[property] !== undefined) { // Only checking undefined properites for leaves
84
+ return target[property];
85
+ }
86
+
87
+ const fullProp = path + '.' + property;
88
+ sendContextRequest(socket, fullProp);
89
+ return null;
90
+ }
91
+ };
92
+ }
93
+
94
+ const startSocket = async () => {
26
95
  const netInfo = await NetInfo.fetch();
27
96
  const netInfoDetails = netInfo?.details;
97
+ const ipAddress = netInfoDetails?.ipAddress;
28
98
 
29
99
  if (!netInfoDetails || !('ipAddress' in netInfoDetails)) {
30
100
  console.error('[Sleeper] Failed to determine local IP address.');
31
- return;
101
+ return stopSocket();
32
102
  }
33
103
 
34
- socket.bind({port: config.localSocketPort, address: netInfoDetails.ipAddress});
35
- };
104
+ connection.current = TcpSocket.createConnection({
105
+ port: config.remoteSocketPort,
106
+ host: config.remoteIP,
107
+ localAddress: ipAddress,
108
+ reuseAddress: true,
109
+ }, () => {
110
+ // When we establish a connection, send the IP address to the server
111
+ const message: SocketMessage = { _ip: ipAddress };
112
+ const json = JSON.stringify(message);
113
+ try {
114
+ connection.current?.write(json, undefined, (error) => {
115
+ if (error) {
116
+ return stopSocket();
117
+ }
118
+ console.log('[Sleeper] Connected to the Sleeper App.');
119
+ _onConnected(true);
120
+ });
121
+ } catch (e) {
122
+ return stopSocket();
123
+ }
124
+ });
125
+
126
+ connection.current.on('data', (data, ...args) => {
127
+ const handler = proxyHandler(connection.current);
128
+ const onSocketHandler = onSocket(handler);
129
+ onSocketHandler(data);
130
+ });
131
+ connection.current.on('error', err => {
132
+ return stopSocket();
133
+ });
134
+ connection.current.on('close', (hadError) => {
135
+ return stopSocket();
136
+ });
137
+ }
36
138
 
37
- const pingServer = socket => {
38
- // Continue to ping the sleeper app server until it responds.
39
- return new Promise(() => {
40
- NetInfo.fetch().then(netInfo => {
41
- const netInfoDetails = netInfo?.details;
42
- if (!netInfoDetails || !('ipAddress' in netInfoDetails)) {
43
- console.error('[Sleeper] Failed to determine local IP address.');
44
- return;
45
- }
139
+ const stopSocket = (retry = true) => {
140
+ _onConnected(false);
46
141
 
47
- const json = JSON.stringify({_ip: netInfoDetails.ipAddress});
142
+ if (connection.current) {
143
+ connection.current.destroy();
144
+ connection.current = undefined;
145
+ }
48
146
 
49
- (async function ping() {
50
- socket.send(json, undefined, undefined, config.remoteSocketPort, config.remoteIP);
51
- setTimeout(ping, 5000);
52
- })();
53
- });
54
- });
55
- };
147
+ // Any time the socket is closed, attempt to connect again.
148
+ if (retry) {
149
+ clearTimeout(_retryTimer.current);
150
+ _retryTimer.current = setTimeout(() => {
151
+ console.log('[Sleeper] Unable to connect to sleeper, retrying...');
152
+ startSocket();
153
+ }, RETRY_TIMER);
154
+ }
155
+ }
56
156
 
57
157
  useEffect(() => {
58
158
  if (!config) {
@@ -60,14 +160,10 @@ const DevServer = props => {
60
160
  return;
61
161
  }
62
162
 
63
- const socket = dgram.createSocket({type: 'udp4'});
64
- bindSocket(socket);
65
- pingServer(socket);
163
+ startSocket();
66
164
 
67
- socket.on('message', onSocket);
68
- socket.on('error', onError);
69
165
  return () => {
70
- socket.removeAllListeners();
166
+ stopSocket(false);
71
167
  };
72
168
  }, []);
73
169
 
@@ -1,5 +1,6 @@
1
1
  export * from '../../declarations/types/index.d';
2
2
  export { default as Context } from '../../declarations/sleeper_context.d';
3
+ export { default as SocketMessage } from '../../declarations/sleeper_message.d';
3
4
 
4
5
  export type Config = {
5
6
  name: string,