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
1 lines • 3.85 kB
Source Map (JSON)
{"version":3,"file":"storybook.mjs","names":[],"sources":["../src/withActorKit.tsx"],"sourcesContent":["import type { StoryContext, StoryFn } from \"@storybook/react\";\nimport React from \"react\";\nimport { createActorKitContext } from \"./createActorKitContext\";\nimport { createActorKitMockClient } from \"./createActorKitMockClient\";\nimport type { AnyActorKitStateMachine } from \"./types\";\nimport { ActorKitParameters } from \"./storybook\";\n\n/**\n * Storybook decorator that sets up actor-kit state machines.\n *\n * There are two main patterns for testing with actor-kit:\n *\n * 1. Static Stories (Use parameters.actorKit + within):\n * - Use this decorator with parameters.actorKit\n * - Use `within(canvasElement)` in play functions\n * - Good for simple stories that don't need state manipulation\n *\n * 2. Interactive Stories (Use mount + direct client):\n * - Don't use this decorator\n * - Create client manually and use mount in play function\n * - Good for stories that need to manipulate state\n *\n * @example\n * ```tsx\n * // Pattern 1: Static Story\n * export const Static: Story = {\n * parameters: {\n * actorKit: {\n * session: {\n * \"session-123\": { ... }\n * }\n * }\n * },\n * play: async ({ canvasElement }) => {\n * const canvas = within(canvasElement);\n * // Test UI state...\n * }\n * };\n *\n * // Pattern 2: Interactive Story\n * export const Interactive: Story = {\n * play: async ({ canvasElement, mount }) => {\n * const client = createActorKitMockClient({...});\n * const canvas = within(canvasElement);\n *\n * await mount(\n * <Context.ProviderFromClient client={client}>\n * <Component />\n * </Context.ProviderFromClient>\n * );\n *\n * // Now you can manipulate client state...\n * client.produce((draft) => { ... });\n * }\n * };\n * ```\n */\nexport const withActorKit = <TMachine extends AnyActorKitStateMachine>({\n actorType,\n context,\n}: {\n actorType: string;\n context: ReturnType<typeof createActorKitContext<TMachine>>;\n}) => {\n return (Story: StoryFn, storyContext: StoryContext): React.ReactElement => {\n const actorKitParams = storyContext.parameters?.actorKit as\n | ActorKitParameters<TMachine>[\"actorKit\"]\n | undefined;\n\n // If no params provided, just render the story without any providers\n if (!actorKitParams?.[actorType]) {\n return <Story />;\n }\n\n // Create nested providers for each actor ID\n const actorSnapshots = actorKitParams[actorType];\n\n // Recursively nest providers\n const createNestedProviders = (\n actorIds: string[],\n index: number,\n children: React.ReactNode\n ): React.ReactElement => {\n if (index >= actorIds.length) {\n return children as React.ReactElement;\n }\n\n const actorId = actorIds[index];\n const snapshot = actorSnapshots[actorId];\n const client = createActorKitMockClient<TMachine>({\n initialSnapshot: snapshot,\n });\n\n return (\n <context.ProviderFromClient client={client}>\n {createNestedProviders(actorIds, index + 1, children)}\n </context.ProviderFromClient>\n );\n };\n\n return createNestedProviders(Object.keys(actorSnapshots), 0, <Story />);\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,MAAa,gBAA0D,EACrE,WACA,cAII;AACJ,SAAQ,OAAgB,iBAAmD;EACzE,MAAM,iBAAiB,aAAa,YAAY;AAKhD,MAAI,CAAC,iBAAiB,WACpB,QAAO,sBAAA,cAAC,OAAA,KAAQ;EAIlB,MAAM,iBAAiB,eAAe;EAGtC,MAAM,yBACJ,UACA,OACA,aACuB;AACvB,OAAI,SAAS,SAAS,OACpB,QAAO;GAIT,MAAM,WAAW,eADD,SAAS;GAEzB,MAAM,SAAS,yBAAmC,EAChD,iBAAiB,UAClB,CAAC;AAEF,UACE,sBAAA,cAAC,QAAQ,oBAAT,EAAoC,QAEP,EAD1B,sBAAsB,UAAU,QAAQ,GAAG,SAAS,CAC1B;;AAIjC,SAAO,sBAAsB,OAAO,KAAK,eAAe,EAAE,GAAG,sBAAA,cAAC,OAAA,KAAQ,CAAC"}