@granite-js/react-native 0.1.6 → 0.1.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @granite-js/react-native
2
2
 
3
+ ## 0.1.8
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [b69366c]
8
+ - @granite-js/mpack@0.1.8
9
+ - @granite-js/cli@0.1.8
10
+ - @granite-js/image@0.1.8
11
+ - @granite-js/jest@0.1.8
12
+ - @granite-js/lottie@0.1.8
13
+ - @granite-js/native@0.1.8
14
+ - @granite-js/style-utils@0.1.8
15
+
16
+ ## 0.1.7
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [208c053]
21
+ - @granite-js/mpack@0.1.7
22
+ - @granite-js/cli@0.1.7
23
+ - @granite-js/image@0.1.7
24
+ - @granite-js/jest@0.1.7
25
+ - @granite-js/lottie@0.1.7
26
+ - @granite-js/native@0.1.7
27
+ - @granite-js/style-utils@0.1.7
28
+
3
29
  ## 0.1.6
4
30
 
5
31
  ### Patch Changes
@@ -0,0 +1 @@
1
+ export declare function AppRoot({ appName, context, container: Container, initialProps, router }: AppRootProps): import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import { ComponentType, PropsWithChildren } from 'react';
2
2
  import type { InitialProps } from '../initial-props';
3
- import { type RouterProps, type RequireContext } from '../router';
3
+ import type { RouterProps, RequireContext } from '../router';
4
4
  export interface GraniteProps {
5
5
  /**
6
6
  * @description
@@ -56,5 +56,6 @@ export interface GraniteProps {
56
56
  */
57
57
  export declare const Granite: {
58
58
  registerApp(AppContainer: ComponentType<PropsWithChildren<InitialProps>>, { appName, context, router }: GraniteProps): (initialProps: InitialProps) => JSX.Element;
59
+ registerHostApp(AppContainer: ComponentType<PropsWithChildren<InitialProps>>, { appName }: Pick<GraniteProps, "appName">): (initialProps: InitialProps) => JSX.Element;
59
60
  readonly appName: string;
60
61
  };
@@ -0,0 +1 @@
1
+ export declare function HostAppRoot({ container: Container, initialProps }: HostAppRootProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare const ENTRY_BUNDLE_NAME = "shared";
@@ -23,22 +23,6 @@ export declare function getRouteScreens(context: RequireContext): RouteScreen[];
23
23
  * @description Maps paths of screens.
24
24
  *
25
25
  * @param {RouteScreen[]} routeScreens - List of screens that can be navigated to
26
- *
27
- * @example
28
- * ```tsx
29
- * import { registerPage, getRouteScreens, getScreenPathMapConfig, Router } from '@granite-js/react-native';
30
- * import { context } from '../require.context';
31
- *
32
- * function App() {
33
- * return <Router context={context} prefix={'scheme://minibench'} />;
34
- * }
35
- *
36
- * export default registerPage(
37
- * App,
38
- * 'minibench',
39
- * getScreenPathMapConfig(getRouteScreens(context))
40
- * );
41
- * ```
42
26
  */
43
27
  export declare function getScreenPathMapConfig(routeScreens: RouteScreen[]): ScreenPath;
44
28
  /**
@@ -1,11 +1,7 @@
1
1
  export interface GraniteGlobal {
2
- shared: {
3
- buildNumber: string;
4
- };
5
2
  app: {
6
3
  name: string;
7
4
  scheme: string;
8
- buildNumber: string;
9
5
  };
10
6
  }
11
7
  declare global {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@granite-js/react-native",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "The Granite Framework",
5
5
  "bin": {
6
6
  "granite": "./bin/cli.js"
@@ -56,7 +56,7 @@
56
56
  "@babel/core": "^7.24.9",
57
57
  "@babel/preset-env": "^7.24.8",
58
58
  "@babel/preset-typescript": "^7.24.7",
59
- "@granite-js/native": "0.1.6",
59
+ "@granite-js/native": "0.1.8",
60
60
  "@testing-library/dom": "^10.4.0",
61
61
  "@testing-library/react": "^16.1.0",
62
62
  "@types/babel__core": "^7",
@@ -65,7 +65,7 @@
65
65
  "@types/react": "18.3.3",
66
66
  "@types/react-dom": "^18",
67
67
  "@vitest/coverage-v8": "^2.1.8",
68
- "esbuild": "^0.25.4",
68
+ "esbuild": "0.25.8",
69
69
  "eslint": "^9.7.0",
70
70
  "jsdom": "^25.0.1",
71
71
  "react": "18.2.0",
@@ -82,12 +82,12 @@
82
82
  "react-native": "*"
83
83
  },
84
84
  "dependencies": {
85
- "@granite-js/cli": "0.1.6",
86
- "@granite-js/image": "0.1.6",
87
- "@granite-js/jest": "0.1.6",
88
- "@granite-js/lottie": "0.1.6",
89
- "@granite-js/mpack": "0.1.6",
90
- "@granite-js/style-utils": "0.1.6",
85
+ "@granite-js/cli": "0.1.8",
86
+ "@granite-js/image": "0.1.8",
87
+ "@granite-js/jest": "0.1.8",
88
+ "@granite-js/lottie": "0.1.8",
89
+ "@granite-js/mpack": "0.1.8",
90
+ "@granite-js/style-utils": "0.1.8",
91
91
  "es-toolkit": "^1.34.1",
92
92
  "react-native-url-polyfill": "1.3.0"
93
93
  }
@@ -0,0 +1,39 @@
1
+ import { SafeAreaProvider } from '@granite-js/native/react-native-safe-area-context';
2
+ import type { ComponentType, PropsWithChildren } from 'react';
3
+ import type { GraniteProps } from './Granite';
4
+ import type { InitialProps } from '../initial-props';
5
+ import { BackEventProvider, useBackEventState } from '../use-back-event';
6
+ import { App } from './App';
7
+ import { Router } from '../router';
8
+
9
+ /**
10
+ * @internal
11
+ */
12
+ interface AppRootProps extends GraniteProps {
13
+ container: ComponentType<PropsWithChildren<InitialProps>>;
14
+ initialProps: InitialProps;
15
+ }
16
+
17
+ export function AppRoot({ appName, context, container: Container, initialProps, router }: AppRootProps) {
18
+ const backEventState = useBackEventState();
19
+ const scheme = global.__granite.app.scheme;
20
+ const baseScheme = `${scheme}://${appName}`;
21
+
22
+ return (
23
+ <App {...initialProps}>
24
+ <SafeAreaProvider>
25
+ <BackEventProvider backEvent={backEventState}>
26
+ <Router
27
+ context={context}
28
+ initialProps={initialProps}
29
+ container={Container}
30
+ canGoBack={!backEventState.hasBackEvent}
31
+ onBack={backEventState.onBack}
32
+ prefix={baseScheme}
33
+ {...router}
34
+ />
35
+ </BackEventProvider>
36
+ </SafeAreaProvider>
37
+ </App>
38
+ );
39
+ }
@@ -1,10 +1,10 @@
1
- import { SafeAreaProvider } from '@granite-js/native/react-native-safe-area-context';
2
1
  import { ComponentType, PropsWithChildren } from 'react';
3
- import { App } from './App';
4
- import { registerPage } from './registerPage';
2
+ import { AppRegistry } from 'react-native';
3
+ import { ENTRY_BUNDLE_NAME } from '../constants';
5
4
  import type { InitialProps } from '../initial-props';
6
- import { Router, type RouterProps, type RequireContext } from '../router';
7
- import { BackEventProvider, useBackEventState } from '../use-back-event';
5
+ import type { RouterProps, RequireContext } from '../router';
6
+ import { AppRoot } from './AppRoot';
7
+ import { HostAppRoot } from './HostAppRoot';
8
8
 
9
9
  export interface GraniteProps {
10
10
  /**
@@ -26,47 +26,26 @@ export interface GraniteProps {
26
26
  router?: RouterProps;
27
27
  }
28
28
 
29
- /**
30
- * @internal
31
- */
32
- interface AppRootProps extends GraniteProps {
33
- container: ComponentType<PropsWithChildren<InitialProps>>;
34
- initialProps: InitialProps;
35
- }
36
-
37
- const scheme = global.__granite.app.scheme;
38
-
39
- function AppRoot({ appName, context, container, initialProps, router }: AppRootProps) {
40
- const backEventState = useBackEventState();
41
- const baseScheme = `${scheme}://${appName}`;
42
-
43
- return (
44
- <App {...initialProps}>
45
- <SafeAreaProvider>
46
- <BackEventProvider backEvent={backEventState}>
47
- <Router
48
- context={context}
49
- initialProps={initialProps}
50
- container={container}
51
- canGoBack={!backEventState.hasBackEvent}
52
- onBack={backEventState.onBack}
53
- prefix={baseScheme}
54
- {...router}
55
- />
56
- </BackEventProvider>
57
- </SafeAreaProvider>
58
- </App>
59
- );
60
- }
61
-
62
29
  const createApp = () => {
63
30
  let _appName: string | null = null;
64
31
 
32
+ function registerComponent(appKey: string, component: React.ComponentType<any>): string {
33
+ if (AppRegistry.getAppKeys().includes(appKey)) {
34
+ throw new Error(`App with key '${appKey}' already registered`);
35
+ }
36
+
37
+ return AppRegistry.registerComponent(appKey, () => component);
38
+ }
39
+
65
40
  return {
66
41
  registerApp(
67
42
  AppContainer: ComponentType<PropsWithChildren<InitialProps>>,
68
43
  { appName, context, router }: GraniteProps
69
44
  ): (initialProps: InitialProps) => JSX.Element {
45
+ if (appName === ENTRY_BUNDLE_NAME) {
46
+ throw new Error(`Reserved app name 'shared' cannot be used`);
47
+ }
48
+
70
49
  function Root(initialProps: InitialProps) {
71
50
  return (
72
51
  <AppRoot
@@ -79,14 +58,33 @@ const createApp = () => {
79
58
  );
80
59
  }
81
60
 
82
- registerPage(Root);
61
+ registerComponent(appName, Root);
62
+ _appName = appName;
63
+
64
+ return Root;
65
+ },
66
+
67
+ registerHostApp(
68
+ AppContainer: ComponentType<PropsWithChildren<InitialProps>>,
69
+ { appName }: Pick<GraniteProps, 'appName'>
70
+ ): (initialProps: InitialProps) => JSX.Element {
71
+ if (appName !== ENTRY_BUNDLE_NAME) {
72
+ throw new Error(`Host appName must be 'shared'`);
73
+ }
74
+
75
+ function Root(initialProps: InitialProps) {
76
+ return <HostAppRoot container={AppContainer} initialProps={initialProps} />;
77
+ }
78
+
79
+ registerComponent(appName, Root);
83
80
  _appName = appName;
81
+
84
82
  return Root;
85
83
  },
86
84
 
87
85
  get appName(): string {
88
86
  if (_appName === null) {
89
- throw new Error('Granite.appName can only be used after registerApp has been called.');
87
+ throw new Error('Granite.appName can only be used after registerApp or registerHostApp has been called.');
90
88
  }
91
89
  return _appName;
92
90
  },
@@ -0,0 +1,19 @@
1
+ import type { ComponentType, PropsWithChildren } from 'react';
2
+ import type { InitialProps } from '../initial-props';
3
+ import { App } from './App';
4
+
5
+ /**
6
+ * @internal
7
+ */
8
+ interface HostAppRootProps {
9
+ container: ComponentType<PropsWithChildren<InitialProps>>;
10
+ initialProps: InitialProps;
11
+ }
12
+
13
+ export function HostAppRoot({ container: Container, initialProps }: HostAppRootProps) {
14
+ return (
15
+ <App {...initialProps}>
16
+ <Container {...initialProps} />
17
+ </App>
18
+ );
19
+ }
@@ -7,7 +7,6 @@ const ReactNativeBlurModule = (() => {
7
7
  }
8
8
 
9
9
  try {
10
- // eslint-disable-next-line @typescript-eslint/no-var-requires
11
10
  return require('@granite-js/native/@react-native-community/blur') as {
12
11
  BlurView: typeof BlurView;
13
12
  VibrancyView: typeof VibrancyView;
@@ -0,0 +1 @@
1
+ export const ENTRY_BUNDLE_NAME = 'shared';
@@ -1,21 +1,17 @@
1
- 'use strict';
2
-
3
1
  import type { ComponentType } from 'react';
4
2
  import { AppRegistry } from 'react-native';
3
+ import { ENTRY_BUNDLE_NAME } from '../constants';
5
4
  import { setup } from '../rn-polyfills';
6
5
 
7
6
  setup();
8
7
 
9
- let registered = false;
10
-
11
8
  export function register(Component: ComponentType<any>) {
12
- if (registered) {
13
- throw new Error(' 이상의 Page를 register할 수 없습니다. entrypoint에서 1회에 한해 호출해주세요.');
9
+ if (AppRegistry.getAppKeys().includes(ENTRY_BUNDLE_NAME)) {
10
+ console.warn('Granite entrypoint is already registered');
11
+ return;
14
12
  }
15
- registered = true;
16
13
 
17
14
  const component = (props: any) => <Component {...props} />;
18
15
 
19
- AppRegistry.registerComponent('Page', () => component);
20
- AppRegistry.registerComponent('shared', () => component);
16
+ AppRegistry.registerComponent(ENTRY_BUNDLE_NAME, () => component);
21
17
  }
@@ -48,22 +48,6 @@ export function getRouteScreens(context: RequireContext): RouteScreen[] {
48
48
  * @description Maps paths of screens.
49
49
  *
50
50
  * @param {RouteScreen[]} routeScreens - List of screens that can be navigated to
51
- *
52
- * @example
53
- * ```tsx
54
- * import { registerPage, getRouteScreens, getScreenPathMapConfig, Router } from '@granite-js/react-native';
55
- * import { context } from '../require.context';
56
- *
57
- * function App() {
58
- * return <Router context={context} prefix={'scheme://minibench'} />;
59
- * }
60
- *
61
- * export default registerPage(
62
- * App,
63
- * 'minibench',
64
- * getScreenPathMapConfig(getRouteScreens(context))
65
- * );
66
- * ```
67
51
  */
68
52
  export function getScreenPathMapConfig(routeScreens: RouteScreen[]) {
69
53
  const screensConfig: ScreenPath = {};
@@ -3,23 +3,13 @@
3
3
  import type { ComponentType } from 'react';
4
4
 
5
5
  export interface GraniteGlobal {
6
- shared: {
7
- buildNumber: string;
8
- };
9
6
  app: {
10
7
  name: string;
11
8
  scheme: string;
12
- buildNumber: string;
13
9
  };
14
10
  }
15
11
 
16
12
  declare global {
17
- // @internal
18
- var __SPLIT_CHUNK_ENABLED__: boolean;
19
-
20
- // @internal
21
- var __granite_require__: (id: string) => any;
22
-
23
13
  // @internal
24
14
  var __granite: GraniteGlobal;
25
15
 
@@ -1,20 +0,0 @@
1
- import type { ComponentType } from 'react';
2
- /**
3
- * @kind function
4
- * @name registerPage
5
- * @description
6
- * Function to register a page component.
7
- *
8
- * @param {ComponentType<any>} Page - The page component to register
9
- * @returns {ComponentType<any>} Returns the registered page component
10
- *
11
- * @example
12
- * ```typescript
13
- * import { registerPage } from './path/to/module';
14
- *
15
- * const MyPage: React.FC = () => <div>My Page</div>;
16
- *
17
- * registerPage(MyPage);
18
- * ```
19
- */
20
- export declare function registerPage(Page: ComponentType<any>): ComponentType<any>;
@@ -1,29 +0,0 @@
1
- import type { ComponentType } from 'react';
2
-
3
- const globalThis = new Function('return this')();
4
-
5
- /**
6
- * @kind function
7
- * @name registerPage
8
- * @description
9
- * Function to register a page component.
10
- *
11
- * @param {ComponentType<any>} Page - The page component to register
12
- * @returns {ComponentType<any>} Returns the registered page component
13
- *
14
- * @example
15
- * ```typescript
16
- * import { registerPage } from './path/to/module';
17
- *
18
- * const MyPage: React.FC = () => <div>My Page</div>;
19
- *
20
- * registerPage(MyPage);
21
- * ```
22
- */
23
- export function registerPage(Page: ComponentType<any>): ComponentType<any> {
24
- if (globalThis.__SPLIT_CHUNK_ENABLED__) {
25
- globalThis.Page = Page;
26
- }
27
-
28
- return Page;
29
- }