@spatius/avatarkit 1.3.3 → 1.3.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/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.3.4] - 2026-08-11
9
+
10
+ ### Fixed
11
+ - **The Opus uplink encoder now actually runs off the main thread.** Asset URLs were emitted as absolute paths (`/assets/…`), so any app not served from the domain root — a Vite dev server included — got HTML back for the worker request. The SDK logged `Worker unavailable, falling back to main-thread encode` and encoded every chunk on the main thread, stalling rendering for the whole of playback. URLs are now relative to the referencing chunk.
12
+ - **Next.js builds no longer fail on the Opus workers.** `withAvatarkit` now copies the pre-built workers (and the sibling chunks they import) into `public/assets/`, and tells webpack to leave those files alone. Previously the bundler re-processed the ESM worker and Terser rejected it with `'import' and 'export' cannot be used outside of module code`, breaking `next build` outright on 1.3.1 and later.
13
+ - Internal telemetry only, no change to public API or runtime behaviour: `http.client.request.duration` no longer records a data point when an asset is served entirely from cache. Those entries carried a hardcoded `statusCode=200` and an empty `server.address`, and their sub-millisecond durations skewed the real network latency distribution. Cache hit rate and cache-hit latency remain available through `download_avatar_assets_latency` and `template_resources_load_measure`, both of which carry `cache_hit` and `cache_type`.
14
+
8
15
  ## [1.3.3] - 2026-08-08
9
16
 
10
17
  ### Fixed
@@ -1,8 +1,8 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-B-1-B7_t.js";
2
- import { t as AvatarSDK } from "./AvatarSDK-BbqaBxdV.js";
3
- import { Mt as ErrorCode, S as recordHttpClientDuration, St as generateTraceId, c as logEvent, l as logMetric, t as logger, v as hostOf, wt as AvatarError } from "./logger-pANhsT4J.js";
4
- import { n as APP_CONFIG, r as getFlameCdnBase, t as errorToMessage } from "./error-utils-DAqUlC0I.js";
5
- import { t as PwaCacheManager } from "./pwa-cache-manager-M3XsMhvz.js";
2
+ import { t as AvatarSDK } from "./AvatarSDK-BMjjoYiZ.js";
3
+ import { Mt as ErrorCode, S as recordHttpClientDuration, St as generateTraceId, c as logEvent, l as logMetric, t as logger, v as hostOf, wt as AvatarError } from "./logger-B_tTFAYq.js";
4
+ import { n as APP_CONFIG, r as getFlameCdnBase, t as errorToMessage } from "./error-utils-B76Nf6d6.js";
5
+ import { t as PwaCacheManager } from "./pwa-cache-manager-BxeZI1BU.js";
6
6
  //#region core/AvatarDownloader.ts
7
7
  var AvatarDownloader_exports = /* @__PURE__ */ __exportAll({ AvatarDownloader: () => AvatarDownloader });
8
8
  /**
@@ -57,23 +57,13 @@ function getCacheInfo(url, response) {
57
57
  */
58
58
  function recordAssetTransaction(outcomes, durationMs, operation = ASSET_OPERATION) {
59
59
  const real = outcomes.filter((o) => !o.skipped);
60
- if (real.length === 0) {
61
- recordHttpClientDuration({
62
- operation,
63
- method: "GET",
64
- durationMs,
65
- statusCode: 200,
66
- cacheHit: true
67
- });
68
- return;
69
- }
60
+ if (real.length === 0) return;
70
61
  recordHttpClientDuration({
71
62
  operation,
72
63
  method: "GET",
73
64
  durationMs,
74
65
  statusCode: real.some((o) => o.statusCode === void 0) ? void 0 : real.reduce((max, o) => Math.max(max, o.statusCode ?? 0), 0),
75
- serverAddress: real[0].host,
76
- cacheHit: false
66
+ serverAddress: real[0].host
77
67
  });
78
68
  }
