zustand-iten 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,84 @@
1
1
  # zustand-iten
2
2
 
3
- Reserved package for the upcoming Zustand adapter for `iten`.
3
+ Zustand bindings for `iten`, an ultralight typed in-memory router for embedded JavaScript apps.
4
4
 
5
- Use `iten-core` today for framework-agnostic routing.
5
+ This package exposes a scoped vanilla Zustand store backed by `iten-core`. Use it when routing should live in a Zustand store, or when you want a framework-light adapter surface that can be consumed by Zustand selectors.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install zustand-iten zustand
11
+ ```
12
+
13
+ `zustand-iten` depends on `iten-core`. Install `@tanstack/react-query` only when route loaders call `queryClient.ensureQueryData`.
14
+
15
+ ## Quick Start
16
+
17
+ ```ts
18
+ import {
19
+ createRouter,
20
+ defineRoutes,
21
+ route,
22
+ } from 'zustand-iten'
23
+
24
+ const routes = defineRoutes({
25
+ home: route(),
26
+ project: route<{ id: string }>(),
27
+ settings: route(),
28
+ })
29
+
30
+ const router = createRouter({
31
+ routes,
32
+ initial: { name: 'home' },
33
+ })
34
+
35
+ await router.navigate({ target: router.to({ name: 'project', params: { id: 'alpha' } }) })
36
+
37
+ router.store.getState().route
38
+ router.store.getState().canGoBack
39
+ ```
40
+
41
+ ## Store Shape
42
+
43
+ The Zustand store state is the core router state plus router actions:
44
+
45
+ - `route`
46
+ - `pendingRoute`
47
+ - `history`
48
+ - `error`
49
+ - `isNavigating`
50
+ - `canGoBack`
51
+ - `navigate(input)`
52
+ - `goBack()`
53
+ - `dispose()`
54
+
55
+ ```ts
56
+ const unsub = router.store.subscribe((state) => {
57
+ console.log(state.route)
58
+ })
59
+
60
+ unsub()
61
+ ```
62
+
63
+ ## URL Sync
64
+
65
+ `zustand-iten/url` keeps URL support explicit and optional.
66
+
67
+ ```ts
68
+ import { createUrlSync } from 'zustand-iten/url'
69
+
70
+ const sync = createUrlSync({
71
+ router,
72
+ parse: ({ url }) => parseRoute(url),
73
+ format: ({ route, url }) => formatRoute({ route, url }),
74
+ })
75
+
76
+ await sync.hydrate()
77
+ sync.start()
78
+ ```
79
+
80
+ ## Entry Points
81
+
82
+ - `zustand-iten`: scoped Zustand store, route utilities, and types
83
+ - `zustand-iten/url`: optional URL sync adapter
84
+ - `zustand-iten/utils`: route factories, guards, matching, and type utilities
@@ -0,0 +1,65 @@
1
+ let iten_core = require("iten-core");
2
+ let zustand_vanilla = require("zustand/vanilla");
3
+ //#region src/create-router.ts
4
+ function createRouter(config) {
5
+ const getCtx = () => {
6
+ if (typeof config.context === "function") return config.context();
7
+ return config.context ?? {};
8
+ };
9
+ const core = (0, iten_core.createItenCore)({
10
+ initial: config.initial,
11
+ routes: config.routes,
12
+ routeConfig: config.routeConfig,
13
+ maxHistoryLength: config.maxHistoryLength,
14
+ queryClient: config.queryClient,
15
+ getCtx
16
+ });
17
+ let stopCoreSubscription;
18
+ function makeState({ state, actions }) {
19
+ return {
20
+ ...state,
21
+ ...actions
22
+ };
23
+ }
24
+ const actions = {
25
+ navigate: async (input) => {
26
+ await core.navigate(input);
27
+ store.setState(makeState({
28
+ state: core.getState(),
29
+ actions
30
+ }), true);
31
+ },
32
+ goBack: () => {
33
+ core.goBack();
34
+ store.setState(makeState({
35
+ state: core.getState(),
36
+ actions
37
+ }), true);
38
+ },
39
+ dispose: () => {
40
+ stopCoreSubscription?.();
41
+ stopCoreSubscription = void 0;
42
+ core.dispose();
43
+ }
44
+ };
45
+ const store = (0, zustand_vanilla.createStore)(() => makeState({
46
+ state: core.getState(),
47
+ actions
48
+ }));
49
+ stopCoreSubscription = core.subscribe({ listener: (state) => {
50
+ store.setState(makeState({
51
+ state,
52
+ actions
53
+ }), true);
54
+ } });
55
+ return {
56
+ store,
57
+ core,
58
+ to: core.to,
59
+ navigate: actions.navigate,
60
+ goBack: actions.goBack,
61
+ dispose: actions.dispose
62
+ };
63
+ }
64
+ //#endregion
65
+ exports.createRouter = createRouter;
@@ -0,0 +1,18 @@
1
+ import { ZustandRouterActions, ZustandRouterConfig, ZustandRouterStore } from "./types.cjs";
2
+ import { InferRoutes, ItenCore, RouteDefinitions, RouteFactory, RouteMapDef } from "iten-core";
3
+
4
+ //#region src/create-router.d.ts
5
+ type ZustandRouter<M extends RouteMapDef, _Ctx = unknown> = {
6
+ store: ZustandRouterStore<M>;
7
+ core: ItenCore<M>;
8
+ to: RouteFactory<M>;
9
+ navigate: ZustandRouterActions<M>["navigate"];
10
+ goBack: ZustandRouterActions<M>["goBack"];
11
+ dispose: ZustandRouterActions<M>["dispose"];
12
+ };
13
+ declare function createRouter<const Defs extends RouteDefinitions, Ctx = unknown>(config: ZustandRouterConfig<InferRoutes<Defs>, Ctx> & {
14
+ routes: Defs;
15
+ }): ZustandRouter<InferRoutes<Defs>, Ctx>;
16
+ declare function createRouter<M extends RouteMapDef, Ctx = unknown>(config: ZustandRouterConfig<M, Ctx>): ZustandRouter<M, Ctx>;
17
+ //#endregion
18
+ export { ZustandRouter, createRouter };
@@ -0,0 +1,18 @@
1
+ import { ZustandRouterActions, ZustandRouterConfig, ZustandRouterStore } from "./types.js";
2
+ import { InferRoutes, ItenCore, RouteDefinitions, RouteFactory, RouteMapDef } from "iten-core";
3
+
4
+ //#region src/create-router.d.ts
5
+ type ZustandRouter<M extends RouteMapDef, _Ctx = unknown> = {
6
+ store: ZustandRouterStore<M>;
7
+ core: ItenCore<M>;
8
+ to: RouteFactory<M>;
9
+ navigate: ZustandRouterActions<M>["navigate"];
10
+ goBack: ZustandRouterActions<M>["goBack"];
11
+ dispose: ZustandRouterActions<M>["dispose"];
12
+ };
13
+ declare function createRouter<const Defs extends RouteDefinitions, Ctx = unknown>(config: ZustandRouterConfig<InferRoutes<Defs>, Ctx> & {
14
+ routes: Defs;
15
+ }): ZustandRouter<InferRoutes<Defs>, Ctx>;
16
+ declare function createRouter<M extends RouteMapDef, Ctx = unknown>(config: ZustandRouterConfig<M, Ctx>): ZustandRouter<M, Ctx>;
17
+ //#endregion
18
+ export { ZustandRouter, createRouter };
@@ -0,0 +1,65 @@
1
+ import { createItenCore } from "iten-core";
2
+ import { createStore } from "zustand/vanilla";
3
+ //#region src/create-router.ts
4
+ function createRouter(config) {
5
+ const getCtx = () => {
6
+ if (typeof config.context === "function") return config.context();
7
+ return config.context ?? {};
8
+ };
9
+ const core = createItenCore({
10
+ initial: config.initial,
11
+ routes: config.routes,
12
+ routeConfig: config.routeConfig,
13
+ maxHistoryLength: config.maxHistoryLength,
14
+ queryClient: config.queryClient,
15
+ getCtx
16
+ });
17
+ let stopCoreSubscription;
18
+ function makeState({ state, actions }) {
19
+ return {
20
+ ...state,
21
+ ...actions
22
+ };
23
+ }
24
+ const actions = {
25
+ navigate: async (input) => {
26
+ await core.navigate(input);
27
+ store.setState(makeState({
28
+ state: core.getState(),
29
+ actions
30
+ }), true);
31
+ },
32
+ goBack: () => {
33
+ core.goBack();
34
+ store.setState(makeState({
35
+ state: core.getState(),
36
+ actions
37
+ }), true);
38
+ },
39
+ dispose: () => {
40
+ stopCoreSubscription?.();
41
+ stopCoreSubscription = void 0;
42
+ core.dispose();
43
+ }
44
+ };
45
+ const store = createStore(() => makeState({
46
+ state: core.getState(),
47
+ actions
48
+ }));
49
+ stopCoreSubscription = core.subscribe({ listener: (state) => {
50
+ store.setState(makeState({
51
+ state,
52
+ actions
53
+ }), true);
54
+ } });
55
+ return {
56
+ store,
57
+ core,
58
+ to: core.to,
59
+ navigate: actions.navigate,
60
+ goBack: actions.goBack,
61
+ dispose: actions.dispose
62
+ };
63
+ }
64
+ //#endregion
65
+ export { createRouter };
package/dist/index.cjs ADDED
@@ -0,0 +1,46 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_create_router = require("./create-router.cjs");
3
+ let iten_core = require("iten-core");
4
+ Object.defineProperty(exports, "createRoute", {
5
+ enumerable: true,
6
+ get: function() {
7
+ return iten_core.createRoute;
8
+ }
9
+ });
10
+ exports.createRouter = require_create_router.createRouter;
11
+ Object.defineProperty(exports, "defineRouteConfig", {
12
+ enumerable: true,
13
+ get: function() {
14
+ return iten_core.defineRouteConfig;
15
+ }
16
+ });
17
+ Object.defineProperty(exports, "defineRoutes", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return iten_core.defineRoutes;
21
+ }
22
+ });
23
+ Object.defineProperty(exports, "isRoute", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return iten_core.isRoute;
27
+ }
28
+ });
29
+ Object.defineProperty(exports, "isRouteName", {
30
+ enumerable: true,
31
+ get: function() {
32
+ return iten_core.isRouteName;
33
+ }
34
+ });
35
+ Object.defineProperty(exports, "matchRoute", {
36
+ enumerable: true,
37
+ get: function() {
38
+ return iten_core.matchRoute;
39
+ }
40
+ });
41
+ Object.defineProperty(exports, "route", {
42
+ enumerable: true,
43
+ get: function() {
44
+ return iten_core.route;
45
+ }
46
+ });
@@ -0,0 +1,4 @@
1
+ import { InferRoutes, NoParams, QueryClientLike, RouteConfigMap, RouteDefinition, RouteDefinitions, RouteMap, RouteMapDef, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion, RouterError, RouterState, ZustandRouterActions, ZustandRouterConfig, ZustandRouterState, ZustandRouterStore } from "./types.cjs";
2
+ import { ZustandRouter, createRouter } from "./create-router.cjs";
3
+ import { createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route } from "iten-core";
4
+ export { type InferRoutes, type NoParams, type QueryClientLike, type RouteConfigMap, type RouteDefinition, type RouteDefinitions, type RouteMap, type RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion, type RouterError, type RouterState, type ZustandRouter, type ZustandRouterActions, type ZustandRouterConfig, type ZustandRouterState, type ZustandRouterStore, createRoute, createRouter, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route };
@@ -0,0 +1,4 @@
1
+ import { InferRoutes, NoParams, QueryClientLike, RouteConfigMap, RouteDefinition, RouteDefinitions, RouteMap, RouteMapDef, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion, RouterError, RouterState, ZustandRouterActions, ZustandRouterConfig, ZustandRouterState, ZustandRouterStore } from "./types.js";
2
+ import { ZustandRouter, createRouter } from "./create-router.js";
3
+ import { createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route } from "iten-core";
4
+ export { type InferRoutes, type NoParams, type QueryClientLike, type RouteConfigMap, type RouteDefinition, type RouteDefinitions, type RouteMap, type RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion, type RouterError, type RouterState, type ZustandRouter, type ZustandRouterActions, type ZustandRouterConfig, type ZustandRouterState, type ZustandRouterStore, createRoute, createRouter, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route };
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import { createRouter } from "./create-router.mjs";
2
+ import { createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route } from "iten-core";
3
+ export { createRoute, createRouter, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route };
@@ -0,0 +1,21 @@
1
+ import { InferRoutes as InferRoutes$1, NavigateInput, NoParams, QueryClientLike, RouteConfigMap, RouteDefinition, RouteDefinitions as RouteDefinitions$1, RouteMap, RouteMapDef as RouteMapDef$1, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion, RouterError, RouterState } from "iten-core";
2
+ import { StoreApi } from "zustand/vanilla";
3
+
4
+ //#region src/types.d.ts
5
+ type ZustandRouterConfig<M extends RouteMapDef$1, Ctx = unknown> = {
6
+ initial: RouteUnion<M> | null;
7
+ routes?: RouteDefinitions$1 | undefined;
8
+ routeConfig?: RouteConfigMap<M, Ctx> | undefined;
9
+ maxHistoryLength?: number | undefined;
10
+ context?: Ctx | (() => Ctx) | undefined;
11
+ queryClient?: QueryClientLike | null | undefined;
12
+ };
13
+ type ZustandRouterActions<M extends RouteMapDef$1> = {
14
+ navigate: (input: NavigateInput<M>) => Promise<void>;
15
+ goBack: () => void;
16
+ dispose: () => void;
17
+ };
18
+ type ZustandRouterState<M extends RouteMapDef$1> = RouterState<M> & ZustandRouterActions<M>;
19
+ type ZustandRouterStore<M extends RouteMapDef$1> = StoreApi<ZustandRouterState<M>>;
20
+ //#endregion
21
+ export { type InferRoutes$1 as InferRoutes, type NoParams, type QueryClientLike, type RouteConfigMap, type RouteDefinition, type RouteDefinitions$1 as RouteDefinitions, type RouteMap, type RouteMapDef$1 as RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion, type RouterError, type RouterState, ZustandRouterActions, ZustandRouterConfig, ZustandRouterState, ZustandRouterStore };
@@ -0,0 +1,21 @@
1
+ import { InferRoutes as InferRoutes$1, NavigateInput, NoParams, QueryClientLike, RouteConfigMap, RouteDefinition, RouteDefinitions as RouteDefinitions$1, RouteMap, RouteMapDef as RouteMapDef$1, RouteMatcher, RouteName, RouteOf, RouteParams, RouteUnion, RouterError, RouterState } from "iten-core";
2
+ import { StoreApi } from "zustand/vanilla";
3
+
4
+ //#region src/types.d.ts
5
+ type ZustandRouterConfig<M extends RouteMapDef$1, Ctx = unknown> = {
6
+ initial: RouteUnion<M> | null;
7
+ routes?: RouteDefinitions$1 | undefined;
8
+ routeConfig?: RouteConfigMap<M, Ctx> | undefined;
9
+ maxHistoryLength?: number | undefined;
10
+ context?: Ctx | (() => Ctx) | undefined;
11
+ queryClient?: QueryClientLike | null | undefined;
12
+ };
13
+ type ZustandRouterActions<M extends RouteMapDef$1> = {
14
+ navigate: (input: NavigateInput<M>) => Promise<void>;
15
+ goBack: () => void;
16
+ dispose: () => void;
17
+ };
18
+ type ZustandRouterState<M extends RouteMapDef$1> = RouterState<M> & ZustandRouterActions<M>;
19
+ type ZustandRouterStore<M extends RouteMapDef$1> = StoreApi<ZustandRouterState<M>>;
20
+ //#endregion
21
+ export { type InferRoutes$1 as InferRoutes, type NoParams, type QueryClientLike, type RouteConfigMap, type RouteDefinition, type RouteDefinitions$1 as RouteDefinitions, type RouteMap, type RouteMapDef$1 as RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion, type RouterError, type RouterState, ZustandRouterActions, ZustandRouterConfig, ZustandRouterState, ZustandRouterStore };
package/dist/url.cjs ADDED
@@ -0,0 +1,21 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let iten_core_url = require("iten-core/url");
3
+ //#region src/url.ts
4
+ function createUrlSync({ router, ...input }) {
5
+ const coreLike = {
6
+ getState: () => router.store.getState(),
7
+ to: router.to,
8
+ navigate: (navigateInput) => router.navigate(navigateInput),
9
+ goBack: () => router.goBack(),
10
+ subscribe: ({ listener }) => router.store.subscribe((state) => {
11
+ listener(state);
12
+ }),
13
+ dispose: () => {}
14
+ };
15
+ return (0, iten_core_url.createUrlSync)({
16
+ ...input,
17
+ router: coreLike
18
+ });
19
+ }
20
+ //#endregion
21
+ exports.createUrlSync = createUrlSync;
package/dist/url.d.cts ADDED
@@ -0,0 +1,14 @@
1
+ import { ZustandRouter } from "./create-router.cjs";
2
+ import { RouteMapDef } from "iten-core";
3
+ import { CreateUrlSyncInput as CreateUrlSyncInput$1, FormatUrlInput, ParseUrlInput, UrlHydrateInput, UrlParseErrorInput, UrlStartInput, UrlSubscribeInput, UrlSync, UrlSync as UrlSync$1, UrlWriteInput, UrlWriteMode } from "iten-core/url";
4
+
5
+ //#region src/url.d.ts
6
+ type CreateUrlSyncInput<M extends RouteMapDef> = Omit<CreateUrlSyncInput$1<M>, "router"> & {
7
+ router: ZustandRouter<M>;
8
+ };
9
+ declare function createUrlSync<M extends RouteMapDef>({
10
+ router,
11
+ ...input
12
+ }: CreateUrlSyncInput<M>): UrlSync$1<M>;
13
+ //#endregion
14
+ export { CreateUrlSyncInput, type FormatUrlInput, type ParseUrlInput, type UrlHydrateInput, type UrlParseErrorInput, type UrlStartInput, type UrlSubscribeInput, type UrlSync, type UrlWriteInput, type UrlWriteMode, createUrlSync };
package/dist/url.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { ZustandRouter } from "./create-router.js";
2
+ import { RouteMapDef } from "iten-core";
3
+ import { CreateUrlSyncInput as CreateUrlSyncInput$1, FormatUrlInput, ParseUrlInput, UrlHydrateInput, UrlParseErrorInput, UrlStartInput, UrlSubscribeInput, UrlSync, UrlSync as UrlSync$1, UrlWriteInput, UrlWriteMode } from "iten-core/url";
4
+
5
+ //#region src/url.d.ts
6
+ type CreateUrlSyncInput<M extends RouteMapDef> = Omit<CreateUrlSyncInput$1<M>, "router"> & {
7
+ router: ZustandRouter<M>;
8
+ };
9
+ declare function createUrlSync<M extends RouteMapDef>({
10
+ router,
11
+ ...input
12
+ }: CreateUrlSyncInput<M>): UrlSync$1<M>;
13
+ //#endregion
14
+ export { CreateUrlSyncInput, type FormatUrlInput, type ParseUrlInput, type UrlHydrateInput, type UrlParseErrorInput, type UrlStartInput, type UrlSubscribeInput, type UrlSync, type UrlWriteInput, type UrlWriteMode, createUrlSync };
package/dist/url.mjs ADDED
@@ -0,0 +1,20 @@
1
+ import { createUrlSync as createUrlSync$1 } from "iten-core/url";
2
+ //#region src/url.ts
3
+ function createUrlSync({ router, ...input }) {
4
+ const coreLike = {
5
+ getState: () => router.store.getState(),
6
+ to: router.to,
7
+ navigate: (navigateInput) => router.navigate(navigateInput),
8
+ goBack: () => router.goBack(),
9
+ subscribe: ({ listener }) => router.store.subscribe((state) => {
10
+ listener(state);
11
+ }),
12
+ dispose: () => {}
13
+ };
14
+ return createUrlSync$1({
15
+ ...input,
16
+ router: coreLike
17
+ });
18
+ }
19
+ //#endregion
20
+ export { createUrlSync };
package/dist/utils.cjs ADDED
@@ -0,0 +1,44 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let iten_core_utils = require("iten-core/utils");
3
+ Object.defineProperty(exports, "createRoute", {
4
+ enumerable: true,
5
+ get: function() {
6
+ return iten_core_utils.createRoute;
7
+ }
8
+ });
9
+ Object.defineProperty(exports, "defineRouteConfig", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return iten_core_utils.defineRouteConfig;
13
+ }
14
+ });
15
+ Object.defineProperty(exports, "defineRoutes", {
16
+ enumerable: true,
17
+ get: function() {
18
+ return iten_core_utils.defineRoutes;
19
+ }
20
+ });
21
+ Object.defineProperty(exports, "isRoute", {
22
+ enumerable: true,
23
+ get: function() {
24
+ return iten_core_utils.isRoute;
25
+ }
26
+ });
27
+ Object.defineProperty(exports, "isRouteName", {
28
+ enumerable: true,
29
+ get: function() {
30
+ return iten_core_utils.isRouteName;
31
+ }
32
+ });
33
+ Object.defineProperty(exports, "matchRoute", {
34
+ enumerable: true,
35
+ get: function() {
36
+ return iten_core_utils.matchRoute;
37
+ }
38
+ });
39
+ Object.defineProperty(exports, "route", {
40
+ enumerable: true,
41
+ get: function() {
42
+ return iten_core_utils.route;
43
+ }
44
+ });
@@ -0,0 +1,3 @@
1
+ import { InferRoutes, NoParams, RouteConfigMap, RouteMap, RouteMapDef, RouteUnion } from "iten-core";
2
+ import { RouteMatcher, RouteName, RouteOf, RouteParams, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route } from "iten-core/utils";
3
+ export { type InferRoutes, type NoParams, type RouteConfigMap, type RouteMap, type RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route };
@@ -0,0 +1,3 @@
1
+ import { InferRoutes, NoParams, RouteConfigMap, RouteMap, RouteMapDef, RouteUnion } from "iten-core";
2
+ import { RouteMatcher, RouteName, RouteOf, RouteParams, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route } from "iten-core/utils";
3
+ export { type InferRoutes, type NoParams, type RouteConfigMap, type RouteMap, type RouteMapDef, type RouteMatcher, type RouteName, type RouteOf, type RouteParams, type RouteUnion, createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route };
package/dist/utils.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route } from "iten-core/utils";
2
+ export { createRoute, defineRouteConfig, defineRoutes, isRoute, isRouteName, matchRoute, route };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zustand-iten",
3
- "version": "0.4.1",
4
- "description": "Zustand adapter for iten — ultralight in-memory router for embedded JS apps. Coming soon.",
3
+ "version": "0.5.0",
4
+ "description": "Zustand adapter for iten — ultralight in-memory router for embedded JS apps",
5
5
  "keywords": [
6
6
  "zustand",
7
7
  "router",
@@ -18,13 +18,69 @@
18
18
  "url": "https://github.com/andrew-bierman/iten/issues"
19
19
  },
20
20
  "homepage": "https://github.com/andrew-bierman/iten#readme",
21
- "main": "index.js",
21
+ "type": "module",
22
+ "sideEffects": false,
23
+ "exports": {
24
+ ".": {
25
+ "bun": "./src/index.ts",
26
+ "import": {
27
+ "types": "./dist/index.d.ts",
28
+ "default": "./dist/index.mjs"
29
+ },
30
+ "require": {
31
+ "types": "./dist/index.d.cts",
32
+ "default": "./dist/index.cjs"
33
+ }
34
+ },
35
+ "./utils": {
36
+ "bun": "./src/utils.ts",
37
+ "import": {
38
+ "types": "./dist/utils.d.ts",
39
+ "default": "./dist/utils.mjs"
40
+ },
41
+ "require": {
42
+ "types": "./dist/utils.d.cts",
43
+ "default": "./dist/utils.cjs"
44
+ }
45
+ },
46
+ "./url": {
47
+ "bun": "./src/url.ts",
48
+ "import": {
49
+ "types": "./dist/url.d.ts",
50
+ "default": "./dist/url.mjs"
51
+ },
52
+ "require": {
53
+ "types": "./dist/url.d.cts",
54
+ "default": "./dist/url.cjs"
55
+ }
56
+ }
57
+ },
58
+ "main": "./dist/index.cjs",
59
+ "module": "./dist/index.mjs",
60
+ "types": "./dist/index.d.ts",
22
61
  "files": [
23
- "index.js",
24
- "README.md"
62
+ "dist",
63
+ "src"
25
64
  ],
65
+ "scripts": {
66
+ "build": "tsdown",
67
+ "typecheck": "tsc --noEmit",
68
+ "typecheck:types": "bun run build && tsc -p tsconfig.type-tests.json",
69
+ "test": "bun test ./test"
70
+ },
71
+ "peerDependencies": {
72
+ "zustand": "^5.0.0"
73
+ },
74
+ "dependencies": {
75
+ "iten-core": "^0.5.0"
76
+ },
26
77
  "publishConfig": {
27
78
  "access": "public",
28
79
  "registry": "https://registry.npmjs.org/"
80
+ },
81
+ "devDependencies": {
82
+ "tsdown": "0.21.9",
83
+ "typescript": "^5.7.0",
84
+ "zustand": "^5.0.0"
29
85
  }
30
86
  }
@@ -0,0 +1,101 @@
1
+ import type {
2
+ InferRoutes,
3
+ ItenCore,
4
+ RouteDefinitions,
5
+ RouteFactory,
6
+ RouteMapDef,
7
+ RouterState,
8
+ } from 'iten-core'
9
+ import { createItenCore } from 'iten-core'
10
+ import { createStore } from 'zustand/vanilla'
11
+ import type {
12
+ ZustandRouterActions,
13
+ ZustandRouterConfig,
14
+ ZustandRouterState,
15
+ ZustandRouterStore,
16
+ } from './types.ts'
17
+
18
+ export type ZustandRouter<M extends RouteMapDef, _Ctx = unknown> = {
19
+ store: ZustandRouterStore<M>
20
+ core: ItenCore<M>
21
+ to: RouteFactory<M>
22
+ navigate: ZustandRouterActions<M>['navigate']
23
+ goBack: ZustandRouterActions<M>['goBack']
24
+ dispose: ZustandRouterActions<M>['dispose']
25
+ }
26
+
27
+ export function createRouter<const Defs extends RouteDefinitions, Ctx = unknown>(
28
+ config: ZustandRouterConfig<InferRoutes<Defs>, Ctx> & { routes: Defs },
29
+ ): ZustandRouter<InferRoutes<Defs>, Ctx>
30
+ export function createRouter<M extends RouteMapDef, Ctx = unknown>(
31
+ config: ZustandRouterConfig<M, Ctx>,
32
+ ): ZustandRouter<M, Ctx>
33
+ export function createRouter<M extends RouteMapDef, Ctx = unknown>(
34
+ config: ZustandRouterConfig<M, Ctx>,
35
+ ): ZustandRouter<M, Ctx> {
36
+ const getCtx = (): Ctx => {
37
+ if (typeof config.context === 'function') {
38
+ return (config.context as () => Ctx)()
39
+ }
40
+ return (config.context ?? {}) as Ctx
41
+ }
42
+
43
+ const core = createItenCore<M, Ctx>({
44
+ initial: config.initial,
45
+ routes: config.routes,
46
+ routeConfig: config.routeConfig,
47
+ maxHistoryLength: config.maxHistoryLength,
48
+ queryClient: config.queryClient,
49
+ getCtx,
50
+ })
51
+
52
+ let stopCoreSubscription: (() => void) | undefined
53
+
54
+ function makeState({
55
+ state,
56
+ actions,
57
+ }: {
58
+ state: RouterState<M>
59
+ actions: ZustandRouterActions<M>
60
+ }): ZustandRouterState<M> {
61
+ return {
62
+ ...state,
63
+ ...actions,
64
+ }
65
+ }
66
+
67
+ const actions: ZustandRouterActions<M> = {
68
+ navigate: async (input) => {
69
+ await core.navigate(input)
70
+ store.setState(makeState({ state: core.getState(), actions }), true)
71
+ },
72
+ goBack: () => {
73
+ core.goBack()
74
+ store.setState(makeState({ state: core.getState(), actions }), true)
75
+ },
76
+ dispose: () => {
77
+ stopCoreSubscription?.()
78
+ stopCoreSubscription = undefined
79
+ core.dispose()
80
+ },
81
+ }
82
+
83
+ const store = createStore<ZustandRouterState<M>>(() =>
84
+ makeState({ state: core.getState(), actions }),
85
+ )
86
+
87
+ stopCoreSubscription = core.subscribe({
88
+ listener: (state) => {
89
+ store.setState(makeState({ state, actions }), true)
90
+ },
91
+ })
92
+
93
+ return {
94
+ store,
95
+ core,
96
+ to: core.to,
97
+ navigate: actions.navigate,
98
+ goBack: actions.goBack,
99
+ dispose: actions.dispose,
100
+ }
101
+ }
package/src/index.ts ADDED
@@ -0,0 +1,32 @@
1
+ export {
2
+ createRoute,
3
+ defineRouteConfig,
4
+ defineRoutes,
5
+ isRoute,
6
+ isRouteName,
7
+ matchRoute,
8
+ route,
9
+ } from 'iten-core'
10
+ export type { ZustandRouter } from './create-router.ts'
11
+ export { createRouter } from './create-router.ts'
12
+ export type {
13
+ InferRoutes,
14
+ NoParams,
15
+ QueryClientLike,
16
+ RouteConfigMap,
17
+ RouteDefinition,
18
+ RouteDefinitions,
19
+ RouteMap,
20
+ RouteMapDef,
21
+ RouteMatcher,
22
+ RouteName,
23
+ RouteOf,
24
+ RouteParams,
25
+ RouterError,
26
+ RouterState,
27
+ RouteUnion,
28
+ ZustandRouterActions,
29
+ ZustandRouterConfig,
30
+ ZustandRouterState,
31
+ ZustandRouterStore,
32
+ } from './types.ts'
package/src/types.ts ADDED
@@ -0,0 +1,58 @@
1
+ import type {
2
+ InferRoutes,
3
+ NavigateInput,
4
+ NoParams,
5
+ QueryClientLike,
6
+ RouteConfigMap,
7
+ RouteDefinition,
8
+ RouteDefinitions,
9
+ RouteFactory,
10
+ RouteMap,
11
+ RouteMapDef,
12
+ RouteMatcher,
13
+ RouteName,
14
+ RouteOf,
15
+ RouteParams,
16
+ RouterError,
17
+ RouterState,
18
+ RouteUnion,
19
+ } from 'iten-core'
20
+ import type { StoreApi } from 'zustand/vanilla'
21
+
22
+ export type {
23
+ InferRoutes,
24
+ NoParams,
25
+ QueryClientLike,
26
+ RouteConfigMap,
27
+ RouteDefinition,
28
+ RouteDefinitions,
29
+ RouteFactory,
30
+ RouteMap,
31
+ RouteMapDef,
32
+ RouteMatcher,
33
+ RouteName,
34
+ RouteOf,
35
+ RouteParams,
36
+ RouterError,
37
+ RouterState,
38
+ RouteUnion,
39
+ }
40
+
41
+ export type ZustandRouterConfig<M extends RouteMapDef, Ctx = unknown> = {
42
+ initial: RouteUnion<M> | null
43
+ routes?: RouteDefinitions | undefined
44
+ routeConfig?: RouteConfigMap<M, Ctx> | undefined
45
+ maxHistoryLength?: number | undefined
46
+ context?: Ctx | (() => Ctx) | undefined
47
+ queryClient?: QueryClientLike | null | undefined
48
+ }
49
+
50
+ export type ZustandRouterActions<M extends RouteMapDef> = {
51
+ navigate: (input: NavigateInput<M>) => Promise<void>
52
+ goBack: () => void
53
+ dispose: () => void
54
+ }
55
+
56
+ export type ZustandRouterState<M extends RouteMapDef> = RouterState<M> & ZustandRouterActions<M>
57
+
58
+ export type ZustandRouterStore<M extends RouteMapDef> = StoreApi<ZustandRouterState<M>>
package/src/url.ts ADDED
@@ -0,0 +1,48 @@
1
+ import type { ItenCore, NavigateInput, RouteMapDef, RouterState } from 'iten-core'
2
+ import {
3
+ type CreateUrlSyncInput as CoreCreateUrlSyncInput,
4
+ createUrlSync as createCoreUrlSync,
5
+ type UrlSync,
6
+ } from 'iten-core/url'
7
+ import type { ZustandRouter } from './create-router.ts'
8
+
9
+ export type {
10
+ FormatUrlInput,
11
+ ParseUrlInput,
12
+ UrlHydrateInput,
13
+ UrlParseErrorInput,
14
+ UrlStartInput,
15
+ UrlSubscribeInput,
16
+ UrlSync,
17
+ UrlWriteInput,
18
+ UrlWriteMode,
19
+ } from 'iten-core/url'
20
+
21
+ export type CreateUrlSyncInput<M extends RouteMapDef> = Omit<
22
+ CoreCreateUrlSyncInput<M>,
23
+ 'router'
24
+ > & {
25
+ router: ZustandRouter<M>
26
+ }
27
+
28
+ export function createUrlSync<M extends RouteMapDef>({
29
+ router,
30
+ ...input
31
+ }: CreateUrlSyncInput<M>): UrlSync<M> {
32
+ const coreLike: ItenCore<M> = {
33
+ getState: () => router.store.getState() as RouterState<M>,
34
+ to: router.to,
35
+ navigate: (navigateInput: NavigateInput<M>) => router.navigate(navigateInput),
36
+ goBack: () => router.goBack(),
37
+ subscribe: ({ listener }) =>
38
+ router.store.subscribe((state) => {
39
+ listener(state as RouterState<M>)
40
+ }),
41
+ dispose: () => {},
42
+ }
43
+
44
+ return createCoreUrlSync<M>({
45
+ ...input,
46
+ router: coreLike,
47
+ })
48
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,23 @@
1
+ export type {
2
+ InferRoutes,
3
+ NoParams,
4
+ RouteConfigMap,
5
+ RouteMap,
6
+ RouteMapDef,
7
+ RouteUnion,
8
+ } from 'iten-core'
9
+ export type {
10
+ RouteMatcher,
11
+ RouteName,
12
+ RouteOf,
13
+ RouteParams,
14
+ } from 'iten-core/utils'
15
+ export {
16
+ createRoute,
17
+ defineRouteConfig,
18
+ defineRoutes,
19
+ isRoute,
20
+ isRouteName,
21
+ matchRoute,
22
+ route,
23
+ } from 'iten-core/utils'
package/index.js DELETED
@@ -1 +0,0 @@
1
- throw new Error('zustand-iten is reserved for the upcoming Zustand adapter. Use iten-core today.')