From 80a2771cad49997b77599c9bf07d82c29cc89c40 Mon Sep 17 00:00:00 2001 From: Joshua Claunch Date: Mon, 23 Feb 2026 18:54:26 -0500 Subject: [PATCH] chore(docs): implement versioned documentation system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Migrate all existing docs to docs/v1/ for version 1 documentation - Create docs/v2/ folder with new v2 beta docs (currently just index) - Create docs/next/ folder for unreleased/development docs - Implement docs-version-resolver plugin that creates smart unversioned URL routes - Routes use layered resolution: explicit redirects → current version → fallback to stale - Add VersionSelector navbar dropdown to switch between doc versions - Add StaleBanner component showing on all non-current version pages - Support sidebar-based doc discovery with nested category and shorthand syntax - Extract v2 docs from sidebars.js '🚧 v2 beta docs' section with v2/ prefix stripping - Create version-map.js for redirect configuration and version settings - Update docusaurus.config.js with multi-instance docs plugins for versioning - Theme swizzling: DocItem wrapper, NavbarItem components, and custom CSS Co-Authored-By: Claude Haiku 4.5 --- docs/docs/next/index.mdx | 8 + docs/docs/{ => v1}/about/faq.mdx | 0 docs/docs/{ => v1}/about/introduction.mdx | 0 .../{ => v1}/about/react-query-comparison.mdx | 0 .../docs/{ => v1}/about/recoil-comparison.mdx | 0 docs/docs/{ => v1}/about/redux-comparison.mdx | 0 docs/docs/{ => v1}/advanced/batching.mdx | 0 .../docs/{ => v1}/advanced/complex-params.mdx | 0 docs/docs/{ => v1}/advanced/dev-tools.mdx | 0 docs/docs/{ => v1}/advanced/more-patterns.mdx | 0 docs/docs/{ => v1}/advanced/persistence.mdx | 0 docs/docs/{ => v1}/advanced/plugins.mdx | 0 docs/docs/{ => v1}/advanced/ssr.mdx | 0 .../{ => v1}/advanced/store-composition.mdx | 0 docs/docs/{ => v1}/advanced/time-travel.mdx | 0 .../{ => v1}/advanced/typescript-tips.mdx | 0 docs/docs/{ => v1}/api/api-overview.md | 0 docs/docs/{ => v1}/api/classes/AtomApi.mdx | 0 .../{ => v1}/api/classes/AtomInstance.mdx | 0 .../{ => v1}/api/classes/AtomTemplate.mdx | 0 docs/docs/{ => v1}/api/classes/Ecosystem.mdx | 0 .../docs/{ => v1}/api/classes/IonTemplate.mdx | 0 .../{ => v1}/api/classes/SelectorCache.mdx | 0 docs/docs/{ => v1}/api/classes/Selectors.mdx | 0 docs/docs/{ => v1}/api/classes/Store.mdx | 0 .../docs/{ => v1}/api/classes/ZeduxPlugin.mdx | 0 .../{ => v1}/api/components/AtomProvider.mdx | 0 .../api/components/EcosystemProvider.mdx | 0 .../{ => v1}/api/factories/actionFactory.mdx | 0 docs/docs/{ => v1}/api/factories/api.mdx | 0 docs/docs/{ => v1}/api/factories/atom.mdx | 0 .../api/factories/createEcosystem.mdx | 0 .../{ => v1}/api/factories/createReducer.mdx | 0 .../{ => v1}/api/factories/createStore.mdx | 0 docs/docs/{ => v1}/api/factories/ion.mdx | 0 docs/docs/{ => v1}/api/glossary.md | 0 .../{ => v1}/api/hooks/useAtomContext.mdx | 0 .../{ => v1}/api/hooks/useAtomInstance.mdx | 0 .../{ => v1}/api/hooks/useAtomSelector.mdx | 0 docs/docs/{ => v1}/api/hooks/useAtomState.mdx | 0 docs/docs/{ => v1}/api/hooks/useAtomValue.mdx | 0 docs/docs/{ => v1}/api/hooks/useEcosystem.mdx | 0 .../api/injectors/injectAtomGetters.mdx | 0 .../api/injectors/injectAtomInstance.mdx | 0 .../api/injectors/injectAtomSelector.mdx | 0 .../api/injectors/injectAtomState.mdx | 0 .../api/injectors/injectAtomValue.mdx | 0 .../{ => v1}/api/injectors/injectCallback.mdx | 0 .../{ => v1}/api/injectors/injectEffect.mdx | 0 .../api/injectors/injectInvalidate.mdx | 0 .../{ => v1}/api/injectors/injectMemo.mdx | 0 .../{ => v1}/api/injectors/injectPromise.mdx | 0 .../docs/{ => v1}/api/injectors/injectRef.mdx | 0 .../{ => v1}/api/injectors/injectSelf.mdx | 0 .../{ => v1}/api/injectors/injectStore.mdx | 0 .../docs/{ => v1}/api/injectors/injectWhy.mdx | 0 docs/docs/{ => v1}/api/types/Action.mdx | 0 docs/docs/{ => v1}/api/types/ActionChain.mdx | 0 .../docs/{ => v1}/api/types/ActionFactory.mdx | 0 docs/docs/{ => v1}/api/types/AtomConfig.mdx | 0 docs/docs/{ => v1}/api/types/AtomGetters.mdx | 0 .../{ => v1}/api/types/AtomInstanceTtl.mdx | 0 docs/docs/{ => v1}/api/types/AtomSelector.mdx | 0 .../{ => v1}/api/types/AtomSelectorConfig.mdx | 0 .../{ => v1}/api/types/DependentCallback.mdx | 0 .../{ => v1}/api/types/EcosystemConfig.mdx | 0 .../{ => v1}/api/types/EvaluationReason.mdx | 0 .../api/types/HierarchyDescriptor.mdx | 0 docs/docs/{ => v1}/api/types/PromiseState.mdx | 0 docs/docs/{ => v1}/api/types/Reducer.mdx | 0 .../{ => v1}/api/types/ReducerBuilder.mdx | 0 docs/docs/{ => v1}/api/types/Settable.mdx | 0 docs/docs/{ => v1}/api/types/StoreEffect.mdx | 0 docs/docs/{ => v1}/api/types/Subscriber.mdx | 0 docs/docs/{ => v1}/api/types/Subscription.mdx | 0 .../{ => v1}/api/utils/action-chain-utils.mdx | 0 .../{ => v1}/api/utils/internal-utils.mdx | 0 docs/docs/{ => v1}/api/utils/is.mdx | 0 docs/docs/{ => v1}/api/utils/zeduxTypes.mdx | 0 docs/docs/v1/index.mdx | 18 ++ docs/docs/{ => v1}/migrations/v2.mdx | 0 docs/docs/{ => v1}/packages/immer.mdx | 0 .../packages/machines/MachineState.mdx | 0 .../packages/machines/MachineStore.mdx | 0 .../packages/machines/injectMachineStore.mdx | 0 .../{ => v1}/packages/machines/overview.mdx | 0 .../packages/machines/walkthrough.mdx | 0 docs/docs/{ => v1}/walkthrough/atom-apis.mdx | 0 .../{ => v1}/walkthrough/atom-getters.mdx | 0 .../{ => v1}/walkthrough/atom-instances.mdx | 0 docs/docs/{ => v1}/walkthrough/atom-state.mdx | 0 .../walkthrough/configuring-atoms.mdx | 0 .../{ => v1}/walkthrough/custom-injectors.mdx | 0 .../docs/{ => v1}/walkthrough/destruction.mdx | 0 docs/docs/{ => v1}/walkthrough/ecosystems.mdx | 0 docs/docs/{ => v1}/walkthrough/overrides.mdx | 0 .../docs/{ => v1}/walkthrough/query-atoms.mdx | 0 .../docs/{ => v1}/walkthrough/quick-start.mdx | 0 .../{ => v1}/walkthrough/react-context.mdx | 0 docs/docs/{ => v1}/walkthrough/resets.mdx | 0 docs/docs/{ => v1}/walkthrough/selectors.mdx | 0 .../{ => v1}/walkthrough/side-effects.mdx | 0 docs/docs/{ => v1}/walkthrough/stores.mdx | 0 docs/docs/{ => v1}/walkthrough/suspense.mdx | 0 docs/docs/{ => v1}/walkthrough/the-graph.mdx | 0 docs/docs/v2/index.mdx | 20 ++ docs/docusaurus.config.js | 59 +++++- docs/plugins/docs-version-resolver.js | 189 ++++++++++++++++++ docs/sidebars-next.js | 18 ++ docs/sidebars-v1.js | 166 +++++++++++++++ docs/sidebars-v2.js | 59 ++++++ docs/src/components/Hero.tsx | 4 +- docs/src/components/LearningPaths.tsx | 4 +- docs/src/components/StaleBanner.tsx | 65 ++++++ docs/src/components/VersionedDocRedirect.tsx | 38 ++++ docs/src/css/custom.css | 90 +++++++++ docs/src/theme/DocItem/index.tsx | 33 +++ docs/src/theme/NavbarItem/ComponentTypes.tsx | 7 + docs/src/theme/NavbarItem/VersionSelector.tsx | 74 +++++++ docs/version-map.js | 31 +++ 120 files changed, 871 insertions(+), 12 deletions(-) create mode 100644 docs/docs/next/index.mdx rename docs/docs/{ => v1}/about/faq.mdx (100%) rename docs/docs/{ => v1}/about/introduction.mdx (100%) rename docs/docs/{ => v1}/about/react-query-comparison.mdx (100%) rename docs/docs/{ => v1}/about/recoil-comparison.mdx (100%) rename docs/docs/{ => v1}/about/redux-comparison.mdx (100%) rename docs/docs/{ => v1}/advanced/batching.mdx (100%) rename docs/docs/{ => v1}/advanced/complex-params.mdx (100%) rename docs/docs/{ => v1}/advanced/dev-tools.mdx (100%) rename docs/docs/{ => v1}/advanced/more-patterns.mdx (100%) rename docs/docs/{ => v1}/advanced/persistence.mdx (100%) rename docs/docs/{ => v1}/advanced/plugins.mdx (100%) rename docs/docs/{ => v1}/advanced/ssr.mdx (100%) rename docs/docs/{ => v1}/advanced/store-composition.mdx (100%) rename docs/docs/{ => v1}/advanced/time-travel.mdx (100%) rename docs/docs/{ => v1}/advanced/typescript-tips.mdx (100%) rename docs/docs/{ => v1}/api/api-overview.md (100%) rename docs/docs/{ => v1}/api/classes/AtomApi.mdx (100%) rename docs/docs/{ => v1}/api/classes/AtomInstance.mdx (100%) rename docs/docs/{ => v1}/api/classes/AtomTemplate.mdx (100%) rename docs/docs/{ => v1}/api/classes/Ecosystem.mdx (100%) rename docs/docs/{ => v1}/api/classes/IonTemplate.mdx (100%) rename docs/docs/{ => v1}/api/classes/SelectorCache.mdx (100%) rename docs/docs/{ => v1}/api/classes/Selectors.mdx (100%) rename docs/docs/{ => v1}/api/classes/Store.mdx (100%) rename docs/docs/{ => v1}/api/classes/ZeduxPlugin.mdx (100%) rename docs/docs/{ => v1}/api/components/AtomProvider.mdx (100%) rename docs/docs/{ => v1}/api/components/EcosystemProvider.mdx (100%) rename docs/docs/{ => v1}/api/factories/actionFactory.mdx (100%) rename docs/docs/{ => v1}/api/factories/api.mdx (100%) rename docs/docs/{ => v1}/api/factories/atom.mdx (100%) rename docs/docs/{ => v1}/api/factories/createEcosystem.mdx (100%) rename docs/docs/{ => v1}/api/factories/createReducer.mdx (100%) rename docs/docs/{ => v1}/api/factories/createStore.mdx (100%) rename docs/docs/{ => v1}/api/factories/ion.mdx (100%) rename docs/docs/{ => v1}/api/glossary.md (100%) rename docs/docs/{ => v1}/api/hooks/useAtomContext.mdx (100%) rename docs/docs/{ => v1}/api/hooks/useAtomInstance.mdx (100%) rename docs/docs/{ => v1}/api/hooks/useAtomSelector.mdx (100%) rename docs/docs/{ => v1}/api/hooks/useAtomState.mdx (100%) rename docs/docs/{ => v1}/api/hooks/useAtomValue.mdx (100%) rename docs/docs/{ => v1}/api/hooks/useEcosystem.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectAtomGetters.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectAtomInstance.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectAtomSelector.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectAtomState.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectAtomValue.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectCallback.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectEffect.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectInvalidate.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectMemo.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectPromise.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectRef.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectSelf.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectStore.mdx (100%) rename docs/docs/{ => v1}/api/injectors/injectWhy.mdx (100%) rename docs/docs/{ => v1}/api/types/Action.mdx (100%) rename docs/docs/{ => v1}/api/types/ActionChain.mdx (100%) rename docs/docs/{ => v1}/api/types/ActionFactory.mdx (100%) rename docs/docs/{ => v1}/api/types/AtomConfig.mdx (100%) rename docs/docs/{ => v1}/api/types/AtomGetters.mdx (100%) rename docs/docs/{ => v1}/api/types/AtomInstanceTtl.mdx (100%) rename docs/docs/{ => v1}/api/types/AtomSelector.mdx (100%) rename docs/docs/{ => v1}/api/types/AtomSelectorConfig.mdx (100%) rename docs/docs/{ => v1}/api/types/DependentCallback.mdx (100%) rename docs/docs/{ => v1}/api/types/EcosystemConfig.mdx (100%) rename docs/docs/{ => v1}/api/types/EvaluationReason.mdx (100%) rename docs/docs/{ => v1}/api/types/HierarchyDescriptor.mdx (100%) rename docs/docs/{ => v1}/api/types/PromiseState.mdx (100%) rename docs/docs/{ => v1}/api/types/Reducer.mdx (100%) rename docs/docs/{ => v1}/api/types/ReducerBuilder.mdx (100%) rename docs/docs/{ => v1}/api/types/Settable.mdx (100%) rename docs/docs/{ => v1}/api/types/StoreEffect.mdx (100%) rename docs/docs/{ => v1}/api/types/Subscriber.mdx (100%) rename docs/docs/{ => v1}/api/types/Subscription.mdx (100%) rename docs/docs/{ => v1}/api/utils/action-chain-utils.mdx (100%) rename docs/docs/{ => v1}/api/utils/internal-utils.mdx (100%) rename docs/docs/{ => v1}/api/utils/is.mdx (100%) rename docs/docs/{ => v1}/api/utils/zeduxTypes.mdx (100%) create mode 100644 docs/docs/v1/index.mdx rename docs/docs/{ => v1}/migrations/v2.mdx (100%) rename docs/docs/{ => v1}/packages/immer.mdx (100%) rename docs/docs/{ => v1}/packages/machines/MachineState.mdx (100%) rename docs/docs/{ => v1}/packages/machines/MachineStore.mdx (100%) rename docs/docs/{ => v1}/packages/machines/injectMachineStore.mdx (100%) rename docs/docs/{ => v1}/packages/machines/overview.mdx (100%) rename docs/docs/{ => v1}/packages/machines/walkthrough.mdx (100%) rename docs/docs/{ => v1}/walkthrough/atom-apis.mdx (100%) rename docs/docs/{ => v1}/walkthrough/atom-getters.mdx (100%) rename docs/docs/{ => v1}/walkthrough/atom-instances.mdx (100%) rename docs/docs/{ => v1}/walkthrough/atom-state.mdx (100%) rename docs/docs/{ => v1}/walkthrough/configuring-atoms.mdx (100%) rename docs/docs/{ => v1}/walkthrough/custom-injectors.mdx (100%) rename docs/docs/{ => v1}/walkthrough/destruction.mdx (100%) rename docs/docs/{ => v1}/walkthrough/ecosystems.mdx (100%) rename docs/docs/{ => v1}/walkthrough/overrides.mdx (100%) rename docs/docs/{ => v1}/walkthrough/query-atoms.mdx (100%) rename docs/docs/{ => v1}/walkthrough/quick-start.mdx (100%) rename docs/docs/{ => v1}/walkthrough/react-context.mdx (100%) rename docs/docs/{ => v1}/walkthrough/resets.mdx (100%) rename docs/docs/{ => v1}/walkthrough/selectors.mdx (100%) rename docs/docs/{ => v1}/walkthrough/side-effects.mdx (100%) rename docs/docs/{ => v1}/walkthrough/stores.mdx (100%) rename docs/docs/{ => v1}/walkthrough/suspense.mdx (100%) rename docs/docs/{ => v1}/walkthrough/the-graph.mdx (100%) create mode 100644 docs/docs/v2/index.mdx create mode 100644 docs/plugins/docs-version-resolver.js create mode 100644 docs/sidebars-next.js create mode 100644 docs/sidebars-v1.js create mode 100644 docs/sidebars-v2.js create mode 100644 docs/src/components/StaleBanner.tsx create mode 100644 docs/src/components/VersionedDocRedirect.tsx create mode 100644 docs/src/theme/DocItem/index.tsx create mode 100644 docs/src/theme/NavbarItem/ComponentTypes.tsx create mode 100644 docs/src/theme/NavbarItem/VersionSelector.tsx create mode 100644 docs/version-map.js diff --git a/docs/docs/next/index.mdx b/docs/docs/next/index.mdx new file mode 100644 index 00000000..3ac397ea --- /dev/null +++ b/docs/docs/next/index.mdx @@ -0,0 +1,8 @@ +--- +id: index +title: Next (Unreleased) Documentation +--- + +# Next (Unreleased) Documentation + +This documentation is for the upcoming release and may change. diff --git a/docs/docs/about/faq.mdx b/docs/docs/v1/about/faq.mdx similarity index 100% rename from docs/docs/about/faq.mdx rename to docs/docs/v1/about/faq.mdx diff --git a/docs/docs/about/introduction.mdx b/docs/docs/v1/about/introduction.mdx similarity index 100% rename from docs/docs/about/introduction.mdx rename to docs/docs/v1/about/introduction.mdx diff --git a/docs/docs/about/react-query-comparison.mdx b/docs/docs/v1/about/react-query-comparison.mdx similarity index 100% rename from docs/docs/about/react-query-comparison.mdx rename to docs/docs/v1/about/react-query-comparison.mdx diff --git a/docs/docs/about/recoil-comparison.mdx b/docs/docs/v1/about/recoil-comparison.mdx similarity index 100% rename from docs/docs/about/recoil-comparison.mdx rename to docs/docs/v1/about/recoil-comparison.mdx diff --git a/docs/docs/about/redux-comparison.mdx b/docs/docs/v1/about/redux-comparison.mdx similarity index 100% rename from docs/docs/about/redux-comparison.mdx rename to docs/docs/v1/about/redux-comparison.mdx diff --git a/docs/docs/advanced/batching.mdx b/docs/docs/v1/advanced/batching.mdx similarity index 100% rename from docs/docs/advanced/batching.mdx rename to docs/docs/v1/advanced/batching.mdx diff --git a/docs/docs/advanced/complex-params.mdx b/docs/docs/v1/advanced/complex-params.mdx similarity index 100% rename from docs/docs/advanced/complex-params.mdx rename to docs/docs/v1/advanced/complex-params.mdx diff --git a/docs/docs/advanced/dev-tools.mdx b/docs/docs/v1/advanced/dev-tools.mdx similarity index 100% rename from docs/docs/advanced/dev-tools.mdx rename to docs/docs/v1/advanced/dev-tools.mdx diff --git a/docs/docs/advanced/more-patterns.mdx b/docs/docs/v1/advanced/more-patterns.mdx similarity index 100% rename from docs/docs/advanced/more-patterns.mdx rename to docs/docs/v1/advanced/more-patterns.mdx diff --git a/docs/docs/advanced/persistence.mdx b/docs/docs/v1/advanced/persistence.mdx similarity index 100% rename from docs/docs/advanced/persistence.mdx rename to docs/docs/v1/advanced/persistence.mdx diff --git a/docs/docs/advanced/plugins.mdx b/docs/docs/v1/advanced/plugins.mdx similarity index 100% rename from docs/docs/advanced/plugins.mdx rename to docs/docs/v1/advanced/plugins.mdx diff --git a/docs/docs/advanced/ssr.mdx b/docs/docs/v1/advanced/ssr.mdx similarity index 100% rename from docs/docs/advanced/ssr.mdx rename to docs/docs/v1/advanced/ssr.mdx diff --git a/docs/docs/advanced/store-composition.mdx b/docs/docs/v1/advanced/store-composition.mdx similarity index 100% rename from docs/docs/advanced/store-composition.mdx rename to docs/docs/v1/advanced/store-composition.mdx diff --git a/docs/docs/advanced/time-travel.mdx b/docs/docs/v1/advanced/time-travel.mdx similarity index 100% rename from docs/docs/advanced/time-travel.mdx rename to docs/docs/v1/advanced/time-travel.mdx diff --git a/docs/docs/advanced/typescript-tips.mdx b/docs/docs/v1/advanced/typescript-tips.mdx similarity index 100% rename from docs/docs/advanced/typescript-tips.mdx rename to docs/docs/v1/advanced/typescript-tips.mdx diff --git a/docs/docs/api/api-overview.md b/docs/docs/v1/api/api-overview.md similarity index 100% rename from docs/docs/api/api-overview.md rename to docs/docs/v1/api/api-overview.md diff --git a/docs/docs/api/classes/AtomApi.mdx b/docs/docs/v1/api/classes/AtomApi.mdx similarity index 100% rename from docs/docs/api/classes/AtomApi.mdx rename to docs/docs/v1/api/classes/AtomApi.mdx diff --git a/docs/docs/api/classes/AtomInstance.mdx b/docs/docs/v1/api/classes/AtomInstance.mdx similarity index 100% rename from docs/docs/api/classes/AtomInstance.mdx rename to docs/docs/v1/api/classes/AtomInstance.mdx diff --git a/docs/docs/api/classes/AtomTemplate.mdx b/docs/docs/v1/api/classes/AtomTemplate.mdx similarity index 100% rename from docs/docs/api/classes/AtomTemplate.mdx rename to docs/docs/v1/api/classes/AtomTemplate.mdx diff --git a/docs/docs/api/classes/Ecosystem.mdx b/docs/docs/v1/api/classes/Ecosystem.mdx similarity index 100% rename from docs/docs/api/classes/Ecosystem.mdx rename to docs/docs/v1/api/classes/Ecosystem.mdx diff --git a/docs/docs/api/classes/IonTemplate.mdx b/docs/docs/v1/api/classes/IonTemplate.mdx similarity index 100% rename from docs/docs/api/classes/IonTemplate.mdx rename to docs/docs/v1/api/classes/IonTemplate.mdx diff --git a/docs/docs/api/classes/SelectorCache.mdx b/docs/docs/v1/api/classes/SelectorCache.mdx similarity index 100% rename from docs/docs/api/classes/SelectorCache.mdx rename to docs/docs/v1/api/classes/SelectorCache.mdx diff --git a/docs/docs/api/classes/Selectors.mdx b/docs/docs/v1/api/classes/Selectors.mdx similarity index 100% rename from docs/docs/api/classes/Selectors.mdx rename to docs/docs/v1/api/classes/Selectors.mdx diff --git a/docs/docs/api/classes/Store.mdx b/docs/docs/v1/api/classes/Store.mdx similarity index 100% rename from docs/docs/api/classes/Store.mdx rename to docs/docs/v1/api/classes/Store.mdx diff --git a/docs/docs/api/classes/ZeduxPlugin.mdx b/docs/docs/v1/api/classes/ZeduxPlugin.mdx similarity index 100% rename from docs/docs/api/classes/ZeduxPlugin.mdx rename to docs/docs/v1/api/classes/ZeduxPlugin.mdx diff --git a/docs/docs/api/components/AtomProvider.mdx b/docs/docs/v1/api/components/AtomProvider.mdx similarity index 100% rename from docs/docs/api/components/AtomProvider.mdx rename to docs/docs/v1/api/components/AtomProvider.mdx diff --git a/docs/docs/api/components/EcosystemProvider.mdx b/docs/docs/v1/api/components/EcosystemProvider.mdx similarity index 100% rename from docs/docs/api/components/EcosystemProvider.mdx rename to docs/docs/v1/api/components/EcosystemProvider.mdx diff --git a/docs/docs/api/factories/actionFactory.mdx b/docs/docs/v1/api/factories/actionFactory.mdx similarity index 100% rename from docs/docs/api/factories/actionFactory.mdx rename to docs/docs/v1/api/factories/actionFactory.mdx diff --git a/docs/docs/api/factories/api.mdx b/docs/docs/v1/api/factories/api.mdx similarity index 100% rename from docs/docs/api/factories/api.mdx rename to docs/docs/v1/api/factories/api.mdx diff --git a/docs/docs/api/factories/atom.mdx b/docs/docs/v1/api/factories/atom.mdx similarity index 100% rename from docs/docs/api/factories/atom.mdx rename to docs/docs/v1/api/factories/atom.mdx diff --git a/docs/docs/api/factories/createEcosystem.mdx b/docs/docs/v1/api/factories/createEcosystem.mdx similarity index 100% rename from docs/docs/api/factories/createEcosystem.mdx rename to docs/docs/v1/api/factories/createEcosystem.mdx diff --git a/docs/docs/api/factories/createReducer.mdx b/docs/docs/v1/api/factories/createReducer.mdx similarity index 100% rename from docs/docs/api/factories/createReducer.mdx rename to docs/docs/v1/api/factories/createReducer.mdx diff --git a/docs/docs/api/factories/createStore.mdx b/docs/docs/v1/api/factories/createStore.mdx similarity index 100% rename from docs/docs/api/factories/createStore.mdx rename to docs/docs/v1/api/factories/createStore.mdx diff --git a/docs/docs/api/factories/ion.mdx b/docs/docs/v1/api/factories/ion.mdx similarity index 100% rename from docs/docs/api/factories/ion.mdx rename to docs/docs/v1/api/factories/ion.mdx diff --git a/docs/docs/api/glossary.md b/docs/docs/v1/api/glossary.md similarity index 100% rename from docs/docs/api/glossary.md rename to docs/docs/v1/api/glossary.md diff --git a/docs/docs/api/hooks/useAtomContext.mdx b/docs/docs/v1/api/hooks/useAtomContext.mdx similarity index 100% rename from docs/docs/api/hooks/useAtomContext.mdx rename to docs/docs/v1/api/hooks/useAtomContext.mdx diff --git a/docs/docs/api/hooks/useAtomInstance.mdx b/docs/docs/v1/api/hooks/useAtomInstance.mdx similarity index 100% rename from docs/docs/api/hooks/useAtomInstance.mdx rename to docs/docs/v1/api/hooks/useAtomInstance.mdx diff --git a/docs/docs/api/hooks/useAtomSelector.mdx b/docs/docs/v1/api/hooks/useAtomSelector.mdx similarity index 100% rename from docs/docs/api/hooks/useAtomSelector.mdx rename to docs/docs/v1/api/hooks/useAtomSelector.mdx diff --git a/docs/docs/api/hooks/useAtomState.mdx b/docs/docs/v1/api/hooks/useAtomState.mdx similarity index 100% rename from docs/docs/api/hooks/useAtomState.mdx rename to docs/docs/v1/api/hooks/useAtomState.mdx diff --git a/docs/docs/api/hooks/useAtomValue.mdx b/docs/docs/v1/api/hooks/useAtomValue.mdx similarity index 100% rename from docs/docs/api/hooks/useAtomValue.mdx rename to docs/docs/v1/api/hooks/useAtomValue.mdx diff --git a/docs/docs/api/hooks/useEcosystem.mdx b/docs/docs/v1/api/hooks/useEcosystem.mdx similarity index 100% rename from docs/docs/api/hooks/useEcosystem.mdx rename to docs/docs/v1/api/hooks/useEcosystem.mdx diff --git a/docs/docs/api/injectors/injectAtomGetters.mdx b/docs/docs/v1/api/injectors/injectAtomGetters.mdx similarity index 100% rename from docs/docs/api/injectors/injectAtomGetters.mdx rename to docs/docs/v1/api/injectors/injectAtomGetters.mdx diff --git a/docs/docs/api/injectors/injectAtomInstance.mdx b/docs/docs/v1/api/injectors/injectAtomInstance.mdx similarity index 100% rename from docs/docs/api/injectors/injectAtomInstance.mdx rename to docs/docs/v1/api/injectors/injectAtomInstance.mdx diff --git a/docs/docs/api/injectors/injectAtomSelector.mdx b/docs/docs/v1/api/injectors/injectAtomSelector.mdx similarity index 100% rename from docs/docs/api/injectors/injectAtomSelector.mdx rename to docs/docs/v1/api/injectors/injectAtomSelector.mdx diff --git a/docs/docs/api/injectors/injectAtomState.mdx b/docs/docs/v1/api/injectors/injectAtomState.mdx similarity index 100% rename from docs/docs/api/injectors/injectAtomState.mdx rename to docs/docs/v1/api/injectors/injectAtomState.mdx diff --git a/docs/docs/api/injectors/injectAtomValue.mdx b/docs/docs/v1/api/injectors/injectAtomValue.mdx similarity index 100% rename from docs/docs/api/injectors/injectAtomValue.mdx rename to docs/docs/v1/api/injectors/injectAtomValue.mdx diff --git a/docs/docs/api/injectors/injectCallback.mdx b/docs/docs/v1/api/injectors/injectCallback.mdx similarity index 100% rename from docs/docs/api/injectors/injectCallback.mdx rename to docs/docs/v1/api/injectors/injectCallback.mdx diff --git a/docs/docs/api/injectors/injectEffect.mdx b/docs/docs/v1/api/injectors/injectEffect.mdx similarity index 100% rename from docs/docs/api/injectors/injectEffect.mdx rename to docs/docs/v1/api/injectors/injectEffect.mdx diff --git a/docs/docs/api/injectors/injectInvalidate.mdx b/docs/docs/v1/api/injectors/injectInvalidate.mdx similarity index 100% rename from docs/docs/api/injectors/injectInvalidate.mdx rename to docs/docs/v1/api/injectors/injectInvalidate.mdx diff --git a/docs/docs/api/injectors/injectMemo.mdx b/docs/docs/v1/api/injectors/injectMemo.mdx similarity index 100% rename from docs/docs/api/injectors/injectMemo.mdx rename to docs/docs/v1/api/injectors/injectMemo.mdx diff --git a/docs/docs/api/injectors/injectPromise.mdx b/docs/docs/v1/api/injectors/injectPromise.mdx similarity index 100% rename from docs/docs/api/injectors/injectPromise.mdx rename to docs/docs/v1/api/injectors/injectPromise.mdx diff --git a/docs/docs/api/injectors/injectRef.mdx b/docs/docs/v1/api/injectors/injectRef.mdx similarity index 100% rename from docs/docs/api/injectors/injectRef.mdx rename to docs/docs/v1/api/injectors/injectRef.mdx diff --git a/docs/docs/api/injectors/injectSelf.mdx b/docs/docs/v1/api/injectors/injectSelf.mdx similarity index 100% rename from docs/docs/api/injectors/injectSelf.mdx rename to docs/docs/v1/api/injectors/injectSelf.mdx diff --git a/docs/docs/api/injectors/injectStore.mdx b/docs/docs/v1/api/injectors/injectStore.mdx similarity index 100% rename from docs/docs/api/injectors/injectStore.mdx rename to docs/docs/v1/api/injectors/injectStore.mdx diff --git a/docs/docs/api/injectors/injectWhy.mdx b/docs/docs/v1/api/injectors/injectWhy.mdx similarity index 100% rename from docs/docs/api/injectors/injectWhy.mdx rename to docs/docs/v1/api/injectors/injectWhy.mdx diff --git a/docs/docs/api/types/Action.mdx b/docs/docs/v1/api/types/Action.mdx similarity index 100% rename from docs/docs/api/types/Action.mdx rename to docs/docs/v1/api/types/Action.mdx diff --git a/docs/docs/api/types/ActionChain.mdx b/docs/docs/v1/api/types/ActionChain.mdx similarity index 100% rename from docs/docs/api/types/ActionChain.mdx rename to docs/docs/v1/api/types/ActionChain.mdx diff --git a/docs/docs/api/types/ActionFactory.mdx b/docs/docs/v1/api/types/ActionFactory.mdx similarity index 100% rename from docs/docs/api/types/ActionFactory.mdx rename to docs/docs/v1/api/types/ActionFactory.mdx diff --git a/docs/docs/api/types/AtomConfig.mdx b/docs/docs/v1/api/types/AtomConfig.mdx similarity index 100% rename from docs/docs/api/types/AtomConfig.mdx rename to docs/docs/v1/api/types/AtomConfig.mdx diff --git a/docs/docs/api/types/AtomGetters.mdx b/docs/docs/v1/api/types/AtomGetters.mdx similarity index 100% rename from docs/docs/api/types/AtomGetters.mdx rename to docs/docs/v1/api/types/AtomGetters.mdx diff --git a/docs/docs/api/types/AtomInstanceTtl.mdx b/docs/docs/v1/api/types/AtomInstanceTtl.mdx similarity index 100% rename from docs/docs/api/types/AtomInstanceTtl.mdx rename to docs/docs/v1/api/types/AtomInstanceTtl.mdx diff --git a/docs/docs/api/types/AtomSelector.mdx b/docs/docs/v1/api/types/AtomSelector.mdx similarity index 100% rename from docs/docs/api/types/AtomSelector.mdx rename to docs/docs/v1/api/types/AtomSelector.mdx diff --git a/docs/docs/api/types/AtomSelectorConfig.mdx b/docs/docs/v1/api/types/AtomSelectorConfig.mdx similarity index 100% rename from docs/docs/api/types/AtomSelectorConfig.mdx rename to docs/docs/v1/api/types/AtomSelectorConfig.mdx diff --git a/docs/docs/api/types/DependentCallback.mdx b/docs/docs/v1/api/types/DependentCallback.mdx similarity index 100% rename from docs/docs/api/types/DependentCallback.mdx rename to docs/docs/v1/api/types/DependentCallback.mdx diff --git a/docs/docs/api/types/EcosystemConfig.mdx b/docs/docs/v1/api/types/EcosystemConfig.mdx similarity index 100% rename from docs/docs/api/types/EcosystemConfig.mdx rename to docs/docs/v1/api/types/EcosystemConfig.mdx diff --git a/docs/docs/api/types/EvaluationReason.mdx b/docs/docs/v1/api/types/EvaluationReason.mdx similarity index 100% rename from docs/docs/api/types/EvaluationReason.mdx rename to docs/docs/v1/api/types/EvaluationReason.mdx diff --git a/docs/docs/api/types/HierarchyDescriptor.mdx b/docs/docs/v1/api/types/HierarchyDescriptor.mdx similarity index 100% rename from docs/docs/api/types/HierarchyDescriptor.mdx rename to docs/docs/v1/api/types/HierarchyDescriptor.mdx diff --git a/docs/docs/api/types/PromiseState.mdx b/docs/docs/v1/api/types/PromiseState.mdx similarity index 100% rename from docs/docs/api/types/PromiseState.mdx rename to docs/docs/v1/api/types/PromiseState.mdx diff --git a/docs/docs/api/types/Reducer.mdx b/docs/docs/v1/api/types/Reducer.mdx similarity index 100% rename from docs/docs/api/types/Reducer.mdx rename to docs/docs/v1/api/types/Reducer.mdx diff --git a/docs/docs/api/types/ReducerBuilder.mdx b/docs/docs/v1/api/types/ReducerBuilder.mdx similarity index 100% rename from docs/docs/api/types/ReducerBuilder.mdx rename to docs/docs/v1/api/types/ReducerBuilder.mdx diff --git a/docs/docs/api/types/Settable.mdx b/docs/docs/v1/api/types/Settable.mdx similarity index 100% rename from docs/docs/api/types/Settable.mdx rename to docs/docs/v1/api/types/Settable.mdx diff --git a/docs/docs/api/types/StoreEffect.mdx b/docs/docs/v1/api/types/StoreEffect.mdx similarity index 100% rename from docs/docs/api/types/StoreEffect.mdx rename to docs/docs/v1/api/types/StoreEffect.mdx diff --git a/docs/docs/api/types/Subscriber.mdx b/docs/docs/v1/api/types/Subscriber.mdx similarity index 100% rename from docs/docs/api/types/Subscriber.mdx rename to docs/docs/v1/api/types/Subscriber.mdx diff --git a/docs/docs/api/types/Subscription.mdx b/docs/docs/v1/api/types/Subscription.mdx similarity index 100% rename from docs/docs/api/types/Subscription.mdx rename to docs/docs/v1/api/types/Subscription.mdx diff --git a/docs/docs/api/utils/action-chain-utils.mdx b/docs/docs/v1/api/utils/action-chain-utils.mdx similarity index 100% rename from docs/docs/api/utils/action-chain-utils.mdx rename to docs/docs/v1/api/utils/action-chain-utils.mdx diff --git a/docs/docs/api/utils/internal-utils.mdx b/docs/docs/v1/api/utils/internal-utils.mdx similarity index 100% rename from docs/docs/api/utils/internal-utils.mdx rename to docs/docs/v1/api/utils/internal-utils.mdx diff --git a/docs/docs/api/utils/is.mdx b/docs/docs/v1/api/utils/is.mdx similarity index 100% rename from docs/docs/api/utils/is.mdx rename to docs/docs/v1/api/utils/is.mdx diff --git a/docs/docs/api/utils/zeduxTypes.mdx b/docs/docs/v1/api/utils/zeduxTypes.mdx similarity index 100% rename from docs/docs/api/utils/zeduxTypes.mdx rename to docs/docs/v1/api/utils/zeduxTypes.mdx diff --git a/docs/docs/v1/index.mdx b/docs/docs/v1/index.mdx new file mode 100644 index 00000000..4a6add75 --- /dev/null +++ b/docs/docs/v1/index.mdx @@ -0,0 +1,18 @@ +--- +id: index +title: v1 Documentation +slug: / +sidebar_label: Overview +--- + +# Zedux v1 Documentation + +Welcome to the v1 documentation. This is for the old store-based API. For the new signal-based API, see the [v2 documentation](/docs/v2/). + +## Getting Started + +The complete v1 documentation starts at [Quick Start](/docs/v1/walkthrough/quick-start). + +## Migration Guide + +If you're upgrading from v1 to v2, see the [Migration Guide](/docs/v1/migrations/v2). diff --git a/docs/docs/migrations/v2.mdx b/docs/docs/v1/migrations/v2.mdx similarity index 100% rename from docs/docs/migrations/v2.mdx rename to docs/docs/v1/migrations/v2.mdx diff --git a/docs/docs/packages/immer.mdx b/docs/docs/v1/packages/immer.mdx similarity index 100% rename from docs/docs/packages/immer.mdx rename to docs/docs/v1/packages/immer.mdx diff --git a/docs/docs/packages/machines/MachineState.mdx b/docs/docs/v1/packages/machines/MachineState.mdx similarity index 100% rename from docs/docs/packages/machines/MachineState.mdx rename to docs/docs/v1/packages/machines/MachineState.mdx diff --git a/docs/docs/packages/machines/MachineStore.mdx b/docs/docs/v1/packages/machines/MachineStore.mdx similarity index 100% rename from docs/docs/packages/machines/MachineStore.mdx rename to docs/docs/v1/packages/machines/MachineStore.mdx diff --git a/docs/docs/packages/machines/injectMachineStore.mdx b/docs/docs/v1/packages/machines/injectMachineStore.mdx similarity index 100% rename from docs/docs/packages/machines/injectMachineStore.mdx rename to docs/docs/v1/packages/machines/injectMachineStore.mdx diff --git a/docs/docs/packages/machines/overview.mdx b/docs/docs/v1/packages/machines/overview.mdx similarity index 100% rename from docs/docs/packages/machines/overview.mdx rename to docs/docs/v1/packages/machines/overview.mdx diff --git a/docs/docs/packages/machines/walkthrough.mdx b/docs/docs/v1/packages/machines/walkthrough.mdx similarity index 100% rename from docs/docs/packages/machines/walkthrough.mdx rename to docs/docs/v1/packages/machines/walkthrough.mdx diff --git a/docs/docs/walkthrough/atom-apis.mdx b/docs/docs/v1/walkthrough/atom-apis.mdx similarity index 100% rename from docs/docs/walkthrough/atom-apis.mdx rename to docs/docs/v1/walkthrough/atom-apis.mdx diff --git a/docs/docs/walkthrough/atom-getters.mdx b/docs/docs/v1/walkthrough/atom-getters.mdx similarity index 100% rename from docs/docs/walkthrough/atom-getters.mdx rename to docs/docs/v1/walkthrough/atom-getters.mdx diff --git a/docs/docs/walkthrough/atom-instances.mdx b/docs/docs/v1/walkthrough/atom-instances.mdx similarity index 100% rename from docs/docs/walkthrough/atom-instances.mdx rename to docs/docs/v1/walkthrough/atom-instances.mdx diff --git a/docs/docs/walkthrough/atom-state.mdx b/docs/docs/v1/walkthrough/atom-state.mdx similarity index 100% rename from docs/docs/walkthrough/atom-state.mdx rename to docs/docs/v1/walkthrough/atom-state.mdx diff --git a/docs/docs/walkthrough/configuring-atoms.mdx b/docs/docs/v1/walkthrough/configuring-atoms.mdx similarity index 100% rename from docs/docs/walkthrough/configuring-atoms.mdx rename to docs/docs/v1/walkthrough/configuring-atoms.mdx diff --git a/docs/docs/walkthrough/custom-injectors.mdx b/docs/docs/v1/walkthrough/custom-injectors.mdx similarity index 100% rename from docs/docs/walkthrough/custom-injectors.mdx rename to docs/docs/v1/walkthrough/custom-injectors.mdx diff --git a/docs/docs/walkthrough/destruction.mdx b/docs/docs/v1/walkthrough/destruction.mdx similarity index 100% rename from docs/docs/walkthrough/destruction.mdx rename to docs/docs/v1/walkthrough/destruction.mdx diff --git a/docs/docs/walkthrough/ecosystems.mdx b/docs/docs/v1/walkthrough/ecosystems.mdx similarity index 100% rename from docs/docs/walkthrough/ecosystems.mdx rename to docs/docs/v1/walkthrough/ecosystems.mdx diff --git a/docs/docs/walkthrough/overrides.mdx b/docs/docs/v1/walkthrough/overrides.mdx similarity index 100% rename from docs/docs/walkthrough/overrides.mdx rename to docs/docs/v1/walkthrough/overrides.mdx diff --git a/docs/docs/walkthrough/query-atoms.mdx b/docs/docs/v1/walkthrough/query-atoms.mdx similarity index 100% rename from docs/docs/walkthrough/query-atoms.mdx rename to docs/docs/v1/walkthrough/query-atoms.mdx diff --git a/docs/docs/walkthrough/quick-start.mdx b/docs/docs/v1/walkthrough/quick-start.mdx similarity index 100% rename from docs/docs/walkthrough/quick-start.mdx rename to docs/docs/v1/walkthrough/quick-start.mdx diff --git a/docs/docs/walkthrough/react-context.mdx b/docs/docs/v1/walkthrough/react-context.mdx similarity index 100% rename from docs/docs/walkthrough/react-context.mdx rename to docs/docs/v1/walkthrough/react-context.mdx diff --git a/docs/docs/walkthrough/resets.mdx b/docs/docs/v1/walkthrough/resets.mdx similarity index 100% rename from docs/docs/walkthrough/resets.mdx rename to docs/docs/v1/walkthrough/resets.mdx diff --git a/docs/docs/walkthrough/selectors.mdx b/docs/docs/v1/walkthrough/selectors.mdx similarity index 100% rename from docs/docs/walkthrough/selectors.mdx rename to docs/docs/v1/walkthrough/selectors.mdx diff --git a/docs/docs/walkthrough/side-effects.mdx b/docs/docs/v1/walkthrough/side-effects.mdx similarity index 100% rename from docs/docs/walkthrough/side-effects.mdx rename to docs/docs/v1/walkthrough/side-effects.mdx diff --git a/docs/docs/walkthrough/stores.mdx b/docs/docs/v1/walkthrough/stores.mdx similarity index 100% rename from docs/docs/walkthrough/stores.mdx rename to docs/docs/v1/walkthrough/stores.mdx diff --git a/docs/docs/walkthrough/suspense.mdx b/docs/docs/v1/walkthrough/suspense.mdx similarity index 100% rename from docs/docs/walkthrough/suspense.mdx rename to docs/docs/v1/walkthrough/suspense.mdx diff --git a/docs/docs/walkthrough/the-graph.mdx b/docs/docs/v1/walkthrough/the-graph.mdx similarity index 100% rename from docs/docs/walkthrough/the-graph.mdx rename to docs/docs/v1/walkthrough/the-graph.mdx diff --git a/docs/docs/v2/index.mdx b/docs/docs/v2/index.mdx new file mode 100644 index 00000000..91b3ad74 --- /dev/null +++ b/docs/docs/v2/index.mdx @@ -0,0 +1,20 @@ +--- +id: index +title: v2 Documentation +slug: / +sidebar_label: Overview +--- + +# Zedux v2 Documentation + +Welcome to the v2 documentation. This section is being actively written as v2 PRs are merged. + +As docs are completed, they will appear in the sidebar on the left. + +## Looking for v1 Docs? + +The complete v1 documentation is available at [/docs/v1/walkthrough/quick-start](/docs/v1/walkthrough/quick-start). + +## Migration Guide + +If you're upgrading from v1 to v2, see the [Migration Guide](/docs/v1/migrations/v2). diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index f8f99310..5286ba4f 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -62,7 +62,7 @@ module.exports = { }, items: [ { - to: 'docs/walkthrough/quick-start', + to: 'docs/v1/walkthrough/quick-start', activeBasePath: 'docs', label: 'Docs', position: 'left', @@ -78,6 +78,10 @@ module.exports = { label: 'Blog', position: 'left', }, + { + type: 'custom-versionSelector', + position: 'right', + }, { href: 'https://github.com/Omnistac/zedux', label: 'GitHub', @@ -97,11 +101,11 @@ module.exports = { items: [ { label: 'Walkthrough', - to: 'docs/walkthrough/quick-start', + to: 'docs/v1/walkthrough/quick-start', }, { label: 'API', - to: 'docs/api/api-overview', + to: 'docs/v1/api/api-overview', }, ], }, @@ -131,15 +135,54 @@ module.exports = { copyright: `Copyright © 2017-${new Date().getFullYear()} Omnistac. Built with Docusaurus.`, }, }, - plugins: [PathsPlugin], + plugins: [ + PathsPlugin, + + // v1 docs (frozen) + [ + '@docusaurus/plugin-content-docs', + { + id: 'v1', + path: 'docs/v1', + routeBasePath: 'docs/v1', + sidebarPath: require.resolve('./sidebars-v1.js'), + editUrl: 'https://github.com/Omnistac/zedux/edit/master/docs/docs/v1/', + }, + ], + + // v2 docs (current stable) + [ + '@docusaurus/plugin-content-docs', + { + id: 'v2', + path: 'docs/v2', + routeBasePath: 'docs/v2', + sidebarPath: require.resolve('./sidebars-v2.js'), + editUrl: 'https://github.com/Omnistac/zedux/edit/master/docs/docs/v2/', + }, + ], + + // next docs (unreleased/development) + [ + '@docusaurus/plugin-content-docs', + { + id: 'next', + path: 'docs/next', + routeBasePath: 'docs/next', + sidebarPath: require.resolve('./sidebars-next.js'), + editUrl: 'https://github.com/Omnistac/zedux/edit/master/docs/docs/next/', + }, + ], + + // Version resolver for unversioned /docs/... URLs + require.resolve('./plugins/docs-version-resolver'), + ], presets: [ [ '@docusaurus/preset-classic', { - docs: { - sidebarPath: require.resolve('./sidebars.js'), - editUrl: 'https://github.com/Omnistac/zedux/edit/master/docs/', - }, + // Docs are handled by the plugins above + docs: false, theme: { customCss: require.resolve('./src/css/custom.css'), }, diff --git a/docs/plugins/docs-version-resolver.js b/docs/plugins/docs-version-resolver.js new file mode 100644 index 00000000..d842b802 --- /dev/null +++ b/docs/plugins/docs-version-resolver.js @@ -0,0 +1,189 @@ +/** + * Docusaurus plugin for versioned documentation URL resolution + * + * This plugin creates routes for unversioned URLs (e.g., /docs/walkthrough/quick-start) + * that redirect to the appropriate versioned content based on: + * 1. Explicit redirects (for restructured content) + * 2. Current version's sidebar (if the doc is "ready") + * 3. Fallback to previous version with stale banner + */ + +const { currentVersion, fallbackOrder, redirects } = require('../version-map') + +// Import all sidebars +const sidebars = { + v1: require('../sidebars-v1'), + v2: require('../sidebars-v2'), + next: require('../sidebars-next'), +} + +/** + * Recursively extract all doc paths from sidebar items + */ +function extractPaths(items) { + const paths = [] + for (const item of items) { + if (typeof item === 'string') { + // Simple string reference: 'walkthrough/quick-start' + paths.push(item) + } else if (Array.isArray(item)) { + // Nested array - recurse into it + paths.push(...extractPaths(item)) + } else if (item.type === 'category' && item.items) { + // Category with nested items: { type: 'category', label: '...', items: [...] } + paths.push(...extractPaths(item.items)) + } else if (item.type === 'doc' && item.id) { + // Explicit doc reference: { type: 'doc', id: 'path' } + paths.push(item.id) + } else if (typeof item === 'object' && item !== null && !item.type) { + // Shorthand category: { Walkthrough: ['quick-start', ...] } + for (const value of Object.values(item)) { + if (Array.isArray(value)) { + paths.push(...extractPaths(value)) + } + } + } + // Ignore 'link', 'html', 'ref', etc. + } + return paths +} + +/** + * Extract all doc paths from a sidebar config + * Handles nested structures like { react: { About: [...], Walkthrough: [...] } } + */ +function extractSidebarPaths(sidebar) { + const allPaths = [] + + function processValue(value) { + if (Array.isArray(value)) { + // Array of items - extract doc paths + allPaths.push(...extractPaths(value)) + } else if (typeof value === 'object' && value !== null) { + // Nested object like { About: [...], Walkthrough: [...] } + for (const nested of Object.values(value)) { + processValue(nested) + } + } + } + + processValue(sidebar) + return new Set(allPaths) +} + +// Pre-compute sidebar paths for each version +const sidebarPaths = { + v1: extractSidebarPaths(sidebars.v1), + v2: extractSidebarPaths(sidebars.v2), + next: extractSidebarPaths(sidebars.next), +} + +/** + * Determine which version a doc path should resolve to + */ +function resolveVersion(docPath) { + // 1. Check explicit redirects first (for restructured content) + if (redirects[docPath]?.[currentVersion]) { + return { + type: 'redirect', + to: redirects[docPath][currentVersion], + } + } + + // 2. If it's in the current version's sidebar → use current (no banner) + if (sidebarPaths[currentVersion].has(docPath)) { + return { + type: 'current', + version: currentVersion, + path: `/docs/${currentVersion}/${docPath}`, + } + } + + // 3. Fallback: find the latest version that has it in sidebar + for (const version of fallbackOrder) { + if (version !== currentVersion && sidebarPaths[version].has(docPath)) { + return { + type: 'stale', + version, + path: `/docs/${version}/${docPath}`, + currentVersion, + } + } + } + + return { type: 'notfound' } +} + +/** + * Docusaurus plugin entry point + */ +module.exports = function docsVersionResolver(context, options) { + return { + name: 'docs-version-resolver', + + async contentLoaded({ actions }) { + const { addRoute, createData, setGlobalData } = actions + + // Expose version data to client-side components (e.g., VersionSelector) + setGlobalData({ + sidebarPaths: Object.fromEntries( + Object.entries(sidebarPaths).map(([v, paths]) => [v, [...paths]]) + ), + redirects, + currentVersion, + }) + + // Collect all unique paths across all versions + const allPaths = new Set([ + ...sidebarPaths.v1, + ...sidebarPaths.v2, + ...sidebarPaths.next, + ]) + + // Create a route for each path + for (const docPath of allPaths) { + const resolution = resolveVersion(docPath) + + // Skip paths that don't resolve to anything + if (resolution.type === 'notfound') { + continue + } + + // Create a data module with the resolution info + const dataPath = await createData( + `version-resolution-${docPath.replace(/\//g, '-')}.json`, + JSON.stringify(resolution) + ) + + // Add the unversioned route + addRoute({ + path: `/docs/${docPath}`, + component: '@site/src/components/VersionedDocRedirect', + modules: { + resolution: dataPath, + }, + exact: true, + }) + } + + // Also add a root /docs/ route that redirects to the current version + const rootResolution = await createData( + 'version-resolution-root.json', + JSON.stringify({ + type: 'current', + version: currentVersion, + path: `/docs/${currentVersion}/`, + }) + ) + + addRoute({ + path: '/docs', + component: '@site/src/components/VersionedDocRedirect', + modules: { + resolution: rootResolution, + }, + exact: true, + }) + }, + } +} diff --git a/docs/sidebars-next.js b/docs/sidebars-next.js new file mode 100644 index 00000000..b064854a --- /dev/null +++ b/docs/sidebars-next.js @@ -0,0 +1,18 @@ +// next (development) sidebar - for unreleased docs +// +// Docs added here live in docs/docs/next/ and are served at /docs/next/ +// e.g. docs/docs/next/walkthrough/ecosystems.mdx → /docs/next/walkthrough/ecosystems +// +// To enable the "next" option in the version selector dropdown, uncomment +// the entry in src/theme/NavbarItem/VersionSelector.tsx (not required). +module.exports = { + react: [ + 'index', // Remove this once we add real docs + // Uncomment and populate sections as we write next docs: + // { + // type: 'category', + // label: 'About', + // items: ['about/introduction'], + // }, + ], +} diff --git a/docs/sidebars-v1.js b/docs/sidebars-v1.js new file mode 100644 index 00000000..e6e24f84 --- /dev/null +++ b/docs/sidebars-v1.js @@ -0,0 +1,166 @@ +module.exports = { + react: [ + 'index', + { + About: [ + 'about/introduction', + 'about/recoil-comparison', + 'about/redux-comparison', + 'about/react-query-comparison', + ], + Walkthrough: [ + 'walkthrough/quick-start', + 'walkthrough/atom-state', + 'walkthrough/atom-instances', + 'walkthrough/atom-apis', + 'walkthrough/ecosystems', + 'walkthrough/the-graph', + 'walkthrough/overrides', + 'walkthrough/configuring-atoms', + 'walkthrough/atom-getters', + 'walkthrough/selectors', + 'walkthrough/destruction', + 'walkthrough/react-context', + 'walkthrough/suspense', + 'walkthrough/query-atoms', + 'walkthrough/stores', + 'walkthrough/side-effects', + 'walkthrough/custom-injectors', + 'walkthrough/resets', + ], + Advanced: [ + 'advanced/batching', + 'advanced/complex-params', + 'advanced/more-patterns', + 'advanced/persistence', + 'advanced/plugins', + 'advanced/ssr', + 'advanced/store-composition', + 'advanced/time-travel', + 'advanced/typescript-tips', + ], + API: [ + 'api/api-overview', + { + type: 'category', + label: 'Classes', + items: [ + 'api/classes/AtomApi', + 'api/classes/AtomInstance', + 'api/classes/AtomTemplate', + 'api/classes/Ecosystem', + 'api/classes/IonTemplate', + 'api/classes/SelectorCache', + 'api/classes/Selectors', + 'api/classes/Store', + 'api/classes/ZeduxPlugin', + ], + }, + { + type: 'category', + label: 'Components', + items: [ + 'api/components/AtomProvider', + 'api/components/EcosystemProvider', + ], + }, + { + type: 'category', + label: 'Factories', + items: [ + 'api/factories/actionFactory', + 'api/factories/api', + 'api/factories/atom', + 'api/factories/createEcosystem', + 'api/factories/createReducer', + 'api/factories/createStore', + 'api/factories/ion', + ], + }, + { + type: 'category', + label: 'Hooks', + items: [ + 'api/hooks/useAtomContext', + 'api/hooks/useAtomInstance', + 'api/hooks/useAtomSelector', + 'api/hooks/useAtomState', + 'api/hooks/useAtomValue', + 'api/hooks/useEcosystem', + ], + }, + { + type: 'category', + label: 'Injectors', + items: [ + 'api/injectors/injectAtomGetters', + 'api/injectors/injectAtomInstance', + 'api/injectors/injectAtomSelector', + 'api/injectors/injectAtomState', + 'api/injectors/injectAtomValue', + 'api/injectors/injectCallback', + 'api/injectors/injectEffect', + 'api/injectors/injectInvalidate', + 'api/injectors/injectMemo', + 'api/injectors/injectPromise', + 'api/injectors/injectRef', + 'api/injectors/injectSelf', + 'api/injectors/injectStore', + 'api/injectors/injectWhy', + ], + }, + { + type: 'category', + label: 'Types', + items: [ + 'api/types/Action', + 'api/types/ActionChain', + 'api/types/ActionFactory', + 'api/types/AtomConfig', + 'api/types/AtomGetters', + 'api/types/AtomInstanceTtl', + 'api/types/AtomSelector', + 'api/types/AtomSelectorConfig', + 'api/types/DependentCallback', + 'api/types/EcosystemConfig', + 'api/types/EvaluationReason', + 'api/types/HierarchyDescriptor', + 'api/types/PromiseState', + 'api/types/Reducer', + 'api/types/ReducerBuilder', + 'api/types/Settable', + 'api/types/StoreEffect', + 'api/types/Subscriber', + 'api/types/Subscription', + ], + }, + { + type: 'category', + label: 'Utils', + items: [ + 'api/utils/action-chain-utils', + 'api/utils/internal-utils', + 'api/utils/is', + 'api/utils/zeduxTypes', + ], + }, + 'api/glossary', + ], + Packages: [ + 'packages/immer', + { + type: 'category', + label: '@zedux/machines', + items: [ + 'packages/machines/overview', + 'packages/machines/walkthrough', + 'packages/machines/MachineStore', + 'packages/machines/injectMachineStore', + 'packages/machines/MachineState', + ], + }, + ], + 'Migration Guides': ['migrations/v2'], + }, + ], +} diff --git a/docs/sidebars-v2.js b/docs/sidebars-v2.js new file mode 100644 index 00000000..76e74bfd --- /dev/null +++ b/docs/sidebars-v2.js @@ -0,0 +1,59 @@ +// v2 sidebar - grabs the '🚧 v2 beta docs' section from sidebars.js +// +// Existing v2 PRs add their docs to `react['🚧 v2 beta docs']` in sidebars.js. +// This file simply extracts that section and uses it as the v2 sidebar. +// +// NOTE: This is a temporary setup. When all v2 docs PRs are merged, the OG +// sidebars.js file itself will be moved here (modified to contain only v2 items +// of course) +const baseSidebar = require('./sidebars') + +/** + * Recursively strip the 'v2/' prefix from all doc IDs in a sidebar structure. + * Handles strings, arrays, and nested objects. + * + * TODO: Remove this and the above NOTE when all v2 docs PRs are merged + */ +function stripV2Prefix(item) { + // String doc ID: 'v2/api/placeholder' → 'api/placeholder' + if (typeof item === 'string') { + return item.startsWith('v2/') ? item.slice(3) : item + } + + // Array of items + if (Array.isArray(item)) { + return item.map(stripV2Prefix) + } + + // Object (category, doc ref, or nested sidebar structure) + if (typeof item === 'object' && item !== null) { + const result = {} + + for (const [key, value] of Object.entries(item)) { + if (key === 'id' && typeof value === 'string') { + // Handle explicit doc id: { type: 'doc', id: 'v2/...' } + result[key] = stripV2Prefix(value) + } else if (key === 'items' || Array.isArray(value)) { + // Handle category items or any array value + result[key] = stripV2Prefix(value) + } else if (typeof value === 'object' && value !== null) { + // Recurse into nested objects (like { API: [...] }) + result[key] = stripV2Prefix(value) + } else { + // Keep other values as-is (label, type, etc.) + result[key] = value + } + } + + return result + } + + return item +} + +const v2Docs = baseSidebar.react['🚧 v2 beta docs'] || {} +const transformed = stripV2Prefix(v2Docs) + +module.exports = { + react: [transformed, 'index'], +} diff --git a/docs/src/components/Hero.tsx b/docs/src/components/Hero.tsx index b2f2a3aa..c1fd55d1 100644 --- a/docs/src/components/Hero.tsx +++ b/docs/src/components/Hero.tsx @@ -143,7 +143,7 @@ export const Hero = () => { Quick Start! @@ -165,7 +165,7 @@ export const Hero = () => { API Docs diff --git a/docs/src/components/LearningPaths.tsx b/docs/src/components/LearningPaths.tsx index e4df6da8..5d431b00 100644 --- a/docs/src/components/LearningPaths.tsx +++ b/docs/src/components/LearningPaths.tsx @@ -192,7 +192,7 @@ export const LearningPaths = () => { depth={8} ease={8} fun={6} - href={useBaseUrl('docs/walkthrough/quick-start')} + href={useBaseUrl('docs/v1/walkthrough/quick-start')} title="Walkthrough" > Take a gentle journey through Zedux' features @@ -202,7 +202,7 @@ export const LearningPaths = () => { depth={10} ease={2} fun={1} - href={useBaseUrl('docs/api/api-overview')} + href={useBaseUrl('docs/v1/api/api-overview')} title="API" > Dive into the comprehensive API docs diff --git a/docs/src/components/StaleBanner.tsx b/docs/src/components/StaleBanner.tsx new file mode 100644 index 00000000..eeb25170 --- /dev/null +++ b/docs/src/components/StaleBanner.tsx @@ -0,0 +1,65 @@ +import React from 'react' +import Link from '@docusaurus/Link' + +interface Props { + version: string + currentVersion: string +} + +/** + * Banner displayed when viewing documentation from a non-current version. + * Shows different messages for old versions vs unreleased (next) versions. + */ +export default function StaleBanner({ version, currentVersion }: Props) { + const isNext = version === 'next' + + return ( +
+ + + {isNext ? ( + // Info icon for unreleased + <> + + + + + ) : ( + // Warning icon for old versions + <> + + + + + )} + + + + {isNext ? ( + <> + You're viewing unreleased documentation. This page + may change before the next release.{' '} + + ) : ( + <> + You're viewing {version} documentation. This page + may be outdated or differ from the current version.{' '} + + )} + + View {currentVersion} docs → + + +
+ ) +} diff --git a/docs/src/components/VersionedDocRedirect.tsx b/docs/src/components/VersionedDocRedirect.tsx new file mode 100644 index 00000000..be3fe7b3 --- /dev/null +++ b/docs/src/components/VersionedDocRedirect.tsx @@ -0,0 +1,38 @@ +import React from 'react' +import { Redirect } from '@docusaurus/router' + +interface Resolution { + type: 'redirect' | 'current' | 'stale' | 'notfound' + to?: string + version?: string + path?: string + currentVersion?: string +} + +interface Props { + resolution: Resolution +} + +/** + * Component that handles redirection for unversioned doc URLs. + * Redirects to the appropriate versioned URL based on resolution config. + */ +export default function VersionedDocRedirect({ resolution }: Props) { + if (resolution.type === 'redirect') { + // Explicit redirect to a new location + return + } + + if (resolution.type === 'current') { + // Doc exists in current version - redirect without stale flag + return + } + + if (resolution.type === 'stale') { + // Doc only exists in older version - redirect with stale flag for banner + return + } + + // Fallback: redirect to docs root + return +} diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 332b2667..1d80695c 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -270,3 +270,93 @@ pre code { line-height: inherit; padding: 0; } + +/* Stale documentation banner */ +.stale-banner { + align-items: flex-start; + background-color: #fff3cd; + border: 1px solid #ffc107; + border-radius: var(--ifm-alert-border-radius); + color: #856404; + display: flex; + gap: 0.75rem; + margin-bottom: 1.5rem; + padding: 1rem; + position: sticky; + top: 50px; + z-index: 1; +} + +html[data-theme='dark'] .stale-banner { + background-color: rgba(255, 193, 7, 0.15); + border-color: rgba(255, 193, 7, 0.4); + color: #ffc107; +} + +.stale-banner__icon { + flex-shrink: 0; + margin-top: 0.1rem; +} + +.stale-banner__text { + line-height: 1.5; +} + +.stale-banner__text a { + color: inherit; + font-weight: 600; + text-decoration: underline; +} + +.stale-banner__text a:hover { + color: inherit; + opacity: 0.8; +} + +/* Unreleased (next) version banner - blue/info style */ +.stale-banner--next { + background-color: #cce5ff; + border-color: #004085; + color: #004085; +} + +html[data-theme='dark'] .stale-banner--next { + background-color: rgba(0, 123, 255, 0.15); + border-color: rgba(0, 123, 255, 0.4); + color: #6cb2ff; +} + +/* Version selector in navbar */ +.version-selector { + align-items: center; + align-self: stretch; + display: flex; +} + +.version-selector__select { + appearance: none; + background-color: transparent; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 0.5rem center; + border: none; + color: var(--ifm-font-color-base); + cursor: pointer; + font-size: 0.85rem; + height: 100%; + padding: 0.35rem 1.75rem 0.35rem 0.65rem; + transition: border-color 0.2s, background-color 0.2s; +} + +.version-selector__select:hover { + border-color: var(--ifm-color-primary); +} + +.version-selector__select:focus { + border-color: var(--ifm-color-primary); + outline: none; +} + +html[data-theme='dark'] .version-selector__select { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); +} diff --git a/docs/src/theme/DocItem/index.tsx b/docs/src/theme/DocItem/index.tsx new file mode 100644 index 00000000..fcac32d3 --- /dev/null +++ b/docs/src/theme/DocItem/index.tsx @@ -0,0 +1,33 @@ +import React from 'react' +import DocItem from '@theme-original/DocItem' +import type DocItemType from '@theme/DocItem' +import type { WrapperProps } from '@docusaurus/types' +import { useLocation } from '@docusaurus/router' +import StaleBanner from '@site/src/components/StaleBanner' +import { currentVersion } from '@site/version-map' + +type Props = WrapperProps + +/** + * Wrapper around DocItem that displays a version banner + * when viewing docs from a non-current version. + */ +export default function DocItemWrapper(props: Props): JSX.Element { + const location = useLocation() + + // Extract version from URL path (e.g., /docs/v1/... → v1) + const versionMatch = location.pathname.match(/\/docs\/(v\d+|next)\//) + const version = versionMatch?.[1] + + // Show banner for any version that isn't the current version + const showBanner = version && version !== currentVersion + + return ( + <> + {showBanner && ( + + )} + + + ) +} diff --git a/docs/src/theme/NavbarItem/ComponentTypes.tsx b/docs/src/theme/NavbarItem/ComponentTypes.tsx new file mode 100644 index 00000000..c3f2d2b5 --- /dev/null +++ b/docs/src/theme/NavbarItem/ComponentTypes.tsx @@ -0,0 +1,7 @@ +import ComponentTypes from '@theme-original/NavbarItem/ComponentTypes' +import VersionSelector from './VersionSelector' + +export default { + ...ComponentTypes, + 'custom-versionSelector': VersionSelector, +} diff --git a/docs/src/theme/NavbarItem/VersionSelector.tsx b/docs/src/theme/NavbarItem/VersionSelector.tsx new file mode 100644 index 00000000..b505ac1b --- /dev/null +++ b/docs/src/theme/NavbarItem/VersionSelector.tsx @@ -0,0 +1,74 @@ +import React from 'react' +import { useLocation } from '@docusaurus/router' +import { usePluginData } from '@docusaurus/useGlobalData' +import { currentVersion } from '@site/version-map' + +const versions = [ + { label: 'v2 (latest)', value: 'v2' }, + { label: 'v1', value: 'v1' }, + // { label: 'next (unreleased)', value: 'next' }, +] + +/** + * Version selector dropdown for the navbar. + * Resolves cross-version navigation using sidebar paths and redirects from the + * docs-version-resolver plugin. + */ +export default function VersionSelector() { + const location = useLocation() + const { sidebarPaths, redirects } = usePluginData( + 'docs-version-resolver' + ) as { + sidebarPaths: Record + redirects: Record> + currentVersion: string + } + + // Extract current version from URL + const versionMatch = location.pathname.match(/\/docs\/(v\d+|next)\//) + const activeVersion = versionMatch?.[1] || currentVersion + + // Extract the doc path after the version (e.g., /docs/v1/walkthrough/quick-start -> walkthrough/quick-start) + const docPathMatch = location.pathname.match(/\/docs\/(?:v\d+|next)\/(.*)/) + const docPath = docPathMatch?.[1]?.replace(/\/$/, '') || '' + + const handleVersionChange = (e: React.ChangeEvent) => { + const newVersion = e.target.value + if (newVersion === activeVersion) return + + // 1. Check explicit redirects + const redirect = redirects[docPath]?.[newVersion] + if (redirect) { + window.location.href = redirect + return + } + + // 2. Check if the current path exists in the target version's sidebar + const targetPaths = sidebarPaths[newVersion] || [] + if (targetPaths.includes(docPath)) { + window.location.href = `/docs/${newVersion}/${docPath}` + return + } + + // 3. Fall back to the target version's root + window.location.href = `/docs/${newVersion}/` + } + + return ( +
+ +
+ ) +} diff --git a/docs/version-map.js b/docs/version-map.js new file mode 100644 index 00000000..307d28e0 --- /dev/null +++ b/docs/version-map.js @@ -0,0 +1,31 @@ +/** + * Documentation Version Configuration + * + * This file controls how unversioned URLs (e.g., /docs/walkthrough/quick-start) + * resolve to versioned content. + * + * The sidebar files (sidebars-v1.js, sidebars-v2.js, etc.) are the source of + * truth for which docs are "ready" in each version. Adding a doc to a sidebar + * automatically makes it the target for unversioned URLs. + */ +module.exports = { + // Which version unversioned URLs should prefer + // Change this when releasing a new major version + currentVersion: 'v2', + + // Order of versions for fallback resolution (newest to oldest) + // 'next' is excluded - it's for development only + fallbackOrder: ['v2', 'v1'], + + // Explicit redirects for pages that have been removed or restructured + // Only needed when the path no longer exists in currentVersion's sidebar + // and you want to redirect to a different location instead of showing stale content + // + // Format: + // 'old/path': { v2: '/docs/v2/new/path' } + // + // Example: + // 'advanced/old-feature': { v2: '/docs/v2/advanced/new-feature' } + // + redirects: {}, +}