79
69
  /**
@@ -106,7 +96,7 @@ async function downloadResource(url, options) {
106
96
  cacheInfo.cacheType = "pwa";
107
97
  cacheInfo.pwaCacheSubtype = pwaCacheSubtype;
108
98
  if (outcomes && outcomeSlotIndex >= 0) outcomes[outcomeSlotIndex] = {
109
- host: "",
99
+ host: hostOf(url),
110
100
  skipped: true
111
101
  };
112
102
  return {
@@ -179,7 +169,6 @@ var AvatarDownloader = class {
179
169
  cache_hit: true,
180
170
  cache_type: "pwa"
181
171
  });
182
- recordAssetTransaction([], duration, TEMPLATE_OPERATION);
183
172
  return { unifiedModel: cached };
184
173
  }
185
174
  const maxRetries = 3;
@@ -1,6 +1,6 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-B-1-B7_t.js";
2
- import { Ft as LogLevel, T as resolveSdkVersion, _ as fetchBootstrap, a as clientContextFields, b as cleanupOtelMetrics, c as logEvent, d as cleanupOtel, f as initializeOtel, g as clockSync, gt as OTEL_STREAM_NAME, ht as OTEL_PASSWORD, i as cleanupPostHog, jt as DrivingServiceMode, mt as OTEL_LOGS_ENDPOINT, n as setLogLevel, o as getLogsFeatureFlag, r as logSink, s as initializePostHog, t as logger, u as updatePostHogPersonPropertiesForFlags, w as getSdkPackage, x as initializeOtelMetrics, xt as idManager, yt as OTEL_USERNAME } from "./logger-pANhsT4J.js";
3
- import { i as startInitTrace, n as initializeOtelTrace, t as cleanupOtelTrace } from "./otel-trace-DBN8K91J.js";
2
+ import { Ft as LogLevel, T as resolveSdkVersion, _ as fetchBootstrap, a as clientContextFields, b as cleanupOtelMetrics, c as logEvent, d as cleanupOtel, f as initializeOtel, g as clockSync, gt as OTEL_STREAM_NAME, ht as OTEL_PASSWORD, i as cleanupPostHog, jt as DrivingServiceMode, mt as OTEL_LOGS_ENDPOINT, n as setLogLevel, o as getLogsFeatureFlag, r as logSink, s as initializePostHog, t as logger, u as updatePostHogPersonPropertiesForFlags, w as getSdkPackage, x as initializeOtelMetrics, xt as idManager, yt as OTEL_USERNAME } from "./logger-B_tTFAYq.js";
3
+ import { i as startInitTrace, n as initializeOtelTrace, t as cleanupOtelTrace } from "./otel-trace-DmmQrXv-.js";
4
4
  //#region node_modules/.pnpm/@bufbuild+protobuf@2.10.1/node_modules/@bufbuild/protobuf/dist/esm/wire/varint.js
5
5
  /**
6
6
  * Read a 64 bit varint as two JS numbers.
@@ -3900,7 +3900,7 @@ var AvatarSDK = class {
3900
3900
  static _initializationState = "uninitialized";
3901
3901
  static _initializingPromise = null;
3902
3902
  static _configuration = null;
3903
- static _version = "1.3.3";
3903
+ static _version = "1.3.4";
3904
3904
  static _avatarCore = null;
3905
3905
  static _cachedDeviceScore = null;
3906
3906
  static _rendererBackend = null;
@@ -4089,7 +4089,7 @@ var AvatarSDK = class {
4089
4089
  logger.log("[AvatarSDK] Loading template resources...");
4090
4090
  logEvent("template_init_start", "info", { stage: "sdk_init" });
4091
4091
  try {
4092
- const { AvatarDownloader } = await import("./AvatarDownloader-DNeU2n5w.js").then((n) => n.n);
4092
+ const { AvatarDownloader } = await import("./AvatarDownloader-CavxMpAz.js").then((n) => n.n);
4093
4093
  const templateResources = await new AvatarDownloader().loadUnifiedTemplate();
4094
4094
  if (await this._avatarCore.loadTemplateResourcesFromBuffers(templateResources)) logger.log("[AvatarSDK] Template resources initialized successfully");
4095
4095
  else logger.log("[AvatarSDK] Template resources already initialized, skipping...");
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll, r as __toESM, t as __commonJSMin } from "./rolldown-runtime-B-1-B7_t.js";
2
- import { t as logger } from "./logger-pANhsT4J.js";
2
+ import { t as logger } from "./logger-B_tTFAYq.js";
3
3
  /** Opus granule positions are always in 48 kHz samples, regardless of input rate. */
4
4
  var OPUS_GRANULE_RATE = 48e3;
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { t as logger } from "./logger-pANhsT4J.js";
1
+ import { t as logger } from "./logger-B_tTFAYq.js";
2
2
  //#region audio/OpusDecoderProxy.ts
