xstate 4.15.4 → 4.16.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/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # xstate
2
2
 
3
+ ## 4.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`d2e328f8`](https://github.com/davidkpiano/xstate/commit/d2e328f8efad7e8d3500d39976d1153a26e835a3) [#1439](https://github.com/davidkpiano/xstate/pull/1439) Thanks [@davidkpiano](https://github.com/davidkpiano)! - An opt-in `createModel()` helper has been introduced to make it easier to work with typed `context` and events.
8
+
9
+ - `createModel(initialContext)` creates a `model` object
10
+ - `model.initialContext` returns the `initialContext`
11
+ - `model.assign(assigner, event?)` creates an `assign` action that is properly scoped to the `event` in TypeScript
12
+
13
+ See https://github.com/davidkpiano/xstate/pull/1439 for more details.
14
+
15
+ ```js
16
+ import { createMachine } from 'xstate';
17
+ import { createModel } from 'xstate/lib/model'; // opt-in, not part of main build
18
+
19
+ interface UserContext {
20
+ name: string;
21
+ age: number;
22
+ }
23
+
24
+ type UserEvents =
25
+ | { type: 'updateName'; value: string }
26
+ | { type: 'updateAge'; value: number }
27
+
28
+ const userModel = createModel<UserContext, UserEvents>({
29
+ name: 'David',
30
+ age: 30
31
+ });
32
+
33
+ const assignName = userModel.assign({
34
+ name: (_, e) => e.value // correctly typed to `string`
35
+ }, 'updateName'); // restrict to 'updateName' event
36
+
37
+ const machine = createMachine<UserContext, UserEvents>({
38
+ context: userModel.context,
39
+ initial: 'active',
40
+ states: {
41
+ active: {
42
+ on: {
43
+ updateName: {
44
+ actions: assignName
45
+ }
46
+ }
47
+ }
48
+ }
49
+ });
50
+ ```
51
+
3
52
  ## 4.15.4
4
53
 
5
54
  ### Patch Changes
package/es/model.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { AssignAction, Assigner, PropertyAssigner, ExtractEvent, EventObject } from './types';
2
+ export interface ContextModel<TContext, TEvent extends EventObject> {
3
+ initialContext: TContext;
4
+ assign: <TEventType extends TEvent['type'] = TEvent['type']>(assigner: Assigner<TContext, ExtractEvent<TEvent, TEventType>> | PropertyAssigner<TContext, ExtractEvent<TEvent, TEventType>>, eventType?: TEventType) => AssignAction<TContext, ExtractEvent<TEvent, TEventType>>;
5
+ reset: () => AssignAction<TContext, any>;
6
+ }
7
+ export declare function createModel<TContext, TEvent extends EventObject>(initialContext: TContext): ContextModel<TContext, TEvent>;
8
+ //# sourceMappingURL=model.d.ts.map
package/es/types.d.ts CHANGED
@@ -201,7 +201,7 @@ export declare type StatesDefinition<TContext, TStateSchema extends StateSchema,
201
201
  };
202
202
  export declare type TransitionConfigTarget<TContext, TEvent extends EventObject> = string | undefined | StateNode<TContext, any, TEvent>;
203
203
  export declare type TransitionConfigOrTarget<TContext, TEvent extends EventObject> = SingleOrArray<TransitionConfigTarget<TContext, TEvent> | TransitionConfig<TContext, TEvent>>;
