@xstate/react 2.0.0-pr2674-202191175724 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,56 +1,74 @@
1
1
  "use strict";
2
- var __read = (this && this.__read) || function (o, n) {
3
- var m = typeof Symbol === "function" && o[Symbol.iterator];
4
- if (!m) return o;
5
- var i = m.call(o), r, ar = [], e;
6
- try {
7
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
- }
9
- catch (error) { e = { error: error }; }
10
- finally {
11
- try {
12
- if (r && !r.done && (m = i["return"])) m.call(i);
13
- }
14
- finally { if (e) throw e.error; }
15
- }
16
- return ar;
17
- };
18
2
  Object.defineProperty(exports, "__esModule", { value: true });
19
3
  exports.useSelector = void 0;
20
4
  var react_1 = require("react");
5
+ var use_subscription_1 = require("use-subscription");
6
+ var use_isomorphic_layout_effect_1 = require("use-isomorphic-layout-effect");
21
7
  var useActor_1 = require("./useActor");
22
- var useService_1 = require("./useService");
8
+ var utils_1 = require("./utils");
23
9
  function isService(actor) {
24
10
  return 'state' in actor && 'machine' in actor;
25
11
  }
26
12
  var defaultCompare = function (a, b) { return a === b; };
27
13
  var defaultGetSnapshot = function (a) {
28
14
  return isService(a)
29
- ? useService_1.getServiceSnapshot(a)
30
- : useActor_1.isActorWithState(a)
15
+ ? (0, utils_1.getServiceSnapshot)(a)
16
+ : (0, useActor_1.isActorWithState)(a)
31
17
  ? a.state
32
18
  : undefined;
33
19
  };
