@coveo/quantic 3.10.0-pre.c5a50cf39c → 3.10.0-pre.e5fef370d0
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/docs/out/quantic-docs.json +38 -2
- package/force-app/main/default/lwc/quanticDidYouMean/__tests__/quanticDidYouMean.test.js +199 -0
- package/force-app/main/default/lwc/quanticDidYouMean/quanticDidYouMean.js +24 -2
- package/force-app/main/default/staticresources/coveoheadless/case-assist/headless.js +4 -4
- package/force-app/main/default/staticresources/coveoheadless/definitions/controllers/core/interactive-result/headless-core-interactive-result.d.ts +2 -2
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/analytics/search-action-cause.d.ts +0 -82
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/facets/facet-set/facet-set-analytics-actions.d.ts +0 -1
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/history/history-analytics-actions.d.ts +0 -3
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/search/search-actions.d.ts +2 -2
- package/force-app/main/default/staticresources/coveoheadless/definitions/features/static-filter-set/static-filter-set-actions.d.ts +0 -4
- package/force-app/main/default/staticresources/coveoheadless/definitions/ssr-commerce.index.d.ts +4 -2
- package/force-app/main/default/staticresources/coveoheadless/headless.js +6 -6
- package/force-app/main/default/staticresources/coveoheadless/insight/headless.js +5 -5
- package/force-app/main/default/staticresources/coveoheadless/recommendation/headless.js +4 -4
- package/package.json +2 -2
|
@@ -382,7 +382,7 @@
|
|
|
382
382
|
],
|
|
383
383
|
"fires": "",
|
|
384
384
|
"examples": [
|
|
385
|
-
"<c-quantic-did-you-mean engine-id={engineId}></c-quantic-did-you-mean>"
|
|
385
|
+
"<c-quantic-did-you-mean engine-id={engineId} disable-query-auto-correction={disableQueryAutoCorrection} query-correction-mode=\"next\"></c-quantic-did-you-mean>"
|
|
386
386
|
],
|
|
387
387
|
"xmlMeta": {
|
|
388
388
|
"apiVersion": "53.0",
|
|
@@ -398,6 +398,24 @@
|
|
|
398
398
|
"required": true,
|
|
399
399
|
"defaultValue": "",
|
|
400
400
|
"type": "string"
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"name": "disableQueryAutoCorrection",
|
|
404
|
+
"attribute": "disable-query-auto-correction",
|
|
405
|
+
"access": "@api",
|
|
406
|
+
"description": "<p>Whether to disable automatically applying corrections for queries that would otherwise return no results.\nWhen <code>disableQueryAutoCorrection</code> is <code>false</code>, the component automatically triggers a new query using the suggested term.\nWhen <code>disableQueryAutoCorrection</code> is <code>true</code>, the component returns the suggested term without triggering a new query.</p>",
|
|
407
|
+
"required": false,
|
|
408
|
+
"defaultValue": "false",
|
|
409
|
+
"type": "boolean"
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
"name": "queryCorrectionMode",
|
|
413
|
+
"attribute": "query-correction-mode",
|
|
414
|
+
"access": "@api",
|
|
415
|
+
"description": "<p>Defines which query correction system to use.\n<code>legacy</code>: Query correction is powered by the legacy index system. This system relies on an algorithm using solely the index content to compute the suggested terms.\n<code>next</code>: Query correction is powered by a machine learning system, requiring a valid query suggestion model configured in your Coveo environment to function properly. This system relies on machine learning algorithms to compute the suggested terms.\nThe <code>legacy</code> system will send two requests to the API to get the suggestions, while the <code>next</code> system will send one request.</p>",
|
|
416
|
+
"required": false,
|
|
417
|
+
"defaultValue": "'legacy'",
|
|
418
|
+
"type": "string"
|
|
401
419
|
}
|
|
402
420
|
]
|
|
403
421
|
},
|
|
@@ -4315,7 +4333,7 @@
|
|
|
4315
4333
|
],
|
|
4316
4334
|
"fires": "",
|
|
4317
4335
|
"examples": [
|
|
4318
|
-
"<c-quantic-did-you-mean engine-id={engineId}></c-quantic-did-you-mean>"
|
|
4336
|
+
"<c-quantic-did-you-mean engine-id={engineId} disable-query-auto-correction={disableQueryAutoCorrection} query-correction-mode=\"next\"></c-quantic-did-you-mean>"
|
|
4319
4337
|
],
|
|
4320
4338
|
"xmlMeta": {
|
|
4321
4339
|
"apiVersion": "53.0",
|
|
@@ -4331,6 +4349,24 @@
|
|
|
4331
4349
|
"required": true,
|
|
4332
4350
|
"defaultValue": "",
|
|
4333
4351
|
"type": "string"
|
|
4352
|
+
},
|
|
4353
|
+
{
|
|
4354
|
+
"name": "disableQueryAutoCorrection",
|
|
4355
|
+
"attribute": "disable-query-auto-correction",
|
|
4356
|
+
"access": "@api",
|
|
4357
|
+
"description": "<p>Whether to disable automatically applying corrections for queries that would otherwise return no results.\nWhen <code>disableQueryAutoCorrection</code> is <code>false</code>, the component automatically triggers a new query using the suggested term.\nWhen <code>disableQueryAutoCorrection</code> is <code>true</code>, the component returns the suggested term without triggering a new query.</p>",
|
|
4358
|
+
"required": false,
|
|
4359
|
+
"defaultValue": "false",
|
|
4360
|
+
"type": "boolean"
|
|
4361
|
+
},
|
|
4362
|
+
{
|
|
4363
|
+
"name": "queryCorrectionMode",
|
|
4364
|
+
"attribute": "query-correction-mode",
|
|
4365
|
+
"access": "@api",
|
|
4366
|
+
"description": "<p>Defines which query correction system to use.\n<code>legacy</code>: Query correction is powered by the legacy index system. This system relies on an algorithm using solely the index content to compute the suggested terms.\n<code>next</code>: Query correction is powered by a machine learning system, requiring a valid query suggestion model configured in your Coveo environment to function properly. This system relies on machine learning algorithms to compute the suggested terms.\nThe <code>legacy</code> system will send two requests to the API to get the suggestions, while the <code>next</code> system will send one request.</p>",
|
|
4367
|
+
"required": false,
|
|
4368
|
+
"defaultValue": "'legacy'",
|
|
4369
|
+
"type": "string"
|
|
4334
4370
|
}
|
|
4335
4371
|
]
|
|
4336
4372
|
},
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/* eslint-disable no-import-assign */
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
import {createElement} from 'lwc';
|
|
4
|
+
import QuanticDidYouMean from '../quanticDidYouMean';
|
|
5
|
+
import * as mockHeadlessLoader from 'c/quanticHeadlessLoader';
|
|
6
|
+
|
|
7
|
+
jest.mock('c/quanticHeadlessLoader');
|
|
8
|
+
|
|
9
|
+
let isInitialized = false;
|
|
10
|
+
|
|
11
|
+
const exampleEngine = {
|
|
12
|
+
id: 'exampleEngineId',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const defaultQueryCorrectionMode = 'legacy';
|
|
16
|
+
|
|
17
|
+
const defaultOptions = {
|
|
18
|
+
engineId: exampleEngine.id,
|
|
19
|
+
disableQueryAutoCorrection: false,
|
|
20
|
+
queryCorrectionMode: defaultQueryCorrectionMode,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const mockDidYouMeanState = {
|
|
24
|
+
wasCorrectedTo: 'example corrected query',
|
|
25
|
+
originalQuery: 'example original query',
|
|
26
|
+
wasAutomaticallyCorrected: true,
|
|
27
|
+
queryCorrection: {
|
|
28
|
+
correctedQuery: 'example corrected query',
|
|
29
|
+
wordCorrected: 'example',
|
|
30
|
+
},
|
|
31
|
+
hasQueryCorrection: true,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const functionsMocks = {
|
|
35
|
+
buildDidYouMean: jest.fn(() => ({
|
|
36
|
+
state: mockDidYouMeanState,
|
|
37
|
+
subscribe: functionsMocks.subscribe,
|
|
38
|
+
})),
|
|
39
|
+
buildQueryTrigger: jest.fn(() => ({
|
|
40
|
+
state: {},
|
|
41
|
+
subscribe: functionsMocks.subscribe,
|
|
42
|
+
})),
|
|
43
|
+
applyCorrection: jest.fn(() => {}),
|
|
44
|
+
subscribe: jest.fn((cb) => {
|
|
45
|
+
cb();
|
|
46
|
+
return functionsMocks.unsubscribe;
|
|
47
|
+
}),
|
|
48
|
+
unsubscribe: jest.fn(() => {}),
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function prepareHeadlessState() {
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
mockHeadlessLoader.getHeadlessBundle = () => {
|
|
54
|
+
return {
|
|
55
|
+
buildDidYouMean: functionsMocks.buildDidYouMean,
|
|
56
|
+
buildQueryTrigger: functionsMocks.buildQueryTrigger,
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function mockSuccessfulHeadlessInitialization() {
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
mockHeadlessLoader.initializeWithHeadless = (element, _, initialize) => {
|
|
64
|
+
if (element instanceof QuanticDidYouMean && !isInitialized) {
|
|
65
|
+
isInitialized = true;
|
|
66
|
+
initialize(exampleEngine);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function createTestComponent(options = defaultOptions) {
|
|
72
|
+
prepareHeadlessState();
|
|
73
|
+
const element = createElement('c-quantic-did-you-mean', {
|
|
74
|
+
is: QuanticDidYouMean,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
for (const [key, value] of Object.entries(options)) {
|
|
78
|
+
element[key] = value;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
document.body.appendChild(element);
|
|
82
|
+
return element;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Helper function to wait until the microtask queue is empty.
|
|
86
|
+
async function flushPromises() {
|
|
87
|
+
return Promise.resolve();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
describe('c-quantic-did-you-mean', () => {
|
|
91
|
+
function cleanup() {
|
|
92
|
+
// The jsdom instance is shared across test cases in a single file so reset the DOM
|
|
93
|
+
while (document.body.firstChild) {
|
|
94
|
+
document.body.removeChild(document.body.firstChild);
|
|
95
|
+
}
|
|
96
|
+
jest.clearAllMocks();
|
|
97
|
+
isInitialized = false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
beforeEach(() => {
|
|
101
|
+
mockSuccessfulHeadlessInitialization();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
afterEach(() => {
|
|
105
|
+
cleanup();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('controller initialization', () => {
|
|
109
|
+
it('should subscribe to the headless state changes', async () => {
|
|
110
|
+
createTestComponent();
|
|
111
|
+
await flushPromises();
|
|
112
|
+
|
|
113
|
+
expect(functionsMocks.buildDidYouMean).toHaveBeenCalled();
|
|
114
|
+
expect(functionsMocks.subscribe).toHaveBeenCalled();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('#disableQueryAutoCorrection property', () => {
|
|
118
|
+
describe('when disableQueryAutoCorrection is false (default)', () => {
|
|
119
|
+
it('should properly initialize the controller with automatic query correction enabled', async () => {
|
|
120
|
+
createTestComponent();
|
|
121
|
+
await flushPromises();
|
|
122
|
+
|
|
123
|
+
expect(functionsMocks.buildDidYouMean).toHaveBeenCalledTimes(1);
|
|
124
|
+
expect(functionsMocks.buildDidYouMean).toHaveBeenCalledWith(
|
|
125
|
+
exampleEngine,
|
|
126
|
+
expect.objectContaining({
|
|
127
|
+
options: expect.objectContaining({
|
|
128
|
+
automaticallyCorrectQuery: true,
|
|
129
|
+
queryCorrectionMode: defaultQueryCorrectionMode,
|
|
130
|
+
}),
|
|
131
|
+
})
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('when disableQueryAutoCorrection is true', () => {
|
|
137
|
+
it('should properly initialize the controller with automatic query correction disabled', async () => {
|
|
138
|
+
createTestComponent({
|
|
139
|
+
...defaultOptions,
|
|
140
|
+
disableQueryAutoCorrection: true,
|
|
141
|
+
});
|
|
142
|
+
await flushPromises();
|
|
143
|
+
|
|
144
|
+
expect(functionsMocks.buildDidYouMean).toHaveBeenCalledTimes(1);
|
|
145
|
+
expect(functionsMocks.buildDidYouMean).toHaveBeenCalledWith(
|
|
146
|
+
exampleEngine,
|
|
147
|
+
expect.objectContaining({
|
|
148
|
+
options: expect.objectContaining({
|
|
149
|
+
automaticallyCorrectQuery: false,
|
|
150
|
+
queryCorrectionMode: defaultQueryCorrectionMode,
|
|
151
|
+
}),
|
|
152
|
+
})
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe('#queryCorrectionMode property', () => {
|
|
159
|
+
describe('when queryCorrectionMode is `legacy` (default)', () => {
|
|
160
|
+
it('should properly initialize the controller with the query correction mode set to `legacy`', async () => {
|
|
161
|
+
createTestComponent();
|
|
162
|
+
await flushPromises();
|
|
163
|
+
|
|
164
|
+
expect(functionsMocks.buildDidYouMean).toHaveBeenCalledTimes(1);
|
|
165
|
+
expect(functionsMocks.buildDidYouMean).toHaveBeenCalledWith(
|
|
166
|
+
exampleEngine,
|
|
167
|
+
expect.objectContaining({
|
|
168
|
+
options: expect.objectContaining({
|
|
169
|
+
automaticallyCorrectQuery: true,
|
|
170
|
+
queryCorrectionMode: defaultQueryCorrectionMode,
|
|
171
|
+
}),
|
|
172
|
+
})
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
describe('when queryCorrectionMode is `next`', () => {
|
|
178
|
+
it('should properly initialize the controller with the query correction mode set to `next`', async () => {
|
|
179
|
+
createTestComponent({
|
|
180
|
+
...defaultOptions,
|
|
181
|
+
queryCorrectionMode: 'next',
|
|
182
|
+
});
|
|
183
|
+
await flushPromises();
|
|
184
|
+
|
|
185
|
+
expect(functionsMocks.buildDidYouMean).toHaveBeenCalledTimes(1);
|
|
186
|
+
expect(functionsMocks.buildDidYouMean).toHaveBeenCalledWith(
|
|
187
|
+
exampleEngine,
|
|
188
|
+
expect.objectContaining({
|
|
189
|
+
options: expect.objectContaining({
|
|
190
|
+
automaticallyCorrectQuery: true,
|
|
191
|
+
queryCorrectionMode: 'next',
|
|
192
|
+
}),
|
|
193
|
+
})
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
});
|
|
@@ -29,7 +29,7 @@ import queryTriggerTemplate from './templates/queryTrigger.html';
|
|
|
29
29
|
* @category Search
|
|
30
30
|
* @category Insight Panel
|
|
31
31
|
* @example
|
|
32
|
-
* <c-quantic-did-you-mean engine-id={engineId}></c-quantic-did-you-mean>
|
|
32
|
+
* <c-quantic-did-you-mean engine-id={engineId} disable-query-auto-correction={disableQueryAutoCorrection} query-correction-mode="next"></c-quantic-did-you-mean>
|
|
33
33
|
*/
|
|
34
34
|
export default class QuanticDidYouMean extends LightningElement {
|
|
35
35
|
/**
|
|
@@ -38,6 +38,25 @@ export default class QuanticDidYouMean extends LightningElement {
|
|
|
38
38
|
* @type {string}
|
|
39
39
|
*/
|
|
40
40
|
@api engineId;
|
|
41
|
+
/**
|
|
42
|
+
* Whether to disable automatically applying corrections for queries that would otherwise return no results.
|
|
43
|
+
* When `disableQueryAutoCorrection` is `false`, the component automatically triggers a new query using the suggested term.
|
|
44
|
+
* When `disableQueryAutoCorrection` is `true`, the component returns the suggested term without triggering a new query.
|
|
45
|
+
* @api
|
|
46
|
+
* @type {boolean}
|
|
47
|
+
* @defaultValue false
|
|
48
|
+
*/
|
|
49
|
+
@api disableQueryAutoCorrection = false;
|
|
50
|
+
/**
|
|
51
|
+
* Defines which query correction system to use.
|
|
52
|
+
* `legacy`: Query correction is powered by the legacy index system. This system relies on an algorithm using solely the index content to compute the suggested terms.
|
|
53
|
+
* `next`: Query correction is powered by a machine learning system, requiring a valid query suggestion model configured in your Coveo environment to function properly. This system relies on machine learning algorithms to compute the suggested terms.
|
|
54
|
+
* The `legacy` system will send two requests to the API to get the suggestions, while the `next` system will send one request.
|
|
55
|
+
* @api
|
|
56
|
+
* @type {string}
|
|
57
|
+
* @defaultValue 'legacy'
|
|
58
|
+
*/
|
|
59
|
+
@api queryCorrectionMode = 'legacy';
|
|
41
60
|
|
|
42
61
|
/** @type {boolean}*/
|
|
43
62
|
@track hasQueryCorrection;
|
|
@@ -85,7 +104,10 @@ export default class QuanticDidYouMean extends LightningElement {
|
|
|
85
104
|
initialize = (engine) => {
|
|
86
105
|
this.headless = getHeadlessBundle(this.engineId);
|
|
87
106
|
this.didYouMean = this.headless.buildDidYouMean(engine, {
|
|
88
|
-
options: {
|
|
107
|
+
options: {
|
|
108
|
+
queryCorrectionMode: this.queryCorrectionMode,
|
|
109
|
+
automaticallyCorrectQuery: !this.disableQueryAutoCorrection,
|
|
110
|
+
},
|
|
89
111
|
});
|
|
90
112
|
this.queryTrigger = this.headless?.buildQueryTrigger?.(engine);
|
|
91
113
|
this.unsubscribeDidYouMean = this.didYouMean.subscribe(() =>
|