204
- declare type TransitionsConfigMap<TContext, TEvent extends EventObject> = {
204
+ export declare type TransitionsConfigMap<TContext, TEvent extends EventObject> = {
205
205
  [K in TEvent['type']]?: TransitionConfigOrTarget<TContext, TEvent extends {
206
206
  type: K;
207
207
  } ? TEvent : never>;
@@ -616,8 +616,9 @@ export interface CancelAction extends ActionObject<any, any> {
616
616
  sendId: string | number;
617
617
  }
618
618
  export declare type Assigner<TContext, TEvent extends EventObject> = (context: TContext, event: TEvent, meta: AssignMeta<TContext, TEvent>) => Partial<TContext>;
619
+ export declare type PartialAssigner<TContext, TEvent extends EventObject, TKey extends keyof TContext> = (context: TContext, event: TEvent, meta: AssignMeta<TContext, TEvent>) => TContext[TKey];
619
620
  export declare type PropertyAssigner<TContext, TEvent extends EventObject> = {
620
- [K in keyof TContext]?: ((context: TContext, event: TEvent, meta: AssignMeta<TContext, TEvent>) => TContext[K]) | TContext[K];
621
+ [K in keyof TContext]?: PartialAssigner<TContext, TEvent, K> | TContext[K];
621
622
  };
622
623
  export declare type Mapper<TContext, TEvent extends EventObject, TParams extends {}> = (context: TContext, event: TEvent) => TParams;
623
624
  export declare type PropertyMapper<TContext, TEvent extends EventObject, TParams extends {}> = {
@@ -854,6 +855,9 @@ export interface Subscribable<T> {
854
855
  subscribe(next: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
855
856
  }
856
857
  export declare type Spawnable = StateMachine<any, any, any> | Promise<any> | InvokeCallback | Subscribable<any>;
858
+ export declare type ExtractEvent<TEvent extends EventObject, TEventType extends TEvent['type']> = TEvent extends {
859
+ type: TEventType;
860
+ } ? TEvent : never;
857
861
  export interface ActorRef<TEvent extends EventObject, TEmitted = any> extends Subscribable<TEmitted> {
858
862
  send: Sender<TEvent>;
859
863
  }
package/es/utils.d.ts CHANGED
@@ -10,12 +10,10 @@ export declare function toStatePath(stateId: string | string[], delimiter: strin
10
10
  export declare function isStateLike(state: any): state is StateLike<any>;
11
11
  export declare function toStateValue(stateValue: StateLike<any> | StateValue | string[], delimiter: string): StateValue;
12
12
  export declare function pathToStateValue(statePath: string[]): StateValue;
13
- export declare function mapValues<T, P>(collection: {
13
+ export declare function mapValues<T, P, O extends {
14
14
  [key: string]: T;
15
- }, iteratee: (item: T, key: string, collection: {
16
- [key: string]: T;
17
- }, i: number) => P): {
18
- [key: string]: P;
15
+ }>(collection: O, iteratee: (item: O[keyof O], key: keyof O, collection: O, i: number) => P): {
16
+ [key in keyof O]: P;
19
17
  };
20
18
  export declare function mapFilterValues<T, P>(collection: {
21
19
  [key: string]: T;
package/lib/model.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { AssignAction, Assigner, PropertyAssigner, ExtractEvent, EventObject } from './types';
2
+ export interface ContextModel<TContext, TEvent extends EventObject> {
3
+ initialContext: TContext;
4
+ assign: <TEventType extends TEvent['type'] = TEvent['type']>(assigner: Assigner<TContext, ExtractEvent<TEvent, TEventType>> | PropertyAssigner<TContext, ExtractEvent<TEvent, TEventType>>, eventType?: TEventType) => AssignAction<TContext, ExtractEvent<TEvent, TEventType>>;
5
+ reset: () => AssignAction<TContext, any>;
6
+ }
7
+ export declare function createModel<TContext, TEvent extends EventObject>(initialContext: TContext): ContextModel<TContext, TEvent>;
8
+ //# sourceMappingURL=model.d.ts.map
package/lib/model.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createModel = void 0;
4
+ var actions_1 = require("./actions");
5
+ function createModel(initialContext) {
6
+ var model = {
7
+ initialContext: initialContext,
8
+ assign: actions_1.assign,
9
+ reset: function () { return actions_1.assign(initialContext); }
10
+ };
11
+ return model;
12
+ }
13
+ exports.createModel = createModel;
package/lib/types.d.ts CHANGED
@@ -201,7 +201,7 @@ export declare type StatesDefinition<TContext, TStateSchema extends StateSchema,
201
201
  };
202
202
  export declare type TransitionConfigTarget<TContext, TEvent extends EventObject> = string | undefined | StateNode<TContext, any, TEvent>;
203
203
  export declare type TransitionConfigOrTarget<TContext, TEvent extends EventObject> = SingleOrArray<TransitionConfigTarget<TContext, TEvent> | TransitionConfig<TContext, TEvent>>;
204
- declare type TransitionsConfigMap<TContext, TEvent extends EventObject> = {
204
+ export declare type TransitionsConfigMap<TContext, TEvent extends EventObject> = {
205
205
  [K in TEvent['type']]?: TransitionConfigOrTarget<TContext, TEvent extends {
206
206
  type: K;
207
207
  } ? TEvent : never>;
@@ -616,8 +616,9 @@ export interface CancelAction extends ActionObject<any, any> {
616
616
  sendId: string | number;
617
617
  }
618
618
  export declare type Assigner<TContext, TEvent extends EventObject> = (context: TContext, event: TEvent, meta: AssignMeta<TContext, TEvent>) => Partial<TContext>;
619
+ export declare type PartialAssigner<TContext, TEvent extends EventObject, TKey extends keyof TContext> = (context: TContext, event: TEvent, meta: AssignMeta<TContext, TEvent>) => TContext[TKey];
619
620
  export declare type PropertyAssigner<TContext, TEvent extends EventObject> = {
620
- [K in keyof TContext]?: ((context: TContext, event: TEvent, meta: AssignMeta<TContext, TEvent>) => TContext[K]) | TContext[K];
621
+ [K in keyof TContext]?: PartialAssigner<TContext, TEvent, K> | TContext[K];
621
622
  };
622
623
  export declare type Mapper<TContext, TEvent extends EventObject, TParams extends {}> = (context: TContext, event: TEvent) => TParams;
623
624
  export declare type PropertyMapper<TContext, TEvent extends EventObject, TParams extends {}> = {
@@ -854,6 +855,9 @@ export interface Subscribable<T> {
854
855
  subscribe(next: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
855
856
  }
856
857
  export declare type Spawnable = StateMachine<any, any, any> | Promise<any> | InvokeCallback | Subscribable<any>;
858
+ export declare type ExtractEvent<TEvent extends EventObject, TEventType extends TEvent['type']> = TEvent extends {
859
+ type: TEventType;
860
+ } ? TEvent : never;
857
861
  export interface ActorRef<TEvent extends EventObject, TEmitted = any> extends Subscribable<TEmitted> {
858
862
  send: Sender<TEvent>;
859
863
  }
package/lib/utils.d.ts CHANGED
@@ -10,12 +10,10 @@ export declare function toStatePath(stateId: string | string[], delimiter: strin
10
10
  export declare function isStateLike(state: any): state is StateLike<any>;
11
11
  export declare function toStateValue(stateValue: StateLike<any> | StateValue | string[], delimiter: string): StateValue;
12
12
  export declare function pathToStateValue(statePath: string[]): StateValue;
13
- export declare function mapValues<T, P>(collection: {
13
+ export declare function mapValues<T, P, O extends {
14
14
  [key: string]: T;
15
- }, iteratee: (item: T, key: string, collection: {
16
- [key: string]: T;
17
- }, i: number) => P): {
18
- [key: string]: P;
15
+ }>(collection: O, iteratee: (item: O[keyof O], key: keyof O, collection: O, i: number) => P): {
16
+ [key in keyof O]: P;
19
17
  };
20
18
  export declare function mapFilterValues<T, P>(collection: {
21
19
  [key: string]: T;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xstate",
3
- "version": "4.15.4",
3
+ "version": "4.16.0",
4
4
  "description": "Finite State Machines and Statecharts for the Modern Web.",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",