@rxova/journey-core 0.3.0 → 0.4.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.
Files changed (2) hide show
  1. package/README.md +54 -112
  2. package/package.json +3 -2
package/README.md CHANGED
@@ -1,137 +1,79 @@
1
1
  # @rxova/journey-core
2
2
 
3
- The core Journey state machine for non-React environments. Use this package if you want the smallest, framework-agnostic runtime.
3
+ <p>
4
+ <a href="https://www.npmjs.com/package/@rxova/journey-core">
5
+ <img src="https://img.shields.io/badge/npm-%40rxova%2Fjourney--core-CB3837?logo=npm&logoColor=white" alt="npm package @rxova/journey-core" />
6
+ </a>
7
+ <a href="https://rxova.org/docs/core/getting-started">
8
+ <img src="https://img.shields.io/badge/docs-core-0f8f6a" alt="Core docs" />
9
+ </a>
10
+ <a href="https://github.com/rxova/journey/actions/workflows/ci.yml">
11
+ <img src="https://github.com/rxova/journey/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI" />
12
+ </a>
13
+ <img src="https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=white" alt="TypeScript" />
14
+ <img src="https://img.shields.io/badge/coverage%20(core)-100%25-brightgreen" alt="Core coverage" />
15
+ <a href="https://www.npmjs.com/package/@rxova/journey-core">
16
+ <img src="https://img.shields.io/npm/v/@rxova/journey-core" alt="npm version" />
17
+ </a>
18
+ <a href="https://www.npmjs.com/package/@rxova/journey-core">
19
+ <img src="https://img.shields.io/npm/dm/@rxova/journey-core" alt="npm downloads" />
20
+ </a>
21
+ <a href="https://bundlephobia.com/package/@rxova/journey-core">
22
+ <img src="https://img.shields.io/bundlephobia/minzip/%40rxova%2Fjourney-core" alt="Bundlephobia" />
23
+ </a>
24
+ </p>
25
+
26
+ Headless runtime for step journeys and non-linear flows.
27
+
28
+ Use `@rxova/journey-core` when you want flow logic that is independent from UI frameworks.
29
+
30
+ `[GETTING STARTED](https://rxova.org/docs/core/getting-started) | [ARCHITECTURE](https://rxova.org/docs/core/architecture) | [API](https://rxova.org/docs/core/api) | [HISTORY](https://rxova.org/docs/core/history) | [PERSISTENCE](https://rxova.org/docs/core/persistence) | [ASYNC](https://rxova.org/docs/core/async) | [EXAMPLES](https://rxova.org/docs/core/examples)`
4
31
 
5
32
  ## Install
6
33
 
7
34
  ```bash
8
- pnpm add @rxova/journey-core
9
- npm install @rxova/journey-core
10
- yarn add @rxova/journey-core
35
+ npm i @rxova/journey-core
11
36
  ```
12
37
 
13
- ## Basic usage
38
+ ## What You Get
14
39
 
15
- ```ts
16
- import {
17
- createJourneyMachine,
18
- JOURNEY_TERMINAL,
19
- type JourneyDefinition
20
- } from "@rxova/journey-core";
21
-
22
- type StepId = "one" | "two" | "three";
23
- type Event = "next" | "submit";
24
- type Ctx = { name: string };
25
-
26
- const journey: JourneyDefinition<Ctx, StepId, Event> = {
27
- initial: "one",
28
- context: { name: "" },
29
- steps: {
30
- one: {},
31
- two: {},
32
- three: {}
33
- },
34
- transitions: [
35
- { from: "one", event: "next", to: "two" },
36
- { from: "two", event: "next", to: "three" },
37
- { from: "three", event: "submit", to: JOURNEY_TERMINAL.COMPLETE }
38
- ]
39
- };
40
-
41
- const machine = createJourneyMachine<Ctx, StepId, Event>(journey);
42
- ```
43
-
44
- ## History behavior
45
-
46
- The machine tracks two related collections:
47
-
48
- - `history`: ordered list of prior steps. It grows when you move to a different step.
49
- - `visited`: list of steps you have reached (including current), with duplicates removed. It is not affected by history trimming.
50
-
51
- Why `visited` is a list (not a `Set`) for the following reasons:
52
-
53
- - JSON-friendly for snapshots, logs, and persistence.
54
- - Deterministic order for tests and UI rendering.
55
- - Easier to consume in TypeScript (`readonly TStepId[]`).
56
- - It is derived from `history + current` initially, then maintained independently so trimming history does not remove earlier entries.
57
-
58
- History is used when you target `HISTORY_TARGET` in a transition. It resolves to the most recent valid step in `history`. If history is empty (or contains invalid steps), the machine stays on the current step.
40
+ - Strongly typed journey definition and events.
41
+ - Deterministic transition matching.
42
+ - Built-in history, persistence helpers, and async lifecycle hooks.
43
+ - A reusable machine API you can run in frontend or backend code.
59
44
 
