@wise/dynamic-flow-client 5.29.0 → 5.30.0-experimental-7a76ef5

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 (28) hide show
  1. package/build/main.css +97 -0
  2. package/build/main.js +539 -326
  3. package/build/main.mjs +539 -326
  4. package/build/tsconfig.types.tsbuildinfo +1 -1
  5. package/build/types/controller/getRequestAbortController.d.ts +4 -3
  6. package/build/types/controller/getRequestAbortController.d.ts.map +1 -1
  7. package/build/types/domain/components/collectionComponent/CollectionComponent.d.ts +6 -7
  8. package/build/types/domain/components/collectionComponent/CollectionComponent.d.ts.map +1 -1
  9. package/build/types/domain/components/collectionComponent/CollectionController.d.ts +18 -0
  10. package/build/types/domain/components/collectionComponent/CollectionController.d.ts.map +1 -0
  11. package/build/types/domain/components/collectionComponent/CollectionStack.d.ts +12 -0
  12. package/build/types/domain/components/collectionComponent/CollectionStack.d.ts.map +1 -0
  13. package/build/types/domain/components/collectionComponent/CollectionState.d.ts +20 -0
  14. package/build/types/domain/components/collectionComponent/CollectionState.d.ts.map +1 -0
  15. package/build/types/domain/components/collectionComponent/applyCollectionResponse.d.ts +7 -0
  16. package/build/types/domain/components/collectionComponent/applyCollectionResponse.d.ts.map +1 -0
  17. package/build/types/domain/components/collectionComponent/mergeSections.d.ts +3 -0
  18. package/build/types/domain/components/collectionComponent/mergeSections.d.ts.map +1 -0
  19. package/build/types/domain/components/collectionComponent/toggleFilterOption.d.ts +3 -0
  20. package/build/types/domain/components/collectionComponent/toggleFilterOption.d.ts.map +1 -0
  21. package/build/types/domain/components/collectionComponent/types.d.ts +42 -18
  22. package/build/types/domain/components/collectionComponent/types.d.ts.map +1 -1
  23. package/build/types/domain/features/collection/getPerformCollectionQuery.d.ts +2 -2
  24. package/build/types/domain/features/collection/getPerformCollectionQuery.d.ts.map +1 -1
  25. package/build/types/domain/mappers/layout/collectionLayoutToComponent.d.ts +3 -3
  26. package/build/types/domain/mappers/layout/collectionLayoutToComponent.d.ts.map +1 -1
  27. package/build/types/renderers/mappers/collectionComponentToProps.d.ts.map +1 -1
  28. package/package.json +2 -2
package/build/main.js CHANGED
@@ -861,6 +861,7 @@ function findRendererPropsByType(root, type, predicate = () => true) {
861
861
  }
862
862
  var isType = (node, type) => node.type === type;
