@nitida/asset-client 0.16.2 → 0.16.4

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/src/palette.ts CHANGED
@@ -100,8 +100,8 @@ export function relativeLuminance(hex: string): number {
100
100
  }
101
101
 
102
102
  /**
103
- * Razón de contraste WCAG entre dos luminancias: `(L1 + 0.05) / (L2 + 0.05)`,
104
- * con la más clara arriba. 1 = idénticos, 21 = negro contra blanco.
103
+ * WCAG contrast ratio between two luminances: `(L1 + 0.05) / (L2 + 0.05)`,
104
+ * lighter on top. 1 = identical, 21 = black against white.
105
105
  */
106
106
  export function contrastRatio(l1: number, l2: number): number {
107
107
  const [hi, lo] = l1 >= l2 ? [l1, l2] : [l2, l1];
@@ -109,37 +109,38 @@ export function contrastRatio(l1: number, l2: number): number {
109
109
  }
110
110
 
111
111
  /**
112
- * Negro o blanco, el que **de verdad** contraste más sobre este fondo.
112
+ * Black or white whichever **actually** contrasts more against this
113
+ * background.
113
114
  *
114
- * ⚠️ CORREGIDO 2026-08-17. Antes decidía con `L > 0.5`, y **0,5 no es el punto
115
- * de empate**. Igualando las dos razones de contraste:
115
+ * The tie point is NOT `L > 0.5`, which is the threshold most implementations
116
+ * reach for. Equating the two contrast ratios gives it exactly:
116
117
  *
117
118
  * (1 + 0.05) / (L + 0.05) = (L + 0.05) / 0.05
118
119
  * (L + 0.05)² = 0.0525
119
120
  * L = 0.1791…
120
121
  *
121
- * Entre **0,179 y 0,5** el código viejo elegía BLANCO cuando negro contrastaba
122
- * másuna banda ancha, y justo donde caen los colores de marca saturados.
123
- * Medido sobre cuatro paletas reales de producción: **8 swatches** en esa banda.
124
- * El peor, el dorado dominante `#CA9528`: devolvía blanco a **2,68:1** cuando
125
- * negro da **7,84:1**. 2,68 no pasa AA ni para texto grande.
122
+ * Between **0.179 and 0.5** a `L > 0.5` test picks WHITE while black contrasts
123
+ * morea wide band, and exactly where saturated brand colours land. A
124
+ * mid-luminance gold in that band can be handed white at **2.68:1** when black
125
+ * would give **7.84:1**; 2.68 does not pass AA even for large text.
126
126
  *
127
- * No se cambia el umbral por 0,179: se **calculan las dos razones y gana la
128
- * mayor**. Un umbral es una constante que hay que mantener correcta; la
129
- * comparación es correcta por construcción.
127
+ * So this does not swap one threshold for another: it **computes both ratios
128
+ * and returns the winner**. A threshold is a constant somebody has to keep
129
+ * correct; the comparison is correct by construction.
130
130
  *
131
- * ⚠️ Esto elige el MEJOR de dos, no garantiza que alcance. Sobre un fondo de
132
- * luminancia media el mejor par puede quedar por debajo de 4,5:1 igual — para
133
- * eso está {@link bestTextContrast}, que además devuelve el número.
131
+ * ⚠️ This picks the BETTER of two it does not guarantee the result is
132
+ * enough. Over a mid-luminance background the best pair can still land under
133
+ * 4.5:1. Use {@link bestTextContrast} when you need to know: it returns the
134
+ * ratio it achieved.
134
135
  */
135
136
  function textColorForHex(hex: string): "#000000" | "#FFFFFF" {
136
137
  return bestTextContrast(hex).color;
137
138
  }
138
139
 
139
140
  /**
140
- * Igual que el color recomendado, pero devuelve también **la razón lograda** y
141
- * si pasa AA para que quien lo use pueda decidir con el número a la vista en
142
- * vez de asumir que alcanzó.
141
+ * Same choice as the recommended text colour, but it also returns **the ratio
142
+ * it achieved** and whether that passes AA so a caller can decide with the
143
+ * number in front of them instead of assuming it was enough.
143
144
  */
144
145
  export function bestTextContrast(hex: string): {
145
146
  color: "#000000" | "#FFFFFF";
package/src/slots.ts CHANGED
@@ -4,9 +4,9 @@
4
4
  * Slots give tenants a way to attach stable, human-readable names
5
5
  * ("webapp.wizard.pool-type.icon-1", "storefront.cr.hero-video.landscape_hd_16x9.mp4")
6
6
  * to assets they uploaded. Consumers resolve names → AssetDTOs at
7
- * build / runtime so their source never hardcodes a CDN URL; the
8
- * admin rebinds a slot from `asset-lab-web` and every consumer picks
9
- * up the swap on cache refresh.
7
+ * build / runtime so their source never hardcodes a CDN URL; an
8
+ * admin rebinds a slot in the platform console and every consumer
9
+ * picks up the swap on cache refresh.
10
10
  *
11
11
  * Two layers in this package:
12
12
  * - `resolveSlot` / `resolveSlots` — universal (server, edge,
@@ -67,8 +67,8 @@ let tenantCode: string | null = null;
67
67
  *
68
68
  * configureSlotResolver({
69
69
  * endpoint: process.env.AQUIENPZ_URL,
70
- * apiKey: process.env.ASSET_MANAGER_RUNTIME_KEY,
71
- * tenantCode: "realtyone-cr",
70
+ * apiKey: process.env.AQUIENPZ_API_KEY, // amk_rt_* — server-only
71
+ * tenantCode: "acme-co",
72
72
  * });
73
73
  */
74
74
  export function configureSlotResolver(opts: {
package/src/transform.ts CHANGED
@@ -262,13 +262,28 @@ export function getVideoTransformUrl(
262
262
  * if (prefersNativeHls(video)) {
263
263
  * video.src = src;
264
264
  * } else {
265
- * // Defaults open at a fixed low rung measure instead of guessing.
266
- * const hls = new Hls({ startLevel: -1, testBandwidth: true, abrEwmaDefaultEstimate: 1_000_000 });
265
+ * const hls = new Hls({ capLevelToPlayerSize: false, abrEwmaDefaultEstimate: 5_000_000 });
267
266
  * hls.loadSource(src);
268
267
  * hls.attachMedia(video);
269
268
  * }
270
269
  * ```
271
270
  *
271
+ * ⚠️ **Do NOT pass `startLevel: -1` with `testBandwidth: true`.** That pair is
272
+ * documented by hls.js as *"forces the player to download a fragment from the
273
+ * lowest level to establish a bandwidth estimate"* — on a clip short enough to
274
+ * be one segment, the probe IS the whole video, and it plays at the bottom
275
+ * rung from first frame to last. (This doc-comment recommended exactly that
276
+ * until 2026-08-18; a 5.042 s 4K asset was measured being delivered at
277
+ * 426x240 because of it.) Leave `startLevel` unset: hls.js then opens on the
278
+ * FIRST level in the manifest, and the server puts the right one there —
279
+ * a mid rung for long video, the top rung for a clip under 18 s, which is the
280
+ * same rung native HLS opens on per RFC 8216 §6.3.4. The ladder decides; the
281
+ * player should not second-guess it.
282
+ *
283
+ * `capLevelToPlayerSize` is worth disabling explicitly: `@videojs/core`
284
+ * defaults it to `true`, which caps quality to the player's rendered pixel box,
285
+ * so a small inline player is pinned to 240p/360p on any connection.
286
+ *
272
287
  * On first request the server returns 202 Accepted while a background
273
288
  * job transcodes the ladder (typically 1-3 min for a 90 s source);
274
289
  * subsequent requests get 302 to the cached master.m3u8. Keep the