@ziztechnology/dial-library 0.0.3 → 0.0.5

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
@@ -311,6 +311,8 @@ const destroy = () => {
311
311
 
312
312
  播放器同一时间只保留一个活动动态素材。它会复用视频元素,并在状态离开时停止播放;页面暂停或隐藏时,播放器与控制器都会自动暂停。
313
313
 
314
+ TGS 使用 SDK 内置的 SVG light 播放器,并且只在首次显示 TGS 素材时动态加载。表盘项目不需要安装、导入或配置 `lottie-web`,也不需要为构建工具添加 Lottie alias。
315
+
314
316
  ## 行车状态的回退
315
317
 
316
318
  行车状态有两类彼此独立的回退:传感器不可用时的**状态回退**,以及表情素材失败时的**媒体回退**。
@@ -397,6 +399,21 @@ if (!config) {
397
399
  }
398
400
  ```
399
401
 
402
+ 正常的 PACKAGED_H5 Runtime 会在 document-start 阶段完成配置注入,因此优先使用上述同步读取。若表盘还需兼容旧 Runtime 或异常的晚注入时序,可以进行一次有上限的异步等待:
403
+
404
+ ```ts
405
+ import { waitForDrivingExpressionsConfig } from '@ziztechnology/dial-library';
406
+
407
+ const abortController = new AbortController();
408
+ const config = await waitForDrivingExpressionsConfig({
409
+ timeoutMs: 3_000,
410
+ pollIntervalMs: 100,
411
+ signal: abortController.signal,
412
+ });
413
+ ```
414
+
415
+ 该函数会立即读取一次,之后使用单个定时器重试。首次读到完整合法的配置时返回;超时返回 `null`;取消时以 `AbortError` 结束。它不会隐式使用官方 Emoji,超时后的界面和回退仍由表盘决定。页面卸载时应调用 `abortController.abort()`。
416
+
400
417
  schema v1 要求 `states` 恰好包含全部八种状态。支持的单个状态素材为:
401
418
 
402
419
  ```ts
package/dist/index.d.mts CHANGED
@@ -162,6 +162,16 @@ interface ParseDrivingExpressionsOptions {
162
162
  /** Accept the v0 bare HTTPS image URL and normalize it to kind=image. */
163
163
  allowLegacyImageUrls?: boolean;
164
164
  }
165
+ interface WaitForDrivingExpressionsConfigOptions {
166
+ /** Maximum time to wait for Runtime injection. Defaults to 3000ms. */
167
+ timeoutMs?: number;
168
+ /** Delay between reads while waiting. Defaults to 100ms. */
169
+ pollIntervalMs?: number;
170
+ /** Cancels the pending wait and rejects with AbortError. */
171
+ signal?: AbortSignal;
172
+ /** Parsing compatibility options applied to every read. */
173
+ parseOptions?: ParseDrivingExpressionsOptions;
174
+ }
165
175
  declare const parseDrivingExpressionsConfig: (raw: unknown, options?: ParseDrivingExpressionsOptions) => CompleteDrivingExpressionsConfig;
166
176
  declare const tryParseDrivingExpressionsConfig: (raw: unknown, options?: ParseDrivingExpressionsOptions) => CompleteDrivingExpressionsConfig | null;
167
177
  /**
@@ -169,6 +179,11 @@ declare const tryParseDrivingExpressionsConfig: (raw: unknown, options?: ParseDr
169
179
  * It never installs official fallbacks implicitly.
170
180
  */
171
181
  declare const readDrivingExpressionsConfig: (raw?: unknown, options?: ParseDrivingExpressionsOptions) => CompleteDrivingExpressionsConfig | null;
182
+ /**
183
+ * Waits for a valid Runtime-injected configuration using bounded polling.
184
+ * It never installs official fallbacks implicitly.
185
+ */
186
+ declare const waitForDrivingExpressionsConfig: (options?: WaitForDrivingExpressionsConfigOptions) => Promise<CompleteDrivingExpressionsConfig | null>;
172
187
  /** Original resolver behavior: missing legacy slots fall back to STEADY_DRIVING. */
173
188
  declare const resolveDrivingExpression: (config: DrivingExpressionsConfigInput, status: CarRunningStatus) => DrivingExpressionMedia;
174
189
  /** Strict resolver used by the player; official fallbacks are opt-in. */
@@ -282,20 +297,12 @@ interface DrivingExpressionPlayerSnapshot {
282
297
  mediaKind: StructuredDrivingExpressionMedia['kind'] | null;
283
298
  errorCategory: DrivingExpressionPlayerErrorCategory | null;
284
299
  }
285
- interface DrivingTgsAnimationHandle {
286
- destroy(): void;
287
- pause?(): void;
288
- play?(): void;
289
- restart?(): void;
290
- }
291
- type DrivingTgsRenderer = (container: HTMLElement, animationData: Record<string, unknown>, signal: AbortSignal) => DrivingTgsAnimationHandle | Promise<DrivingTgsAnimationHandle>;
292
300
  interface DrivingExpressionPlayerOptions {
293
301
  config: DrivingExpressionsConfigInput;
294
302
  fallbacks?: Partial<Readonly<Record<CarRunningStatus, StructuredDrivingExpressionMedia>>>;
295
303
  loadTimeoutMs?: number;
296
304
  retryBackoffMs?: number;
297
305
  fit?: 'contain' | 'cover';
298
- tgsRenderer?: DrivingTgsRenderer;
299
306
  fetch?: typeof globalThis.fetch;
300
307
  onDiagnostic?: (event: DrivingExpressionPlayerDiagnosticEvent) => void;
301
308
  maxTgsCompressedBytes?: number;
@@ -313,4 +320,4 @@ interface DrivingExpressionPlayer {
313
320
  }
314
321
  declare const createDrivingExpressionPlayer: (container: HTMLElement, options: DrivingExpressionPlayerOptions) => DrivingExpressionPlayer;
315
322
  //#endregion
316
- export { AvailableSensorMetric, BATTERY_HEALTH_LABELS, BatteryCapacityValue, BatteryHealth, BatteryPlugged, BatteryStateValue, BatteryStatus, CAR_RUNNING_LABELS, CAR_RUNNING_STATUSES, CAR_RUNNING_STATUS_PRIORITY, CarRunningStatus, CompleteDrivingExpressionsConfig, DEFAULT_DRIVING_STATUS_TUNING, DrivingControllerSnapshot, DrivingExpressionMedia, DrivingExpressionPlayer, DrivingExpressionPlayerDiagnosticEvent, DrivingExpressionPlayerErrorCategory, DrivingExpressionPlayerOptions, DrivingExpressionPlayerSnapshot, DrivingExpressionResolutionError, DrivingExpressionsConfig, DrivingExpressionsConfigError, DrivingExpressionsConfigErrorCode, DrivingExpressionsConfigInput, DrivingSensorProvider, DrivingSnapshotMetrics, DrivingStatusChangeReason, DrivingStatusClock, DrivingStatusController, DrivingStatusControllerOptions, DrivingStatusDiagnosticEvent, DrivingStatusEvent, DrivingStatusTuning, DrivingStatusTuningOverrides, DrivingTgsAnimationHandle, DrivingTgsRenderer, EmojiDrivingExpressionMedia, ImageDrivingExpressionMedia, LivePhotoDrivingExpressionMedia, MediaLibraryRef, OFFICIAL_DRIVING_EXPRESSIONS_CONFIG, OFFICIAL_DRIVING_EXPRESSION_FALLBACKS, OrientationValue, ParseDrivingExpressionsOptions, StructuredDrivingExpressionMedia, TgsDrivingExpressionMedia, UnavailableSensorMetric, UnifiedSensorInfoPayload, UnifiedSensorMetric, UnifiedSensorUnavailableReason, Vector3Value, VideoDrivingExpressionMedia, checkRunningStatus, classifyDrivingMetrics, classifyDrivingSnapshot, createDrivingExpressionPlayer, createDrivingStatusController, extractDrivingSnapshotMetrics, isPublicDrivingMediaUrl, parseDrivingExpressionsConfig, readDrivingExpressionsConfig, resolveDrivingExpression, resolveDrivingExpressionStrict, resolveDrivingStatusTuning, tryParseDrivingExpressionsConfig, unifiedSensorInfo };
323
+ export { AvailableSensorMetric, BATTERY_HEALTH_LABELS, BatteryCapacityValue, BatteryHealth, BatteryPlugged, BatteryStateValue, BatteryStatus, CAR_RUNNING_LABELS, CAR_RUNNING_STATUSES, CAR_RUNNING_STATUS_PRIORITY, CarRunningStatus, CompleteDrivingExpressionsConfig, DEFAULT_DRIVING_STATUS_TUNING, DrivingControllerSnapshot, DrivingExpressionMedia, DrivingExpressionPlayer, DrivingExpressionPlayerDiagnosticEvent, DrivingExpressionPlayerErrorCategory, DrivingExpressionPlayerOptions, DrivingExpressionPlayerSnapshot, DrivingExpressionResolutionError, DrivingExpressionsConfig, DrivingExpressionsConfigError, DrivingExpressionsConfigErrorCode, DrivingExpressionsConfigInput, DrivingSensorProvider, DrivingSnapshotMetrics, DrivingStatusChangeReason, DrivingStatusClock, DrivingStatusController, DrivingStatusControllerOptions, DrivingStatusDiagnosticEvent, DrivingStatusEvent, DrivingStatusTuning, DrivingStatusTuningOverrides, EmojiDrivingExpressionMedia, ImageDrivingExpressionMedia, LivePhotoDrivingExpressionMedia, MediaLibraryRef, OFFICIAL_DRIVING_EXPRESSIONS_CONFIG, OFFICIAL_DRIVING_EXPRESSION_FALLBACKS, OrientationValue, ParseDrivingExpressionsOptions, StructuredDrivingExpressionMedia, TgsDrivingExpressionMedia, UnavailableSensorMetric, UnifiedSensorInfoPayload, UnifiedSensorMetric, UnifiedSensorUnavailableReason, Vector3Value, VideoDrivingExpressionMedia, WaitForDrivingExpressionsConfigOptions, checkRunningStatus, classifyDrivingMetrics, classifyDrivingSnapshot, createDrivingExpressionPlayer, createDrivingStatusController, extractDrivingSnapshotMetrics, isPublicDrivingMediaUrl, parseDrivingExpressionsConfig, readDrivingExpressionsConfig, resolveDrivingExpression, resolveDrivingExpressionStrict, resolveDrivingStatusTuning, tryParseDrivingExpressionsConfig, unifiedSensorInfo, waitForDrivingExpressionsConfig };
package/dist/index.mjs CHANGED
@@ -256,6 +256,63 @@ const readDrivingExpressionsConfig = (raw, options) => {
256
256
  const source = raw === void 0 ? readRuntimeDrivingExpressionsValue() : raw;
257
257
  return source === void 0 ? null : tryParseDrivingExpressionsConfig(source, options);
258
258
  };
259
+ /**
260
+ * Waits for a valid Runtime-injected configuration using bounded polling.
261
+ * It never installs official fallbacks implicitly.
262
+ */
263
+ const waitForDrivingExpressionsConfig = (options = {}) => {
264
+ const timeoutMs = requireNonNegativeFinite("timeoutMs", options.timeoutMs ?? 3e3);
265
+ const pollIntervalMs = requirePositiveFinite$1("pollIntervalMs", options.pollIntervalMs ?? 100);
266
+ const { signal } = options;
267
+ return new Promise((resolve, reject) => {
268
+ const deadlineMs = Date.now() + timeoutMs;
269
+ let timer;
270
+ let settled = false;
271
+ const cleanup = () => {
272
+ if (timer !== void 0) {
273
+ globalThis.clearTimeout(timer);
274
+ timer = void 0;
275
+ }
276
+ signal?.removeEventListener("abort", handleAbort);
277
+ };
278
+ const finish = (config) => {
279
+ if (settled) return;
280
+ settled = true;
281
+ cleanup();
282
+ resolve(config);
283
+ };
284
+ const fail = (error) => {
285
+ if (settled) return;
286
+ settled = true;
287
+ cleanup();
288
+ reject(error);
289
+ };
290
+ const handleAbort = () => {
291
+ fail(createAbortError$1());
292
+ };
293
+ const read = () => readDrivingExpressionsConfig(void 0, options.parseOptions);
294
+ const poll = () => {
295
+ if (settled) return;
296
+ if (signal?.aborted) {
297
+ handleAbort();
298
+ return;
299
+ }
300
+ const config = read();
301
+ if (config !== null) {
302
+ finish(config);
303
+ return;
304
+ }
305
+ const remainingMs = deadlineMs - Date.now();
306
+ if (remainingMs <= 0) {
307
+ finish(null);
308
+ return;
309
+ }
310
+ timer = globalThis.setTimeout(poll, Math.min(pollIntervalMs, remainingMs));
311
+ };
312
+ signal?.addEventListener("abort", handleAbort, { once: true });
313
+ poll();
314
+ });
315
+ };
259
316
  /** Original resolver behavior: missing legacy slots fall back to STEADY_DRIVING. */
260
317
  const resolveDrivingExpression = (config, status) => config.states[status] ?? config.states.STEADY_DRIVING;
261
318
  /** Strict resolver used by the player; official fallbacks are opt-in. */
@@ -531,6 +588,20 @@ const compact = (value) => {
531
588
  return value;
532
589
  };
533
590
  const isRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
591
+ const requireNonNegativeFinite = (name, value) => {
592
+ if (!Number.isFinite(value) || value < 0) throw new RangeError(`${name} must be a non-negative finite number`);
593
+ return value;
594
+ };
595
+ const requirePositiveFinite$1 = (name, value) => {
596
+ if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${name} must be a positive finite number`);
597
+ return value;
598
+ };
599
+ const createAbortError$1 = () => {
600
+ if (typeof DOMException === "function") return new DOMException("The operation was aborted", "AbortError");
601
+ const error = /* @__PURE__ */ new Error("The operation was aborted");
602
+ error.name = "AbortError";
603
+ return error;
604
+ };
534
605
  //#endregion
535
606
  //#region src/sensor/page_lifecycle.ts
536
607
  const subscribers = /* @__PURE__ */ new Set();
@@ -1071,7 +1142,7 @@ var DefaultDrivingExpressionPlayer = class {
1071
1142
  this.loadTimeoutMs = positiveFinite("loadTimeoutMs", options.loadTimeoutMs ?? 5e3);
1072
1143
  this.retryBackoffMs = positiveFinite("retryBackoffMs", options.retryBackoffMs ?? 15e3);
1073
1144
  this.fit = options.fit ?? "contain";
1074
- this.tgsRenderer = options.tgsRenderer ?? defaultTgsRenderer;
1145
+ this.tgsRenderer = defaultTgsRenderer;
1075
1146
  this.fetchImplementation = options.fetch ?? globalThis.fetch?.bind(globalThis);
1076
1147
  this.onDiagnostic = options.onDiagnostic;
1077
1148
  this.maxTgsCompressedBytes = positiveFinite("maxTgsCompressedBytes", options.maxTgsCompressedBytes ?? 2 * 1024 * 1024);
@@ -1604,7 +1675,7 @@ const withTimeout = (promise, timeoutMs, signal) => new Promise((resolve, reject
1604
1675
  });
1605
1676
  const defaultTgsRenderer = async (container, animationData, signal) => {
1606
1677
  if (signal.aborted) throw createAbortError();
1607
- const module = await import("lottie-web");
1678
+ const module = await import("lottie-web/build/player/lottie_light.js");
1608
1679
  if (signal.aborted) throw createAbortError();
1609
1680
  const animation = module.default.loadAnimation({
1610
1681
  animationData,
@@ -1731,4 +1802,4 @@ const safeDestroy = (handle) => {
1731
1802
  };
1732
1803
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1733
1804
  //#endregion
1734
- export { BATTERY_HEALTH_LABELS, CAR_RUNNING_LABELS, CAR_RUNNING_STATUSES, CAR_RUNNING_STATUS_PRIORITY, DEFAULT_DRIVING_STATUS_TUNING, DrivingExpressionResolutionError, DrivingExpressionsConfigError, OFFICIAL_DRIVING_EXPRESSIONS_CONFIG, OFFICIAL_DRIVING_EXPRESSION_FALLBACKS, checkRunningStatus, classifyDrivingMetrics, classifyDrivingSnapshot, createDrivingExpressionPlayer, createDrivingStatusController, extractDrivingSnapshotMetrics, isPublicDrivingMediaUrl, parseDrivingExpressionsConfig, readDrivingExpressionsConfig, resolveDrivingExpression, resolveDrivingExpressionStrict, resolveDrivingStatusTuning, tryParseDrivingExpressionsConfig, unifiedSensorInfo };
1805
+ export { BATTERY_HEALTH_LABELS, CAR_RUNNING_LABELS, CAR_RUNNING_STATUSES, CAR_RUNNING_STATUS_PRIORITY, DEFAULT_DRIVING_STATUS_TUNING, DrivingExpressionResolutionError, DrivingExpressionsConfigError, OFFICIAL_DRIVING_EXPRESSIONS_CONFIG, OFFICIAL_DRIVING_EXPRESSION_FALLBACKS, checkRunningStatus, classifyDrivingMetrics, classifyDrivingSnapshot, createDrivingExpressionPlayer, createDrivingStatusController, extractDrivingSnapshotMetrics, isPublicDrivingMediaUrl, parseDrivingExpressionsConfig, readDrivingExpressionsConfig, resolveDrivingExpression, resolveDrivingExpressionStrict, resolveDrivingStatusTuning, tryParseDrivingExpressionsConfig, unifiedSensorInfo, waitForDrivingExpressionsConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziztechnology/dial-library",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "private": false,
5
5
  "description": "Tooony 表盘工具函数、方法",
6
6
  "files": [