@koordinates/xstate-tree 4.4.0-beta.1 → 5.1.0-next.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/lib/builders.js CHANGED
@@ -3,115 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.viewToMachine = exports.createXStateTreeMachine = exports.buildXStateTreeMachine = exports.buildView = exports.buildActions = exports.buildSelectors = void 0;
6
+ exports.buildRoutingMachine = exports.viewToMachine = exports.createXStateTreeMachine = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const xstate_1 = require("xstate");
9
- /**
10
- * @public
11
- *
12
- * Factory function for selectors. The selectors function is passed three arguments:
13
- * - `ctx` - the current context of the machines state
14
- * - `canHandleEvent` - a function that can be used to determine if the machine can handle a
15
- * given event, by simulating sending the event and seeing if a stat change would happen.
16
- * Handles guards
17
- * - `inState` - equivalent to xstates `state.matches`, allows checking if the machine is in a given state
18
- *
19
- * The resulting selector function has memoization. It will return the same value until the
20
- * machine's state changes or the machine's context changes
21
- * @param machine - The machine to create the selectors for
22
- * @param selectors - The selector function
23
- * @returns The selectors - ready to be passed to {@link buildActions}
24
- * @deprecated use {@link createXStateTreeMachine} instead
25
- */
26
- function buildSelectors(__machine, selectors) {
27
- let lastState = undefined;
28
- let lastCachedResult = undefined;
29
- let lastCtxRef = undefined;
30
- return (ctx, canHandleEvent, inState, currentState) => {
31
- // Handles caching to ensure stable references to selector results
32
- // Only re-run the selector if
33
- // * The reference to the context object has changed (the context object should never be mutated)
34
- // * The last state we ran the selectors in has changed. This is to ensure `canHandleEvent` and `inState` calls aren't stale
35
- if (lastCtxRef === ctx &&
36
- lastState === currentState &&
37
- lastCachedResult !== undefined) {
38
- return lastCachedResult;
39
- }
40
- else {
41
- const result = selectors(ctx, canHandleEvent, inState, currentState);
42
- lastCtxRef = ctx;
43
- lastCachedResult = result;
44
- lastState = currentState;
45
- return result;
46
- }
47
- };
48
- }
49
- exports.buildSelectors = buildSelectors;
50
- /**
51
- * @public
52
- *
53
- * Factory function for actions. The actions function is passed two arguments:
54
- * - `send` - the interpreters send function, which can be used to send events to the machine
55
- * - `selectors` - the output of the selectors function from {@link buildSelectors}
56
- *
57
- * The resulting action function will only be called once per invocation of a machine.
58
- * The selectors are passed in as a proxy to always read the latest selector value
59
- *
60
- * @param machine - The machine to create the actions for
61
- * @param selectors - The selectors function
62
- * @param actions - The action function
63
- * @returns The actions function - ready to be passed to {@link buildView}
64
- * @deprecated use {@link createXStateTreeMachine} instead
65
- * */
66
- function buildActions(__machine, __selectors, actions) {
67
- return actions;
68
- }
69
- exports.buildActions = buildActions;
70
- /**
71
- * @public
72
- *
73
- * Factory function for views. The view is passed four props:
74
- * - `slots` - the slots object, which can be used to render the children of the view invoked by the machine
75
- * - `actions` - the output of the actions function from {@link buildActions}
76
- * - `selectors` - the output of the selectors function from {@link buildSelectors}
77
- * - `inState` - equivalent to xstates `state.matches`, allows checking if the machine is in a given state
78
- *
79
- * The resulting view is wrapped in React.memo, it will re-render when the actions or selectors reference changes
80
- *
81
- * @param machine - The machine to create the view for
82
- * @param selectors - The selectors function from {@link buildSelectors}
83
- * @param actions - The actions function from {@link buildActions}
84
- * @param slots - The array of slots that can be rendered by the view
85
- * @param view - The view function
86
- * @returns The React view
87
- * @deprecated use {@link createXStateTreeMachine} instead
88
- */
89
- function buildView(__machine, __selectors, __actions, __slots, view) {
90
- return react_1.default.memo(view);
91
- }
92
- exports.buildView = buildView;
93
- /**
94
- * @public
95
- *
96
- * staples xstate machine and xstate-tree metadata together into an xstate-tree machine
97
- *
98
- * @param machine - The machine to staple the selectors/actions/slots/view to
99
- * @param metadata - The xstate-tree metadata to staple to the machine
100
- * @returns The xstate-tree machine, ready to be invoked by other xstate-machines or used with `buildRootComponent`
101
- * @deprecated use {@link createXStateTreeMachine} instead
102
- */
103
- function buildXStateTreeMachine(machine, meta) {
104
- const copiedMeta = { ...meta };
105
- copiedMeta.xstateTreeMachine = true;
106
- machine.config.meta = {
107
- ...machine.config.meta,
108
- ...copiedMeta,
109
- builderVersion: 1,
110
- };
111
- machine.meta = { ...machine.meta, ...copiedMeta, builderVersion: 1 };
112
- return machine;
113
- }
114
- exports.buildXStateTreeMachine = buildXStateTreeMachine;
9
+ const slots_1 = require("./slots");
115
10
  /**
116
11
  * @public
117
12
  * Creates an xstate-tree machine from an xstate-machine
@@ -127,26 +22,16 @@ exports.buildXStateTreeMachine = buildXStateTreeMachine;
127
22
  * @param options - the xstate-tree options
128
23
  */