34
20
  function useSelector(actor, selector, compare, getSnapshot) {
35
21
  if (compare === void 0) { compare = defaultCompare; }
36
22
  if (getSnapshot === void 0) { getSnapshot = defaultGetSnapshot; }
37
- var _a = __read(react_1.useState(function () { return selector(getSnapshot(actor)); }), 2), selected = _a[0], setSelected = _a[1];
38
- var selectedRef = react_1.useRef(selected);
39
- react_1.useEffect(function () {
40
- var updateSelectedIfChanged = function (nextSelected) {
41
- if (!compare(selectedRef.current, nextSelected)) {
42
- setSelected(nextSelected);
43
- selectedRef.current = nextSelected;
23
+ var latestSelectorRef = (0, react_1.useRef)(selector);
24
+ var subscription = (0, react_1.useMemo)(function () {
25
+ var snapshot = getSnapshot(actor);
26
+ var current = selector(snapshot);
27
+ var notifySubscriber;
28
+ return {
29
+ getSnapshot: function () { return snapshot; },
30
+ getCurrentValue: function () { return current; },
31
+ setCurrentValue: function (newCurrent) {
32
+ current = newCurrent;
33
+ notifySubscriber === null || notifySubscriber === void 0 ? void 0 : notifySubscriber();
34
+ },
35
+ subscribe: function (callback) {
36
+ notifySubscriber = callback;
37
+ var sub = actor.subscribe(function (emitted) {
38
+ snapshot = emitted;
39
+ var next = latestSelectorRef.current(emitted);
40
+ if (!compare(current, next)) {
41
+ current = next;
42
+ callback();
43
+ }
44
+ });
45
+ return function () {
46
+ sub.unsubscribe();
47
+ };
44
48
  }
45
49
  };
46
- var initialSelected = selector(getSnapshot(actor));
47
- updateSelectedIfChanged(initialSelected);
48
- var sub = actor.subscribe(function (emitted) {
49
- var nextSelected = selector(emitted);
50
- updateSelectedIfChanged(nextSelected);
51
- });
52
- return function () { return sub.unsubscribe(); };
53
- }, [selector, compare]);
54
- return selected;
50
+ // intentionally omit `getSnapshot` and `compare`
51
+ // - `getSnapshot`: it is only supposed to read the "initial" snapshot of an actor
52
+ // - `compare`: is really supposed to be idempotent and the same throughout the lifetime of this hook (the same assumption is made in React Redux v7)
53
+ }, [actor]);
54
+ var currentSelected = (0, use_subscription_1.useSubscription)(subscription);
55
+ var currentChanged = false;
56
+ if (latestSelectorRef.current !== selector) {
57
+ var selected = selector(subscription.getSnapshot());
58
+ if (!compare(currentSelected, selected)) {
59
+ currentChanged = true;
60
+ currentSelected = selected;
61
+ }
62
+ }
63
+ (0, use_isomorphic_layout_effect_1.default)(function () {
64
+ latestSelectorRef.current = selector;
65
+ // this condition should not be required, but setState bailouts are currently buggy: https://github.com/facebook/react/issues/22654
66
+ if (currentChanged) {
67
+ // required so we don't cause a rerender by setting state (this could create infinite rerendering loop with inline selectors)
68
+ // at the same time we need to update the value within the subscription so new emits can compare against what has been returned to the user as current value
69
+ subscription.setCurrentValue(currentSelected);
70
+ }
71
+ });
72
+ return currentSelected;
55
73
  }
56
74
  exports.useSelector = useSelector;
package/lib/useSpawn.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useSpawn = void 0;
4
- var behaviors_1 = require("xstate/lib/behaviors");
4
+ var xstate_1 = require("xstate");
5
5
  var useConstant_1 = require("./useConstant");
6
6
  /**
7
7
  * React hook that spawns an `ActorRef` with the specified `behavior`.
@@ -11,8 +11,8 @@ var useConstant_1 = require("./useConstant");
11
11
  * @returns An ActorRef with the specified `behavior`
12
12
  */
13
13
  function useSpawn(behavior) {
14
- var actorRef = useConstant_1.default(function () {
15
- return behaviors_1.spawnBehavior(behavior);
14
+ var actorRef = (0, useConstant_1.default)(function () {
15
+ return (0, xstate_1.spawnBehavior)(behavior);
16
16
  });
17
17
  return actorRef;
18
18
  }
package/lib/utils.d.ts CHANGED
@@ -1,2 +1,4 @@
1
+ import { Interpreter } from 'xstate';
1
2
  export declare function partition<T, A extends T, B extends T>(items: T[], predicate: (item: T) => item is A): [A[], B[]];
3
+ export declare function getServiceSnapshot<TService extends Interpreter<any, any, any, any>>(service: TService): TService['state'];
2
4
  //# sourceMappingURL=utils.d.ts.map
package/lib/utils.js CHANGED
@@ -27,7 +27,7 @@ var __values = (this && this.__values) || function(o) {
27
27
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
28
28
  };
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.partition = void 0;
30
+ exports.getServiceSnapshot = exports.partition = void 0;
31
31
  function partition(items, predicate) {
32
32
  var e_1, _a;
33
33
  var _b = __read([[], []], 2), truthy = _b[0], falsy = _b[1];
@@ -52,3 +52,7 @@ function partition(items, predicate) {
52
52
  return [truthy, falsy];
53
53
  }
54
54
  exports.partition = partition;
55
+ function getServiceSnapshot(service) {
56
+ return service.status !== 0 ? service.state : service.machine.initialState;
57
+ }
58
+ exports.getServiceSnapshot = getServiceSnapshot;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xstate/react",
3
- "version": "2.0.0-pr2674-202191175724",
3
+ "version": "2.0.1",
4
4
  "description": "XState tools for React",
5
5
  "keywords": [
6
6
  "state",
@@ -13,7 +13,7 @@
13
13
  "hook"
14
14
  ],
15
15
  "author": "David Khourshid <davidkpiano@gmail.com>",
16
- "homepage": "https://github.com/davidkpiano/xstate/tree/main/packages/xstate-react#readme",
16
+ "homepage": "https://github.com/statelyai/xstate/tree/main/packages/xstate-react#readme",
17
17
  "license": "MIT",
18
18
  "main": "lib/index.js",
19
19
  "module": "es/index.js",
@@ -40,21 +40,21 @@
40
40
  ],
41
41
  "repository": {
42
42
  "type": "git",
43
- "url": "git+ssh://git@github.com/davidkpiano/xstate.git"
43
+ "url": "git+ssh://git@github.com/statelyai/xstate.git"
44
44
  },
45
45
  "scripts": {
46
46
  "clean": "rm -rf dist lib tsconfig.tsbuildinfo",
47
47
  "build": "tsc && tsc --outDir es --module es2015 && rollup -c",
48
48
  "test": "jest",
49
- "prepublish": "npm run build && npm run test"
49
+ "prepare": "npm run build"
50
50
  },
51
51
  "bugs": {
52
- "url": "https://github.com/davidkpiano/xstate/issues"
52
+ "url": "https://github.com/statelyai/xstate/issues"
53
53
  },
54
54
  "peerDependencies": {
55
- "@xstate/fsm": "^1.0.0",
55
+ "@xstate/fsm": "^1.6.5",
56
56
  "react": "^16.8.0 || ^17.0.0",
57
- "xstate": "^4.26.0-pr2674-202191175724"
57
+ "xstate": "^4.30.3"
58
58
  },
59
59
  "peerDependenciesMeta": {
60
60
  "@xstate/fsm": {
@@ -87,7 +87,7 @@
87
87
  "rollup-plugin-terser": "^5.1.2",
88
88
  "rollup-plugin-typescript2": "^0.30.0",
89
89
  "ts-jest": "^26.5.6",
90
- "typescript": "^4.3.5",
90
+ "typescript": "^4.5.2",
91
91
  "xstate": "*"
92
92
  }
93
93
  }
@@ -1,16 +0,0 @@
1
- "use strict";
2
- // this file might look strange and you might be wondering what it's for
3
- // it's lets you import your source files by importing this entrypoint
4
- // as you would import it if it was built with preconstruct build
5
- // this file is slightly different to some others though
6
- // it has a require hook which compiles your code with Babel
7
- // this means that you don't have to set up @babel/register or anything like that
8
- // but you can still require this module and it'll be compiled
9
-
10
- // this bit of code imports the require hook and registers it
11
- let unregister = require("../../../node_modules/@preconstruct/hook").___internalHook(typeof __dirname === 'undefined' ? undefined : __dirname, "../../..", "..");
12
-
13
- // this re-exports the source file
14
- module.exports = require("../src/index.ts");
15
-
16
- unregister();
@@ -1,16 +0,0 @@
1
- import { EventObject, Interpreter, PayloadSender, State, TypegenConstraint, TypegenDisabled, Typestate } from 'xstate';
2
- export declare function getServiceSnapshot<TService extends Interpreter<any, any, any, any>>(service: TService): TService['state'];
3
- /**
4
- * @deprecated Use `useActor` instead.
5
- *
6
- * @param service The interpreted machine
7
- * @returns A tuple of the current `state` of the service and the service's `send(event)` method
8
- */
9
- export declare function useService<TContext, TEvent extends EventObject, TTypestate extends Typestate<TContext> = {
10
- value: any;
11
- context: TContext;
12
- }, TTypesMeta extends TypegenConstraint = TypegenDisabled>(service: Interpreter<TContext, any, TEvent, TTypestate, TTypesMeta>): [
13
- State<TContext, TEvent, any, TTypestate, TTypesMeta>,
14
- PayloadSender<TEvent>
15
- ];
16
- //# sourceMappingURL=useService.d.ts.map
package/es/useService.js DELETED
@@ -1,36 +0,0 @@
1
- var __read = (this && this.__read) || function (o, n) {
2
- var m = typeof Symbol === "function" && o[Symbol.iterator];
3
- if (!m) return o;
4
- var i = m.call(o), r, ar = [], e;
5
- try {
6
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
7
- }
8
- catch (error) { e = { error: error }; }
9
- finally {
10
- try {
11
- if (r && !r.done && (m = i["return"])) m.call(i);
12
- }
13
- finally { if (e) throw e.error; }
14
- }
15
- return ar;
16
- };
17
- import { useActor } from './useActor';
18
- export function getServiceSnapshot(service) {
19
- // TODO: remove compat lines in a new major, replace literal number with InterpreterStatus then as well
20
- return ('status' in service ? service.status : service._status) !== 0
21
- ? service.state
22
- : service.machine.initialState;
23
- }
24
- /**
25
- * @deprecated Use `useActor` instead.
26
- *
27
- * @param service The interpreted machine
28
- * @returns A tuple of the current `state` of the service and the service's `send(event)` method
29
- */
30
- export function useService(service) {
31
- if (process.env.NODE_ENV !== 'production' && !('machine' in service)) {
32
- throw new Error("Attempted to use an actor-like object instead of a service in the useService() hook. Please use the useActor() hook instead.");
33
- }
34
- var _a = __read(useActor(service), 1), state = _a[0];
35
- return [state, service.send];
36
- }
@@ -1,16 +0,0 @@
1
- import { EventObject, Interpreter, PayloadSender, State, TypegenConstraint, TypegenDisabled, Typestate } from 'xstate';
2
- export declare function getServiceSnapshot<TService extends Interpreter<any, any, any, any>>(service: TService): TService['state'];
3
- /**
4
- * @deprecated Use `useActor` instead.
5
- *
6
- * @param service The interpreted machine
7
- * @returns A tuple of the current `state` of the service and the service's `send(event)` method
8
- */
9
- export declare function useService<TContext, TEvent extends EventObject, TTypestate extends Typestate<TContext> = {
10
- value: any;
11
- context: TContext;
12
- }, TTypesMeta extends TypegenConstraint = TypegenDisabled>(service: Interpreter<TContext, any, TEvent, TTypestate, TTypesMeta>): [
13
- State<TContext, TEvent, any, TTypestate, TTypesMeta>,
14
- PayloadSender<TEvent>
15
- ];
16
- //# sourceMappingURL=useService.d.ts.map
package/lib/useService.js DELETED
@@ -1,41 +0,0 @@
1
- "use strict";
2
- var __read = (this && this.__read) || function (o, n) {
3
- var m = typeof Symbol === "function" && o[Symbol.iterator];
4
- if (!m) return o;
5
- var i = m.call(o), r, ar = [], e;
6
- try {
7
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
- }
9
- catch (error) { e = { error: error }; }
10
- finally {
11
- try {
12
- if (r && !r.done && (m = i["return"])) m.call(i);
13
- }
14
- finally { if (e) throw e.error; }
15
- }
16
- return ar;
17
- };
18
- Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.useService = exports.getServiceSnapshot = void 0;
20
- var useActor_1 = require("./useActor");
21
- function getServiceSnapshot(service) {
22
- // TODO: remove compat lines in a new major, replace literal number with InterpreterStatus then as well
23
- return ('status' in service ? service.status : service._status) !== 0
24
- ? service.state
25
- : service.machine.initialState;
26
- }
27
- exports.getServiceSnapshot = getServiceSnapshot;
28
- /**
29
- * @deprecated Use `useActor` instead.
30
- *
31
- * @param service The interpreted machine
32
- * @returns A tuple of the current `state` of the service and the service's `send(event)` method
33
- */
34
- function useService(service) {
35
- if (process.env.NODE_ENV !== 'production' && !('machine' in service)) {
36
- throw new Error("Attempted to use an actor-like object instead of a service in the useService() hook. Please use the useActor() hook instead.");
37
- }
38
- var _a = __read(useActor_1.useActor(service), 1), state = _a[0];
39
- return [state, service.send];
40
- }
41
- exports.useService = useService;