@vuu-ui/vuu-filters 0.8.0-debug → 0.8.1-debug

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/esm/index.js CHANGED
@@ -548,268 +548,510 @@ var RangeFilter = ({
548
548
  ] });
549
549
  };
550
550
 
551
- // ../vuu-data-react/src/hooks/useDataSource.ts
552
- import { getFullRange, metadataKeys, WindowRange } from "@vuu-ui/vuu-utils";
553
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
554
- var { SELECTED } = metadataKeys;
555
-
556
- // ../vuu-data-react/src/hooks/useServerConnectionStatus.ts
557
- import { useCallback as useCallback2, useEffect as useEffect2, useState as useState2 } from "react";
558
- import { ConnectionManager } from "@vuu-ui/vuu-data";
559
-
560
- // ../vuu-data-react/src/hooks/useServerConnectionQuality.ts
561
- import { useCallback as useCallback3, useEffect as useEffect3, useState as useState3 } from "react";
562
- import { ConnectionManager as ConnectionManager2 } from "@vuu-ui/vuu-data";
563
-
564
- // ../vuu-data-react/src/hooks/useTypeaheadSuggestions.ts
565
- import { useCallback as useCallback4 } from "react";
566
- import { makeRpcCall } from "@vuu-ui/vuu-data";
567
- var TYPEAHEAD_MESSAGE_CONSTANTS = {
568
- type: "RPC_CALL",
569
- service: "TypeAheadRpcHandler"
570
- };
571
- var getTypeaheadParams = (table, column, text = "", selectedValues = []) => {
572
- if (text !== "" && !selectedValues.includes(text.toLowerCase())) {
573
- return [table, column, text];
574
- }
575
- return [table, column];
576
- };
577
- var useTypeaheadSuggestions = () => {
578
- const getTypeaheadSuggestions = useCallback4(
579
- async (params) => {
580
- const rpcMessage = params.length === 2 ? {
581
- method: "getUniqueFieldValues",
582
- params,
583
- ...TYPEAHEAD_MESSAGE_CONSTANTS
584
- } : {
585
- method: "getUniqueFieldValuesStartingWith",
586
- params,
587
- ...TYPEAHEAD_MESSAGE_CONSTANTS
588
- };
589
- const suggestions = await makeRpcCall(rpcMessage);
590
- return suggestions;
551
+ // src/column-filter/TypeaheadFilter.tsx
552
+ import { useTypeaheadSuggestions } from "@vuu-ui/vuu-data-react";
553
+ import { ComboBoxDeprecated } from "@heswell/salt-lab";
554
+ import { useCallback, useEffect, useState } from "react";
555
+ import { jsx as jsx4 } from "react/jsx-runtime";
556
+ var TypeaheadFilter = ({
557
+ defaultTypeaheadParams,
558
+ filterValues = [],
559
+ onChange: onFilterChange
560
+ }) => {
561
+ const [tableName, columnName] = defaultTypeaheadParams;
562
+ const [searchValue, setSearchValue] = useState("");
563
+ const [typeaheadValues, setTypeaheadValues] = useState([]);
564
+ const getSuggestions = useTypeaheadSuggestions();
565
+ useEffect(() => {
566
+ const params = searchValue ? [tableName, columnName, searchValue] : defaultTypeaheadParams;
567
+ let isSubscribed = true;
568
+ getSuggestions(params).then((options) => {
569
+ if (!isSubscribed) {
570
+ return;
571
+ }
572
+ if (isStartsWithValue(filterValues[0])) {
573
+ options.unshift(filterValues[0]);
574
+ }
575
+ if (searchValue) {
576
+ options.unshift(`${searchValue}...`);
577
+ }
578
+ options.concat(filterValues);
579
+ setTypeaheadValues(options);
580
+ });
581
+ return () => {
582
+ isSubscribed = false;
583
+ };
584
+ }, [
585
+ filterValues,
586
+ searchValue,
587
+ columnName,
588
+ tableName,
589
+ getSuggestions,
590
+ defaultTypeaheadParams
591
+ ]);
592
+ const onInputChange = useCallback(
593
+ (evt) => {
594
+ const value = evt.target.value;
595
+ setSearchValue(value);
591
596
  },
592
597
  []
593
598
  );
594
- return getTypeaheadSuggestions;
599
+ const onSelectionChange = useCallback(
600
+ (_evt, selected) => {
601
+ setSearchValue("");
602
+ if (selected === null)
603
+ return;
604
+ if (selected.some(isStartsWithValue)) {
605
+ selected = selected.filter(isStartsWithValue).slice(-1);
606
+ }
607
+ const filter = getTypeaheadFilter(
608
+ columnName,
609
+ selected,
610
+ isStartsWithValue(selected[0])
611
+ );
612
+ onFilterChange(selected, filter);
613
+ },
614
+ [columnName, onFilterChange]
615
+ );
616
+ return /* @__PURE__ */ jsx4(
617
+ ComboBoxDeprecated,
618
+ {
619
+ multiSelect: true,
620
+ onInputChange,
621
+ onChange: onSelectionChange,
622
+ source: typeaheadValues,
623
+ style: { minWidth: 200 },
624
+ inputValue: searchValue,
625
+ selectedItem: filterValues
626
+ },
627
+ columnName
628
+ );
595
629
  };
596
630
 
597
- // ../../node_modules/@lezer/common/dist/index.js
598
- var DefaultBufferLength = 1024;
599
- var nextPropID = 0;
600
- var Range = class {
601
- constructor(from, to) {
602
- this.from = from;
603
- this.to = to;
604
- }
605
- };
606
- var NodeProp = class {
607
- /// Create a new node prop type.
608
- constructor(config = {}) {
609
- this.id = nextPropID++;
610
- this.perNode = !!config.perNode;
611
- this.deserialize = config.deserialize || (() => {
612
- throw new Error("This node type doesn't define a deserialize function");
613
- });
614
- }
615
- /// This is meant to be used with
616
- /// [`NodeSet.extend`](#common.NodeSet.extend) or
617
- /// [`LRParser.configure`](#lr.ParserConfig.props) to compute
618
- /// prop values for each node type in the set. Takes a [match
619
- /// object](#common.NodeType^match) or function that returns undefined
620
- /// if the node type doesn't get this prop, and the prop's value if
621
- /// it does.
622
- add(match) {
623
- if (this.perNode)
624
- throw new RangeError("Can't add per-node props to node types");
625
- if (typeof match != "function")
626
- match = NodeType.match(match);
627
- return (type) => {
628
- let result = match(type);
629
- return result === void 0 ? null : [this, result];
630
- };
631
- }
632
- };
633
- NodeProp.closedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
634
- NodeProp.openedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
635
- NodeProp.group = new NodeProp({ deserialize: (str) => str.split(" ") });
636
- NodeProp.contextHash = new NodeProp({ perNode: true });
637
- NodeProp.lookAhead = new NodeProp({ perNode: true });
638
- NodeProp.mounted = new NodeProp({ perNode: true });
639
- var noProps = /* @__PURE__ */ Object.create(null);
640
- var NodeType = class {
641
- /// @internal
642
- constructor(name, props, id, flags = 0) {
643
- this.name = name;
644
- this.props = props;
645
- this.id = id;
646
- this.flags = flags;
647
- }
648
- /// Define a node type.
649
- static define(spec) {
650
- let props = spec.props && spec.props.length ? /* @__PURE__ */ Object.create(null) : noProps;
651
- let flags = (spec.top ? 1 : 0) | (spec.skipped ? 2 : 0) | (spec.error ? 4 : 0) | (spec.name == null ? 8 : 0);
652
- let type = new NodeType(spec.name || "", props, spec.id, flags);
653
- if (spec.props)
654
- for (let src of spec.props) {
655
- if (!Array.isArray(src))
656
- src = src(type);
657
- if (src) {
658
- if (src[0].perNode)
659
- throw new RangeError("Can't store a per-node prop on a node type");
660
- props[src[0].id] = src[1];
661
- }
662
- }
663
- return type;
664
- }
665
- /// Retrieves a node prop for this type. Will return `undefined` if
666
- /// the prop isn't present on this node.
667
- prop(prop) {
668
- return this.props[prop.id];
669
- }
670
- /// True when this is the top node of a grammar.
671
- get isTop() {
672
- return (this.flags & 1) > 0;
673
- }
674
- /// True when this node is produced by a skip rule.
675
- get isSkipped() {
676
- return (this.flags & 2) > 0;
677
- }
678
- /// Indicates whether this is an error node.
679
- get isError() {
680
- return (this.flags & 4) > 0;
681
- }
682
- /// When true, this node type doesn't correspond to a user-declared
683
- /// named node, for example because it is used to cache repetition.
684
- get isAnonymous() {
685
- return (this.flags & 8) > 0;
686
- }
687
- /// Returns true when this node's name or one of its
688
- /// [groups](#common.NodeProp^group) matches the given string.
689
- is(name) {
690
- if (typeof name == "string") {
691
- if (this.name == name)
692
- return true;
693
- let group = this.prop(NodeProp.group);
694
- return group ? group.indexOf(name) > -1 : false;
695
- }
696
- return this.id == name;
697
- }
698
- /// Create a function from node types to arbitrary values by
699
- /// specifying an object whose property names are node or
700
- /// [group](#common.NodeProp^group) names. Often useful with
701
- /// [`NodeProp.add`](#common.NodeProp.add). You can put multiple
702
- /// names, separated by spaces, in a single property name to map
703
- /// multiple node names to a single value.
704
- static match(map) {
705
- let direct = /* @__PURE__ */ Object.create(null);
706
- for (let prop in map)
707
- for (let name of prop.split(" "))
708
- direct[name] = map[prop];
709
- return (node) => {
710
- for (let groups = node.prop(NodeProp.group), i = -1; i < (groups ? groups.length : 0); i++) {
711
- let found = direct[i < 0 ? node.name : groups[i]];
712
- if (found)
713
- return found;
714
- }
715
- };
716
- }
631
+ // src/column-filter/ColumnListItem.tsx
632
+ import { memo } from "react";
633
+ import {
634
+ Highlighter,
635
+ ListItem
636
+ } from "@heswell/salt-lab";
637
+ import { jsx as jsx5 } from "react/jsx-runtime";
638
+ var ColumnListItem = (props) => {
639
+ return /* @__PURE__ */ jsx5(MemoColumnItem, { ...props });
717
640
  };
718
- NodeType.none = new NodeType(
719
- "",
720
- /* @__PURE__ */ Object.create(null),
721
- 0,
722
- 8
723
- /* NodeFlag.Anonymous */
724
- );
725
- var NodeSet = class {
726
- /// Create a set with the given types. The `id` property of each
727
- /// type should correspond to its position within the array.
728
- constructor(types) {
729
- this.types = types;
730
- for (let i = 0; i < types.length; i++)
731
- if (types[i].id != i)
732
- throw new RangeError("Node type ids should correspond to array positions when creating a node set");
733
- }
734
- /// Create a copy of this set with some node properties added. The
735
- /// arguments to this method can be created with
736
- /// [`NodeProp.add`](#common.NodeProp.add).
737
- extend(...props) {
738
- let newTypes = [];
739
- for (let type of this.types) {
740
- let newProps = null;
741
- for (let source of props) {
742
- let add = source(type);
743
- if (add) {
744
- if (!newProps)
745
- newProps = Object.assign({}, type.props);
746
- newProps[add[0].id] = add[1];
747
- }
748
- }
749
- newTypes.push(newProps ? new NodeType(type.name, newProps, type.id, type.flags) : type);
641
+ var MemoColumnItem = memo(function MemoizedItem({
642
+ item,
643
+ itemTextHighlightPattern,
644
+ ...restProps
645
+ }) {
646
+ return /* @__PURE__ */ jsx5(ListItem, { ...restProps, children: /* @__PURE__ */ jsx5("span", { style: { marginLeft: 10 }, children: /* @__PURE__ */ jsx5(
647
+ Highlighter,
648
+ {
649
+ matchPattern: itemTextHighlightPattern,
650
+ text: item == null ? void 0 : item.name
750
651
  }
751
- return new NodeSet(newTypes);
752
- }
753
- };
754
- var CachedNode = /* @__PURE__ */ new WeakMap();
755
- var CachedInnerNode = /* @__PURE__ */ new WeakMap();
756
- var IterMode;
757
- (function(IterMode2) {
758
- IterMode2[IterMode2["ExcludeBuffers"] = 1] = "ExcludeBuffers";
759
- IterMode2[IterMode2["IncludeAnonymous"] = 2] = "IncludeAnonymous";
760
- IterMode2[IterMode2["IgnoreMounts"] = 4] = "IgnoreMounts";
761
- IterMode2[IterMode2["IgnoreOverlays"] = 8] = "IgnoreOverlays";
762
- })(IterMode || (IterMode = {}));
763
- var Tree = class {
764
- /// Construct a new tree. See also [`Tree.build`](#common.Tree^build).
765
- constructor(type, children, positions, length, props) {
766
- this.type = type;
767
- this.children = children;
768
- this.positions = positions;
769
- this.length = length;
770
- this.props = null;
771
- if (props && props.length) {
772
- this.props = /* @__PURE__ */ Object.create(null);
773
- for (let [prop, value] of props)
774
- this.props[typeof prop == "number" ? prop : prop.id] = value;
652
+ ) }) });
653
+ });
654
+
655
+ // src/column-filter/useColumnFilterStore.ts
656
+ import { filterAsQuery as filterAsQuery2 } from "@vuu-ui/vuu-utils";
657
+ import { useCallback as useCallback2, useState as useState2 } from "react";
658
+ var addOrReplace = (array, newValue, key) => array.filter((oldValue) => oldValue[key] !== newValue[key]).concat(newValue);
659
+ var useColumnFilterStore = (onFilterSubmit) => {
660
+ var _a, _b;
661
+ const [selectedColumnName, setSelectedColumnName] = useState2("");
662
+ const [savedFilters, setSavedFilters] = useState2([]);
663
+ const [rangeValues, setRangeValues] = useState2([]);
664
+ const [typeaheadValues, setTypeaheadValues] = useState2([]);
665
+ const clear = () => {
666
+ setSelectedColumnName("");
667
+ setRangeValues([]);
668
+ setTypeaheadValues([]);
669
+ setSavedFilters([]);
670
+ onFilterSubmit({ filter: "" });
671
+ };
672
+ const updateFilters = useCallback2(
673
+ (newFilter) => {
674
+ const newSavedFilters = addOrReplace(
675
+ savedFilters,
676
+ { column: selectedColumnName, filter: newFilter },
677
+ "column"
678
+ );
679
+ setSavedFilters(newSavedFilters);
680
+ const combinedFilter = newSavedFilters.map((x) => x.filter).reduce((prev, filter) => {
681
+ if (filter === void 0)
682
+ return prev;
683
+ return addFilter(prev, filter, { combineWith: AND });
684
+ }, void 0);
685
+ const query = combinedFilter === void 0 ? "" : filterAsQuery2(combinedFilter);
686
+ onFilterSubmit({ filter: query, filterStruct: combinedFilter });
687
+ },
688
+ [selectedColumnName, onFilterSubmit, savedFilters]
689
+ );
690
+ const onTypeaheadChange = useCallback2(
691
+ (newValues, newFilter) => {
692
+ setTypeaheadValues(
693
+ addOrReplace(
694
+ typeaheadValues,
695
+ { column: selectedColumnName, value: newValues },
696
+ "column"
697
+ )
698
+ );
699
+ updateFilters(newFilter);
700
+ },
701
+ [selectedColumnName, typeaheadValues, updateFilters]
702
+ );
703
+ const onRangeChange = useCallback2(
704
+ (newValues, newFilter) => {
705
+ setRangeValues(
706
+ addOrReplace(
707
+ rangeValues,
708
+ { column: selectedColumnName, value: newValues },
709
+ "column"
710
+ )
711
+ );
712
+ updateFilters(newFilter);
713
+ },
714
+ [selectedColumnName, rangeValues, updateFilters]
715
+ );
716
+ const onSelectedColumnChange = useCallback2(
717
+ (column) => setSelectedColumnName((column == null ? void 0 : column.name) || ""),
718
+ []
719
+ );
720
+ const rangeValue = (_a = rangeValues.filter(
721
+ (v) => v.column === selectedColumnName
722
+ )[0]) == null ? void 0 : _a.value;
723
+ const typeaheadValue = (_b = typeaheadValues.filter(
724
+ (v) => v.column === selectedColumnName
725
+ )[0]) == null ? void 0 : _b.value;
726
+ return {
727
+ clear,
728
+ selectedColumnName,
729
+ rangeValue,
730
+ typeaheadValue,
731
+ onSelectedColumnChange,
732
+ onRangeChange,
733
+ onTypeaheadChange
734
+ };
735
+ };
736
+
737
+ // src/column-filter/ColumnFilter.tsx
738
+ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
739
+ var ColumnFilter = ({
740
+ className,
741
+ table,
742
+ columns,
743
+ onFilterSubmit,
744
+ ...htmlAttributes
745
+ }) => {
746
+ const {
747
+ clear,
748
+ onTypeaheadChange,
749
+ onRangeChange,
750
+ onSelectedColumnChange,
751
+ selectedColumnName,
752
+ rangeValue,
753
+ typeaheadValue
754
+ } = useColumnFilterStore(onFilterSubmit);
755
+ const getFilterComponent = () => {
756
+ var _a;
757
+ const defaultTypeaheadParams = [table, selectedColumnName];
758
+ const selectedColumnType = (_a = columns.find(
759
+ (column) => column.name === selectedColumnName
760
+ )) == null ? void 0 : _a.serverDataType;
761
+ switch (selectedColumnType) {
762
+ case "string":
763
+ case "char":
764
+ return /* @__PURE__ */ jsx6(
765
+ ToolbarField2,
766
+ {
767
+ label: "Start typing to select a filter",
768
+ labelPlacement: "top",
769
+ children: /* @__PURE__ */ jsx6(
770
+ TypeaheadFilter,
771
+ {
772
+ defaultTypeaheadParams,
773
+ filterValues: typeaheadValue,
774
+ onChange: onTypeaheadChange
775
+ }
776
+ )
777
+ }
778
+ );
779
+ case "int":
780
+ case "long":
781
+ case "double":
782
+ return /* @__PURE__ */ jsx6(ToolbarField2, { label: "Select a range", labelPlacement: "top", children: /* @__PURE__ */ jsx6(
783
+ RangeFilter,
784
+ {
785
+ defaultTypeaheadParams,
786
+ filterValues: rangeValue,
787
+ onChange: onRangeChange
788
+ }
789
+ ) });
790
+ default:
791
+ return /* @__PURE__ */ jsx6(ToolbarField2, { children: /* @__PURE__ */ jsx6(Text, { children: "Data type unsupported" }) });
775
792
  }
776
- }
777
- /// @internal
778
- toString() {
779
- let mounted = this.prop(NodeProp.mounted);
780
- if (mounted && !mounted.overlay)
781
- return mounted.tree.toString();
782
- let children = "";
783
- for (let ch of this.children) {
784
- let str = ch.toString();
785
- if (str) {
786
- if (children)
787
- children += ",";
788
- children += str;
789
- }
793
+ };
794
+ return /* @__PURE__ */ jsxs3(
795
+ Toolbar,
796
+ {
797
+ ...htmlAttributes,
798
+ style: { alignItems: "center", height: "36px" },
799
+ children: [
800
+ /* @__PURE__ */ jsx6(
801
+ ToolbarField2,
802
+ {
803
+ label: "Select a column to filter",
804
+ labelPlacement: "top",
805
+ style: { width: 180 },
806
+ children: /* @__PURE__ */ jsx6(
807
+ Dropdown,
808
+ {
809
+ source: columns,
810
+ ListItem: ColumnListItem,
811
+ itemToString: (column) => column.name,
812
+ onSelectionChange: (_evt, column) => onSelectedColumnChange(column)
813
+ }
814
+ )
815
+ }
816
+ ),
817
+ selectedColumnName && getFilterComponent(),
818
+ /* @__PURE__ */ jsx6(ToolbarButton, { onClick: clear, children: /* @__PURE__ */ jsx6(DeleteIcon, {}) })
819
+ ]
790
820
  }
791
- return !this.type.name ? children : (/\W/.test(this.type.name) && !this.type.isError ? JSON.stringify(this.type.name) : this.type.name) + (children.length ? "(" + children + ")" : "");
792
- }
793
- /// Get a [tree cursor](#common.TreeCursor) positioned at the top of
794
- /// the tree. Mode can be used to [control](#common.IterMode) which
795
- /// nodes the cursor visits.
796
- cursor(mode = 0) {
797
- return new TreeCursor(this.topNode, mode);
821
+ );
822
+ };
823
+
824
+ // src/filter-input/FilterInput.tsx
825
+ import { Button } from "@salt-ds/core";
826
+
827
+ // src/filter-input/useCodeMirrorEditor.ts
828
+ import {
829
+ autocompletion,
830
+ defaultKeymap,
831
+ EditorState as EditorState2,
832
+ EditorView as EditorView2,
833
+ ensureSyntaxTree,
834
+ keymap,
835
+ minimalSetup,
836
+ startCompletion
837
+ } from "@vuu-ui/vuu-codemirror";
838
+
839
+ // ../../node_modules/@lezer/common/dist/index.js
840
+ var DefaultBufferLength = 1024;
841
+ var nextPropID = 0;
842
+ var Range = class {
843
+ constructor(from, to) {
844
+ this.from = from;
845
+ this.to = to;
798
846
  }
799
- /// Get a [tree cursor](#common.TreeCursor) pointing into this tree
800
- /// at the given position and side (see
801
- /// [`moveTo`](#common.TreeCursor.moveTo).
802
- cursorAt(pos, side = 0, mode = 0) {
803
- let scope = CachedNode.get(this) || this.topNode;
804
- let cursor = new TreeCursor(scope);
805
- cursor.moveTo(pos, side);
806
- CachedNode.set(this, cursor._tree);
807
- return cursor;
847
+ };
848
+ var NodeProp = class {
849
+ /// Create a new node prop type.
850
+ constructor(config = {}) {
851
+ this.id = nextPropID++;
852
+ this.perNode = !!config.perNode;
853
+ this.deserialize = config.deserialize || (() => {
854
+ throw new Error("This node type doesn't define a deserialize function");
855
+ });
808
856
  }
809
- /// Get a [syntax node](#common.SyntaxNode) object for the top of the
810
- /// tree.
811
- get topNode() {
812
- return new TreeNode(this, 0, 0, null);
857
+ /// This is meant to be used with
858
+ /// [`NodeSet.extend`](#common.NodeSet.extend) or
859
+ /// [`LRParser.configure`](#lr.ParserConfig.props) to compute
860
+ /// prop values for each node type in the set. Takes a [match
861
+ /// object](#common.NodeType^match) or function that returns undefined
862
+ /// if the node type doesn't get this prop, and the prop's value if
863
+ /// it does.
864
+ add(match) {
865
+ if (this.perNode)
866
+ throw new RangeError("Can't add per-node props to node types");
867
+ if (typeof match != "function")
868
+ match = NodeType.match(match);
869
+ return (type) => {
870
+ let result = match(type);
871
+ return result === void 0 ? null : [this, result];
872
+ };
873
+ }
874
+ };
875
+ NodeProp.closedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
876
+ NodeProp.openedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
877
+ NodeProp.group = new NodeProp({ deserialize: (str) => str.split(" ") });
878
+ NodeProp.contextHash = new NodeProp({ perNode: true });
879
+ NodeProp.lookAhead = new NodeProp({ perNode: true });
880
+ NodeProp.mounted = new NodeProp({ perNode: true });
881
+ var noProps = /* @__PURE__ */ Object.create(null);
882
+ var NodeType = class {
883
+ /// @internal
884
+ constructor(name, props, id, flags = 0) {
885
+ this.name = name;
886
+ this.props = props;
887
+ this.id = id;
888
+ this.flags = flags;
889
+ }
890
+ /// Define a node type.
891
+ static define(spec) {
892
+ let props = spec.props && spec.props.length ? /* @__PURE__ */ Object.create(null) : noProps;
893
+ let flags = (spec.top ? 1 : 0) | (spec.skipped ? 2 : 0) | (spec.error ? 4 : 0) | (spec.name == null ? 8 : 0);
894
+ let type = new NodeType(spec.name || "", props, spec.id, flags);
895
+ if (spec.props)
896
+ for (let src of spec.props) {
897
+ if (!Array.isArray(src))
898
+ src = src(type);
899
+ if (src) {
900
+ if (src[0].perNode)
901
+ throw new RangeError("Can't store a per-node prop on a node type");
902
+ props[src[0].id] = src[1];
903
+ }
904
+ }
905
+ return type;
906
+ }
907
+ /// Retrieves a node prop for this type. Will return `undefined` if
908
+ /// the prop isn't present on this node.
909
+ prop(prop) {
910
+ return this.props[prop.id];
911
+ }
912
+ /// True when this is the top node of a grammar.
913
+ get isTop() {
914
+ return (this.flags & 1) > 0;
915
+ }
916
+ /// True when this node is produced by a skip rule.
917
+ get isSkipped() {
918
+ return (this.flags & 2) > 0;
919
+ }
920
+ /// Indicates whether this is an error node.
921
+ get isError() {
922
+ return (this.flags & 4) > 0;
923
+ }
924
+ /// When true, this node type doesn't correspond to a user-declared
925
+ /// named node, for example because it is used to cache repetition.
926
+ get isAnonymous() {
927
+ return (this.flags & 8) > 0;
928
+ }
929
+ /// Returns true when this node's name or one of its
930
+ /// [groups](#common.NodeProp^group) matches the given string.
931
+ is(name) {
932
+ if (typeof name == "string") {
933
+ if (this.name == name)
934
+ return true;
935
+ let group = this.prop(NodeProp.group);
936
+ return group ? group.indexOf(name) > -1 : false;
937
+ }
938
+ return this.id == name;
939
+ }
940
+ /// Create a function from node types to arbitrary values by
941
+ /// specifying an object whose property names are node or
942
+ /// [group](#common.NodeProp^group) names. Often useful with
943
+ /// [`NodeProp.add`](#common.NodeProp.add). You can put multiple
944
+ /// names, separated by spaces, in a single property name to map
945
+ /// multiple node names to a single value.
946
+ static match(map) {
947
+ let direct = /* @__PURE__ */ Object.create(null);
948
+ for (let prop in map)
949
+ for (let name of prop.split(" "))
950
+ direct[name] = map[prop];
951
+ return (node) => {
952
+ for (let groups = node.prop(NodeProp.group), i = -1; i < (groups ? groups.length : 0); i++) {
953
+ let found = direct[i < 0 ? node.name : groups[i]];
954
+ if (found)
955
+ return found;
956
+ }
957
+ };
958
+ }
959
+ };
960
+ NodeType.none = new NodeType(
961
+ "",
962
+ /* @__PURE__ */ Object.create(null),
963
+ 0,
964
+ 8
965
+ /* NodeFlag.Anonymous */
966
+ );
967
+ var NodeSet = class {
968
+ /// Create a set with the given types. The `id` property of each
969
+ /// type should correspond to its position within the array.
970
+ constructor(types) {
971
+ this.types = types;
972
+ for (let i = 0; i < types.length; i++)
973
+ if (types[i].id != i)
974
+ throw new RangeError("Node type ids should correspond to array positions when creating a node set");
975
+ }
976
+ /// Create a copy of this set with some node properties added. The
977
+ /// arguments to this method can be created with
978
+ /// [`NodeProp.add`](#common.NodeProp.add).
979
+ extend(...props) {
980
+ let newTypes = [];
981
+ for (let type of this.types) {
982
+ let newProps = null;
983
+ for (let source of props) {
984
+ let add = source(type);
985
+ if (add) {
986
+ if (!newProps)
987
+ newProps = Object.assign({}, type.props);
988
+ newProps[add[0].id] = add[1];
989
+ }
990
+ }
991
+ newTypes.push(newProps ? new NodeType(type.name, newProps, type.id, type.flags) : type);
992
+ }
993
+ return new NodeSet(newTypes);
994
+ }
995
+ };
996
+ var CachedNode = /* @__PURE__ */ new WeakMap();
997
+ var CachedInnerNode = /* @__PURE__ */ new WeakMap();
998
+ var IterMode;
999
+ (function(IterMode2) {
1000
+ IterMode2[IterMode2["ExcludeBuffers"] = 1] = "ExcludeBuffers";
1001
+ IterMode2[IterMode2["IncludeAnonymous"] = 2] = "IncludeAnonymous";
1002
+ IterMode2[IterMode2["IgnoreMounts"] = 4] = "IgnoreMounts";
1003
+ IterMode2[IterMode2["IgnoreOverlays"] = 8] = "IgnoreOverlays";
1004
+ })(IterMode || (IterMode = {}));
1005
+ var Tree = class {
1006
+ /// Construct a new tree. See also [`Tree.build`](#common.Tree^build).
1007
+ constructor(type, children, positions, length, props) {
1008
+ this.type = type;
1009
+ this.children = children;
1010
+ this.positions = positions;
1011
+ this.length = length;
1012
+ this.props = null;
1013
+ if (props && props.length) {
1014
+ this.props = /* @__PURE__ */ Object.create(null);
1015
+ for (let [prop, value] of props)
1016
+ this.props[typeof prop == "number" ? prop : prop.id] = value;
1017
+ }
1018
+ }
1019
+ /// @internal
1020
+ toString() {
1021
+ let mounted = this.prop(NodeProp.mounted);
1022
+ if (mounted && !mounted.overlay)
1023
+ return mounted.tree.toString();
1024
+ let children = "";
1025
+ for (let ch of this.children) {
1026
+ let str = ch.toString();
1027
+ if (str) {
1028
+ if (children)
1029
+ children += ",";
1030
+ children += str;
1031
+ }
1032
+ }
1033
+ return !this.type.name ? children : (/\W/.test(this.type.name) && !this.type.isError ? JSON.stringify(this.type.name) : this.type.name) + (children.length ? "(" + children + ")" : "");
1034
+ }
1035
+ /// Get a [tree cursor](#common.TreeCursor) positioned at the top of
1036
+ /// the tree. Mode can be used to [control](#common.IterMode) which
1037
+ /// nodes the cursor visits.
1038
+ cursor(mode = 0) {
1039
+ return new TreeCursor(this.topNode, mode);
1040
+ }
1041
+ /// Get a [tree cursor](#common.TreeCursor) pointing into this tree
1042
+ /// at the given position and side (see
1043
+ /// [`moveTo`](#common.TreeCursor.moveTo).
1044
+ cursorAt(pos, side = 0, mode = 0) {
1045
+ let scope = CachedNode.get(this) || this.topNode;
1046
+ let cursor = new TreeCursor(scope);
1047
+ cursor.moveTo(pos, side);
1048
+ CachedNode.set(this, cursor._tree);
1049
+ return cursor;
1050
+ }
1051
+ /// Get a [syntax node](#common.SyntaxNode) object for the top of the
1052
+ /// tree.
1053
+ get topNode() {
1054
+ return new TreeNode(this, 0, 0, null);
813
1055
  }
814
1056
  /// Get the [syntax node](#common.SyntaxNode) at the given position.
815
1057
  /// If `side` is -1, this will move into nodes that end at the
@@ -2194,26 +2436,58 @@ var Stack = class {
2194
2436
  // be done.
2195
2437
  /// @internal
2196
2438
  forceReduce() {
2197
- let reduce = this.p.parser.stateSlot(
2439
+ let { parser: parser2 } = this.p;
2440
+ let reduce = parser2.stateSlot(
2198
2441
  this.state,
2199
2442
  5
2200
2443
  /* ParseState.ForcedReduce */
2201
2444
  );
2202
2445
  if ((reduce & 65536) == 0)
2203
2446
  return false;
2204
- let { parser: parser2 } = this.p;
2205
2447
  if (!parser2.validAction(this.state, reduce)) {
2206
2448
  let depth = reduce >> 19, term = reduce & 65535;
2207
2449
  let target = this.stack.length - depth * 3;
2208
- if (target < 0 || parser2.getGoto(this.stack[target], term, false) < 0)
2209
- return false;
2210
- this.storeNode(0, this.reducePos, this.reducePos, 4, true);
2450
+ if (target < 0 || parser2.getGoto(this.stack[target], term, false) < 0) {
2451
+ let backup = this.findForcedReduction();
2452
+ if (backup == null)
2453
+ return false;
2454
+ reduce = backup;
2455
+ }
2456
+ this.storeNode(0, this.pos, this.pos, 4, true);
2211
2457
  this.score -= 100;
2212
2458
  }
2213
2459
  this.reducePos = this.pos;
2214
2460
  this.reduce(reduce);
2215
2461
  return true;
2216
2462
  }
2463
+ /// Try to scan through the automaton to find some kind of reduction
2464
+ /// that can be applied. Used when the regular ForcedReduce field
2465
+ /// isn't a valid action. @internal
2466
+ findForcedReduction() {
2467
+ let { parser: parser2 } = this.p, seen = [];
2468
+ let explore = (state, depth) => {
2469
+ if (seen.includes(state))
2470
+ return;
2471
+ seen.push(state);
2472
+ return parser2.allActions(state, (action) => {
2473
+ if (action & (262144 | 131072))
2474
+ ;
2475
+ else if (action & 65536) {
2476
+ let rDepth = (action >> 19) - depth;
2477
+ if (rDepth > 1) {
2478
+ let term = action & 65535, target = this.stack.length - rDepth * 3;
2479
+ if (target >= 0 && parser2.getGoto(this.stack[target], term, false) >= 0)
2480
+ return rDepth << 19 | 65536 | term;
2481
+ }
2482
+ } else {
2483
+ let found = explore(action, depth + 1);
2484
+ if (found != null)
2485
+ return found;
2486
+ }
2487
+ });
2488
+ };
2489
+ return explore(this.state, 0);
2490
+ }
2217
2491
  /// @internal
2218
2492
  forceAll() {
2219
2493
  while (!this.p.parser.stateFlag(
@@ -2282,13 +2556,13 @@ var Stack = class {
2282
2556
  emitContext() {
2283
2557
  let last = this.buffer.length - 1;
2284
2558
  if (last < 0 || this.buffer[last] != -3)
2285
- this.buffer.push(this.curContext.hash, this.reducePos, this.reducePos, -3);
2559
+ this.buffer.push(this.curContext.hash, this.pos, this.pos, -3);
2286
2560
  }
2287
2561
  /// @internal
2288
2562
  emitLookAhead() {
2289
2563
  let last = this.buffer.length - 1;
2290
2564
  if (last < 0 || this.buffer[last] != -4)
2291
- this.buffer.push(this.lookAhead, this.reducePos, this.reducePos, -4);
2565
+ this.buffer.push(this.lookAhead, this.pos, this.pos, -4);
2292
2566
  }
2293
2567
  updateContext(context) {
2294
2568
  if (context != this.curContext.context) {
@@ -2645,16 +2919,17 @@ var LocalTokenGroup = class {
2645
2919
  token(input, stack) {
2646
2920
  let start = input.pos, skipped = 0;
2647
2921
  for (; ; ) {
2922
+ let atEof = input.next < 0, nextPos = input.resolveOffset(1, 1);
2648
2923
  readToken(this.data, input, stack, 0, this.data, this.precTable);
2649
2924
  if (input.token.value > -1)
2650
2925
  break;
2651
2926
  if (this.elseToken == null)
2652
2927
  return;
2653
- if (input.next < 0)
2928
+ if (!atEof)
2929
+ skipped++;
2930
+ if (nextPos == null)
2654
2931
  break;
2655
- input.advance();
2656
- input.reset(input.pos, input.token);
2657
- skipped++;
2932
+ input.reset(nextPos, input.token);
2658
2933
  }
2659
2934
  if (skipped) {
2660
2935
  input.reset(start, input.token);
@@ -3367,26 +3642,30 @@ var LRParser = class extends Parser {
3367
3642
  }
3368
3643
  /// @internal
3369
3644
  validAction(state, action) {
3370
- if (action == this.stateSlot(
3645
+ return !!this.allActions(state, (a) => a == action ? true : null);
3646
+ }
3647
+ /// @internal
3648
+ allActions(state, action) {
3649
+ let deflt = this.stateSlot(
3371
3650
  state,
3372
3651
  4
3373
3652
  /* ParseState.DefaultReduce */
3374
- ))
3375
- return true;
3653
+ );
3654
+ let result = deflt ? action(deflt) : void 0;
3376
3655
  for (let i = this.stateSlot(
3377
3656
  state,
3378
3657
  1
3379
3658
  /* ParseState.Actions */
3380
- ); ; i += 3) {
3659
+ ); result == null; i += 3) {
3381
3660
  if (this.data[i] == 65535) {
3382
3661
  if (this.data[i + 1] == 1)
3383
3662
  i = pair(this.data, i + 2);
3384
3663
  else
3385
- return false;
3664
+ break;
3386
3665
  }
3387
- if (action == pair(this.data, i + 1))
3388
- return true;
3666
+ result = action(pair(this.data, i + 1));
3389
3667
  }
3668
+ return result;
3390
3669
  }
3391
3670
  /// Get the states that can follow this one through shift actions or
3392
3671
  /// goto jumps. @internal
@@ -3494,476 +3773,178 @@ var LRParser = class extends Parser {
3494
3773
  (disabled || (disabled = new Uint8Array(this.maxTerm + 1)))[id] = 1;
3495
3774
  }
3496
3775
  return new Dialect(dialect, flags, disabled);
3497
- }
3498
- /// Used by the output of the parser generator. Not available to
3499
- /// user code. @hide
3500
- static deserialize(spec) {
3501
- return new LRParser(spec);
3502
- }
3503
- };
3504
- function pair(data, off) {
3505
- return data[off] | data[off + 1] << 16;
3506
- }
3507
- function findFinished(stacks) {
3508
- let best = null;
3509
- for (let stack of stacks) {
3510
- let stopped = stack.p.stoppedAt;
3511
- if ((stack.pos == stack.p.stream.end || stopped != null && stack.pos > stopped) && stack.p.parser.stateFlag(
3512
- stack.state,
3513
- 2
3514
- /* StateFlag.Accepting */
3515
- ) && (!best || best.score < stack.score))
3516
- best = stack;
3517
- }
3518
- return best;
3519
- }
3520
- function getSpecializer(spec) {
3521
- if (spec.external) {
3522
- let mask = spec.extend ? 1 : 0;
3523
- return (value, stack) => spec.external(value, stack) << 1 | mask;
3524
- }
3525
- return spec.get;
3526
- }
3527
-
3528
- // ../vuu-filter-parser/src/generated/filter-parser.js
3529
- var parser = LRParser.deserialize({
3530
- version: 14,
3531
- states: "%QOVQPOOOOQO'#C_'#C_O_QQO'#C^OOQO'#DO'#DOOvQQO'#C|OOQO'#DR'#DROVQPO'#CuOOQO'#C}'#C}QOQPOOOOQO'#C`'#C`O!UQQO,58xO!dQPO,59VOVQPO,59]OVQPO,59_O!iQPO,59hO!nQQO,59aOOQO'#DQ'#DQOOQO1G.d1G.dO!UQQO1G.qO!yQQO1G.wOOQO1G.y1G.yOOQO'#Cw'#CwOOQO1G/S1G/SOOQO1G.{1G.{O#[QPO'#CnO#dQPO7+$]O!UQQO'#CxO#iQPO,59YOOQO<<Gw<<GwOOQO,59d,59dOOQO-E6v-E6v",
3532
- stateData: "#q~OoOS~OsPOvUO~OTXOUXOVXOWXOXXOYXO`ZO~Of[Oh]Oj^OmpX~OZ`O[`O]`O^`O~OabO~OseO~Of[Oh]OwgO~Oh]Ofeijeimeiwei~OcjOdbX~OdlO~OcjOdba~O",
3533
- goto: "#YvPPw}!TPPPPPPPPPPwPP!WPP!ZP!ZP!aP!g!jPPP!p!s!aP#P!aXROU[]XQOU[]RYQRibXTOU[]XVOU[]Rf^QkhRnkRWOQSOQ_UQc[Rd]QaYQhbRmj",
3534
- nodeNames: "\u26A0 Filter ColumnValueExpression Column Operator Eq NotEq Gt Lt Starts Ends Number String True False ColumnSetExpression In LBrack Values Comma RBrack AndExpression And OrExpression Or ParenthesizedExpression As FilterName",
3535
- maxTerm: 39,
3536
- skippedNodes: [0],
3537
- repeatNodeCount: 1,
3538
- tokenData: "6p~RnXY#PYZ#P]^#Ppq#Pqr#brs#mxy$eyz$j|}$o!O!P$t!Q![%S!^!_%_!_!`%d!`!a%i!c!}%n!}#O&V#P#Q&[#R#S%n#T#U&a#U#X%n#X#Y(w#Y#Z+]#Z#]%n#]#^.]#^#c%n#c#d/e#d#g%n#g#h0m#h#i4[#i#o%n~#USo~XY#PYZ#P]^#Ppq#P~#eP!_!`#h~#mOU~~#pWOX#mZ]#m^r#mrs$Ys#O#m#P;'S#m;'S;=`$_<%lO#m~$_O[~~$bP;=`<%l#m~$jOv~~$oOw~~$tOc~~$wP!Q![$z~%PPZ~!Q![$z~%XQZ~!O!P$t!Q![%S~%dOW~~%iOT~~%nOV~P%sUsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%n~&[Oa~~&aOd~R&fYsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c'U#c#g%n#g#h(^#h#o%nR'ZWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#W%n#W#X's#X#o%nR'zUfQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR(eUjQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR(|WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c)f#c#o%nR)kWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#W%n#W#X*T#X#o%nR*YWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h*r#h#o%nR*yUYQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR+bVsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#U+w#U#o%nR+|WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#`%n#`#a,f#a#o%nR,kWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h-T#h#o%nR-YWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#X%n#X#Y-r#Y#o%nR-yU^QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR.bWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c.z#c#o%nR/RU`QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR/jWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g0S#g#o%nR0ZUhQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR0rWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#h%n#h#i1[#i#o%nR1aVsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#U1v#U#o%nR1{WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g2e#g#o%nR2jWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#h%n#h#i3S#i#o%nR3XWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h3q#h#o%nR3xUXQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR4aWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g4y#g#o%nR5OWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#i%n#i#j5h#j#o%nR5mWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#X%n#X#Y6V#Y#o%nR6^U]QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%n",
3539
- tokenizers: [0, 1],
3540
- topRules: { "Filter": [0, 1] },
3541
- tokenPrec: 0
3542
- });
3543
-
3544
- // ../vuu-filter-parser/src/FilterTreeWalker.ts
3545
- import {
3546
- isMultiClauseFilter as isMultiClauseFilter2,
3547
- isMultiValueFilter as isMultiValueFilter2,
3548
- isSingleValueFilter as isSingleValueFilter2
3549
- } from "@vuu-ui/vuu-utils";
3550
- var _filter;
3551
- var FilterExpression = class {
3552
- constructor() {
3553
- __privateAdd(this, _filter, void 0);
3554
- }
3555
- setFilterCombinatorOp(op, filter = __privateGet(this, _filter)) {
3556
- if (isMultiClauseFilter2(filter) && filter.op === op) {
3557
- return;
3558
- } else {
3559
- __privateSet(this, _filter, {
3560
- op,
3561
- filters: [__privateGet(this, _filter)]
3562
- });
3563
- }
3564
- }
3565
- add(filter) {
3566
- if (__privateGet(this, _filter) === void 0) {
3567
- __privateSet(this, _filter, filter);
3568
- } else if (isMultiClauseFilter2(__privateGet(this, _filter))) {
3569
- __privateGet(this, _filter).filters.push(filter);
3570
- } else {
3571
- throw Error(`Invalid filter passed to FilterExpression`);
3572
- }
3573
- }
3574
- setColumn(column, filter = __privateGet(this, _filter)) {
3575
- if (isMultiClauseFilter2(filter)) {
3576
- const target = filter.filters.at(-1);
3577
- if (target) {
3578
- this.setColumn(column, target);
3579
- }
3580
- } else if (filter) {
3581
- filter.column = column;
3582
- }
3583
- }
3584
- setOp(value, filter = __privateGet(this, _filter)) {
3585
- if (isMultiClauseFilter2(filter)) {
3586
- const target = filter.filters.at(-1);
3587
- if (target) {
3588
- this.setOp(value, target);
3589
- }
3590
- } else if (filter) {
3591
- filter.op = value;
3592
- }
3593
- }
3594
- setValue(value, filter = __privateGet(this, _filter)) {
3595
- var _a;
3596
- if (isMultiClauseFilter2(filter)) {
3597
- const target = filter.filters.at(-1);
3598
- if (target) {
3599
- this.setValue(value, target);
3600
- }
3601
- } else if (isMultiValueFilter2(filter)) {
3602
- (_a = filter.values) != null ? _a : filter.values = [];
3603
- filter.values.push(value);
3604
- } else if (isSingleValueFilter2(filter)) {
3605
- filter.value = value;
3606
- }
3607
- }
3608
- toJSON(filter = __privateGet(this, _filter)) {
3609
- if (this.name) {
3610
- return {
3611
- ...filter,
3612
- name: this.name
3613
- };
3614
- } else {
3615
- return filter;
3616
- }
3617
- }
3618
- };
3619
- _filter = new WeakMap();
3620
- var walkTree = (tree, source) => {
3621
- const filterExpression = new FilterExpression();
3622
- const cursor = tree.cursor();
3623
- do {
3624
- const { name, from, to } = cursor;
3625
- switch (name) {
3626
- case "ColumnValueExpression":
3627
- filterExpression.add({});
3628
- break;
3629
- case "ColumnSetExpression":
3630
- filterExpression.add({ op: "in" });
3631
- break;
3632
- case "Or":
3633
- case "And":
3634
- filterExpression.setFilterCombinatorOp(source.substring(from, to));
3635
- break;
3636
- case "Column":
3637
- filterExpression.setColumn(source.substring(from, to));
3638
- break;
3639
- case "Operator":
3640
- filterExpression.setOp(source.substring(from, to));
3641
- break;
3642
- case "String":
3643
- filterExpression.setValue(source.substring(from + 1, to - 1));
3644
- break;
3645
- case "Number":
3646
- filterExpression.setValue(parseFloat(source.substring(from, to)));
3647
- break;
3648
- case "True":
3649
- filterExpression.setValue(true);
3650
- break;
3651
- case "False":
3652
- filterExpression.setValue(false);
3653
- break;
3654
- case "FilterName":
3655
- filterExpression.name = source.substring(from, to);
3656
- break;
3657
- default:
3658
- }
3659
- } while (cursor.next());
3660
- return filterExpression.toJSON();
3661
- };
3662
-
3663
- // ../vuu-filter-parser/src/FilterParser.ts
3664
- var strictParser = parser.configure({ strict: true });
3665
-
3666
- // ../vuu-data-react/src/hooks/useVuuMenuActions.ts
3667
- import {
3668
- getRowRecord,
3669
- isGroupMenuItemDescriptor,
3670
- metadataKeys as metadataKeys2
3671
- } from "@vuu-ui/vuu-utils";
3672
- import { useCallback as useCallback5 } from "react";
3673
- var { KEY } = metadataKeys2;
3674
-
3675
- // ../vuu-data-react/src/hooks/useVuuTables.ts
3676
- import { useCallback as useCallback6, useEffect as useEffect4, useState as useState4 } from "react";
3677
- import { getServerAPI } from "@vuu-ui/vuu-data";
3678
-
3679
- // src/column-filter/TypeaheadFilter.tsx
3680
- import { ComboBoxDeprecated } from "@heswell/salt-lab";
3681
- import { useCallback as useCallback7, useEffect as useEffect5, useState as useState5 } from "react";
3682
- import { jsx as jsx4 } from "react/jsx-runtime";
3683
- var TypeaheadFilter = ({
3684
- defaultTypeaheadParams,
3685
- filterValues = [],
3686
- onChange: onFilterChange
3687
- }) => {
3688
- const [tableName, columnName] = defaultTypeaheadParams;
3689
- const [searchValue, setSearchValue] = useState5("");
3690
- const [typeaheadValues, setTypeaheadValues] = useState5([]);
3691
- const getSuggestions = useTypeaheadSuggestions();
3692
- useEffect5(() => {
3693
- const params = searchValue ? [tableName, columnName, searchValue] : defaultTypeaheadParams;
3694
- let isSubscribed = true;
3695
- getSuggestions(params).then((options) => {
3696
- if (!isSubscribed) {
3697
- return;
3698
- }
3699
- if (isStartsWithValue(filterValues[0])) {
3700
- options.unshift(filterValues[0]);
3701
- }
3702
- if (searchValue) {
3703
- options.unshift(`${searchValue}...`);
3704
- }
3705
- options.concat(filterValues);
3706
- setTypeaheadValues(options);
3707
- });
3708
- return () => {
3709
- isSubscribed = false;
3710
- };
3711
- }, [
3712
- filterValues,
3713
- searchValue,
3714
- columnName,
3715
- tableName,
3716
- getSuggestions,
3717
- defaultTypeaheadParams
3718
- ]);
3719
- const onInputChange = useCallback7(
3720
- (evt) => {
3721
- const value = evt.target.value;
3722
- setSearchValue(value);
3723
- },
3724
- []
3725
- );
3726
- const onSelectionChange = useCallback7(
3727
- (_evt, selected) => {
3728
- setSearchValue("");
3729
- if (selected === null)
3730
- return;
3731
- if (selected.some(isStartsWithValue)) {
3732
- selected = selected.filter(isStartsWithValue).slice(-1);
3733
- }
3734
- const filter = getTypeaheadFilter(
3735
- columnName,
3736
- selected,
3737
- isStartsWithValue(selected[0])
3738
- );
3739
- onFilterChange(selected, filter);
3740
- },
3741
- [columnName, onFilterChange]
3742
- );
3743
- return /* @__PURE__ */ jsx4(
3744
- ComboBoxDeprecated,
3745
- {
3746
- multiSelect: true,
3747
- onInputChange,
3748
- onChange: onSelectionChange,
3749
- source: typeaheadValues,
3750
- style: { minWidth: 200 },
3751
- inputValue: searchValue,
3752
- selectedItem: filterValues
3753
- },
3754
- columnName
3755
- );
3756
- };
3757
-
3758
- // src/column-filter/ColumnListItem.tsx
3759
- import { memo } from "react";
3760
- import {
3761
- Highlighter,
3762
- ListItem
3763
- } from "@heswell/salt-lab";
3764
- import { jsx as jsx5 } from "react/jsx-runtime";
3765
- var ColumnListItem = (props) => {
3766
- return /* @__PURE__ */ jsx5(MemoColumnItem, { ...props });
3767
- };
3768
- var MemoColumnItem = memo(function MemoizedItem({
3769
- item,
3770
- itemTextHighlightPattern,
3771
- ...restProps
3772
- }) {
3773
- return /* @__PURE__ */ jsx5(ListItem, { ...restProps, children: /* @__PURE__ */ jsx5("span", { style: { marginLeft: 10 }, children: /* @__PURE__ */ jsx5(
3774
- Highlighter,
3775
- {
3776
- matchPattern: itemTextHighlightPattern,
3777
- text: item == null ? void 0 : item.name
3778
- }
3779
- ) }) });
3780
- });
3781
-
3782
- // src/column-filter/useColumnFilterStore.ts
3783
- import { filterAsQuery as filterAsQuery2 } from "@vuu-ui/vuu-utils";
3784
- import { useCallback as useCallback8, useState as useState6 } from "react";
3785
- var addOrReplace = (array, newValue, key) => array.filter((oldValue) => oldValue[key] !== newValue[key]).concat(newValue);
3786
- var useColumnFilterStore = (onFilterSubmit) => {
3787
- var _a, _b;
3788
- const [selectedColumnName, setSelectedColumnName] = useState6("");
3789
- const [savedFilters, setSavedFilters] = useState6([]);
3790
- const [rangeValues, setRangeValues] = useState6([]);
3791
- const [typeaheadValues, setTypeaheadValues] = useState6([]);
3792
- const clear = () => {
3793
- setSelectedColumnName("");
3794
- setRangeValues([]);
3795
- setTypeaheadValues([]);
3796
- setSavedFilters([]);
3797
- onFilterSubmit({ filter: "" });
3798
- };
3799
- const updateFilters = useCallback8(
3800
- (newFilter) => {
3801
- const newSavedFilters = addOrReplace(
3802
- savedFilters,
3803
- { column: selectedColumnName, filter: newFilter },
3804
- "column"
3805
- );
3806
- setSavedFilters(newSavedFilters);
3807
- const combinedFilter = newSavedFilters.map((x) => x.filter).reduce((prev, filter) => {
3808
- if (filter === void 0)
3809
- return prev;
3810
- return addFilter(prev, filter, { combineWith: AND });
3811
- }, void 0);
3812
- const query = combinedFilter === void 0 ? "" : filterAsQuery2(combinedFilter);
3813
- onFilterSubmit({ filter: query, filterStruct: combinedFilter });
3814
- },
3815
- [selectedColumnName, onFilterSubmit, savedFilters]
3816
- );
3817
- const onTypeaheadChange = useCallback8(
3818
- (newValues, newFilter) => {
3819
- setTypeaheadValues(
3820
- addOrReplace(
3821
- typeaheadValues,
3822
- { column: selectedColumnName, value: newValues },
3823
- "column"
3824
- )
3825
- );
3826
- updateFilters(newFilter);
3827
- },
3828
- [selectedColumnName, typeaheadValues, updateFilters]
3829
- );
3830
- const onRangeChange = useCallback8(
3831
- (newValues, newFilter) => {
3832
- setRangeValues(
3833
- addOrReplace(
3834
- rangeValues,
3835
- { column: selectedColumnName, value: newValues },
3836
- "column"
3837
- )
3838
- );
3839
- updateFilters(newFilter);
3840
- },
3841
- [selectedColumnName, rangeValues, updateFilters]
3842
- );
3843
- const onSelectedColumnChange = useCallback8(
3844
- (column) => setSelectedColumnName((column == null ? void 0 : column.name) || ""),
3845
- []
3846
- );
3847
- const rangeValue = (_a = rangeValues.filter(
3848
- (v) => v.column === selectedColumnName
3849
- )[0]) == null ? void 0 : _a.value;
3850
- const typeaheadValue = (_b = typeaheadValues.filter(
3851
- (v) => v.column === selectedColumnName
3852
- )[0]) == null ? void 0 : _b.value;
3853
- return {
3854
- clear,
3855
- selectedColumnName,
3856
- rangeValue,
3857
- typeaheadValue,
3858
- onSelectedColumnChange,
3859
- onRangeChange,
3860
- onTypeaheadChange
3861
- };
3776
+ }
3777
+ /// Used by the output of the parser generator. Not available to
3778
+ /// user code. @hide
3779
+ static deserialize(spec) {
3780
+ return new LRParser(spec);
3781
+ }
3862
3782
  };
3783
+ function pair(data, off) {
3784
+ return data[off] | data[off + 1] << 16;
3785
+ }
3786
+ function findFinished(stacks) {
3787
+ let best = null;
3788
+ for (let stack of stacks) {
3789
+ let stopped = stack.p.stoppedAt;
3790
+ if ((stack.pos == stack.p.stream.end || stopped != null && stack.pos > stopped) && stack.p.parser.stateFlag(
3791
+ stack.state,
3792
+ 2
3793
+ /* StateFlag.Accepting */
3794
+ ) && (!best || best.score < stack.score))
3795
+ best = stack;
3796
+ }
3797
+ return best;
3798
+ }
3799
+ function getSpecializer(spec) {
3800
+ if (spec.external) {
3801
+ let mask = spec.extend ? 1 : 0;
3802
+ return (value, stack) => spec.external(value, stack) << 1 | mask;
3803
+ }
3804
+ return spec.get;
3805
+ }
3863
3806
 
3864
- // src/column-filter/ColumnFilter.tsx
3865
- import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
3866
- var ColumnFilter = ({
3867
- className,
3868
- table,
3869
- columns,
3870
- onFilterSubmit,
3871
- ...htmlAttributes
3872
- }) => {
3873
- const {
3874
- clear,
3875
- onTypeaheadChange,
3876
- onRangeChange,
3877
- onSelectedColumnChange,
3878
- selectedColumnName,
3879
- rangeValue,
3880
- typeaheadValue
3881
- } = useColumnFilterStore(onFilterSubmit);
3882
- const getFilterComponent = () => {
3807
+ // ../vuu-filter-parser/src/generated/filter-parser.js
3808
+ var parser = LRParser.deserialize({
3809
+ version: 14,
3810
+ states: "%QOVQPOOOOQO'#C_'#C_O_QQO'#C^OOQO'#DO'#DOOvQQO'#C|OOQO'#DR'#DROVQPO'#CuOOQO'#C}'#C}QOQPOOOOQO'#C`'#C`O!UQQO,58xO!dQPO,59VOVQPO,59]OVQPO,59_O!iQPO,59hO!nQQO,59aOOQO'#DQ'#DQOOQO1G.d1G.dO!UQQO1G.qO!yQQO1G.wOOQO1G.y1G.yOOQO'#Cw'#CwOOQO1G/S1G/SOOQO1G.{1G.{O#[QPO'#CnO#dQPO7+$]O!UQQO'#CxO#iQPO,59YOOQO<<Gw<<GwOOQO,59d,59dOOQO-E6v-E6v",
3811
+ stateData: "#q~OoOS~OsPOvUO~OTXOUXOVXOWXOXXOYXO`ZO~Of[Oh]Oj^OmpX~OZ`O[`O]`O^`O~OabO~OseO~Of[Oh]OwgO~Oh]Ofeijeimeiwei~OcjOdbX~OdlO~OcjOdba~O",
3812
+ goto: "#YvPPw}!TPPPPPPPPPPwPP!WPP!ZP!ZP!aP!g!jPPP!p!s!aP#P!aXROU[]XQOU[]RYQRibXTOU[]XVOU[]Rf^QkhRnkRWOQSOQ_UQc[Rd]QaYQhbRmj",
3813
+ nodeNames: "\u26A0 Filter ColumnValueExpression Column Operator Eq NotEq Gt Lt Starts Ends Number String True False ColumnSetExpression In LBrack Values Comma RBrack AndExpression And OrExpression Or ParenthesizedExpression As FilterName",
3814
+ maxTerm: 39,
3815
+ skippedNodes: [0],
3816
+ repeatNodeCount: 1,
3817
+ tokenData: "6p~RnXY#PYZ#P]^#Ppq#Pqr#brs#mxy$eyz$j|}$o!O!P$t!Q![%S!^!_%_!_!`%d!`!a%i!c!}%n!}#O&V#P#Q&[#R#S%n#T#U&a#U#X%n#X#Y(w#Y#Z+]#Z#]%n#]#^.]#^#c%n#c#d/e#d#g%n#g#h0m#h#i4[#i#o%n~#USo~XY#PYZ#P]^#Ppq#P~#eP!_!`#h~#mOU~~#pWOX#mZ]#m^r#mrs$Ys#O#m#P;'S#m;'S;=`$_<%lO#m~$_O[~~$bP;=`<%l#m~$jOv~~$oOw~~$tOc~~$wP!Q![$z~%PPZ~!Q![$z~%XQZ~!O!P$t!Q![%S~%dOW~~%iOT~~%nOV~P%sUsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%n~&[Oa~~&aOd~R&fYsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c'U#c#g%n#g#h(^#h#o%nR'ZWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#W%n#W#X's#X#o%nR'zUfQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR(eUjQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR(|WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c)f#c#o%nR)kWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#W%n#W#X*T#X#o%nR*YWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h*r#h#o%nR*yUYQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR+bVsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#U+w#U#o%nR+|WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#`%n#`#a,f#a#o%nR,kWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h-T#h#o%nR-YWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#X%n#X#Y-r#Y#o%nR-yU^QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR.bWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c.z#c#o%nR/RU`QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR/jWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g0S#g#o%nR0ZUhQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR0rWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#h%n#h#i1[#i#o%nR1aVsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#U1v#U#o%nR1{WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g2e#g#o%nR2jWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#h%n#h#i3S#i#o%nR3XWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h3q#h#o%nR3xUXQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR4aWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g4y#g#o%nR5OWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#i%n#i#j5h#j#o%nR5mWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#X%n#X#Y6V#Y#o%nR6^U]QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%n",
3818
+ tokenizers: [0, 1],
3819
+ topRules: { "Filter": [0, 1] },
3820
+ tokenPrec: 0
3821
+ });
3822
+
3823
+ // ../vuu-filter-parser/src/FilterTreeWalker.ts
3824
+ import {
3825
+ isMultiClauseFilter as isMultiClauseFilter2,
3826
+ isMultiValueFilter as isMultiValueFilter2,
3827
+ isSingleValueFilter as isSingleValueFilter2
3828
+ } from "@vuu-ui/vuu-utils";
3829
+ var _filter;
3830
+ var FilterExpression = class {
3831
+ constructor() {
3832
+ __privateAdd(this, _filter, void 0);
3833
+ }
3834
+ setFilterCombinatorOp(op, filter = __privateGet(this, _filter)) {
3835
+ if (isMultiClauseFilter2(filter) && filter.op === op) {
3836
+ return;
3837
+ } else {
3838
+ __privateSet(this, _filter, {
3839
+ op,
3840
+ filters: [__privateGet(this, _filter)]
3841
+ });
3842
+ }
3843
+ }
3844
+ add(filter) {
3845
+ if (__privateGet(this, _filter) === void 0) {
3846
+ __privateSet(this, _filter, filter);
3847
+ } else if (isMultiClauseFilter2(__privateGet(this, _filter))) {
3848
+ __privateGet(this, _filter).filters.push(filter);
3849
+ } else {
3850
+ throw Error(`Invalid filter passed to FilterExpression`);
3851
+ }
3852
+ }
3853
+ setColumn(column, filter = __privateGet(this, _filter)) {
3854
+ if (isMultiClauseFilter2(filter)) {
3855
+ const target = filter.filters.at(-1);
3856
+ if (target) {
3857
+ this.setColumn(column, target);
3858
+ }
3859
+ } else if (filter) {
3860
+ filter.column = column;
3861
+ }
3862
+ }
3863
+ setOp(value, filter = __privateGet(this, _filter)) {
3864
+ if (isMultiClauseFilter2(filter)) {
3865
+ const target = filter.filters.at(-1);
3866
+ if (target) {
3867
+ this.setOp(value, target);
3868
+ }
3869
+ } else if (filter) {
3870
+ filter.op = value;
3871
+ }
3872
+ }
3873
+ setValue(value, filter = __privateGet(this, _filter)) {
3883
3874
  var _a;
3884
- const defaultTypeaheadParams = [table, selectedColumnName];
3885
- const selectedColumnType = (_a = columns.find(
3886
- (column) => column.name === selectedColumnName
3887
- )) == null ? void 0 : _a.serverDataType;
3888
- switch (selectedColumnType) {
3889
- case "string":
3890
- case "char":
3891
- return /* @__PURE__ */ jsx6(
3892
- ToolbarField2,
3893
- {
3894
- label: "Start typing to select a filter",
3895
- labelPlacement: "top",
3896
- children: /* @__PURE__ */ jsx6(
3897
- TypeaheadFilter,
3898
- {
3899
- defaultTypeaheadParams,
3900
- filterValues: typeaheadValue,
3901
- onChange: onTypeaheadChange
3902
- }
3903
- )
3904
- }
3905
- );
3906
- case "int":
3907
- case "long":
3908
- case "double":
3909
- return /* @__PURE__ */ jsx6(ToolbarField2, { label: "Select a range", labelPlacement: "top", children: /* @__PURE__ */ jsx6(
3910
- RangeFilter,
3911
- {
3912
- defaultTypeaheadParams,
3913
- filterValues: rangeValue,
3914
- onChange: onRangeChange
3915
- }
3916
- ) });
3917
- default:
3918
- return /* @__PURE__ */ jsx6(ToolbarField2, { children: /* @__PURE__ */ jsx6(Text, { children: "Data type unsupported" }) });
3875
+ if (isMultiClauseFilter2(filter)) {
3876
+ const target = filter.filters.at(-1);
3877
+ if (target) {
3878
+ this.setValue(value, target);
3879
+ }
3880
+ } else if (isMultiValueFilter2(filter)) {
3881
+ (_a = filter.values) != null ? _a : filter.values = [];
3882
+ filter.values.push(value);
3883
+ } else if (isSingleValueFilter2(filter)) {
3884
+ filter.value = value;
3919
3885
  }
3920
- };
3921
- return /* @__PURE__ */ jsxs3(
3922
- Toolbar,
3923
- {
3924
- ...htmlAttributes,
3925
- style: { alignItems: "center", height: "36px" },
3926
- children: [
3927
- /* @__PURE__ */ jsx6(
3928
- ToolbarField2,
3929
- {
3930
- label: "Select a column to filter",
3931
- labelPlacement: "top",
3932
- style: { width: 180 },
3933
- children: /* @__PURE__ */ jsx6(
3934
- Dropdown,
3935
- {
3936
- source: columns,
3937
- ListItem: ColumnListItem,
3938
- itemToString: (column) => column.name,
3939
- onSelectionChange: (_evt, column) => onSelectedColumnChange(column)
3940
- }
3941
- )
3942
- }
3943
- ),
3944
- selectedColumnName && getFilterComponent(),
3945
- /* @__PURE__ */ jsx6(ToolbarButton, { onClick: clear, children: /* @__PURE__ */ jsx6(DeleteIcon, {}) })
3946
- ]
3886
+ }
3887
+ toJSON(filter = __privateGet(this, _filter)) {
3888
+ if (this.name) {
3889
+ return {
3890
+ ...filter,
3891
+ name: this.name
3892
+ };
3893
+ } else {
3894
+ return filter;
3947
3895
  }
3948
- );
3896
+ }
3897
+ };
3898
+ _filter = new WeakMap();
3899
+ var walkTree = (tree, source) => {
3900
+ const filterExpression = new FilterExpression();
3901
+ const cursor = tree.cursor();
3902
+ do {
3903
+ const { name, from, to } = cursor;
3904
+ switch (name) {
3905
+ case "ColumnValueExpression":
3906
+ filterExpression.add({});
3907
+ break;
3908
+ case "ColumnSetExpression":
3909
+ filterExpression.add({ op: "in" });
3910
+ break;
3911
+ case "Or":
3912
+ case "And":
3913
+ filterExpression.setFilterCombinatorOp(source.substring(from, to));
3914
+ break;
3915
+ case "Column":
3916
+ filterExpression.setColumn(source.substring(from, to));
3917
+ break;
3918
+ case "Operator":
3919
+ filterExpression.setOp(source.substring(from, to));
3920
+ break;
3921
+ case "String":
3922
+ filterExpression.setValue(source.substring(from + 1, to - 1));
3923
+ break;
3924
+ case "Number":
3925
+ filterExpression.setValue(parseFloat(source.substring(from, to)));
3926
+ break;
3927
+ case "True":
3928
+ filterExpression.setValue(true);
3929
+ break;
3930
+ case "False":
3931
+ filterExpression.setValue(false);
3932
+ break;
3933
+ case "FilterName":
3934
+ filterExpression.name = source.substring(from, to);
3935
+ break;
3936
+ default:
3937
+ }
3938
+ } while (cursor.next());
3939
+ return filterExpression.toJSON();
3949
3940
  };
3950
3941
 
3951
- // src/filter-input/FilterInput.tsx
3952
- import { Button } from "@salt-ds/core";
3942
+ // ../vuu-filter-parser/src/FilterParser.ts
3943
+ var strictParser = parser.configure({ strict: true });
3953
3944
 
3954
3945
  // src/filter-input/useCodeMirrorEditor.ts
3955
- import {
3956
- autocompletion,
3957
- defaultKeymap,
3958
- EditorState as EditorState2,
3959
- EditorView as EditorView2,
3960
- ensureSyntaxTree,
3961
- keymap,
3962
- minimalSetup,
3963
- startCompletion
3964
- } from "@vuu-ui/vuu-codemirror";
3965
3946
  var import_classnames = __toESM(require_classnames(), 1);
3966
- import { useEffect as useEffect6, useMemo as useMemo2, useRef as useRef2 } from "react";
3947
+ import { useEffect as useEffect2, useMemo, useRef } from "react";
3967
3948
 
3968
3949
  // src/filter-input/FilterLanguage.ts
3969
3950
  import {
@@ -4081,7 +4062,7 @@ import {
4081
4062
  getValue,
4082
4063
  syntaxTree
4083
4064
  } from "@vuu-ui/vuu-codemirror";
4084
- import { useCallback as useCallback9 } from "react";
4065
+ import { useCallback as useCallback3 } from "react";
4085
4066
  var getOperator = (node, state) => {
4086
4067
  let maybeColumnNode = node.prevSibling || node.parent;
4087
4068
  while (maybeColumnNode && !["Column", "Operator", "In"].includes(maybeColumnNode.name)) {
@@ -4151,7 +4132,7 @@ var getSetValues = (node, state) => {
4151
4132
  return values;
4152
4133
  };
4153
4134
  var useAutoComplete = (suggestionProvider, onSubmit, existingFilter) => {
4154
- const makeSuggestions = useCallback9(
4135
+ const makeSuggestions = useCallback3(
4155
4136
  async (context, suggestionType, optionalArgs = {}) => {
4156
4137
  const { startsWith = "" } = optionalArgs;
4157
4138
  const options = await suggestionProvider.getSuggestions(
@@ -4162,7 +4143,7 @@ var useAutoComplete = (suggestionProvider, onSubmit, existingFilter) => {
4162
4143
  },
4163
4144
  [suggestionProvider]
4164
4145
  );
4165
- return useCallback9(
4146
+ return useCallback3(
4166
4147
  async (context) => {
4167
4148
  var _a, _b;
4168
4149
  const { state, pos } = context;
@@ -4346,15 +4327,15 @@ var useCodeMirrorEditor = ({
4346
4327
  onSubmitFilter,
4347
4328
  suggestionProvider
4348
4329
  }) => {
4349
- const editorRef = useRef2(null);
4350
- const onSubmit = useRef2(noop);
4351
- const viewRef = useRef2();
4330
+ const editorRef = useRef(null);
4331
+ const onSubmit = useRef(noop);
4332
+ const viewRef = useRef();
4352
4333
  const completionFn = useAutoComplete(
4353
4334
  suggestionProvider,
4354
4335
  onSubmit,
4355
4336
  existingFilter
4356
4337
  );
4357
- const [createState, clearInput] = useMemo2(() => {
4338
+ const [createState, clearInput] = useMemo(() => {
4358
4339
  const parseFilter2 = () => {
4359
4340
  const view = getView(viewRef);
4360
4341
  const source = view.state.doc.toString();
@@ -4429,7 +4410,7 @@ var useCodeMirrorEditor = ({
4429
4410
  };
4430
4411
  return [createState2, clearInput2];
4431
4412
  }, [completionFn, onSubmitFilter]);
4432
- useEffect6(() => {
4413
+ useEffect2(() => {
4433
4414
  if (!editorRef.current) {
4434
4415
  throw Error("editor not in dom");
4435
4416
  }
@@ -4491,7 +4472,11 @@ import {
4491
4472
  stringOperators,
4492
4473
  toSuggestions
4493
4474
  } from "@vuu-ui/vuu-codemirror";
4494
- import { useCallback as useCallback10, useRef as useRef3 } from "react";
4475
+ import {
4476
+ getTypeaheadParams,
4477
+ useTypeaheadSuggestions as useTypeaheadSuggestions2
4478
+ } from "@vuu-ui/vuu-data-react";
4479
+ import { useCallback as useCallback4, useRef as useRef2 } from "react";
4495
4480
 
4496
4481
  // src/filter-input/filterInfo.ts
4497
4482
  import { createEl } from "@vuu-ui/vuu-utils";
@@ -4585,11 +4570,11 @@ var useFilterSuggestionProvider = ({
4585
4570
  namedFilters,
4586
4571
  saveOptions = defaultSaveOptions,
4587
4572
  table,
4588
- typeaheadHook: useTypeahead = useTypeaheadSuggestions
4573
+ typeaheadHook: useTypeahead = useTypeaheadSuggestions2
4589
4574
  }) => {
4590
- const latestSuggestionsRef = useRef3();
4575
+ const latestSuggestionsRef = useRef2();
4591
4576
  const getTypeaheadSuggestions = useTypeahead();
4592
- const getSuggestions = useCallback10(
4577
+ const getSuggestions = useCallback4(
4593
4578
  async (suggestionType, options = NONE) => {
4594
4579
  const {
4595
4580
  columnName,
@@ -4679,7 +4664,7 @@ var useFilterSuggestionProvider = ({
4679
4664
  },
4680
4665
  [columns, getTypeaheadSuggestions, namedFilters, saveOptions, table]
4681
4666
  );
4682
- const isPartialMatch = useCallback10(
4667
+ const isPartialMatch = useCallback4(
4683
4668
  async (valueType, columnName, pattern) => {
4684
4669
  const suggestions = (
4685
4670
  // latestSuggestions && latestSuggestions.length > 0
@@ -4719,7 +4704,7 @@ import { ToggleButton, ToolbarField as ToolbarField3 } from "@heswell/salt-lab";
4719
4704
 
4720
4705
  // src/filter-toolbar/FilterDropdown.tsx
4721
4706
  import { Dropdown as Dropdown2 } from "@heswell/salt-lab";
4722
- import { useCallback as useCallback11, useState as useState7 } from "react";
4707
+ import { useCallback as useCallback5, useState as useState3 } from "react";
4723
4708
  import { jsx as jsx8 } from "react/jsx-runtime";
4724
4709
  var isString = (s) => typeof s === "string";
4725
4710
  var stripQuotes = (selected) => {
@@ -4741,9 +4726,9 @@ var FilterDropdown = ({
4741
4726
  }) => {
4742
4727
  const selected = selectedProp != null ? stripQuotes(selectedProp) : void 0;
4743
4728
  const initialValues = Array.isArray(selected) ? selected : selected != null ? [selected] : [];
4744
- const [values, setValues] = useState7(initialValues);
4729
+ const [values, setValues] = useState3(initialValues);
4745
4730
  console.log({ initialValues });
4746
- const handleOpenChange = useCallback11(
4731
+ const handleOpenChange = useCallback5(
4747
4732
  async (isOpen) => {
4748
4733
  if (isOpen) {
4749
4734
  const values2 = await suggestionProvider.getSuggestions("columnValue", {
@@ -4768,7 +4753,7 @@ var FilterDropdown = ({
4768
4753
 
4769
4754
  // src/filter-toolbar/FilterDropdownMultiSelect.tsx
4770
4755
  import { Dropdown as Dropdown3 } from "@heswell/salt-lab";
4771
- import { useCallback as useCallback12, useState as useState8 } from "react";
4756
+ import { useCallback as useCallback6, useState as useState4 } from "react";
4772
4757
  import { jsx as jsx9 } from "react/jsx-runtime";
4773
4758
  var isString2 = (s) => typeof s === "string";
4774
4759
  var stripQuotes2 = (selected) => {
@@ -4792,8 +4777,8 @@ var FilterDropdownMultiSelect = ({
4792
4777
  }) => {
4793
4778
  const selected = stripQuotes2(selectedProp);
4794
4779
  const initialValues = Array.isArray(selected) ? selected : selected != null ? [selected] : [];
4795
- const [values, setValues] = useState8(initialValues);
4796
- const handleOpenChange = useCallback12(
4780
+ const [values, setValues] = useState4(initialValues);
4781
+ const handleOpenChange = useCallback6(
4797
4782
  async (isOpen) => {
4798
4783
  if (isOpen) {
4799
4784
  const values2 = await suggestionProvider.getSuggestions("columnValue", {