ihsm 0.0.14 → 0.0.19

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 (50) hide show
  1. package/README.md +190 -6
  2. package/lib/cjs/index.d.ts +282 -0
  3. package/lib/cjs/index.js +331 -0
  4. package/lib/cjs/index.js.map +1 -0
  5. package/lib/cjs/internal/defs.private.d.ts +31 -0
  6. package/lib/cjs/internal/defs.private.js +3 -0
  7. package/lib/cjs/internal/defs.private.js.map +1 -0
  8. package/lib/cjs/internal/dispatch.debug.d.ts +4 -0
  9. package/lib/cjs/internal/dispatch.debug.js +330 -0
  10. package/lib/cjs/internal/dispatch.debug.js.map +1 -0
  11. package/lib/cjs/internal/dispatch.production.d.ts +6 -0
  12. package/lib/cjs/internal/dispatch.production.js +239 -0
  13. package/lib/cjs/internal/dispatch.production.js.map +1 -0
  14. package/lib/cjs/internal/dispatch.trace.d.ts +4 -0
  15. package/lib/cjs/internal/dispatch.trace.js +410 -0
  16. package/lib/cjs/internal/dispatch.trace.js.map +1 -0
  17. package/lib/cjs/internal/hsm.d.ts +54 -0
  18. package/lib/cjs/internal/hsm.js +182 -0
  19. package/lib/cjs/internal/hsm.js.map +1 -0
  20. package/lib/cjs/internal/utils.d.ts +18 -0
  21. package/lib/cjs/internal/utils.js +51 -0
  22. package/lib/cjs/internal/utils.js.map +1 -0
  23. package/lib/cjs/package.json +3 -0
  24. package/lib/esm/index.d.ts +282 -0
  25. package/lib/esm/index.js +314 -0
  26. package/lib/esm/index.js.map +1 -0
  27. package/lib/esm/internal/defs.private.d.ts +31 -0
  28. package/lib/esm/internal/defs.private.js +2 -0
  29. package/lib/esm/internal/defs.private.js.map +1 -0
  30. package/lib/esm/internal/dispatch.debug.d.ts +4 -0
  31. package/lib/esm/internal/dispatch.debug.js +326 -0
  32. package/lib/esm/internal/dispatch.debug.js.map +1 -0
  33. package/lib/esm/internal/dispatch.production.d.ts +6 -0
  34. package/lib/esm/internal/dispatch.production.js +235 -0
  35. package/lib/esm/internal/dispatch.production.js.map +1 -0
  36. package/lib/esm/internal/dispatch.trace.d.ts +4 -0
  37. package/lib/esm/internal/dispatch.trace.js +406 -0
  38. package/lib/esm/internal/dispatch.trace.js.map +1 -0
  39. package/lib/esm/internal/hsm.d.ts +54 -0
  40. package/lib/esm/internal/hsm.js +178 -0
  41. package/lib/esm/internal/hsm.js.map +1 -0
  42. package/lib/esm/internal/utils.d.ts +18 -0
  43. package/lib/esm/internal/utils.js +41 -0
  44. package/lib/esm/internal/utils.js.map +1 -0
  45. package/lib/esm/package.json +3 -0
  46. package/package.json +114 -66
  47. package/lib/index.browser.js +0 -523
  48. package/lib/index.d.ts +0 -104
  49. package/lib/index.js +0 -374
  50. package/tsconfig.json +0 -72
