@apvee/spfx-react-toolkit 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/lib/core/atoms.internal.js +1 -1
  2. package/lib/core/atoms.internal.js.map +1 -1
  3. package/lib/core/context.internal.js +2 -2
  4. package/lib/core/context.internal.js.map +1 -1
  5. package/lib/core/provider-base.internal.js +29 -29
  6. package/lib/core/provider-base.internal.js.map +1 -1
  7. package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.js +8 -29
  8. package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.js.map +1 -1
  9. package/lib/hooks/index.d.ts +1 -0
  10. package/lib/hooks/index.d.ts.map +1 -1
  11. package/lib/hooks/index.js +1 -0
  12. package/lib/hooks/index.js.map +1 -1
  13. package/lib/hooks/useAppCatalogUrl.internal.d.ts +26 -0
  14. package/lib/hooks/useAppCatalogUrl.internal.d.ts.map +1 -0
  15. package/lib/hooks/useAppCatalogUrl.internal.js +72 -0
  16. package/lib/hooks/useAppCatalogUrl.internal.js.map +1 -0
  17. package/lib/hooks/useAsyncInvoke.internal.js +27 -75
  18. package/lib/hooks/useAsyncInvoke.internal.js.map +1 -1
  19. package/lib/hooks/useSPFxAadHttpClient.js +27 -27
  20. package/lib/hooks/useSPFxAadHttpClient.js.map +1 -1
  21. package/lib/hooks/useSPFxContainerInfo.js +5 -5
  22. package/lib/hooks/useSPFxContainerInfo.js.map +1 -1
  23. package/lib/hooks/useSPFxContainerSize.js +9 -10
  24. package/lib/hooks/useSPFxContainerSize.js.map +1 -1
  25. package/lib/hooks/useSPFxCorrelationInfo.js +6 -7
  26. package/lib/hooks/useSPFxCorrelationInfo.js.map +1 -1
  27. package/lib/hooks/useSPFxCrossSitePermissions.js +48 -58
  28. package/lib/hooks/useSPFxCrossSitePermissions.js.map +1 -1
  29. package/lib/hooks/useSPFxDisplayMode.js +8 -8
  30. package/lib/hooks/useSPFxDisplayMode.js.map +1 -1
  31. package/lib/hooks/useSPFxEnvironmentInfo.js +17 -18
  32. package/lib/hooks/useSPFxEnvironmentInfo.js.map +1 -1
  33. package/lib/hooks/useSPFxFluent9ThemeInfo.js +4 -4
  34. package/lib/hooks/useSPFxFluent9ThemeInfo.js.map +1 -1
  35. package/lib/hooks/useSPFxHttpClient.js +10 -10
  36. package/lib/hooks/useSPFxHttpClient.js.map +1 -1
  37. package/lib/hooks/useSPFxHubSiteInfo.js +21 -24
  38. package/lib/hooks/useSPFxHubSiteInfo.js.map +1 -1
  39. package/lib/hooks/useSPFxInstanceInfo.js +2 -2
  40. package/lib/hooks/useSPFxInstanceInfo.js.map +1 -1
  41. package/lib/hooks/useSPFxListInfo.js +8 -9
  42. package/lib/hooks/useSPFxListInfo.js.map +1 -1
  43. package/lib/hooks/useSPFxLocaleInfo.js +10 -10
  44. package/lib/hooks/useSPFxLocaleInfo.js.map +1 -1
  45. package/lib/hooks/useSPFxLogger.js +26 -26
  46. package/lib/hooks/useSPFxLogger.js.map +1 -1
  47. package/lib/hooks/useSPFxMSGraphClient.js +25 -25
  48. package/lib/hooks/useSPFxMSGraphClient.js.map +1 -1
  49. package/lib/hooks/useSPFxOneDriveAppData.js +148 -209
  50. package/lib/hooks/useSPFxOneDriveAppData.js.map +1 -1
  51. package/lib/hooks/useSPFxPageContext.js +2 -2
  52. package/lib/hooks/useSPFxPageContext.js.map +1 -1
  53. package/lib/hooks/useSPFxPageType.js +19 -20
  54. package/lib/hooks/useSPFxPageType.js.map +1 -1
  55. package/lib/hooks/useSPFxPerformance.js +33 -87
  56. package/lib/hooks/useSPFxPerformance.js.map +1 -1
  57. package/lib/hooks/useSPFxPermissions.js +14 -15
  58. package/lib/hooks/useSPFxPermissions.js.map +1 -1
  59. package/lib/hooks/useSPFxPnP.js +62 -119
  60. package/lib/hooks/useSPFxPnP.js.map +1 -1
  61. package/lib/hooks/useSPFxPnPContext.js +22 -25
  62. package/lib/hooks/useSPFxPnPContext.js.map +1 -1
  63. package/lib/hooks/useSPFxPnPList.js +307 -451
  64. package/lib/hooks/useSPFxPnPList.js.map +1 -1
  65. package/lib/hooks/useSPFxPnPSearch.js +262 -353
  66. package/lib/hooks/useSPFxPnPSearch.js.map +1 -1
  67. package/lib/hooks/useSPFxProperties.js +12 -20
  68. package/lib/hooks/useSPFxProperties.js.map +1 -1
  69. package/lib/hooks/useSPFxSPHttpClient.js +19 -19
  70. package/lib/hooks/useSPFxSPHttpClient.js.map +1 -1
  71. package/lib/hooks/useSPFxServiceScope.js +6 -6
  72. package/lib/hooks/useSPFxServiceScope.js.map +1 -1
  73. package/lib/hooks/useSPFxSiteInfo.js +7 -8
  74. package/lib/hooks/useSPFxSiteInfo.js.map +1 -1
  75. package/lib/hooks/useSPFxStorage.js +22 -22
  76. package/lib/hooks/useSPFxStorage.js.map +1 -1
  77. package/lib/hooks/useSPFxTeams.js +37 -92
  78. package/lib/hooks/useSPFxTeams.js.map +1 -1
  79. package/lib/hooks/useSPFxTenantKeyValueStore.d.ts +252 -0
  80. package/lib/hooks/useSPFxTenantKeyValueStore.d.ts.map +1 -0
  81. package/lib/hooks/useSPFxTenantKeyValueStore.js +572 -0
  82. package/lib/hooks/useSPFxTenantKeyValueStore.js.map +1 -0
  83. package/lib/hooks/useSPFxTenantProperty.d.ts +23 -244
  84. package/lib/hooks/useSPFxTenantProperty.d.ts.map +1 -1
  85. package/lib/hooks/useSPFxTenantProperty.js +85 -559
  86. package/lib/hooks/useSPFxTenantProperty.js.map +1 -1
  87. package/lib/hooks/useSPFxUserInfo.js +3 -4
  88. package/lib/hooks/useSPFxUserInfo.js.map +1 -1
  89. package/lib/hooks/useSPFxUserPhoto.js +76 -123
  90. package/lib/hooks/useSPFxUserPhoto.js.map +1 -1
  91. package/lib/utils/resize-observer.internal.js +6 -7
  92. package/lib/utils/resize-observer.internal.js.map +1 -1
  93. package/lib/utils/theme-subscription.internal.js +8 -8
  94. package/lib/utils/theme-subscription.internal.js.map +1 -1
  95. package/lib/utils/type-guards.internal.js +6 -6
  96. package/lib/utils/type-guards.internal.js.map +1 -1
  97. package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js +12 -37
  98. package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js.map +1 -1
  99. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.d.ts.map +1 -1
  100. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js +277 -336
  101. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js.map +1 -1
  102. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js +1 -1
  103. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js.map +1 -1
  104. package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.js +26 -86
  105. package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.js.map +1 -1
  106. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.js +53 -113
  107. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.js.map +1 -1
  108. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.js +49 -121
  109. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.js.map +1 -1
  110. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.js +44 -103
  111. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.js.map +1 -1
  112. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.js +15 -15
  113. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.js.map +1 -1
  114. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.js +18 -66
  115. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.js.map +1 -1
  116. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.js +9 -9
  117. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.js.map +1 -1
  118. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.js +37 -86
  119. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.js.map +1 -1
  120. package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.js +6 -9
  121. package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.js.map +1 -1
  122. package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.js +3 -6
  123. package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.js.map +1 -1
  124. package/package.json +1 -1