129
24
  function createXStateTreeMachine(machine, options) {
130
- var _a, _b, _c;
131
- const selectors = (_a = options.selectors) !== null && _a !== void 0 ? _a : (({ ctx }) => ctx);
132
- const actions = (_b = options.actions) !== null && _b !== void 0 ? _b : (() => ({}));
133
- const xstateTreeMeta = {
134
- selectors,
135
- actions,
25
+ const selectors = options.selectors ?? (({ ctx }) => ctx);
26
+ const actions = options.actions ?? (() => ({}));
27
+ const machineWithMeta = machine;
28
+ machineWithMeta._xstateTree = {
29
+ selectors: selectors,
30
+ actions: actions,
136
31
  View: options.View,
137
- slots: (_c = options.slots) !== null && _c !== void 0 ? _c : [],
138
- };
139
- machine.meta = {
140
- ...machine.meta,
141
- ...xstateTreeMeta,
142
- builderVersion: 2,
143
- };
144
- machine.config.meta = {
145
- ...machine.config.meta,
146
- ...xstateTreeMeta,
147
- builderVersion: 2,
32
+ slots: (options.slots ?? []),
148
33
  };
149
- return machine;
34
+ return machineWithMeta;
150
35
  }
151
36
  exports.createXStateTreeMachine = createXStateTreeMachine;
152
37
  /**
@@ -158,8 +43,62 @@ exports.createXStateTreeMachine = createXStateTreeMachine;
158
43
  * @returns The view wrapped into an xstate-tree machine, ready to be invoked by other xstate machines or used with `buildRootComponent`
159
44
  */
160
45
  function viewToMachine(view) {
161
- return createXStateTreeMachine((0, xstate_1.createMachine)({ initial: "idle", states: { idle: {} } }), {
46
+ return createXStateTreeMachine((0, xstate_1.createMachine)({
47
+ initial: "idle",
48
+ states: { idle: {} },
49
+ }), {
162
50
  View: view,
163
51
  });
164
52
  }
165
53
  exports.viewToMachine = viewToMachine;
54
+ /**
55
+ * @public
56
+ *
57
+ * Utility to aid in reducing boilerplate of mapping route events to xstate-tree machines
58
+ *
59
+ * Takes a list of routes and a mapping of route events to xstate-tree machines and returns an xstate-tree machine
60
+ * that renders the machines based on the routing events
61
+ *
62
+ * @param _routes - the array of routes you wish to map to machines
63
+ * @param mappings - an object mapping the route events to the machine to invoke
64
+ * @returns an xstate-tree machine that will render the right machines based on the routing events
65
+ */
66
+ function buildRoutingMachine(_routes, mappings) {
67
+ const contentSlot = (0, slots_1.singleSlot)("Content");
68
+ const mappingsToStates = Object.entries(mappings).reduce((acc, [event, _machine]) => {
69
+ return {
70
+ ...acc,
71
+ [event]: {
72
+ invoke: {
73
+ src: event,
74
+ id: contentSlot.getId(),
75
+ },
76
+ },
77
+ };
78
+ }, {});
79
+ const mappingsToEvents = Object.keys(mappings).reduce((acc, event) => ({
80
+ ...acc,
81
+ [event]: {
82
+ target: `.${event}`,
83
+ },
84
+ }), {});
85
+ const machine = (0, xstate_1.setup)({
86
+ actors: mappings,
87
+ }).createMachine({
88
+ on: {
89
+ ...mappingsToEvents,
90
+ },
91
+ initial: "idle",
92
+ states: {
93
+ idle: {},
94
+ ...mappingsToStates,
95
+ },
96
+ });
97
+ return createXStateTreeMachine(machine, {
98
+ slots: [contentSlot],
99
+ View: ({ slots }) => {
100
+ return react_1.default.createElement(slots.Content, null);
101
+ },
102
+ });
103
+ }
104
+ exports.buildRoutingMachine = buildRoutingMachine;
package/lib/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.lazy = exports.loggingMetaOptions = exports.TestRoutingContext = exports.useActiveRouteEvents = exports.useRouteArgsIfActive = exports.useIsRouteActive = exports.matchRoute = exports.buildCreateRoute = exports.Link = exports.slotTestingDummyFactory = exports.genericSlotsTestingDummy = exports.buildViewProps = exports.buildTestRootComponent = exports.onBroadcast = exports.buildRootComponent = exports.broadcast = void 0;
17
+ exports.lazy = exports.loggingMetaOptions = exports.TestRoutingContext = exports.useActiveRouteEvents = exports.useRouteArgsIfActive = exports.useIsRouteActive = exports.matchRoute = exports.buildCreateRoute = exports.Link = exports.genericSlotsTestingDummy = exports.onBroadcast = exports.buildRootComponent = exports.broadcast = void 0;
18
18
  __exportStar(require("./builders"), exports);
19
19
  __exportStar(require("./slots"), exports);
20
20
  var xstateTree_1 = require("./xstateTree");
@@ -23,10 +23,7 @@ Object.defineProperty(exports, "buildRootComponent", { enumerable: true, get: fu
23
23
  Object.defineProperty(exports, "onBroadcast", { enumerable: true, get: function () { return xstateTree_1.onBroadcast; } });
24
24
  __exportStar(require("./types"), exports);
25
25
  var testingUtilities_1 = require("./testingUtilities");
26
- Object.defineProperty(exports, "buildTestRootComponent", { enumerable: true, get: function () { return testingUtilities_1.buildTestRootComponent; } });
27
- Object.defineProperty(exports, "buildViewProps", { enumerable: true, get: function () { return testingUtilities_1.buildViewProps; } });
28
26
  Object.defineProperty(exports, "genericSlotsTestingDummy", { enumerable: true, get: function () { return testingUtilities_1.genericSlotsTestingDummy; } });
29
- Object.defineProperty(exports, "slotTestingDummyFactory", { enumerable: true, get: function () { return testingUtilities_1.slotTestingDummyFactory; } });
30
27
  var routing_1 = require("./routing");
31
28
  Object.defineProperty(exports, "Link", { enumerable: true, get: function () { return routing_1.Link; } });
32
29
  Object.defineProperty(exports, "buildCreateRoute", { enumerable: true, get: function () { return routing_1.buildCreateRoute; } });
package/lib/lazy.js CHANGED
@@ -18,41 +18,41 @@ const slots_1 = require("./slots");
18
18
  * @param options - configure loading component and context to invoke machine with
19
19
  * @returns an xstate-tree machine that wraps the promise, invoking the resulting machine when it resolves
20
20
  */
21
- function lazy(factory, { Loader = () => null, withContext = () => ({}), } = {}) {
21
+ function lazy(factory, { Loader = () => null, input } = {}) {
22
22
  const loadedMachineSlot = (0, slots_1.singleSlot)("loadedMachine");
23
23
  const slots = [loadedMachineSlot];
24
- const machine = (0, xstate_1.createMachine)({
24
+ const machine = (0, xstate_1.setup)({}).createMachine({
25
25
  initial: "loading",
26
+ context: {},
26
27
  states: {
27
28
  loading: {
28
29
  invoke: {
29
- src: () => factory,
30
- onDone: "rendering",
31
- },
32
- },
33
- rendering: {
34
- invoke: {
35
- id: loadedMachineSlot.getId(),
36
- src: (_ctx, e) => {
37
- return e.data.withContext({ ...e.data.context, ...withContext() });
30
+ src: (0, xstate_1.fromPromise)(factory),
31
+ onDone: {
32
+ target: "rendering",
33
+ actions: (0, xstate_1.assign)({
34
+ loadedMachine: ({ spawn, event }) => spawn(event.output, {
35
+ id: loadedMachineSlot.getId(),
36
+ input,
37
+ }),
38
+ }),
38
39
  },
39
40
  },
40
41
  },
42
+ rendering: {},
41
43
  },
42
44
  });
43
- const selectors = (0, builders_1.buildSelectors)(machine, (ctx) => ctx);
44
- const actions = (0, builders_1.buildActions)(machine, selectors, (_send, _selectors) => { });
45
- const view = (0, builders_1.buildView)(machine, selectors, actions, slots, ({ slots, inState }) => {
46
- if (inState("loading")) {
47
- return react_1.default.createElement(Loader, null);
48
- }
49
- return react_1.default.createElement(slots.loadedMachine, null);
50
- });
51
- return (0, builders_1.buildXStateTreeMachine)(machine, {
52
- actions,
53
- selectors,
45
+ return (0, builders_1.createXStateTreeMachine)(machine, {
54
46
  slots,
55
- view,
47
+ selectors({ inState }) {
48
+ return { loading: inState("loading") };
49
+ },
50
+ View({ selectors, slots }) {
51
+ if (selectors.loading) {
52
+ return react_1.default.createElement(Loader, null);
53
+ }
54
+ return react_1.default.createElement(slots.loadedMachine, null);
55
+ },
56
56
  });
57
57
  }
58
58
  exports.lazy = lazy;
@@ -34,13 +34,13 @@ function LinkInner({ to, children, testId, preloadOnHoverMs, preloadOnInteractio
34
34
  const href = (0, useHref_1.useHref)(to, params, query);
35
35
  const onMouseDown = preloadOnInteraction
36
36
  ? (e) => {
37
- _onMouseDown === null || _onMouseDown === void 0 ? void 0 : _onMouseDown(e);
37
+ _onMouseDown?.(e);
38
38
  to.preload({ params, query, meta });
39
39
  }
40
40
  : undefined;
41
41
  const onMouseEnter = preloadOnHoverMs !== undefined
42
42
  ? (e) => {
43
- _onMouseEnter === null || _onMouseEnter === void 0 ? void 0 : _onMouseEnter(e);
43
+ _onMouseEnter?.(e);
44
44
  timeout = setTimeout(() => {
45
45
  to.preload({ params, query, meta });
46
46
  }, preloadOnHoverMs);
@@ -48,15 +48,14 @@ function LinkInner({ to, children, testId, preloadOnHoverMs, preloadOnInteractio
48
48
  : undefined;
49
49
  const onMouseLeave = preloadOnHoverMs !== undefined
50
50
  ? (e) => {
51
- _onMouseLeave === null || _onMouseLeave === void 0 ? void 0 : _onMouseLeave(e);
51
+ _onMouseLeave?.(e);
52
52
  if (timeout !== undefined) {
53
53
  clearTimeout(timeout);
54
54
  }
55
55
  }
56
56
  : undefined;
57
- return (react_1.default.createElement("a", { ...props, ref: ref, href: href, "data-testid": testId, onMouseDown: onMouseDown !== null && onMouseDown !== void 0 ? onMouseDown : _onMouseDown, onMouseEnter: onMouseEnter !== null && onMouseEnter !== void 0 ? onMouseEnter : _onMouseEnter, onMouseLeave: onMouseLeave !== null && onMouseLeave !== void 0 ? onMouseLeave : _onMouseLeave, "data-xstate-tree": true, onClick: (e) => {
58
- var _a;
59
- if (((_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, e)) === false) {
57
+ return (react_1.default.createElement("a", { ...props, ref: ref, href: href, "data-testid": testId, onMouseDown: onMouseDown ?? _onMouseDown, onMouseEnter: onMouseEnter ?? _onMouseEnter, onMouseLeave: onMouseLeave ?? _onMouseLeave, "data-xstate-tree": true, onClick: (e) => {
58
+ if (props.onClick?.(e) === false) {
60
59
  return;
61
60
  }
62
61
  // Holding the Command key on Mac or the Control Key on Windows while clicking the link will open a new tab/window
@@ -14,7 +14,7 @@ const joinRoutes_1 = require("../joinRoutes");
14
14
  */
15
15
  function buildCreateRoute(history, basePath) {
16
16
  function navigate({ history, url, meta, }) {
17
- const method = (meta === null || meta === void 0 ? void 0 : meta.replace) ? history.replace : history.push;
17
+ const method = meta?.replace ? history.replace : history.push;
18
18
  method(url, {
19
19
  meta,
20
20
  previousUrl: `${window.location.pathname}${window.location.search}`,
@@ -90,12 +90,11 @@ function buildCreateRoute(history, basePath) {
90
90
  reverser: reverser,
91
91
  // @ts-ignore :cry:
92
92
  getEvent(args) {
93
- const { params, query, meta } = args !== null && args !== void 0 ? args : {};
93
+ const { params, query, meta } = args ?? {};
94
94
  return { type: event, params, query, meta };
95
95
  },
96
96
  // @ts-ignore :cry:
97
97
  matches(suppliedUrl, search) {
98
- var _a, _b, _c;
99
98
  const fullUrl = suppliedUrl.endsWith("/")
100
99
  ? suppliedUrl
101
100
  : suppliedUrl + "/";
@@ -115,7 +114,7 @@ function buildCreateRoute(history, basePath) {
115
114
  if (!url.startsWith("/")) {
116
115
  url = "/" + url;
117
116
  }
118
- params = { ...params, ...((_a = parentMatch.params) !== null && _a !== void 0 ? _a : {}) };
117
+ params = { ...params, ...(parentMatch.params ?? {}) };
119
118
  }
120
119
  const matches = matcher(url, (0, query_string_1.parse)(search));
121
120
  // if there is any URL left after matching this route, the last to match
@@ -125,7 +124,7 @@ function buildCreateRoute(history, basePath) {
125
124
  }
126
125
  const fullParams = {
127
126
  ...params,
128
- ...((_b = matches.params) !== null && _b !== void 0 ? _b : {}),
127
+ ...(matches.params ?? {}),
129
128
  };
130
129
  if (fullParamsSchema) {
131
130
  fullParamsSchema.parse(fullParams);
@@ -137,12 +136,12 @@ function buildCreateRoute(history, basePath) {
137
136
  originalUrl: `${fullUrl}${search}`,
138
137
  type: event,
139
138
  params: fullParams,
140
- query: (_c = matches.query) !== null && _c !== void 0 ? _c : {},
139
+ query: matches.query ?? {},
141
140
  };
142
141
  },
143
142
  // @ts-ignore :cry:
144
143
  reverse(args) {
145
- const { params, query } = args !== null && args !== void 0 ? args : {};
144
+ const { params, query } = args ?? {};
146
145
  const parentRoutes = getParentArray();
147
146
  const baseUrl = parentRoutes
148
147
  .map((route) => route.reverser({ params }))
@@ -151,7 +150,7 @@ function buildCreateRoute(history, basePath) {
151
150
  },
152
151
  // @ts-ignore :cry:
153
152
  navigate(args) {
154
- const { params, query, meta } = args !== null && args !== void 0 ? args : {};
153
+ const { params, query, meta } = args ?? {};
155
154
  const url = this.reverse({ params, query });
156
155
  navigate({
157
156
  url: (0, joinRoutes_1.joinRoutes)(this.basePath, url),
@@ -163,9 +162,9 @@ function buildCreateRoute(history, basePath) {
163
162
  preload(args) {
164
163
  const parentRoutes = getParentArray();
165
164
  parentRoutes.forEach((route) => {
166
- route === null || route === void 0 ? void 0 : route.preload(args);
165
+ route?.preload(args);
167
166
  });
168
- preload === null || preload === void 0 ? void 0 : preload(args);
167
+ preload?.(args);
169
168
  },
170
169
  };
171
170
  };
@@ -25,14 +25,14 @@ function handleLocationChange(routes, basePath, path, search, meta) {
25
25
  }
26
26
  else {
27
27
  const matchedEvent = match.event;
28
- matchedEvent.meta = { ...(meta !== null && meta !== void 0 ? meta : {}) };
28
+ matchedEvent.meta = { ...(meta ?? {}) };
29
29
  matchedEvent.meta.indexEvent = true;
30
30
  const { params, query } = match.event;
31
31
  const routingEvents = [];
32
32
  let route = match.route;
33
33
  route.preload({ params, query, meta: matchedEvent.meta });
34
34
  while (route.parent) {
35
- routingEvents.push(route.parent.getEvent({ params, query: {}, meta: { ...(meta !== null && meta !== void 0 ? meta : {}) } }));
35
+ routingEvents.push(route.parent.getEvent({ params, query: {}, meta: { ...(meta ?? {}) } }));
36
36
  route = route.parent;
37
37
  }
38
38
  const clonedRoutingEvents = [...routingEvents];
@@ -5,7 +5,6 @@ exports.matchRoute = void 0;
5
5
  * @public
6
6
  */
7
7
  function matchRoute(routes, basePath, path, search) {
8
- var _a;
9
8
  const realBase = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
10
9
  const realPath = (() => {
11
10
  if (path.startsWith(realBase) && realBase.length > 0) {
@@ -13,7 +12,7 @@ function matchRoute(routes, basePath, path, search) {
13
12
  }
14
13
  return path;
15
14
  })();
16
- const [matchingRoute, event] = (_a = routes
15
+ const [matchingRoute, event] = routes
17
16
  .map((route) => {
18
17
  try {
19
18
  const match = route.matches(realPath, search);
@@ -28,7 +27,7 @@ function matchRoute(routes, basePath, path, search) {
28
27
  }
29
28
  return [undefined, undefined];
30
29
  })
31
- .find(([match]) => Boolean(match))) !== null && _a !== void 0 ? _a : [undefined, undefined];
30
+ .find(([match]) => Boolean(match)) ?? [undefined, undefined];
32
31
  if (matchingRoute === undefined) {
33
32
  return { type: "no-matches" };
34
33
  }
@@ -28,12 +28,11 @@ exports.useInRoutingContext = useInRoutingContext;
28
28
  * Returns the list of active routing events, or undefined if there are none / used outside of an xstate-tree routing context
29
29
  */
30
30
  function useActiveRouteEvents() {
31
- var _a;
32
31
  try {
33
32
  const context = useRoutingContext();
34
- return (_a = context.activeRouteEvents) === null || _a === void 0 ? void 0 : _a.current;
33
+ return context.activeRouteEvents?.current;
35
34
  }
36
- catch (_b) {
35
+ catch {
37
36
  return undefined;
38
37
  }
39
38
  }
@@ -19,7 +19,7 @@ function useRouteArgsIfActive(route) {
19
19
  if (!isActive) {
20
20
  return undefined;
21
21
  }
22
- const activeRoute = activeRoutes === null || activeRoutes === void 0 ? void 0 : activeRoutes.find((activeRoute) => activeRoute.type === route.event);
22
+ const activeRoute = activeRoutes?.find((activeRoute) => activeRoute.type === route.event);
23
23
  (0, utils_1.assertIsDefined)(activeRoute, "active route is not defined, but the route is active??");
24
24
  return {
25
25
  params: activeRoute.params,
@@ -1,61 +1,11 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
4
  };
25
5
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.buildTestRootComponent = exports.buildViewProps = exports.genericSlotsTestingDummy = exports.slotTestingDummyFactory = void 0;
6
+ exports.genericSlotsTestingDummy = void 0;
27
7
  // ignore file coverage
28
- const react_1 = require("@xstate/react");
29
- const react_2 = __importStar(require("react"));
30
- const tiny_emitter_1 = require("tiny-emitter");
31
- const xstate_1 = require("xstate");
32
- const builders_1 = require("./builders");
33
- const utils_1 = require("./utils");
34
- const xstateTree_1 = require("./xstateTree");
35
- /**
36
- * @public
37
- *
38
- * Creates a dummy machine that just renders the supplied string - useful for rendering xstate-tree views in isolation
39
- *
40
- * @param name - the string to render in the machines view
41
- * @returns a dummy machine that renders a div containing the supplied string
42
- */
43
- function slotTestingDummyFactory(name) {
44
- return (0, builders_1.buildXStateTreeMachine)((0, xstate_1.createMachine)({
45
- id: name,
46
- initial: "idle",
47
- states: {
48
- idle: {},
49
- },
50
- }), {
51
- actions: () => ({}),
52
- selectors: () => ({}),
53
- slots: [],
54
- view: () => (react_2.default.createElement("div", null,
55
- react_2.default.createElement("p", null, name))),
56
- });
57
- }
58
- exports.slotTestingDummyFactory = slotTestingDummyFactory;
8
+ const react_1 = __importDefault(require("react"));
59
9
  /**
60
10
  * @public
61
11
  *
@@ -63,98 +13,10 @@ exports.slotTestingDummyFactory = slotTestingDummyFactory;
63
13
  */
64
14
  exports.genericSlotsTestingDummy = new Proxy({}, {
65
15
  get(_target, prop) {
66
- return () => (react_2.default.createElement("div", null,
67
- react_2.default.createElement("p", null,
68
- react_2.default.createElement(react_2.default.Fragment, null,
16
+ return () => (react_1.default.createElement("div", null,
17
+ react_1.default.createElement("p", null,
18
+ react_1.default.createElement(react_1.default.Fragment, null,
69
19
  prop,
70
20
  "-slot"))));
71
21
  },
72
22
  });
73
- /**
74
- * @public
75
- *
76
- * Aids in type inference for creating props objects for xstate-tree views.
77
- *
78
- * @param view - The view to create props for
79
- * @param props - The actions/selectors props to pass to the view
80
- * @returns An object with the view's selectors, actions, and inState function props
81
- */
82
- function buildViewProps(_view, props) {
83
- return {
84
- ...props,
85
- inState: (testState) => (state) => state === testState || testState.startsWith(state),
86
- };
87
- }
88
- exports.buildViewProps = buildViewProps;
89
- /**
90
- * @public
91
- *
92
- * Sets up a root component for use in an \@xstate/test model backed by \@testing-library/react for the component
93
- *
94
- * The logger argument should just be a simple function which forwards the arguments to console.log,
95
- * this is needed because Wallaby.js only displays console logs in tests that come from source code, not library code,
96
- * so any logs from inside this file don't show up in the test explorer
97
- *
98
- * The returned object has a `rootComponent` property and a function, `awaitTransition`, that returns a Promise
99
- * when called that is resolved the next time the underlying machine transitions. This can be used in the \@xstate/test
100
- * model to ensure after an event action is executed the test in the next state doesn't run until after the machine transitions
101
- *
102
- * It also delays for 5ms to ensure any React re-rendering happens in response to the state transition
103
- */
104
- function buildTestRootComponent(machine, logger) {
105
- if (!machine.meta) {
106
- throw new Error("Root machine has no meta");
107
- }
108
- if ((machine.meta.builderVersion === 1 && !machine.meta.view) ||
109
- (machine.meta.builderVersion === 2 && !machine.meta.View)) {
110
- throw new Error("Root machine has no associated view");
111
- }
112
- const onChangeEmitter = new tiny_emitter_1.TinyEmitter();
113
- function addTransitionListener(listener) {
114
- onChangeEmitter.once("transition", listener);
115
- }
116
- return {
117
- rootComponent: function XstateTreeRootComponent() {
118
- const [_, __, interpreter] = (0, react_1.useMachine)(machine, { devTools: true });
119
- (0, react_2.useEffect)(() => {
120
- function handler(event) {
121
- (0, xstateTree_1.recursivelySend)(interpreter, event);
122
- }
123
- function changeHandler(ctx, oldCtx) {
124
- logger("onChange: ", (0, utils_1.difference)(oldCtx, ctx));
125
- onChangeEmitter.emit("changed", ctx);
126
- }
127
- function onEventHandler(e) {
128
- logger("onEvent", e);
129
- }
130
- function onTransitionHandler(s) {
131
- logger("State: ", s.value);
132
- onChangeEmitter.emit("transition");
133
- }
134
- interpreter.onChange(changeHandler);
135
- interpreter.onEvent(onEventHandler);
136
- interpreter.onTransition(onTransitionHandler);
137
- xstateTree_1.emitter.on("event", handler);
138
- return () => {
139
- xstateTree_1.emitter.off("event", handler);
140
- interpreter.off(changeHandler);
141
- interpreter.off(onEventHandler);
142
- interpreter.off(onTransitionHandler);
143
- };
144
- }, [interpreter]);
145
- if (!interpreter.initialized) {
146
- return null;
147
- }
148
- return react_2.default.createElement(xstateTree_1.XstateTreeView, { interpreter: interpreter });
149
- },
150
- addTransitionListener,
151
- awaitTransition() {
152
- return new Promise((res) => {
153
- addTransitionListener(() => {
154
- setTimeout(res, 50);
155
- });
156
- });
157
- },
158
- };
159
- }
160
- exports.buildTestRootComponent = buildTestRootComponent;