@xstate/react
Advanced tools
Comparing version 1.0.0-rc.6 to 1.0.0-rc.7
@@ -5,9 +5,28 @@ # Changelog | ||
## [1.0.0-rc.7] | ||
- The `machine` passed into `useMachine(machine)` can now be passed in lazily: | ||
```js | ||
const [state, send] = useMachine(() => createMachine(/* ... */)); | ||
// ... | ||
``` | ||
This has the benefit of avoiding unnecessary machine initializations whenever the component rerenders. | ||
- The `useActor` hook now takes a second argument: `getSnapshot` which is a function that should return the last emitted value: | ||
```js | ||
const [state, send] = useActor(someActor, (actor) => actor.current); | ||
``` | ||
## [1.0.0-rc.6] | ||
## [1.0.0-rc.5] | ||
- You can now schedule actions in `useEffect` or `useLayoutEffect` via: | ||
- `asEffect` - queues the action to be executed in `useEffect` | ||
- `asLayoutEffect` - queues the action to be executed in `useLayoutEffect` | ||
- `asEffect` - queues the action to be executed in `useEffect` | ||
- `asLayoutEffect` - queues the action to be executed in `useLayoutEffect` | ||
```jsx | ||
@@ -14,0 +33,0 @@ import { createMachine } from 'xstate'; |
import { StateMachine, EventObject, Typestate } from '@xstate/fsm'; | ||
export declare function useMachine<TContext extends object, TEvent extends EventObject = EventObject, TState extends Typestate<TContext> = any>(stateMachine: StateMachine.Machine<TContext, TEvent, TState>, options?: { | ||
export declare function useMachine<TContext extends object, TEvent extends EventObject = EventObject, TState extends Typestate<TContext> = { | ||
value: any; | ||
context: TContext; | ||
}>(stateMachine: StateMachine.Machine<TContext, TEvent, TState>, options?: { | ||
actions?: StateMachine.ActionMap<TContext, TEvent>; | ||
}): [StateMachine.State<TContext, TEvent, TState>, StateMachine.Service<TContext, TEvent>['send'], StateMachine.Service<TContext, TEvent>]; | ||
export declare function useService<TContext extends object, TEvent extends EventObject = EventObject, TState extends Typestate<TContext> = any>(service: StateMachine.Service<TContext, TEvent, TState>): [StateMachine.State<TContext, TEvent, TState>, StateMachine.Service<TContext, TEvent, TState>['send'], StateMachine.Service<TContext, TEvent, TState>]; | ||
}): [ | ||
StateMachine.State<TContext, TEvent, TState>, | ||
StateMachine.Service<TContext, TEvent>['send'], | ||
StateMachine.Service<TContext, TEvent> | ||
]; | ||
export declare function useService<TContext extends object, TEvent extends EventObject = EventObject, TState extends Typestate<TContext> = { | ||
value: any; | ||
context: TContext; | ||
}>(service: StateMachine.Service<TContext, TEvent, TState>): [ | ||
StateMachine.State<TContext, TEvent, TState>, | ||
StateMachine.Service<TContext, TEvent, TState>['send'], | ||
StateMachine.Service<TContext, TEvent, TState> | ||
]; | ||
//# sourceMappingURL=fsm.d.ts.map |
@@ -19,2 +19,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useService = exports.useMachine = void 0; | ||
var react_1 = require("react"); | ||
@@ -21,0 +22,0 @@ var fsm_1 = require("@xstate/fsm"); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useActor = exports.useService = exports.asLayoutEffect = exports.asEffect = exports.useMachine = void 0; | ||
var useMachine_1 = require("./useMachine"); | ||
exports.useMachine = useMachine_1.useMachine; | ||
exports.asEffect = useMachine_1.asEffect; | ||
exports.asLayoutEffect = useMachine_1.asLayoutEffect; | ||
Object.defineProperty(exports, "useMachine", { enumerable: true, get: function () { return useMachine_1.useMachine; } }); | ||
Object.defineProperty(exports, "asEffect", { enumerable: true, get: function () { return useMachine_1.asEffect; } }); | ||
Object.defineProperty(exports, "asLayoutEffect", { enumerable: true, get: function () { return useMachine_1.asLayoutEffect; } }); | ||
var useService_1 = require("./useService"); | ||
exports.useService = useService_1.useService; | ||
Object.defineProperty(exports, "useService", { enumerable: true, get: function () { return useService_1.useService; } }); | ||
var useActor_1 = require("./useActor"); | ||
exports.useActor = useActor_1.useActor; | ||
Object.defineProperty(exports, "useActor", { enumerable: true, get: function () { return useActor_1.useActor; } }); |
@@ -25,8 +25,7 @@ import { EventObject } from 'xstate'; | ||
export interface ActorRefLike<TEvent extends EventObject, TEmitted = any> extends Subscribable<TEmitted> { | ||
name?: string; | ||
id?: string; | ||
send: Sender<TEvent>; | ||
stop?: () => void; | ||
state?: TEmitted; | ||
[key: string]: any; | ||
} | ||
export declare type MaybeLazy<T> = T | (() => T); | ||
//# sourceMappingURL=types.d.ts.map |
import { Sender, ActorRefLike } from './types'; | ||
import { EventObject, Actor } from 'xstate'; | ||
export declare function useActor<TEvent extends EventObject, TEmitted = any>(actorLike: ActorRefLike<TEvent, TEmitted> | Actor): [TEmitted, Sender<TEvent>]; | ||
export declare function useActor<TEvent extends EventObject, TEmitted = any>(actorRef: ActorRefLike<TEvent, TEmitted> | Actor, getSnapshot?: (actor: typeof actorRef) => TEmitted): [TEmitted, Sender<TEvent>]; | ||
//# sourceMappingURL=useActor.d.ts.map |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
@@ -30,20 +19,11 @@ var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useActor = void 0; | ||
var react_1 = require("react"); | ||
var xstate_1 = require("xstate"); | ||
var useService_1 = require("./useService"); | ||
function resolveActor(actorLike) { | ||
if (actorLike instanceof xstate_1.Interpreter) { | ||
return useService_1.fromService(actorLike); | ||
} | ||
if (!('current' in actorLike)) { | ||
return __assign(__assign({ stop: function () { | ||
/* do nothing */ | ||
} }, actorLike), { subscribe: actorLike.subscribe, name: actorLike.id, current: actorLike.state }); | ||
} | ||
return actorLike; | ||
} | ||
function useActor(actorLike) { | ||
var actor = react_1.useMemo(function () { return resolveActor(actorLike); }, [actorLike]); | ||
function useActor(actorRef, getSnapshot) { | ||
if (getSnapshot === void 0) { getSnapshot = function (a) { | ||
return 'state' in a ? a.state : undefined; | ||
}; } | ||
// const actor = useMemo(() => resolveActor(actorLike), [actorLike]); | ||
var deferredEventsRef = react_1.useRef([]); | ||
var _a = __read(react_1.useState(actor.current), 2), current = _a[0], setCurrent = _a[1]; | ||
var _a = __read(react_1.useState(function () { return getSnapshot(actorRef); }), 2), current = _a[0], setCurrent = _a[1]; | ||
var send = react_1.useCallback(function (event) { | ||
@@ -53,15 +33,16 @@ // If the previous actor is a deferred actor, | ||
// on the non-deferred actor. | ||
if (actor.deferred) { | ||
if ('deferred' in actorRef && actorRef.deferred) { | ||
deferredEventsRef.current.push(event); | ||
} | ||
else { | ||
actor.send(event); | ||
actorRef.send(event); | ||
} | ||
}, [actor]); | ||
}, [actorRef]); | ||
react_1.useEffect(function () { | ||
var subscription = actor.subscribe(setCurrent); | ||
// Dequeue deferred events from the previous deferred actor | ||
setCurrent(getSnapshot(actorRef)); | ||
var subscription = actorRef.subscribe(setCurrent); | ||
// Dequeue deferred events from the previous deferred actorRef | ||
while (deferredEventsRef.current.length > 0) { | ||
var deferredEvent = deferredEventsRef.current.shift(); | ||
actor.send(deferredEvent); | ||
actorRef.send(deferredEvent); | ||
} | ||
@@ -71,5 +52,5 @@ return function () { | ||
}; | ||
}, [actor]); | ||
}, [actorRef]); | ||
return [current, send]; | ||
} | ||
exports.useActor = useActor; |
import { EventObject, StateMachine, State, Interpreter, InterpreterOptions, MachineOptions, StateConfig, Typestate, ActionObject, ActionFunction, ActionMeta } from 'xstate'; | ||
import { MaybeLazy } from './types'; | ||
declare enum ReactEffectType { | ||
@@ -15,3 +16,6 @@ Effect = 1, | ||
export declare function asLayoutEffect<TContext, TEvent extends EventObject>(exec: ActionFunction<TContext, TEvent>): ReactActionFunction<TContext, TEvent>; | ||
export declare type ActionStateTuple<TContext, TEvent extends EventObject> = [ReactActionObject<TContext, TEvent>, State<TContext, TEvent>]; | ||
export declare type ActionStateTuple<TContext, TEvent extends EventObject> = [ | ||
ReactActionObject<TContext, TEvent>, | ||
State<TContext, TEvent> | ||
]; | ||
interface UseMachineOptions<TContext, TEvent extends EventObject> { | ||
@@ -28,4 +32,11 @@ /** | ||
} | ||
export declare function useMachine<TContext, TEvent extends EventObject, TTypestate extends Typestate<TContext> = any>(machine: StateMachine<TContext, any, TEvent, TTypestate>, options?: Partial<InterpreterOptions> & Partial<UseMachineOptions<TContext, TEvent>> & Partial<MachineOptions<TContext, TEvent>>): [State<TContext, TEvent, any, TTypestate>, Interpreter<TContext, any, TEvent, TTypestate>['send'], Interpreter<TContext, any, TEvent, TTypestate>]; | ||
export declare function useMachine<TContext, TEvent extends EventObject, TTypestate extends Typestate<TContext> = { | ||
value: any; | ||
context: TContext; | ||
}>(getMachine: MaybeLazy<StateMachine<TContext, any, TEvent, TTypestate>>, options?: Partial<InterpreterOptions> & Partial<UseMachineOptions<TContext, TEvent>> & Partial<MachineOptions<TContext, TEvent>>): [ | ||
State<TContext, TEvent, any, TTypestate>, | ||
Interpreter<TContext, any, TEvent, TTypestate>['send'], | ||
Interpreter<TContext, any, TEvent, TTypestate> | ||
]; | ||
export {}; | ||
//# sourceMappingURL=useMachine.d.ts.map |
@@ -45,2 +45,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useMachine = exports.asLayoutEffect = exports.asEffect = void 0; | ||
var react_1 = require("react"); | ||
@@ -90,5 +91,9 @@ var use_isomorphic_layout_effect_1 = require("use-isomorphic-layout-effect"); | ||
} | ||
function useMachine(machine, options) { | ||
function useMachine(getMachine, options) { | ||
if (options === void 0) { options = {}; } | ||
if (process.env.NODE_ENV !== 'production') { | ||
var machine = useConstant_1.default(function () { | ||
return typeof getMachine === 'function' ? getMachine() : getMachine; | ||
}); | ||
if (process.env.NODE_ENV !== 'production' && | ||
typeof getMachine !== 'function') { | ||
var _a = __read(react_1.useState(machine), 1), initialMachine = _a[0]; | ||
@@ -117,5 +122,6 @@ if (machine !== initialMachine) { | ||
var _c = __read(react_1.useState(function () { | ||
return rehydratedState | ||
? xstate_1.State.create(rehydratedState) | ||
: resolvedMachine.initialState; | ||
// Always read the initial state to properly initialize the machine | ||
// https://github.com/davidkpiano/xstate/issues/1334 | ||
var initialState = resolvedMachine.initialState; | ||
return rehydratedState ? xstate_1.State.create(rehydratedState) : initialState; | ||
}), 2), state = _c[0], setState = _c[1]; | ||
@@ -122,0 +128,0 @@ var effectActionsRef = react_1.useRef([]); |
import { EventObject, State, Interpreter, Typestate, Sender } from 'xstate'; | ||
import { ActorRef } from './types'; | ||
export declare function fromService<TContext, TEvent extends EventObject>(service: Interpreter<TContext, any, TEvent, any>): ActorRef<TEvent, State<TContext, TEvent>>; | ||
export declare function useService<TContext, TEvent extends EventObject, TTypestate extends Typestate<TContext> = any>(service: Interpreter<TContext, any, TEvent, TTypestate>): [State<TContext, TEvent, any, TTypestate>, Sender<TEvent>]; | ||
export declare function fromService<TContext, TEvent extends EventObject>(service: Interpreter<TContext, any, TEvent>): ActorRef<TEvent, State<TContext, TEvent>>; | ||
export declare function useService<TContext, TEvent extends EventObject, TTypestate extends Typestate<TContext> = { | ||
value: any; | ||
context: TContext; | ||
}>(service: Interpreter<TContext, any, TEvent, TTypestate>): [State<TContext, TEvent, any, TTypestate>, Sender<TEvent>]; | ||
//# sourceMappingURL=useService.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.useService = exports.fromService = void 0; | ||
var react_1 = require("react"); | ||
@@ -18,4 +19,4 @@ var useActor_1 = require("./useActor"); | ||
var serviceActor = react_1.useMemo(function () { return fromService(service); }, [service]); | ||
return useActor_1.useActor(serviceActor); | ||
return useActor_1.useActor(serviceActor, function (actor) { return actor.current; }); | ||
} | ||
exports.useService = useService; |
@@ -30,2 +30,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.partition = void 0; | ||
function partition(items, predicate) { | ||
@@ -32,0 +33,0 @@ var e_1, _a; |
{ | ||
"name": "@xstate/react", | ||
"version": "1.0.0-rc.6", | ||
"version": "1.0.0-rc.7", | ||
"description": "XState tools for React", | ||
@@ -19,2 +19,3 @@ "keywords": [ | ||
"main": "lib/index.js", | ||
"module": "es/index.js", | ||
"types": "lib/index.d.ts", | ||
@@ -28,3 +29,5 @@ "sideEffects": false, | ||
"lib/**/*.js", | ||
"lib/**/*.d.ts" | ||
"lib/**/*.d.ts", | ||
"es/**/*.js", | ||
"es/**/*.d.ts" | ||
], | ||
@@ -37,3 +40,3 @@ "repository": { | ||
"clean": "rm -rf dist lib tsconfig.tsbuildinfo", | ||
"build": "tsc", | ||
"build": "tsc && tsc --outDir es --module es2015", | ||
"test": "jest", | ||
@@ -68,3 +71,3 @@ "prepublish": "npm run build && npm run test" | ||
"@xstate/fsm": "*", | ||
"jest": "^24.8.0", | ||
"jest": "^26.4.2", | ||
"jsdom": "^14.0.0", | ||
@@ -75,6 +78,6 @@ "jsdom-global": "^3.0.2", | ||
"react-dom": "^16.12.0", | ||
"ts-jest": "^24.1.9", | ||
"typescript": "^3.8.3", | ||
"ts-jest": "^26.4.0", | ||
"typescript": "^4.0.3", | ||
"xstate": "*" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
56876
35
1000
4