Skip to content

Commit

Permalink
chore: pin xstate (#36398) (#36415)
Browse files Browse the repository at this point in the history
Co-authored-by: LekoArts <lekoarts@gmail.com>
(cherry picked from commit 6e4a0de)

Co-authored-by: Michal Piechowiak <misiek.piechowiak@gmail.com>
  • Loading branch information
ViCo0TeCH and pieh committed Aug 18, 2022
1 parent b8eac2d commit 29c7ad1
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 20 deletions.
4 changes: 2 additions & 2 deletions packages/gatsby-source-filesystem/package.json
Expand Up @@ -17,7 +17,7 @@
"pretty-bytes": "^5.4.1",
"progress": "^2.0.3",
"valid-url": "^1.0.9",
"xstate": "^4.26.1"
"xstate": "4.32.1"
},
"devDependencies": {
"@babel/cli": "^7.15.4",
Expand Down Expand Up @@ -48,4 +48,4 @@
"engines": {
"node": ">=14.15.0"
}
}
}
2 changes: 1 addition & 1 deletion packages/gatsby/package.json
Expand Up @@ -169,7 +169,7 @@
"webpack-merge": "^5.8.0",
"webpack-stats-plugin": "^1.0.3",
"webpack-virtual-modules": "^0.3.2",
"xstate": "^4.26.0",
"xstate": "4.32.1",
"yaml-loader": "^0.6.0"
},
"devDependencies": {
Expand Down
200 changes: 200 additions & 0 deletions packages/gatsby/src/state-machines/__tests__/query-running.ts
@@ -0,0 +1,200 @@
import { queryRunningMachine } from "../query-running"
import { queryActions } from "../query-running/actions"
import { interpret, Interpreter } from "xstate"
import { IProgram } from "../../commands/types"
import { store } from "../../redux"
import reporter from "gatsby-cli/lib/reporter"
import pDefer from "p-defer"
import { IGroupedQueryIds } from "../../services/types"

const services = {
extractQueries: jest.fn(async () => {}),
writeOutRequires: jest.fn(async () => {}),
calculateDirtyQueries: jest.fn(
async (): Promise<{
queryIds: IGroupedQueryIds
}> => {
return {
queryIds: {
pageQueryIds: [],
staticQueryIds: [],
},
}
}
),
}

const machine = queryRunningMachine.withConfig(
{
actions: queryActions,
services,
},
{
program: {} as IProgram,
store,
reporter,
pendingQueryRuns: new Set([`/`]),
}
)

const resetMocks = (mocks: Record<string, jest.Mock>): void =>
Object.values(mocks).forEach(mock => mock.mockClear())

const resetAllMocks = (): void => {
resetMocks(services)
}

const finished = async (
service: Interpreter<any, any, any, any, any>
): Promise<void> =>
new Promise(resolve => {
service.onDone(() => resolve())
})

function debug(service: Interpreter<any, any, any, any, any>): void {
let last: any

service.onTransition(state => {
if (!last) {
last = state
} else if (!state.changed) {
return
}

reporter.info(
`---onTransition---\n${require(`util`).inspect(
{
stateValue: state.value,
event: state.event,
pendingQueryRuns: state.context.pendingQueryRuns,
changedStateValue: state.value !== last.value,
},
{ depth: Infinity }
)}`
)
last = state
})
}

expect.extend({
toHaveInSet(received, item) {
if (received.has(item)) {
return {
pass: true,
message: (): string =>
`Expected ${Array.from(received)} not to contain ${item}`,
}
} else {
return {
pass: false,
message: (): string =>
`Expected ${Array.from(received)} not to contain ${item}`,
}
}
},
})

/* eslint-disable @typescript-eslint/no-namespace */
declare global {
namespace jest {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface Expect {
toHaveInSet(item: any): any
}
}
}

describe(`query-running state machine`, () => {
beforeEach(() => {
resetAllMocks()
})

it(`initialises`, async () => {
const service = interpret(machine)
// debug(service)

service.start()
expect(service.state.value).toBe(`extractingQueries`)
})

it(`doesn't drop pendingQueryRuns that were added during calculation of dirty queries`, async () => {
const deferred = pDefer<{
queryIds: IGroupedQueryIds
}>()
const waitForExecutionOfCalcDirtyQueries = pDefer()

services.calculateDirtyQueries.mockImplementation(
async (): Promise<{
queryIds: IGroupedQueryIds
}> => {
waitForExecutionOfCalcDirtyQueries.resolve()

// allow test to execute some code before resuming service

await deferred.promise

return {
queryIds: {
pageQueryIds: [],
staticQueryIds: [],
},
}
}
)

const service = interpret(machine)
// debug(service)

service.send({
type: `QUERY_RUN_REQUESTED`,
payload: {
pagePath: `/bar/`,
},
})

service.start()

await waitForExecutionOfCalcDirtyQueries.promise

// we are in middle of execution of calcDirtyQueries service
// let's dispatch QUERY_RUN_REQUESTED for page /foo/
service.send({
type: `QUERY_RUN_REQUESTED`,
payload: {
pagePath: `/foo/`,
},
})

deferred.resolve()

// let state machine reach final state
await finished(service)

// let's make sure that we called calculateDirtyQueries service
// with every page that was requested, even if page was requested
// while we were executing calcDirtyQueries service
expect(services.calculateDirtyQueries).toHaveBeenCalledWith(
expect.objectContaining({
currentlyHandledPendingQueryRuns: expect.toHaveInSet(`/`),
}),
expect.anything(),
expect.anything()
)

expect(services.calculateDirtyQueries).toHaveBeenCalledWith(
expect.objectContaining({
currentlyHandledPendingQueryRuns: expect.toHaveInSet(`/bar/`),
}),
expect.anything(),
expect.anything()
)

expect(services.calculateDirtyQueries).toHaveBeenCalledWith(
expect.objectContaining({
currentlyHandledPendingQueryRuns: expect.toHaveInSet(`/foo/`),
}),
expect.anything(),
expect.anything()
)
})
})
10 changes: 5 additions & 5 deletions packages/gatsby/src/state-machines/data-layer/services.ts
@@ -1,4 +1,4 @@
import { ServiceConfig } from "xstate"
import { MachineOptions } from "xstate"
import {
customizeSchema,
createPages,
Expand All @@ -8,10 +8,10 @@ import {
} from "../../services"
import { IDataLayerContext } from "./types"

export const dataLayerServices: Record<
string,
ServiceConfig<IDataLayerContext>
> = {
export const dataLayerServices: MachineOptions<
IDataLayerContext,
any
>["services"] = {
customizeSchema,
sourceNodes,
createPages,
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby/src/state-machines/develop/services.ts
Expand Up @@ -13,9 +13,9 @@ import {
} from "../data-layer"
import { queryRunningMachine } from "../query-running"
import { waitingMachine } from "../waiting"
import { ServiceConfig } from "xstate"
import { MachineOptions } from "xstate"

export const developServices: Record<string, ServiceConfig<IBuildContext>> = {
export const developServices: MachineOptions<IBuildContext, any>["services"] = {
initializeData: initializeDataMachine,
reloadData: reloadDataMachine,
recreatePages: recreatePagesMachine,
Expand Down
10 changes: 5 additions & 5 deletions packages/gatsby/src/state-machines/query-running/services.ts
@@ -1,4 +1,4 @@
import { ServiceConfig } from "xstate"
import { MachineOptions } from "xstate"
import {
extractQueries,
writeOutRequires,
Expand All @@ -10,10 +10,10 @@ import {
} from "../../services"
import { IQueryRunningContext } from "./types"

export const queryRunningServices: Record<
string,
ServiceConfig<IQueryRunningContext>
> = {
export const queryRunningServices: MachineOptions<
IQueryRunningContext,
any
>["services"] = {
extractQueries,
writeOutRequires,
calculateDirtyQueries,
Expand Down
4 changes: 3 additions & 1 deletion packages/gatsby/src/utils/state-machine-logging.ts
Expand Up @@ -7,12 +7,14 @@ import {
} from "xstate"
import reporter from "gatsby-cli/lib/reporter"

type AnyInterpreterWithContext<T> = Interpreter<T, any, any, any, any>

const isInterpreter = <T>(
actor: Actor<T> | Interpreter<T>
): actor is Interpreter<T> => `machine` in actor

export function logTransitions<T = DefaultContext>(
service: Interpreter<T>
service: AnyInterpreterWithContext<T>
): void {
const listeners = new WeakSet()
let last: State<T, AnyEventObject, any, any>
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Expand Up @@ -26954,10 +26954,10 @@ xss@^1.0.6:
commander "^2.20.3"
cssfilter "0.0.10"

xstate@^4.26.0, xstate@^4.26.1:
version "4.26.1"
resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.26.1.tgz#4fc1afd153f88cf302a9ee2b758f6629e6a829b6"
integrity sha512-JLofAEnN26l/1vbODgsDa+Phqa61PwDlxWu8+2pK+YbXf+y9pQSDLRvcYH2H1kkeUBA5fGp+xFL/zfE8jNMw4g==
xstate@4.32.1:
version "4.32.1"
resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.32.1.tgz#1a09c808a66072938861a3b4acc5b38460244b70"
integrity sha512-QYUd+3GkXZ8i6qdixnOn28bL3EvA++LONYL/EMWwKlFSh/hiLndJ8YTnz77FDs+JUXcwU7NZJg7qoezoRHc4GQ==

xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1:
version "4.0.2"
Expand Down

0 comments on commit 29c7ad1

Please sign in to comment.