@@ -1,39 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- var __generator = (this && this.__generator) || function (thisArg, body) {
11
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
- function verb(n) { return function (v) { return step([n, v]); }; }
14
- function step(op) {
15
- if (f) throw new TypeError("Generator is already executing.");
16
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
- if (y = 0, t) op = [op[0] & 2, t.value];
19
- switch (op[0]) {
20
- case 0: case 1: t = op; break;
21
- case 4: _.label++; return { value: op[1], done: false };
22
- case 5: _.label++; y = op[1]; op = [0]; continue;
23
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
- default:
25
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
- if (t[2]) _.ops.pop();
30
- _.trys.pop(); continue;
31
- }
32
- op = body.call(thisArg, _);
33
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
- }
36
- };
37
1
  import { useState, useCallback, useRef, useEffect } from 'react';
38
2
  import { useSPFxPnPContext } from './useSPFxPnPContext';
39
3
  // Import PnPjs native search
@@ -53,7 +17,7 @@ import { SearchQueryBuilder } from '@pnp/sp/search';
53
17
  * );
54
18
  * ```
55
19
  */
56
- export var SearchVerticals = {
20
+ export const SearchVerticals = {
57
21
  /**
58
22
  * All results (default) - no filtering
59
23
  */
@@ -308,364 +272,309 @@ export var SearchVerticals = {
308
272
  * ```
