@ryuzaki13/react-foundation-lib 1.8.2 → 1.9.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.
- package/dist/excel/index.js +9 -1
- package/dist/excel/index.js.map +1 -1
- package/dist/excel/matrixWorkbook.d.ts +11 -0
- package/dist/excel/matrixWorkbook.d.ts.map +1 -1
- package/dist/pwa/index.d.ts +1 -0
- package/dist/pwa/index.d.ts.map +1 -1
- package/dist/pwa/index.js +75 -59
- package/dist/pwa/index.js.map +1 -1
- package/dist/pwa/useBrowserOnlineStatus.d.ts +3 -0
- package/dist/pwa/useBrowserOnlineStatus.d.ts.map +1 -0
- package/dist/query-client/index.js +137 -43
- package/dist/query-client/index.js.map +1 -1
- package/dist/query-client/persistence.d.ts +21 -3
- package/dist/query-client/persistence.d.ts.map +1 -1
- package/dist/query-client/queryMeta.d.ts +21 -2
- package/dist/query-client/queryMeta.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/excel/README.mdx +8 -0
- package/src/pwa/README.mdx +4 -0
- package/src/query-client/README.mdx +48 -7
package/src/excel/README.mdx
CHANGED
|
@@ -253,6 +253,9 @@ await downloadExcelWorkbook({
|
|
|
253
253
|
import { downloadExcelMatrixWorkbook } from "@ryuzaki13/react-foundation-lib/excel";
|
|
254
254
|
|
|
255
255
|
await downloadExcelMatrixWorkbook("Расписание.xlsx", {
|
|
256
|
+
// Базовый шрифт Normal определяет, сколько пикселей занимает символьная
|
|
257
|
+
// ширина из `columns[].width`, даже если ячейки используют другой шрифт.
|
|
258
|
+
defaultFont: { fontFamily: "Verdana", fontSize: 12 },
|
|
256
259
|
sheets: [
|
|
257
260
|
{
|
|
258
261
|
name: "Неделя",
|
|
@@ -280,6 +283,11 @@ await downloadExcelMatrixWorkbook("Расписание.xlsx", {
|
|
|
280
283
|
быть целыми неотрицательными: ноль означает автоматическое число страниц по
|
|
281
284
|
этой оси.
|
|
282
285
|
|
|
286
|
+
`defaultFont` задаёт шрифт стиля Normal всей книги. Excel измеряет символьную
|
|
287
|
+
ширину столбца относительно этого шрифта, поэтому одинаковое значение
|
|
288
|
+
`columns[].width` при разных базовых шрифтах может давать разную ширину в
|
|
289
|
+
пикселях. Стили отдельных ячеек при этом остаются независимыми.
|
|
290
|
+
|
|
283
291
|
`createExcelMatrixWorkbookBlob` не инициирует скачивание и подходит для preview
|
|
284
292
|
и проверки сформированного файла. `downloadExcelMatrixWorkbook` делегирует
|
|
285
293
|
browser download общему `downloadFileFromBlob`.
|
package/src/pwa/README.mdx
CHANGED
|
@@ -13,6 +13,9 @@ import { Meta } from "@storybook/addon-docs/blocks";
|
|
|
13
13
|
|
|
14
14
|
Используйте точный subpath. Внутренний файл `serviceWorker` не является самостоятельным публичным export, даже если отдельные функции используются самим hook.
|
|
15
15
|
|
|
16
|
+
`useBrowserOnlineStatus()` возвращает browser hint `navigator.onLine` через `useSyncExternalStore` и подписывается на события
|
|
17
|
+
`online`/`offline`. Это сигнал для UX и запуска revalidation, а не доказательство доступности конкретного backend.
|
|
18
|
+
|
|
16
19
|
## Часть 1. Обновление Service Worker
|
|
17
20
|
|
|
18
21
|
### Задача hook
|
|
@@ -378,6 +381,7 @@ Waiting worker остаётся установленным. Следующая
|
|
|
378
381
|
| Экспорт | Публичный path | Назначение |
|
|
379
382
|
| ----------------------------------- | -------------- | -------------------------------------------------- |
|
|
380
383
|
| `useServiceWorkerUpdate()` | `/pwa` | Регистрация, проверка и UI-состояние обновления SW |
|
|
384
|
+
| `useBrowserOnlineStatus()` | `/pwa` | Реактивный browser online/offline hint |
|
|
381
385
|
| `parseSwCachePolicy()` | оба | Разобрать текстовую политику |
|
|
382
386
|
| `buildSwCachePolicyValue()` | оба | Собрать каноническую строку из draft |
|
|
383
387
|
| `normalizeSwCacheName()` | оба | Подготовить безопасную часть cache name |
|
|
@@ -274,12 +274,14 @@ Stale не означает «удалена». Data может продолжа
|
|
|
274
274
|
| Нужны данные только пока открыта вкладка? | Обычная query без `persistedQueryMeta`. |
|
|
275
275
|
| Данные публичные, тяжёлые и могут пережить reload? | Рассмотреть `persistedQueryMeta`. |
|
|
276
276
|
| Данные зависят от пользователя, роли или server session? | `sessionScopedQueryMeta`. |
|
|
277
|
+
| Session snapshot явно разрешено читать offline? | `createSessionQueryPersistenceMeta` + active scope. |
|
|
277
278
|
| Нужно передать обновление другой открытой вкладке? | Broadcast installation и подходящее cache event. |
|
|
278
279
|
| UI должен измениться до ответа mutation? | Optimistic update с обязательным rollback policy. |
|
|
279
280
|
| Server response авторитетен и уже содержит новое состояние? | `setQueryData`/`onSuccessOptimistic`. |
|
|
280
281
|
| После mutation нужен свежий server snapshot? | Scoped `invalidateQueries` с выбранным `refetchType`. |
|
|
281
282
|
|
|
282
|
-
`persistedQueryMeta` и `sessionScopedQueryMeta` взаимоисключающие.
|
|
283
|
+
`persistedQueryMeta` и `sessionScopedQueryMeta` взаимоисключающие. Для узкого offline allowlist session data используется
|
|
284
|
+
отдельный `sessionPersistence` contract: он требует активную server-session identity и абсолютный `expiresAt`.
|
|
283
285
|
|
|
284
286
|
## Быстрый старт
|
|
285
287
|
|
|
@@ -489,7 +491,8 @@ queryOptions({
|
|
|
489
491
|
});
|
|
490
492
|
```
|
|
491
493
|
|
|
492
|
-
`Record<string, unknown>` разрешает consumer-проекту добавлять собственную metadata. Infrastructure этого модуля читает
|
|
494
|
+
`Record<string, unknown>` разрешает consumer-проекту добавлять собственную metadata. Infrastructure этого модуля читает
|
|
495
|
+
`persist`, `sessionScoped` и явный `sessionPersistence` contract.
|
|
493
496
|
|
|
494
497
|
### `persistedQueryMeta`
|
|
495
498
|
|
|
@@ -533,6 +536,36 @@ queryOptions({
|
|
|
533
536
|
|
|
534
537
|
При смене сессии host обязан вызвать `resetSessionScopedQueries`.
|
|
535
538
|
|
|
539
|
+
### Session-scoped offline persistence
|
|
540
|
+
|
|
541
|
+
Только для явно согласованного offline allowlist создайте bounded metadata:
|
|
542
|
+
|
|
543
|
+
```ts
|
|
544
|
+
import {
|
|
545
|
+
createSessionQueryPersistenceMeta,
|
|
546
|
+
setSessionQueryPersistenceScope
|
|
547
|
+
} from "@ryuzaki13/react-foundation-lib/query-client";
|
|
548
|
+
|
|
549
|
+
await setSessionQueryPersistenceScope({
|
|
550
|
+
id: session.id,
|
|
551
|
+
expiresAt: session.expiresAt
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
queryOptions({
|
|
555
|
+
queryKey: ["opened-week", weekStart],
|
|
556
|
+
queryFn: fetchWeek,
|
|
557
|
+
meta: createSessionQueryPersistenceMeta({
|
|
558
|
+
cacheName: "opened-weeks",
|
|
559
|
+
maxEntries: 24
|
|
560
|
+
}),
|
|
561
|
+
networkMode: "offlineFirst"
|
|
562
|
+
});
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
Scope устанавливается отдельно от query contract, не содержит cookie secret/access token и меняет in-memory границу до очистки IndexedDB.
|
|
566
|
+
При `null`, истёкшем `expiresAt` или смене `id` старые session snapshots удаляются. `networkMode: "offlineFirst"` нужен, чтобы
|
|
567
|
+
TanStack вызвал persister до network pause. Cached data остаётся неавторитетным: write после reconnect обязан повторно получить серверный state.
|
|
568
|
+
|
|
536
569
|
### Meta нельзя совмещать
|
|
537
570
|
|
|
538
571
|
Неверно:
|
|
@@ -550,13 +583,14 @@ meta: {
|
|
|
550
583
|
|
|
551
584
|
- публичный/безопасный долгоживущий справочник → `persistedQueryMeta`;
|
|
552
585
|
- auth/session dependent data → `sessionScopedQueryMeta`;
|
|
586
|
+
- разрешённый bounded offline snapshot → `createSessionQueryPersistenceMeta`;
|
|
553
587
|
- обычные transient data → meta не нужна.
|
|
554
588
|
|
|
555
589
|
## Настройка project adapter
|
|
556
590
|
|
|
557
591
|
### Зачем нужен adapter
|
|
558
592
|
|
|
559
|
-
Foundation-пакет не знает имя SAP system, client, tenant или окружение конкретного приложения. `QueryPersistenceProjectAdapter` позволяет host передать устойчивый namespace и собственный buster:
|
|
593
|
+
Foundation-пакет не знает имя SAP system, client, tenant или окружение конкретного приложения. `QueryPersistenceProjectAdapter` позволяет host передать устойчивый namespace и собственный buster. Текущая session identity задаётся отдельным runtime API и не входит в adapter:
|
|
560
594
|
|
|
561
595
|
```ts
|
|
562
596
|
type QueryPersistenceProjectAdapter = {
|
|
@@ -778,7 +812,8 @@ Storage не скрывает ошибки. Promise отклоняется, ес
|
|
|
778
812
|
const persister = createReactQueryPersister();
|
|
779
813
|
```
|
|
780
814
|
|
|
781
|
-
Возвращает
|
|
815
|
+
Возвращает routing-обёртку над `experimental_createQueryPersister` либо `undefined`, если IndexedDB недоступен. Обычные public query
|
|
816
|
+
идут в прежний persister, а query с `sessionPersistence` — в отдельный cache активной сессии с независимым `maxEntries`.
|
|
782
817
|
|
|
783
818
|
Настройки foundation wrapper:
|
|
784
819
|
|
|
@@ -2356,9 +2391,11 @@ Profile tests подтверждают:
|
|
|
2356
2391
|
|
|
2357
2392
|
| Symbol | Вид | Назначение |
|
|
2358
2393
|
| ------------------------ | ----- | ----------------------------------------------- |
|
|
2359
|
-
| `AppQueryMeta`
|
|
2360
|
-
| `
|
|
2361
|
-
| `
|
|
2394
|
+
| `AppQueryMeta` | type | Public/session persistence и consumer metadata. |
|
|
2395
|
+
| `SessionQueryPersistencePolicy` | type | Имя и bounded limit session cache. |
|
|
2396
|
+
| `persistedQueryMeta` | const | Opt-in public persistence marker. |
|
|
2397
|
+
| `sessionScopedQueryMeta` | const | Session reset marker без browser persistence. |
|
|
2398
|
+
| `createSessionQueryPersistenceMeta` | function | Явный opt-in bounded persistence текущей server session. |
|
|
2362
2399
|
|
|
2363
2400
|
### Persistence project adapter
|
|
2364
2401
|
|
|
@@ -2377,6 +2414,10 @@ Profile tests подтверждают:
|
|
|
2377
2414
|
| `shouldPersistQuery` | function | Opt-in predicate с session safety. |
|
|
2378
2415
|
| `createIndexedDbQueryStorage` | function | AsyncStorage поверх IndexedDB. |
|
|
2379
2416
|
| `createReactQueryPersister` | function | Настроенный per-query TanStack persister. |
|
|
2417
|
+
| `SessionQueryPersistenceScope` | type | Public session id и абсолютный expiresAt. |
|
|
2418
|
+
| `getSessionQueryPersistenceScope` | function | Читает валидный активный browser scope. |
|
|
2419
|
+
| `setSessionQueryPersistenceScope` | function | Меняет scope и очищает чужие snapshots. |
|
|
2420
|
+
| `clearSessionQueryPersistence` | function | Удаляет один или все session snapshots. |
|
|
2380
2421
|
|
|
2381
2422
|
Options type `createIndexedDbQueryStorage` не экспортируется отдельным symbol; используйте структурный object или `Parameters<typeof createIndexedDbQueryStorage>[0]`.
|
|
2382
2423
|
|