UNPKG

@portabletext/editor

Version:

Portable Text Editor made in React

44 lines (39 loc) 1.79 kB
/** * Copy/pasted from https://github.com/statelyai/xstate/blob/main/packages/xstate-react/src/stopRootWithRehydration.ts * and renamed to `stopActor` */ import type {AnyActorRef, Snapshot} from 'xstate' const forEachActor = ( actorRef: AnyActorRef, callback: (ref: AnyActorRef) => void, ) => { callback(actorRef) const children = actorRef.getSnapshot().children if (children) { Object.values(children).forEach((child) => { forEachActor(child as AnyActorRef, callback) }) } } export function stopActor(actorRef: AnyActorRef) { // persist snapshot 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: Array<[AnyActorRef, Snapshot<unknown>]> = [] forEachActor(actorRef, (ref) => { persistedSnapshots.push([ref, ref.getSnapshot()]) // muting observers allow us to avoid `useSelector` from being notified about the stopped snapshot // 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 as any).observers = new Set() }) const systemSnapshot = actorRef.system.getSnapshot?.() actorRef.stop() ;(actorRef.system as any)._snapshot = systemSnapshot persistedSnapshots.forEach(([ref, snapshot]) => { ;(ref as any)._processingStatus = 0 ;(ref as any)._snapshot = snapshot }) }