Files
request-portal/src/webparts/requestPortal/shared/pnp/pnpjs.ts
T
2026-08-21 10:01:33 +00:00

56 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { spfi, SPFI, SPFx } from '@pnp/sp';
import '@pnp/sp/webs';
import '@pnp/sp/lists';
import '@pnp/sp/items';
import '@pnp/sp/attachments';
import '@pnp/sp/site-users/web';
import { BrowserFetchWithRetry } from '@pnp/queryable';
import { WebPartContext } from '@microsoft/sp-webpart-base';
import { DATA_SITE_URL } from '../config';
import { PerfObserver } from '../perfTrace';
// PerfObserver подключён к ОБОИМ клиентам ниже: это единственное место, через
// которое проходит любой SharePoint-запрос портала, поэтому отладочный замер
// (window.rpPerf, см. shared/perfTrace.ts) покрывает сразу все разделы — и
// списки заявок, и формы, и панель заявки, — а не только те, где расставлены
// метки этапов вручную. Выключенный замер не делает ничего дороже чтения флага.
// Мягкая ретрай-политика вместо стандартной PnPjs (retries: 3, interval: 200).
// Дефолт слишком напорист: при отказе (429 «слишком много запросов», 503) он
// начинает повторять почти сразу, что при массовой загрузке только усугубляет
// throttling со стороны SharePoint. Здесь меньше попыток и заметно длиннее
// первая пауза; интервал в PnPjs удваивается с каждой попыткой, так что выходит
// примерно 1.5с → 3с.
const RETRY = { retries: 2, interval: 1500 };
// Единый инициализированный клиент PnPjs на весь web part.
let _sp: SPFI | undefined;
/**
* Инициализировать PnPjs контекстом web part. Вызывать один раз в onInit.
* Клиент нацелен на сайт данных (DATA_SITE_URL), а не на текущий сайт, —
* списки живут там, где бы ни стоял сам web part. Авторизация берётся из context.
*/
export function initSP(context: WebPartContext): void {
_sp = spfi(DATA_SITE_URL).using(SPFx(context), BrowserFetchWithRetry(RETRY), PerfObserver());
}
/**
* Клиент для ПРОИЗВОЛЬНОГО сайта (списки типов заявок живут на разных сайтах,
* см. approval-route API). В отличие от getSP() не кэшируется — адрес сайта
* приходит из данных. Ретрай-политика та же, что и у основного клиента:
* BrowserFetchWithRetry идёт ПОСЛЕ SPFx, поэтому заменяет его обработчик
* отправки (у behavior replace: true по умолчанию).
*/
export function spForSite(siteUrl: string, context: WebPartContext): SPFI {
return spfi(siteUrl).using(SPFx(context), BrowserFetchWithRetry(RETRY), PerfObserver());
}
/** Получить инициализированный клиент. Бросает, если initSP не был вызван. */
export function getSP(): SPFI {
if (!_sp) {
throw new Error('PnPjs не инициализирован: вызовите initSP(context) в onInit web part.');
}
return _sp;
}