60
- ### History retention
61
-
62
- You can cap history growth with `maxHistory`. When the history exceeds that limit, the oldest entries are trimmed.
63
-
64
- Defaults:
65
-
66
- - `maxHistory`: `50`
67
- - `maxHistory: null` disables trimming entirely.
68
-
69
- Automatic trimming happens:
70
-
71
- - After transitions (including `goTo`)
72
- - After persistence hydrate
73
-
74
- ### Overflow callback
75
-
76
- `onOverflow` fires only when trimming actually happens. It receives:
77
-
78
- - `previous`: history before trimming
79
- - `next`: history after trimming
80
- - `trimmed`: entries removed
81
- - `maxHistory`: resolved limit (number or `null`)
82
- - `reason`: `"auto" | "hydrate" | "manual"`
83
- - `auto`: trimming happened automatically during a transition (including `goTo`)
84
- - `hydrate`: trimming happened right after loading persisted state
85
- - `manual`: trimming happened because you called `trimHistory()`
86
-
87
- ### Config example
45
+ ## Quickstart
88
46
 
89
47
  ```ts
90
- const machine = createJourneyMachine(journey, {
91
- history: {
92
- maxHistory: 20,
93
- onOverflow: ({ trimmed, reason }) => {
94
- console.warn("trimmed history", trimmed, "reason:", reason);
95
- }
96
- }
97
- });
98
- ```
48
+ import { createJourneyMachine, JOURNEY_TERMINAL } from "@rxova/journey-core";
99
49
 
100
- ### History target example
50
+ type StepId = "start" | "review";
51
+ type Event = "next" | "submit";
101
52
 
102
- ```ts
103
- import { HISTORY_TARGET } from "@rxova/journey-core";
53
+ type Ctx = { name: string };
104
54
 
105
- const journey: JourneyDefinition<Ctx, StepId, Event> = {
106
- initial: "one",
55
+ // 1) Describe the flow as data.
56
+ const journey = {
57
+ initial: "start",
107
58
  context: { name: "" },
108
- steps: {
109
- one: {},
110
- two: {},
111
- three: {}
112
- },
59
+ steps: { start: {}, review: {} },
113
60
  transitions: [
114
- { from: "one", event: "next", to: "two" },
115
- { from: "two", event: "next", to: "three" },
116
- { from: "*", event: "back", to: HISTORY_TARGET }
61
+ { from: "start", event: "next", to: "review" },
62
+ { from: "review", event: "submit", to: JOURNEY_TERMINAL.COMPLETE }
117
63
  ]
118
64
  };
119
- ```
120
-
121
- ### Manual history management
122
65
 
123
- ```ts
124
- const machine = createJourneyMachine(journey, { history: { maxHistory: 5 } });
66
+ // 2) Create a machine instance.
67
+ const machine = createJourneyMachine<Ctx, StepId, Event>(journey);
125
68
 
126
- await machine.send({ type: "goTo", to: "two" });
127
- await machine.send({ type: "goTo", to: "three" });
69
+ // 3) Drive the flow with typed events.
70
+ await machine.send({ type: "next" });
128
71
 
129
- machine.trimHistory(1); // keep most recent entry only
130
- machine.clearHistory(); // reset history to []
72
+ // 4) Read immutable runtime state at any time.
73
+ const snapshot = machine.getSnapshot();
74
+ console.log(snapshot.current);
131
75
  ```
132
76
 
133
- ## Links
77
+ ## Coverage Notes
134
78
 
135
- - Docs: ../../docs/GETTING_STARTED.md
136
- - API: ../../docs/API.md
137
- - React bindings: ../react
79
+ Coverage badge is package-specific (`packages/core/test` against `packages/core/src`), not monorepo-wide.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rxova/journey-core",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Journey core state machine.",
5
5
  "keywords": [
6
6
  "journey",
@@ -19,7 +19,8 @@
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "git+https://github.com/rxova/journey.git"
22
+ "url": "git+https://github.com/rxova/journey.git",
23
+ "directory": "packages/core"
23
24
  },
24
25
  "publishConfig": {
25
26
  "access": "public"