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
98 lines (97 loc) • 3.01 kB
JavaScript
import { produce } from "immer";
//#region src/createActorKitMockClient.ts
/**
* Creates a mock Actor Kit client for testing purposes.
*
* @template TMachine - The type of the state machine.
* @param {ActorKitMockClientProps<TMachine>} props - Configuration options for the mock client.
* @returns {ActorKitMockClient<TMachine>} An object with methods to interact with the mock actor.
*/
function createActorKitMockClient(props) {
let currentSnapshot = props.initialSnapshot;
const listeners = /* @__PURE__ */ new Set();
/**
* Notifies all registered listeners with the current state.
*/
const notifyListeners = () => {
listeners.forEach((listener) => listener(currentSnapshot));
};
/**
* Updates the state using an Immer producer function.
* @param {(draft: Draft<CallerSnapshotFrom<TMachine>>) => void} recipe - The state update recipe.
*/
const produceFn = (recipe) => {
currentSnapshot = produce(currentSnapshot, recipe);
notifyListeners();
};
/**
* Sends an event to the mock client.
* @param {ClientEventFrom<TMachine>} event - The event to send.
*/
const send = (event) => {
props.onSend?.(event);
notifyListeners();
};
/**
* Retrieves the current state of the mock actor.
* @returns {CallerSnapshotFrom<TMachine>} The current state.
*/
const getState = () => currentSnapshot;
/**
* Subscribes a listener to state changes.
* @param {(state: CallerSnapshotFrom<TMachine>) => void} listener - The listener function to be called on state changes.
* @returns {() => void} A function to unsubscribe the listener.
*/
const subscribe = (listener) => {
listeners.add(listener);
return () => {
listeners.delete(listener);
};
};
/**
* Mock connect method.
* @returns {Promise<void>} A promise that resolves immediately.
*/
const connect = async () => {
return Promise.resolve();
};
/**
* Mock disconnect method.
*/
const disconnect = () => {};
/**
* Waits for a state condition to be met.
* @param {(state: CallerSnapshotFrom<TMachine>) => boolean} predicateFn - Function that returns true when condition is met
* @param {number} [timeoutMs=5000] - Maximum time to wait in milliseconds
* @returns {Promise<void>} Resolves when condition is met, rejects on timeout
*/
const waitFor = async (predicateFn, timeoutMs = 5e3) => {
if (predicateFn(currentSnapshot)) return Promise.resolve();
return new Promise((resolve, reject) => {
let timeoutId = null;
if (timeoutMs > 0) timeoutId = setTimeout(() => {
unsubscribe();
reject(/* @__PURE__ */ new Error(`Timeout waiting for condition after ${timeoutMs}ms`));
}, timeoutMs);
const unsubscribe = subscribe((state) => {
if (predicateFn(state)) {
if (timeoutId) clearTimeout(timeoutId);
unsubscribe();
resolve();
}
});
});
};
return {
connect,
disconnect,
send,
getState,
subscribe,
produce: produceFn,
waitFor
};
}
//#endregion
export { createActorKitMockClient as t };
//# sourceMappingURL=createActorKitMockClient-Bqgcb5gz.mjs.map