Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@xstate/react

Package Overview
Dependencies
Maintainers
3
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@xstate/react - npm Package Compare versions

Comparing version 4.0.0-beta.10 to 4.0.0-beta.11

4

dist/declarations/src/createActorContext.d.ts

@@ -10,2 +10,6 @@ import * as React from 'react';

options?: ActorOptions<TLogic>;
/**
* @deprecated Use `logic` instead.
*/
machine?: never;
} & (TLogic extends AnyStateMachine ? AreAllImplementationsAssumedToBeProvided<TLogic['__TResolvedTypesMeta']> extends true ? {

@@ -12,0 +16,0 @@ logic?: TLogic;

17

dist/declarations/src/useActorRef.d.ts

@@ -1,14 +0,3 @@

import { AnyActorLogic, AnyActor, AnyStateMachine, AreAllImplementationsAssumedToBeProvided, InternalMachineImplementations, ActorRefFrom, ActorOptions, Observer, StateFrom, SnapshotFrom, TODO } from 'xstate';
export declare function useIdleInterpreter(machine: AnyActorLogic, options: Partial<ActorOptions<AnyActorLogic>>): AnyActor;
type RestParams<TLogic extends AnyActorLogic> = TLogic extends AnyStateMachine ? AreAllImplementationsAssumedToBeProvided<TLogic['__TResolvedTypesMeta']> extends false ? [
options: ActorOptions<TLogic> & InternalMachineImplementations<TLogic['__TContext'], TLogic['__TEvent'], TODO, TODO, TODO, TLogic['__TResolvedTypesMeta'], true>,
observerOrListener?: Observer<StateFrom<TLogic>> | ((value: StateFrom<TLogic>) => void)
] : [
options?: ActorOptions<TLogic> & InternalMachineImplementations<TLogic['__TContext'], TLogic['__TEvent'], TODO, TODO, TODO, TLogic['__TResolvedTypesMeta']>,
observerOrListener?: Observer<StateFrom<TLogic>> | ((value: StateFrom<TLogic>) => void)
] : [
options?: ActorOptions<TLogic>,
observerOrListener?: Observer<SnapshotFrom<TLogic>> | ((value: SnapshotFrom<TLogic>) => void)
];
export declare function useActorRef<TLogic extends AnyActorLogic>(machine: TLogic, ...[options, observerOrListener]: RestParams<TLogic>): ActorRefFrom<TLogic>;
export {};
import { AnyActorLogic, AnyActor, ActorRefFrom, ActorOptions, Observer, SnapshotFrom } from 'xstate';
export declare function useIdleActor(logic: AnyActorLogic, options: Partial<ActorOptions<AnyActorLogic>>): AnyActor;
export declare function useActorRef<TLogic extends AnyActorLogic>(machine: TLogic, options?: ActorOptions<TLogic>, observerOrListener?: Observer<SnapshotFrom<TLogic>> | ((value: SnapshotFrom<TLogic>) => void)): ActorRefFrom<TLogic>;

@@ -34,25 +34,56 @@ 'use strict';

function useConstant(fn) {
const ref = React__namespace.useRef();
if (!ref.current) {
ref.current = {
v: fn()
};
const forEachActor = (actorRef, callback) => {
callback(actorRef);
const children = actorRef.getSnapshot().children;
if (children) {
Object.values(children).forEach(child => {
forEachActor(child, callback);
});
}
return ref.current.v;
};
function stopRootWithRehydration(actorRef) {
// persist state here in a custom way allows us to persist inline actors and to preserve actor references
// we do it to avoid setState in useEffect when the effect gets "reconnected"
// this currently only happens in Strict Effects but it simulates the Offscreen aka Activity API
// it also just allows us to end up with a somewhat more predictable behavior for the users
const persistedSnapshots = [];
forEachActor(actorRef, ref => {
persistedSnapshots.push([ref, ref.getSnapshot()]);
// muting observers allow us to avoid `useSelector` from being notified about the stopped state
// React reconnects its subscribers (from the useSyncExternalStore) on its own
// and userland subscibers should basically always do the same anyway
// as each subscription should have its own cleanup logic and that should be called each such reconnect
ref.observers = new Set();
});
actorRef.stop();
persistedSnapshots.forEach(([ref, snapshot]) => {
ref._processingStatus = 0;
ref._state = snapshot;
});
}
function useIdleInterpreter(machine, options) {
const actorRef = useConstant(() => {
return xstate.createActor(machine, options);
function useIdleActor(logic, options) {
let [[currentConfig, actorRef], setCurrent] = React.useState(() => {
const actorRef = xstate.createActor(logic, options);
return [logic.config, actorRef];
});
if (logic.config !== currentConfig) {
const newActorRef = xstate.createActor(logic, {
...options,
state: actorRef.getPersistedState({
__unsafeAllowInlineActors: true
})
});
setCurrent([logic.config, newActorRef]);
actorRef = newActorRef;
}
// TODO: consider using `useAsapEffect` that would do this in `useInsertionEffect` is that's available
useIsomorphicLayoutEffect__default["default"](() => {
actorRef.logic.implementations = machine.implementations;
actorRef.logic.implementations = logic.implementations;
});
return actorRef;
}
function useActorRef(machine, ...[options = {}, observerOrListener]) {
const actorRef = useIdleInterpreter(machine, options);
function useActorRef(machine, options = {}, observerOrListener) {
const actorRef = useIdleActor(machine, options);
React.useEffect(() => {

@@ -70,7 +101,5 @@ if (!observerOrListener) {

return () => {
actorRef.stop();
actorRef.status = xstate.ActorStatus.NotStarted;
actorRef._initState();
stopRootWithRehydration(actorRef);
};
}, []);
}, [actorRef]);
return actorRef;

@@ -80,3 +109,3 @@ }

function useActor(logic, options = {}) {
const actorRef = useIdleInterpreter(logic, options);
const actorRef = useIdleActor(logic, options);
const getSnapshot = React.useCallback(() => {

@@ -95,5 +124,3 @@ return actorRef.getSnapshot();

return () => {
actorRef.stop();
actorRef.status = xstate.ActorStatus.NotStarted;
actorRef._initState();
stopRootWithRehydration(actorRef);
};

@@ -100,0 +127,0 @@ }, [actorRef]);

@@ -34,31 +34,56 @@ 'use strict';

function useConstant(fn) {
const ref = React__namespace.useRef();
if (!ref.current) {
ref.current = {
v: fn()
};
const forEachActor = (actorRef, callback) => {
callback(actorRef);
const children = actorRef.getSnapshot().children;
if (children) {
Object.values(children).forEach(child => {
forEachActor(child, callback);
});
}
return ref.current.v;
};
function stopRootWithRehydration(actorRef) {
// persist state here in a custom way allows us to persist inline actors and to preserve actor references
// we do it to avoid setState in useEffect when the effect gets "reconnected"
// this currently only happens in Strict Effects but it simulates the Offscreen aka Activity API
// it also just allows us to end up with a somewhat more predictable behavior for the users
const persistedSnapshots = [];
forEachActor(actorRef, ref => {
persistedSnapshots.push([ref, ref.getSnapshot()]);
// muting observers allow us to avoid `useSelector` from being notified about the stopped state
// React reconnects its subscribers (from the useSyncExternalStore) on its own
// and userland subscibers should basically always do the same anyway
// as each subscription should have its own cleanup logic and that should be called each such reconnect
ref.observers = new Set();
});
actorRef.stop();
persistedSnapshots.forEach(([ref, snapshot]) => {
ref._processingStatus = 0;
ref._state = snapshot;
});
}
function useIdleInterpreter(machine, options) {
{
const [initialMachine] = React.useState(machine);
if (machine.config !== initialMachine.config) {
console.warn(`Actor logic has changed between renders. This is not supported and may lead to invalid snapshots.`);
}
function useIdleActor(logic, options) {
let [[currentConfig, actorRef], setCurrent] = React.useState(() => {
const actorRef = xstate.createActor(logic, options);
return [logic.config, actorRef];
});
if (logic.config !== currentConfig) {
const newActorRef = xstate.createActor(logic, {
...options,
state: actorRef.getPersistedState({
__unsafeAllowInlineActors: true
})
});
setCurrent([logic.config, newActorRef]);
actorRef = newActorRef;
}
const actorRef = useConstant(() => {
return xstate.createActor(machine, options);
});
// TODO: consider using `useAsapEffect` that would do this in `useInsertionEffect` is that's available
useIsomorphicLayoutEffect__default["default"](() => {
actorRef.logic.implementations = machine.implementations;
actorRef.logic.implementations = logic.implementations;
});
return actorRef;
}
function useActorRef(machine, ...[options = {}, observerOrListener]) {
const actorRef = useIdleInterpreter(machine, options);
function useActorRef(machine, options = {}, observerOrListener) {
const actorRef = useIdleActor(machine, options);
React.useEffect(() => {

@@ -76,7 +101,5 @@ if (!observerOrListener) {

return () => {
actorRef.stop();
actorRef.status = xstate.ActorStatus.NotStarted;
actorRef._initState();
stopRootWithRehydration(actorRef);
};
}, []);
}, [actorRef]);
return actorRef;

@@ -89,3 +112,3 @@ }

}
const actorRef = useIdleInterpreter(logic, options);
const actorRef = useIdleActor(logic, options);
const getSnapshot = React.useCallback(() => {

@@ -104,5 +127,3 @@ return actorRef.getSnapshot();

return () => {
actorRef.stop();
actorRef.status = xstate.ActorStatus.NotStarted;
actorRef._initState();
stopRootWithRehydration(actorRef);
};

@@ -109,0 +130,0 @@ }, [actorRef]);

import * as React from 'react';
import { useEffect, useState, useCallback } from 'react';
import { useSyncExternalStore } from 'use-sync-external-store/shim';
import { toObserver, ActorStatus, createActor } from 'xstate';
import { toObserver, createActor } from 'xstate';
import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';
function useConstant(fn) {
const ref = React.useRef();
if (!ref.current) {
ref.current = {
v: fn()
};
const forEachActor = (actorRef, callback) => {
callback(actorRef);
const children = actorRef.getSnapshot().children;
if (children) {
Object.values(children).forEach(child => {
forEachActor(child, callback);
});
}
return ref.current.v;
};
function stopRootWithRehydration(actorRef) {
// persist state here in a custom way allows us to persist inline actors and to preserve actor references
// we do it to avoid setState in useEffect when the effect gets "reconnected"
// this currently only happens in Strict Effects but it simulates the Offscreen aka Activity API
// it also just allows us to end up with a somewhat more predictable behavior for the users
const persistedSnapshots = [];
forEachActor(actorRef, ref => {
persistedSnapshots.push([ref, ref.getSnapshot()]);
// muting observers allow us to avoid `useSelector` from being notified about the stopped state
// React reconnects its subscribers (from the useSyncExternalStore) on its own
// and userland subscibers should basically always do the same anyway
// as each subscription should have its own cleanup logic and that should be called each such reconnect
ref.observers = new Set();
});
actorRef.stop();
persistedSnapshots.forEach(([ref, snapshot]) => {
ref._processingStatus = 0;
ref._state = snapshot;
});
}
function useIdleInterpreter(machine, options) {
{
const [initialMachine] = useState(machine);
if (machine.config !== initialMachine.config) {
console.warn(`Actor logic has changed between renders. This is not supported and may lead to invalid snapshots.`);
}
function useIdleActor(logic, options) {
let [[currentConfig, actorRef], setCurrent] = useState(() => {
const actorRef = createActor(logic, options);
return [logic.config, actorRef];
});
if (logic.config !== currentConfig) {
const newActorRef = createActor(logic, {
...options,
state: actorRef.getPersistedState({
__unsafeAllowInlineActors: true
})
});
setCurrent([logic.config, newActorRef]);
actorRef = newActorRef;
}
const actorRef = useConstant(() => {
return createActor(machine, options);
});
// TODO: consider using `useAsapEffect` that would do this in `useInsertionEffect` is that's available
useIsomorphicLayoutEffect(() => {
actorRef.logic.implementations = machine.implementations;
actorRef.logic.implementations = logic.implementations;
});
return actorRef;
}
function useActorRef(machine, ...[options = {}, observerOrListener]) {
const actorRef = useIdleInterpreter(machine, options);
function useActorRef(machine, options = {}, observerOrListener) {
const actorRef = useIdleActor(machine, options);
useEffect(() => {

@@ -49,7 +74,5 @@ if (!observerOrListener) {

return () => {
actorRef.stop();
actorRef.status = ActorStatus.NotStarted;
actorRef._initState();
stopRootWithRehydration(actorRef);
};
}, []);
}, [actorRef]);
return actorRef;

@@ -62,3 +85,3 @@ }

}
const actorRef = useIdleInterpreter(logic, options);
const actorRef = useIdleActor(logic, options);
const getSnapshot = useCallback(() => {

@@ -77,5 +100,3 @@ return actorRef.getSnapshot();

return () => {
actorRef.stop();
actorRef.status = ActorStatus.NotStarted;
actorRef._initState();
stopRootWithRehydration(actorRef);
};

@@ -82,0 +103,0 @@ }, [actorRef]);

import * as React from 'react';
import { useEffect, useCallback } from 'react';
import { useEffect, useState, useCallback } from 'react';
import { useSyncExternalStore } from 'use-sync-external-store/shim';
import { toObserver, ActorStatus, createActor } from 'xstate';
import { toObserver, createActor } from 'xstate';
import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect';
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector';
function useConstant(fn) {
const ref = React.useRef();
if (!ref.current) {
ref.current = {
v: fn()
};
const forEachActor = (actorRef, callback) => {
callback(actorRef);
const children = actorRef.getSnapshot().children;
if (children) {
Object.values(children).forEach(child => {
forEachActor(child, callback);
});
}
return ref.current.v;
};
function stopRootWithRehydration(actorRef) {
// persist state here in a custom way allows us to persist inline actors and to preserve actor references
// we do it to avoid setState in useEffect when the effect gets "reconnected"
// this currently only happens in Strict Effects but it simulates the Offscreen aka Activity API
// it also just allows us to end up with a somewhat more predictable behavior for the users
const persistedSnapshots = [];
forEachActor(actorRef, ref => {
persistedSnapshots.push([ref, ref.getSnapshot()]);
// muting observers allow us to avoid `useSelector` from being notified about the stopped state
// React reconnects its subscribers (from the useSyncExternalStore) on its own
// and userland subscibers should basically always do the same anyway
// as each subscription should have its own cleanup logic and that should be called each such reconnect
ref.observers = new Set();
});
actorRef.stop();
persistedSnapshots.forEach(([ref, snapshot]) => {
ref._processingStatus = 0;
ref._state = snapshot;
});
}
function useIdleInterpreter(machine, options) {
const actorRef = useConstant(() => {
return createActor(machine, options);
function useIdleActor(logic, options) {
let [[currentConfig, actorRef], setCurrent] = useState(() => {
const actorRef = createActor(logic, options);
return [logic.config, actorRef];
});
if (logic.config !== currentConfig) {
const newActorRef = createActor(logic, {
...options,
state: actorRef.getPersistedState({
__unsafeAllowInlineActors: true
})
});
setCurrent([logic.config, newActorRef]);
actorRef = newActorRef;
}
// TODO: consider using `useAsapEffect` that would do this in `useInsertionEffect` is that's available
useIsomorphicLayoutEffect(() => {
actorRef.logic.implementations = machine.implementations;
actorRef.logic.implementations = logic.implementations;
});
return actorRef;
}
function useActorRef(machine, ...[options = {}, observerOrListener]) {
const actorRef = useIdleInterpreter(machine, options);
function useActorRef(machine, options = {}, observerOrListener) {
const actorRef = useIdleActor(machine, options);
useEffect(() => {

@@ -43,7 +74,5 @@ if (!observerOrListener) {

return () => {
actorRef.stop();
actorRef.status = ActorStatus.NotStarted;
actorRef._initState();
stopRootWithRehydration(actorRef);
};
}, []);
}, [actorRef]);
return actorRef;

@@ -53,3 +82,3 @@ }

function useActor(logic, options = {}) {
const actorRef = useIdleInterpreter(logic, options);
const actorRef = useIdleActor(logic, options);
const getSnapshot = useCallback(() => {

@@ -68,5 +97,3 @@ return actorRef.getSnapshot();

return () => {
actorRef.stop();
actorRef.status = ActorStatus.NotStarted;
actorRef._initState();
stopRootWithRehydration(actorRef);
};

@@ -73,0 +100,0 @@ }, [actorRef]);

{
"name": "@xstate/react",
"version": "4.0.0-beta.10",
"version": "4.0.0-beta.11",
"description": "XState tools for React",

@@ -58,3 +58,3 @@ "keywords": [

"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"xstate": "^5.0.0-beta.29"
"xstate": "^5.0.0-beta.41"
},

@@ -80,4 +80,4 @@ "peerDependenciesMeta": {

"react-dom": "^18.0.0",
"xstate": "5.0.0-beta.29"
"xstate": "5.0.0-beta.41"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc