add/lys xstate scaffolding (#45548)
* dev: added xstate 5 * add xstate scaffolding for launch your store
This commit is contained in:
parent
5a54dd6527
commit
dbd577cbd6
|
@ -0,0 +1,9 @@
|
||||||
|
const fs = require( 'fs-extra' );
|
||||||
|
const path = require( 'path' );
|
||||||
|
|
||||||
|
const rootNodeModules = path.join( __dirname, '..', 'node_modules' );
|
||||||
|
|
||||||
|
fs.ensureSymlinkSync(
|
||||||
|
path.join( rootNodeModules, 'xstate5' ),
|
||||||
|
path.join( rootNodeModules, '@xstate5', 'react', 'node_modules', 'xstate' )
|
||||||
|
);
|
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { useMachine } from '@xstate5/react';
|
||||||
|
import React from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { useFullScreen } from '~/utils';
|
||||||
|
import { useComponentFromXStateService } from '~/utils/xstate/useComponentFromService';
|
||||||
|
|
||||||
|
import './styles.scss';
|
||||||
|
import {
|
||||||
|
SidebarMachineEvents,
|
||||||
|
sidebarMachine,
|
||||||
|
SidebarComponentProps,
|
||||||
|
SidebarContainer,
|
||||||
|
} from './sidebar/xstate';
|
||||||
|
import {
|
||||||
|
MainContentMachineEvents,
|
||||||
|
mainContentMachine,
|
||||||
|
MainContentComponentProps,
|
||||||
|
MainContentContainer,
|
||||||
|
} from './main-content/xstate';
|
||||||
|
|
||||||
|
export type LaunchYourStoreComponentProps = {
|
||||||
|
sendEventToSidebar: ( arg0: SidebarMachineEvents ) => void;
|
||||||
|
sendEventToMainContent: ( arg0: MainContentMachineEvents ) => void;
|
||||||
|
className?: string;
|
||||||
|
};
|
||||||
|
const LaunchStoreController = () => {
|
||||||
|
useFullScreen( [ 'woocommerce-launch-your-store' ] );
|
||||||
|
|
||||||
|
const [ mainContentState, sendToMainContent, mainContentMachineService ] =
|
||||||
|
useMachine( mainContentMachine );
|
||||||
|
|
||||||
|
const [ sidebarState, sendToSidebar, sidebarMachineService ] = useMachine(
|
||||||
|
sidebarMachine,
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
mainContentMachineRef: mainContentMachineService,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const isSidebarVisible = ! sidebarState.hasTag( 'fullscreen' );
|
||||||
|
|
||||||
|
const [ CurrentSidebarComponent ] =
|
||||||
|
useComponentFromXStateService< SidebarComponentProps >(
|
||||||
|
sidebarMachineService
|
||||||
|
);
|
||||||
|
|
||||||
|
const [ CurrentMainContentComponent ] =
|
||||||
|
useComponentFromXStateService< MainContentComponentProps >(
|
||||||
|
mainContentMachineService
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ 'launch-your-store-layout__container' }>
|
||||||
|
<SidebarContainer
|
||||||
|
className={ classnames( {
|
||||||
|
'is-sidebar-hidden': ! isSidebarVisible,
|
||||||
|
} ) }
|
||||||
|
>
|
||||||
|
{ CurrentSidebarComponent && (
|
||||||
|
<CurrentSidebarComponent
|
||||||
|
sendEventToSidebar={ sendToSidebar }
|
||||||
|
sendEventToMainContent={ sendToMainContent }
|
||||||
|
context={ sidebarState.context }
|
||||||
|
/>
|
||||||
|
) }
|
||||||
|
{ JSON.stringify( sidebarState.toJSON() ) }
|
||||||
|
{ JSON.stringify( sidebarState.getMeta() ) }
|
||||||
|
</SidebarContainer>
|
||||||
|
<MainContentContainer>
|
||||||
|
{ CurrentMainContentComponent && (
|
||||||
|
<CurrentMainContentComponent
|
||||||
|
sendEventToSidebar={ sendToSidebar }
|
||||||
|
sendEventToMainContent={ sendToMainContent }
|
||||||
|
context={ mainContentState.context }
|
||||||
|
/>
|
||||||
|
) }
|
||||||
|
{ JSON.stringify( mainContentState.getMeta() ) }
|
||||||
|
{ JSON.stringify( mainContentState.toJSON() ) }
|
||||||
|
</MainContentContainer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default LaunchStoreController;
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import type { MainContentComponentProps } from '../xstate';
|
||||||
|
export const LaunchYourStoreSuccess = ( props: MainContentComponentProps ) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={ classnames(
|
||||||
|
'launch-store-success-page__container',
|
||||||
|
props.className
|
||||||
|
) }
|
||||||
|
>
|
||||||
|
<p>Main Content - Site Launch Store Success Page</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import classnames from 'classnames';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import type { MainContentComponentProps } from '../xstate';
|
||||||
|
export const LoadingPage = ( props: MainContentComponentProps ) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={ classnames(
|
||||||
|
'launch-store-loading-page__container',
|
||||||
|
props.className
|
||||||
|
) }
|
||||||
|
>
|
||||||
|
<p>Main Content - Loading page</p>
|
||||||
|
<button
|
||||||
|
onClick={ () => {
|
||||||
|
props.sendEventToSidebar( {
|
||||||
|
type: 'LAUNCH_STORE_SUCCESS',
|
||||||
|
} );
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
Launch Store Success
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import classnames from 'classnames';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import type { MainContentComponentProps } from '../xstate';
|
||||||
|
|
||||||
|
export const SitePreviewPage = ( props: MainContentComponentProps ) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={ classnames(
|
||||||
|
'launch-store-site-preview-page__container',
|
||||||
|
props.className
|
||||||
|
) }
|
||||||
|
>
|
||||||
|
<p>Main Content - Site Preview</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { setup } from 'xstate5';
|
||||||
|
import React from 'react';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { LoadingPage } from './pages/loading';
|
||||||
|
import { LaunchYourStoreSuccess } from './pages/launch-store-success';
|
||||||
|
import { SitePreviewPage } from './pages/site-preview';
|
||||||
|
import type { LaunchYourStoreComponentProps } from '..';
|
||||||
|
|
||||||
|
export type MainContentMachineContext = {
|
||||||
|
placeholder?: string; // remove this when we have some types to put here
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MainContentComponentProps = LaunchYourStoreComponentProps & {
|
||||||
|
context: MainContentMachineContext;
|
||||||
|
};
|
||||||
|
export type MainContentMachineEvents =
|
||||||
|
| { type: 'SHOW_LAUNCH_STORE_SUCCESS' }
|
||||||
|
| { type: 'SHOW_LOADING' };
|
||||||
|
|
||||||
|
export const mainContentMachine = setup( {
|
||||||
|
types: {} as {
|
||||||
|
context: MainContentMachineContext;
|
||||||
|
events: MainContentMachineEvents;
|
||||||
|
},
|
||||||
|
} ).createMachine( {
|
||||||
|
id: 'mainContent',
|
||||||
|
initial: 'init',
|
||||||
|
context: {},
|
||||||
|
states: {
|
||||||
|
init: {
|
||||||
|
always: [
|
||||||
|
{
|
||||||
|
target: '#sitePreview',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
sitePreview: {
|
||||||
|
id: 'sitePreview',
|
||||||
|
meta: {
|
||||||
|
component: SitePreviewPage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
launchStoreSuccess: {
|
||||||
|
id: 'launchStoreSuccess',
|
||||||
|
meta: {
|
||||||
|
component: LaunchYourStoreSuccess,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
id: 'loading',
|
||||||
|
meta: {
|
||||||
|
component: LoadingPage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
SHOW_LAUNCH_STORE_SUCCESS: {
|
||||||
|
target: '#launchStoreSuccess',
|
||||||
|
},
|
||||||
|
SHOW_LOADING: {
|
||||||
|
target: '#loading',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
export const MainContentContainer = ( {
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
} ) => {
|
||||||
|
return (
|
||||||
|
<div className="launch-your-store-layout__content">{ children }</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import classnames from 'classnames';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import type { SidebarComponentProps } from '../xstate';
|
||||||
|
export const LaunchYourStoreHubSidebar: React.FC< SidebarComponentProps > = (
|
||||||
|
props
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={ classnames(
|
||||||
|
'launch-store-sidebar__container',
|
||||||
|
props.className
|
||||||
|
) }
|
||||||
|
>
|
||||||
|
<p>Sidebar</p>
|
||||||
|
<button
|
||||||
|
onClick={ () => {
|
||||||
|
props.sendEventToSidebar( { type: 'LAUNCH_STORE' } );
|
||||||
|
// when we send LAUNCH_STORE to the sidebar machine, the sidebar machine sends the appropriate event to the main content machine to show the launching state
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
Launch Store
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={ () => {
|
||||||
|
props.sendEventToSidebar( {
|
||||||
|
type: 'OPEN_EXTERNAL_URL',
|
||||||
|
url: 'https://example.com',
|
||||||
|
} );
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
Open external URL
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,135 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { ActorRefFrom, sendTo, setup } from 'xstate5';
|
||||||
|
import React from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { LaunchYourStoreHubSidebar } from './components/launch-store-hub';
|
||||||
|
import type { LaunchYourStoreComponentProps } from '..';
|
||||||
|
import type { mainContentMachine } from '../main-content/xstate';
|
||||||
|
|
||||||
|
export type SidebarMachineContext = {
|
||||||
|
externalUrl: string | null;
|
||||||
|
mainContentMachineRef: ActorRefFrom< typeof mainContentMachine >;
|
||||||
|
};
|
||||||
|
export type SidebarComponentProps = LaunchYourStoreComponentProps & {
|
||||||
|
context: SidebarMachineContext;
|
||||||
|
};
|
||||||
|
export type SidebarMachineEvents =
|
||||||
|
| { type: 'OPEN_EXTERNAL_URL'; url: string }
|
||||||
|
| { type: 'OPEN_WC_ADMIN_URL'; url: string }
|
||||||
|
| { type: 'OPEN_WC_ADMIN_URL_IN_CONTENT_AREA'; url: string }
|
||||||
|
| { type: 'LAUNCH_STORE' }
|
||||||
|
| { type: 'LAUNCH_STORE_SUCCESS' };
|
||||||
|
export const sidebarMachine = setup( {
|
||||||
|
types: {} as {
|
||||||
|
context: SidebarMachineContext;
|
||||||
|
events: SidebarMachineEvents;
|
||||||
|
input: {
|
||||||
|
mainContentMachineRef: ActorRefFrom< typeof mainContentMachine >;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
openExternalUrl: ( { event } ) => {
|
||||||
|
if ( event.type === 'OPEN_EXTERNAL_URL' ) {
|
||||||
|
window.open( event.url, '_self' );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showLaunchStoreSuccessPage: sendTo(
|
||||||
|
( { context } ) => context.mainContentMachineRef,
|
||||||
|
{ type: 'SHOW_LAUNCH_STORE_SUCCESS' }
|
||||||
|
),
|
||||||
|
showLoadingPage: sendTo(
|
||||||
|
( { context } ) => context.mainContentMachineRef,
|
||||||
|
{ type: 'SHOW_LOADING' }
|
||||||
|
),
|
||||||
|
},
|
||||||
|
} ).createMachine( {
|
||||||
|
id: 'sidebar',
|
||||||
|
initial: 'init',
|
||||||
|
context: ( { input } ) => ( {
|
||||||
|
externalUrl: null,
|
||||||
|
mainContentMachineRef: input.mainContentMachineRef,
|
||||||
|
} ),
|
||||||
|
states: {
|
||||||
|
init: {
|
||||||
|
always: {
|
||||||
|
target: 'launchYourStoreHub',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
launchYourStoreHub: {
|
||||||
|
initial: 'preLaunchYourStoreHub',
|
||||||
|
states: {
|
||||||
|
preLaunchYourStoreHub: {
|
||||||
|
always: 'launchYourStoreHub',
|
||||||
|
// do async stuff here such as retrieving task statuses
|
||||||
|
},
|
||||||
|
launchYourStoreHub: {
|
||||||
|
tags: 'sidebar-visible',
|
||||||
|
meta: {
|
||||||
|
component: LaunchYourStoreHubSidebar,
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
LAUNCH_STORE: {
|
||||||
|
target: '#storeLaunching',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
storeLaunching: {
|
||||||
|
id: 'storeLaunching',
|
||||||
|
initial: 'launching',
|
||||||
|
states: {
|
||||||
|
launching: {
|
||||||
|
tags: 'fullscreen',
|
||||||
|
entry: { type: 'showLoadingPage' },
|
||||||
|
on: {
|
||||||
|
LAUNCH_STORE_SUCCESS: {
|
||||||
|
target: '#storeLaunchSuccessful',
|
||||||
|
actions: { type: 'showLaunchStoreSuccessPage' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
storeLaunchSuccessful: {
|
||||||
|
id: 'storeLaunchSuccessful',
|
||||||
|
tags: 'fullscreen',
|
||||||
|
},
|
||||||
|
openExternalUrl: {
|
||||||
|
id: 'openExternalUrl',
|
||||||
|
tags: 'sidebar-visible', // unintuitive but it prevents a layout shift just before leaving
|
||||||
|
entry: [ 'openExternalUrl' ],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
OPEN_EXTERNAL_URL: {
|
||||||
|
target: '#openExternalUrl',
|
||||||
|
},
|
||||||
|
OPEN_WC_ADMIN_URL: {},
|
||||||
|
OPEN_WC_ADMIN_URL_IN_CONTENT_AREA: {},
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
export const SidebarContainer = ( {
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
} ) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={ classnames(
|
||||||
|
'launch-your-store-layout__sidebar',
|
||||||
|
className
|
||||||
|
) }
|
||||||
|
>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
.woocommerce-layout__main .launch-your-store-layout__container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.launch-your-store-layout__sidebar {
|
||||||
|
width: 380px;
|
||||||
|
|
||||||
|
&.is-sidebar-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.launch-your-store-layout__content {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -86,6 +86,10 @@ const CustomizeStore = lazy( () =>
|
||||||
import( /* webpackChunkName: "customize-store" */ '../customize-store' )
|
import( /* webpackChunkName: "customize-store" */ '../customize-store' )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const LaunchStore = lazy( () =>
|
||||||
|
import( /* webpackChunkName: "launch-store" */ '../launch-store' )
|
||||||
|
);
|
||||||
|
|
||||||
export const PAGES_FILTER = 'woocommerce_admin_pages_list';
|
export const PAGES_FILTER = 'woocommerce_admin_pages_list';
|
||||||
|
|
||||||
export const getPages = () => {
|
export const getPages = () => {
|
||||||
|
@ -343,6 +347,25 @@ export const getPages = () => {
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( window.wcAdminFeatures[ 'launch-your-store' ] ) {
|
||||||
|
pages.push( {
|
||||||
|
container: LaunchStore,
|
||||||
|
path: '/launch-your-store/*',
|
||||||
|
breadcrumbs: [
|
||||||
|
...initialBreadcrumbs,
|
||||||
|
__( 'Launch Your Store', 'woocommerce' ),
|
||||||
|
],
|
||||||
|
layout: {
|
||||||
|
header: false,
|
||||||
|
footer: true,
|
||||||
|
showNotices: true,
|
||||||
|
showStoreAlerts: false,
|
||||||
|
showPluginArea: false,
|
||||||
|
},
|
||||||
|
capability: 'manage_woocommerce',
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
if ( window.wcAdminFeatures.settings ) {
|
if ( window.wcAdminFeatures.settings ) {
|
||||||
pages.push( {
|
pages.push( {
|
||||||
container: SettingsGroup,
|
container: SettingsGroup,
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { useSelector as xstateUseSelector } from '@xstate5/react';
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { findComponentMeta } from '~/utils/xstate/find-component';
|
||||||
|
|
||||||
|
type ComponentMetaType< ComponentPropsType > = {
|
||||||
|
component: ( arg0: ComponentPropsType ) => React.ReactElement;
|
||||||
|
};
|
||||||
|
export function useComponentFromXStateService< ComponentProps >(
|
||||||
|
service: Parameters< typeof xstateUseSelector >[ 0 ]
|
||||||
|
): [ ComponentMetaType< ComponentProps >[ 'component' ] | null ] {
|
||||||
|
const componentMeta = xstateUseSelector( service, ( state ) =>
|
||||||
|
findComponentMeta< ComponentMetaType< ComponentProps > >(
|
||||||
|
state.getMeta() ?? undefined
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const [ Component, setComponent ] = useState<
|
||||||
|
ComponentMetaType< ComponentProps >[ 'component' ] | null
|
||||||
|
>( null );
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
if ( componentMeta?.component ) {
|
||||||
|
setComponent( () => componentMeta.component );
|
||||||
|
}
|
||||||
|
}, [ componentMeta?.component ] );
|
||||||
|
|
||||||
|
return [ Component ? Component : null ];
|
||||||
|
}
|
|
@ -29,7 +29,8 @@
|
||||||
"watch:build": "pnpm --if-present --workspace-concurrency=Infinity --filter=\"$npm_package_name...\" --parallel '/^watch:build:project:.*$/'",
|
"watch:build": "pnpm --if-present --workspace-concurrency=Infinity --filter=\"$npm_package_name...\" --parallel '/^watch:build:project:.*$/'",
|
||||||
"watch:build:project": "pnpm --if-present run '/^watch:build:project:.*$/'",
|
"watch:build:project": "pnpm --if-present run '/^watch:build:project:.*$/'",
|
||||||
"watch:build:project:bundle": "wireit",
|
"watch:build:project:bundle": "wireit",
|
||||||
"watch:build:project:feature-config": "WC_ADMIN_PHASE=development php ../woocommerce/bin/generate-feature-config.php"
|
"watch:build:project:feature-config": "WC_ADMIN_PHASE=development php ../woocommerce/bin/generate-feature-config.php",
|
||||||
|
"postinstall": "node ./bin/xstate5-react-script.js"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.scss": [
|
"*.scss": [
|
||||||
|
@ -77,6 +78,7 @@
|
||||||
"@wordpress/viewport": "wp-6.0",
|
"@wordpress/viewport": "wp-6.0",
|
||||||
"@wordpress/warning": "wp-6.0",
|
"@wordpress/warning": "wp-6.0",
|
||||||
"@xstate/react": "3.2.1",
|
"@xstate/react": "3.2.1",
|
||||||
|
"@xstate5/react": "npm:@xstate/react@4",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
"core-js": "^3.34.0",
|
"core-js": "^3.34.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
|
@ -96,6 +98,7 @@
|
||||||
"react-visibility-sensor": "^5.1.1",
|
"react-visibility-sensor": "^5.1.1",
|
||||||
"redux": "^4.2.1",
|
"redux": "^4.2.1",
|
||||||
"xstate": "4.37.1",
|
"xstate": "4.37.1",
|
||||||
|
"xstate5": "npm:xstate@^5.9.1",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -193,6 +196,7 @@
|
||||||
"eslint-plugin-xstate": "^1.1.3",
|
"eslint-plugin-xstate": "^1.1.3",
|
||||||
"expose-loader": "^3.1.0",
|
"expose-loader": "^3.1.0",
|
||||||
"fork-ts-checker-webpack-plugin": "^8.0.0",
|
"fork-ts-checker-webpack-plugin": "^8.0.0",
|
||||||
|
"fs-extra": "11.1.1",
|
||||||
"jest": "~27.5.1",
|
"jest": "~27.5.1",
|
||||||
"jest-environment-jsdom": "~27.5.1",
|
"jest-environment-jsdom": "~27.5.1",
|
||||||
"jest-environment-node": "~27.5.1",
|
"jest-environment-node": "~27.5.1",
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add xstate scaffold for Launch your store feature
|
785
pnpm-lock.yaml
785
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue