diff --git a/.gitignore b/.gitignore index 150de1370..3012c9832 100644 --- a/.gitignore +++ b/.gitignore @@ -31,5 +31,5 @@ yarn-error.log* .idea .fleet -# Fumadocs build (TEMPORARY) -fumadocs +# Next.js +.next diff --git a/.source/index.ts b/.source/index.ts new file mode 100644 index 000000000..8fd16adbc --- /dev/null +++ b/.source/index.ts @@ -0,0 +1,229 @@ +// @ts-nocheck -- skip type checking +import * as d_docs_102 from "../content/docs/agents/agents.mdx?collection=docs" +import * as d_docs_101 from "../content/docs/xstate.mdx?collection=docs" +import * as d_docs_100 from "../content/docs/xstate-vue.mdx?collection=docs" +import * as d_docs_99 from "../content/docs/xstate-vscode-extension.mdx?collection=docs" +import * as d_docs_98 from "../content/docs/xstate-test.mdx?collection=docs" +import * as d_docs_97 from "../content/docs/xstate-svelte.mdx?collection=docs" +import * as d_docs_96 from "../content/docs/xstate-store.mdx?collection=docs" +import * as d_docs_95 from "../content/docs/xstate-store-v2.mdx?collection=docs" +import * as d_docs_94 from "../content/docs/xstate-react.mdx?collection=docs" +import * as d_docs_93 from "../content/docs/xstate-immer.mdx?collection=docs" +import * as d_docs_92 from "../content/docs/xstate-graph.mdx?collection=docs" +import * as d_docs_91 from "../content/docs/xstate-fsm.mdx?collection=docs" +import * as d_docs_90 from "../content/docs/visualizer.mdx?collection=docs" +import * as d_docs_89 from "../content/docs/versions.mdx?collection=docs" +import * as d_docs_88 from "../content/docs/user-preferences.mdx?collection=docs" +import * as d_docs_87 from "../content/docs/url.mdx?collection=docs" +import * as d_docs_86 from "../content/docs/upgrade.mdx?collection=docs" +import * as d_docs_85 from "../content/docs/typescript.mdx?collection=docs" +import * as d_docs_84 from "../content/docs/typegen.mdx?collection=docs" +import * as d_docs_83 from "../content/docs/transitions.mdx?collection=docs" +import * as d_docs_82 from "../content/docs/transition-actors.mdx?collection=docs" +import * as d_docs_81 from "../content/docs/testing.mdx?collection=docs" +import * as d_docs_80 from "../content/docs/templates.mdx?collection=docs" +import * as d_docs_79 from "../content/docs/teams.mdx?collection=docs" +import * as d_docs_78 from "../content/docs/tags.mdx?collection=docs" +import * as d_docs_77 from "../content/docs/system.mdx?collection=docs" +import * as d_docs_76 from "../content/docs/studio.mdx?collection=docs" +import * as d_docs_75 from "../content/docs/studio-team-plan.mdx?collection=docs" +import * as d_docs_74 from "../content/docs/studio-pro-plan.mdx?collection=docs" +import * as d_docs_73 from "../content/docs/studio-enterprise-plan.mdx?collection=docs" +import * as d_docs_72 from "../content/docs/studio-community-plan.mdx?collection=docs" +import * as d_docs_71 from "../content/docs/studio-api.mdx?collection=docs" +import * as d_docs_70 from "../content/docs/states.mdx?collection=docs" +import * as d_docs_69 from "../content/docs/stately-sky-getting-started.mdx?collection=docs" +import * as d_docs_68 from "../content/docs/state-machines-and-statecharts.mdx?collection=docs" +import * as d_docs_67 from "../content/docs/state-machine-actors.mdx?collection=docs" +import * as d_docs_66 from "../content/docs/state-done-events.mdx?collection=docs" +import * as d_docs_65 from "../content/docs/spawn.mdx?collection=docs" +import * as d_docs_64 from "../content/docs/sources.mdx?collection=docs" +import * as d_docs_63 from "../content/docs/simulate-mode.mdx?collection=docs" +import * as d_docs_62 from "../content/docs/sign-up.mdx?collection=docs" +import * as d_docs_61 from "../content/docs/setup.mdx?collection=docs" +import * as d_docs_60 from "../content/docs/quick-start.mdx?collection=docs" +import * as d_docs_59 from "../content/docs/pure-transitions.mdx?collection=docs" +import * as d_docs_58 from "../content/docs/promise-actors.mdx?collection=docs" +import * as d_docs_57 from "../content/docs/projects.mdx?collection=docs" +import * as d_docs_56 from "../content/docs/persistence.mdx?collection=docs" +import * as d_docs_55 from "../content/docs/parent-states.mdx?collection=docs" +import * as d_docs_54 from "../content/docs/parallel-states.mdx?collection=docs" +import * as d_docs_53 from "../content/docs/output.mdx?collection=docs" +import * as d_docs_52 from "../content/docs/observable-actors.mdx?collection=docs" +import * as d_docs_51 from "../content/docs/migration.mdx?collection=docs" +import * as d_docs_50 from "../content/docs/machines.mdx?collection=docs" +import * as d_docs_49 from "../content/docs/machine-restore.mdx?collection=docs" +import * as d_docs_48 from "../content/docs/lock-machines.mdx?collection=docs" +import * as d_docs_47 from "../content/docs/live-simulation.mdx?collection=docs" +import * as d_docs_46 from "../content/docs/keyboard-shortcuts.mdx?collection=docs" +import * as d_docs_45 from "../content/docs/invoke.mdx?collection=docs" +import * as d_docs_44 from "../content/docs/installation.mdx?collection=docs" +import * as d_docs_43 from "../content/docs/inspector.mdx?collection=docs" +import * as d_docs_42 from "../content/docs/inspection.mdx?collection=docs" +import * as d_docs_41 from "../content/docs/input.mdx?collection=docs" +import * as d_docs_40 from "../content/docs/initial-states.mdx?collection=docs" +import * as d_docs_39 from "../content/docs/index.mdx?collection=docs" +import * as d_docs_38 from "../content/docs/import-from-github.mdx?collection=docs" +import * as d_docs_37 from "../content/docs/import-from-code.mdx?collection=docs" +import * as d_docs_36 from "../content/docs/immer.mdx?collection=docs" +import * as d_docs_35 from "../content/docs/image.mdx?collection=docs" +import * as d_docs_34 from "../content/docs/history-states.mdx?collection=docs" +import * as d_docs_33 from "../content/docs/guards.mdx?collection=docs" +import * as d_docs_32 from "../content/docs/glossary.mdx?collection=docs" +import * as d_docs_31 from "../content/docs/generate-test-paths.mdx?collection=docs" +import * as d_docs_30 from "../content/docs/generate-react.mdx?collection=docs" +import * as d_docs_29 from "../content/docs/generate-flow.mdx?collection=docs" +import * as d_docs_28 from "../content/docs/function-actors.mdx?collection=docs" +import * as d_docs_27 from "../content/docs/finite-states.mdx?collection=docs" +import * as d_docs_26 from "../content/docs/final-states.mdx?collection=docs" +import * as d_docs_25 from "../content/docs/figma.mdx?collection=docs" +import * as d_docs_24 from "../content/docs/export-as-code.mdx?collection=docs" +import * as d_docs_23 from "../content/docs/examples.mdx?collection=docs" +import * as d_docs_22 from "../content/docs/eventless-transitions.mdx?collection=docs" +import * as d_docs_21 from "../content/docs/event-emitter.mdx?collection=docs" +import * as d_docs_20 from "../content/docs/embed.mdx?collection=docs" +import * as d_docs_19 from "../content/docs/editor-tags.mdx?collection=docs" +import * as d_docs_18 from "../content/docs/editor-states-and-transitions.mdx?collection=docs" +import * as d_docs_17 from "../content/docs/editor-context-and-meta.mdx?collection=docs" +import * as d_docs_16 from "../content/docs/editor-actions-and-actors.mdx?collection=docs" +import * as d_docs_15 from "../content/docs/discover.mdx?collection=docs" +import * as d_docs_14 from "../content/docs/developer-tools.mdx?collection=docs" +import * as d_docs_13 from "../content/docs/design-mode.mdx?collection=docs" +import * as d_docs_12 from "../content/docs/descriptions.mdx?collection=docs" +import * as d_docs_11 from "../content/docs/delayed-transitions.mdx?collection=docs" +import * as d_docs_10 from "../content/docs/context.mdx?collection=docs" +import * as d_docs_9 from "../content/docs/colors.mdx?collection=docs" +import * as d_docs_8 from "../content/docs/cheatsheet.mdx?collection=docs" +import * as d_docs_7 from "../content/docs/canvas-view-controls.mdx?collection=docs" +import * as d_docs_6 from "../content/docs/callback-actors.mdx?collection=docs" +import * as d_docs_5 from "../content/docs/autolayout.mdx?collection=docs" +import * as d_docs_4 from "../content/docs/assets.mdx?collection=docs" +import * as d_docs_3 from "../content/docs/annotations.mdx?collection=docs" +import * as d_docs_2 from "../content/docs/actors.mdx?collection=docs" +import * as d_docs_1 from "../content/docs/actor-model.mdx?collection=docs" +import * as d_docs_0 from "../content/docs/actions.mdx?collection=docs" +import * as d_blogPosts_120 from "../content/blog/2024-03-21-xstate-store-v3/index.mdx?collection=blogPosts" +import * as d_blogPosts_119 from "../content/blog/2024-07-29-claw-game-state-machine/index.mdx?collection=blogPosts" +import * as d_blogPosts_118 from "../content/blog/2024-11-12-webinargeek-and-stately-case-study/index.mdx?collection=blogPosts" +import * as d_blogPosts_117 from "../content/blog/2024-04-10-xstate-store/index.mdx?collection=blogPosts" +import * as d_blogPosts_116 from "../content/blog/2024-02-16-changelog-week-7/index.mdx?collection=blogPosts" +import * as d_blogPosts_115 from "../content/blog/2024-02-16-office-hours/index.mdx?collection=blogPosts" +import * as d_blogPosts_114 from "../content/blog/2024-02-12-xstate-react-global-state/index.mdx?collection=blogPosts" +import * as d_blogPosts_113 from "../content/blog/2024-01-11-changelog/index.mdx?collection=blogPosts" +import * as d_blogPosts_112 from "../content/blog/2024-02-07-single-file-prs/index.mdx?collection=blogPosts" +import * as d_blogPosts_111 from "../content/blog/2024-02-02-migrating-machines-to-xstate-v5/index.mdx?collection=blogPosts" +import * as d_blogPosts_110 from "../content/blog/2024-01-24-embed-figma/index.mdx?collection=blogPosts" +import * as d_blogPosts_109 from "../content/blog/2024-01-30-changelog/index.mdx?collection=blogPosts" +import * as d_blogPosts_108 from "../content/blog/2024-01-24-backend-workflows-credit-checking/index.mdx?collection=blogPosts" +import * as d_blogPosts_107 from "../content/blog/2024-01-23-state-machines-whats-in-a-name/index.mdx?collection=blogPosts" +import * as d_blogPosts_106 from "../content/blog/2024-01-19-office-hours/index.mdx?collection=blogPosts" +import * as d_blogPosts_105 from "../content/blog/2024-01-19-changelog/index.mdx?collection=blogPosts" +import * as d_blogPosts_104 from "../content/blog/2024-01-15-introducing-stately-inspector/index.mdx?collection=blogPosts" +import * as d_blogPosts_103 from "../content/blog/2024-01-12-xstate-exploring-actors/index.mdx?collection=blogPosts" +import * as d_blogPosts_102 from "../content/blog/2024-01-09-introducing-sources/index.mdx?collection=blogPosts" +import * as d_blogPosts_101 from "../content/blog/2024-01-11-building-backend-workflows/index.mdx?collection=blogPosts" +import * as d_blogPosts_100 from "../content/blog/2024-01-09-introducing-bidirectional-github-sync/index.mdx?collection=blogPosts" +import * as d_blogPosts_99 from "../content/blog/2023-09-15-teams-feature-overview/index.mdx?collection=blogPosts" +import * as d_blogPosts_98 from "../content/blog/2024-01-08-a-look-back-at-2023/index.mdx?collection=blogPosts" +import * as d_blogPosts_97 from "../content/blog/2024-01-03-learn-stately/index.mdx?collection=blogPosts" +import * as d_blogPosts_96 from "../content/blog/2024-01-05-office-hours/index.mdx?collection=blogPosts" +import * as d_blogPosts_95 from "../content/blog/2024-01-02-office-hours/index.mdx?collection=blogPosts" +import * as d_blogPosts_94 from "../content/blog/2023-5-30-what-is-the-actor-model-and-when-should-i-use-it/index.mdx?collection=blogPosts" +import * as d_blogPosts_93 from "../content/blog/2023-12-29-end-of-year-changelog/index.mdx?collection=blogPosts" +import * as d_blogPosts_92 from "../content/blog/2023-12-07-tidefi-and-stately-case-study/index.mdx?collection=blogPosts" +import * as d_blogPosts_91 from "../content/blog/2023-12-04-fugo-and-stately-case-study/index.mdx?collection=blogPosts" +import * as d_blogPosts_90 from "../content/blog/2023-11-28-koordinates-and-stately-case-study/index.mdx?collection=blogPosts" +import * as d_blogPosts_89 from "../content/blog/2023-12-01-xstate-v5/index.mdx?collection=blogPosts" +import * as d_blogPosts_88 from "../content/blog/2023-11-23-stately-studio-2-0-changelog/index.mdx?collection=blogPosts" +import * as d_blogPosts_87 from "../content/blog/2023-11-13-introducing-stately-sky/index.mdx?collection=blogPosts" +import * as d_blogPosts_86 from "../content/blog/2023-11-20-stately-studio-2-0/index.mdx?collection=blogPosts" +import * as d_blogPosts_85 from "../content/blog/2023-11-03-generate-test-paths-and-create-machines-faster/index.mdx?collection=blogPosts" +import * as d_blogPosts_84 from "../content/blog/2023-10-02-what-is-a-state-machine/index.mdx?collection=blogPosts" +import * as d_blogPosts_83 from "../content/blog/2023-10-02-persisting-state/index.mdx?collection=blogPosts" +import * as d_blogPosts_82 from "../content/blog/2023-1-27-making-state-machines-global-in-react/index.mdx?collection=blogPosts" +import * as d_blogPosts_81 from "../content/blog/2023-09-15-event-schemas-viewer-role/index.mdx?collection=blogPosts" +import * as d_blogPosts_80 from "../content/blog/2023-09-21-context-schema-and-export-to-external-editors/index.mdx?collection=blogPosts" +import * as d_blogPosts_79 from "../content/blog/2023-09-01-generate-flow/index.mdx?collection=blogPosts" +import * as d_blogPosts_78 from "../content/blog/2023-09-01-lock-machines/index.mdx?collection=blogPosts" +import * as d_blogPosts_77 from "../content/blog/2023-09-06-generating-flows/index.mdx?collection=blogPosts" +import * as d_blogPosts_76 from "../content/blog/2023-09-06-fixes-and-improvements/index.mdx?collection=blogPosts" +import * as d_blogPosts_75 from "../content/blog/2023-08-23-fixes-and-improvements/index.mdx?collection=blogPosts" +import * as d_blogPosts_74 from "../content/blog/2023-08-17-export-descriptions-and-meta-fields/index.mdx?collection=blogPosts" +import * as d_blogPosts_73 from "../content/blog/2023-08-17-latest-live-streams-from-stately/index.mdx?collection=blogPosts" +import * as d_blogPosts_72 from "../content/blog/2023-08-10-new-editor-videos/index.mdx?collection=blogPosts" +import * as d_blogPosts_71 from "../content/blog/2023-08-10-all-the-other-improvements/index.mdx?collection=blogPosts" +import * as d_blogPosts_70 from "../content/blog/2023-08-04-markdown-in-annotations/index.mdx?collection=blogPosts" +import * as d_blogPosts_69 from "../content/blog/2023-07-26-stately-minor-improvements/index.mdx?collection=blogPosts" +import * as d_blogPosts_68 from "../content/blog/2023-07-24-improving-your-flows-with-color/index.mdx?collection=blogPosts" +import * as d_blogPosts_67 from "../content/blog/2023-07-26-office-hours-68/index.mdx?collection=blogPosts" +import * as d_blogPosts_66 from "../content/blog/2023-07-20-export-to-mermaid/index.mdx?collection=blogPosts" +import * as d_blogPosts_65 from "../content/blog/2023-06-20-serverside-workflow-examples/index.mdx?collection=blogPosts" +import * as d_blogPosts_64 from "../content/blog/2023-07-18-stately-studio-minor-improvements/index.mdx?collection=blogPosts" +import * as d_blogPosts_63 from "../content/blog/2023-06-14-stately-studio-minor-improvements/index.mdx?collection=blogPosts" +import * as d_blogPosts_62 from "../content/blog/2023-07-05-webinar-intro-to-stately-studio/index.mdx?collection=blogPosts" +import * as d_blogPosts_61 from "../content/blog/2023-06-14-supercharge-the-canvas/index.mdx?collection=blogPosts" +import * as d_blogPosts_60 from "../content/blog/2023-05-19-context-aware-search/index.mdx?collection=blogPosts" +import * as d_blogPosts_59 from "../content/blog/2023-05-25-announcing-xstate-v5-beta/index.mdx?collection=blogPosts" +import * as d_blogPosts_58 from "../content/blog/2023-05-26-stately-studio-minor-improvements/index.mdx?collection=blogPosts" +import * as d_blogPosts_57 from "../content/blog/2023-05-17-stately-studio-minor-improvements/index.mdx?collection=blogPosts" +import * as d_blogPosts_56 from "../content/blog/2023-05-18-explain-your-machines-with-annotations/index.mdx?collection=blogPosts" +import * as d_blogPosts_55 from "../content/blog/2023-05-16-stately-streams/index.mdx?collection=blogPosts" +import * as d_blogPosts_54 from "../content/blog/2023-05-02-track-changes-as-you-work-with-version-history/index.mdx?collection=blogPosts" +import * as d_blogPosts_53 from "../content/blog/2023-05-03-introducing-state-new/index.mdx?collection=blogPosts" +import * as d_blogPosts_52 from "../content/blog/2023-05-12-office-hours-64/index.mdx?collection=blogPosts" +import * as d_blogPosts_51 from "../content/blog/2023-05-04-everything-new-since-stately-studio-1-0/index.mdx?collection=blogPosts" +import * as d_blogPosts_50 from "../content/blog/2023-04-28-new-default-machine/index.mdx?collection=blogPosts" +import * as d_blogPosts_49 from "../content/blog/2023-04-21-embed-url/index.mdx?collection=blogPosts" +import * as d_blogPosts_48 from "../content/blog/2023-03-09-import-all-machines-from-github-repo/index.mdx?collection=blogPosts" +import * as d_blogPosts_47 from "../content/blog/2023-04-03-book-a-demo/index.mdx?collection=blogPosts" +import * as d_blogPosts_46 from "../content/blog/2023-02-06-github-import-machines/index.mdx?collection=blogPosts" +import * as d_blogPosts_45 from "../content/blog/2023-01-20-whats-new-in-2023/index.mdx?collection=blogPosts" +import * as d_blogPosts_44 from "../content/blog/2023-01-19-introducing-the-stately-docs/index.mdx?collection=blogPosts" +import * as d_blogPosts_43 from "../content/blog/2022-2-6-stately-editor-public-beta/index.mdx?collection=blogPosts" +import * as d_blogPosts_42 from "../content/blog/2022-12-13-new-in-the-studio-machine-disaster-recovery/index.mdx?collection=blogPosts" +import * as d_blogPosts_41 from "../content/blog/2022-11-29-import-from-code/index.mdx?collection=blogPosts" +import * as d_blogPosts_40 from "../content/blog/2022-11-22-studio-update/index.mdx?collection=blogPosts" +import * as d_blogPosts_39 from "../content/blog/2022-10-27-studio-tutorials/index.mdx?collection=blogPosts" +import * as d_blogPosts_38 from "../content/blog/2022-10-18-stately-studio-1-0/index.mdx?collection=blogPosts" +import * as d_blogPosts_37 from "../content/blog/2022-08-31-building-a-resizable-panel/index.mdx?collection=blogPosts" +import * as d_blogPosts_36 from "../content/blog/2022-09-14-whats-new-september-2022/index.mdx?collection=blogPosts" +import * as d_blogPosts_35 from "../content/blog/2022-08-23-building-a-resizable-panel/index.mdx?collection=blogPosts" +import * as d_blogPosts_34 from "../content/blog/2022-08-17-goodbye-use-effect-at-react-next/index.mdx?collection=blogPosts" +import * as d_blogPosts_33 from "../content/blog/2022-08-10-get-started-with-xstate-using-xsm-snippet/index.mdx?collection=blogPosts" +import * as d_blogPosts_32 from "../content/blog/2022-07-18-just-use-hooks-xstate-in-react-components/index.mdx?collection=blogPosts" +import * as d_blogPosts_31 from "../content/blog/2022-08-03-whats-new-august-2022/index.mdx?collection=blogPosts" +import * as d_blogPosts_30 from "../content/blog/2022-07-06-whats-new-july-2022/index.mdx?collection=blogPosts" +import * as d_blogPosts_29 from "../content/blog/2022-06-07-whats-new-june-2022/index.mdx?collection=blogPosts" +import * as d_blogPosts_28 from "../content/blog/2022-06-13-nesting-typegen-files/index.mdx?collection=blogPosts" +import * as d_blogPosts_27 from "../content/blog/2022-06-20-what-is-xstate-used-for/index.mdx?collection=blogPosts" +import * as d_blogPosts_26 from "../content/blog/2022-05-03-whats-new-may-2022/index.mdx?collection=blogPosts" +import * as d_blogPosts_25 from "../content/blog/2022-03-29-introducing-the-new-stately-roadmap/index.mdx?collection=blogPosts" +import * as d_blogPosts_24 from "../content/blog/2022-04-05-building-a-video-player/index.mdx?collection=blogPosts" +import * as d_blogPosts_23 from "../content/blog/2022-03-23-stately-changelog-1/index.mdx?collection=blogPosts" +import * as d_blogPosts_22 from "../content/blog/2022-03-28-stately-is-hiring/index.mdx?collection=blogPosts" +import * as d_blogPosts_21 from "../content/blog/2022-01-27-introducing-typegen/index.mdx?collection=blogPosts" +import * as d_blogPosts_20 from "../content/blog/2022-03-15-introducing-the-new-stately-homepage/index.mdx?collection=blogPosts" +import * as d_blogPosts_19 from "../content/blog/2022-03-11-xstate-vscode-extension-now-available-on-the-open-vsx-registry/index.mdx?collection=blogPosts" +import * as d_blogPosts_18 from "../content/blog/2022-02-14-modelling-101-how-to-build-a-statechart-from-scratch/index.mdx?collection=blogPosts" +import * as d_blogPosts_17 from "../content/blog/2022-03-03-introducing-the-xstate-cli/index.mdx?collection=blogPosts" +import * as d_blogPosts_16 from "../content/blog/2021-10-11-convince-teammates/index.mdx?collection=blogPosts" +import * as d_blogPosts_15 from "../content/blog/2021-12-14-what-are-the-biggest-benefits-youve-had-from-using-state-machines/index.mdx?collection=blogPosts" +import * as d_blogPosts_14 from "../content/blog/2021-10-02-intro-fsm-sc/index.mdx?collection=blogPosts" +import * as d_blogPosts_13 from "../content/blog/2021-07-28-usestate-vs-usereducer-vs-xstate-part-1-modals/index.mdx?collection=blogPosts" +import * as d_blogPosts_12 from "../content/blog/2021-05-13-why-i-love-invoked-callbacks/index.mdx?collection=blogPosts" +import * as d_blogPosts_11 from "../content/blog/2021-05-27-global-state-xstate-react/index.mdx?collection=blogPosts" +import * as d_blogPosts_10 from "../content/blog/2021-04-30-should-this-be-an-action-or-a-service/index.mdx?collection=blogPosts" +import * as d_blogPosts_9 from "../content/blog/2021-04-29-should-this-be-a-state-or-in-context/index.mdx?collection=blogPosts" +import * as d_blogPosts_8 from "../content/blog/2021-04-28-whats-the-difference-between-machine-and-createmachine/index.mdx?collection=blogPosts" +import * as d_blogPosts_7 from "../content/blog/2021-01-20-you-dont-need-a-library-for-state-machines/index.mdx?collection=blogPosts" +import * as d_blogPosts_6 from "../content/blog/2021-01-11-just-use-props-an-opinionated-guide-to-react-and-xstate/index.mdx?collection=blogPosts" +import * as d_blogPosts_5 from "../content/blog/2020-07-27-state-machines-how-to-stop-making-horcruxes-in-your-code/index.mdx?collection=blogPosts" +import * as d_blogPosts_4 from "../content/blog/2020-05-27-state-management-bad-bolean-good-boolean/index.mdx?collection=blogPosts" +import * as d_blogPosts_3 from "../content/blog/2020-05-22-redux-is-half-a-pattern-2-2/index.mdx?collection=blogPosts" +import * as d_blogPosts_2 from "../content/blog/2020-01-20-redux-is-half-a-pattern-1-2/index.mdx?collection=blogPosts" +import * as d_blogPosts_1 from "../content/blog/2019-12-09-xstate-version-47-and-the-future/index.mdx?collection=blogPosts" +import * as d_blogPosts_0 from "../content/blog/2019-11-13-no-disabling-a-button-is-not-app-logic/index.mdx?collection=blogPosts" +import { _runtime } from "fumadocs-mdx/runtime/next" +import * as _source from "../source.config" +export const blogPosts = _runtime.doc([{ info: {"path":"2019-11-13-no-disabling-a-button-is-not-app-logic/index.mdx","fullPath":"content/blog/2019-11-13-no-disabling-a-button-is-not-app-logic/index.mdx"}, data: d_blogPosts_0 }, { info: {"path":"2019-12-09-xstate-version-47-and-the-future/index.mdx","fullPath":"content/blog/2019-12-09-xstate-version-47-and-the-future/index.mdx"}, data: d_blogPosts_1 }, { info: {"path":"2020-01-20-redux-is-half-a-pattern-1-2/index.mdx","fullPath":"content/blog/2020-01-20-redux-is-half-a-pattern-1-2/index.mdx"}, data: d_blogPosts_2 }, { info: {"path":"2020-05-22-redux-is-half-a-pattern-2-2/index.mdx","fullPath":"content/blog/2020-05-22-redux-is-half-a-pattern-2-2/index.mdx"}, data: d_blogPosts_3 }, { info: {"path":"2020-05-27-state-management-bad-bolean-good-boolean/index.mdx","fullPath":"content/blog/2020-05-27-state-management-bad-bolean-good-boolean/index.mdx"}, data: d_blogPosts_4 }, { info: {"path":"2020-07-27-state-machines-how-to-stop-making-horcruxes-in-your-code/index.mdx","fullPath":"content/blog/2020-07-27-state-machines-how-to-stop-making-horcruxes-in-your-code/index.mdx"}, data: d_blogPosts_5 }, { info: {"path":"2021-01-11-just-use-props-an-opinionated-guide-to-react-and-xstate/index.mdx","fullPath":"content/blog/2021-01-11-just-use-props-an-opinionated-guide-to-react-and-xstate/index.mdx"}, data: d_blogPosts_6 }, { info: {"path":"2021-01-20-you-dont-need-a-library-for-state-machines/index.mdx","fullPath":"content/blog/2021-01-20-you-dont-need-a-library-for-state-machines/index.mdx"}, data: d_blogPosts_7 }, { info: {"path":"2021-04-28-whats-the-difference-between-machine-and-createmachine/index.mdx","fullPath":"content/blog/2021-04-28-whats-the-difference-between-machine-and-createmachine/index.mdx"}, data: d_blogPosts_8 }, { info: {"path":"2021-04-29-should-this-be-a-state-or-in-context/index.mdx","fullPath":"content/blog/2021-04-29-should-this-be-a-state-or-in-context/index.mdx"}, data: d_blogPosts_9 }, { info: {"path":"2021-04-30-should-this-be-an-action-or-a-service/index.mdx","fullPath":"content/blog/2021-04-30-should-this-be-an-action-or-a-service/index.mdx"}, data: d_blogPosts_10 }, { info: {"path":"2021-05-27-global-state-xstate-react/index.mdx","fullPath":"content/blog/2021-05-27-global-state-xstate-react/index.mdx"}, data: d_blogPosts_11 }, { info: {"path":"2021-05-13-why-i-love-invoked-callbacks/index.mdx","fullPath":"content/blog/2021-05-13-why-i-love-invoked-callbacks/index.mdx"}, data: d_blogPosts_12 }, { info: {"path":"2021-07-28-usestate-vs-usereducer-vs-xstate-part-1-modals/index.mdx","fullPath":"content/blog/2021-07-28-usestate-vs-usereducer-vs-xstate-part-1-modals/index.mdx"}, data: d_blogPosts_13 }, { info: {"path":"2021-10-02-intro-fsm-sc/index.mdx","fullPath":"content/blog/2021-10-02-intro-fsm-sc/index.mdx"}, data: d_blogPosts_14 }, { info: {"path":"2021-12-14-what-are-the-biggest-benefits-youve-had-from-using-state-machines/index.mdx","fullPath":"content/blog/2021-12-14-what-are-the-biggest-benefits-youve-had-from-using-state-machines/index.mdx"}, data: d_blogPosts_15 }, { info: {"path":"2021-10-11-convince-teammates/index.mdx","fullPath":"content/blog/2021-10-11-convince-teammates/index.mdx"}, data: d_blogPosts_16 }, { info: {"path":"2022-03-03-introducing-the-xstate-cli/index.mdx","fullPath":"content/blog/2022-03-03-introducing-the-xstate-cli/index.mdx"}, data: d_blogPosts_17 }, { info: {"path":"2022-02-14-modelling-101-how-to-build-a-statechart-from-scratch/index.mdx","fullPath":"content/blog/2022-02-14-modelling-101-how-to-build-a-statechart-from-scratch/index.mdx"}, data: d_blogPosts_18 }, { info: {"path":"2022-03-11-xstate-vscode-extension-now-available-on-the-open-vsx-registry/index.mdx","fullPath":"content/blog/2022-03-11-xstate-vscode-extension-now-available-on-the-open-vsx-registry/index.mdx"}, data: d_blogPosts_19 }, { info: {"path":"2022-03-15-introducing-the-new-stately-homepage/index.mdx","fullPath":"content/blog/2022-03-15-introducing-the-new-stately-homepage/index.mdx"}, data: d_blogPosts_20 }, { info: {"path":"2022-01-27-introducing-typegen/index.mdx","fullPath":"content/blog/2022-01-27-introducing-typegen/index.mdx"}, data: d_blogPosts_21 }, { info: {"path":"2022-03-28-stately-is-hiring/index.mdx","fullPath":"content/blog/2022-03-28-stately-is-hiring/index.mdx"}, data: d_blogPosts_22 }, { info: {"path":"2022-03-23-stately-changelog-1/index.mdx","fullPath":"content/blog/2022-03-23-stately-changelog-1/index.mdx"}, data: d_blogPosts_23 }, { info: {"path":"2022-04-05-building-a-video-player/index.mdx","fullPath":"content/blog/2022-04-05-building-a-video-player/index.mdx"}, data: d_blogPosts_24 }, { info: {"path":"2022-03-29-introducing-the-new-stately-roadmap/index.mdx","fullPath":"content/blog/2022-03-29-introducing-the-new-stately-roadmap/index.mdx"}, data: d_blogPosts_25 }, { info: {"path":"2022-05-03-whats-new-may-2022/index.mdx","fullPath":"content/blog/2022-05-03-whats-new-may-2022/index.mdx"}, data: d_blogPosts_26 }, { info: {"path":"2022-06-20-what-is-xstate-used-for/index.mdx","fullPath":"content/blog/2022-06-20-what-is-xstate-used-for/index.mdx"}, data: d_blogPosts_27 }, { info: {"path":"2022-06-13-nesting-typegen-files/index.mdx","fullPath":"content/blog/2022-06-13-nesting-typegen-files/index.mdx"}, data: d_blogPosts_28 }, { info: {"path":"2022-06-07-whats-new-june-2022/index.mdx","fullPath":"content/blog/2022-06-07-whats-new-june-2022/index.mdx"}, data: d_blogPosts_29 }, { info: {"path":"2022-07-06-whats-new-july-2022/index.mdx","fullPath":"content/blog/2022-07-06-whats-new-july-2022/index.mdx"}, data: d_blogPosts_30 }, { info: {"path":"2022-08-03-whats-new-august-2022/index.mdx","fullPath":"content/blog/2022-08-03-whats-new-august-2022/index.mdx"}, data: d_blogPosts_31 }, { info: {"path":"2022-07-18-just-use-hooks-xstate-in-react-components/index.mdx","fullPath":"content/blog/2022-07-18-just-use-hooks-xstate-in-react-components/index.mdx"}, data: d_blogPosts_32 }, { info: {"path":"2022-08-10-get-started-with-xstate-using-xsm-snippet/index.mdx","fullPath":"content/blog/2022-08-10-get-started-with-xstate-using-xsm-snippet/index.mdx"}, data: d_blogPosts_33 }, { info: {"path":"2022-08-17-goodbye-use-effect-at-react-next/index.mdx","fullPath":"content/blog/2022-08-17-goodbye-use-effect-at-react-next/index.mdx"}, data: d_blogPosts_34 }, { info: {"path":"2022-08-23-building-a-resizable-panel/index.mdx","fullPath":"content/blog/2022-08-23-building-a-resizable-panel/index.mdx"}, data: d_blogPosts_35 }, { info: {"path":"2022-09-14-whats-new-september-2022/index.mdx","fullPath":"content/blog/2022-09-14-whats-new-september-2022/index.mdx"}, data: d_blogPosts_36 }, { info: {"path":"2022-08-31-building-a-resizable-panel/index.mdx","fullPath":"content/blog/2022-08-31-building-a-resizable-panel/index.mdx"}, data: d_blogPosts_37 }, { info: {"path":"2022-10-18-stately-studio-1-0/index.mdx","fullPath":"content/blog/2022-10-18-stately-studio-1-0/index.mdx"}, data: d_blogPosts_38 }, { info: {"path":"2022-10-27-studio-tutorials/index.mdx","fullPath":"content/blog/2022-10-27-studio-tutorials/index.mdx"}, data: d_blogPosts_39 }, { info: {"path":"2022-11-22-studio-update/index.mdx","fullPath":"content/blog/2022-11-22-studio-update/index.mdx"}, data: d_blogPosts_40 }, { info: {"path":"2022-11-29-import-from-code/index.mdx","fullPath":"content/blog/2022-11-29-import-from-code/index.mdx"}, data: d_blogPosts_41 }, { info: {"path":"2022-12-13-new-in-the-studio-machine-disaster-recovery/index.mdx","fullPath":"content/blog/2022-12-13-new-in-the-studio-machine-disaster-recovery/index.mdx"}, data: d_blogPosts_42 }, { info: {"path":"2022-2-6-stately-editor-public-beta/index.mdx","fullPath":"content/blog/2022-2-6-stately-editor-public-beta/index.mdx"}, data: d_blogPosts_43 }, { info: {"path":"2023-01-19-introducing-the-stately-docs/index.mdx","fullPath":"content/blog/2023-01-19-introducing-the-stately-docs/index.mdx"}, data: d_blogPosts_44 }, { info: {"path":"2023-01-20-whats-new-in-2023/index.mdx","fullPath":"content/blog/2023-01-20-whats-new-in-2023/index.mdx"}, data: d_blogPosts_45 }, { info: {"path":"2023-02-06-github-import-machines/index.mdx","fullPath":"content/blog/2023-02-06-github-import-machines/index.mdx"}, data: d_blogPosts_46 }, { info: {"path":"2023-04-03-book-a-demo/index.mdx","fullPath":"content/blog/2023-04-03-book-a-demo/index.mdx"}, data: d_blogPosts_47 }, { info: {"path":"2023-03-09-import-all-machines-from-github-repo/index.mdx","fullPath":"content/blog/2023-03-09-import-all-machines-from-github-repo/index.mdx"}, data: d_blogPosts_48 }, { info: {"path":"2023-04-21-embed-url/index.mdx","fullPath":"content/blog/2023-04-21-embed-url/index.mdx"}, data: d_blogPosts_49 }, { info: {"path":"2023-04-28-new-default-machine/index.mdx","fullPath":"content/blog/2023-04-28-new-default-machine/index.mdx"}, data: d_blogPosts_50 }, { info: {"path":"2023-05-04-everything-new-since-stately-studio-1-0/index.mdx","fullPath":"content/blog/2023-05-04-everything-new-since-stately-studio-1-0/index.mdx"}, data: d_blogPosts_51 }, { info: {"path":"2023-05-12-office-hours-64/index.mdx","fullPath":"content/blog/2023-05-12-office-hours-64/index.mdx"}, data: d_blogPosts_52 }, { info: {"path":"2023-05-03-introducing-state-new/index.mdx","fullPath":"content/blog/2023-05-03-introducing-state-new/index.mdx"}, data: d_blogPosts_53 }, { info: {"path":"2023-05-02-track-changes-as-you-work-with-version-history/index.mdx","fullPath":"content/blog/2023-05-02-track-changes-as-you-work-with-version-history/index.mdx"}, data: d_blogPosts_54 }, { info: {"path":"2023-05-16-stately-streams/index.mdx","fullPath":"content/blog/2023-05-16-stately-streams/index.mdx"}, data: d_blogPosts_55 }, { info: {"path":"2023-05-18-explain-your-machines-with-annotations/index.mdx","fullPath":"content/blog/2023-05-18-explain-your-machines-with-annotations/index.mdx"}, data: d_blogPosts_56 }, { info: {"path":"2023-05-17-stately-studio-minor-improvements/index.mdx","fullPath":"content/blog/2023-05-17-stately-studio-minor-improvements/index.mdx"}, data: d_blogPosts_57 }, { info: {"path":"2023-05-26-stately-studio-minor-improvements/index.mdx","fullPath":"content/blog/2023-05-26-stately-studio-minor-improvements/index.mdx"}, data: d_blogPosts_58 }, { info: {"path":"2023-05-25-announcing-xstate-v5-beta/index.mdx","fullPath":"content/blog/2023-05-25-announcing-xstate-v5-beta/index.mdx"}, data: d_blogPosts_59 }, { info: {"path":"2023-05-19-context-aware-search/index.mdx","fullPath":"content/blog/2023-05-19-context-aware-search/index.mdx"}, data: d_blogPosts_60 }, { info: {"path":"2023-06-14-supercharge-the-canvas/index.mdx","fullPath":"content/blog/2023-06-14-supercharge-the-canvas/index.mdx"}, data: d_blogPosts_61 }, { info: {"path":"2023-07-05-webinar-intro-to-stately-studio/index.mdx","fullPath":"content/blog/2023-07-05-webinar-intro-to-stately-studio/index.mdx"}, data: d_blogPosts_62 }, { info: {"path":"2023-06-14-stately-studio-minor-improvements/index.mdx","fullPath":"content/blog/2023-06-14-stately-studio-minor-improvements/index.mdx"}, data: d_blogPosts_63 }, { info: {"path":"2023-07-18-stately-studio-minor-improvements/index.mdx","fullPath":"content/blog/2023-07-18-stately-studio-minor-improvements/index.mdx"}, data: d_blogPosts_64 }, { info: {"path":"2023-06-20-serverside-workflow-examples/index.mdx","fullPath":"content/blog/2023-06-20-serverside-workflow-examples/index.mdx"}, data: d_blogPosts_65 }, { info: {"path":"2023-07-20-export-to-mermaid/index.mdx","fullPath":"content/blog/2023-07-20-export-to-mermaid/index.mdx"}, data: d_blogPosts_66 }, { info: {"path":"2023-07-26-office-hours-68/index.mdx","fullPath":"content/blog/2023-07-26-office-hours-68/index.mdx"}, data: d_blogPosts_67 }, { info: {"path":"2023-07-24-improving-your-flows-with-color/index.mdx","fullPath":"content/blog/2023-07-24-improving-your-flows-with-color/index.mdx"}, data: d_blogPosts_68 }, { info: {"path":"2023-07-26-stately-minor-improvements/index.mdx","fullPath":"content/blog/2023-07-26-stately-minor-improvements/index.mdx"}, data: d_blogPosts_69 }, { info: {"path":"2023-08-04-markdown-in-annotations/index.mdx","fullPath":"content/blog/2023-08-04-markdown-in-annotations/index.mdx"}, data: d_blogPosts_70 }, { info: {"path":"2023-08-10-all-the-other-improvements/index.mdx","fullPath":"content/blog/2023-08-10-all-the-other-improvements/index.mdx"}, data: d_blogPosts_71 }, { info: {"path":"2023-08-10-new-editor-videos/index.mdx","fullPath":"content/blog/2023-08-10-new-editor-videos/index.mdx"}, data: d_blogPosts_72 }, { info: {"path":"2023-08-17-latest-live-streams-from-stately/index.mdx","fullPath":"content/blog/2023-08-17-latest-live-streams-from-stately/index.mdx"}, data: d_blogPosts_73 }, { info: {"path":"2023-08-17-export-descriptions-and-meta-fields/index.mdx","fullPath":"content/blog/2023-08-17-export-descriptions-and-meta-fields/index.mdx"}, data: d_blogPosts_74 }, { info: {"path":"2023-08-23-fixes-and-improvements/index.mdx","fullPath":"content/blog/2023-08-23-fixes-and-improvements/index.mdx"}, data: d_blogPosts_75 }, { info: {"path":"2023-09-06-fixes-and-improvements/index.mdx","fullPath":"content/blog/2023-09-06-fixes-and-improvements/index.mdx"}, data: d_blogPosts_76 }, { info: {"path":"2023-09-06-generating-flows/index.mdx","fullPath":"content/blog/2023-09-06-generating-flows/index.mdx"}, data: d_blogPosts_77 }, { info: {"path":"2023-09-01-lock-machines/index.mdx","fullPath":"content/blog/2023-09-01-lock-machines/index.mdx"}, data: d_blogPosts_78 }, { info: {"path":"2023-09-01-generate-flow/index.mdx","fullPath":"content/blog/2023-09-01-generate-flow/index.mdx"}, data: d_blogPosts_79 }, { info: {"path":"2023-09-21-context-schema-and-export-to-external-editors/index.mdx","fullPath":"content/blog/2023-09-21-context-schema-and-export-to-external-editors/index.mdx"}, data: d_blogPosts_80 }, { info: {"path":"2023-09-15-event-schemas-viewer-role/index.mdx","fullPath":"content/blog/2023-09-15-event-schemas-viewer-role/index.mdx"}, data: d_blogPosts_81 }, { info: {"path":"2023-1-27-making-state-machines-global-in-react/index.mdx","fullPath":"content/blog/2023-1-27-making-state-machines-global-in-react/index.mdx"}, data: d_blogPosts_82 }, { info: {"path":"2023-10-02-persisting-state/index.mdx","fullPath":"content/blog/2023-10-02-persisting-state/index.mdx"}, data: d_blogPosts_83 }, { info: {"path":"2023-10-02-what-is-a-state-machine/index.mdx","fullPath":"content/blog/2023-10-02-what-is-a-state-machine/index.mdx"}, data: d_blogPosts_84 }, { info: {"path":"2023-11-03-generate-test-paths-and-create-machines-faster/index.mdx","fullPath":"content/blog/2023-11-03-generate-test-paths-and-create-machines-faster/index.mdx"}, data: d_blogPosts_85 }, { info: {"path":"2023-11-20-stately-studio-2-0/index.mdx","fullPath":"content/blog/2023-11-20-stately-studio-2-0/index.mdx"}, data: d_blogPosts_86 }, { info: {"path":"2023-11-13-introducing-stately-sky/index.mdx","fullPath":"content/blog/2023-11-13-introducing-stately-sky/index.mdx"}, data: d_blogPosts_87 }, { info: {"path":"2023-11-23-stately-studio-2-0-changelog/index.mdx","fullPath":"content/blog/2023-11-23-stately-studio-2-0-changelog/index.mdx"}, data: d_blogPosts_88 }, { info: {"path":"2023-12-01-xstate-v5/index.mdx","fullPath":"content/blog/2023-12-01-xstate-v5/index.mdx"}, data: d_blogPosts_89 }, { info: {"path":"2023-11-28-koordinates-and-stately-case-study/index.mdx","fullPath":"content/blog/2023-11-28-koordinates-and-stately-case-study/index.mdx"}, data: d_blogPosts_90 }, { info: {"path":"2023-12-04-fugo-and-stately-case-study/index.mdx","fullPath":"content/blog/2023-12-04-fugo-and-stately-case-study/index.mdx"}, data: d_blogPosts_91 }, { info: {"path":"2023-12-07-tidefi-and-stately-case-study/index.mdx","fullPath":"content/blog/2023-12-07-tidefi-and-stately-case-study/index.mdx"}, data: d_blogPosts_92 }, { info: {"path":"2023-12-29-end-of-year-changelog/index.mdx","fullPath":"content/blog/2023-12-29-end-of-year-changelog/index.mdx"}, data: d_blogPosts_93 }, { info: {"path":"2023-5-30-what-is-the-actor-model-and-when-should-i-use-it/index.mdx","fullPath":"content/blog/2023-5-30-what-is-the-actor-model-and-when-should-i-use-it/index.mdx"}, data: d_blogPosts_94 }, { info: {"path":"2024-01-02-office-hours/index.mdx","fullPath":"content/blog/2024-01-02-office-hours/index.mdx"}, data: d_blogPosts_95 }, { info: {"path":"2024-01-05-office-hours/index.mdx","fullPath":"content/blog/2024-01-05-office-hours/index.mdx"}, data: d_blogPosts_96 }, { info: {"path":"2024-01-03-learn-stately/index.mdx","fullPath":"content/blog/2024-01-03-learn-stately/index.mdx"}, data: d_blogPosts_97 }, { info: {"path":"2024-01-08-a-look-back-at-2023/index.mdx","fullPath":"content/blog/2024-01-08-a-look-back-at-2023/index.mdx"}, data: d_blogPosts_98 }, { info: {"path":"2023-09-15-teams-feature-overview/index.mdx","fullPath":"content/blog/2023-09-15-teams-feature-overview/index.mdx"}, data: d_blogPosts_99 }, { info: {"path":"2024-01-09-introducing-bidirectional-github-sync/index.mdx","fullPath":"content/blog/2024-01-09-introducing-bidirectional-github-sync/index.mdx"}, data: d_blogPosts_100 }, { info: {"path":"2024-01-11-building-backend-workflows/index.mdx","fullPath":"content/blog/2024-01-11-building-backend-workflows/index.mdx"}, data: d_blogPosts_101 }, { info: {"path":"2024-01-09-introducing-sources/index.mdx","fullPath":"content/blog/2024-01-09-introducing-sources/index.mdx"}, data: d_blogPosts_102 }, { info: {"path":"2024-01-12-xstate-exploring-actors/index.mdx","fullPath":"content/blog/2024-01-12-xstate-exploring-actors/index.mdx"}, data: d_blogPosts_103 }, { info: {"path":"2024-01-15-introducing-stately-inspector/index.mdx","fullPath":"content/blog/2024-01-15-introducing-stately-inspector/index.mdx"}, data: d_blogPosts_104 }, { info: {"path":"2024-01-19-changelog/index.mdx","fullPath":"content/blog/2024-01-19-changelog/index.mdx"}, data: d_blogPosts_105 }, { info: {"path":"2024-01-19-office-hours/index.mdx","fullPath":"content/blog/2024-01-19-office-hours/index.mdx"}, data: d_blogPosts_106 }, { info: {"path":"2024-01-23-state-machines-whats-in-a-name/index.mdx","fullPath":"content/blog/2024-01-23-state-machines-whats-in-a-name/index.mdx"}, data: d_blogPosts_107 }, { info: {"path":"2024-01-24-backend-workflows-credit-checking/index.mdx","fullPath":"content/blog/2024-01-24-backend-workflows-credit-checking/index.mdx"}, data: d_blogPosts_108 }, { info: {"path":"2024-01-30-changelog/index.mdx","fullPath":"content/blog/2024-01-30-changelog/index.mdx"}, data: d_blogPosts_109 }, { info: {"path":"2024-01-24-embed-figma/index.mdx","fullPath":"content/blog/2024-01-24-embed-figma/index.mdx"}, data: d_blogPosts_110 }, { info: {"path":"2024-02-02-migrating-machines-to-xstate-v5/index.mdx","fullPath":"content/blog/2024-02-02-migrating-machines-to-xstate-v5/index.mdx"}, data: d_blogPosts_111 }, { info: {"path":"2024-02-07-single-file-prs/index.mdx","fullPath":"content/blog/2024-02-07-single-file-prs/index.mdx"}, data: d_blogPosts_112 }, { info: {"path":"2024-01-11-changelog/index.mdx","fullPath":"content/blog/2024-01-11-changelog/index.mdx"}, data: d_blogPosts_113 }, { info: {"path":"2024-02-12-xstate-react-global-state/index.mdx","fullPath":"content/blog/2024-02-12-xstate-react-global-state/index.mdx"}, data: d_blogPosts_114 }, { info: {"path":"2024-02-16-office-hours/index.mdx","fullPath":"content/blog/2024-02-16-office-hours/index.mdx"}, data: d_blogPosts_115 }, { info: {"path":"2024-02-16-changelog-week-7/index.mdx","fullPath":"content/blog/2024-02-16-changelog-week-7/index.mdx"}, data: d_blogPosts_116 }, { info: {"path":"2024-04-10-xstate-store/index.mdx","fullPath":"content/blog/2024-04-10-xstate-store/index.mdx"}, data: d_blogPosts_117 }, { info: {"path":"2024-11-12-webinargeek-and-stately-case-study/index.mdx","fullPath":"content/blog/2024-11-12-webinargeek-and-stately-case-study/index.mdx"}, data: d_blogPosts_118 }, { info: {"path":"2024-07-29-claw-game-state-machine/index.mdx","fullPath":"content/blog/2024-07-29-claw-game-state-machine/index.mdx"}, data: d_blogPosts_119 }, { info: {"path":"2024-03-21-xstate-store-v3/index.mdx","fullPath":"content/blog/2024-03-21-xstate-store-v3/index.mdx"}, data: d_blogPosts_120 }]); +export const docs = _runtime.docs([{ info: {"path":"actions.mdx","fullPath":"content/docs/actions.mdx"}, data: d_docs_0 }, { info: {"path":"actor-model.mdx","fullPath":"content/docs/actor-model.mdx"}, data: d_docs_1 }, { info: {"path":"actors.mdx","fullPath":"content/docs/actors.mdx"}, data: d_docs_2 }, { info: {"path":"annotations.mdx","fullPath":"content/docs/annotations.mdx"}, data: d_docs_3 }, { info: {"path":"assets.mdx","fullPath":"content/docs/assets.mdx"}, data: d_docs_4 }, { info: {"path":"autolayout.mdx","fullPath":"content/docs/autolayout.mdx"}, data: d_docs_5 }, { info: {"path":"callback-actors.mdx","fullPath":"content/docs/callback-actors.mdx"}, data: d_docs_6 }, { info: {"path":"canvas-view-controls.mdx","fullPath":"content/docs/canvas-view-controls.mdx"}, data: d_docs_7 }, { info: {"path":"cheatsheet.mdx","fullPath":"content/docs/cheatsheet.mdx"}, data: d_docs_8 }, { info: {"path":"colors.mdx","fullPath":"content/docs/colors.mdx"}, data: d_docs_9 }, { info: {"path":"context.mdx","fullPath":"content/docs/context.mdx"}, data: d_docs_10 }, { info: {"path":"delayed-transitions.mdx","fullPath":"content/docs/delayed-transitions.mdx"}, data: d_docs_11 }, { info: {"path":"descriptions.mdx","fullPath":"content/docs/descriptions.mdx"}, data: d_docs_12 }, { info: {"path":"design-mode.mdx","fullPath":"content/docs/design-mode.mdx"}, data: d_docs_13 }, { info: {"path":"developer-tools.mdx","fullPath":"content/docs/developer-tools.mdx"}, data: d_docs_14 }, { info: {"path":"discover.mdx","fullPath":"content/docs/discover.mdx"}, data: d_docs_15 }, { info: {"path":"editor-actions-and-actors.mdx","fullPath":"content/docs/editor-actions-and-actors.mdx"}, data: d_docs_16 }, { info: {"path":"editor-context-and-meta.mdx","fullPath":"content/docs/editor-context-and-meta.mdx"}, data: d_docs_17 }, { info: {"path":"editor-states-and-transitions.mdx","fullPath":"content/docs/editor-states-and-transitions.mdx"}, data: d_docs_18 }, { info: {"path":"editor-tags.mdx","fullPath":"content/docs/editor-tags.mdx"}, data: d_docs_19 }, { info: {"path":"embed.mdx","fullPath":"content/docs/embed.mdx"}, data: d_docs_20 }, { info: {"path":"event-emitter.mdx","fullPath":"content/docs/event-emitter.mdx"}, data: d_docs_21 }, { info: {"path":"eventless-transitions.mdx","fullPath":"content/docs/eventless-transitions.mdx"}, data: d_docs_22 }, { info: {"path":"examples.mdx","fullPath":"content/docs/examples.mdx"}, data: d_docs_23 }, { info: {"path":"export-as-code.mdx","fullPath":"content/docs/export-as-code.mdx"}, data: d_docs_24 }, { info: {"path":"figma.mdx","fullPath":"content/docs/figma.mdx"}, data: d_docs_25 }, { info: {"path":"final-states.mdx","fullPath":"content/docs/final-states.mdx"}, data: d_docs_26 }, { info: {"path":"finite-states.mdx","fullPath":"content/docs/finite-states.mdx"}, data: d_docs_27 }, { info: {"path":"function-actors.mdx","fullPath":"content/docs/function-actors.mdx"}, data: d_docs_28 }, { info: {"path":"generate-flow.mdx","fullPath":"content/docs/generate-flow.mdx"}, data: d_docs_29 }, { info: {"path":"generate-react.mdx","fullPath":"content/docs/generate-react.mdx"}, data: d_docs_30 }, { info: {"path":"generate-test-paths.mdx","fullPath":"content/docs/generate-test-paths.mdx"}, data: d_docs_31 }, { info: {"path":"glossary.mdx","fullPath":"content/docs/glossary.mdx"}, data: d_docs_32 }, { info: {"path":"guards.mdx","fullPath":"content/docs/guards.mdx"}, data: d_docs_33 }, { info: {"path":"history-states.mdx","fullPath":"content/docs/history-states.mdx"}, data: d_docs_34 }, { info: {"path":"image.mdx","fullPath":"content/docs/image.mdx"}, data: d_docs_35 }, { info: {"path":"immer.mdx","fullPath":"content/docs/immer.mdx"}, data: d_docs_36 }, { info: {"path":"import-from-code.mdx","fullPath":"content/docs/import-from-code.mdx"}, data: d_docs_37 }, { info: {"path":"import-from-github.mdx","fullPath":"content/docs/import-from-github.mdx"}, data: d_docs_38 }, { info: {"path":"index.mdx","fullPath":"content/docs/index.mdx"}, data: d_docs_39 }, { info: {"path":"initial-states.mdx","fullPath":"content/docs/initial-states.mdx"}, data: d_docs_40 }, { info: {"path":"input.mdx","fullPath":"content/docs/input.mdx"}, data: d_docs_41 }, { info: {"path":"inspection.mdx","fullPath":"content/docs/inspection.mdx"}, data: d_docs_42 }, { info: {"path":"inspector.mdx","fullPath":"content/docs/inspector.mdx"}, data: d_docs_43 }, { info: {"path":"installation.mdx","fullPath":"content/docs/installation.mdx"}, data: d_docs_44 }, { info: {"path":"invoke.mdx","fullPath":"content/docs/invoke.mdx"}, data: d_docs_45 }, { info: {"path":"keyboard-shortcuts.mdx","fullPath":"content/docs/keyboard-shortcuts.mdx"}, data: d_docs_46 }, { info: {"path":"live-simulation.mdx","fullPath":"content/docs/live-simulation.mdx"}, data: d_docs_47 }, { info: {"path":"lock-machines.mdx","fullPath":"content/docs/lock-machines.mdx"}, data: d_docs_48 }, { info: {"path":"machine-restore.mdx","fullPath":"content/docs/machine-restore.mdx"}, data: d_docs_49 }, { info: {"path":"machines.mdx","fullPath":"content/docs/machines.mdx"}, data: d_docs_50 }, { info: {"path":"migration.mdx","fullPath":"content/docs/migration.mdx"}, data: d_docs_51 }, { info: {"path":"observable-actors.mdx","fullPath":"content/docs/observable-actors.mdx"}, data: d_docs_52 }, { info: {"path":"output.mdx","fullPath":"content/docs/output.mdx"}, data: d_docs_53 }, { info: {"path":"parallel-states.mdx","fullPath":"content/docs/parallel-states.mdx"}, data: d_docs_54 }, { info: {"path":"parent-states.mdx","fullPath":"content/docs/parent-states.mdx"}, data: d_docs_55 }, { info: {"path":"persistence.mdx","fullPath":"content/docs/persistence.mdx"}, data: d_docs_56 }, { info: {"path":"projects.mdx","fullPath":"content/docs/projects.mdx"}, data: d_docs_57 }, { info: {"path":"promise-actors.mdx","fullPath":"content/docs/promise-actors.mdx"}, data: d_docs_58 }, { info: {"path":"pure-transitions.mdx","fullPath":"content/docs/pure-transitions.mdx"}, data: d_docs_59 }, { info: {"path":"quick-start.mdx","fullPath":"content/docs/quick-start.mdx"}, data: d_docs_60 }, { info: {"path":"setup.mdx","fullPath":"content/docs/setup.mdx"}, data: d_docs_61 }, { info: {"path":"sign-up.mdx","fullPath":"content/docs/sign-up.mdx"}, data: d_docs_62 }, { info: {"path":"simulate-mode.mdx","fullPath":"content/docs/simulate-mode.mdx"}, data: d_docs_63 }, { info: {"path":"sources.mdx","fullPath":"content/docs/sources.mdx"}, data: d_docs_64 }, { info: {"path":"spawn.mdx","fullPath":"content/docs/spawn.mdx"}, data: d_docs_65 }, { info: {"path":"state-done-events.mdx","fullPath":"content/docs/state-done-events.mdx"}, data: d_docs_66 }, { info: {"path":"state-machine-actors.mdx","fullPath":"content/docs/state-machine-actors.mdx"}, data: d_docs_67 }, { info: {"path":"state-machines-and-statecharts.mdx","fullPath":"content/docs/state-machines-and-statecharts.mdx"}, data: d_docs_68 }, { info: {"path":"stately-sky-getting-started.mdx","fullPath":"content/docs/stately-sky-getting-started.mdx"}, data: d_docs_69 }, { info: {"path":"states.mdx","fullPath":"content/docs/states.mdx"}, data: d_docs_70 }, { info: {"path":"studio-api.mdx","fullPath":"content/docs/studio-api.mdx"}, data: d_docs_71 }, { info: {"path":"studio-community-plan.mdx","fullPath":"content/docs/studio-community-plan.mdx"}, data: d_docs_72 }, { info: {"path":"studio-enterprise-plan.mdx","fullPath":"content/docs/studio-enterprise-plan.mdx"}, data: d_docs_73 }, { info: {"path":"studio-pro-plan.mdx","fullPath":"content/docs/studio-pro-plan.mdx"}, data: d_docs_74 }, { info: {"path":"studio-team-plan.mdx","fullPath":"content/docs/studio-team-plan.mdx"}, data: d_docs_75 }, { info: {"path":"studio.mdx","fullPath":"content/docs/studio.mdx"}, data: d_docs_76 }, { info: {"path":"system.mdx","fullPath":"content/docs/system.mdx"}, data: d_docs_77 }, { info: {"path":"tags.mdx","fullPath":"content/docs/tags.mdx"}, data: d_docs_78 }, { info: {"path":"teams.mdx","fullPath":"content/docs/teams.mdx"}, data: d_docs_79 }, { info: {"path":"templates.mdx","fullPath":"content/docs/templates.mdx"}, data: d_docs_80 }, { info: {"path":"testing.mdx","fullPath":"content/docs/testing.mdx"}, data: d_docs_81 }, { info: {"path":"transition-actors.mdx","fullPath":"content/docs/transition-actors.mdx"}, data: d_docs_82 }, { info: {"path":"transitions.mdx","fullPath":"content/docs/transitions.mdx"}, data: d_docs_83 }, { info: {"path":"typegen.mdx","fullPath":"content/docs/typegen.mdx"}, data: d_docs_84 }, { info: {"path":"typescript.mdx","fullPath":"content/docs/typescript.mdx"}, data: d_docs_85 }, { info: {"path":"upgrade.mdx","fullPath":"content/docs/upgrade.mdx"}, data: d_docs_86 }, { info: {"path":"url.mdx","fullPath":"content/docs/url.mdx"}, data: d_docs_87 }, { info: {"path":"user-preferences.mdx","fullPath":"content/docs/user-preferences.mdx"}, data: d_docs_88 }, { info: {"path":"versions.mdx","fullPath":"content/docs/versions.mdx"}, data: d_docs_89 }, { info: {"path":"visualizer.mdx","fullPath":"content/docs/visualizer.mdx"}, data: d_docs_90 }, { info: {"path":"xstate-fsm.mdx","fullPath":"content/docs/xstate-fsm.mdx"}, data: d_docs_91 }, { info: {"path":"xstate-graph.mdx","fullPath":"content/docs/xstate-graph.mdx"}, data: d_docs_92 }, { info: {"path":"xstate-immer.mdx","fullPath":"content/docs/xstate-immer.mdx"}, data: d_docs_93 }, { info: {"path":"xstate-react.mdx","fullPath":"content/docs/xstate-react.mdx"}, data: d_docs_94 }, { info: {"path":"xstate-store-v2.mdx","fullPath":"content/docs/xstate-store-v2.mdx"}, data: d_docs_95 }, { info: {"path":"xstate-store.mdx","fullPath":"content/docs/xstate-store.mdx"}, data: d_docs_96 }, { info: {"path":"xstate-svelte.mdx","fullPath":"content/docs/xstate-svelte.mdx"}, data: d_docs_97 }, { info: {"path":"xstate-test.mdx","fullPath":"content/docs/xstate-test.mdx"}, data: d_docs_98 }, { info: {"path":"xstate-vscode-extension.mdx","fullPath":"content/docs/xstate-vscode-extension.mdx"}, data: d_docs_99 }, { info: {"path":"xstate-vue.mdx","fullPath":"content/docs/xstate-vue.mdx"}, data: d_docs_100 }, { info: {"path":"xstate.mdx","fullPath":"content/docs/xstate.mdx"}, data: d_docs_101 }, { info: {"path":"agents/agents.mdx","fullPath":"content/docs/agents/agents.mdx"}, data: d_docs_102 }], [{"info":{"path":"meta.json","fullPath":"content/docs/meta.json"},"data":{"title":"Documentation","pages":["index","get-started","core-concepts","stately-studio","actors","state-machines","agents","guides","packages","developer-tools","glossary"]}}, {"info":{"path":"agents/meta.json","fullPath":"content/docs/agents/meta.json"},"data":{"title":"Agents","pages":["agents"]}}, {"info":{"path":"core-concepts/meta.json","fullPath":"content/docs/core-concepts/meta.json"},"data":{"title":"Core concepts","pages":["state-machines-and-statecharts","actor-model","xstate"]}}, {"info":{"path":"developer-tools/meta.json","fullPath":"content/docs/developer-tools/meta.json"},"data":{"title":"Developer tools","pages":["xstate-vscode-extension","visualizer","inspector","developer-tools"]}}, {"info":{"path":"get-started/meta.json","fullPath":"content/docs/get-started/meta.json"},"data":{"title":"Get started","pages":["quick-start","installation","migration","examples","templates","cheatsheet","typescript"]}}, {"info":{"path":"guides/meta.json","fullPath":"content/docs/guides/meta.json"},"data":{"title":"Guides","pages":["testing","immer"]}}, {"info":{"path":"packages/meta.json","fullPath":"content/docs/packages/meta.json"},"data":{"title":"Packages","pages":["xstate-store","xstate-react","xstate-vue","xstate-svelte","xstate-graph","xstate-test"]}}, {"info":{"path":"stately-studio/meta.json","fullPath":"content/docs/stately-studio/meta.json"},"data":{"title":"Stately Studio","pages":["studio","studio-pro-plan","studio-team-plan","studio-enterprise-plan","studio-community-plan","editor-states-and-transitions","editor-actions-and-actors","design-mode","simulate-mode","code","projects","stately-sky","teams","discover","share","accounts","versions","lock-machines","keyboard-shortcuts","canvas-view-controls","user-preferences","studio-api"]}}, {"info":{"path":"actors/meta.json","fullPath":"content/docs/actors/meta.json"},"data":{"title":"Actors","pages":["actors","state-machine-actors","promise-actors","transition-actors","callback-actors","observable-actors","invoke","spawn","system","inspection"]}}, {"info":{"path":"stately-studio/code/meta.json","fullPath":"content/docs/stately-studio/code/meta.json"},"data":{"title":"Code","pages":["import-from-code","import-from-github","generate-test-paths","sources","export-as-code"]}}, {"info":{"path":"stately-studio/accounts/meta.json","fullPath":"content/docs/stately-studio/accounts/meta.json"},"data":{"title":"Accounts","pages":["sign-up","upgrade"]}}, {"info":{"path":"stately-studio/design-mode/meta.json","fullPath":"content/docs/stately-studio/design-mode/meta.json"},"data":{"title":"Design mode","pages":["design-mode","generate-flow","generate-react","colors","annotations","descriptions","figma","assets","editor-tags","machine-restore","autolayout"]}}, {"info":{"path":"stately-studio/share/meta.json","fullPath":"content/docs/stately-studio/share/meta.json"},"data":{"title":"Share","pages":["embed","image","url"]}}, {"info":{"path":"stately-studio/stately-sky/meta.json","fullPath":"content/docs/stately-studio/stately-sky/meta.json"},"data":{"title":"Stately Sky","pages":["stately-sky-getting-started"]}}, {"info":{"path":"stately-studio/simulate-mode/meta.json","fullPath":"content/docs/stately-studio/simulate-mode/meta.json"},"data":{"title":"Simulate mode","pages":["simulate-mode","live-simulation"]}}]) \ No newline at end of file diff --git a/.source/source.config.mjs b/.source/source.config.mjs new file mode 100644 index 000000000..bcd1f07fb --- /dev/null +++ b/.source/source.config.mjs @@ -0,0 +1,61 @@ +// source.config.ts +import { + defineCollections, + defineConfig, + defineDocs, + frontmatterSchema, + metaSchema +} from "fumadocs-mdx/config"; +import { transformerTwoslash } from "fumadocs-twoslash"; +import { + rehypeCodeDefaultOptions, + remarkImage +} from "fumadocs-core/mdx-plugins"; +import z from "zod"; +var docs = defineDocs({ + docs: { + schema: frontmatterSchema, + postprocess: { + includeProcessedMarkdown: true + } + }, + meta: { + schema: metaSchema + } +}); +var blogPosts = defineCollections({ + type: "doc", + dir: "content/blog", + schema: frontmatterSchema.extend({ + authors: z.array(z.string()), + date: z.iso.date().or(z.date()) + }) +}); +var source_config_default = defineConfig({ + mdxOptions: { + // MDX options + rehypeCodeOptions: { + themes: { + light: "github-light", + dark: "github-dark" + }, + transformers: [ + ...rehypeCodeDefaultOptions.transformers ?? [], + transformerTwoslash() + ] + }, + remarkPlugins: [ + [ + remarkImage, + { + external: false + } + ] + ] + } +}); +export { + blogPosts, + source_config_default as default, + docs +}; diff --git a/README.md b/README.md index 27304d025..70fd7dfd2 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,45 @@ -# Welcome to the Stately docs +# fumadocs -This repo contains the Stately landing page, including our blog and docs for Stately Studio and XState. +This is a Next.js application generated with +[Create Fumadocs](https://github.com/fuma-nama/fumadocs). -The site is built using [Docusaurus 2](https://docusaurus.io/). +Run development server: -We welcome any contributions to the documentation and code base. - -- ✨ [Contribution guide](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md) -- 🖊️ [The Stately Guide to Writing Docs](https://github.com/statelyai/docs/wiki) -- 🙋 [Code of conduct](https://github.com/statelyai/docs/blob/main/CODE_OF_CONDUCT.md) - -## Installation - -``` -$ yarn +```bash +npm run dev +# or +pnpm dev +# or +yarn dev ``` -## Local development +Open http://localhost:3000 with your browser to see the result. -``` -$ yarn dev -``` +## Explore -This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. +In the project, you can see: -### Note on the index page +- `lib/source.ts`: Code for content source adapter, [`loader()`](https://fumadocs.dev/docs/headless/source-api) provides the interface to access your content. +- `lib/layout.shared.tsx`: Shared options for layouts, optional but preferred to keep. -Currently we serve the root landing page from a static file. +| Route | Description | +| ------------------------- | ------------------------------------------------------ | +| `app/(home)` | The route group for your landing page and other pages. | +| `app/docs` | The documentation layout and pages. | +| `app/api/search/route.ts` | The Route Handler for search. | -- During server side rendering (SSR) we use [`/static/index.html`](./static/index.html) -- During client side rendering (CSR) we use [`/static/landing-page/index.html`](./static/landing-page/index.html) +### Fumadocs MDX -## Build +A `source.config.ts` config file has been included, you can customise different options like frontmatter schema. -``` -$ yarn build -``` +Read the [Introduction](https://fumadocs.dev/docs/mdx) for further details. -This command generates static content into the `build` directory. +## Learn More -## Deployment +To learn more about Next.js and Fumadocs, take a look at the following +resources: -The docs are built and deployed when merged into `main`. +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js + features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +- [Fumadocs](https://fumadocs.dev) - learn about Fumadocs diff --git a/app/(home)/layout.tsx b/app/(home)/layout.tsx new file mode 100644 index 000000000..b8b7d1b90 --- /dev/null +++ b/app/(home)/layout.tsx @@ -0,0 +1,77 @@ +import { baseOptions } from '@/lib/layout.shared'; +import type { ReactNode } from 'react'; +import { HomeLayout } from 'fumadocs-ui/layouts/home'; +import { TelescopeIcon } from 'lucide-react'; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + , + }, + { + text: 'Blog', + url: '/blog', + active: 'nested-url', + }, + { + type: 'icon', + text: 'Visit XState GitHub repository', + icon: ( + + + + + ), + url: 'https://github.com/statelyai/xstate', + external: true, + }, + ]} + > + {children} + + ); +} diff --git a/app/(home)/page.tsx b/app/(home)/page.tsx new file mode 100644 index 000000000..71f2f8c1f --- /dev/null +++ b/app/(home)/page.tsx @@ -0,0 +1,714 @@ +'use client'; + +import Link from 'next/link'; +import { + ArrowRight, + Play, + Wand2, + Sparkles, + CheckCircle, + ArrowLeftRight, + FileDown, + Share, + Github, + ShieldCheck, + BookOpen, + ExternalLink, +} from 'lucide-react'; + +export default function HomePage() { + return ( +
+ + + + + + + +
+
+ ); +} + +function Hero() { + return ( +
+ {/* Background gradient */} +
+
+ +
+
+

+ Turn ideas into diagrams and code in minutes. +

+ +

+ From frontend user flows to backend workflows, visually build and + deploy any type of logic with Stately as your source of truth. +

+ +
+ + Try the visual editor + + + Book a demo + +
+
+ + {/* Hero image */} +
+
+
+ This state machine is called Accumulate room readings. Its purpose is to get temperature and humidity readings from IoT sensors and generate a report every hour. +
+
+
+
+ ); +} + +function Companies() { + const companies = [ + { name: 'AWS', src: '/landing-page/assets/aws.svg', width: 65 }, + { name: 'Netflix', src: '/landing-page/assets/netflix.svg', width: 122 }, + { name: 'Lyft', src: '/landing-page/assets/lyft.svg', width: 58 }, + { name: 'Microsoft', src: '/landing-page/assets/microsoft.svg', width: 154 }, + { name: 'Epic Games', src: '/landing-page/assets/epic-games.svg', width: 45 }, + { name: 'Cisco', src: '/landing-page/assets/cisco.svg', width: 74 }, + ]; + + return ( +
+
+
+ {companies.map((company) => ( + {company.name} + ))} +
+
+
+ ); +} + +function DesignSection() { + return ( +
+
+

+ Design how it works with a + visual language for everyone on the team. +

+ +
+
+ +

+ Our drag and drop editor brings together contributors of all + backgrounds. Code, diagrams, documentation, test generation, and + more in one place. No more silos. Always up to date. +

+
+
+ +

+ AIs love helping at each phase with state machines to guide them, + while humans use the visual editor to audit and enhance their + work. +

+
+
+ +
+
+

+ + Create flows with no code required + + . Rapidly prototype or gather requirements without worrying about + technical details. +

+
+
+

+ + Then simulate your design + {' '} + to test and iterate. You can even instantly try out a prototype as + an auto-generated React app. +

+
+
+

+ Get feedback from + your team and clients on how everything is supposed to work. +

+
+
+

+ + Explore community diagrams + {' '} + to inspire your own solutions. Share your work with the community + to get feedback and kudos. +

+
+
+

+ + Generate flows with AI + {' '} + to scaffold behavior, suggest variants, turn up edge cases, and + even write code. +

+
+
+
+
+ ); +} + +function BuildSection() { + return ( +
+
+

+ Build with executable diagrams{' '} + and get the best of text-based and visual tools. +

+ +
+
+

+ + Run diagrams using XState + + , a best-in-class open source library for orchestrating and + managing state in JavaScript and TypeScript apps. No lock-in. +

+
+ + Read XState docs + + + View on Github + +
+
+
+

+ + Use XState on the frontend, backend, or wherever JavaScript runs + + . Integrations are available for React, Vue, Svelte, and other + frameworks. +

+
+
+

+ XState uses event-driven programming, state machines, statecharts, + and the actor model to{' '} + + handle even the most complex logic in predictable, robust, and + visual ways + + . +

+ + Learn more about statecharts + +
+
+ + {/* VS Code image */} +
+ A book lender state machine in VSCode. One panel shows the state machine as a JavaScript object, the other panel shows the same state machine visualized using the XState VSCode extension. +
+ +
+
+ +

+ + Bidirectional updates + {' '} + between code and visualization let you use what makes you most + productive. +

+
+
+ +

+ + Automatically visualize Redux, Zustand, and other code + {' '} + to get the benefits of Stately in your codebase even without + XState. +

+
+
+

+ An IDE extension{' '} + brings the power of Stately into VS Code. +

+ + Download the VS Code extension + +
+
+ + {/* Generate React apps */} +
+
+
+

+ + Generate React apps from diagrams + {' '} + to jumpstart product development. Keep iterating visually with the + help of AI, or dive straight into the code to rapidly extend the + scaffolding with your vision. +

+
+ The room reading state machine visualized in the Stately editor alongside the React app code generated for that app logic. +
+
+ + {/* Generate tests */} +
+
+

+ + Generate tests automatically + {' '} + to keep coverage robust and up-to-date. +

+
+ A test path list of states and events in the Stately editor alongside that path being highlighted on the canvas, and the code generated to implement the tests. +
+ +
+
+ +

+ + Export all of your generated code + {' '} + in Javascript or Typescript. +

+
+
+ +

+ + Connect with Github + {' '} + to sync Stately with your codebase. +

+
+
+ + {/* Inspector */} +
+
+
+

+ + Inspect running apps + {' '} + with Stately Inspector to help test, and debug your logic. +

+

+ + Visualize communication between actors + {' '} + in your running app with sequence diagrams. +

+
+
+ The Stately Inspector view, showing a state machine and a sequence diagram for the pizza ordering process side-by-side. +
+
+
+ ); +} + +function UnderstandSection() { + return ( +
+
+

+ Products evolve. People are busy. +

+

+ Understand and stay aligned{' '} + with Stately as the source of truth. +

+ +
+
+ +

+ + Future proof your code + {' '} + with clear visualizations that are easy to return to and change + later. Even years later. +

+
+
+ +

+ + Living documentation + {' '} + keeps the whole team in sync without extra overhead. +

+
+
+ +
+
+

+ Save versions as + backup and to see the history of your work. +

+
+
+

+ + Export as markdown stories, Mermaid drawings, or JSON documents + {' '} + that can be copied into issues and project documents. +

+
+
+

+ + Generate diagram summaries + {' '} + to get oriented quickly. +

+
+
+
+
+ ); +} + +function Testimonials() { + const column1 = [ + { + quote: + 'Every team where I introduced XState has been more effective at handling state management with complex user interfaces. It fills a gap in the JS ecosystem no other tool did before.', + name: 'Amy Pellegrini', + company: 'Thoughtworks', + avatar: '/landing-page/assets/amy.png', + }, + { + quote: + "We've been using XState for our new payments product. Shout out to the team that is making designing complex front-end flows a dream.", + name: 'Natalie Cuthbert', + company: 'Stitch', + avatar: '/landing-page/assets/natalie.png', + }, + { + quote: + 'XState is a revelation. It makes complex tasks easier to build and debug while also making the code more straightforward and approachable.', + name: 'Patrick Cavit', + company: 'Netflix', + avatar: '/landing-page/assets/patrick.png', + }, + ]; + + const column2 = [ + { + quote: + "XState naturally separates the logic and makes it simple to mock out API calls, so it's easier to test the code and organize it!", + name: 'Presley Pizzo', + company: 'Coder', + avatar: '/landing-page/assets/presley.png', + }, + { + quote: + 'We use XState to implement business workflows as statecharts. The visualizer helps us collaborate more closely with customers, the ability to externalize workflows as JSON configuration makes complex workflow changes surprisingly simple to roll out, and test case generation makes it easier than ever to move forward with confidence. XState makes it all possible!', + name: 'James Tharpe', + company: 'T-Mobile', + avatar: '/landing-page/assets/james.png', + }, + ]; + + const column3 = [ + { + quote: + 'Advantages of XState: Visually clear view of the code flow, code reusability, test coverage, easy to debug/ spot bugs, code scalability & maintenance, and better code design & planning.', + name: 'Maya Shavin', + company: 'Microsoft', + avatar: '/landing-page/assets/maya.png', + }, + { + quote: + 'Thinking and building with XState has been a revolution in how I develop robust business logic. But being able to visualize that in real time, has been a game changer in how I model and communicate any logic!', + name: 'Santi Cros', + company: 'Domestic Data Streamers', + avatar: '/landing-page/assets/santi.png', + }, + ]; + + const TestimonialCard = ({ testimonial }: { testimonial: typeof column1[0] }) => ( +
+
+ {testimonial.name} +
+

+ {testimonial.name} +

+

+ @ {testimonial.company} +

+
+
+

+ {testimonial.quote} +

+
+ ); + + return ( +
+
+

+ Loved by teams +

+ +
+
+ {column1.map((t) => ( + + ))} +
+
+ {column2.map((t) => ( + + ))} +
+
+ {column3.map((t) => ( + + ))} +
+
+
+
+ ); +} + +function CTA() { + return ( +
+
+
+ {/* Background */} +
+ +
+

+ Intelligent logic to transition from design to deployment,{' '} + and back again. +

+
+ + Sign up for free + + + Book a demo + +
+
+
+
+
+ ); +} + +function Footer() { + return ( +
+
+ {/* Newsletter */} + + + {/* Discord */} + +
+ + +
+ ); +} diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts new file mode 100644 index 000000000..9952728f6 --- /dev/null +++ b/app/api/chat/route.ts @@ -0,0 +1,30 @@ +import { ProvideLinksToolSchema } from '../../../lib/inkeep-qa-schema'; +import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; +import { convertToModelMessages, streamText } from 'ai'; + +export const runtime = 'edge'; + +const openai = createOpenAICompatible({ + name: 'inkeep', + apiKey: process.env.INKEEP_API_KEY, + baseURL: 'https://api.inkeep.com/v1', +}); + +export async function POST(req: Request) { + const reqJson = await req.json(); + + const result = streamText({ + model: openai('inkeep-qa-sonnet-4'), + tools: { + provideLinks: { + inputSchema: ProvideLinksToolSchema, + }, + }, + messages: convertToModelMessages(reqJson.messages, { + ignoreIncompleteToolCalls: true, + }), + toolChoice: 'auto', + }); + + return result.toUIMessageStreamResponse(); +} diff --git a/app/api/search/route.ts b/app/api/search/route.ts new file mode 100644 index 000000000..fd4b8684b --- /dev/null +++ b/app/api/search/route.ts @@ -0,0 +1,25 @@ +import { source, blog } from '@/lib/source'; +import { createSearchAPI } from 'fumadocs-core/search/server'; + +export const { GET } = createSearchAPI('advanced', { + // https://docs.orama.com/docs/orama-js/supported-languages + language: 'english', + indexes: [ + ...source.getPages().map((page) => ({ + title: page.data.title, + description: page.data.description, + url: page.url, + id: page.url, + structuredData: page.data.structuredData, + tag: 'docs', + })), + ...blog.getPages().map((page) => ({ + title: page.data.title, + description: page.data.description, + url: page.url, + id: page.url, + structuredData: page.data.structuredData, + tag: 'blog', + })), + ], +}); diff --git a/app/blog/[slug]/page.client.tsx b/app/blog/[slug]/page.client.tsx new file mode 100644 index 000000000..d88f56be3 --- /dev/null +++ b/app/blog/[slug]/page.client.tsx @@ -0,0 +1,24 @@ +'use client'; +import { Check, Share } from 'lucide-react'; +import { cn } from '@/lib/cn'; +import { buttonVariants } from '@/components/ui/button'; +import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button'; + +export function Control({ url }: { url: string }) { + const [isChecked, onCopy] = useCopyButton(() => { + void navigator.clipboard.writeText(`${window.location.origin}${url}`); + }); + + return ( + + ); +} diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx new file mode 100644 index 000000000..85e2a36f8 --- /dev/null +++ b/app/blog/[slug]/page.tsx @@ -0,0 +1,66 @@ +import type { Metadata } from 'next'; +import { notFound } from 'next/navigation'; +import Link from 'next/link'; +import { + DocsBody, + DocsDescription, + DocsPage, + DocsTitle, +} from 'fumadocs-ui/page'; +import { blog } from '@/lib/source'; +import { getMDXComponents } from '@/mdx-components'; +import path from 'node:path'; + +export default async function Page(props: PageProps<'/blog/[slug]'>) { + const params = await props.params; + const page = blog.getPage([params.slug]); + + if (!page) notFound(); + const { body: Mdx, toc } = page.data; + + return ( + + + ← Back to Blog + + {page.data.title} + {page.data.description} +
+ {page.data.authors.join(', ')} + + + {new Date( + page.data.date ?? path.basename(page.path, path.extname(page.path)), + ).toDateString()} + +
+ + + +
+ ); +} + +export async function generateMetadata( + props: PageProps<'/blog/[slug]'>, +): Promise { + const params = await props.params; + const page = blog.getPage([params.slug]); + + if (!page) notFound(); + + return { + title: page.data.title, + description: + page.data.description ?? 'The library for building documentation sites', + }; +} + +export function generateStaticParams(): { slug: string }[] { + return blog.getPages().map((page) => ({ + slug: page.slugs[0], + })); +} diff --git a/app/blog/layout.tsx b/app/blog/layout.tsx new file mode 100644 index 000000000..8e9ec7226 --- /dev/null +++ b/app/blog/layout.tsx @@ -0,0 +1,11 @@ +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import { baseOptions } from '@/lib/layout.shared'; +import { source } from '@/lib/source'; + +export default function Layout({ children }: LayoutProps<'/docs'>) { + return ( + + {children} + + ); +} diff --git a/app/blog/page.tsx b/app/blog/page.tsx new file mode 100644 index 000000000..6aa9f3910 --- /dev/null +++ b/app/blog/page.tsx @@ -0,0 +1,36 @@ +import Link from 'next/link'; +import { DocsBody, DocsPage, DocsTitle } from 'fumadocs-ui/page'; +import { blog } from '@/lib/source'; + +export default function Page() { + const posts = [...blog.getPages()].sort( + (a, b) => + new Date(b.data.date).getTime() - new Date(a.data.date).getTime(), + ); + + return ( + + Blog + +
    + {posts.map((post) => ( +
  • + +

    {post.data.title}

    +

    + {post.data.description} +

    +

    + {new Date(post.data.date).toDateString()} +

    + +
  • + ))} +
+
+
+ ); +} diff --git a/app/docs/[[...slug]]/page.tsx b/app/docs/[[...slug]]/page.tsx new file mode 100644 index 000000000..357971e55 --- /dev/null +++ b/app/docs/[[...slug]]/page.tsx @@ -0,0 +1,62 @@ +import { getPageImage, source } from '@/lib/source'; +import { + DocsBody, + DocsDescription, + DocsPage, + DocsTitle, +} from 'fumadocs-ui/page'; +import { notFound } from 'next/navigation'; +import { getMDXComponents } from '@/mdx-components'; +import type { Metadata } from 'next'; +import { createRelativeLink } from 'fumadocs-ui/mdx'; +import { LLMCopyButton, ViewOptions } from '@/components/page-actions'; + +export default async function Page(props: PageProps<'/docs/[[...slug]]'>) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + const MDX = page.data.body; + + return ( + + {page.data.title} + {page.data.description} + +
+ + +
+ +
+
+ ); +} + +export async function generateStaticParams() { + return source.generateParams(); +} + +export async function generateMetadata( + props: PageProps<'/docs/[[...slug]]'>, +): Promise { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + return { + title: page.data.title, + description: page.data.description, + openGraph: { + images: getPageImage(page).url, + }, + }; +} diff --git a/app/docs/layout.tsx b/app/docs/layout.tsx new file mode 100644 index 000000000..bac1433aa --- /dev/null +++ b/app/docs/layout.tsx @@ -0,0 +1,576 @@ +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import { baseOptions } from '@/lib/layout.shared'; + +export default function Layout({ children }: LayoutProps<'/docs'>) { + return ( + + {children} + + ); +} diff --git a/app/global.css b/app/global.css new file mode 100644 index 000000000..b6b46defd --- /dev/null +++ b/app/global.css @@ -0,0 +1,85 @@ +@import 'tailwindcss'; +@import 'fumadocs-ui/css/neutral.css'; +@import 'fumadocs-ui/css/preset.css'; +@import 'fumadocs-twoslash/twoslash.css'; + +@theme { + /* Light mode - matching original custom.css colors */ + --color-fd-background: white; + --color-fd-foreground: hsl(240, 4.3%, 17.6%); /* #2d2e34 - st-gray-800 */ + --color-fd-muted: hsl(240, 5.9%, 94.1%); /* #efeff1 - st-gray-50 */ + --color-fd-muted-foreground: hsl( + 240, + 3.8%, + 40.4% + ); /* #5d5f6a - st-gray-600 */ + --color-fd-popover: white; + --color-fd-popover-foreground: hsl( + 240, + 4.3%, + 17.6% + ); /* #2d2e34 - st-gray-800 */ + --color-fd-card: hsl(240, 5.9%, 94.1%); /* #efeff1 - st-gray-50 */ + --color-fd-card-foreground: hsl(240, 4.3%, 17.6%); /* #2d2e34 - st-gray-800 */ + --color-fd-border: hsl(240, 5.9%, 88.2%); /* #e1e2e5 - st-gray-100 */ + --color-fd-primary: hsl(240, 5.1%, 8.2%); /* #15151d - st-gray-900 */ + --color-fd-primary-foreground: white; + --color-fd-secondary: hsl(240, 5.9%, 94.1%); /* #efeff1 - st-gray-50 */ + --color-fd-secondary-foreground: hsl( + 240, + 4.3%, + 17.6% + ); /* #2d2e34 - st-gray-800 */ + --color-fd-accent: hsl(240, 5.9%, 88.2%); /* #e1e2e5 - st-gray-100 */ + --color-fd-accent-foreground: hsl( + 240, + 4.3%, + 17.6% + ); /* #2d2e34 - st-gray-800 */ + --color-fd-ring: hsl(240, 3.7%, 46.1%); /* #757785 - st-gray-500 */ +} +.dark { + /* Dark mode - matching original custom.css colors */ + --color-fd-background: #15151d; /* #15151d - st-gray-900 */ + --color-fd-foreground: hsl(240, 4.9%, 78.8%); /* #c6c7cd - st-gray-200 */ + --color-fd-muted: hsl(240, 4.3%, 17.6%); /* #2d2e34 - st-gray-800 */ + --color-fd-muted-foreground: hsl( + 240, + 3.7%, + 58.2% + ); /* #8f919d - st-gray-400 */ + --color-fd-popover: hsl(240, 4.3%, 17.6%); /* #2d2e34 - st-gray-800 */ + --color-fd-popover-foreground: hsl( + 240, + 4.9%, + 78.8% + ); /* #c6c7cd - st-gray-200 */ + --color-fd-card: #15151d; /* #2d2e34 - st-gray-800 */ + --color-fd-card-foreground: hsl(240, 5.9%, 96.1%); /* #efeff1 - st-gray-50 */ + --color-fd-border: hsl(240, 3.4%, 28.6%); /* #45464f - st-gray-700 */ + --color-fd-primary: hsl(240, 5.9%, 96.1%); /* #efeff1 - st-gray-50 */ + --color-fd-primary-foreground: hsl( + 240, + 5.1%, + 8.2% + ); /* #15151d - st-gray-900 */ + --color-fd-secondary: hsl(240, 4.3%, 17.6%); /* #2d2e34 - st-gray-800 */ + --color-fd-secondary-foreground: hsl( + 240, + 4.9%, + 78.8% + ); /* #c6c7cd - st-gray-200 */ + --color-fd-accent: hsl(240, 3.4%, 28.6%); /* #45464f - st-gray-700 */ + --color-fd-accent-foreground: hsl( + 240, + 5.9%, + 96.1% + ); /* #efeff1 - st-gray-50 */ + --color-fd-ring: hsl(240, 3.7%, 46.1%); /* #757785 - st-gray-500 */ +} + +.prose { + svg { + display: inline-block; + } +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 000000000..0b9d76415 --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,17 @@ +import '@/app/global.css'; +import { RootProvider } from 'fumadocs-ui/provider/next'; +import { Inter } from 'next/font/google'; + +const inter = Inter({ + subsets: ['latin'], +}); + +export default function Layout({ children }: LayoutProps<'/'>) { + return ( + + + {children} + + + ); +} diff --git a/app/llms-full.txt/route.ts b/app/llms-full.txt/route.ts new file mode 100644 index 000000000..d494d2cbb --- /dev/null +++ b/app/llms-full.txt/route.ts @@ -0,0 +1,10 @@ +import { getLLMText, source } from '@/lib/source'; + +export const revalidate = false; + +export async function GET() { + const scan = source.getPages().map(getLLMText); + const scanned = await Promise.all(scan); + + return new Response(scanned.join('\n\n')); +} diff --git a/app/llms.mdx/[[...slug]]/route.ts b/app/llms.mdx/[[...slug]]/route.ts new file mode 100644 index 000000000..c029b0f44 --- /dev/null +++ b/app/llms.mdx/[[...slug]]/route.ts @@ -0,0 +1,24 @@ +import { getLLMText } from '@/lib/get-llm-text'; +import { source } from '@/lib/source'; +import { notFound } from 'next/navigation'; + +export const revalidate = false; + +export async function GET( + _req: Request, + { params }: RouteContext<'/llms.mdx/[[...slug]]'>, +) { + const { slug } = await params; + const page = source.getPage(slug); + if (!page) notFound(); + + return new Response(await getLLMText(page), { + headers: { + 'Content-Type': 'text/markdown', + }, + }); +} + +export function generateStaticParams() { + return source.generateParams(); +} diff --git a/app/middleware.ts b/app/middleware.ts new file mode 100644 index 000000000..826a697b0 --- /dev/null +++ b/app/middleware.ts @@ -0,0 +1,12 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { isMarkdownPreferred, rewritePath } from 'fumadocs-core/negotiation'; +const { rewrite: rewriteLLM } = rewritePath('/docs/*path', '/llms.mdx/*path'); +export function middleware(request: NextRequest) { + if (isMarkdownPreferred(request)) { + const result = rewriteLLM(request.nextUrl.pathname); + if (result) { + return NextResponse.rewrite(new URL(result, request.nextUrl)); + } + } + return NextResponse.next(); +} diff --git a/app/og/docs/[...slug]/route.tsx b/app/og/docs/[...slug]/route.tsx new file mode 100644 index 000000000..f5df96dbc --- /dev/null +++ b/app/og/docs/[...slug]/route.tsx @@ -0,0 +1,36 @@ +import { getPageImage, source } from '@/lib/source'; +import { notFound } from 'next/navigation'; +import { ImageResponse } from 'next/og'; +import { generate as DefaultImage } from 'fumadocs-ui/og'; + +export const revalidate = false; + +export async function GET( + _req: Request, + { params }: RouteContext<'/og/docs/[...slug]'>, +) { + const { slug } = await params; + const page = source.getPage(slug.slice(0, -1)); + if (!page) notFound(); + + return new ImageResponse( + ( + + ), + { + width: 1200, + height: 630, + }, + ); +} + +export function generateStaticParams() { + return source.getPages().map((page) => ({ + lang: page.locale, + slug: getPageImage(page).segments, + })); +} diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index e00595dae..000000000 --- a/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: [require.resolve('@docusaurus/core/lib/babel/preset')], -}; diff --git a/cli.json b/cli.json new file mode 100644 index 000000000..15844394d --- /dev/null +++ b/cli.json @@ -0,0 +1,11 @@ +{ + "aliases": { + "uiDir": "./components/ui", + "componentsDir": "./components", + "blockDir": "./components", + "cssDir": "./styles", + "libDir": "./lib" + }, + "baseDir": "", + "commands": {} +} \ No newline at end of file diff --git a/components/markdown.tsx b/components/markdown.tsx new file mode 100644 index 000000000..7c2cddc3d --- /dev/null +++ b/components/markdown.tsx @@ -0,0 +1,119 @@ +import { remark } from 'remark'; +import remarkGfm from 'remark-gfm'; +import remarkRehype from 'remark-rehype'; +import { toJsxRuntime } from 'hast-util-to-jsx-runtime'; +import { + Children, + type ComponentProps, + type ReactElement, + type ReactNode, + Suspense, + use, + useDeferredValue, +} from 'react'; +import { Fragment, jsx, jsxs } from 'react/jsx-runtime'; +import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock'; +import defaultMdxComponents from 'fumadocs-ui/mdx'; +import { visit } from 'unist-util-visit'; +import type { ElementContent, Root, RootContent } from 'hast'; + +export interface Processor { + process: (content: string) => Promise; +} + +export function rehypeWrapWords() { + return (tree: Root) => { + visit(tree, ['text', 'element'], (node, index, parent) => { + if (node.type === 'element' && node.tagName === 'pre') return 'skip'; + if (node.type !== 'text' || !parent || index === undefined) return; + + const words = node.value.split(/(?=\s)/); + + // Create new span nodes for each word and whitespace + const newNodes: ElementContent[] = words.flatMap((word) => { + if (word.length === 0) return []; + + return { + type: 'element', + tagName: 'span', + properties: { + class: 'animate-fd-fade-in', + }, + children: [{ type: 'text', value: word }], + }; + }); + + Object.assign(node, { + type: 'element', + tagName: 'span', + properties: {}, + children: newNodes, + } satisfies RootContent); + return 'skip'; + }); + }; +} + +function createProcessor(): Processor { + const processor = remark() + .use(remarkGfm) + .use(remarkRehype) + .use(rehypeWrapWords); + + return { + async process(content) { + const nodes = processor.parse({ value: content }); + const hast = await processor.run(nodes); + + return toJsxRuntime(hast, { + development: false, + jsx, + jsxs, + Fragment, + components: { + ...defaultMdxComponents, + pre: Pre, + img: undefined, // use JSX + }, + }); + }, + }; +} + +function Pre(props: ComponentProps<'pre'>) { + const code = Children.only(props.children) as ReactElement; + const codeProps = code.props as ComponentProps<'code'>; + const content = codeProps.children; + if (typeof content !== 'string') return null; + + let lang = + codeProps.className + ?.split(' ') + .find((v) => v.startsWith('language-')) + ?.slice('language-'.length) ?? 'text'; + + if (lang === 'mdx') lang = 'md'; + + return ; +} + +const processor = createProcessor(); + +export function Markdown({ text }: { text: string }) { + const deferredText = useDeferredValue(text); + + return ( + {text}

}> + +
+ ); +} + +const cache = new Map>(); + +function Renderer({ text }: { text: string }) { + const result = cache.get(text) ?? processor.process(text); + cache.set(text, result); + + return use(result); +} diff --git a/components/page-actions.tsx b/components/page-actions.tsx new file mode 100644 index 000000000..63ccf70cd --- /dev/null +++ b/components/page-actions.tsx @@ -0,0 +1,247 @@ +'use client'; +import { useMemo, useState } from 'react'; +import { + Check, + ChevronDown, + Copy, + ExternalLinkIcon, + MessageCircleIcon, +} from 'lucide-react'; +import { cn } from '../lib/cn'; +import { useCopyButton } from 'fumadocs-ui/utils/use-copy-button'; +import { buttonVariants } from './ui/button'; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from 'fumadocs-ui/components/ui/popover'; +import { cva } from 'class-variance-authority'; + +const cache = new Map(); + +export function LLMCopyButton({ + /** + * A URL to fetch the raw Markdown/MDX content of page + */ + markdownUrl, +}: { + markdownUrl: string; +}) { + const [isLoading, setLoading] = useState(false); + const [checked, onClick] = useCopyButton(async () => { + const cached = cache.get(markdownUrl); + if (cached) return navigator.clipboard.writeText(cached); + + setLoading(true); + + try { + await navigator.clipboard.write([ + new ClipboardItem({ + 'text/plain': fetch(markdownUrl).then(async (res) => { + const content = await res.text(); + cache.set(markdownUrl, content); + + return content; + }), + }), + ]); + } finally { + setLoading(false); + } + }); + + return ( + + ); +} + +const optionVariants = cva( + 'text-sm p-2 rounded-lg inline-flex items-center gap-2 hover:text-fd-accent-foreground hover:bg-fd-accent [&_svg]:size-4', +); + +export function ViewOptions({ + markdownUrl, + githubUrl, +}: { + /** + * A URL to the raw Markdown/MDX content of page + */ + markdownUrl: string; + + /** + * Source file URL on GitHub + */ + githubUrl: string; +}) { + const items = useMemo(() => { + const fullMarkdownUrl = + typeof window !== 'undefined' + ? new URL(markdownUrl, window.location.origin) + : 'loading'; + const q = `Read ${fullMarkdownUrl}, I want to ask questions about it.`; + + return [ + { + title: 'Open in GitHub', + href: githubUrl, + icon: ( + + GitHub + + + ), + }, + { + title: 'Open in Scira AI', + href: `https://scira.ai/?${new URLSearchParams({ + q, + })}`, + icon: ( + + Scira AI + + + + + + + + + ), + }, + { + title: 'Open in ChatGPT', + href: `https://chatgpt.com/?${new URLSearchParams({ + hints: 'search', + q, + })}`, + icon: ( + + OpenAI + + + ), + }, + { + title: 'Open in Claude', + href: `https://claude.ai/new?${new URLSearchParams({ + q, + })}`, + icon: ( + + Anthropic + + + ), + }, + { + title: 'Open in T3 Chat', + href: `https://t3.chat/new?${new URLSearchParams({ + q, + })}`, + icon: , + }, + ]; + }, [githubUrl, markdownUrl]); + + return ( + + + Open + + + + {items.map((item) => ( + + {item.icon} + {item.title} + + + ))} + + + ); +} diff --git a/components/search.tsx b/components/search.tsx new file mode 100644 index 000000000..42ab84d10 --- /dev/null +++ b/components/search.tsx @@ -0,0 +1,385 @@ +'use client'; +import { RemoveScroll } from 'react-remove-scroll'; +import { + type ComponentProps, + createContext, + type SyntheticEvent, + use, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { Loader2, RefreshCw, SearchIcon, Send, X } from 'lucide-react'; +import { cn } from '../lib/cn'; +import { buttonVariants } from './ui/button'; +import Link from 'fumadocs-core/link'; +import { type UIMessage, useChat, type UseChatHelpers } from '@ai-sdk/react'; +import type { ProvideLinksToolSchema } from '../lib/inkeep-qa-schema'; +import type { z } from 'zod'; +import { DefaultChatTransport } from 'ai'; +import { Markdown } from './markdown'; +import { Presence } from '@radix-ui/react-presence'; + +const Context = createContext<{ + open: boolean; + setOpen: (open: boolean) => void; + chat: UseChatHelpers; +} | null>(null); + +function useChatContext() { + return use(Context)!.chat; +} + +function SearchAIActions() { + const { messages, status, setMessages, regenerate } = useChatContext(); + const isLoading = status === 'streaming'; + + if (messages.length === 0) return null; + + return ( + <> + {!isLoading && messages.at(-1)?.role === 'assistant' && ( + + )} + + + ); +} + +function SearchAIInput(props: ComponentProps<'form'>) { + const { status, sendMessage, stop } = useChatContext(); + const [input, setInput] = useState(''); + const isLoading = status === 'streaming' || status === 'submitted'; + const onStart = (e?: SyntheticEvent) => { + e?.preventDefault(); + void sendMessage({ text: input }); + setInput(''); + }; + + useEffect(() => { + if (isLoading) document.getElementById('nd-ai-input')?.focus(); + }, [isLoading]); + + return ( +
+ { + setInput(e.target.value); + }} + onKeyDown={(event) => { + if (!event.shiftKey && event.key === 'Enter') { + onStart(event); + } + }} + /> + {isLoading ? ( + + ) : ( + + )} +
+ ); +} + +function List(props: Omit, 'dir'>) { + const containerRef = useRef(null); + + useEffect(() => { + if (!containerRef.current) return; + function callback() { + const container = containerRef.current; + if (!container) return; + + container.scrollTo({ + top: container.scrollHeight, + behavior: 'instant', + }); + } + + const observer = new ResizeObserver(callback); + callback(); + + const element = containerRef.current?.firstElementChild; + + if (element) { + observer.observe(element); + } + + return () => { + observer.disconnect(); + }; + }, []); + + return ( +
+ {props.children} +
+ ); +} + +function Input(props: ComponentProps<'textarea'>) { + const ref = useRef(null); + const shared = cn('col-start-1 row-start-1', props.className); + + return ( +
+