added dynamically loading of xstates machines from composite definitions
This commit is contained in:
		| @@ -1,22 +1,30 @@ | |||||||
| <script> | <script> | ||||||
| 	import { interpret } from 'xstate'; | 	import { interpret, Machine } from 'xstate'; | ||||||
| 	import { toggleMachine } from './machines/toggleMachine'; |  | ||||||
|  |  | ||||||
| 	export let store; | 	export let store; | ||||||
|  | 	let service; | ||||||
|  | 	let current; | ||||||
|  | 	export let machine; | ||||||
|  |  | ||||||
| 	$: console.log('ready child:  ' + JSON.stringify($store)); | 	let compositeMachine; | ||||||
|  |  | ||||||
| 	let current = toggleMachine.initialState.value; | 	$: if (machine) { | ||||||
| 	const service = interpret(toggleMachine).onTransition((state) => { | 		compositeMachine = Machine(machine); | ||||||
|  |  | ||||||
|  | 		current = compositeMachine.initialState.value; // remove let | ||||||
|  | 		service = interpret(compositeMachine).onTransition((state) => { | ||||||
| 			current = state.value; | 			current = state.value; | ||||||
| 			$store.xstate = state.value; | 			$store.xstate = state.value; | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		service.start(); | 		service.start(); | ||||||
|  | 	} | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <div class="border-2 border-yellow-500"> | <div class="border-2 border-yellow-500"> | ||||||
|  | 	{#if machine} | ||||||
| 		i am the child and this is my state: {current} | 		i am the child and this is my state: {current} | ||||||
|  | 	{/if} | ||||||
| 	<button | 	<button | ||||||
| 		class="px-4 py-2 font-bold text-white bg-blue-500 rounded hover:bg-blue-700" | 		class="px-4 py-2 font-bold text-white bg-blue-500 rounded hover:bg-blue-700" | ||||||
| 		on:click={() => service.send('TOGGLE')}>Switch</button | 		on:click={() => service.send('TOGGLE')}>Switch</button | ||||||
|   | |||||||
| @@ -1,15 +0,0 @@ | |||||||
| childState: function subscribe2(run, invalidate = noop) { |  | ||||||
|     const subscriber = [run, invalidate]; |  | ||||||
|     subscribers.add(subscriber); |  | ||||||
|     if (subscribers.size === 1) { |  | ||||||
|       stop = start(set, update) || noop; |  | ||||||
|     } |  | ||||||
|     run(value); |  | ||||||
|     return () => { |  | ||||||
|       subscribers.delete(subscriber); |  | ||||||
|       if (subscribers.size === 0 && stop) { |  | ||||||
|         stop(); |  | ||||||
|         stop = null; |  | ||||||
|       } |  | ||||||
|     }; |  | ||||||
|   } |  | ||||||
| @@ -1,14 +0,0 @@ | |||||||
| import { Machine } from 'xstate'; |  | ||||||
|  |  | ||||||
| export const toggleMachine = Machine({ |  | ||||||
|     id: 'toggle', |  | ||||||
|     initial: 'NOTREADY', |  | ||||||
|     states: { |  | ||||||
|         NOTREADY: { |  | ||||||
|             on: { TOGGLE: 'READY' } |  | ||||||
|         }, |  | ||||||
|         READY: { |  | ||||||
|             on: { TOGGLE: 'NOTREADY' } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
| @@ -3,7 +3,7 @@ | |||||||
| 	import { interpret } from 'xstate'; | 	import { interpret } from 'xstate'; | ||||||
| 	import Composite from '$lib/core/Composite.svelte'; | 	import Composite from '$lib/core/Composite.svelte'; | ||||||
|  |  | ||||||
| 	export let machine; | 	// export let machine; | ||||||
|  |  | ||||||
| 	let composite = { | 	let composite = { | ||||||
| 		id: 'testingstuff', | 		id: 'testingstuff', | ||||||
| @@ -16,10 +16,22 @@ | |||||||
| 		children: [ | 		children: [ | ||||||
| 			{ | 			{ | ||||||
| 				id: 'child', | 				id: 'child', | ||||||
| 				// component: 'LearnReady', | 				component: 'LearnReady', | ||||||
| 				slot: 'left', | 				slot: 'left', | ||||||
| 				store: { | 				store: { | ||||||
| 					xstate: 'NOTREADY' | 					xstate: 'NOTREADY' | ||||||
|  | 				}, | ||||||
|  | 				machine: { | ||||||
|  | 					id: 'compositemachine', | ||||||
|  | 					initial: 'NOTREADY', | ||||||
|  | 					states: { | ||||||
|  | 						NOTREADY: { | ||||||
|  | 							on: { TOGGLE: 'READY' } | ||||||
|  | 						}, | ||||||
|  | 						READY: { | ||||||
|  | 							on: { TOGGLE: 'NOTREADY' } | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 			}, | 			}, | ||||||
| 			{ | 			{ | ||||||
| @@ -30,23 +42,26 @@ | |||||||
| 		] | 		] | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	let current = machine.initialState.value; | 	// let current = machine.initialState.value; | ||||||
|  |  | ||||||
| 	const service = interpret(machine) | 	// const service = interpret(machine) | ||||||
| 		.onTransition((state) => { | 	// 	.onTransition((state) => { | ||||||
| 			current = state.value; | 	// 		current = state.value; | ||||||
| 		}) | 	// 	}) | ||||||
| 		.start(); | 	// 	.start(); | ||||||
|  |  | ||||||
| 	// Derive possible actions from the current state | 	// Derive possible actions from the current state | ||||||
| 	$: possibleActions = machine.states[current]?.meta.buttons || []; | 	// $: possibleActions = machine.states[current]?.meta.buttons || []; | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <main class="grid w-full h-full grid-rows-layout"> |  | ||||||
| 	<div class="w-full h-full p-4 overflow-scroll"> |  | ||||||
| <div class="h-1/4"> | <div class="h-1/4"> | ||||||
| 	<Composite {composite} /> | 	<Composite {composite} /> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | <!--  | ||||||
|  | <main class="grid w-full h-full grid-rows-layout"> | ||||||
|  | 	<div class="w-full h-full p-4 overflow-scroll"> | ||||||
|  | 	 | ||||||
| 		<p>Current state: {current}</p> | 		<p>Current state: {current}</p> | ||||||
| 		<h1>{machine.states[current].meta.title}</h1> | 		<h1>{machine.states[current].meta.title}</h1> | ||||||
| 		{#if machine.states[current].meta.composite} | 		{#if machine.states[current].meta.composite} | ||||||
| @@ -70,4 +85,4 @@ | |||||||
| 	.grid-rows-layout { | 	.grid-rows-layout { | ||||||
| 		grid-template-rows: 1fr auto; | 		grid-template-rows: 1fr auto; | ||||||
| 	} | 	} | ||||||
| </style> | </style> --> | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| 	import { dataStore } from '$lib/core/dataLoader'; | 	import { dataStore } from '$lib/core/dataLoader'; | ||||||
| 	import { createCompositeStore, getCompositeStore } from '$lib/core/compositeStores'; | 	import { createCompositeStore, getCompositeStore } from '$lib/core/compositeStores'; | ||||||
| 	import { coreServices } from './coreServices'; | 	import { coreServices } from './coreServices'; | ||||||
|  | 	import { Machine } from 'xstate'; | ||||||
|  |  | ||||||
| 	interface ICompositeLayout { | 	interface ICompositeLayout { | ||||||
| 		areas: string; | 		areas: string; | ||||||
| @@ -26,6 +27,7 @@ | |||||||
| 		store?: Record<string, any>; | 		store?: Record<string, any>; | ||||||
| 		children?: IComposite[]; | 		children?: IComposite[]; | ||||||
| 		servicesLoaded?: boolean; | 		servicesLoaded?: boolean; | ||||||
|  | 		machine?: any; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	export let composite: IComposite; | 	export let composite: IComposite; | ||||||
| @@ -185,6 +187,7 @@ | |||||||
| 				this={Component} | 				this={Component} | ||||||
| 				id={composite.id} | 				id={composite.id} | ||||||
| 				store={getCompositeStore(composite.id)} | 				store={getCompositeStore(composite.id)} | ||||||
|  | 				machine={composite.machine} | ||||||
| 				services={loadedServices} | 				services={loadedServices} | ||||||
| 			/> | 			/> | ||||||
| 		{/await} | 		{/await} | ||||||
| @@ -201,6 +204,7 @@ | |||||||
| 							this={ChildComponent} | 							this={ChildComponent} | ||||||
| 							id={child.id} | 							id={child.id} | ||||||
| 							store={getCompositeStore(child.id)} | 							store={getCompositeStore(child.id)} | ||||||
|  | 							machine={child.machine} | ||||||
| 							services={loadedServices} | 							services={loadedServices} | ||||||
| 						/> | 						/> | ||||||
| 						{#if child.children && child.children.length} | 						{#if child.children && child.children.length} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user