3
3
  var OpusDecoderProxy = class OpusDecoderProxy {
4
4
  worker = null;
@@ -21,7 +21,7 @@ var OpusDecoderProxy = class OpusDecoderProxy {
21
21
  } catch (err) {
22
22
  logger.warn("[Opus][DecoderProxy] Worker unavailable, falling back to main-thread decode:", err instanceof Error ? err.message : String(err));
23
23
  }
24
- const { OggOpusDecoder } = await import("./OpusCodec-TzsHzMqb.js").then((n) => n.n);
24
+ const { OggOpusDecoder } = await import("./OpusCodec-Cib3mtQ2.js").then((n) => n.n);
25
25
  proxy.fallbackDecoder = new OggOpusDecoder();
26
26
  proxy.backend = "main-thread";
27
27
  return proxy;
@@ -32,7 +32,7 @@ var OpusDecoderProxy = class OpusDecoderProxy {
32
32
  try {
33
33
  worker = new Worker(new URL(
34
34
  /* @vite-ignore */
35
- "/assets/OpusDecoderWorker.worker-ChLjIgER.js",
35
+ "" + new URL("assets/OpusDecoderWorker.worker-BAd4MYA3.js", import.meta.url).href,
36
36
  "" + import.meta.url
37
37
  ), { type: "module" });
38
38
  } catch (err) {
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-B-1-B7_t.js";
2
- import { t as logger } from "./logger-pANhsT4J.js";
2
+ import { t as logger } from "./logger-B_tTFAYq.js";
3
3
  //#region audio/OpusEncoderProxy.ts
4
4
  var OpusEncoderProxy_exports = /* @__PURE__ */ __exportAll({
5
5
  OpusEncoderProxy: () => OpusEncoderProxy,
@@ -43,7 +43,7 @@ var OpusEncoderProxy = class OpusEncoderProxy {
43
43
  } catch (err) {
44
44
  logger.warn("[Opus][Proxy] Worker unavailable, falling back to main-thread encode:", err instanceof Error ? err.message : String(err));
45
45
  }
46
- const { OggOpusEncoder } = await import("./OpusCodec-TzsHzMqb.js").then((n) => n.n);
46
+ const { OggOpusEncoder } = await import("./OpusCodec-Cib3mtQ2.js").then((n) => n.n);
47
47
  proxy.fallbackEncoder = new OggOpusEncoder(sampleRate, bitrate);
48
48
  proxy.backend = "main-thread";
49
49
  return proxy;
@@ -54,7 +54,7 @@ var OpusEncoderProxy = class OpusEncoderProxy {
54
54
  try {
55
55
  worker = new Worker(new URL(
56
56
  /* @vite-ignore */
57
- "/assets/OpusEncoderWorker.worker-bjAyiJ3b.js",
57
+ "" + new URL("assets/OpusEncoderWorker.worker-DdhFHkno.js", import.meta.url).href,
58
58
  "" + import.meta.url
59
59
  ), { type: "module" });
60
60
  } catch (err) {
@@ -1,5 +1,5 @@
1
- import { c as logEvent, t as logger } from "./logger-pANhsT4J.js";
2
- import { n as APP_CONFIG, t as errorToMessage } from "./error-utils-DAqUlC0I.js";
1
+ import { c as logEvent, t as logger } from "./logger-B_tTFAYq.js";
2
+ import { n as APP_CONFIG, t as errorToMessage } from "./error-utils-B76Nf6d6.js";
3
3
  //#region audio/StreamingAudioPlayer.ts
4
4
  /**
5
5
  * Streaming Audio Player
@@ -1,5 +1,5 @@
1
- import { St as ErrorCode, _t as generateTraceId, c as logEvent, h as hostOf, ht as isDebugMode, l as logMetric, t as logger, vt as AvatarError, y as recordHttpClientDuration } from "./logger-DI85eKqW.js";
2
- import { t as AvatarSDK } from "./AvatarSDK-Bdz1V7pz.js";
1
+ import { St as ErrorCode, _t as generateTraceId, c as logEvent, h as hostOf, ht as isDebugMode, l as logMetric, t as logger, vt as AvatarError, y as recordHttpClientDuration } from "./logger-__jZD7QG.js";
2
+ import { t as AvatarSDK } from "./AvatarSDK-DX8_-oyi.js";
3
3
  //#region config/app-config.ts
4
4
  const GLOBAL_FLAME_CDN_BASE = "https://cdn.spatialwalk.cloud/public";
5
5
  const CN_FLAME_CDN_BASE = "https://cdn.spatialwalk.top/public";
@@ -283,23 +283,13 @@ function getCacheInfo(url, response) {
283
283
  */
284
284
  function recordAssetTransaction(outcomes, durationMs, operation = ASSET_OPERATION) {
285
285
  const real = outcomes.filter((o) => !o.skipped);
286
- if (real.length === 0) {
287
- recordHttpClientDuration({
288
- operation,
289
- method: "GET",
290
- durationMs,
291
- statusCode: 200,
292
- cacheHit: true
293
- });
294
- return;
295
- }
286
+ if (real.length === 0) return;
296
287
  recordHttpClientDuration({
297
288
  operation,
298
289
  method: "GET",
299
290
  durationMs,
300
291
  statusCode: real.some((o) => o.statusCode === void 0) ? void 0 : real.reduce((max, o) => Math.max(max, o.statusCode ?? 0), 0),
301
- serverAddress: real[0].host,
302
- cacheHit: false
292
+ serverAddress: real[0].host
303
293
  });
304
294
  }
305
295
  /**
@@ -332,7 +322,7 @@ async function downloadResource(url, options) {
332
322
  cacheInfo.cacheType = "pwa";
333
323
  cacheInfo.pwaCacheSubtype = pwaCacheSubtype;
334
324
  if (outcomes && outcomeSlotIndex >= 0) outcomes[outcomeSlotIndex] = {
335
- host: "",
325
+ host: hostOf(url),
336
326
  skipped: true
337
327
  };
338
328
  return {
@@ -405,7 +395,6 @@ var AvatarDownloader = class {
405
395
  cache_hit: true,
406
396
  cache_type: "pwa"
407
397
  });
408
- recordAssetTransaction([], duration, TEMPLATE_OPERATION);
409
398
  return { unifiedModel: cached };
410
399
  }
411
400
  const maxRetries = 3;
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-B-1-B7_t.js";
2
- import { $ as INVALID_SPAN_CONTEXT, A as BindOnceFuture, B as ATTR_EXCEPTION_STACKTRACE, C as JSON_ENCODER, Ct as LogLevel, D as OTLPExporterBase, E as toAttributes, F as isTimeInput, G as globalErrorHandler, H as ATTR_SERVICE_NAME, I as isTimeInputHrTime, J as trace, K as isTracingSuppressed, L as millisToHrTime, M as addHrTimes, N as hrTime, O as defaultResource, P as hrTimeDuration, Q as isValidTraceId, R as otperformance, S as createLegacyOtlpBrowserExportDelegate, T as createResource, U as getNumberFromEnv, V as ATTR_EXCEPTION_TYPE, W as getStringFromEnv, X as context, Y as diag$1, Z as isSpanContextValid, _ as cleanupOtelMetrics, a as clientContextFields, at as DiagAPI, b as getSdkPackage, c as logEvent, ct as unregisterGlobal, d as cleanupOtel, dt as OTEL_STREAM_NAME, et as TraceFlags, f as initializeOtel, ft as OTEL_TRACES_ENDPOINT, g as observeExporter, gt as idManager, i as cleanupPostHog, it as createContextKey, j as ExportResultCode, k as resourceFromAttributes, lt as OTEL_LOGS_ENDPOINT, m as fetchBootstrap, mt as OTEL_USERNAME, n as setLogLevel, nt as createNoopMeter, o as getLogsFeatureFlag, ot as getGlobal, p as clockSync, pt as OTEL_TRACES_STREAM_NAME, q as suppressTracing, r as logSink, rt as ROOT_CONTEXT, s as initializePostHog, st as registerGlobal, t as logger, tt as ContextAPI, u as updatePostHogPersonPropertiesForFlags, ut as OTEL_PASSWORD, v as initializeOtelMetrics, w as createInstrumentationScope, x as resolveSdkVersion, xt as DrivingServiceMode, z as ATTR_EXCEPTION_MESSAGE } from "./logger-DI85eKqW.js";
2
+ import { $ as INVALID_SPAN_CONTEXT, A as BindOnceFuture, B as ATTR_EXCEPTION_STACKTRACE, C as JSON_ENCODER, Ct as LogLevel, D as OTLPExporterBase, E as toAttributes, F as isTimeInput, G as globalErrorHandler, H as ATTR_SERVICE_NAME, I as isTimeInputHrTime, J as trace, K as isTracingSuppressed, L as millisToHrTime, M as addHrTimes, N as hrTime, O as defaultResource, P as hrTimeDuration, Q as isValidTraceId, R as otperformance, S as createLegacyOtlpBrowserExportDelegate, T as createResource, U as getNumberFromEnv, V as ATTR_EXCEPTION_TYPE, W as getStringFromEnv, X as context, Y as diag$1, Z as isSpanContextValid, _ as cleanupOtelMetrics, a as clientContextFields, at as DiagAPI, b as getSdkPackage, c as logEvent, ct as unregisterGlobal, d as cleanupOtel, dt as OTEL_STREAM_NAME, et as TraceFlags, f as initializeOtel, ft as OTEL_TRACES_ENDPOINT, g as observeExporter, gt as idManager, i as cleanupPostHog, it as createContextKey, j as ExportResultCode, k as resourceFromAttributes, lt as OTEL_LOGS_ENDPOINT, m as fetchBootstrap, mt as OTEL_USERNAME, n as setLogLevel, nt as createNoopMeter, o as getLogsFeatureFlag, ot as getGlobal, p as clockSync, pt as OTEL_TRACES_STREAM_NAME, q as suppressTracing, r as logSink, rt as ROOT_CONTEXT, s as initializePostHog, st as registerGlobal, t as logger, tt as ContextAPI, u as updatePostHogPersonPropertiesForFlags, ut as OTEL_PASSWORD, v as initializeOtelMetrics, w as createInstrumentationScope, x as resolveSdkVersion, xt as DrivingServiceMode, z as ATTR_EXCEPTION_MESSAGE } from "./logger-__jZD7QG.js";
3
3
  //#region node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/baggage/internal/baggage-impl.js
4
4
  var BaggageImpl = class BaggageImpl {
5
5
  constructor(entries) {
@@ -6223,7 +6223,7 @@ var AvatarSDK = class {
6223
6223
  static _initializationState = "uninitialized";
6224
6224
  static _initializingPromise = null;
6225
6225
  static _configuration = null;
6226
- static _version = "1.3.3";
6226
+ static _version = "1.3.4";
6227
6227
  static _avatarCore = null;
6228
6228
  static _cachedDeviceScore = null;
6229
6229
  static _rendererBackend = null;
@@ -6412,7 +6412,7 @@ var AvatarSDK = class {
6412
6412
  logger.log("[AvatarSDK] Loading template resources...");
6413
6413
  logEvent("template_init_start", "info", { stage: "sdk_init" });
6414
6414
  try {
6415
- const { AvatarDownloader } = await import("./AvatarDownloader-Cy2QvOfT.js");
6415
+ const { AvatarDownloader } = await import("./AvatarDownloader-DkReeoUZ.js");
6416
6416
  const templateResources = await new AvatarDownloader().loadUnifiedTemplate();
6417
6417
  if (await this._avatarCore.loadTemplateResourcesFromBuffers(templateResources)) logger.log("[AvatarSDK] Template resources initialized successfully");
6418
6418
  else logger.log("[AvatarSDK] Template resources already initialized, skipping...");
@@ -1,5 +1,5 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "./rolldown-runtime-B-1-B7_t.js";
2
- import { t as logger } from "./logger-DI85eKqW.js";
2
+ import { t as logger } from "./logger-__jZD7QG.js";
3
3
  //#region __vite-browser-external
4
4
  var require___vite_browser_external = /* @__PURE__ */ __commonJSMin(((exports, module) => {
5
5
  module.exports = {};
@@ -1,5 +1,5 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "./rolldown-runtime-B-1-B7_t.js";
2
- import { t as logger } from "./logger-DI85eKqW.js";
2
+ import { t as logger } from "./logger-__jZD7QG.js";
3
3
  //#region __vite-browser-external
4
4
  var require___vite_browser_external = /* @__PURE__ */ __commonJSMin(((exports, module) => {
5
5
  module.exports = {};
@@ -13925,13 +13925,12 @@ function recordMetric(name, value, attributes = {}) {
13925
13925
  * @internal
13926
13926
  */
13927
13927
  function recordHttpClientDuration(params) {
13928
- const { operation, method, durationMs, statusCode, serverAddress, cacheHit } = params;
13928
+ const { operation, method, durationMs, statusCode, serverAddress } = params;
13929
13929
  const attrs = {
13930
13930
  "http.request.method": method,
13931
13931
  "operation": operation || "_OTHER"
13932
13932
  };
13933
13933
  if (serverAddress) attrs["server.address"] = serverAddress;
13934
- if (typeof cacheHit === "boolean") attrs["cache_hit"] = cacheHit;
13935
13934
  if (typeof statusCode === "number") attrs["http.response.status_code"] = statusCode;
13936
13935
  else attrs["error.type"] = "transport_error";
13937
13936
  recordMetric(HTTP_CLIENT_DURATION_METRIC, durationMs, attrs);
@@ -15450,7 +15449,7 @@ async function writeToLocalLog(message, level, extra = {}) {
15450
15449
  try {
15451
15450
  const { shouldPersist, sanitized } = sanitizeForLocalLog(message);
15452
15451
  if (!shouldPersist) return;
15453
- const { AvatarSDK } = await import("./AvatarSDK-Bdz1V7pz.js").then((n) => n.n);
15452
+ const { AvatarSDK } = await import("./AvatarSDK-DX8_-oyi.js").then((n) => n.n);
15454
15453
  const version = AvatarSDK.version;
15455
15454
  const appId = idManager.getAppId();
15456
15455
  const userId = idManager.getUserId();
@@ -1,4 +1,4 @@
1
- import { bt as isDebugMode } from "./logger-pANhsT4J.js";
1
+ import { bt as isDebugMode } from "./logger-B_tTFAYq.js";
2
2
  //#region config/app-config.ts
3
3
  var GLOBAL_FLAME_CDN_BASE = "https://cdn.spatialwalk.cloud/public";
4
4
  var CN_FLAME_CDN_BASE = "https://cdn.spatialwalk.top/public";
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { a as EgressType, c as TransportCompression, i as AudioFormat, l as BinaryReader, o as Message, r as avatarViewRegistry, s as MessageType, t as AvatarSDK, u as BinaryWriter } from "./AvatarSDK-BbqaBxdV.js";
2
- import { At as DEFAULT_REGION_REQUEST, C as recordMetric, Ct as AnimationType, Dt as ConversationState, Et as ConnectionState, Ft as LogLevel, It as RENDER_QUALITY_PARAMS, Lt as RenderQuality, Mt as ErrorCode, Nt as FrameStarvationMode, Ot as DEFAULT_OPUS_BITRATE, Pt as LoadProgress, Rt as TransitionType, Tt as AvatarState, c as logEvent, g as clockSync, h as resolveMarks, jt as DrivingServiceMode, kt as DEFAULT_REGION, l as logMetric, m as monoTimestamp, p as monoMarkFrom, t as logger, wt as AvatarError, xt as idManager } from "./logger-pANhsT4J.js";
3
- import { a as startLoadTrace, o as startPlaybackTrace, r as startConnectTrace, s as buildTraceparent } from "./otel-trace-DBN8K91J.js";
4
- import { n as APP_CONFIG } from "./error-utils-DAqUlC0I.js";
5
- import { r as OggMuxer, t as OggPageSplitter } from "./OpusCodec-TzsHzMqb.js";
6
- import { n as setOpusEncodeFrameSink } from "./OpusEncoderProxy-bLEToi2R.js";
7
- import { t as AvatarDownloader } from "./AvatarDownloader-DNeU2n5w.js";
1
+ import { a as EgressType, c as TransportCompression, i as AudioFormat, l as BinaryReader, o as Message, r as avatarViewRegistry, s as MessageType, t as AvatarSDK, u as BinaryWriter } from "./AvatarSDK-BMjjoYiZ.js";
2
+ import { At as DEFAULT_REGION_REQUEST, C as recordMetric, Ct as AnimationType, Dt as ConversationState, Et as ConnectionState, Ft as LogLevel, It as RENDER_QUALITY_PARAMS, Lt as RenderQuality, Mt as ErrorCode, Nt as FrameStarvationMode, Ot as DEFAULT_OPUS_BITRATE, Pt as LoadProgress, Rt as TransitionType, Tt as AvatarState, c as logEvent, g as clockSync, h as resolveMarks, jt as DrivingServiceMode, kt as DEFAULT_REGION, l as logMetric, m as monoTimestamp, p as monoMarkFrom, t as logger, wt as AvatarError, xt as idManager } from "./logger-B_tTFAYq.js";
3
+ import { a as startLoadTrace, o as startPlaybackTrace, r as startConnectTrace, s as buildTraceparent } from "./otel-trace-DmmQrXv-.js";
4
+ import { n as APP_CONFIG } from "./error-utils-B76Nf6d6.js";
5
+ import { r as OggMuxer, t as OggPageSplitter } from "./OpusCodec-Cib3mtQ2.js";
6
+ import { n as setOpusEncodeFrameSink } from "./OpusEncoderProxy-BiX90p4q.js";
7
+ import { t as AvatarDownloader } from "./AvatarDownloader-CavxMpAz.js";
8
8
  //#region core/Avatar.ts
9
9
  var Avatar = class {
10
10
  id;
@@ -311,8 +311,8 @@ var AnimationPlayer = class AnimationPlayer {
311
311
  */
312
312
  async createAndInitializeStreamingPlayer() {
313
313
  if (this.streamingPlayer) return;
314
- const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-CCg4uoVV.js");
315
- const { AvatarSDK } = await import("./AvatarSDK-BbqaBxdV.js").then((n) => n.n);
314
+ const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-D5_x6veD.js");
315
+ const { AvatarSDK } = await import("./AvatarSDK-BMjjoYiZ.js").then((n) => n.n);
316
316
  const audioFormat = AvatarSDK.getAudioFormat();
317
317
  this.streamingPlayer = new StreamingAudioPlayer({
318
318
  sampleRate: audioFormat.sampleRate,
@@ -1352,7 +1352,7 @@ var AnimationWebSocketClient = class extends EventEmitter {
1352
1352
  return;
1353
1353
  }
1354
1354
  try {
1355
- const { OpusEncoderProxy } = await import("./OpusEncoderProxy-bLEToi2R.js").then((n) => n.t);
1355
+ const { OpusEncoderProxy } = await import("./OpusEncoderProxy-BiX90p4q.js").then((n) => n.t);
1356
1356
  const bitrate = opusBitrate ?? 48e3;
1357
1357
  this.opusEncoder = await OpusEncoderProxy.create(sampleRate, bitrate);
1358
1358
  this.uplinkIsOpus = true;
@@ -2794,7 +2794,7 @@ var AvatarController = class {
2794
2794
  const { inputAudioFormat } = AvatarSDK.getAudioFormat();
2795
2795
  if (inputAudioFormat !== "opus" || this.inputOpusDecoderProxy) return;
2796
2796
  try {
2797
- const { OpusDecoderProxy } = await import("./OpusDecoderProxy-D4J2CfRQ.js");
2797
+ const { OpusDecoderProxy } = await import("./OpusDecoderProxy-Dz21UtCz.js");
2798
2798
  this.inputOpusDecoderProxy = await OpusDecoderProxy.create();
2799
2799
  this.inputDecodeChain = Promise.resolve();
2800
2800
  } catch (error) {
@@ -4094,7 +4094,7 @@ var AvatarManager = class AvatarManager {
4094
4094
  } else {
4095
4095
  logger.log(`[AvatarManager] Avatar ${id} cache invalid: updatedAt=${cachedUpdatedAt}->${newUpdatedAt}, modelType=${cachedModelType}->${requestedModelType}, reloading...`);
4096
4096
  this.avatarCache.delete(id);
4097
- const { PwaCacheManager } = await import("./pwa-cache-manager-M3XsMhvz.js").then((n) => n.n);
4097
+ const { PwaCacheManager } = await import("./pwa-cache-manager-BxeZI1BU.js").then((n) => n.n);
4098
4098
  await PwaCacheManager.clearCharacterCache(id);
4099
4099
  }
4100
4100
  }
@@ -1,5 +1,5 @@
1
- import { C as recordMetric$1, E as setSdkIdentity$1, g as clockSync } from "./logger-pANhsT4J.js";
2
- import { o as startPlaybackTrace$1 } from "./otel-trace-DBN8K91J.js";
1
+ import { C as recordMetric$1, E as setSdkIdentity$1, g as clockSync } from "./logger-B_tTFAYq.js";
2
+ import { o as startPlaybackTrace$1 } from "./otel-trace-DmmQrXv-.js";
3
3
  //#region internal-telemetry.ts
4
4
  /**
5
5
  * Internal telemetry surface for the companion RTC SDK.
@@ -14017,13 +14017,12 @@ function recordMetric(name, value, attributes = {}) {
14017
14017
  * @internal
14018
14018
  */
14019
14019
  function recordHttpClientDuration(params) {
14020
- const { operation, method, durationMs, statusCode, serverAddress, cacheHit } = params;
14020
+ const { operation, method, durationMs, statusCode, serverAddress } = params;
14021
14021
  const attrs = {
14022
14022
  "http.request.method": method,
14023
14023
  "operation": operation || "_OTHER"
14024
14024
  };
14025
14025
  if (serverAddress) attrs["server.address"] = serverAddress;
14026
- if (typeof cacheHit === "boolean") attrs["cache_hit"] = cacheHit;
14027
14026
  if (typeof statusCode === "number") attrs["http.response.status_code"] = statusCode;
14028
14027
  else attrs["error.type"] = "transport_error";
14029
14028
  recordMetric(HTTP_CLIENT_DURATION_METRIC, durationMs, attrs);
@@ -15571,7 +15570,7 @@ async function writeToLocalLog(message, level, extra = {}) {
15571
15570
  try {
15572
15571
  const { shouldPersist, sanitized } = sanitizeForLocalLog(message);
15573
15572
  if (!shouldPersist) return;
15574
- const { AvatarSDK } = await import("./AvatarSDK-BbqaBxdV.js").then((n) => n.n);
15573
+ const { AvatarSDK } = await import("./AvatarSDK-BMjjoYiZ.js").then((n) => n.n);
15575
15574
  const version = AvatarSDK.version;
15576
15575
  const appId = idManager.getAppId();
15577
15576
  const userId = idManager.getUserId();
@@ -1,4 +1,4 @@
1
- import { $ as trace, A as createResource, B as isTimeInput, D as createLegacyOtlpBrowserExportDelegate, F as BindOnceFuture, G as ATTR_EXCEPTION_STACKTRACE, H as millisToHrTime, I as ExportResultCode, J as getNumberFromEnv, K as ATTR_EXCEPTION_TYPE, L as addHrTimes, M as OTLPExporterBase, N as defaultResource, O as JSON_ENCODER, P as resourceFromAttributes, Q as suppressTracing, R as hrTime, T as resolveSdkVersion, U as otperformance, V as isTimeInputHrTime, W as ATTR_EXCEPTION_MESSAGE, X as globalErrorHandler, Y as getStringFromEnv, Z as isTracingSuppressed, _t as OTEL_TRACES_ENDPOINT, a as clientContextFields, at as TraceFlags, ct as ROOT_CONTEXT, dt as getGlobal, et as diag$1, ft as registerGlobal, ht as OTEL_PASSWORD, it as INVALID_SPAN_CONTEXT, j as toAttributes, k as createInstrumentationScope, lt as createContextKey, nt as isSpanContextValid, ot as ContextAPI, pt as unregisterGlobal, q as ATTR_SERVICE_NAME, rt as isValidTraceId, st as createNoopMeter, t as logger, tt as context, ut as DiagAPI, vt as OTEL_TRACES_STREAM_NAME, w as getSdkPackage, xt as idManager, y as observeExporter, yt as OTEL_USERNAME, z as hrTimeDuration } from "./logger-pANhsT4J.js";
1
+ import { $ as trace, A as createResource, B as isTimeInput, D as createLegacyOtlpBrowserExportDelegate, F as BindOnceFuture, G as ATTR_EXCEPTION_STACKTRACE, H as millisToHrTime, I as ExportResultCode, J as getNumberFromEnv, K as ATTR_EXCEPTION_TYPE, L as addHrTimes, M as OTLPExporterBase, N as defaultResource, O as JSON_ENCODER, P as resourceFromAttributes, Q as suppressTracing, R as hrTime, T as resolveSdkVersion, U as otperformance, V as isTimeInputHrTime, W as ATTR_EXCEPTION_MESSAGE, X as globalErrorHandler, Y as getStringFromEnv, Z as isTracingSuppressed, _t as OTEL_TRACES_ENDPOINT, a as clientContextFields, at as TraceFlags, ct as ROOT_CONTEXT, dt as getGlobal, et as diag$1, ft as registerGlobal, ht as OTEL_PASSWORD, it as INVALID_SPAN_CONTEXT, j as toAttributes, k as createInstrumentationScope, lt as createContextKey, nt as isSpanContextValid, ot as ContextAPI, pt as unregisterGlobal, q as ATTR_SERVICE_NAME, rt as isValidTraceId, st as createNoopMeter, t as logger, tt as context, ut as DiagAPI, vt as OTEL_TRACES_STREAM_NAME, w as getSdkPackage, xt as idManager, y as observeExporter, yt as OTEL_USERNAME, z as hrTimeDuration } from "./logger-B_tTFAYq.js";
2
2
  //#region node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/baggage/internal/baggage-impl.js
3
3
  var BaggageImpl = class BaggageImpl {
4
4
  constructor(entries) {
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-B-1-B7_t.js";
2
- import { t as logger } from "./logger-pANhsT4J.js";
2
+ import { t as logger } from "./logger-B_tTFAYq.js";
3
3
  //#region utils/pwa-cache-manager.ts
4
4
  /**
5
5
  * PWA Cache Manager
package/next.js CHANGED
@@ -65,6 +65,46 @@ function copyWasmToPublic(projectDir) {
65
65
  console.warn('[avatarkit] SDK dist dir:', sdkDistDir);
66
66
  }
67
67
  }
68
+ // ── Copy Opus workers to public directory ─────────────────────────────
69
+ // The SDK loads these with `new Worker(new URL('assets/…', import.meta.url))`.
70
+ // Vite resolves that at build time; Next.js instead tries to bundle the worker,
71
+ // and its ESM output then fails Terser (`import` outside module code). Serving
72
+ // the pre-built worker from public/ sidesteps the consumer bundler entirely.
73
+ function copyWorkersToPublic(projectDir) {
74
+ const publicAssetsDir = join(projectDir, 'public', 'assets');
75
+ try {
76
+ const workerDir = join(sdkDistDir, 'assets');
77
+ if (!existsSync(workerDir))
78
+ return;
79
+ mkdirSync(publicAssetsDir, { recursive: true });
80
+ // The workers are ES modules that import sibling chunks (the logger and the
81
+ // rolldown runtime), so copying the worker alone leaves it unable to start.
82
+ // Follow the import graph instead of naming chunks that can change on any
83
+ // rebuild.
84
+ const queue = readdirSync(workerDir).filter((file) => file.includes('.worker-') && file.endsWith('.js'));
85
+ const copied = new Set();
86
+ while (queue.length > 0) {
87
+ const file = queue.shift();
88
+ if (copied.has(file))
89
+ continue;
90
+ const src = join(workerDir, file);
91
+ if (!existsSync(src)) {
92
+ console.warn('[avatarkit] Worker chunk missing from dist:', file);
93
+ continue;
94
+ }
95
+ copied.add(file);
96
+ copyFileSync(src, join(publicAssetsDir, file));
97
+ const source = readFileSync(src, 'utf8');
98
+ for (const match of source.matchAll(/from\s*["']\.\/([^"']+)["']/g)) {
99
+ if (!copied.has(match[1]))
100
+ queue.push(match[1]);
101
+ }
102
+ }
103
+ }
104
+ catch (err) {
105
+ console.warn('[avatarkit] Failed to copy Opus workers:', err.message);
106
+ }
107
+ }
68
108
  // ── Webpack plugin: copy WASM to build output ─────────────────────────
69
109
  // Emits WASM files into .next/static/chunks/ during webpack compilation.
70
110
  // This is needed in addition to public/ for standalone Docker deployments
@@ -131,6 +171,7 @@ export function withAvatarkit(nextConfig = {}) {
131
171
  const projectRoot = findProjectRoot();
132
172
  // Copy WASM files to public/_avatarkit/ (works for both webpack & Turbopack)
133
173
  copyWasmToPublic(projectRoot);
174
+ copyWorkersToPublic(projectRoot);
134
175
  return {
135
176
  ...nextConfig,
136
177
  // ── Turbopack configuration (Next.js 15+/16+) ──
@@ -161,7 +202,18 @@ export function withAvatarkit(nextConfig = {}) {
161
202
  enforce: 'pre',
162
203
  use: [{ loader: loaderPath }],
163
204
  });
164
- // 3. Copy WASM files to static/chunks/ (client build only, for standalone)
205
+ // 3. Leave the Opus workers alone: they are already built and are served
206
+ // from public/assets/. Webpack would otherwise pull them through its own
207
+ // pipeline, where Terser parses the ESM worker as a classic script and
208
+ // fails on the `import` statements. An empty loader list keeps the file
209
+ // resolvable without re-processing it.
210
+ config.module.rules.unshift({
211
+ test: /[\\/]assets[\\/].*\.worker-[^/\\]*\.js$/,
212
+ type: 'javascript/auto',
213
+ use: [],
214
+ parser: { javascript: { worker: false } },
215
+ });
216
+ // 4. Copy WASM files to static/chunks/ (client build only, for standalone)
165
217
  if (!context.isServer) {
166
218
  config.plugins.push(new CopyWasmPlugin());
167
219
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spatius/avatarkit",
3
3
  "type": "module",
4
- "version": "1.3.3",
4
+ "version": "1.3.4",
5
5
  "packageManager": "pnpm@10.18.2",
6
6
  "description": "AvatarKit — real-time, audio-driven avatar rendering SDK for Web.",
7
7
  "homepage": "https://spatius.ai/",