actor-kit
Version:
Actor Kit is a library for running state machines in Cloudflare Workers, leveraging XState for robust state management. It provides a framework for managing the logic, lifecycle, persistence, synchronization, and access control of actors in a distributed
129 lines (128 loc) • 4.57 kB
JavaScript
import "./schemas-DTUwr6Qg.mjs";
import { t as createActorKitClient } from "./createActorKitClient-BJBupEaE.mjs";
import React, { createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useSyncExternalStore } from "react";
import { matchesState } from "xstate";
//#region src/createActorKitContext.tsx
function createActorKitContext(actorType) {
const ActorKitContext = createContext(null);
const ProviderFromClient = ({ children, client }) => {
return /* @__PURE__ */ React.createElement(ActorKitContext.Provider, { value: client }, children);
};
const InitialSnapshotContext = createContext(null);
const Provider = memo((props) => {
const clientRef = useRef(createActorKitClient({
host: props.host,
actorId: props.actorId,
accessToken: props.accessToken,
checksum: props.checksum,
initialSnapshot: props.initialSnapshot,
actorType
}));
const initializedRef = useRef(false);
useEffect(() => {
if (!initializedRef.current) {
initializedRef.current = true;
clientRef.current.connect().then(() => {});
}
}, [initializedRef]);
return /* @__PURE__ */ React.createElement(InitialSnapshotContext.Provider, { value: props.initialSnapshot }, /* @__PURE__ */ React.createElement(ActorKitContext.Provider, { value: clientRef.current }, props.children));
});
function useClient() {
const client = useContext(ActorKitContext);
if (!client) throw new Error("useClient must be used within an ActorKitContext.Provider");
return client;
}
const useSelector = (selector) => {
const client = useClient();
const initialSnapshot = useContext(InitialSnapshotContext);
const getServerSnapshot = useMemo(() => {
if (!initialSnapshot) return void 0;
return () => initialSnapshot;
}, [initialSnapshot]);
return useSyncExternalStoreWithSelector(client.subscribe, client.getState, getServerSnapshot, selector, defaultCompare);
};
function useSend() {
return useClient().send;
}
function useMatches(stateValue) {
return useSelector((state) => matchesState(stateValue, state.value));
}
const Matches = (props) => {
const active = useMatches(props.state);
const matchesAnd = props.and ? useMatches(props.and) : true;
const matchesOr = props.or ? useMatches(props.or) : false;
const value = typeof props.initialValueOverride === "boolean" ? props.initialValueOverride : active && matchesAnd || matchesOr;
return (props.not ? !value : value) ? /* @__PURE__ */ React.createElement(React.Fragment, null, props.children) : null;
};
Matches.create = (state, options = {}) => {
const Component = ({ children, initialValueOverride }) => /* @__PURE__ */ React.createElement(Matches, {
state,
and: options.and,
or: options.or,
not: options.not,
initialValueOverride
}, children);
Component.displayName = `MatchesComponent(${state.toString()})`;
return Component;
};
return {
Provider,
ProviderFromClient,
useClient,
useSelector,
useSend,
useMatches,
Matches
};
}
function useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
const [getSelection, getServerSelection] = useMemo(() => {
let hasMemo = false;
let memoizedSnapshot;
let memoizedSelection;
const memoizedSelector = (nextSnapshot) => {
if (!hasMemo) {
hasMemo = true;
memoizedSnapshot = nextSnapshot;
memoizedSelection = selector(nextSnapshot);
return memoizedSelection;
}
if (Object.is(memoizedSnapshot, nextSnapshot)) return memoizedSelection;
const nextSelection = selector(nextSnapshot);
if (isEqual && isEqual(memoizedSelection, nextSelection)) {
memoizedSnapshot = nextSnapshot;
return memoizedSelection;
}
memoizedSnapshot = nextSnapshot;
memoizedSelection = nextSelection;
return nextSelection;
};
const getSnapshotWithSelector = () => memoizedSelector(getSnapshot());
return [getSnapshotWithSelector, getServerSnapshot ? () => memoizedSelector(getServerSnapshot()) : void 0];
}, [
getSnapshot,
getServerSnapshot,
selector,
isEqual
]);
return useSyncExternalStore(useCallback((onStoreChange) => {
let previousSelection = getSelection();
return subscribe(() => {
const nextSelection = getSelection();
if (!isEqual || !isEqual(previousSelection, nextSelection)) {
previousSelection = nextSelection;
onStoreChange();
}
});
}, [
subscribe,
getSelection,
isEqual
]), getSelection, getServerSelection);
}
function defaultCompare(a, b) {
return a === b;
}
//#endregion
export { createActorKitContext };
//# sourceMappingURL=react.mjs.map