-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Fixed a type compatibility with Svelte's readables #3063
Conversation
🦋 Changeset detectedLatest commit: c4ed71e The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
.github/workflows/ci-checks.yml
Outdated
@@ -0,0 +1,12 @@ | |||
name: 'CI checks' | |||
runs: | |||
using: 'composite' |
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.
I had to add svelte-check to our CI jobs here and I've thought that it would be nice to experiment with those composite actions - we'll see how it goes, it's the first time when I've attempted to use this.
CodeSee Review Map:Review in an interactive map View more CodeSee Maps Legend |
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. Latest deployment of this branch, based on commit c4ed71e:
|
@@ -15,9 +15,7 @@ | |||
"test": "jest", | |||
"test:core": "npm test --prefix packages/core", | |||
"dev": "node ./scripts/dev.js", | |||
"ci": "npm run build && npm run test", |
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.
from what I can tell this wasn't actually used by anything
"changeset": "changeset", | ||
"prerelease": "npm run build && npm run test", |
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.
"pre*" scripts dont work with all package managers, so I've decided to just move this directly to a github action
@@ -4,33 +4,6 @@ import { terser } from 'rollup-plugin-terser'; | |||
import rollupReplace from 'rollup-plugin-replace'; | |||
import fileSize from 'rollup-plugin-filesize'; | |||
|
|||
const stripSymbolObservableMethodPlugin = ({ types: t }) => { |
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 no longer needed since I've figured out how to assign symbolObservable
to a "variable" and maintain the Symbol.observable
type at the same time
4e22e7d
to
d912a8d
Compare
@@ -529,15 +529,18 @@ export function isObservable<T>(value: any): value is Subscribable<T> { | |||
} | |||
} | |||
|
|||
export const symbolObservable = (() => | |||
const symbolObservable = (() => |
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, what happens in this file is weird and I don't have much on my defense... except... this TS playground
@@ -386,3 +387,23 @@ describe('Typestates', () => { | |||
expect(failed).toEqual({ result: none, error: 'oops' }); | |||
}); | |||
}); | |||
|
|||
describe('interpreter', () => { | |||
it('should be convertable to Rx observable', () => { |
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.
an explicit test covering for changes from: https://github.com/statelyai/xstate/pull/2371/files
@@ -0,0 +1,19 @@ | |||
<script lang="ts"> | |||
// this file acts as a type test | |||
import { createMachine, interpret } from 'xstate'; |
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 is a new test for what is being fixed in this PR
export interface InteropSubscribable<T> { | ||
subscribe(observer: Observer<T>): Subscription; | ||
} |
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.
In a way, this breaks the previous contract exposed under Symbol.observable
method. However, this is the only signature that is valid from Rx's PoV. The InteropObservable
returns Subscribable<T>
:
https://github.com/ReactiveX/rxjs/blob/67cb317a7a6b9fdbd3d2e8fdbc2ac9ac7e57179c/api_guard/dist/types/index.d.ts#L321-L323
and Subscribable is defined as follows:
https://github.com/ReactiveX/rxjs/blob/67cb317a7a6b9fdbd3d2e8fdbc2ac9ac7e57179c/api_guard/dist/types/index.d.ts#L690-L692
So, in fact, this interface only accepts observers - it doesn't accept separate listener functions for next
, error
and complete
.
By implementing this change and using this as an explicit return type of the Symol.observable
method on the Interpreter
class we ensure that it's compatible with the Rx's signature for this:
xstate/packages/core/src/interpreter.ts
Lines 1369 to 1373 in d912a8d
public [symbolObservableRef.symbol](): InteropSubscribable< | |
State<TContext, TEvent, TStateSchema, TTypestate, TResolvedTypesMeta> | |
> { | |
return this; | |
} |
Thanks to that we can revert the reordering of the subscribe
's overloads from this PR and fix the issue with Svelte's readables. This is because both libraries are using conditional types to match the input argument and to "extract" the emitted type and conditional types are only seeing the last overload.
So, in a sense, this is a hack and might break any minute... cause the whole thing is fitting both libraries thanks to the alignment of the stars and not because this is built on super solid principles. We trick Rx by only exposing a single overload with the observer as the parameter for its conditional type from the Symbol.observable
method and we trick Svelte by reordering overloads so it only sees the one with callbacks parameters.
const observer = toObserver(next); | ||
listeners.add(observer.next); |
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 is a fix from the perspective of the Symbol.observable
- since that method is accepting observers we convert the received callback (or observer) to an observer
b8b4a79
to
f5485bd
Compare
CI is expected to fail right now. It rightfully reports errors in some svelte files related to I'll look into fixing this problem and I think it's OK to wait with this PR a little bit before I do so. |
f5485bd
to
c4ed71e
Compare
The CI should get unblocked in a sec since I've landed #3065 |
fixes #2533