Skip to content

Commit 7da7ed5

Browse files
committed
refactor(instantsearch): replace "helper" with the value of "mainHelper" (#6516)
* refactor(instantsearch): remove "helper" in favor of "mainHelper" [FX-3212] * refactor(instantsearch): rename "mainHelper" to "helper" [FX-3212] BREAKING CHANGE: the value search.helper is what used to be search.mainHelper. search.mainHelper no longer exists. Use either search.helper now or search.mainIndex.getHelper()
1 parent 503a357 commit 7da7ed5

File tree

20 files changed

+136
-154
lines changed

20 files changed

+136
-154
lines changed

packages/instantsearch-core/src/__tests__/instantsearch.test.tsx

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ search.addWidgets([
378378
See https://www.algolia.com/doc/api-reference/widgets/configure/js/`);
379379
});
380380

381-
it("exposes helper's last results", async () => {
381+
it("helper's results are null", async () => {
382382
const searchClient = createSearchClient();
383383

384384
const search = new InstantSearch({
@@ -394,8 +394,7 @@ See https://www.algolia.com/doc/api-reference/widgets/configure/js/`);
394394

395395
await wait(0);
396396

397-
// could be null if we don't pretend the main helper is the one who searched
398-
expect(search.helper!.lastResults).not.toBe(null);
397+
expect(search.helper!.lastResults).toBe(null);
399398
});
400399

401400
describe('insights middleware', () => {
@@ -822,9 +821,9 @@ describe('start', () => {
822821

823822
await wait(0);
824823

825-
expect(
826-
search.mainHelper!.searchOnlyWithDerivedHelpers
827-
).toHaveBeenCalledTimes(1);
824+
expect(search.helper!.searchOnlyWithDerivedHelpers).toHaveBeenCalledTimes(
825+
1
826+
);
828827
});
829828

830829
it('forwards the `initialUiState` to the main index', () => {
@@ -1004,7 +1003,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/instantsear
10041003
`);
10051004
});
10061005

1007-
it('keeps a mainHelper already set on the instance (Vue SSR)', () => {
1006+
it('keeps a helper already set on the instance (Vue SSR)', () => {
10081007
const searchClient = createSearchClient();
10091008
const instance = new InstantSearch({
10101009
indexName: 'indexName',
@@ -1013,17 +1012,17 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/instantsear
10131012

10141013
const helper = algoliasearchHelper(searchClient, '');
10151014

1016-
// explicitly setting the mainHelper before start is used to force render to
1015+
// explicitly setting the helper before start is used to force render to
10171016
// happen before the results of the first search are done. We need to make
10181017
// sure no extra helper is created, as that can cause certain things (like routing)
10191018
// to be listening to the wrong helper.
1020-
instance.mainHelper = helper;
1019+
instance.helper = helper;
10211020

1022-
expect(instance.mainHelper).toBe(helper);
1021+
expect(instance.helper).toBe(helper);
10231022

10241023
instance.start();
10251024

1026-
expect(instance.mainHelper).toBe(helper);
1025+
expect(instance.helper).toBe(helper);
10271026
});
10281027

10291028
it('no query for root if indexName is not given', async () => {
@@ -1122,7 +1121,7 @@ describe('dispose', () => {
11221121
await wait(0);
11231122

11241123
// Simulate a search
1125-
search.mainHelper!.search();
1124+
search.helper!.search();
11261125

11271126
search.dispose();
11281127

@@ -1195,17 +1194,17 @@ describe('dispose', () => {
11951194

11961195
search.start();
11971196

1198-
const mainHelper = search.mainHelper!;
1197+
const helper = search.helper!;
11991198

1200-
mainHelper.on('searchQueueEmpty', onEventName);
1199+
helper.on('searchQueueEmpty', onEventName);
12011200

1202-
mainHelper.emit('searchQueueEmpty');
1201+
helper.emit('searchQueueEmpty');
12031202

12041203
expect(onEventName).toHaveBeenCalledTimes(1);
12051204

12061205
search.dispose();
12071206

1208-
mainHelper.emit('searchQueueEmpty');
1207+
helper.emit('searchQueueEmpty');
12091208

12101209
expect(onEventName).toHaveBeenCalledTimes(1);
12111210
});
@@ -1240,25 +1239,22 @@ describe('dispose', () => {
12401239
expect(onRender).toHaveBeenCalledTimes(2);
12411240
});
12421241

1243-
it('removes the Helpers references', () => {
1242+
it('removes the helper references', () => {
12441243
const search = new InstantSearch({
12451244
indexName: 'indexName',
12461245
searchClient: createSearchClient(),
12471246
});
12481247

12491248
search.start();
12501249

1251-
expect(search.mainHelper).not.toBe(null);
12521250
expect(search.helper).not.toBe(null);
12531251

12541252
search.dispose();
12551253

1256-
expect(search.mainHelper).toBe(null);
12571254
expect(search.helper).toBe(null);
12581255

12591256
search.start();
12601257

1261-
expect(search.mainHelper).not.toBe(null);
12621258
expect(search.helper).not.toBe(null);
12631259
});
12641260

@@ -1283,15 +1279,15 @@ describe('scheduleSearch', () => {
12831279

12841280
search.start();
12851281

1286-
const mainHelperSearch = jest.spyOn(search.mainHelper!, 'search');
1282+
const helperSearch = jest.spyOn(search.helper!, 'search');
12871283

12881284
search.scheduleSearch();
12891285

1290-
expect(mainHelperSearch).toHaveBeenCalledTimes(0);
1286+
expect(helperSearch).toHaveBeenCalledTimes(0);
12911287

12921288
await wait(0);
12931289

1294-
expect(mainHelperSearch).toHaveBeenCalledTimes(1);
1290+
expect(helperSearch).toHaveBeenCalledTimes(1);
12951291
});
12961292

12971293
it('deduplicates the calls to the `search` method', async () => {
@@ -1304,18 +1300,18 @@ describe('scheduleSearch', () => {
13041300

13051301
search.start();
13061302

1307-
const mainHelperSearch = jest.spyOn(search.mainHelper!, 'search');
1303+
const helperSearch = jest.spyOn(search.helper!, 'search');
13081304

13091305
search.scheduleSearch();
13101306
search.scheduleSearch();
13111307
search.scheduleSearch();
13121308
search.scheduleSearch();
13131309

1314-
expect(mainHelperSearch).toHaveBeenCalledTimes(0);
1310+
expect(helperSearch).toHaveBeenCalledTimes(0);
13151311

13161312
await wait(0);
13171313

1318-
expect(mainHelperSearch).toHaveBeenCalledTimes(1);
1314+
expect(helperSearch).toHaveBeenCalledTimes(1);
13191315
});
13201316
});
13211317

@@ -1418,7 +1414,7 @@ describe('scheduleStalledRender', () => {
14181414
castToJestMock(widget.render!).mockReset();
14191415

14201416
// Trigger a new search
1421-
search.mainHelper!.search();
1417+
search.helper!.search();
14221418

14231419
// search starts
14241420
await wait(0);
@@ -1456,10 +1452,10 @@ describe('scheduleStalledRender', () => {
14561452
castToJestMock(widget.render!).mockClear();
14571453

14581454
// Trigger multiple searches
1459-
search.mainHelper!.search();
1460-
search.mainHelper!.search();
1461-
search.mainHelper!.search();
1462-
search.mainHelper!.search();
1455+
search.helper!.search();
1456+
search.helper!.search();
1457+
search.helper!.search();
1458+
search.helper!.search();
14631459

14641460
await wait(0);
14651461

@@ -1507,7 +1503,7 @@ describe('scheduleStalledRender', () => {
15071503
);
15081504

15091505
// Trigger a new search
1510-
search.mainHelper!.search();
1506+
search.helper!.search();
15111507

15121508
expect(widget.render).toHaveBeenCalledTimes(1);
15131509
castToJestMock(widget.render!).mockClear();

packages/instantsearch-core/src/connectors/__tests__/connectGeoSearch.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ describe('connectGeoSearch', () => {
7373
const widget = customGeoSearch({});
7474

7575
const instantSearchInstance = createInstantSearch();
76-
const helper = instantSearchInstance.mainHelper!;
76+
const helper = instantSearchInstance.helper!;
7777

7878
widget.init!(
7979
createInitOptions({
@@ -160,7 +160,7 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/geo-search/
160160
const widget = customGeoSearch({});
161161

162162
const instantSearchInstance = createInstantSearch();
163-
const { mainHelper: helper } = instantSearchInstance;
163+
const { helper } = instantSearchInstance;
164164

165165
widget.init!(createInitOptions({ instantSearchInstance }));
166166

packages/instantsearch-core/src/instantsearch.ts

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ export class InstantSearch<
6565
onStateChange: InstantSearchOptions<TUiState>['onStateChange'] | null = null;
6666
future: NonNullable<InstantSearchOptions<TUiState>['future']>;
6767
helper: AlgoliaSearchHelper | null;
68-
mainHelper: AlgoliaSearchHelper | null;
6968
mainIndex: IndexWidget;
7069
started: boolean;
7170
renderState: RenderState = {};
@@ -74,7 +73,7 @@ export class InstantSearch<
7473
_initialUiState: TUiState;
7574
_initialResults: InitialResults | null;
7675
_createURL: CreateURL<TUiState>;
77-
_mainHelperSearch?: AlgoliaSearchHelper['search'];
76+
_helperSearch?: AlgoliaSearchHelper['search'];
7877
_hasSearchWidget: boolean = false;
7978
_hasRecommendWidget: boolean = false;
8079
_insights: InstantSearchOptions['insights'];
@@ -150,7 +149,6 @@ See ${createDocumentationLink({
150149
this.future = future;
151150
this.indexName = indexName;
152151
this.helper = null;
153-
this.mainHelper = null;
154152
this.mainIndex = index({
155153
indexName,
156154
});
@@ -296,11 +294,11 @@ See ${createDocumentationLink({
296294
// DerivedHelper scoped into the `index` widgets.
297295
// In Vue InstantSearch' hydrate, a main helper gets set before start, so
298296
// we need to respect this helper as a way to keep all listeners correct.
299-
const mainHelper =
300-
this.mainHelper ||
297+
const helper =
298+
this.helper ||
301299
algoliasearchHelper(this.client, this.indexName, undefined);
302300

303-
mainHelper.search = () => {
301+
helper.search = () => {
304302
this.status = 'loading';
305303
this.scheduleRender(false);
306304

@@ -315,19 +313,19 @@ See ${createDocumentationLink({
315313
// completely transparent for the rest of the codebase. Only this module
316314
// is impacted.
317315
if (this._hasSearchWidget) {
318-
mainHelper.searchOnlyWithDerivedHelpers();
316+
helper.searchOnlyWithDerivedHelpers();
319317
}
320318

321319
if (this._hasRecommendWidget) {
322-
mainHelper.recommend();
320+
helper.recommend();
323321
}
324322

325-
return mainHelper;
323+
return helper;
326324
};
327325

328326
// Only the "main" Helper emits the `error` event vs the one for `search`
329327
// and `results` that are also emitted on the derived one.
330-
mainHelper.on('error', (error) => {
328+
helper.on('error', (error) => {
331329
if (!(error instanceof Error)) {
332330
// typescript lies here, error is in some cases { name: string, message: string }
333331
const err = error as Record<string, any>;
@@ -345,7 +343,7 @@ See ${createDocumentationLink({
345343
this.emit('error', this.error);
346344
});
347345

348-
this.mainHelper = mainHelper;
346+
this.helper = helper;
349347

350348
this.middleware.forEach(({ instance }) => {
351349
instance.subscribe();
@@ -359,7 +357,7 @@ See ${createDocumentationLink({
359357

360358
if (this._initialResults) {
361359
hydrateSearchClient(this.client, this._initialResults);
362-
hydrateRecommendCache(this.mainHelper, this._initialResults);
360+
hydrateRecommendCache(this.helper, this._initialResults);
363361

364362
const originalScheduleSearch = this.scheduleSearch;
365363
// We don't schedule a first search when initial results are provided
@@ -387,10 +385,6 @@ See ${createDocumentationLink({
387385
this.scheduleSearch();
388386
}
389387

390-
// Keep the previous reference for legacy purpose, some pattern use
391-
// the direct Helper access `search.helper` (e.g multi-index).
392-
this.helper = this.mainIndex.getHelper();
393-
394388
// track we started the search if we add more widgets,
395389
// to init them directly after add
396390
this.started = true;
@@ -403,7 +397,7 @@ See ${createDocumentationLink({
403397
// added when `insights` is unset and the initial results possess `queryID`.
404398
// Any user-provided middleware will be added later and override this one.
405399
if (typeof this._insights === 'undefined') {
406-
mainHelper.derivedHelpers[0].once('result', () => {
400+
helper.derivedHelpers[0].once('result', () => {
407401
const hasAutomaticInsights = this.mainIndex
408402
.getScopedResults()
409403
.some(({ results }) => results?._automaticInsights);
@@ -435,8 +429,7 @@ See ${createDocumentationLink({
435429
// The helper needs to be reset to perform the next search from a fresh state.
436430
// If not reset, it would use the state stored before calling `dispose()`.
437431
this.removeAllListeners();
438-
this.mainHelper?.removeAllListeners();
439-
this.mainHelper = null;
432+
this.helper?.removeAllListeners();
440433
this.helper = null;
441434

442435
this.middleware.forEach(({ instance }) => {
@@ -446,12 +439,12 @@ See ${createDocumentationLink({
446439

447440
scheduleSearch = defer(() => {
448441
if (this.started) {
449-
this.mainHelper!.search();
442+
this.helper!.search();
450443
}
451444
});
452445

453446
scheduleRender = defer((shouldResetStatus: boolean = true) => {
454-
if (!this.mainHelper?.hasPendingRequests()) {
447+
if (!this.helper?.hasPendingRequests()) {
455448
clearTimeout(this._searchStalledTimer);
456449
this._searchStalledTimer = null;
457450

@@ -481,7 +474,7 @@ See ${createDocumentationLink({
481474
uiState: TUiState | ((previousUiState: TUiState) => TUiState),
482475
callOnStateChange = true
483476
) {
484-
if (!this.mainHelper) {
477+
if (!this.helper) {
485478
throw new Error(
486479
withUsage('The `start` method needs to be called before `setUiState`.')
487480
);
@@ -548,13 +541,13 @@ See ${createDocumentationLink({
548541
}
549542

550543
refresh() {
551-
if (!this.mainHelper) {
544+
if (!this.helper) {
552545
throw new Error(
553546
withUsage('The `start` method needs to be called before `refresh`.')
554547
);
555548
}
556549

557-
this.mainHelper.clearCache().search();
550+
this.helper.clearCache().search();
558551
}
559552
}
560553

0 commit comments

Comments
 (0)