863
863
  var getChildren = (node) => {
864
+ var _a;
864
865
  switch (node.type) {
865
866
  case "root":
866
867
  case "box":
@@ -882,9 +883,16 @@ var getChildren = (node) => {
882
883
  return node.childrenProps ? [node.childrenProps] : [];
883
884
  case "tabs":
884
885
  return node.tabs.flatMap((c) => c.childrenProps);
886
+ case "collection": {
887
+ const { beforeSectionsProps, afterSectionsProps, sections, search } = node.state;
888
+ return [
889
+ ...beforeSectionsProps,
890
+ ...afterSectionsProps,
891
+ ...[...sections, ...(_a = search == null ? void 0 : search.initialSections) != null ? _a : []].filter((section) => section.type === "layout").flatMap((section) => section.childrenProps)
892
+ ];
893
+ }
885
894
  case "alert":
886
895
  case "button":
887
- case "collection":
888
896
  case "input-checkbox":
889
897
  case "input-date":
890
898
  case "decision":
@@ -1577,101 +1585,78 @@ var boxLayoutToComponent = (uid, { border = false, components, control, margin,
1577
1585
  )
1578
1586
  });
1579
1587
 
1580
- // src/domain/mappers/utils/image.ts
1581
- var mapSpecImage = (image) => {
1582
- var _a, _b, _c;
1583
- return image ? {
1584
- uri: (_b = (_a = image.uri) != null ? _a : image.url) != null ? _b : "",
1585
- accessibilityDescription: (_c = image.accessibilityDescription) != null ? _c : image.text
1586
- } : void 0;
1588
+ // src/domain/components/collectionComponent/CollectionState.ts
1589
+ var createCollectionState = (id, _a, searchQuery) => {
1590
+ var _b = _a, { search } = _b, response = __objRest(_b, ["search"]);
1591
+ return __spreadProps(__spreadValues({}, response), {
1592
+ id,
1593
+ status: { type: "idle" },
1594
+ search: search ? __spreadProps(__spreadValues({}, search), { query: searchQuery }) : void 0
1595
+ });
1587
1596
  };
1588
-
1589
- // src/domain/mappers/utils/media-utils.ts
1590
- var getDomainLayerMedia = ({ icon, image, media }) => {
1591
- if (media) {
1592
- return media;
1593
- }
1594
- if (icon || image) {
1595
- return {
1596
- type: "legacy",
1597
- icon,
1598
- image: mapSpecImage(image)
1599
- };
1600
- }
1601
- return void 0;
1597
+ var forkCollectionState = (_a, forkedId) => {
1598
+ var _b = _a, { id, status } = _b, state = __objRest(_b, ["id", "status"]);
1599
+ var _a2, _b2;
1600
+ return createCollectionState(forkedId, state, (_b2 = (_a2 = state.search) == null ? void 0 : _a2.query) != null ? _b2 : "");
1602
1601
  };
1603
-
1604
- // src/domain/mappers/utils/utils.ts
1605
- var mapInlineAlert = (alert) => {
1606
- return alert ? {
1607
- content: alert.content,
1608
- context: alert.context ? mapLegacyContext(alert.context) : "neutral",
1609
- media: getDomainLayerMedia({ media: alert.media })
1610
- } : void 0;
1602
+ var getCollectionStateChildren = (state) => {
1603
+ var _a, _b, _c, _d;
1604
+ return [
1605
+ // TODO We should be calling the lifecycle stop/start methods on new layouts
1606
+ ...(_a = state.beforeSections) != null ? _a : [],
1607
+ ...getSectionsChildren(state.sections),
1608
+ ...getSectionsChildren((_c = (_b = state.search) == null ? void 0 : _b.initialSections) != null ? _c : []),
1609
+ ...(_d = state.afterSections) != null ? _d : []
1610
+ ];
1611
1611
  };
1612
- var mapAdditionalInfo = (info, mapperProps) => {
1613
- const { onBehavior, trackEvent, registerSubmissionBehavior } = mapperProps;
1614
- if (info) {
1615
- const behavior = getDomainLayerBehavior(info, [], registerSubmissionBehavior);
1616
- const isLink = behavior.type === "link";
1617
- return {
1618
- text: info.text,
1619
- href: isLink ? behavior.url : void 0,
1620
- hrefWithTracking: getHrefWithTracking({
1621
- behavior,
1622
- onBehavior,
1623
- trackEvent
1624
- }),
1625
- accessibilityDescription: info.accessibilityDescription,
1626
- onClick: behavior.type === "none" ? void 0 : () => {
1627
- void onBehavior(behavior);
1612
+ var setLoading = (state, reason) => __spreadProps(__spreadValues({}, state), { status: { type: "loading", reason } });
1613
+ var setError = (state, reason) => __spreadProps(__spreadValues({}, state), {
1614
+ sections: reason === "pagination" ? state.sections : [],
1615
+ status: { type: "error", reason }
1616
+ });
1617
+ var setQuery = (state, value) => state.search ? __spreadProps(__spreadValues({}, state), {
1618
+ search: __spreadProps(__spreadValues({}, state.search), { query: value })
1619
+ }) : state;
1620
+ var getSectionsChildren = (sections) => sections.filter((section) => section.type === "layout").flatMap((section) => section.components);
1621
+
1622
+ // src/domain/components/collectionComponent/CollectionStack.ts
1623
+ var createCollectionStack = (uid, initialState, onChange) => {
1624
+ let states = [createCollectionState(`${uid}-state-0`, initialState, "")];
1625
+ let forkCount = 0;
1626
+ return {
1627
+ getStates: () => states,
1628
+ getState: (id) => states.find((state) => state.id === id),
1629
+ getActiveState: () => states[states.length - 1],
1630
+ update(id, transform) {
1631
+ const state = states.find((current) => current.id === id);
1632
+ if (!state) {
1633
+ return;
1628
1634
  }
1629
- };
1630
- }
1631
- return void 0;
1632
- };
1633
- var mapSchemaAlert = (alert) => {
1634
- return alert ? {
1635
- content: alert.markdown,
1636
- context: alert.context ? mapLegacyContext(alert.context) : "neutral",
1637
- media: getDomainLayerMedia({ media: alert.media })
1638
- } : void 0;
1639
- };
1640
-
1641
- // src/domain/components/utils/debounce.ts
1642
- var debounce = (callback, waitMs) => {
1643
- let timeoutId = null;
1644
- let lastArgs = null;
1645
- const clearTimer = () => {
1646
- if (timeoutId !== null) {
1647
- clearTimeout(timeoutId);
1648
- timeoutId = null;
1649
- }
1650
- lastArgs = null;
1651
- };
1652
- const debouncedFn = (...args) => {
1653
- lastArgs = args;
1654
- if (timeoutId !== null) {
1655
- clearTimeout(timeoutId);
1656
- }
1657
- timeoutId = setTimeout(() => {
1658
- callback(...lastArgs);
1659
- timeoutId = null;
1660
- lastArgs = null;
1661
- }, waitMs);
1662
- };
1663
- debouncedFn.cancel = () => {
1664
- if (timeoutId !== null) {
1665
- clearTimer();
1666
- }
1667
- };
1668
- debouncedFn.flush = () => {
1669
- if (timeoutId !== null) {
1670
- callback(...lastArgs);
1671
- clearTimer();
1635
+ const updated = transform(state);
1636
+ if (updated === state) {
1637
+ return;
1638
+ }
1639
+ const replace = (current) => current.id === id ? updated : current;
1640
+ const [root, ...forks] = states;
1641
+ states = [replace(root), ...forks.map(replace)];
1642
+ onChange();
1643
+ },
1644
+ fork() {
1645
+ forkCount += 1;
1646
+ const state = forkCollectionState(states[states.length - 1], `${uid}-state-${forkCount}`);
1647
+ states = [...states, state];
1648
+ onChange();
1649
+ },
1650
+ pop() {
1651
+ const [root, ...forks] = states;
1652
+ const popped = forks.at(-1);
1653
+ if (popped) {
1654
+ states = [root, ...forks.slice(0, -1)];
1655
+ onChange();
1656
+ }
1657
+ return popped;
1672
1658
  }
1673
1659
  };
1674
- return debouncedFn;
1675
1660
  };
1676
1661
 
1677
1662
  // src/utils/recursiveMerge.ts
@@ -1713,176 +1698,251 @@ function mergeArrays(valueA, valueB) {
1713
1698
  );
1714
1699
  }
1715
1700
 
1716
- // src/domain/components/collectionComponent/CollectionComponent.ts
1717
- var DEBOUNCE_TIME = 800;
1718
- var createCollectionComponent = (props, onComponentUpdate, queryFunction, trackEvent) => {
1719
- const { uid, analyticsId, control, margin, tags, state } = props;
1720
- const update = getInputUpdateFunction(onComponentUpdate);
1721
- let abortController = new AbortController();
1722
- const trackCollectionEvent = (source, status) => trackEvent(getEventName(source, status), component.state.analytics);
1723
- const query = (mode, source) => {
1724
- var _a, _b;
1725
- abortController.abort();
1726
- abortController = new AbortController();
1727
- const { signal } = abortController;
1728
- trackCollectionEvent(source != null ? source : mode, "Triggered");
1729
- queryFunction({
1730
- searchParam: (_a = component.state.search) == null ? void 0 : _a.param,
1731
- query: (_b = component.state.search) == null ? void 0 : _b.query,
1732
- cursor: mode === "pagination" ? component.state.nextCursor : void 0,
1733
- signal,
1734
- filters: component.state.filters
1735
- }).then((response) => {
1736
- if (!response) {
1737
- return;
1738
- }
1739
- update(component, (draft) => {
1740
- draft.state = mergeState(mode, component.state, response);
1741
- draft.status = {
1742
- type: "idle",
1743
- loadMore: response.nextCursor ? paginate : void 0
1744
- };
1701
+ // src/domain/components/collectionComponent/mergeSections.ts
1702
+ var mergeSections = (existing, incoming) => {
1703
+ const knownIds = new Set(existing.map((section) => section.id));
1704
+ const newSections = incoming.filter((section) => !knownIds.has(section.id));
1705
+ const merged = existing.map((section) => {
1706
+ var _a, _b, _c, _d;
1707
+ const match = incoming.find((s) => s.id === section.id);
1708
+ if (!match) return section;
1709
+ if (section.type !== match.type) return section;
1710
+ const baseProps = {
1711
+ type: section.type,
1712
+ id: match.id,
1713
+ title: (_a = match.title) != null ? _a : section.title,
1714
+ callToAction: (_b = match.callToAction) != null ? _b : section.callToAction,
1715
+ help: (_c = match.help) != null ? _c : section.help,
1716
+ inlineAlert: (_d = match.inlineAlert) != null ? _d : section.inlineAlert
1717
+ };
1718
+ if (section.type === "layout" && match.type === "layout") {
1719
+ return __spreadProps(__spreadValues({}, baseProps), {
1720
+ type: "layout",
1721
+ components: [...section.components, ...match.components]
1745
1722
  });
1746
- trackCollectionEvent(source != null ? source : mode, "Succeeded");
1747
- }).catch(() => {
1748
- if (!signal.aborted) {
1749
- const retry = () => {
1750
- update(component, (draft) => {
1751
- draft.status = { type: "loading", reason: mode };
1752
- });
1753
- query(mode, source);
1754
- };
1755
- update(component, (draft) => {
1756
- if (mode === "search") {
1757
- draft.state.sections = [];
1758
- }
1759
- draft.status = { type: "error", reason: mode, retry };
1760
- });
1761
- trackCollectionEvent(source != null ? source : mode, "Failed");
1762
- }
1763
- });
1723
+ }
1724
+ if (section.type === "items" && match.type === "items") {
1725
+ return __spreadProps(__spreadValues({}, baseProps), {
1726
+ type: "items",
1727
+ items: [...section.items, ...match.items]
1728
+ });
1729
+ }
1730
+ return section;
1731
+ });
1732
+ return [...merged, ...newSections];
1733
+ };
1734
+
1735
+ // src/domain/components/collectionComponent/applyCollectionResponse.ts
1736
+ var applyCollectionResponse = (state, mode, incoming) => {
1737
+ var _a, _b, _c, _d, _e;
1738
+ return __spreadProps(__spreadValues({}, state), {
1739
+ sections: mode === "pagination" ? mergeSections(state.sections, incoming.sections) : incoming.sections,
1740
+ nextCursor: incoming.nextCursor,
1741
+ analytics: mode === "pagination" ? recursiveMerge(state.analytics, incoming.analytics) : incoming.analytics,
1742
+ filters: (_a = incoming.filters) != null ? _a : state.filters,
1743
+ search: incoming.search ? __spreadProps(__spreadValues({}, incoming.search), { query: (_c = (_b = state.search) == null ? void 0 : _b.query) != null ? _c : "" }) : state.search,
1744
+ beforeSections: (_d = incoming.beforeSections) != null ? _d : state.beforeSections,
1745
+ afterSections: (_e = incoming.afterSections) != null ? _e : state.afterSections,
1746
+ status: { type: "idle" }
1747
+ });
1748
+ };
1749
+
1750
+ // src/controller/getRequestAbortController.ts
1751
+ var getRequestAbortController = () => {
1752
+ let abortController = new AbortController();
1753
+ return {
1754
+ refresh() {
1755
+ abortController.abort();
1756
+ abortController = new AbortController();
1757
+ return abortController.signal;
1758
+ },
1759
+ abort() {
1760
+ abortController.abort();
1761
+ }
1764
1762
  };
1765
- const debouncedQuery = debounce(query, DEBOUNCE_TIME);
1766
- const search = () => {
1767
- abortController.abort();
1768
- debouncedQuery("search");
1763
+ };
1764
+
1765
+ // src/domain/components/utils/debounce.ts
1766
+ var debounce = (callback, waitMs) => {
1767
+ let timeoutId = null;
1768
+ let lastArgs = null;
1769
+ const clearTimer = () => {
1770
+ if (timeoutId !== null) {
1771
+ clearTimeout(timeoutId);
1772
+ timeoutId = null;
1773
+ }
1774
+ lastArgs = null;
1769
1775
  };
1770
- const filter = () => {
1771
- debouncedQuery("search", "filter");
1772
- debouncedQuery.flush();
1776
+ const debouncedFn = (...args) => {
1777
+ lastArgs = args;
1778
+ if (timeoutId !== null) {
1779
+ clearTimeout(timeoutId);
1780
+ }
1781
+ timeoutId = setTimeout(() => {
1782
+ callback(...lastArgs);
1783
+ timeoutId = null;
1784
+ lastArgs = null;
1785
+ }, waitMs);
1773
1786
  };
1774
- const paginate = () => query("pagination");
1775
- const mergeState = (mode, original, incoming) => {
1776
- var _a, _b;
1777
- return {
1778
- sections: mode === "pagination" ? mergeSections(original.sections, incoming.sections) : incoming.sections,
1779
- nextCursor: incoming.nextCursor,
1780
- filters: incoming.filters ? mapFilters(incoming.filters) : original.filters,
1781
- search: incoming.search ? mapSearch(incoming.search) : original.search,
1782
- beforeSections: (_a = incoming.beforeSections) != null ? _a : original.beforeSections,
1783
- afterSections: (_b = incoming.afterSections) != null ? _b : original.afterSections,
1784
- analytics: mode === "pagination" ? recursiveMerge(original.analytics, incoming.analytics) : incoming.analytics
1785
- };
1787
+ debouncedFn.cancel = () => {
1788
+ if (timeoutId !== null) {
1789
+ clearTimer();
1790
+ }
1786
1791
  };
1787
- const selectFilter = (filterIndex, optionIndex) => {
1788
- var _a;
1789
- const selected = (_a = component.state.filters) == null ? void 0 : _a[filterIndex];
1790
- if (!selected) {
1791
- return;
1792
+ debouncedFn.flush = () => {
1793
+ if (timeoutId !== null) {
1794
+ callback(...lastArgs);
1795
+ clearTimer();
1792
1796
  }
1793
- const currentValue = selected.options[optionIndex].selected;
1794
- update(component, (draft) => {
1795
- if (!draft.state.filters) {
1796
- return;
1797
- }
1798
- const draftFilter = draft.state.filters[filterIndex];
1799
- if (selected.multiSelect) {
1800
- draftFilter.options[optionIndex].selected = !currentValue;
1801
- } else {
1802
- draftFilter.options.forEach((draftOption, index) => {
1803
- draftOption.selected = index === optionIndex ? !currentValue : false;
1804
- });
1805
- }
1806
- draft.status = { type: "loading", reason: "search" };
1807
- });
1808
- filter();
1809
1797
  };
1810
- const mapFilters = (filters) => filters == null ? void 0 : filters.map((f, filterIndex) => {
1811
- var _a;
1812
- return __spreadProps(__spreadValues({}, f), {
1813
- options: (_a = f.options) == null ? void 0 : _a.map((option, optionIndex) => {
1814
- var _a2;
1815
- return __spreadProps(__spreadValues({}, option), {
1816
- selected: (_a2 = option.selected) != null ? _a2 : false,
1817
- onSelect: () => selectFilter(filterIndex, optionIndex)
1818
- });
1819
- })
1820
- });
1798
+ return debouncedFn;
1799
+ };
1800
+
1801
+ // src/domain/components/collectionComponent/toggleFilterOption.ts
1802
+ var toggleFilterOption = (state, filterIndex, optionIndex) => {
1803
+ var _a;
1804
+ const filter = (_a = state.filters) == null ? void 0 : _a[filterIndex];
1805
+ if (!state.filters || !filter) {
1806
+ return state;
1807
+ }
1808
+ const currentValue = filter.options[optionIndex].selected;
1809
+ const options = filter.options.map((option, index) => {
1810
+ if (index === optionIndex) {
1811
+ return __spreadProps(__spreadValues({}, option), { selected: !currentValue });
1812
+ }
1813
+ return filter.multiSelect ? option : __spreadProps(__spreadValues({}, option), { selected: false });
1821
1814
  });
1822
- const mapSearch = (searchConfig) => searchConfig ? __spreadProps(__spreadValues({
1823
- query: ""
1824
- }, searchConfig), {
1825
- onChange(value) {
1826
- update(component, (draft) => {
1827
- if (draft.state.search) {
1828
- draft.state.search.query = value;
1829
- draft.status = { type: "loading", reason: "search" };
1830
- }
1815
+ return __spreadProps(__spreadValues({}, state), {
1816
+ filters: state.filters.map(
1817
+ (current, index) => index === filterIndex ? __spreadProps(__spreadValues({}, current), { options }) : current
1818
+ )
1819
+ });
1820
+ };
1821
+
1822
+ // src/domain/components/collectionComponent/CollectionController.ts
1823
+ var createCollectionController = ({
1824
+ stack,
1825
+ collectionClient,
1826
+ trackEvent
1827
+ }) => {
1828
+ let requests = /* @__PURE__ */ new Map();
1829
+ const getRequest = (id) => {
1830
+ const existing = requests.get(id);
1831
+ if (existing) {
1832
+ return existing;
1833
+ }
1834
+ const request = createSchedulableRequest((mode, signal) => executeRequest2(id, mode, signal));
1835
+ requests = new Map([...requests, [id, request]]);
1836
+ return request;
1837
+ };
1838
+ const queueRequest = (id, mode, transform) => {
1839
+ if (!stack.getState(id)) {
1840
+ return;
1841
+ }
1842
+ stack.update(id, (state) => setLoading(transform(state), mode));
1843
+ getRequest(id).queue(mode);
1844
+ };
1845
+ const runRequest = (id, mode, transform = (state) => state) => {
1846
+ if (!stack.getState(id)) {
1847
+ return;
1848
+ }
1849
+ stack.update(id, (state) => setLoading(transform(state), mode));
1850
+ getRequest(id).run(mode);
1851
+ };
1852
+ const handleSuccess = (state, mode, response) => {
1853
+ trackEvent(
1854
+ getEventName(mode, "Succeeded"),
1855
+ mode === "pagination" ? recursiveMerge(state.analytics, response.analytics) : response.analytics
1856
+ );
1857
+ stack.update(state.id, (current) => applyCollectionResponse(current, mode, response));
1858
+ };
1859
+ const handleFailure = (state, mode) => {
1860
+ trackEvent(getEventName(mode, "Failed"), state.analytics);
1861
+ stack.update(state.id, (current) => setError(current, mode));
1862
+ };
1863
+ const executeRequest2 = async (id, mode, signal) => {
1864
+ const state = stack.getState(id);
1865
+ if (!state) {
1866
+ return;
1867
+ }
1868
+ const { analytics, filters, search } = state;
1869
+ trackEvent(getEventName(mode, "Triggered"), analytics);
1870
+ try {
1871
+ const response = await collectionClient({
1872
+ searchParam: search == null ? void 0 : search.param,
1873
+ query: search == null ? void 0 : search.query,
1874
+ cursor: mode === "pagination" ? state.nextCursor : void 0,
1875
+ signal,
1876
+ filters
1831
1877
  });
1832
- search();
1878
+ if (response && !signal.aborted) {
1879
+ handleSuccess(state, mode, response);
1880
+ }
1881
+ } catch (e) {
1882
+ if (!signal.aborted) {
1883
+ handleFailure(state, mode);
1884
+ }
1833
1885
  }
1834
- }) : void 0;
1835
- const component = {
1836
- type: "collection",
1837
- kind: "layout",
1838
- uid,
1839
- analyticsId,
1840
- control,
1841
- margin,
1842
- tags,
1843
- getChildren() {
1844
- var _a, _b, _c, _d;
1845
- return [
1846
- ...(_b = (_a = component.state) == null ? void 0 : _a.beforeSections) != null ? _b : [],
1847
- ...(_d = (_c = component.state) == null ? void 0 : _c.afterSections) != null ? _d : []
1848
- ];
1886
+ };
1887
+ return {
1888
+ search(id, value) {
1889
+ queueRequest(id, "search", (state) => setQuery(state, value));
1849
1890
  },
1850
- status: {
1851
- type: "idle",
1852
- loadMore: state.nextCursor ? () => query("pagination") : void 0
1891
+ selectFilter(id, filterIndex, optionIndex) {
1892
+ var _a, _b;
1893
+ if (!((_b = (_a = stack.getState(id)) == null ? void 0 : _a.filters) == null ? void 0 : _b[filterIndex])) {
1894
+ return;
1895
+ }
1896
+ runRequest(id, "filter", (state) => toggleFilterOption(state, filterIndex, optionIndex));
1853
1897
  },
1854
- state: __spreadProps(__spreadValues({}, state), {
1855
- filters: mapFilters(state.filters),
1856
- search: mapSearch(props.search)
1857
- }),
1858
- start() {
1859
- component.getChildren().forEach((child) => child.start());
1898
+ loadMore(id) {
1899
+ runRequest(id, "pagination");
1860
1900
  },
1861
- stop() {
1862
- component.getChildren().forEach((child) => child.stop());
1901
+ retry(id) {
1902
+ var _a;
1903
+ const status = (_a = stack.getState(id)) == null ? void 0 : _a.status;
1904
+ if ((status == null ? void 0 : status.type) !== "error") {
1905
+ return;
1906
+ }
1907
+ runRequest(id, status.reason);
1908
+ },
1909
+ fork: stack.fork,
1910
+ pop() {
1911
+ var _a;
1912
+ const states = stack.getStates();
1913
+ if (states.length === 1) {
1914
+ return;
1915
+ }
1916
+ const { id } = stack.getActiveState();
1917
+ (_a = requests.get(id)) == null ? void 0 : _a.abort();
1918
+ requests = new Map([...requests].filter(([stateId]) => stateId !== id));
1919
+ stack.pop();
1863
1920
  }
1864
1921
  };
1865
- return component;
1866
1922
  };
1867
- var mergeSections = (existing, incoming) => {
1868
- const knownIds = new Set(existing.map((section) => section.id));
1869
- const newSections = incoming.filter((section) => !knownIds.has(section.id));
1870
- const merged = existing.map((section) => {
1871
- var _a, _b, _c, _d;
1872
- const match = incoming.find((s) => s.id === section.id);
1873
- if (!match) return section;
1874
- return {
1875
- id: match.id,
1876
- title: (_a = match.title) != null ? _a : section.title,
1877
- callToAction: (_b = match.callToAction) != null ? _b : section.callToAction,
1878
- help: (_c = match.help) != null ? _c : section.help,
1879
- inlineAlert: (_d = match.inlineAlert) != null ? _d : section.inlineAlert,
1880
- items: [...section.items, ...match.items]
1881
- };
1882
- });
1883
- return [...merged, ...newSections];
1923
+ var DEBOUNCE_TIME = 800;
1924
+ var createSchedulableRequest = (execute) => {
1925
+ const { abort, refresh } = getRequestAbortController();
1926
+ const run = (mode) => {
1927
+ void execute(mode, refresh());
1928
+ };
1929
+ const debouncedRun = debounce(run, DEBOUNCE_TIME);
1930
+ return {
1931
+ run(mode) {
1932
+ debouncedRun.cancel();
1933
+ run(mode);
1934
+ },
1935
+ queue(mode) {
1936
+ abort();
1937
+ debouncedRun(mode);
1938
+ },
1939
+ abort() {
1940
+ debouncedRun.cancel();
1941
+ abort();
1942
+ }
1943
+ };
1884
1944
  };
1885
- var getEventName = (mode, state) => {
1945
+ var getEventName = (mode, status) => {
1886
1946
  const getMode = () => {
1887
1947
  switch (mode) {
1888
1948
  case "pagination":
@@ -1893,7 +1953,94 @@ var getEventName = (mode, state) => {
1893
1953
  return "Filter";
1894
1954
  }
1895
1955
  };
1896
- return `Collection ${getMode()} ${state}`;
1956
+ return `Collection ${getMode()} ${status}`;
1957
+ };
1958
+
1959
+ // src/domain/mappers/utils/image.ts
1960
+ var mapSpecImage = (image) => {
1961
+ var _a, _b, _c;
1962
+ return image ? {
1963
+ uri: (_b = (_a = image.uri) != null ? _a : image.url) != null ? _b : "",
1964
+ accessibilityDescription: (_c = image.accessibilityDescription) != null ? _c : image.text
1965
+ } : void 0;
1966
+ };
1967
+
1968
+ // src/domain/mappers/utils/media-utils.ts
1969
+ var getDomainLayerMedia = ({ icon, image, media }) => {
1970
+ if (media) {
1971
+ return media;
1972
+ }
1973
+ if (icon || image) {
1974
+ return {
1975
+ type: "legacy",
1976
+ icon,
1977
+ image: mapSpecImage(image)
1978
+ };
1979
+ }
1980
+ return void 0;
1981
+ };
1982
+
1983
+ // src/domain/mappers/utils/utils.ts
1984
+ var mapInlineAlert = (alert) => {
1985
+ return alert ? {
1986
+ content: alert.content,
1987
+ context: alert.context ? mapLegacyContext(alert.context) : "neutral",
1988
+ media: getDomainLayerMedia({ media: alert.media })
1989
+ } : void 0;
1990
+ };
1991
+ var mapAdditionalInfo = (info, mapperProps) => {
1992
+ const { onBehavior, trackEvent, registerSubmissionBehavior } = mapperProps;
1993
+ if (info) {
1994
+ const behavior = getDomainLayerBehavior(info, [], registerSubmissionBehavior);
1995
+ const isLink = behavior.type === "link";
1996
+ return {
1997
+ text: info.text,
1998
+ href: isLink ? behavior.url : void 0,
1999
+ hrefWithTracking: getHrefWithTracking({
2000
+ behavior,
2001
+ onBehavior,
2002
+ trackEvent
2003
+ }),
2004
+ accessibilityDescription: info.accessibilityDescription,
2005
+ onClick: behavior.type === "none" ? void 0 : () => {
2006
+ void onBehavior(behavior);
2007
+ }
2008
+ };
2009
+ }
2010
+ return void 0;
2011
+ };
2012
+ var mapSchemaAlert = (alert) => {
2013
+ return alert ? {
2014
+ content: alert.markdown,
2015
+ context: alert.context ? mapLegacyContext(alert.context) : "neutral",
2016
+ media: getDomainLayerMedia({ media: alert.media })
2017
+ } : void 0;
2018
+ };
2019
+
2020
+ // src/domain/components/collectionComponent/CollectionComponent.ts
2021
+ var createCollectionComponent = (props, stack, controller) => {
2022
+ const getChildren2 = () => getCollectionStateChildren(stack.getActiveState());
2023
+ return __spreadProps(__spreadValues({}, props), {
2024
+ type: "collection",
2025
+ kind: "layout",
2026
+ get stack() {
2027
+ return stack.getStates();
2028
+ },
2029
+ getActiveState: stack.getActiveState,
2030
+ fork: controller.fork,
2031
+ pop: controller.pop,
2032
+ search: ({ id }, value) => controller.search(id, value),
2033
+ selectFilter: ({ id }, filterIndex, optionIndex) => controller.selectFilter(id, filterIndex, optionIndex),
2034
+ loadMore: ({ id }) => controller.loadMore(id),
2035
+ retry: ({ id }) => controller.retry(id),
2036
+ getChildren: getChildren2,
2037
+ start() {
2038
+ getChildren2().forEach((child) => child.start());
2039
+ },
2040
+ stop() {
2041
+ getChildren2().forEach((child) => child.stop());
2042
+ }
2043
+ });
1897
2044
  };
1898
2045
 
1899
2046
  // src/domain/features/collection/getPerformCollectionQuery.ts
@@ -1987,29 +2134,45 @@ var hashRequest = ({
1987
2134
  }) => JSON.stringify({ query, cursor, filters: getFilterValues(filters != null ? filters : []) });
1988
2135
 
1989
2136
  // src/domain/mappers/layout/collectionLayoutToComponent.ts
1990
- var collectionLayoutToComponent = (uid, { analyticsId, control, initialState, margin, search, tags, baseRequest }, mapperProps) => {
2137
+ var collectionLayoutToComponent = (uid, { analyticsId, control, initialState, margin, search, tags, baseRequest }, mapperProps, schemaComponents) => {
2138
+ var _a;
1991
2139
  const { httpClient, onComponentUpdate, trackEvent } = mapperProps;
1992
- const mapLayout = (layout, index) => mapLayoutToComponent(`${uid}-collection-response-${index}`, layout, mapperProps, []);
2140
+ let layoutIndex = 0;
2141
+ const mapLayout = (layout) => {
2142
+ layoutIndex += 1;
2143
+ return mapLayoutToComponent(
2144
+ `${uid}-collection-response-${layoutIndex}`,
2145
+ layout,
2146
+ mapperProps,
2147
+ schemaComponents
2148
+ );
2149
+ };
1993
2150
  const mapState = (state) => mapCollectionSpecToDomainState(state, mapperProps, mapLayout);
1994
- const queryFunction = getPerformCollectionQuery(httpClient, baseRequest, mapState);
2151
+ const collectionClient = getPerformCollectionQuery(httpClient, baseRequest, mapState);
2152
+ const stack = createCollectionStack(
2153
+ uid,
2154
+ mapState(__spreadProps(__spreadValues({}, initialState), {
2155
+ search: (_a = initialState.search) != null ? _a : search
2156
+ })),
2157
+ onComponentUpdate
2158
+ );
2159
+ const controller = createCollectionController({ stack, collectionClient, trackEvent });
1995
2160
  const component = createCollectionComponent(
1996
2161
  {
1997
2162
  uid,
1998
2163
  analyticsId,
1999
2164
  control,
2000
2165
  margin: margin != null ? margin : "md",
2001
- tags,
2002
- state: mapState(initialState),
2003
- search
2166
+ tags
2004
2167
  },
2005
- onComponentUpdate,
2006
- queryFunction,
2007
- trackEvent
2168
+ stack,
2169
+ controller
2008
2170
  );
2009
2171
  return component;
2010
2172
  };
2011
2173
  var mapCollectionSpecToDomainState = (specState, mapperProps, mapLayout) => {
2012
2174
  const {
2175
+ search,
2013
2176
  sections,
2014
2177
  filters,
2015
2178
  beforeSections,
@@ -2018,29 +2181,8 @@ var mapCollectionSpecToDomainState = (specState, mapperProps, mapLayout) => {
2018
2181
  analytics = {}
2019
2182
  } = specState;
2020
2183
  return {
2021
- sections: sections.map((section) => {
2022
- var _a;
2023
- return __spreadProps(__spreadValues({}, section), {
2024
- callToAction: getDomainLayerCallToAction(section.callToAction, mapperProps),
2025
- help: (_a = section.help) == null ? void 0 : _a.markdown,
2026
- inlineAlert: mapInlineAlert(section.inlineAlert),
2027
- items: section.items.map((item) => {
2028
- const behavior = getDomainLayerBehavior(
2029
- { behavior: item.primaryBehavior },
2030
- [],
2031
- mapperProps.registerSubmissionBehavior
2032
- );
2033
- return __spreadProps(__spreadValues({}, item), {
2034
- id: item.entityId,
2035
- onClick: item.primaryBehavior ? () => {
2036
- void mapperProps.onBehavior(behavior);
2037
- } : void 0,
2038
- callToAction: getDomainLayerCallToAction(item.callToAction, mapperProps),
2039
- inlineAlert: mapInlineAlert(item.inlineAlert)
2040
- });
2041
- })
2042
- });
2043
- }),
2184
+ search: search ? mapSearch(search, mapperProps, mapLayout) : void 0,
2185
+ sections: sections.map((section) => mapSection(section, mapperProps, mapLayout)),
2044
2186
  filters: filters == null ? void 0 : filters.map(mapFilter),
2045
2187
  beforeSections: beforeSections == null ? void 0 : beforeSections.map(mapLayout),
2046
2188
  afterSections: afterSections == null ? void 0 : afterSections.map(mapLayout),
@@ -2048,6 +2190,49 @@ var mapCollectionSpecToDomainState = (specState, mapperProps, mapLayout) => {
2048
2190
  analytics
2049
2191
  };
2050
2192
  };
2193
+ var mapSearch = (search, mapperProps, mapLayout) => {
2194
+ var _a, _b, _c;
2195
+ return search ? __spreadProps(__spreadValues({}, search), {
2196
+ help: (_a = search.help) == null ? void 0 : _a.markdown,
2197
+ hints: (_b = search.hints) != null ? _b : search.hint ? [search.hint] : void 0,
2198
+ initialSections: (_c = search.initialSections) == null ? void 0 : _c.map(
2199
+ (section) => mapSection(section, mapperProps, mapLayout)
2200
+ )
2201
+ }) : void 0;
2202
+ };
2203
+ var mapSection = (section, mapperProps, mapLayout) => {
2204
+ var _a;
2205
+ const baseProps = __spreadProps(__spreadValues({}, section), {
2206
+ callToAction: getDomainLayerCallToAction(section.callToAction, mapperProps),
2207
+ help: (_a = section.help) == null ? void 0 : _a.markdown,
2208
+ inlineAlert: mapInlineAlert(section.inlineAlert)
2209
+ });
2210
+ if (section.type === "layout") {
2211
+ return __spreadProps(__spreadValues({}, baseProps), {
2212
+ type: "layout",
2213
+ components: section.components.map(mapLayout)
2214
+ });
2215
+ }
2216
+ return __spreadProps(__spreadValues({}, baseProps), {
2217
+ type: "items",
2218
+ items: section.items.map((item) => mapResultItem(item, mapperProps))
2219
+ });
2220
+ };
2221
+ var mapResultItem = (item, mapperProps) => {
2222
+ const behavior = getDomainLayerBehavior(
2223
+ { behavior: item.primaryBehavior },
2224
+ [],
2225
+ mapperProps.registerSubmissionBehavior
2226
+ );
2227
+ return __spreadProps(__spreadValues({}, item), {
2228
+ id: item.entityId,
2229
+ onClick: item.primaryBehavior ? () => {
2230
+ void mapperProps.onBehavior(behavior);
2231
+ } : void 0,
2232
+ callToAction: getDomainLayerCallToAction(item.callToAction, mapperProps),
2233
+ inlineAlert: mapInlineAlert(item.inlineAlert)
2234
+ });
2235
+ };
2051
2236
  var mapFilter = (filter) => {
2052
2237
  const anySelected = filter.options.some((option) => option.selected);
2053
2238
  return __spreadProps(__spreadValues({}, filter), {
@@ -2055,10 +2240,7 @@ var mapFilter = (filter) => {
2055
2240
  var _a;
2056
2241
  return __spreadProps(__spreadValues({}, option), {
2057
2242
  // if a single select with no selection, we should default to selecting the first item
2058
- selected: filter.multiSelect || anySelected ? (_a = option.selected) != null ? _a : false : index === 0,
2059
- onSelect: () => {
2060
- }
2061
- // noop - this gets added during mapping in the component itself
2243
+ selected: filter.multiSelect || anySelected ? (_a = option.selected) != null ? _a : false : index === 0
2062
2244
  });
2063
2245
  })
2064
2246
  });
@@ -3310,7 +3492,7 @@ var mapLayoutToComponent = (uid, layout, mapperProps, schemaComponents) => {
3310
3492
  case "button":
3311
3493
  return buttonLayoutToComponent(uid, layout, mapperProps);
3312
3494
  case "collection":
3313
- return collectionLayoutToComponent(uid, layout, mapperProps);
3495
+ return collectionLayoutToComponent(uid, layout, mapperProps, schemaComponents);
3314
3496
  case "columns":
3315
3497
  return columnsLayoutToComponent(uid, layout, mapperProps, schemaComponents);
3316
3498
  case "decision":
@@ -8020,21 +8202,6 @@ var executeSubflow = async ({
8020
8202
  });
8021
8203
  };
8022
8204
 
8023
- // src/controller/getRequestAbortController.ts
8024
- var getRequestAbortController = () => {
8025
- let abortController = new AbortController();
8026
- return {
8027
- abortAndGetNewSignal() {
8028
- abortController.abort();
8029
- abortController = new AbortController();
8030
- return abortController.signal;
8031
- },
8032
- abort() {
8033
- abortController.abort();
8034
- }
8035
- };
8036
- };
8037
-
8038
8205
  // src/controller/getStepCounter.ts
8039
8206
  var getStepCounter = () => {
8040
8207
  let count = 0;
@@ -8413,7 +8580,7 @@ var createFlowController = (props) => {
8413
8580
  rootComponent.setLoadingState("refreshing");
8414
8581
  const model = rootComponent.getSubmittableValueSync();
8415
8582
  const command = await executeRefresh({
8416
- abortSignal: refreshAbortController.abortAndGetNewSignal(),
8583
+ abortSignal: refreshAbortController.refresh(),
8417
8584
  url: (_a = refreshUrl != null ? refreshUrl : rootComponent.getRefreshUrl()) != null ? _a : "",
8418
8585
  model,
8419
8586
  etag: (_c = (_b = rootComponent.getStep()) == null ? void 0 : _b.etag) != null ? _c : null,
@@ -8971,31 +9138,77 @@ var mapBoxControl = ({
8971
9138
 
8972
9139
  // src/renderers/mappers/collectionComponentToProps.ts
8973
9140
  var collectionComponentToProps = (component, rendererMapperProps) => {
8974
- var _a, _b, _c, _d, _e;
9141
+ const { stack } = component;
9142
+ return __spreadProps(__spreadValues(__spreadValues({}, pick(component, "uid", "analyticsId", "type", "control", "margin", "tags", "fork", "pop")), rendererMapperProps), {
9143
+ state: mapCollectionState(component, component.getActiveState(), rendererMapperProps),
9144
+ onSearchChange: (query) => component.search(component.getActiveState(), query),
9145
+ depth: stack.length - 1
9146
+ });
9147
+ };
9148
+ var mapCollectionState = (component, state, rendererMapperProps) => {
9149
+ var _a, _b, _c, _d;
8975
9150
  const { render } = rendererMapperProps;
8976
- const beforeSectionsProps = (_b = (_a = component.state.beforeSections) == null ? void 0 : _a.map(
8977
- (child) => componentToRendererProps(child, rendererMapperProps)
8978
- )) != null ? _b : [];
8979
- const afterSectionsProps = (_d = (_c = component.state.afterSections) == null ? void 0 : _c.map(
8980
- (child) => componentToRendererProps(child, rendererMapperProps)
8981
- )) != null ? _d : [];
8982
- return __spreadProps(__spreadValues(__spreadValues({}, pick(component, "uid", "analyticsId", "type", "control", "margin", "tags")), rendererMapperProps), {
8983
- status: component.status,
8984
- state: __spreadProps(__spreadValues({}, component.state), {
8985
- filters: (_e = component.state.filters) != null ? _e : [],
8986
- sections: component.state.sections.map((section) => __spreadProps(__spreadValues({}, section), {
8987
- callToAction: mapCallToActionOptional(section.callToAction),
8988
- items: section.items.map((item) => __spreadProps(__spreadValues({}, item), {
8989
- callToAction: mapCallToActionOptional(item.callToAction),
8990
- additionalInfo: mapAdditionalInfo2(item.additionalInfo),
8991
- disabled: rendererMapperProps.stepLoadingState !== "idle" || item.disabled
8992
- }))
8993
- })),
8994
- beforeSectionsProps,
8995
- beforeSections: beforeSectionsProps.map(render),
8996
- afterSectionsProps,
8997
- afterSections: afterSectionsProps.map(render)
8998
- })
9151
+ const { search } = state;
9152
+ const beforeSectionsProps = (_b = (_a = state.beforeSections) == null ? void 0 : _a.map((child) => componentToRendererProps(child, rendererMapperProps))) != null ? _b : [];
9153
+ const afterSectionsProps = (_d = (_c = state.afterSections) == null ? void 0 : _c.map((child) => componentToRendererProps(child, rendererMapperProps))) != null ? _d : [];
9154
+ return {
9155
+ id: state.id,
9156
+ status: mapStatus(component, state),
9157
+ sections: mapSections(state.sections, rendererMapperProps),
9158
+ filters: mapFilters(component, state),
9159
+ beforeSectionsProps,
9160
+ beforeSections: beforeSectionsProps.map(render),
9161
+ afterSectionsProps,
9162
+ afterSections: afterSectionsProps.map(render),
9163
+ search: search ? __spreadProps(__spreadValues({}, pick(search, "title", "hint", "hints", "query")), {
9164
+ initialSections: search.initialSections ? mapSections(search.initialSections, rendererMapperProps) : void 0
9165
+ }) : void 0
9166
+ };
9167
+ };
9168
+ var mapStatus = (component, state) => {
9169
+ const { status } = state;
9170
+ switch (status.type) {
9171
+ case "idle":
9172
+ return {
9173
+ type: "idle",
9174
+ loadMore: state.nextCursor ? () => component.loadMore(state) : void 0
9175
+ };
9176
+ case "loading":
9177
+ return status;
9178
+ case "error":
9179
+ return __spreadProps(__spreadValues({}, status), { retry: () => component.retry(state) });
9180
+ }
9181
+ };
9182
+ var mapFilters = (component, state) => {
9183
+ var _a;
9184
+ return ((_a = state.filters) != null ? _a : []).map((filter, filterIndex) => __spreadProps(__spreadValues({}, filter), {
9185
+ options: filter.options.map((option, optionIndex) => __spreadProps(__spreadValues({}, option), {
9186
+ onSelect: () => component.selectFilter(state, filterIndex, optionIndex)
9187
+ }))
9188
+ }));
9189
+ };
9190
+ var mapSections = (sections, rendererMapperProps) => sections.map((section) => mapSection2(section, rendererMapperProps));
9191
+ var mapSection2 = (section, rendererMapperProps) => {
9192
+ const baseProps = __spreadProps(__spreadValues({}, section), {
9193
+ callToAction: mapCallToActionOptional(section.callToAction)
9194
+ });
9195
+ if (section.type === "layout") {
9196
+ const childrenProps = section.components.map(
9197
+ (child) => componentToRendererProps(child, rendererMapperProps)
9198
+ );
9199
+ return __spreadProps(__spreadValues({}, baseProps), {
9200
+ type: "layout",
9201
+ childrenProps,
9202
+ children: childrenProps.map(rendererMapperProps.render)
9203
+ });
9204
+ }
9205
+ return __spreadProps(__spreadValues({}, baseProps), {
9206
+ type: "items",
9207
+ items: section.items.map((item) => __spreadProps(__spreadValues({}, item), {
9208
+ callToAction: mapCallToActionOptional(item.callToAction),
9209
+ additionalInfo: mapAdditionalInfo2(item.additionalInfo),
9210
+ disabled: rendererMapperProps.stepLoadingState !== "idle" || item.disabled
9211
+ }))
8999
9212
  });
9000
9213
  };
9001
9214
 
@@ -9416,7 +9629,7 @@ var reviewComponentToProps = (component, rendererMapperProps) => __spreadValues(
9416
9629
 
9417
9630
  // src/renderers/mappers/searchComponentToProps.ts
9418
9631
  var searchComponentToProps = (component, rendererMapperProps) => {
9419
- const { uid, emptyMessage, error, query, setQuery, selectResult } = component;
9632
+ const { uid, emptyMessage, error, query, setQuery: setQuery2, selectResult } = component;
9420
9633
  const state = getSearchState({
9421
9634
  emptyMessage,
9422
9635
  error,
@@ -9424,11 +9637,11 @@ var searchComponentToProps = (component, rendererMapperProps) => {
9424
9637
  query,
9425
9638
  state: component.state,
9426
9639
  rendererMapperProps,
9427
- setQuery,
9640
+ setQuery: setQuery2,
9428
9641
  selectResult
9429
9642
  });
9430
9643
  return __spreadValues(__spreadProps(__spreadValues({}, pick(component, "uid", "control", "hint", "isLoading", "margin", "query", "title", "tags")), {
9431
- onChange: setQuery,
9644
+ onChange: setQuery2,
9432
9645
  type: "search",
9433
9646
  id: uid,
9434
9647
  state
@@ -9441,14 +9654,14 @@ var getSearchState = ({
9441
9654
  query,
9442
9655
  state,
9443
9656
  rendererMapperProps,
9444
- setQuery,
9657
+ setQuery: setQuery2,
9445
9658
  selectResult
9446
9659
  }) => {
9447
9660
  if (isLoading) {
9448
9661
  return { type: "pending" };
9449
9662
  }
9450
9663
  if (error) {
9451
- return { type: "error", onRetry: () => setQuery(query) };
9664
+ return { type: "error", onRetry: () => setQuery2(query) };
9452
9665
  }
9453
9666
  if (!state) {
9454
9667
  return { type: "noResults", message: emptyMessage };