added stateMachine to stateMachine communication

This commit is contained in:
Samuel Andert 2023-08-02 11:49:05 +02:00
parent 48903fbe7d
commit 7f57036e94
6 changed files with 147 additions and 9 deletions

View File

@ -0,0 +1,52 @@
<script>
import { Machine, interpret } from 'xstate';
export let services;
let childStore;
$: if (services.core) {
childStore = services.core.subscribeComposite('@child');
}
const colorMachine = Machine({
id: 'color',
initial: 'RED',
states: {
GREEN: {
on: { SWITCH: 'YELLOW' }
},
YELLOW: {
on: { SWITCH: 'RED' }
},
RED: {
on: { SWITCH: 'GREEN' }
}
},
on: {
READY: 'GREEN',
NOTREADY: 'RED'
}
});
let current = colorMachine.initialState.value;
const service = interpret(colorMachine)
.onTransition((state) => {
current = state.value;
})
.start();
$: {
if ($childStore && $childStore.xstate) {
service.send($childStore.xstate);
}
}
</script>
<div class="p-2 border-2 border-blue-500">I am the parent, this is my state: {current}</div>
<div
class="p-2 border-2"
style="background-color: {current}; border-radius: 50%; width: 50px; height: 50px;"
/>
<p>The child state: {JSON.stringify($childStore)}</p>

View File

@ -0,0 +1,24 @@
<script>
import { interpret } from 'xstate';
import { toggleMachine } from './machines/toggleMachine';
export let store;
$: console.log('ready child: ' + JSON.stringify($store));
let current = toggleMachine.initialState.value;
const service = interpret(toggleMachine).onTransition((state) => {
current = state.value;
$store.xstate = state.value;
});
service.start();
</script>
<div class="border-2 border-yellow-500">
i am the child and this is my state: {current}
<button
class="px-4 py-2 font-bold text-white bg-blue-500 rounded hover:bg-blue-700"
on:click={() => service.send('TOGGLE')}>Switch</button
>
</div>

View File

@ -0,0 +1,15 @@
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;
}
};
}

View File

@ -0,0 +1,14 @@
import { Machine } from 'xstate';
export const toggleMachine = Machine({
id: 'toggle',
initial: 'NOTREADY',
states: {
NOTREADY: {
on: { TOGGLE: 'READY' }
},
READY: {
on: { TOGGLE: 'NOTREADY' }
}
}
});

View File

@ -5,6 +5,31 @@
export let machine;
let composite = {
id: 'testingstuff',
layout: {
columns: '1fr 1fr',
areas: `
"left right"
`
},
children: [
{
id: 'child',
component: 'LearnReady',
slot: 'left',
store: {
xstate: 'NOTREADY'
}
},
{
id: 'parent',
component: 'LearnColor',
slot: 'right'
}
]
};
let current = machine.initialState.value;
const service = interpret(machine)
@ -19,6 +44,9 @@
<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">
<Composite {composite} />
</div>
<p>Current state: {current}</p>
<h1>{machine.states[current].meta.title}</h1>
{#if machine.states[current].meta.composite}

View File

@ -2,15 +2,20 @@
import { getCompositeStore } from './compositeStores';
export const coreServices = {
updateStore: (mappings: Record<string, string>) => {
for (const [mappingString, value] of Object.entries(mappings)) {
const [storeID, key] = mappingString.replace('@', '').split(':');
const store = getCompositeStore(storeID);
store.update(storeData => {
storeData[key] = value;
return storeData;
});
}
// updateComposite: (mappings: Record<string, string>) => {
// for (const [mappingString, value] of Object.entries(mappings)) {
// const [storeID, key] = mappingString.replace('@', '').split(':');
// const store = getCompositeStore(storeID);
// store.update(storeData => {
// storeData[key] = value;
// return storeData;
// });
// }
// },
subscribeComposite: (mappingString: string) => {
const [storeID] = mappingString.replace('@', '').split(':');
const store = getCompositeStore(storeID);
return store;
},
testAlert: () => {
alert("core service alert")