sass-template-common 0.10.14 → 0.10.16

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/README.md CHANGED
@@ -1,36 +1,36 @@
1
- # sass-template-common
2
-
3
- Librería web, maqueta de configuración y componentes para proyectos sass.
4
-
5
- ## Publicar nueva versión
6
-
7
- Para que los cambios se reflejen al publicar:
8
-
9
- 1. **Subir versión** (obligatorio; si no, npm rechaza o se usa la misma versión):
10
- ```bash
11
- pnpm version:patch # 0.3.21 → 0.3.22
12
- # o
13
- pnpm version:minor # 0.3.21 → 0.4.0
14
- pnpm version:major # 0.3.21 → 1.0.0
15
- ```
16
-
17
- 2. **Build limpio + publicar**:
18
- ```bash
19
- pnpm run clean && pnpm run build && pnpm publish
20
- ```
21
- O en un solo paso (patch):
22
- ```bash
23
- pnpm release:patch
24
- ```
25
-
26
- 3. **`prepublishOnly`**: Antes de cada `pnpm publish` se ejecuta `clean` + `build`, así siempre se publica un build nuevo.
27
-
28
- 4. **En proyectos que consumen la lib**: Actualizar la dependencia y reinstalar:
29
- ```bash
30
- pnpm update sass-template-common
31
- # o cambiar la versión en package.json y luego
32
- pnpm install
33
- ```
34
- Si usan versión fija (`"0.3.21"`), hay que actualizarla a la nueva (p. ej. `"0.3.22"`).
35
-
36
- **Si no ves los cambios:** comprueba que subiste la versión (`version:patch` o similar), que hiciste `clean` + `build` antes de publicar, y que el proyecto consumidor tiene actualizada la dependencia (o `^0.3.21` y ha ejecutado `pnpm update`).
1
+ # sass-template-common
2
+
3
+ Librería web, maqueta de configuración y componentes para proyectos sass.
4
+
5
+ ## Publicar nueva versión
6
+
7
+ Para que los cambios se reflejen al publicar:
8
+
9
+ 1. **Subir versión** (obligatorio; si no, npm rechaza o se usa la misma versión):
10
+ ```bash
11
+ pnpm version:patch # 0.3.21 → 0.3.22
12
+ # o
13
+ pnpm version:minor # 0.3.21 → 0.4.0
14
+ pnpm version:major # 0.3.21 → 1.0.0
15
+ ```
16
+
17
+ 2. **Build limpio + publicar**:
18
+ ```bash
19
+ pnpm run clean && pnpm run build && pnpm publish
20
+ ```
21
+ O en un solo paso (patch):
22
+ ```bash
23
+ pnpm release:patch
24
+ ```
25
+
26
+ 3. **`prepublishOnly`**: Antes de cada `pnpm publish` se ejecuta `clean` + `build`, así siempre se publica un build nuevo.
27
+
28
+ 4. **En proyectos que consumen la lib**: Actualizar la dependencia y reinstalar:
29
+ ```bash
30
+ pnpm update sass-template-common
31
+ # o cambiar la versión en package.json y luego
32
+ pnpm install
33
+ ```
34
+ Si usan versión fija (`"0.3.21"`), hay que actualizarla a la nueva (p. ej. `"0.3.22"`).
35
+
36
+ **Si no ves los cambios:** comprueba que subiste la versión (`version:patch` o similar), que hiciste `clean` + `build` antes de publicar, y que el proyecto consumidor tiene actualizada la dependencia (o `^0.3.21` y ha ejecutado `pnpm update`).
@@ -244,29 +244,51 @@ export declare type BucketOriginConfig = {
244
244
  proxyUrl?: string;
245
245
  /** Prefijo raíz del cliente dentro del bucket (ej. `'debate'`). */
246
246
  clientName: string;
247
- /** Sirve el menú (sidebar/menu/footer/freeZone/cintillo + equipos/sites) desde el bucket. */
247
+ /**
248
+ * Sirve el menú (sidebar/menu/footer/freeZone/cintillo + equipos/sites) desde
249
+ * el bucket. Con el toggle ON, SIN fallback a CMS: si el bucket agota los 4
250
+ * intentos, se sirve vacío + registro en el debugPanel (`reportBucketOriginExhausted`).
251
+ */
248
252
  menu?: boolean;
249
- /** Sirve los banners (home/seccion/nota) desde el bucket. */
253
+ /**
254
+ * Sirve los banners (home/seccion/nota) desde el bucket. Con el toggle ON, SIN
255
+ * fallback a CMS: si el bucket agota los 4 intentos, se sirve vacío + registro
256
+ * en el debugPanel.
257
+ */
250
258
  banners?: boolean;
251
259
  /**
252
260
  * [transicional] Sirve la config de los slots dinámicos de home
253
261
  * (`bloques/modulos-dinamicos/modulos-dinamicos.json`) desde el bucket en
254
262
  * lugar del fan-out N contra `/config/blocks-saas`. Toggle de migración: al
255
263
  * pasar todos los sitios a `true`, la rama legacy CMS se elimina y el toggle
256
- * queda no-op (luego se remueve). Requiere el adapter
257
- * `mapBucketModulesToSlots`, aún sin implementar por depender del shape real
258
- * del JSON ver `PLAN_DYNAMIC_SLOTS_BUCKET_ORIGIN.md` §2. NO prender hasta
259
- * que el adapter exista (hoy lanza si se activa).
264
+ * queda no-op (luego se remueve). El JSON keyea plano `Home_N` (sin subíndices);
265
+ * cada entry se resuelve con `resolveSlotContent` (content-fetch al CMS igual
266
+ * que legacy). SIN fallback de CONFIG a CMS: con el toggle ON el bucket es el
267
+ * método único; si agota los 4 intentos, los slots se sirven vacíos y se
268
+ * registra en el debugPanel (`reportBucketOriginExhausted`) para notar la falla.
269
+ * El fan-out CMS solo corre con el toggle OFF (sitios sin migrar).
270
+ * Ver `PLAN_DYNAMIC_SLOTS_BUCKET_ORIGIN.md` §4.3/§7.
260
271
  */
261
272
  slots?: boolean;
262
273
  /**
263
274
  * [transicional] Sirve la config del destacado dinámico
264
275
  * (`bloques/destacado/destacado.json`) desde el bucket en lugar de
265
- * `/config/blocks`. Drop-in 1→1: asume el mismo envelope `{ data: [...] }`
266
- * que el endpoint CMS (verificar contra el archivo real antes de prender
267
- * `PLAN_DYNAMIC_SLOTS_BUCKET_ORIGIN.md` §2 Q4). Cae al CMS legacy si el
268
- * bucket agota reintentos, igual que `menu`/`banners`. Al migrar todos los
269
- * sitios la rama legacy se elimina y el toggle queda no-op.
276
+ * `/config/blocks`. Es drop-in de TRANSPORTE (mismo `.data.data` que el CMS).
277
+ * CONTRATO (verificado contra un sitio CMS funcional, golfo): el LAYOUT del
278
+ * destacado va en `data[0].block`, que debe ser uno de los 5 nombres de layout
279
+ * (`Diario` | `Diario con imagen` | `Super` | `3 notas verticales` |
280
+ * `3 notas horizontales`) — es la key que consume `DynamicMainSlot` vía el prop
281
+ * `component`. Los campos `value`/`size`/`title`/`link` NO los usa el destacado
282
+ * (en el CMS vuelven como tokens sin rellenar) → se ignoran. (Nota: existe
283
+ * `getMainBlockData`, que lee `value` contra `GetByOptions`, pero es otra ruta
284
+ * que el render vivo de golfo no usa.)
285
+ * El CONTENIDO (las notas) SIEMPRE sale del CMS (zona `destacadas`, sección
286
+ * provista por la app) — permanente, no transicional: este toggle solo mueve el
287
+ * ORIGEN DE LA CONFIG (bucket vs CMS), nunca el contenido. SIN fallback de CONFIG
288
+ * a CMS: con el toggle ON el bucket es el método único; si agota los 4 intentos,
289
+ * el destacado se sirve vacío y se registra en el debugPanel (`reportBucketOriginExhausted`).
290
+ * El CMS solo sirve la config con el toggle OFF (sitios sin migrar).
291
+ * Ver `PLAN_DYNAMIC_SLOTS_BUCKET_ORIGIN.md` §4.4/§7.
270
292
  */
271
293
  destacado?: boolean;
272
294
  /**
@@ -553,9 +575,7 @@ export declare class CommonServices {
553
575
  getEntitySection: (params: Params) => Promise<AxiosResponse<{
554
576
  data: Array<NewListResponse>;
555
577
  }, any, {}>> | undefined;
556
- getMainMenu: (params: Params) => Promise<AxiosResponse<{
557
- data: Array<MenuResponse>;
558
- }, any, {}> | {
578
+ getMainMenu: (params: Params) => Promise<{
559
579
  data: {
560
580
  data: Array<MenuResponse>;
561
581
  };
@@ -583,9 +603,7 @@ export declare class CommonServices {
583
603
  getVideosList: (params: Params) => Promise<AxiosResponse<{
584
604
  data: Array<VideoResponseData>;
585
605
  }, any, {}>> | undefined;
586
- getBanners: (params: Params) => Promise<AxiosResponse<{
587
- data: Array<BannerResponse>;
588
- }, any, {}> | {
606
+ getBanners: (params: Params) => Promise<{
589
607
  data: {
590
608
  data: Array<BannerResponse>;
591
609
  };
@@ -1050,7 +1068,7 @@ export declare class DynamicBlockServices extends CommonServices {
1050
1068
  }>;
1051
1069
  }
1052
1070
 
1053
- export declare const DynamicComponents: ({ slots, DYNAMIC_SLOT_SUBINDEXES, stylesConfig, AutorIcon, config, banners, showTagBySection, pathname, }: Props_21) => JSX.Element[];
1071
+ export declare const DynamicComponents: ({ slots, DYNAMIC_SLOT_SUBINDEXES, stylesConfig, AutorIcon, config, banners, showTagBySection, pathname, }: Props_21) => ReactNode[];
1054
1072
 
1055
1073
  export declare const DynamicMainSlot: ({ component, data, banners, rightOnlyBanner, isHome, }: Props_20) => JSX.Element;
1056
1074
 
@@ -1147,7 +1165,10 @@ export declare function fetchMaybeBatched(route: string, fetchFn: (size: number,
1147
1165
  * Cache in-memory + deduplicación de requests en vuelo (misma clave → misma promesa).
1148
1166
  * TTL corto pensado para SSR: evita 4–5 GETs repetidos de menú/banners por instancia.
1149
1167
  */
1150
- export declare function fetchWithConfigCache<T>(cacheKey: string, fetchFn: () => Promise<T>, ttlMs?: number): Promise<T>;
1168
+ export declare function fetchWithConfigCache<T>(cacheKey: string, fetchFn: () => Promise<T>, options?: number | {
1169
+ ttlMs?: number;
1170
+ shouldCache?: (value: T) => boolean;
1171
+ }): Promise<T>;
1151
1172
 
1152
1173
  export declare const Font: ({ config }: {
1153
1174
  config: Config;
@@ -1954,6 +1975,12 @@ export declare type LibraryConfig = {
1954
1975
  * comportamiento no cambia (sigue yendo al CMS). Si un archivo no existe
1955
1976
  * en el bucket para un sitio/tipo dado, el request falla simple (sin
1956
1977
  * fallback automático al CMS) — igual que cualquier otro fetch fallido.
1978
+ *
1979
+ * [offline] Cuando `PUBLIC_IS_OFFLINE === 'true'`, todos los archivos de bucket
1980
+ * se leen de la subcarpeta `offline/` del mismo directorio
1981
+ * (`.../${subtype}/offline/${subtype}.json`) y, si fallan tras agotar
1982
+ * reintentos, NO caen al CMS ni al archivo online: se devuelve vacío. Ver
1983
+ * `resolveBucketOriginUrl`.
1957
1984
  */
1958
1985
  BUCKET_ORIGIN?: BucketOriginConfig;
1959
1986
  };
@@ -2025,9 +2052,11 @@ export declare class MainComponentServices {
2025
2052
  readonly contract: ImageSizesContract;
2026
2053
  constructor(config: Config, imgSizes: any, axiosApi: AxiosInstance, exclude?: string, customMainImagesSizes?: string, imageSizes?: ImageSizesContractInput);
2027
2054
  getNewsListZone(params: Params): Promise<AxiosResponse<NewListResponse, any, {}> | undefined>;
2028
- getOutstandingBlock(params: Params): Promise<AxiosResponse<{
2029
- data: Array<Outstanding>;
2030
- }, any, {}> | undefined>;
2055
+ getOutstandingBlock(params: Params): Promise<{
2056
+ data: {
2057
+ data: Array<Outstanding>;
2058
+ };
2059
+ } | undefined>;
2031
2060
  getNewsListZoneWrapper(section: string, size: number, imagesizes?: string): Promise<AxiosResponse<NewListResponse, any, {}> | undefined>;
2032
2061
  getNewsDestacadoDiario(section: string): Promise<never[] | AxiosResponse<NewListResponse, any, {}>>;
2033
2062
  getNewsDestacadoDiarioImage(section: string): Promise<never[] | AxiosResponse<NewListResponse, any, {}>>;
@@ -3291,6 +3320,18 @@ export declare const REPORT_REASONS: {
3291
3320
  readonly bullying: "Bullying o acoso";
3292
3321
  };
3293
3322
 
3323
+ /**
3324
+ * Registra en el **debugPanel** (`DebugStore`, gated por `DEBUG_ENABLED`) que un
3325
+ * recurso de `BUCKET_ORIGIN` agotó los reintentos. En un sitio con el toggle
3326
+ * prendido, el bucket es el MÉTODO ÚNICO: NO se cae al CMS (eso solo pasa con el
3327
+ * toggle OFF, en sitios sin migrar). El recurso se sirve VACÍO y esta entrada
3328
+ * deja constancia explícita del "servido vacío, sin fallback" para que la falla
3329
+ * se NOTE en el panel en vez de quedar enmascarada. (El fallo de red crudo ya lo
3330
+ * registra `resilientFetch`; esta entrada agrega la decisión de no-fallback.)
3331
+ * Ver `PLAN_DYNAMIC_SLOTS_BUCKET_ORIGIN.md` §7.
3332
+ */
3333
+ export declare function reportBucketOriginExhausted(kind: string, url: string): void;
3334
+
3294
3335
  export declare function reportComment({ publication, username, id, type, baseUrl, captchaToken, apiToken, securityToken, COMMENTS_VARS, }: ReportCommentParams): Promise<{
3295
3336
  type: string;
3296
3337
  message: string;
@@ -3322,22 +3363,42 @@ export declare type ReportReasonKey = keyof typeof REPORT_REASONS;
3322
3363
  export declare type RequiredGroup = Exclude<keyof ImageSizesContract, 'squareLg'>;
3323
3364
 
3324
3365
  /**
3325
- * Reintenta `fn` con backoff exponencial, acotando cada intento con `timeoutMs`
3326
- * (un fetch a un bucket S3 colgado no debe bloquear el request indefinidamente).
3366
+ * Defaults alineados con AWS SDK JS v3 (`standard` retry + NodeHttpHandler):
3367
+ * - maxAttempts 3 1 intento + 2 reintentos (`retries = 2`)
3368
+ * - backoff exponencial con full jitter (base 100ms, cap 20s)
3369
+ * - timeout por intento (SSR): el SDK no lo pone por defecto; acá sí para no
3370
+ * colgar el render si el bucket no responde.
3371
+ */
3372
+ export declare const RESILIENT_FETCH_DEFAULTS: {
3373
+ readonly retries: 2;
3374
+ readonly timeoutMs: 2500;
3375
+ readonly baseDelayMs: 100;
3376
+ readonly maxDelayMs: 20000;
3377
+ };
3378
+
3379
+ /**
3380
+ * Reintenta `fn` con backoff exponencial + jitter (paridad SDK `standard`),
3381
+ * acotando cada intento con `timeoutMs` (un fetch a un bucket S3 colgado no
3382
+ * debe bloquear el request indefinidamente).
3327
3383
  * Si se agotan los reintentos (o el error no es reintentable, ej. 404), registra el
3328
3384
  * fallo en DebugStore y devuelve `fallback` en vez de rechazar: una falla del bucket
3329
3385
  * no debe tumbar el render del sitio consumidor.
3330
3386
  */
3331
- export declare function resilientFetch<T, F>(fn: () => Promise<T> | T, fallback: F, { label, endpoint, params, retries, timeoutMs, baseDelayMs, }: ResilientFetchOptions): Promise<T | F>;
3387
+ export declare function resilientFetch<T, F>(fn: () => Promise<T> | T, fallback: F, { label, endpoint, params, retries, timeoutMs, baseDelayMs, maxDelayMs, }: ResilientFetchOptions): Promise<T | F>;
3332
3388
 
3333
3389
  export declare interface ResilientFetchOptions {
3334
3390
  /** Identifica el fetch en logs y en el DebugStore (ej. '/news-list-zone', 'bucket:menu'). */
3335
3391
  label: string;
3336
3392
  endpoint?: string;
3337
3393
  params?: Record<string, any>;
3394
+ /**
3395
+ * Reintentos adicionales tras el primer intento.
3396
+ * Default 2 → 3 intentos totales (paridad con `maxAttempts: 3` del SDK).
3397
+ */
3338
3398
  retries?: number;
3339
3399
  timeoutMs?: number;
3340
3400
  baseDelayMs?: number;
3401
+ maxDelayMs?: number;
3341
3402
  }
3342
3403
 
3343
3404
  /**
@@ -3349,7 +3410,18 @@ export declare function resolveBatchCount(): number;
3349
3410
 
3350
3411
  export declare function resolveBucketMenuSubtype(path?: string): string;
3351
3412
 
3352
- export declare function resolveBucketOriginUrl(bucket: BucketOriginConfig, servicePrefix: string | undefined, type: 'menu' | 'banners' | 'bloques', subtype: string): string;
3413
+ /**
3414
+ * Arma la URL del recurso en el bucket:
3415
+ * `${base}/${clientName}/${site}/${type}/${subtype}/${subtype}.json`.
3416
+ *
3417
+ * En modo offline (`PUBLIC_IS_OFFLINE === 'true'`) el consumidor pasa
3418
+ * `offline = true` y el archivo se resuelve dentro de la subcarpeta `offline/`
3419
+ * del MISMO directorio: `.../${subtype}/offline/${subtype}.json`. La variante
3420
+ * offline es un archivo aparte que convive con el de producción
3421
+ * (`.../${subtype}/${subtype}.json`); el consumidor NO cae al CMS ni al archivo
3422
+ * online si la offline falla (ver getMainMenu/getBanners/getDynamicSlots/destacado).
3423
+ */
3424
+ export declare function resolveBucketOriginUrl(bucket: BucketOriginConfig, servicePrefix: string | undefined, type: 'menu' | 'banners' | 'bloques', subtype: string, offline?: boolean): string;
3353
3425
 
3354
3426
  /**
3355
3427
  * Recibe lo que el app mande hoy (contrato completo, parcial, o nada) y