package/README.md CHANGED
@@ -1,9 +1,193 @@
1
- ```ts
2
- /* (_) | |__ ___ _ __ ___ */
3
- /* | | | '_ \ / __| | '_ ` _ \ */
4
- /* | | | | | | \__ \ | | | | | | */
5
- /* |_| |_| |_| |___/ |_| |_| |_| */
1
+ [![CI](https://img.shields.io/github/actions/workflow/status/filasieno/ihsm/ci.yml?label=CI)](https://github.com/filasieno/ihsm/actions/workflows/ci.yml)
2
+ [![Documentation](https://img.shields.io/github/actions/workflow/status/filasieno/ihsm/docs.yml?label=docs)](https://github.com/filasieno/ihsm/actions/workflows/docs.yml)
3
+ [![Coverage](https://img.shields.io/coverallsCoverage/github/filasieno/ihsm)](https://coveralls.io/github/filasieno/ihsm)
4
+ [![License: MIT](https://img.shields.io/github/license/filasieno/ihsm)](https://github.com/filasieno/ihsm/blob/HEAD/LICENSE)
5
+ [![npm version](https://img.shields.io/npm/v/ihsm)](https://www.npmjs.com/package/ihsm)
6
+ [![Node](https://img.shields.io/badge/node-%3E%3D22-339933?logo=node.js)](https://github.com/filasieno/ihsm/blob/HEAD/package.json)
7
+
8
+ # ihsm
9
+
10
+ An idiomatic hierarchical state machine package for TypeScript — **Samek/QP-style** class hierarchy with
11
+ **cached LCA transitions**, **zero production dependencies**, and **100% code coverage** on the runtime.
12
+
13
+ ## Quality
14
+
15
+ | Metric | Value |
16
+ |--------|-------|
17
+ | **Statements** | 100% |
18
+ | **Branches** | 100% |
19
+ | **Functions** | 100% |
20
+ | **Lines** | 100% |
21
+
22
+ CI enforces full coverage on every push (`nix flake check`).
23
+
24
+ ## Features
25
+
26
+ - User-defined event payloads (typed `Protocol`)
27
+ - User-defined state context (`ctx`)
28
+ - Hierarchically nested states (class inheritance)
29
+ - Orthogonal regions (nest multiple machines; compose via `post`/`call`)
30
+ - Internal transitions (handle event without calling `transition()`)
31
+ - Explicit transitions with cached entry/exit sequences
32
+ - Guards (inline `if` in handlers)
33
+ - History (`ctx` + `restore()`)
34
+ - Entry / exit actions (`onEntry`, `onExit`)
35
+ - Async and sync handlers
36
+ - **`call()` — typed request/response through the actor mailbox** (unique)
37
+ - **`then()` — decision pseudo-states with automatic follow-up transitions**
38
+ - **`postNow()` — hi-priority extended transitions within the same dispatch**
39
+ - Actor-style messaging (`post`, `deferredPost`, serialized queue)
40
+ - Structured errors and trace levels
41
+
42
+ ## Documentation
43
+
44
+ | Resource | Link |
45
+ |----------|------|
46
+ | **Documentation site** | [filasieno.github.io/ihsm](https://filasieno.github.io/ihsm/) — reference manual + interactive tutorials |
47
+ | Reference (source) | [reference/REFERENCE.md](./reference/REFERENCE.md) |
48
+ | Tutorials (source) | [tutorials/](./tutorials/) |
49
+ | Examples | [`src/spec/`](./src/spec/) |
50
+ | Code of conduct | [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) |
51
+ | Security | [SECURITY.md](./SECURITY.md) |
52
+
53
+ Each tutorial page on the documentation site combines prose, code samples, and an embedded playground
54
+ (sender/message forms, live trace, reset). The same machines are verified headlessly by Mocha specs under
55
+ `tutorials/*/tutorial.spec.ts`.
56
+
57
+ ## Install
58
+
59
+ ```shell
60
+ npm install ihsm@latest
61
+ ```
62
+
63
+ ### Runtime support
64
+
65
+ ihsm ships modern **ES2022** ESM and CommonJS — no transpiled legacy (ES5/ES2015)
66
+ output and no polyfills. Supported runtimes:
67
+
68
+ | Runtime | Minimum |
69
+ | ------- | ------- |
70
+ | Node.js | **22+** |
71
+ | Chrome / Edge | **94+** |
72
+ | Firefox | **93+** |
73
+ | Safari (macOS / iOS) | **15.4+** |
74
+
75
+ Older browsers and JavaScript engines are intentionally **not** supported. If you
76
+ must target them, transpile `ihsm` yourself with your bundler (the published
77
+ `browserslist` field declares this baseline for downstream tooling).
78
+
79
+ ## Requirements
80
+
81
+ **[Nix](https://nixos.org/download/)** with flakes enabled — the only prerequisite to build and test
82
+ from source.
83
+
84
+ ## Building
85
+
86
+ ```shell
87
+ git clone https://github.com/filasieno/ihsm.git
88
+ cd ihsm
89
+ ```
90
+
91
+ ### Development environment
92
+
93
+ **Always use the Nix dev shell** before running npm scripts. It provides Node 22,
94
+ PlantUML, Graphviz, and a store-pinned `node_modules` symlink (same lockfile as CI).
95
+
96
+ ```shell
97
+ nix develop
98
+ # or: direnv allow # .envrc → use flake; auto-enters the shell in supported terminals
99
+ ```
100
+
101
+ Run npm commands **inside** that shell, or prefix each one with `nix develop --command`:
102
+
103
+ ```shell
104
+ nix develop --command npm test
6
105
  ```
7
106
 
8
- # Idiomatic hierarchical state machine
107
+ If you see `remove local node_modules/ to use Nix store deps`, delete a plain
108
+ `npm install` tree: `rm -rf node_modules` and enter `nix develop` again.
109
+
110
+ ### Nix commands (CI parity)
111
+
112
+ | Command | Purpose |
113
+ | ------- | ------- |
114
+ | `nix flake check` | Full CI gate: library compile, unit + tutorial tests, lint, docs site |
115
+ | `nix build` | Compile library and run tests → `result/lib/` |
116
+ | `nix build .#lint` | TypeScript (full solution), ESLint, Prettier |
117
+ | `nix build .#docs` | Production documentation site → `result/share/doc/ihsm/` |
118
+
119
+ Full check before opening a PR:
120
+
121
+ ```shell
122
+ nix flake check
123
+ ```
124
+
125
+ After `nix build .#docs`, copy artifacts from `result/share/doc/ihsm/` or run
126
+ `bash scripts/verify-docs-site.sh result/share/doc/ihsm`.
127
+
128
+ ### npm scripts
129
+
130
+ All commands below assume **`nix develop`** (interactive shell) or
131
+ **`nix develop --command …`** (one-shot). See [website/README.md](./website/README.md)
132
+ for docs-site layout and generated output.
133
+
134
+ #### Build
135
+
136
+ | Command | Purpose |
137
+ | ------- | ------- |
138
+ | `npm run build` | Compile the publishable library → `lib/cjs/` (CommonJS) and `lib/esm/` (ESM), then finalize |
139
+ | `npm run build-cjs` | Compile the CommonJS tree only → `lib/cjs/` |
140
+ | `npm run build-esm` | Compile the ESM tree only → `lib/esm/` |
141
+ | `npm run clean` | Remove generated artifacts (`lib/`, `.tsc/`, coverage, `docs-build/`, `website/docs/`, …) |
142
+ | `npm run dist` | Clean, then build library and documentation site (maintainer bundle) |
143
+
144
+ #### Test
145
+
146
+ | Command | Purpose |
147
+ | ------- | ------- |
148
+ | `npm test` | Unit tests in Node (`src/spec/`) with NYC coverage, then the same specs minified in headless Chromium |
149
+ | `npm run test:node` | Node-only unit tests (with coverage) |
150
+ | `npm run test:browser` | Minified browser bundles for unit + tutorial specs (Playwright + esbuild) |
151
+ | `npm run test:tutorials` | Tutorial specs in Node, then minified in the browser |
152
+ | `npm run test:all` | `npm test` + `npm run test:tutorials` (both environments) |
153
+ | `npm run coverage` | Print an LCOV coverage report from the last `npm run test:node` run |
154
+
155
+ First-time browser setup: `npx playwright install chromium`.
156
+
157
+ #### Quality
158
+
159
+ | Command | Purpose |
160
+ | ------- | ------- |
161
+ | `npm run typecheck` | Type-check the full project graph (CJS lib, ESM lib, tutorials, website); runs `sync:docs` first |
162
+ | `npm run lint` | Typecheck, then ESLint and Prettier check |
163
+ | `npm run prettier` | Auto-format TypeScript sources (`src/`, `tutorials/`, `website/`) |
164
+ | `npm run verify:source` | Fail if generated output (compiled `.js`/`.d.ts`, docs) appears in the source tree |
165
+ | `npm run release:check` | Local release gate: `test:all`, lint, build, doc, and `verify:doc` |
166
+
167
+ #### Documentation
168
+
169
+ | Command | Purpose |
170
+ | ------- | ------- |
171
+ | `npm run sync:docs` | Generate gitignored site inputs: `website/docs/`, `website/sidebars.ts`, PlantUML SVGs |
172
+ | `npm run doc` | `sync:docs`, then production Docusaurus build (website workspace) |
173
+ | `npm run doc:preview` | `sync:docs`, then Docusaurus dev server at [localhost:3010/ihsm/](http://localhost:3010/ihsm/) |
174
+ | `npm run doc:site` | `sync:docs`, then static site → `docs-build/` |
175
+ | `npm run verify:doc` | Sanity-check `docs-build/` (links, assets, tutorial pages) |
176
+
177
+ Release process: [RELEASING.md](./RELEASING.md).
178
+
179
+ ## Contributing
180
+
181
+ Contributions are welcome — bug reports, docs, and code.
182
+
183
+ - Bug reports → [issue template](https://github.com/filasieno/ihsm/issues/new?template=bug_report.yml)
184
+ - Features → [issue template](https://github.com/filasieno/ihsm/issues/new?template=feature_request.yml)
185
+ - Security → [GitHub Security Advisories](https://github.com/filasieno/ihsm/security/advisories/new) (not public issues)
186
+
187
+ Please follow [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md). New behavior needs tests in `src/spec/`; tutorial changes need matching specs under `tutorials/`.
188
+
189
+ **Generated output is never committed** — only sources (`src/`, `tutorials/`, `reference/`, `website/docs-src/`). CI runs `scripts/verify-no-generated-in-source.sh`. Build artifacts (`lib/`, `website/docs/`, `docs-build/`, …) are gitignored and produced by Nix/npm.
190
+
191
+ ## License
9
192
 
193
+ [MIT](./LICENSE) © Fabio N. Filasieno, Roberto Boati
@@ -0,0 +1,282 @@
1
+ /**
2
+ * Default context and protocol map when a machine is created without explicit typing.
3
+ * @category Factory
4
+ */
5
+ export type Any = Record<string, any>;
6
+ /**
7
+ * Rejects an async {@link Hsm.call} service with an error.
8
+ * @category Event handler
9
+ */
10
+ export type RejectCallback = (error: Error) => void;
11
+ /**
12
+ * Resolves an async {@link Hsm.call} service with a typed reply.
13
+ * @category Event handler
14
+ */
15
+ export type ResolveCallback<Reply> = (result: Reply) => void;
16
+ /**
17
+ * Called when event dispatch fails and the runtime does not recover via `onError`.
18
+ * @category Factory
19
+ */
20
+ export interface DispatchErrorCallback<Context, Protocol extends {} | undefined> {
21
+ (hsm: Base<Context, Protocol>, err: Error): void;
22
+ }
23
+ /**
24
+ * Trace verbosity for dispatch logging.
25
+ * @category Factory
26
+ */
27
+ export declare enum TraceLevel {
28
+ PRODUCTION = 0,
29
+ DEBUG = 1,
30
+ VERBOSE_DEBUG = 2
31
+ }
32
+ /**
33
+ * Receives trace lines from the runtime and from handlers via `this.traceWriter.write`.
34
+ * @category Factory
35
+ */
36
+ export interface TraceWriter {
37
+ write<Context, Protocol extends {} | undefined>(hsm: Properties<Context, Protocol>, msg: any): void;
38
+ }
39
+ /**
40
+ * @category State machine
41
+ */
42
+ export interface Properties<Context, Protocol extends {} | undefined> {
43
+ readonly currentState: StateClass<Context, Protocol>;
44
+ readonly currentStateName: string;
45
+ readonly topState: StateClass<Context, Protocol>;
46
+ readonly topStateName: string;
47
+ readonly ctxTypeName: string;
48
+ readonly traceHeader: string;
49
+ readonly eventName: string;
50
+ readonly eventPayload: any[];
51
+ traceLevel: TraceLevel;
52
+ traceWriter: TraceWriter;
53
+ dispatchErrorCallback: DispatchErrorCallback<Context, Protocol>;
54
+ }
55
+ /**
56
+ * @category State machine
57
+ */
58
+ export interface Base<Context, Protocol extends {} | undefined> extends Properties<Context, Protocol> {
59
+ post<EventName extends keyof Protocol>(eventName: PostedEvent<Protocol, EventName>, ...eventPayload: EventPayload<Protocol, EventName>): void;
60
+ deferredPost<EventName extends keyof Protocol>(millis: number, eventName: PostedEvent<Protocol, EventName>, ...eventPayload: EventPayload<Protocol, EventName>): void;
61
+ }
62
+ /**
63
+ * @category State machine
64
+ */
65
+ export interface State<Context, Protocol extends {} | undefined> extends Base<Context, Protocol> {
66
+ readonly ctx: Context;
67
+ transition(nextState: StateClass<Context, Protocol>): void;
68
+ unhandled(): never;
69
+ sleep(millis: number): Promise<void>;
70
+ /** Handler-only: queue an event on the internal high-priority mailbox (before normal `post`). */
71
+ postNow<EventName extends keyof Protocol>(eventName: PostedEvent<Protocol, EventName>, ...eventPayload: EventPayload<Protocol, EventName>): void;
72
+ }
73
+ /**
74
+ * Actor handle returned by {@link makeHsm} — client API (`post`, `call`, `sync`, `restore`).
75
+ * @category State machine
76
+ */
77
+ export interface Hsm<Context = Any, Protocol extends {} | undefined = undefined> extends Base<Context, Protocol> {
78
+ readonly ctx: Context;
79
+ sync(): Promise<void>;
80
+ restore(state: StateClass<Context, Protocol>, ctx: Context): void;
81
+ call<EventName extends keyof Protocol>(eventName: ServiceName<Protocol, EventName>, ...eventPayload: ServiceRequest<Protocol, EventName>): Promise<ServiceResponse<Protocol, EventName>>;
82
+ }
83
+ /**
84
+ * @category Event handler
85
+ */
86
+ export type PostedEvent<Protocol extends {} | undefined, EventName extends keyof Protocol> = Protocol extends undefined ? string : EventName extends keyof State<any, any> ? never : EventName;
87
+ /**
88
+ * @category Event handler
89
+ */
90
+ export type EventPayload<Protocol extends {} | undefined, EventName extends keyof Protocol> = Protocol extends undefined ? any[] : Protocol[EventName] extends (...payload: infer Payload) => Promise<void> | void ? (Payload extends any[] ? Payload : never) : never;
91
+ /**
92
+ * Constructor type for a state class in the machine hierarchy.
93
+ * @category State machine
94
+ */
95
+ export type StateClass<Context = Any, Protocol extends {} | undefined = undefined> = Function & {
96
+ prototype: TopState<Context, Protocol>;
97
+ };
98
+ /**
99
+ *
100
+ */
101
+ export type ServiceRequest<Protocol, EventName extends keyof Protocol> = Protocol extends undefined ? any[] : Protocol[EventName] extends (resolve: (result: infer Reply) => void, reject: (error: infer Error) => void, ...payload: infer Payload) => Promise<void> | void ? (Payload extends any[] ? Payload : never) : never;
102
+ /**
103
+ *
104
+ */
105
+ export type ServiceResponse<Protocol, EventName extends keyof Protocol> = Protocol extends undefined ? any : Protocol[EventName] extends (resolve: infer Reply, reject: infer Error, ...payload: infer Payload) => Promise<void> | void ? Reply : never;
106
+ /**
107
+ *
108
+ */
109
+ export type ServiceName<Protocol, EventName> = Protocol extends undefined ? string : EventName extends keyof State<any, any> ? never : EventName;
110
+ /**
111
+ * Optional lifecycle hooks implemented by state classes (`onEntry`, `onExit`, …).
112
+ * @category State machine
113
+ */
114
+ export interface StateEvents<Context, Protocol extends {} | undefined> {
115
+ onExit(): Promise<void> | void;
116
+ onEntry(): Promise<void> | void;
117
+ onError<EventName extends keyof Protocol>(error: RuntimeError<Context, Protocol, EventName>): Promise<void> | void;
118
+ onUnhandled<EventName extends keyof Protocol>(error: UnhandledEventError<Context, Protocol, EventName>): Promise<void> | void;
119
+ }
120
+ /**
121
+ * Root of the state class hierarchy; hosts mailbox machinery. Subclass or pass to {@link makeHsm}.
122
+ * @category State machine
123
+ */
124
+ export declare abstract class TopState<Context = Any, Protocol extends {} | undefined = undefined> implements State<Context, Protocol>, StateEvents<Context, Protocol> {
125
+ readonly ctx: Context;
126
+ readonly hsm: State<Context, Protocol>;
127
+ constructor();
128
+ get eventName(): string;
129
+ get eventPayload(): any[];
130
+ get traceHeader(): string;
131
+ get topState(): StateClass<Context, Protocol>;
132
+ get currentStateName(): string;
133
+ get currentState(): StateClass<Context, Protocol>;
134
+ get ctxTypeName(): string;
135
+ set traceLevel(value: TraceLevel);
136
+ get traceLevel(): TraceLevel;
137
+ get topStateName(): string;
138
+ get traceWriter(): TraceWriter;
139
+ set traceWriter(value: TraceWriter);
140
+ get dispatchErrorCallback(): DispatchErrorCallback<Context, Protocol>;
141
+ set dispatchErrorCallback(value: DispatchErrorCallback<Context, Protocol>);
142
+ transition(nextState: StateClass<Context, Protocol>): void;
143
+ unhandled(): never;
144
+ sleep(millis: number): Promise<void>;
145
+ post<EventName extends keyof Protocol>(eventName: PostedEvent<Protocol, EventName>, ...eventPayload: EventPayload<Protocol, EventName>): void;
146
+ deferredPost<EventName extends keyof Protocol>(millis: number, eventName: PostedEvent<Protocol, EventName>, ...eventPayload: EventPayload<Protocol, EventName>): void;
147
+ postNow<EventName extends keyof Protocol>(eventName: PostedEvent<Protocol, EventName>, ...eventPayload: EventPayload<Protocol, EventName>): void;
148
+ onExit(): Promise<void> | void;
149
+ onEntry(): Promise<void> | void;
150
+ onError<EventName extends keyof Protocol>(error: RuntimeError<Context, Protocol, EventName>): Promise<void> | void;
151
+ onUnhandled<EventName extends keyof Protocol>(error: UnhandledEventError<Context, Protocol, EventName>): Promise<void> | void;
152
+ }
153
+ /**
154
+ * @category Error
155
+ */
156
+ export declare abstract class HsmError<Context, Protocol extends {} | undefined> extends Error {
157
+ name: string;
158
+ topStateName: string;
159
+ stateName: string;
160
+ context: Context;
161
+ cause?: Error;
162
+ protected constructor(name: string, hsm: State<Context, Protocol>, message: string, cause?: Error);
163
+ }
164
+ /**
165
+ * @category Error
166
+ */
167
+ export declare abstract class RuntimeError<Context, Protocol extends {} | undefined, EventName extends keyof Protocol> extends HsmError<Context, Protocol> {
168
+ eventName: PostedEvent<Protocol, EventName>;
169
+ eventPayload: EventPayload<Protocol, EventName>;
170
+ protected constructor(errorName: string, hsm: State<Context, Protocol>, message: string, cause?: Error);
171
+ }
172
+ /**
173
+ * @category Error
174
+ */
175
+ export declare class TransitionError<Context, Protocol extends {} | undefined, EventName extends keyof Protocol> extends RuntimeError<Context, Protocol, EventName> {
176
+ failedStateName: string;
177
+ failedCallback: 'onExit' | 'onEntry';
178
+ fromStateName: string;
179
+ toStateName: string;
180
+ constructor(hsm: State<Context, Protocol>, cause: Error, failedStateName: string, failedCallback: 'onExit' | 'onEntry', fromStateName: string, toStateName: string);
181
+ }
182
+ /**
183
+ * @category Error
184
+ */
185
+ export declare class EventHandlerError<Context, Protocol extends {} | undefined, EventName extends keyof Protocol> extends RuntimeError<Context, Protocol, EventName> {
186
+ constructor(hsm: State<Context, Protocol>, cause: Error);
187
+ }
188
+ /**
189
+ * @category Error
190
+ */
191
+ export declare class UnhandledEventError<Context, Protocol extends {} | undefined, EventName extends keyof Protocol> extends RuntimeError<Context, Protocol, EventName> {
192
+ constructor(hsm: State<Context, Protocol>);
193
+ }
194
+ /**
195
+ * @category Error
196
+ */
197
+ export declare class InitialStateError<Context, Protocol extends {} | undefined> extends Error {
198
+ targetStateName: string;
199
+ constructor(targetState: StateClass<Context, Protocol>);
200
+ }
201
+ /**
202
+ * @category Error
203
+ */
204
+ export declare class FatalError<Context, Protocol extends {} | undefined, EventName extends keyof Protocol> extends RuntimeError<Context, Protocol, EventName> {
205
+ constructor(hsm: State<Context, Protocol>, cause: Error);
206
+ }
207
+ /**
208
+ * @category Error
209
+ */
210
+ export declare class InitializationError<Context, Protocol extends {} | undefined> extends HsmError<Context, Protocol> {
211
+ failedState: StateClass<Context, Protocol>;
212
+ constructor(hsm: State<Context, Protocol>, failedState: StateClass<Context, Protocol>, cause: Error);
213
+ }
214
+ /**
215
+ * Terminal error state class used when the machine cannot recover.
216
+ * @category State machine
217
+ */
218
+ export declare class FatalErrorState<Context, Protocol extends {} | undefined> extends TopState<Context, Protocol> {
219
+ }
220
+ /**
221
+ * Marks `TargetState` as the initial substate of its parent composite state.
222
+ * @category Factory
223
+ */
224
+ export declare function InitialState<Context, Protocol extends {} | undefined>(TargetState: StateClass<Context, Protocol>): void;
225
+ /**
226
+ * Assigns a stable display name to a state class.
227
+ *
228
+ * Minifiers (and browser production bundles) rewrite class names, so the
229
+ * built-in `Class.name` is unreliable in optimized builds. Registering an
230
+ * explicit name keeps {@link Properties.currentStateName},
231
+ * {@link Properties.topStateName}, trace output, and error messages stable in
232
+ * every environment (Node and minified browsers alike).
233
+ *
234
+ * The name is stored as a non-enumerable, non-inherited own property, so it is
235
+ * never accidentally shared with subclasses through the prototype chain.
236
+ *
237
+ * @example
238
+ * ```ts
239
+ * class Door extends TopState {}
240
+ * defineStateName(Door, 'Door');
241
+ * ```
242
+ * @category State machine
243
+ */
244
+ export declare function defineStateName<Context, Protocol extends {} | undefined>(state: StateClass<Context, Protocol>, name: string): void;
245
+ /**
246
+ * Registers stable display names for every state class found in an exports map,
247
+ * using the export key as the display name.
248
+ *
249
+ * This is the convenient way to make a whole machine module minification-safe:
250
+ * pass the module namespace (or an object literal of the state classes) and
251
+ * each state class gets its export key as its display name. Non state-class
252
+ * values (factory functions, interfaces compiled away, constants) are ignored.
253
+ *
254
+ * @example
255
+ * ```ts
256
+ * // machine.ts
257
+ * export class DoorTop extends TopState {}
258
+ * export class Open extends DoorTop {}
259
+ * export class Closed extends DoorTop {}
260
+ * registerStateNames({ DoorTop, Open, Closed });
261
+ * ```
262
+ * @example
263
+ * ```ts
264
+ * // from another module
265
+ * import * as machine from './machine';
266
+ * registerStateNames(machine);
267
+ * ```
268
+ * @category State machine
269
+ */
270
+ export declare function registerStateNames(exports: Record<string, unknown>): void;
271
+ /**
272
+ * Creates a state machine instance bound to the given context object.
273
+ *
274
+ * @param topState - Root state class
275
+ * @param ctx - Mutable domain context
276
+ * @param initialize - When `true`, walk `@InitialState` chain and run `onEntry` on the path to the initial leaf (default `true`)
277
+ * @param traceLevel - Trace verbosity (default {@link TraceLevel.DEBUG})
278
+ * @param traceWriter - Trace sink (default console logger)
279
+ * @param dispatchErrorCallback - Hook when dispatch throws and is not recovered (default: log and rethrow)
280
+ * @category Factory
281
+ */
282
+ export declare function makeHsm<Context, Protocol extends undefined | {}>(topState: StateClass<Context, Protocol>, ctx: Context, initialize?: boolean, traceLevel?: TraceLevel, traceWriter?: TraceWriter, dispatchErrorCallback?: DispatchErrorCallback<Context, Protocol>): Hsm<Context, Protocol>;