309
273
  */
310
274
  export function useSPFxPnPSearch(options, pnpContext) {
311
- var _this = this;
312
- var _a;
313
275
  // Get PnP context
314
- var context = useSPFxPnPContext(pnpContext === null || pnpContext === void 0 ? void 0 : pnpContext.siteUrl);
315
- var sp = context.sp;
276
+ const context = useSPFxPnPContext(pnpContext?.siteUrl);
277
+ const { sp } = context;
316
278
  // Default options
317
- var defaultPageSize = (_a = options === null || options === void 0 ? void 0 : options.pageSize) !== null && _a !== void 0 ? _a : 50;
279
+ const defaultPageSize = options?.pageSize ?? 50;
318
280
  // State
319
- var _b = useState([]), results = _b[0], setResults = _b[1];
320
- var _c = useState(0), totalResults = _c[0], setTotalResults = _c[1];
321
- var _d = useState([]), refiners = _d[0], setRefiners = _d[1];
322
- var _e = useState(false), loading = _e[0], setLoading = _e[1];
323
- var _f = useState(false), loadingMore = _f[0], setLoadingMore = _f[1];
324
- var _g = useState(undefined), error = _g[0], setError = _g[1];
325
- var _h = useState(false), hasMore = _h[0], setHasMore = _h[1];
281
+ const [results, setResults] = useState([]);
282
+ const [totalResults, setTotalResults] = useState(0);
283
+ const [refiners, setRefiners] = useState([]);
284
+ const [loading, setLoading] = useState(false);
285
+ const [loadingMore, setLoadingMore] = useState(false);
286
+ const [error, setError] = useState(undefined);
287
+ const [hasMore, setHasMore] = useState(false);
326
288
  // Tracking for pagination and refetch
327
289
  // Type is wrapper function that returns the original callback (to avoid React state comparison issues)
328
- var _j = useState(null), lastQueryBuilder = _j[0], setLastQueryBuilder = _j[1];
329
- var _k = useState(null), lastQueryText = _k[0], setLastQueryText = _k[1];
330
- var _l = useState(undefined), lastPageSize = _l[0], setLastPageSize = _l[1];
331
- var _m = useState(0), currentStartRow = _m[0], setCurrentStartRow = _m[1];
332
- var _o = useState(new Map()), appliedRefiners = _o[0], setAppliedRefiners = _o[1];
290
+ const [lastQueryBuilder, setLastQueryBuilder] = useState(null);
291
+ const [lastQueryText, setLastQueryText] = useState(null);
292
+ const [lastPageSize, setLastPageSize] = useState(undefined);
293
+ const [currentStartRow, setCurrentStartRow] = useState(0);
294
+ const [appliedRefiners, setAppliedRefiners] = useState(new Map());
333
295
  // Refs
334
- var mountedRef = useRef(true);
296
+ const mountedRef = useRef(true);
335
297
  // Cleanup on unmount
336
- useEffect(function () {
298
+ useEffect(() => {
337
299
  mountedRef.current = true;
338
300
  return function cleanup() {
339
301
  mountedRef.current = false;
340
302
  };
341
303
  }, []);
342
304
  // Clear error handler
343
- var clearError = useCallback(function () {
305
+ const clearError = useCallback(() => {
344
306
  setError(undefined);
345
307
  }, []);
346
308
  /**
347
309
  * Core search execution logic.
348
310
  * Builds query with defaults, executes search, parses results.
349
311
  */
350
- var executeSearch = useCallback(function (query, queryOptions, startRow, appendResults, overrideRefiners) { return __awaiter(_this, void 0, void 0, function () {
351
- var err, pageSize, row, builder, refinersToApply, refinementFilters_1, searchResults, rawResults, totalRows, parsedResults_1, refinerResults, parsedRefiners, finalResultsLength_1, err_1, error_1;
352
- var _a, _b, _c, _d, _e, _f, _g, _h;
353
- return __generator(this, function (_j) {
354
- switch (_j.label) {
355
- case 0:
356
- if (!sp || !(context === null || context === void 0 ? void 0 : context.isInitialized)) {
357
- err = new Error('[useSPFxPnPSearch] PnP context not initialized. Ensure @pnp/sp/search is imported.');
358
- setError(err);
359
- throw err;
360
- }
361
- _j.label = 1;
362
- case 1:
363
- _j.trys.push([1, 3, , 4]);
364
- pageSize = (_b = (_a = queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.pageSize) !== null && _a !== void 0 ? _a : lastPageSize) !== null && _b !== void 0 ? _b : defaultPageSize;
365
- row = startRow !== null && startRow !== void 0 ? startRow : 0;
366
- builder = void 0;
367
- if (typeof query === 'string') {
368
- // String query case
369
- builder = SearchQueryBuilder(query);
370
- }
371
- else {
372
- // Builder callback case
373
- builder = SearchQueryBuilder('');
374
- // Apply default options BEFORE user callback
375
- if ((options === null || options === void 0 ? void 0 : options.selectProperties) && options.selectProperties.length > 0) {
376
- builder = builder.selectProperties.apply(builder, options.selectProperties);
377
- }
378
- if (options === null || options === void 0 ? void 0 : options.refiners) {
379
- builder = builder.refiners(options.refiners);
380
- }
381
- // Let user override everything
382
- builder = query(builder);
383
- }
384
- // Apply pagination
385
- builder = builder.rowLimit(pageSize);
386
- if (row > 0) {
387
- builder = builder.startRow(row);
388
- }
389
- refinersToApply = overrideRefiners !== null && overrideRefiners !== void 0 ? overrideRefiners : appliedRefiners;
390
- if (refinersToApply.size > 0) {
391
- refinementFilters_1 = [];
392
- refinersToApply.forEach(function (values, key) {
393
- values.forEach(function (value) {
394
- refinementFilters_1.push(key + ":equals('" + value + "')");
395
- });
396
- });
397
- if (refinementFilters_1.length > 0) {
398
- builder = builder.refinementFilters.apply(builder, refinementFilters_1);
399
- }
400
- }
401
- return [4 /*yield*/, sp.search(builder)];
402
- case 2:
403
- searchResults = _j.sent();
404
- rawResults = (_c = searchResults.PrimarySearchResults) !== null && _c !== void 0 ? _c : [];
405
- totalRows = (_d = searchResults.TotalRows) !== null && _d !== void 0 ? _d : 0;
406
- parsedResults_1 = rawResults.map(function (result) {
407
- var _a, _b;
408
- // ISearchResult is already a flat object with all properties
409
- // Generate ID from Path or DocId
410
- var id = String((_b = (_a = result.DocId) !== null && _a !== void 0 ? _a : result.Path) !== null && _b !== void 0 ? _b : Math.random());
411
- var rank = result.Rank ? parseInt(String(result.Rank), 10) : undefined;
412
- return {
413
- id: id,
414
- data: result, // ISearchResult is already the data
415
- raw: result, // Keep original for reference
416
- rank: rank
417
- };
312
+ const executeSearch = useCallback(async (query, queryOptions, startRow, appendResults, overrideRefiners) => {
313
+ if (!sp || !context?.isInitialized) {
314
+ const err = new Error('[useSPFxPnPSearch] PnP context not initialized. Ensure @pnp/sp/search is imported.');
315
+ setError(err);
316
+ throw err;
317
+ }
318
+ try {
319
+ const pageSize = queryOptions?.pageSize ?? lastPageSize ?? defaultPageSize;
320
+ const row = startRow ?? 0;
321
+ // Initialize SearchQueryBuilder
322
+ let builder;
323
+ if (typeof query === 'string') {
324
+ // String query case
325
+ builder = SearchQueryBuilder(query);
326
+ }
327
+ else {
328
+ // Builder callback case
329
+ builder = SearchQueryBuilder('');
330
+ // Apply default options BEFORE user callback
331
+ if (options?.selectProperties && options.selectProperties.length > 0) {
332
+ builder = builder.selectProperties(...options.selectProperties);
333
+ }
334
+ if (options?.refiners) {
335
+ builder = builder.refiners(options.refiners);
336
+ }
337
+ // Let user override everything
338
+ builder = query(builder);
339
+ }
340
+ // Apply pagination
341
+ builder = builder.rowLimit(pageSize);
342
+ if (row > 0) {
343
+ builder = builder.startRow(row);
344
+ }
345
+ // Apply refinement filters if any
346
+ // Use overrideRefiners if provided (for applyRefiner race condition fix)
347
+ const refinersToApply = overrideRefiners ?? appliedRefiners;
348
+ if (refinersToApply.size > 0) {
349
+ const refinementFilters = [];
350
+ refinersToApply.forEach(function (values, key) {
351
+ values.forEach(function (value) {
352
+ refinementFilters.push(key + ":equals('" + value + "')");
418
353
  });
419
- refinerResults = (_h = (_g = (_f = (_e = searchResults.RawSearchResults) === null || _e === void 0 ? void 0 : _e.PrimaryQueryResult) === null || _f === void 0 ? void 0 : _f.RefinementResults) === null || _g === void 0 ? void 0 : _g.Refiners) !== null && _h !== void 0 ? _h : [];
420
- parsedRefiners = refinerResults.map(function (refiner) {
421
- var _a, _b;
354
+ });
355
+ if (refinementFilters.length > 0) {
356
+ builder = builder.refinementFilters(...refinementFilters);
357
+ }
358
+ }
359
+ // Execute search - sp.search() returns SearchResults (PnPjs v4)
360
+ // SearchResults exposes: ElapsedTime, RowCount, PrimarySearchResults, TotalRows
361
+ const searchResults = await sp.search(builder);
362
+ // PnPjs v4 SearchResults.PrimarySearchResults already contains parsed result objects
363
+ // Each result is an ISearchResult with properties like Title, Path, Rank, etc.
364
+ const rawResults = searchResults.PrimarySearchResults ?? [];
365
+ const totalRows = searchResults.TotalRows ?? 0;
366
+ // Map ISearchResult to our SearchResult<T> format
367
+ const parsedResults = rawResults.map(function (result) {
368
+ // ISearchResult is already a flat object with all properties
369
+ // Generate ID from Path or DocId
370
+ const id = String(result.DocId ?? result.Path ?? Math.random());
371
+ const rank = result.Rank ? parseInt(String(result.Rank), 10) : undefined;
372
+ return {
373
+ id: id,
374
+ data: result, // ISearchResult is already the data
375
+ raw: result, // Keep original for reference
376
+ rank: rank
377
+ };
378
+ });
379
+ // Parse refiners from RawSearchResults
380
+ // PnPjs v4: SearchResults.RawSearchResults.PrimaryQueryResult.RefinementResults.Refiners
381
+ const refinerResults = searchResults.RawSearchResults?.PrimaryQueryResult?.RefinementResults?.Refiners ?? [];
382
+ const parsedRefiners = refinerResults.map(function (refiner) {
383
+ return {
384
+ name: refiner.Name ?? '',
385
+ entries: (refiner.Entries ?? []).map(function (entry) {
422
386
  return {
423
- name: (_a = refiner.Name) !== null && _a !== void 0 ? _a : '',
424
- entries: ((_b = refiner.Entries) !== null && _b !== void 0 ? _b : []).map(function (entry) {
425
- var _a, _b;
426
- return {
427
- value: (_a = entry.RefinementName) !== null && _a !== void 0 ? _a : '',
428
- count: parseInt(entry.RefinementCount, 10) || 0,
429
- token: (_b = entry.RefinementToken) !== null && _b !== void 0 ? _b : ''
430
- };
431
- })
387
+ value: entry.RefinementName ?? '',
388
+ count: parseInt(entry.RefinementCount, 10) || 0,
389
+ token: entry.RefinementToken ?? ''
432
390
  };
433
- });
434
- // Update state
435
- if (!mountedRef.current) {
436
- return [2 /*return*/, parsedResults_1];
437
- }
438
- finalResultsLength_1 = 0;
439
- if (appendResults) {
440
- setResults(function (prev) {
441
- finalResultsLength_1 = prev.length + parsedResults_1.length;
442
- return prev.concat(parsedResults_1);
443
- });
444
- }
445
- else {
446
- finalResultsLength_1 = parsedResults_1.length;
447
- setResults(parsedResults_1);
448
- }
449
- setTotalResults(totalRows);
450
- setRefiners(parsedRefiners);
451
- setHasMore(finalResultsLength_1 < totalRows);
452
- return [2 /*return*/, parsedResults_1];
453
- case 3:
454
- err_1 = _j.sent();
455
- error_1 = err_1 instanceof Error ? err_1 : new Error(String(err_1));
456
- setError(error_1);
457
- throw error_1;
458
- case 4: return [2 /*return*/];
391
+ })
392
+ };
393
+ });
394
+ // Update state
395
+ if (!mountedRef.current) {
396
+ return parsedResults;
459
397
  }
460
- });
461
- }); }, [sp, context === null || context === void 0 ? void 0 : context.isInitialized, options, defaultPageSize, lastPageSize, appliedRefiners]);
398
+ // Calculate new results length for hasMore using functional update
399
+ // This avoids needing results.length in the dependency array
400
+ let finalResultsLength = 0;
401
+ if (appendResults) {
402
+ setResults(function (prev) {
403
+ finalResultsLength = prev.length + parsedResults.length;
404
+ return prev.concat(parsedResults);
405
+ });
406
+ }
407
+ else {
408
+ finalResultsLength = parsedResults.length;
409
+ setResults(parsedResults);
410
+ }
411
+ setTotalResults(totalRows);
412
+ setRefiners(parsedRefiners);
413
+ setHasMore(finalResultsLength < totalRows);
414
+ return parsedResults;
415
+ }
416
+ catch (err) {
417
+ const error = err instanceof Error ? err : new Error(String(err));
418
+ setError(error);
419
+ throw error;
420
+ }
421
+ }, [sp, context?.isInitialized, options, defaultPageSize, lastPageSize, appliedRefiners]);
462
422
  /**
463
423
  * Executes a search query.
464
424
  */
465
- var search = useCallback(function (query, queryOptions) { return __awaiter(_this, void 0, void 0, function () {
466
- var parsedResults;
467
- var _a;
468
- return __generator(this, function (_b) {
469
- switch (_b.label) {
470
- case 0:
471
- setLoading(true);
472
- setError(undefined);
473
- setCurrentStartRow(0);
474
- setAppliedRefiners(new Map()); // Reset refiners on new search
475
- _b.label = 1;
476
- case 1:
477
- _b.trys.push([1, , 3, 4]);
478
- // Store query for refetch/loadMore
479
- if (typeof query === 'string') {
480
- setLastQueryText(query);
481
- setLastQueryBuilder(null);
482
- }
483
- else {
484
- setLastQueryBuilder(function () { return query; });
485
- setLastQueryText(null);
486
- }
487
- setLastPageSize((_a = queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.pageSize) !== null && _a !== void 0 ? _a : defaultPageSize);
488
- return [4 /*yield*/, executeSearch(query, queryOptions, 0, false)];
489
- case 2:
490
- parsedResults = _b.sent();
491
- return [2 /*return*/, parsedResults];
492
- case 3:
493
- if (mountedRef.current) {
494
- setLoading(false);
495
- }
496
- return [7 /*endfinally*/];
497
- case 4: return [2 /*return*/];
425
+ const search = useCallback(async (query, queryOptions) => {
426
+ setLoading(true);
427
+ setError(undefined);
428
+ setCurrentStartRow(0);
429
+ setAppliedRefiners(new Map()); // Reset refiners on new search
430
+ try {
431
+ // Store query for refetch/loadMore
432
+ if (typeof query === 'string') {
433
+ setLastQueryText(query);
434
+ setLastQueryBuilder(null);
498
435
  }
499
- });
500
- }); }, [executeSearch, defaultPageSize]);
436
+ else {
437
+ setLastQueryBuilder(function () { return query; });
438
+ setLastQueryText(null);
439
+ }
440
+ setLastPageSize(queryOptions?.pageSize ?? defaultPageSize);
441
+ const parsedResults = await executeSearch(query, queryOptions, 0, false);
442
+ return parsedResults;
443
+ }
444
+ finally {
445
+ if (mountedRef.current) {
446
+ setLoading(false);
447
+ }
448
+ }
449
+ }, [executeSearch, defaultPageSize]);
501
450
  /**
502
451
  * Gets search suggestions.
503
452
  */
504
- var suggest = useCallback(function (queryText) { return __awaiter(_this, void 0, void 0, function () {
505
- var err, result, err_2, error_2;
506
- var _a;
507
- return __generator(this, function (_b) {
508
- switch (_b.label) {
509
- case 0:
510
- if (!sp || !(context === null || context === void 0 ? void 0 : context.isInitialized)) {
511
- err = new Error('[useSPFxPnPSearch] PnP context not initialized.');
512
- setError(err);
513
- throw err;
514
- }
515
- _b.label = 1;
516
- case 1:
517
- _b.trys.push([1, 3, , 4]);
518
- return [4 /*yield*/, sp.searchSuggest(queryText)];
519
- case 2:
520
- result = _b.sent();
521
- return [2 /*return*/, (_a = result.Queries) !== null && _a !== void 0 ? _a : []];
522
- case 3:
523
- err_2 = _b.sent();
524
- error_2 = err_2 instanceof Error ? err_2 : new Error(String(err_2));
525
- setError(error_2);
526
- throw error_2;
527
- case 4: return [2 /*return*/];
528
- }
529
- });
530
- }); }, [sp, context === null || context === void 0 ? void 0 : context.isInitialized]);
453
+ const suggest = useCallback(async (queryText) => {
454
+ if (!sp || !context?.isInitialized) {
455
+ const err = new Error('[useSPFxPnPSearch] PnP context not initialized.');
456
+ setError(err);
457
+ throw err;
458
+ }
459
+ try {
460
+ const result = await sp.searchSuggest(queryText);
461
+ return result.Queries ?? [];
462
+ }
463
+ catch (err) {
464
+ const error = err instanceof Error ? err : new Error(String(err));
465
+ setError(error);
466
+ throw error;
467
+ }
468
+ }, [sp, context?.isInitialized]);
531
469
  /**
532
470
  * Loads more results (pagination).
533
471
  */
534
- var loadMore = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
535
- var err, err, nextStartRow, query, parsedResults;
536
- return __generator(this, function (_a) {
537
- switch (_a.label) {
538
- case 0:
539
- if (!lastQueryBuilder && !lastQueryText) {
540
- err = new Error('[useSPFxPnPSearch] No previous search to load more from. Call search() first.');
541
- setError(err);
542
- throw err;
543
- }
544
- if (!lastPageSize) {
545
- err = new Error('[useSPFxPnPSearch] Cannot loadMore without pageSize. Specify pageSize in options or search call.');
546
- setError(err);
547
- throw err;
548
- }
549
- setLoadingMore(true);
550
- setError(undefined);
551
- _a.label = 1;
552
- case 1:
553
- _a.trys.push([1, , 3, 4]);
554
- nextStartRow = currentStartRow + lastPageSize;
555
- query = lastQueryBuilder
556
- ? lastQueryBuilder()
557
- : lastQueryText;
558
- return [4 /*yield*/, executeSearch(query, { pageSize: lastPageSize }, nextStartRow, true // Append results
559
- )];
560
- case 2:
561
- parsedResults = _a.sent();
562
- setCurrentStartRow(nextStartRow);
563
- return [2 /*return*/, parsedResults];
564
- case 3:
565
- if (mountedRef.current) {
566
- setLoadingMore(false);
567
- }
568
- return [7 /*endfinally*/];
569
- case 4: return [2 /*return*/];
472
+ const loadMore = useCallback(async () => {
473
+ if (!lastQueryBuilder && !lastQueryText) {
474
+ const err = new Error('[useSPFxPnPSearch] No previous search to load more from. Call search() first.');
475
+ setError(err);
476
+ throw err;
477
+ }
478
+ if (!lastPageSize) {
479
+ const err = new Error('[useSPFxPnPSearch] Cannot loadMore without pageSize. Specify pageSize in options or search call.');
480
+ setError(err);
481
+ throw err;
482
+ }
483
+ setLoadingMore(true);
484
+ setError(undefined);
485
+ try {
486
+ const nextStartRow = currentStartRow + lastPageSize;
487
+ // Call lastQueryBuilder() to get the original callback function
488
+ const query = lastQueryBuilder
489
+ ? lastQueryBuilder()
490
+ : lastQueryText;
491
+ const parsedResults = await executeSearch(query, { pageSize: lastPageSize }, nextStartRow, true // Append results
492
+ );
493
+ setCurrentStartRow(nextStartRow);
494
+ return parsedResults;
495
+ }
496
+ finally {
497
+ if (mountedRef.current) {
498
+ setLoadingMore(false);
570
499
  }
571
- });
572
- }); }, [lastQueryBuilder, lastQueryText, lastPageSize, currentStartRow, executeSearch]);
500
+ }
501
+ }, [lastQueryBuilder, lastQueryText, lastPageSize, currentStartRow, executeSearch]);
573
502
  /**
574
503
  * Re-executes the last search.
575
504
  */
576
- var refetch = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
577
- var err, query;
578
- return __generator(this, function (_a) {
579
- switch (_a.label) {
580
- case 0:
581
- if (!lastQueryBuilder && !lastQueryText) {
582
- err = new Error('[useSPFxPnPSearch] No previous search to refetch. Call search() first.');
583
- setError(err);
584
- throw err;
585
- }
586
- setLoading(true);
587
- setError(undefined);
588
- setCurrentStartRow(0);
589
- _a.label = 1;
590
- case 1:
591
- _a.trys.push([1, , 3, 4]);
592
- query = lastQueryBuilder
593
- ? lastQueryBuilder()
594
- : lastQueryText;
595
- return [4 /*yield*/, executeSearch(query, { pageSize: lastPageSize }, 0, false)];
596
- case 2:
597
- _a.sent();
598
- return [3 /*break*/, 4];
599
- case 3:
600
- if (mountedRef.current) {
601
- setLoading(false);
602
- }
603
- return [7 /*endfinally*/];
604
- case 4: return [2 /*return*/];
505
+ const refetch = useCallback(async () => {
506
+ if (!lastQueryBuilder && !lastQueryText) {
507
+ const err = new Error('[useSPFxPnPSearch] No previous search to refetch. Call search() first.');
508
+ setError(err);
509
+ throw err;
510
+ }
511
+ setLoading(true);
512
+ setError(undefined);
513
+ setCurrentStartRow(0);
514
+ try {
515
+ // Call lastQueryBuilder() to get the original callback function
516
+ const query = lastQueryBuilder
517
+ ? lastQueryBuilder()
518
+ : lastQueryText;
519
+ await executeSearch(query, { pageSize: lastPageSize }, 0, false);
520
+ }
521
+ finally {
522
+ if (mountedRef.current) {
523
+ setLoading(false);
605
524
  }
606
- });
607
- }); }, [lastQueryBuilder, lastQueryText, lastPageSize, executeSearch]);
525
+ }
526
+ }, [lastQueryBuilder, lastQueryText, lastPageSize, executeSearch]);
608
527
  /**
609
528
  * Applies a refiner filter to the current search.
610
529
  */
611
- var applyRefiner = useCallback(function (refinerName, refinerValue) { return __awaiter(_this, void 0, void 0, function () {
612
- var err, newRefiners, existing, index, updated, query;
613
- var _a;
614
- return __generator(this, function (_b) {
615
- switch (_b.label) {
616
- case 0:
617
- if (!lastQueryBuilder && !lastQueryText) {
618
- err = new Error('[useSPFxPnPSearch] No previous search to apply refiner to. Call search() first.');
619
- setError(err);
620
- throw err;
621
- }
622
- newRefiners = new Map();
623
- appliedRefiners.forEach(function (value, key) {
624
- newRefiners.set(key, value);
625
- });
626
- existing = (_a = newRefiners.get(refinerName)) !== null && _a !== void 0 ? _a : [];
627
- index = existing.indexOf(refinerValue);
628
- if (index > -1) {
629
- updated = existing.slice();
630
- updated.splice(index, 1);
631
- if (updated.length === 0) {
632
- newRefiners.delete(refinerName);
633
- }
634
- else {
635
- newRefiners.set(refinerName, updated);
636
- }
637
- }
638
- else {
639
- newRefiners.set(refinerName, existing.concat([refinerValue]));
640
- }
641
- // Update state for UI
642
- setAppliedRefiners(newRefiners);
643
- // Re-execute search with new refiners passed directly
644
- // This avoids the race condition where state isn't updated yet
645
- setLoading(true);
646
- setError(undefined);
647
- setCurrentStartRow(0);
648
- _b.label = 1;
649
- case 1:
650
- _b.trys.push([1, , 3, 4]);
651
- query = lastQueryBuilder
652
- ? lastQueryBuilder()
653
- : lastQueryText;
654
- // Pass newRefiners directly to avoid race condition
655
- return [4 /*yield*/, executeSearch(query, { pageSize: lastPageSize }, 0, false, newRefiners)];
656
- case 2:
657
- // Pass newRefiners directly to avoid race condition
658
- _b.sent();
659
- return [3 /*break*/, 4];
660
- case 3:
661
- if (mountedRef.current) {
662
- setLoading(false);
663
- }
664
- return [7 /*endfinally*/];
665
- case 4: return [2 /*return*/];
666
- }
530
+ const applyRefiner = useCallback(async (refinerName, refinerValue) => {
531
+ if (!lastQueryBuilder && !lastQueryText) {
532
+ const err = new Error('[useSPFxPnPSearch] No previous search to apply refiner to. Call search() first.');
533
+ setError(err);
534
+ throw err;
535
+ }
536
+ // Calculate new refiners map (toggle logic)
537
+ const newRefiners = new Map();
538
+ appliedRefiners.forEach(function (value, key) {
539
+ newRefiners.set(key, value);
667
540
  });
668
- }); }, [lastQueryBuilder, lastQueryText, lastPageSize, appliedRefiners, executeSearch]);
541
+ const existing = newRefiners.get(refinerName) ?? [];
542
+ // Toggle: if already exists, remove; otherwise add
543
+ const index = existing.indexOf(refinerValue);
544
+ if (index > -1) {
545
+ const updated = existing.slice();
546
+ updated.splice(index, 1);
547
+ if (updated.length === 0) {
548
+ newRefiners.delete(refinerName);
549
+ }
550
+ else {
551
+ newRefiners.set(refinerName, updated);
552
+ }
553
+ }
554
+ else {
555
+ newRefiners.set(refinerName, existing.concat([refinerValue]));
556
+ }
557
+ // Update state for UI
558
+ setAppliedRefiners(newRefiners);
559
+ // Re-execute search with new refiners passed directly
560
+ // This avoids the race condition where state isn't updated yet
561
+ setLoading(true);
562
+ setError(undefined);
563
+ setCurrentStartRow(0);
564
+ try {
565
+ // Call lastQueryBuilder() to get the original callback function
566
+ const query = lastQueryBuilder
567
+ ? lastQueryBuilder()
568
+ : lastQueryText;
569
+ // Pass newRefiners directly to avoid race condition
570
+ await executeSearch(query, { pageSize: lastPageSize }, 0, false, newRefiners);
571
+ }
572
+ finally {
573
+ if (mountedRef.current) {
574
+ setLoading(false);
575
+ }
576
+ }
577
+ }, [lastQueryBuilder, lastQueryText, lastPageSize, appliedRefiners, executeSearch]);
669
578
  return {
670
579
  search: search,
671
580
  suggest: suggest,