@koordinates/xstate-tree 4.0.0 → 4.1.0-beta.1

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
@@ -23,10 +23,7 @@ import { createRoot } from "react-dom/client";
23
23
  import { createMachine } from "xstate";
24
24
  import { assign } from "@xstate/immer";
25
25
  import {
26
- buildSelectors,
27
- buildActions,
28
- buildView,
29
- buildXStateTreeMachine,
26
+ createXStateTreeMachine
30
27
  buildRootComponent
31
28
  } from "@koordinates/xstate-tree";
32
29
 
@@ -35,10 +32,6 @@ type Events =
35
32
  | { type: "INCREMENT"; amount: number };
36
33
  type Context = { incremented: number };
37
34
 
38
- // If this tree had more than a single machine the slots to render child machines into would be defined here
39
- // see the codesandbox example for an expanded demonstration that uses slots
40
- const slots = [];
41
-
42
35
  // A standard xstate machine, nothing extra is needed for xstate-tree
43
36
  const machine = createMachine<Context, Events>(
44
37
  {
@@ -74,39 +67,42 @@ const machine = createMachine<Context, Events>(
74
67
  }
75
68
  );
76
69
 
77
- // Selectors to transform the machines state into a representation useful for the view
78
- const selectors = buildSelectors(machine, (ctx, canHandleEvent) => ({
79
- canIncrement: canHandleEvent({ type: "INCREMENT", amount: 1 }),
80
- showSecret: ctx.incremented > 10,
81
- count: ctx.incremented
82
- }));
83
-
84
- // Actions to abstract away the details of sending events to the machine
85
- const actions = buildActions(machine, selectors, (send, selectors) => ({
86
- increment(amount: number) {
87
- send({
88
- type: "INCREMENT",
89
- amount: selectors.count > 4 ? amount * 2 : amount
90
- });
70
+ const RootMachine = createXStateTreeMachine(machine, {
71
+ // Selectors to transform the machines state into a representation useful for the view
72
+ selectors({ ctx, canHandleEvent, inState }) {
73
+ return {
74
+ canIncrement: canHandleEvent({ type: "INCREMENT", amount: 1 }),
75
+ showSecret: ctx.incremented > 10,
76
+ count: ctx.incremented,
77
+ active: inState("active")
78
+ }
91
79
  },
92
- switch() {
93
- send({ type: "SWITCH_CLICKED" });
94
- }
95
- }));
96
-
97
- // A view to bring it all together
98
- // the return value is a plain React view that can be rendered anywhere by passing in the needed props
99
- // the view has no knowledge of the machine it's bound to
100
- const view = buildView(
101
- machine,
102
- selectors,
103
- actions,
104
- slots,
105
- ({ actions, selectors, inState }) => {
80
+ // Actions to abstract away the details of sending events to the machine
81
+ actions({ send, selectors }) {
82
+ return {
83
+ increment(amount: number) {
84
+ send({
85
+ type: "INCREMENT",
86
+ amount: selectors.count > 4 ? amount * 2 : amount
87
+ });
88
+ },
89
+ switch() {
90
+ send({ type: "SWITCH_CLICKED" });
91
+ }
92
+ }
93
+ },
94
+
95
+ // If this tree had more than a single machine the slots to render child machines into would be defined here
96
+ // see the codesandbox example for an expanded demonstration that uses slots
97
+ slots: [],
98
+ // A view to bring it all together
99
+ // the return value is a plain React view that can be rendered anywhere by passing in the needed props
100
+ // the view has no knowledge of the machine it's bound to
101
+ view({ actions, selectors }) {
106
102
  return (
107
103
  <div>
108
104
  <button onClick={() => actions.switch()}>
109
- {inState("active") ? "Deactivate" : "Activate"}
105
+ {selectors.active ? "Deactivate" : "Activate"}
110
106
  </button>
111
107
  <p>Count: {selectors.count}</p>
112
108
  <button
@@ -118,15 +114,7 @@ const view = buildView(
118
114
  {selectors.showSecret && <p>The secret password is hunter2</p>}
119
115
  </div>
120
116
  );
121
- }
122
- );
123
-
124
- // Stapling the machine, selectors, actions, view, and slots together
125
- const RootMachine = buildXStateTreeMachine(machine, {
126
- selectors,
127
- actions,
128
- view,
129
- slots
117
+ },
130
118
  });
131
119
 
132
120
  // Build the React host for the tree
@@ -145,16 +133,16 @@ Each machine that forms the tree representing your UI has an associated set of s
145
133
  - Selector functions are provided with the current context of the machine, a function to determine if it can handle a given event and a function to determine if it is in a given state, and expose the returned result to the view.
146
134
  - Action functions are provided with the `send` method bound to the machines interpreter and the result of calling the selector function
147
135
  - Slots are how children of the machine are exposed to the view. They can be either single slot for a single actor, or multi slot for when you have a list of actors.
148
- - View functions are React views provided with the output of the selector and action functions, a function to determine if the machine is in a given state, and the currently active slots
136
+ - View functions are React views provided with the output of the selector and action functions, and the currently active slots
149
137
 
150
138
  ## API
151
139
 
152
- To assist in making xstate-tree easy to use with TypeScript there are "builder" functions for selectors, actions, views and the final XState tree machine itself. These functions primarily exist to type the arguments passed into the selector/action/view functions.
140
+ To assist in making xstate-tree easy to use with TypeScript there is the `createXStateTreeMachine` function for typing selectors, actions and view arguments and stapling the resulting functions to the xstate machine
153
141
 
154
- * `buildSelectors`, first argument is the machine we are creating selectors for, second argument is the selector factory which receives the machines context as the first argument. It also memoizes the selector factory for better rendering performance
155
- * `buildActions`, first argument is the machine we are creating actions for, the second argument is the result of `buildSelectors` and the third argument is the actions factory which receives an XState `send` function and the result of calling the selectors factory. It also memoizes the selector factory for better rendering performance
156
- * `buildView`, first argument is the machine we are creating a view for, second argument is the selector factory, third argument is the actions factory, fourth argument is the array of slots and the fifth argument is the view function itself which gets supplied the selectors, actions, slots and `inState` method as props. It wraps the view in a React.memo
157
- * `buildXStateTreeMachine` takes the results of `buildSelectors`, `buildActions`, `buildView` and the list of slots and returns an xstate-tree compatible machine
142
+ `createXStateTreeMachine` accepts the xstate machine as the first argument and takes an options argument with the following fields, it is important the fields are defined in this order or TypeScript will infer the wrong types:
143
+ * `selectors`, receives an object with `ctx`, `inState`, and `canHandleEvent` fields. `ctx` is the machines current context, `inState` is the xstate `state.matches` function to allow determining if the machine is in a given state, and `canHandleEvent` accepts an event object and returns whether the machine will do anything in response to that event in it's current state
144
+ * `actions`, receives an object with `send` and `selectors` fields. `send` is the xstate `send` function bound to the machine, and `selectors` is the result of calling the selector function
145
+ * `view`, is a React component that receives `actions`, `selectors`, and `slots` as props. `actions` and `selectors` being the result of the action/selector functions and `slots` being an object with keys as the slot names and the values the slots React component
158
146
 
159
147
  Full API docs coming soon, see [#20](https://github.com/koordinates/xstate-tree/issues/20)
160
148
 
@@ -203,15 +191,6 @@ It is relatively simple to display xstate-tree views directly in Storybook. Sinc
203
191
 
204
192
  There are a few utilities in xstate-tree to make this easier
205
193
 
206
- #### `buildViewProps`
207
- This is a builder function that accepts a view to provide typings and then an object containing
208
- actions/selector fields. With the typings it provides these fields are type safe and you can autocomplete them.
209
-
210
- It returns the props object and extends it with an `inState` factory function, so you can destructure it for use in Stories. The `inState` function accepts a state string as an argument, and returns a function that returns true if the state supplied matches that. So you can easily render the view in a specific machine state in the Story
211
- ```
212
- const { actions, selectors, inState } = buildViewProps(view, { actions: {], selectors: {} });
213
- ```
214
-
215
194
  #### `genericSlotsTestingDummy`
216
195
 
217
196
  This is a simple Proxy object that renders a <div> containing the name of the slot whenever rendering
package/lib/builders.js CHANGED
@@ -14,6 +14,7 @@ import React from "react";
14
14
  * @param machine - The machine to create the selectors for
15
15
  * @param selectors - The selector function
16
16
  * @returns The selectors - ready to be passed to {@link buildActions}
17
+ * @deprecated use {@link createXStateTreeMachine} instead
17
18
  */
18
19
  export function buildSelectors(__machine, selectors) {
19
20
  let lastState = undefined;
@@ -52,6 +53,7 @@ export function buildSelectors(__machine, selectors) {
52
53
  * @param selectors - The selectors function
53
54
  * @param actions - The action function
54
55
  * @returns The actions function - ready to be passed to {@link buildView}
56
+ * @deprecated use {@link createXStateTreeMachine} instead
55
57
  * */
56
58
  export function buildActions(__machine, __selectors, actions) {
57
59
  return actions;
@@ -73,6 +75,7 @@ export function buildActions(__machine, __selectors, actions) {
73
75
  * @param slots - The array of slots that can be rendered by the view
74
76
  * @param view - The view function
75
77
  * @returns The React view
78
+ * @deprecated use {@link createXStateTreeMachine} instead
76
79
  */
77
80
  export function buildView(__machine, __selectors, __actions, __slots, view) {
78
81
  return React.memo(view);
@@ -85,11 +88,52 @@ export function buildView(__machine, __selectors, __actions, __slots, view) {
85
88
  * @param machine - The machine to staple the selectors/actions/slots/view to
86
89
  * @param metadata - The xstate-tree metadata to staple to the machine
87
90
  * @returns The xstate-tree machine, ready to be invoked by other xstate-machines or used with `buildRootComponent`
91
+ * @deprecated use {@link createXStateTreeMachine} instead
88
92
  */
89
93
  export function buildXStateTreeMachine(machine, meta) {
90
94
  const copiedMeta = { ...meta };
91
95
  copiedMeta.xstateTreeMachine = true;
92
- machine.config.meta = { ...machine.config.meta, ...copiedMeta };
93
- machine.meta = { ...machine.meta, ...copiedMeta };
96
+ machine.config.meta = {
97
+ ...machine.config.meta,
98
+ ...copiedMeta,
99
+ builderVersion: 1,
100
+ };
101
+ machine.meta = { ...machine.meta, ...copiedMeta, builderVersion: 1 };
102
+ return machine;
103
+ }
104
+ /**
105
+ * @public
106
+ * Creates an xstate-tree machine from an xstate-machine
107
+ *
108
+ * Accepts an options object defining the selectors/actions/slots and view for the xstate-tree machine
109
+ *
110
+ * Selectors/slots/actions can be omitted from the options object and will default to
111
+ * - actions: an empty object
112
+ * - selectors: the context of the machine
113
+ * - slots: an empty array
114
+ *
115
+ * @param machine - The xstate machine to create the xstate-tree machine from
116
+ * @param options - the xstate-tree options
117
+ */
118
+ export function createXStateTreeMachine(machine, options) {
119
+ var _a, _b, _c;
120
+ const selectors = (_a = options.selectors) !== null && _a !== void 0 ? _a : (({ ctx }) => ctx);
121
+ const actions = (_b = options.actions) !== null && _b !== void 0 ? _b : (() => ({}));
122
+ const xstateTreeMeta = {
123
+ selectors,
124
+ actions,
125
+ view: options.view,
126
+ slots: (_c = options.slots) !== null && _c !== void 0 ? _c : [],
127
+ };
128
+ machine.meta = {
129
+ ...machine.meta,
130
+ ...xstateTreeMeta,
131
+ builderVersion: 2,
132
+ };
133
+ machine.config.meta = {
134
+ ...machine.config.meta,
135
+ ...xstateTreeMeta,
136
+ builderVersion: 2,
137
+ };
94
138
  return machine;
95
139
  }
@@ -18,6 +18,14 @@ import { StateMachine } from 'xstate';
18
18
  import { TypegenDisabled } from 'xstate';
19
19
  import * as Z from 'zod';
20
20
 
21
+ /**
22
+ * @public
23
+ */
24
+ export declare type Actions<TMachine extends AnyStateMachine, TSelectorsOutput, TOut> = (args: {
25
+ send: InterpreterFrom<TMachine>["send"];
26
+ selectors: TSelectorsOutput;
27
+ }) => TOut;
28
+
21
29
  /**
22
30
  * @public
23
31
  */
@@ -45,12 +53,12 @@ export declare type AnyRoute = {
45
53
  /**
46
54
  * @public
47
55
  */
48
- export declare type AnySelector = Selectors<any, any, any, any>;
56
+ export declare type AnySelector = V1Selectors<any, any, any, any>;
49
57
 
50
58
  /**
51
59
  * @public
52
60
  */
53
- export declare type AnyXstateTreeMachine = StateMachine<any, XstateTreeMachineStateSchema<AnyStateMachine, any, any>, any>;
61
+ export declare type AnyXstateTreeMachine = StateMachine<any, XstateTreeMachineStateSchemaV1<AnyStateMachine, AnySelector, AnyActions> | XstateTreeMachineStateSchemaV2<AnyStateMachine, any, any>, any>;
54
62
 
55
63
  /**
56
64
  * @public
@@ -80,6 +88,7 @@ export declare function broadcast(event: GlobalEvents): void;
80
88
  * @param selectors - The selectors function
81
89
  * @param actions - The action function
82
90
  * @returns The actions function - ready to be passed to {@link buildView}
91
+ * @deprecated use {@link createXStateTreeMachine} instead
83
92
  * */
84
93
  export declare function buildActions<TMachine extends AnyStateMachine, TActions, TSelectors, TSend = InterpreterFrom<TMachine>["send"]>(__machine: TMachine, __selectors: TSelectors, actions: (send: TSend, selectors: OutputFromSelector<TSelectors>) => TActions): (send: TSend, selectors: OutputFromSelector<TSelectors>) => TActions;
85
94
 
@@ -174,8 +183,9 @@ export declare function buildRootComponent(machine: AnyXstateTreeMachine, routin
174
183
  * @param machine - The machine to create the selectors for
175
184
  * @param selectors - The selector function
176
185
  * @returns The selectors - ready to be passed to {@link buildActions}
186
+ * @deprecated use {@link createXStateTreeMachine} instead
177
187
  */
178
- export declare function buildSelectors<TMachine extends AnyStateMachine, TSelectors, TContext = ContextFrom<TMachine>>(__machine: TMachine, selectors: (ctx: TContext, canHandleEvent: CanHandleEvent<TMachine>, inState: MatchesFrom<TMachine>, __currentState: never) => TSelectors): Selectors<TContext, EventFrom<TMachine>, TSelectors, MatchesFrom<TMachine>>;
188
+ export declare function buildSelectors<TMachine extends AnyStateMachine, TSelectors, TContext = ContextFrom<TMachine>>(__machine: TMachine, selectors: (ctx: TContext, canHandleEvent: CanHandleEvent<TMachine>, inState: MatchesFrom<TMachine>, __currentState: never) => TSelectors): V1Selectors<TContext, EventFrom<TMachine>, TSelectors, MatchesFrom<TMachine>>;
179
189
 
180
190
  /**
181
191
  * @public
@@ -192,7 +202,7 @@ export declare function buildSelectors<TMachine extends AnyStateMachine, TSelect
192
202
  *
193
203
  * It also delays for 5ms to ensure any React re-rendering happens in response to the state transition
194
204
  */
195
- export declare function buildTestRootComponent<TMachine extends AnyStateMachine, TSelectors extends AnySelector, TActions extends AnyActions, TContext = ContextFrom<TMachine>>(machine: StateMachine<TContext, XstateTreeMachineStateSchema<TMachine, TSelectors, TActions>, EventFrom<TMachine>>, logger: typeof console.log): {
205
+ export declare function buildTestRootComponent<TMachine extends AnyStateMachine, TSelectors extends AnySelector, TActions extends AnyActions, TContext = ContextFrom<TMachine>>(machine: StateMachine<TContext, XstateTreeMachineStateSchemaV1<TMachine, TSelectors, TActions>, EventFrom<TMachine>>, logger: typeof console.log): {
196
206
  rootComponent: () => JSX.Element | null;
197
207
  addTransitionListener: (listener: () => void) => void;
198
208
  awaitTransition(): Promise<void>;
@@ -215,6 +225,7 @@ export declare function buildTestRootComponent<TMachine extends AnyStateMachine,
215
225
  * @param slots - The array of slots that can be rendered by the view
216
226
  * @param view - The view function
217
227
  * @returns The React view
228
+ * @deprecated use {@link createXStateTreeMachine} instead
218
229
  */
219
230
  export declare function buildView<TMachine extends AnyStateMachine, TEvent extends EventObject, TActions, TSelectors extends AnySelector, TSlots extends readonly Slot[] = [], TMatches extends AnyFunction = MatchesFrom<TMachine>, TViewProps = ViewProps<OutputFromSelector<TSelectors>, TActions, TSlots, TMatches>, TSend = (send: TEvent) => void>(__machine: TMachine, __selectors: TSelectors, __actions: (send: TSend, selectors: OutputFromSelector<TSelectors>) => TActions, __slots: TSlots, view: React_2.ComponentType<TViewProps>): React_2.ComponentType<TViewProps>;
220
231
 
@@ -237,13 +248,33 @@ export declare function buildViewProps<C extends keyof JSX.IntrinsicElements | J
237
248
  * @param machine - The machine to staple the selectors/actions/slots/view to
238
249
  * @param metadata - The xstate-tree metadata to staple to the machine
239
250
  * @returns The xstate-tree machine, ready to be invoked by other xstate-machines or used with `buildRootComponent`
251
+ * @deprecated use {@link createXStateTreeMachine} instead
240
252
  */
241
- export declare function buildXStateTreeMachine<TMachine extends AnyStateMachine, TSelectors extends AnySelector, TActions extends AnyActions>(machine: TMachine, meta: XStateTreeMachineMeta<TMachine, TSelectors, TActions>): StateMachine<ContextFrom<TMachine>, XstateTreeMachineStateSchema<TMachine, TSelectors, TActions>, EventFrom<TMachine>, any, any, any, any>;
253
+ export declare function buildXStateTreeMachine<TMachine extends AnyStateMachine, TSelectors extends AnySelector, TActions extends AnyActions>(machine: TMachine, meta: XStateTreeMachineMetaV1<TMachine, TSelectors, TActions>): StateMachine<ContextFrom<TMachine>, XstateTreeMachineStateSchemaV1<TMachine, TSelectors, TActions>, EventFrom<TMachine>, any, any, any, any>;
242
254
 
243
- declare type CanHandleEvent<TMachine extends AnyStateMachine> = (e: EventFrom<TMachine>) => boolean;
255
+ /**
256
+ * @internal
257
+ */
258
+ export declare type CanHandleEvent<TMachine extends AnyStateMachine> = (e: EventFrom<TMachine>) => boolean;
244
259
 
245
260
  declare type Context = {};
246
261
 
262
+ /**
263
+ * @public
264
+ * Creates an xstate-tree machine from an xstate-machine
265
+ *
266
+ * Accepts an options object defining the selectors/actions/slots and view for the xstate-tree machine
267
+ *
268
+ * Selectors/slots/actions can be omitted from the options object and will default to
269
+ * - actions: an empty object
270
+ * - selectors: the context of the machine
271
+ * - slots: an empty array
272
+ *
273
+ * @param machine - The xstate machine to create the xstate-tree machine from
274
+ * @param options - the xstate-tree options
275
+ */
276
+ export declare function createXStateTreeMachine<TMachine extends AnyStateMachine, TSelectorsOutput = ContextFrom<TMachine>, TActionsOutput = Record<never, string>, TSlots extends readonly Slot[] = []>(machine: TMachine, options: V2BuilderMeta<TMachine, TSelectorsOutput, TActionsOutput, TSlots>): StateMachine<ContextFrom<TMachine>, XstateTreeMachineStateSchemaV2<TMachine, TSelectorsOutput, TActionsOutput, TSlots>, EventFrom<TMachine>, any, any, any, any>;
277
+
247
278
  declare type EmptyKeys<T> = keyof {
248
279
  [K in keyof T as IsEmptyObject<T[K], true> extends true ? K : never]: T[K];
249
280
  };
@@ -400,7 +431,7 @@ declare type Options<TContext> = {
400
431
  /**
401
432
  * @public
402
433
  */
403
- export declare type OutputFromSelector<T> = T extends Selectors<any, any, infer O, any> ? O : never;
434
+ export declare type OutputFromSelector<T> = T extends V1Selectors<any, any, infer O, any> ? O : never;
404
435
 
405
436
  /**
406
437
  * @public
@@ -582,7 +613,11 @@ export declare type RoutingEvent<T> = T extends Route<infer TParams, infer TQuer
582
613
  /**
583
614
  * @public
584
615
  */
585
- export declare type Selectors<TContext, TEvent, TSelectors, TMatches> = (ctx: TContext, canHandleEvent: (e: TEvent) => boolean, inState: TMatches, __currentState: never) => TSelectors;
616
+ export declare type Selectors<TMachine extends AnyStateMachine, TOut> = (args: {
617
+ ctx: ContextFrom<TMachine>;
618
+ canHandleEvent: CanHandleEvent<TMachine>;
619
+ inState: MatchesFrom<TMachine>;
620
+ }) => TOut;
586
621
 
587
622
  /**
588
623
  * @public
@@ -636,7 +671,7 @@ export declare type Slot = SingleSlot<any> | MultiSlot<any>;
636
671
  * @param name - the string to render in the machines view
637
672
  * @returns a dummy machine that renders a div containing the supplied string
638
673
  */
639
- export declare function slotTestingDummyFactory(name: string): StateMachine<unknown, XstateTreeMachineStateSchema<StateMachine<unknown, any, AnyEventObject, {
674
+ export declare function slotTestingDummyFactory(name: string): StateMachine<unknown, XstateTreeMachineStateSchemaV1<StateMachine<unknown, any, AnyEventObject, {
640
675
  value: any;
641
676
  context: unknown;
642
677
  }, BaseActionObject, ServiceMap, ResolveTypegenMeta<TypegenDisabled, AnyEventObject, BaseActionObject, ServiceMap>>, () => {}, () => {}>, AnyEventObject, any, any, any, any>;
@@ -662,6 +697,30 @@ declare type States = {
662
697
  */
663
698
  export declare type StyledLink<TStyleProps = {}> = <TRoute extends AnyRoute>(props: LinkProps<TRoute> & TStyleProps) => JSX.Element;
664
699
 
700
+ /**
701
+ * @public
702
+ */
703
+ export declare type V1Selectors<TContext, TEvent, TSelectors, TMatches> = (ctx: TContext, canHandleEvent: (e: TEvent) => boolean, inState: TMatches, __currentState: never) => TSelectors;
704
+
705
+ /**
706
+ * @public
707
+ */
708
+ export declare type V2BuilderMeta<TMachine extends AnyStateMachine, TSelectorsOutput = ContextFrom<TMachine>, TActionsOutput = Record<never, string>, TSlots extends readonly Slot[] = Slot[]> = {
709
+ selectors?: Selectors<TMachine, TSelectorsOutput>;
710
+ actions?: Actions<TMachine, TSelectorsOutput, TActionsOutput>;
711
+ slots?: TSlots;
712
+ view: View<TActionsOutput, TSelectorsOutput, TSlots>;
713
+ };
714
+
715
+ /**
716
+ * @public
717
+ */
718
+ export declare type View<TActionsOutput, TSelectorsOutput, TSlots extends readonly Slot[]> = React_2.ComponentType<{
719
+ slots: Record<GetSlotNames<TSlots>, React_2.ComponentType>;
720
+ actions: TActionsOutput;
721
+ selectors: TSelectorsOutput;
722
+ }>;
723
+
665
724
  /**
666
725
  * @public
667
726
  */
@@ -669,6 +728,9 @@ export declare type ViewProps<TSelectors, TActions, TSlots extends readonly Slot
669
728
  slots: Record<GetSlotNames<TSlots>, React_2.ComponentType>;
670
729
  actions: TActions;
671
730
  selectors: TSelectors;
731
+ /**
732
+ * @deprecated see https://github.com/koordinates/xstate-tree/issues/33 use `inState` in the selector function instead
733
+ */
672
734
  inState: TMatches;
673
735
  };
674
736
 
@@ -683,7 +745,7 @@ export declare type XstateTreeHistory<T = unknown> = History_2<{
683
745
  /**
684
746
  * @public
685
747
  */
686
- export declare type XStateTreeMachineMeta<TMachine extends AnyStateMachine, TSelectors, TActions extends AnyActions, TSlots extends readonly Slot[] = Slot[]> = {
748
+ export declare type XStateTreeMachineMetaV1<TMachine extends AnyStateMachine, TSelectors, TActions extends AnyActions, TSlots extends readonly Slot[] = Slot[]> = {
687
749
  slots: TSlots;
688
750
  view: React_2.ComponentType<ViewProps<OutputFromSelector<TSelectors>, ReturnType<TActions>, TSlots, MatchesFrom<TMachine>>>;
689
751
  selectors: TSelectors;
@@ -694,8 +756,19 @@ export declare type XStateTreeMachineMeta<TMachine extends AnyStateMachine, TSel
694
756
  /**
695
757
  * @public
696
758
  */
697
- export declare type XstateTreeMachineStateSchema<TMachine extends AnyStateMachine, TSelectors extends AnySelector, TActions extends AnyActions> = {
698
- meta: XStateTreeMachineMeta<TMachine, TSelectors, TActions>;
759
+ export declare type XstateTreeMachineStateSchemaV1<TMachine extends AnyStateMachine, TSelectors extends AnySelector, TActions extends AnyActions> = {
760
+ meta: XStateTreeMachineMetaV1<TMachine, TSelectors, TActions> & {
761
+ builderVersion: 1;
762
+ };
763
+ };
764
+
765
+ /**
766
+ * @public
767
+ */
768
+ export declare type XstateTreeMachineStateSchemaV2<TMachine extends AnyStateMachine, TSelectorsOutput = ContextFrom<TMachine>, TActionsOutput = Record<never, string>, TSlots extends readonly Slot[] = Slot[]> = {
769
+ meta: Required<V2BuilderMeta<TMachine, TSelectorsOutput, TActionsOutput, TSlots> & {
770
+ builderVersion: 2;
771
+ }>;
699
772
  };
700
773
 
701
774
  export { }
package/lib/xstateTree.js CHANGED
@@ -77,7 +77,6 @@ function useSlots(interpreter, slots) {
77
77
  [slot]: () => {
78
78
  // eslint-disable-next-line react-hooks/rules-of-hooks
79
79
  const [__, children] = useService(interpreter);
80
- console.log(slot.toString());
81
80
  if (slot.toString().endsWith("Multi")) {
82
81
  const MultiView = getMultiSlotViewForChildren(interpreter, slot.toLowerCase());
83
82
  return React.createElement(MultiView, null);
@@ -105,11 +104,12 @@ function XstateTreeMultiSlotView({ childInterpreters, }) {
105
104
  * @internal
106
105
  */
107
106
  export function XstateTreeView({ interpreter }) {
107
+ var _a, _b;
108
108
  const [current] = useService(interpreter);
109
109
  const currentRef = useRef(current);
110
110
  currentRef.current = current;
111
111
  const selectorsRef = useRef(undefined);
112
- const { view: View, actions: actionsFactory, selectors: selectorsFactory, slots: interpreterSlots, } = interpreter.machine.meta;
112
+ const { slots: interpreterSlots } = interpreter.machine.meta;
113
113
  const slots = useSlots(interpreter, interpreterSlots.map((x) => x.name));
114
114
  const canHandleEvent = useCallback((e) => {
115
115
  var _a;
@@ -132,14 +132,44 @@ export function XstateTreeView({ interpreter }) {
132
132
  });
133
133
  });
134
134
  const actions = useConstant(() => {
135
- return actionsFactory(interpreter.send, selectorsProxy);
135
+ var _a;
136
+ switch ((_a = interpreter.machine.meta) === null || _a === void 0 ? void 0 : _a.builderVersion) {
137
+ case 1:
138
+ return interpreter.machine.meta.actions(interpreter.send, selectorsProxy);
139
+ case 2:
140
+ return interpreter.machine.meta.actions({
141
+ send: interpreter.send,
142
+ selectors: selectorsProxy,
143
+ });
144
+ default:
145
+ throw new Error("builderVersion not set");
146
+ }
136
147
  });
137
148
  if (!current) {
138
149
  return null;
139
150
  }
140
- const selectors = selectorsFactory(current.context, canHandleEvent, inState, current.value);
141
- selectorsRef.current = selectors;
142
- return (React.createElement(View, { selectors: selectors, actions: actions, slots: slots, inState: inState }));
151
+ switch ((_a = interpreter.machine.meta) === null || _a === void 0 ? void 0 : _a.builderVersion) {
152
+ case 1:
153
+ selectorsRef.current = interpreter.machine.meta.selectors(current.context, canHandleEvent, inState, current.value);
154
+ break;
155
+ case 2:
156
+ selectorsRef.current = interpreter.machine.meta.selectors({
157
+ ctx: current.context,
158
+ canHandleEvent,
159
+ inState,
160
+ });
161
+ break;
162
+ }
163
+ switch ((_b = interpreter.machine.meta) === null || _b === void 0 ? void 0 : _b.builderVersion) {
164
+ case 1:
165
+ const ViewV1 = interpreter.machine.meta.view;
166
+ return (React.createElement(ViewV1, { selectors: selectorsRef.current, actions: actions, slots: slots, inState: inState }));
167
+ case 2:
168
+ const ViewV2 = interpreter.machine.meta.view;
169
+ return (React.createElement(ViewV2, { selectors: selectorsRef.current, actions: actions, slots: slots }));
170
+ default:
171
+ throw new Error("builderVersion not set");
172
+ }
143
173
  }
144
174
  /**
145
175
  * @internal
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@koordinates/xstate-tree",
3
3
  "main": "lib/index.js",
4
4
  "types": "lib/xstate-tree.d.ts",
5
- "version": "4.0.0",
5
+ "version": "4.1.0-beta.1",
6
6
  "license": "MIT",
7
7
  "description": "Build UIs with Actors using xstate and React",
8
8
  "keywords": [