@ziztechnology/dial-library 0.0.6 → 0.0.8

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
@@ -13,14 +13,6 @@
13
13
  npm install @ziztechnology/dial-library
14
14
  ```
15
15
 
16
- ```bash
17
- pnpm add @ziztechnology/dial-library
18
- ```
19
-
20
- ```bash
21
- yarn add @ziztechnology/dial-library
22
- ```
23
-
24
16
  SDK 是 ESM 包,并自带 TypeScript 类型。
25
17
 
26
18
  ## 快速开始
package/dist/index.mjs CHANGED
@@ -1,5 +1,22 @@
1
1
  import { Gunzip } from "fflate";
2
+ const resolveLogIntervalMs = (intervalMs = void 0) => typeof intervalMs === "number" && Number.isFinite(intervalMs) && intervalMs > 0 ? intervalMs : 300;
3
+ //#endregion
2
4
  //#region src/helper/debugger.ts
5
+ const logIntervalMs = resolveLogIntervalMs();
6
+ const lastLoggedAtByType = /* @__PURE__ */ new Map();
7
+ const createLogTypeKey = (moduleName, scope, phase) => JSON.stringify([
8
+ moduleName,
9
+ scope,
10
+ phase
11
+ ]);
12
+ const shouldLog = (moduleName, scope, phase) => {
13
+ const key = createLogTypeKey(moduleName, scope, phase);
14
+ const now = Date.now();
15
+ const lastLoggedAt = lastLoggedAtByType.get(key);
16
+ if (lastLoggedAt !== void 0 && now >= lastLoggedAt && now - lastLoggedAt < logIntervalMs) return false;
17
+ lastLoggedAtByType.set(key, now);
18
+ return true;
19
+ };
3
20
  const stringifyDebugData = (data) => {
4
21
  const seen = /* @__PURE__ */ new WeakSet();
5
22
  return JSON.stringify(data, (_key, value) => {
@@ -18,6 +35,7 @@ const stringifyDebugData = (data) => {
18
35
  }) ?? String(data);
19
36
  };
20
37
  const dialSdkDebugWarn = (moduleName, scope, phase, data) => {
38
+ if (!shouldLog(moduleName, scope, phase)) return;
21
39
  const message = `[DIAL_SDK_DEBUG - ${moduleName}] ${scope}: ${phase}`;
22
40
  try {
23
41
  if (data === void 0) console.warn(message);
@@ -2057,6 +2075,7 @@ const noop = () => {
2057
2075
  //#endregion
2058
2076
  //#region src/sensor/driving_expression_player.ts
2059
2077
  const DEBUG_MODULE = "driving_expression_player.ts";
2078
+ const MAX_RETAINED_IMAGES = 3;
2060
2079
  const createDrivingExpressionPlayer = (container, options) => {
2061
2080
  dialSdkDebugWarn(DEBUG_MODULE, "createDrivingExpressionPlayer", "called", {
2062
2081
  container,
@@ -2086,6 +2105,8 @@ var DefaultDrivingExpressionPlayer = class {
2086
2105
  this.reusableVideo = null;
2087
2106
  this.activeTgs = null;
2088
2107
  this.unsubscribePageLifecycle = null;
2108
+ this.retainedImages = /* @__PURE__ */ new Map();
2109
+ this.preloadedHintUrls = /* @__PURE__ */ new Set();
2089
2110
  this.handleLifecyclePause = () => {
2090
2111
  dialSdkDebugWarn(DEBUG_MODULE, "DefaultDrivingExpressionPlayer.handleLifecyclePause", "called");
2091
2112
  if (this.destroyed || this.lifecycleSuspended) {
@@ -2215,6 +2236,8 @@ var DefaultDrivingExpressionPlayer = class {
2215
2236
  this.failedOperation = null;
2216
2237
  this.cancelPendingWork();
2217
2238
  this.releaseActiveMedia();
2239
+ this.clearRetainedImages();
2240
+ this.preloadedHintUrls.clear();
2218
2241
  this.container.replaceChildren();
2219
2242
  this.status = null;
2220
2243
  this.desiredMedia = null;
@@ -2315,8 +2338,7 @@ var DefaultDrivingExpressionPlayer = class {
2315
2338
  try {
2316
2339
  switch (media.kind) {
2317
2340
  case "image":
2318
- this.renderConfiguredFallback(status, false);
2319
- await this.loadImage(media.url, loadAbort.signal, operation);
2341
+ await this.loadImage(status, media, loadAbort.signal, operation);
2320
2342
  break;
2321
2343
  case "video":
2322
2344
  this.renderLoadingPlaceholder(status, media.coverUrl, operation, loadAbort.signal);
@@ -2361,12 +2383,27 @@ var DefaultDrivingExpressionPlayer = class {
2361
2383
  dialSdkDebugWarn(DEBUG_MODULE, "DefaultDrivingExpressionPlayer.load", "completed", { operation });
2362
2384
  }
2363
2385
  }
2364
- async loadImage(url, signal, operation) {
2386
+ async loadImage(status, media, signal, operation) {
2387
+ const { url } = media;
2365
2388
  dialSdkDebugWarn(DEBUG_MODULE, "DefaultDrivingExpressionPlayer.loadImage", "called", {
2366
- url,
2389
+ status,
2390
+ media,
2367
2391
  signal,
2368
2392
  operation
2369
2393
  });
2394
+ if (isRetainableImage(media)) {
2395
+ const retained = this.takeRetainedImage(url);
2396
+ if (retained !== null) {
2397
+ this.container.replaceChildren(retained);
2398
+ dialSdkDebugWarn(DEBUG_MODULE, "DefaultDrivingExpressionPlayer.loadImage", "resolved retained image", {
2399
+ url,
2400
+ operation,
2401
+ image: retained
2402
+ });
2403
+ return;
2404
+ }
2405
+ }
2406
+ this.renderConfiguredFallback(status, false);
2370
2407
  const image = this.createImage();
2371
2408
  await waitForElementEvent(image, "load", "error", signal, this.loadTimeoutMs, () => {
2372
2409
  image.src = url;
@@ -2375,6 +2412,7 @@ var DefaultDrivingExpressionPlayer = class {
2375
2412
  dialSdkDebugWarn(DEBUG_MODULE, "DefaultDrivingExpressionPlayer.loadImage", "discarded", { operation });
2376
2413
  return;
2377
2414
  }
2415
+ if (isRetainableImage(media)) this.retainImage(url, image);
2378
2416
  this.container.replaceChildren(image);
2379
2417
  dialSdkDebugWarn(DEBUG_MODULE, "DefaultDrivingExpressionPlayer.loadImage", "resolved", {
2380
2418
  url,
@@ -2382,6 +2420,29 @@ var DefaultDrivingExpressionPlayer = class {
2382
2420
  image
2383
2421
  });
2384
2422
  }
2423
+ takeRetainedImage(url) {
2424
+ const image = this.retainedImages.get(url) ?? null;
2425
+ if (image === null) return null;
2426
+ this.retainedImages.delete(url);
2427
+ this.retainedImages.set(url, image);
2428
+ return image;
2429
+ }
2430
+ retainImage(url, image) {
2431
+ const previous = this.retainedImages.get(url);
2432
+ if (previous && previous !== image) previous.removeAttribute("src");
2433
+ this.retainedImages.delete(url);
2434
+ this.retainedImages.set(url, image);
2435
+ while (this.retainedImages.size > MAX_RETAINED_IMAGES) {
2436
+ const oldest = this.retainedImages.entries().next().value;
2437
+ if (!oldest) break;
2438
+ this.retainedImages.delete(oldest[0]);
2439
+ oldest[1].removeAttribute("src");
2440
+ }
2441
+ }
2442
+ clearRetainedImages() {
2443
+ for (const image of this.retainedImages.values()) image.removeAttribute("src");
2444
+ this.retainedImages.clear();
2445
+ }
2385
2446
  async loadVideo(url, mimeType, status, media, signal, operation) {
2386
2447
  dialSdkDebugWarn(DEBUG_MODULE, "DefaultDrivingExpressionPlayer.loadVideo", "called", {
2387
2448
  url,
@@ -2705,11 +2766,13 @@ var DefaultDrivingExpressionPlayer = class {
2705
2766
  const media = normalizeMedia(configured);
2706
2767
  const hintUrl = mediaPreloadHint(media);
2707
2768
  if (!hintUrl || !isPublicDrivingMediaUrl(hintUrl)) continue;
2769
+ if (this.preloadedHintUrls.has(hintUrl) || this.retainedImages.has(hintUrl)) continue;
2708
2770
  try {
2709
2771
  const image = this.createImage();
2710
2772
  await waitForElementEvent(image, "load", "error", preloadAbort.signal, this.loadTimeoutMs, () => {
2711
2773
  image.src = hintUrl;
2712
2774
  });
2775
+ this.preloadedHintUrls.add(hintUrl);
2713
2776
  image.removeAttribute("src");
2714
2777
  dialSdkDebugWarn(DEBUG_MODULE, "DefaultDrivingExpressionPlayer.startPreloading.worker", "preloaded", {
2715
2778
  status,
@@ -2917,6 +2980,14 @@ const normalizeMedia = (media) => {
2917
2980
  });
2918
2981
  return result;
2919
2982
  };
2983
+ const isRetainableImage = (media) => {
2984
+ if (media.mimeType?.split(";", 1)[0]?.trim().toLowerCase() === "image/gif") return false;
2985
+ try {
2986
+ return !new URL(media.url).pathname.toLowerCase().endsWith(".gif");
2987
+ } catch {
2988
+ return false;
2989
+ }
2990
+ };
2920
2991
  const firstInvalidMediaUrl = (media) => {
2921
2992
  dialSdkDebugWarn(DEBUG_MODULE, "firstInvalidMediaUrl", "called", { media });
2922
2993
  let values;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziztechnology/dial-library",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "private": false,
5
5
  "description": "Tooony 表盘工具函数、方法",
6
6
  "files": [