New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[@xstate/lit] Add Lit Controller #4775
base: main
Are you sure you want to change the base?
Conversation
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this package should try to use this experimental option: preconstruct/preconstruct#586
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, I added 'type:module' and that fixed the error in "yarn typecheck".
https://github.com/preconstruct/preconstruct/pull/586/checks#discussion_r1452789690
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it still should use that experimental option - otherwise, I'd expect us to run into problems with preconstruct dev/validate/build
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
transformIgnorePatterns: [ | ||
'node_modules/(?!(@open-wc|lit-html|lit-element|lit|@lit)/)' | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this? does it turn off ESM->CJS transform?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is necessary to use Jest with Lit.
You can see more information here.
Hi, @davidkpiano, @Andarist The folder xstat-lit corresponds to what is in the folder packages/xstate-lit |
1. state renamed to snapshot; 2. transition event should in an object.
* Support for parameterized `enqueueActions` * add missing context
* Add basic event emitter * Remove id and delay * Fix types * Rename * Add machine types * Add TEmitted type... everywhere * Avoid upsetting devs who rely on order of ActorLogic<…> generics * Same for ActorScope<…> * Update packages/core/src/actions/emit.ts Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/core/src/actions/emit.ts Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/core/src/State.ts Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/core/src/actions/emit.ts Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/core/src/actions/emit.ts Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/core/src/actions/emit.ts Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/core/test/types.test.ts Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/core/src/createMachine.ts Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/core/src/actions/emit.ts Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Fix TS error * Add emit to enqueueActions * Add default * Wrap handler * Check for errors * Add changeset * Types * small tweaks * fix types * tweak things * fix small issues around listeners management * rename stuff * tighten up one default * remove unused type * fixed `MachineImplementationsActions` * No need for defer * Add test * rewrite test to make it fail correctly * defer again * Add jsdocs * Update packages/core/src/actions/emit.ts --------- Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
export const useActorRef = <TMachine extends AnyActorLogic>( | ||
logic: TMachine, | ||
options?: ActorOptions<TMachine> | ||
): Actor<TMachine> => { | ||
const actorRef = createActor(logic, options); | ||
return actorRef; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's just a wrapper around createActor
- do you even need it here? couldn't u just call createActor
directly in ur UseMachine
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Completely agree, I did it like this following the 'format' of the other packages, but it's much better to use 'createActor' directly.
Done.
packages/xstate-lit/test/UseActor.ts
Outdated
fetchController: UseMachine<typeof fetchMachine> = {} as UseMachine< | ||
typeof fetchMachine | ||
>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't it be possible to call new UseMachine(...)
here? declaring a property like this would be much easier for consumers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, updated.
Hi @Andarist This way, I can add the dependency to the Here are the steps I would take:
Does this approach sound reasonable? |
I'd keep this PR open but remove templates from it. Then you can have a branch with templates on it, and point us to it so we can see how it's used in practice (although tests in this PR here might/should be enough too). Once we land this PR that introduces Also, please note that I'm aware of this PR and I plan to review it thoroughly (so far I didn't really do a proper review - just a driveby one). It might take some time before I properly get to it because at the moment I'm focusing on something else. We really appreciate your contribution! |
Perfect, I'll leave it as it is for now to not drive you crazy, and if it eventually makes sense and gets approved, I'll make the necessary changes. Thank you for taking the time to review the PR. |
Hi @Andarist, just checking in to see if there's been any progress on reviewing the PR or if you need me to make any changes. Thanks! |
For those interested, this is an alternate lit-controller: https://github.com/lit-apps/lit-app/tree/dev/packages/actor It leverages https://github.com/lit-apps/lit-app/tree/dev/packages/state and wraps xstate actors so that lit element re-renders when the snapshot changes. example usage: const actor = new Actor(workflow)
export default class fsmTest extends LitElement {
// bind actor state to fsmTest element, so it will re-render when actor snapshot changes
bindActor = new StateController(this, actor)
override render() {
const send = () => actor.send({
type: 'NewPatientEvent', name: 'John', condition: 'healthy'
})
return html`
<div>
<div>status: ${actor.status}</div>
<div>any context value: ${actor.context.anyValue}</div>
<div>value: ${JSON.stringify(actor.value)}</div>
</div>
<button @click=${send}>NewPatientEvent</button>
`;
}
} |
This pull request adds compatibility for linking XState with Lit.
Motivation
XState's state machines offer a structured and predictable approach to handle complex logic, while Lit facilitates reactive UI updates in response to state changes.
Changes
It follows the established structure of the xstate repository, including:
📂 packages/xstate-lit/src/
Adds xstate-lit to packages with code, tests, and documentation.
▨ UseMachine.ts
Implements the @xstate/lit controller, referencing other packages for guidance as much as possible.
@xstate/svelte, @xstate/vue and Lifecycle: reactive controller adapters for other frameworks
actor
, getsnapshot
, andsend(ev: EventFrom<TMachine>)
method for interacting with the XState actor.unsubscribe
method▨ useActorRef.ts
Creates and returns the XState actor without Lit-specific dependencies (handled in UseMachine.js).
▨ index.ts:
Exports only UseMachine.ts.
📂 packages/xstate-lit/test
Leverages @open-wc/testing-helpers for unit testing components, drawing inspiration from existing tests in Svelte and Vue integrations.
▨ useActor.test.ts
▨ useActorRef.test.ts
📂 templates/lit-ts/
Adds examples and documentation.
Usage:
npm i && npm start
Provides two demos:
<lit-ts>
& feedbackMachine: Equal to existing templates in other packages.<lit-ts-counter>
& counterMachine: Illustrates using a reactive property and the inspect API to listen for events that caused transitions and reset reactive property.Other Modified Files:
▨ jest.config.js
Add transformIgnorePatterns to accommodate Lit and Open-WC.
📂 scripts/jest-utils/
▨ setup.js
Filters out Lit's "Lit is in dev mode..." console logs during tests.