search-gold 0.9.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -11
- package/package.json +1 -1
- package/src/search.ts +17 -4
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
|
|
41
41
|
This wrapper method only needs to be called in the following two cases:
|
|
42
42
|
|
|
43
|
-
* when component is initialized and when data is ready
|
|
43
|
+
* when component is initialized and when data is ready
|
|
44
44
|
* when data changes (record has been created, edited, deleted)
|
|
45
45
|
|
|
46
46
|
You can name this wrapper method anything you want.
|
|
@@ -52,7 +52,7 @@ const initSearchConfig = () => {
|
|
|
52
52
|
// objects.
|
|
53
53
|
//
|
|
54
54
|
// 'search-gold' package only reads this data.
|
|
55
|
-
//
|
|
55
|
+
// Search results are returned in a separate array.
|
|
56
56
|
items: MyData,
|
|
57
57
|
|
|
58
58
|
// required: keys are the object properties you
|
|
@@ -62,7 +62,14 @@ const initSearchConfig = () => {
|
|
|
62
62
|
|
|
63
63
|
// optional: default is false
|
|
64
64
|
caseSensitive: true,
|
|
65
|
-
|
|
65
|
+
|
|
66
|
+
// optional: default is true
|
|
67
|
+
//
|
|
68
|
+
// You should only ever consider disabling
|
|
69
|
+
// memoization if you observe browser memory
|
|
70
|
+
// limitations with cached search results.
|
|
71
|
+
enableMemoize: false,
|
|
72
|
+
}
|
|
66
73
|
|
|
67
74
|
// Call the imported method with config arg.
|
|
68
75
|
searchSetConfig(config)
|
|
@@ -71,12 +78,14 @@ const initSearchConfig = () => {
|
|
|
71
78
|
// as many times as necessary without having to set the
|
|
72
79
|
// config again.
|
|
73
80
|
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
81
|
+
// Your template would be iterating over myFilteredData
|
|
82
|
+
// in this example.
|
|
76
83
|
//
|
|
77
84
|
// How you set up your component to display the filtered
|
|
78
85
|
// data is up to you and how your component is structured.
|
|
79
|
-
//
|
|
86
|
+
//
|
|
87
|
+
// Passing an empty string effectively returns the
|
|
88
|
+
// the unfiltered set of records, the same as MyData.
|
|
80
89
|
myFilteredData = <ItemRecord[]>searchHandler('')
|
|
81
90
|
}
|
|
82
91
|
````
|
|
@@ -87,7 +96,7 @@ This method (from Step 2.) should be called when your component has been
|
|
|
87
96
|
initialized and your data is ready.
|
|
88
97
|
|
|
89
98
|
Also, this `initSearchConfig()` method should be called whenever your
|
|
90
|
-
data changes
|
|
99
|
+
data changes after a record has been created, edited, or deleted.
|
|
91
100
|
|
|
92
101
|
```javascript
|
|
93
102
|
// For this example we chose this method name; you
|
|
@@ -98,9 +107,9 @@ initSearchConfig()
|
|
|
98
107
|
### 4. Execute search queries and get results.
|
|
99
108
|
|
|
100
109
|
Presumably, a method is binded to the UI's search field (in this example it's called
|
|
101
|
-
`searchMyData`) and is called on every keystroke
|
|
102
|
-
|
|
103
|
-
|
|
110
|
+
`searchMyData`) and is called on every keystroke, debounced keystrokes, or an explicit
|
|
111
|
+
and separate submit event. Ultimately, the UX behavior is left up to the front end
|
|
112
|
+
engineer / design team.
|
|
104
113
|
```javascript
|
|
105
114
|
const searchMyData = (query: string) => {
|
|
106
115
|
// Call the imported method and get results.
|
|
@@ -111,10 +120,11 @@ const searchMyData = (query: string) => {
|
|
|
111
120
|
## Author's Development
|
|
112
121
|
|
|
113
122
|
During development of the `search-gold` package, I integrated it
|
|
114
|
-
into
|
|
123
|
+
into several apps I had previously created with Vue using its Composition API.
|
|
115
124
|
|
|
116
125
|
In this documentation I tried to keep the Usage code snippets framework neutral.
|
|
117
126
|
|
|
127
|
+
`search-gold` itself is framework neutral and should work in any TS codebase.
|
|
118
128
|
# Credits
|
|
119
129
|
|
|
120
130
|
G. Gold
|
package/package.json
CHANGED
package/src/search.ts
CHANGED
|
@@ -4,13 +4,14 @@ export interface ConfigParams {
|
|
|
4
4
|
items: ItemRecord[]
|
|
5
5
|
keys: string[]
|
|
6
6
|
caseSensitive?: boolean
|
|
7
|
+
enableMemoize?: boolean
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
interface Config {
|
|
10
11
|
Items: ItemRecord[]
|
|
11
12
|
Keys: string[]
|
|
12
|
-
CaseSensitive: boolean
|
|
13
13
|
RegexFlag: 'i' | undefined
|
|
14
|
+
EnableMemoize: boolean
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
|
|
@@ -21,18 +22,22 @@ const escapeRegExp = (str: string): string => {
|
|
|
21
22
|
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
const cache = new Map()
|
|
26
|
+
|
|
24
27
|
const Conf: Config = {
|
|
25
28
|
Items: [],
|
|
26
29
|
Keys: [],
|
|
27
|
-
CaseSensitive: false,
|
|
28
30
|
RegexFlag: 'i',
|
|
31
|
+
EnableMemoize: true,
|
|
29
32
|
}
|
|
30
33
|
export const searchSetConfig = (params: ConfigParams): void => {
|
|
31
|
-
const { items, keys, caseSensitive = false } = params
|
|
34
|
+
const { items, keys, caseSensitive = false, enableMemoize = true } = params
|
|
32
35
|
Conf.Items = items
|
|
33
36
|
Conf.Keys = keys
|
|
34
|
-
Conf.CaseSensitive = caseSensitive
|
|
35
37
|
Conf.RegexFlag = caseSensitive ? undefined : 'i'
|
|
38
|
+
Conf.EnableMemoize = enableMemoize
|
|
39
|
+
|
|
40
|
+
cache.clear()
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
// Since (if no debounce) every search input keystroke calls this
|
|
@@ -52,6 +57,10 @@ export const searchHandler = (query: string): ItemRecord[] => {
|
|
|
52
57
|
return Conf.Items
|
|
53
58
|
}
|
|
54
59
|
|
|
60
|
+
if (Conf.EnableMemoize && cache.has(qTrimmed)) {
|
|
61
|
+
return cache.get(qTrimmed)
|
|
62
|
+
}
|
|
63
|
+
|
|
55
64
|
const rx = new RegExp(qTrimmed, Conf.RegexFlag)
|
|
56
65
|
|
|
57
66
|
// All the dirty work is done here...
|
|
@@ -62,5 +71,9 @@ export const searchHandler = (query: string): ItemRecord[] => {
|
|
|
62
71
|
}
|
|
63
72
|
}
|
|
64
73
|
|
|
74
|
+
if (Conf.EnableMemoize && qTrimmed.length >= 3) {
|
|
75
|
+
cache.set(qTrimmed, results)
|
|
76
|
+
}
|
|
77
|
+
|
|
65
78
|
return results
|
|
66
79
|
}
|