@spatialwalk/avatarkit 1.0.0-beta.57 → 1.0.0-beta.59

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
@@ -2,6 +2,17 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.0.0-beta.59] - 2026-01-14
6
+
7
+ ### 🐛 Bugfixes
8
+ - **AudioContext Auto-Resume** - Fixed issue where audio playback would get stuck after external applications request recording permissions. AudioContext now automatically resumes when suspended during playback
9
+ - **PostHog Instance Initialization** - Fixed PostHog named instance initialization to avoid conflicts with external PostHog instances
10
+
11
+ ## [1.0.0-beta.58] - 2026-01-14
12
+
13
+ ### ✨ New Features
14
+ - **Pure Rendering Mode APIs** - Added `renderFlame()` and `generateTransitionFromIdle()` methods to `AvatarView` for external-controlled rendering without audio synchronization
15
+
5
16
  ## [1.0.0-beta.57] - 2026-01-09
6
17
 
7
18
  ### 🐛 Bugfixes
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { A as APP_CONFIG, e as errorToMessage, l as logEvent, a as logger } from "./index-cfYSlUmQ.js";
4
+ import { A as APP_CONFIG, l as logger, e as errorToMessage, a as logEvent } from "./index-B0MJ_hCJ.js";
5
5
  class StreamingAudioPlayer {
6
6
  constructor(options) {
7
7
  __publicField(this, "audioContext", null);
@@ -27,6 +27,8 @@ class StreamingAudioPlayer {
27
27
  __publicField(this, "gainNode", null);
28
28
  __publicField(this, "volume", 1);
29
29
  __publicField(this, "onEndedCallback");
30
+ __publicField(this, "stateChangeHandler");
31
+ __publicField(this, "isResuming", false);
30
32
  this.sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
31
33
  this.sampleRate = (options == null ? void 0 : options.sampleRate) ?? APP_CONFIG.audio.sampleRate;
32
34
  this.channelCount = (options == null ? void 0 : options.channelCount) ?? 1;
@@ -46,6 +48,15 @@ class StreamingAudioPlayer {
46
48
  if (this.audioContext.state === "suspended") {
47
49
  await this.audioContext.resume();
48
50
  }
51
+ this.stateChangeHandler = (event) => {
52
+ const context = event.target;
53
+ if (context.state === "suspended" && this.isPlaying && !this.isPaused) {
54
+ this.ensureAudioContextRunning().catch((err) => {
55
+ logger.errorWithError("[StreamingAudioPlayer] Failed to auto-resume AudioContext after external suspend:", err);
56
+ });
57
+ }
58
+ };
59
+ this.audioContext.addEventListener("statechange", this.stateChangeHandler);
49
60
  this.log("AudioContext initialized", {
50
61
  sessionId: this.sessionId,
51
62
  sampleRate: this.audioContext.sampleRate,
@@ -61,11 +72,64 @@ class StreamingAudioPlayer {
61
72
  throw error instanceof Error ? error : new Error(message);
62
73
  }
63
74
  }
75
+ async ensureAudioContextRunning() {
76
+ if (!this.audioContext) {
77
+ return;
78
+ }
79
+ const state = this.audioContext.state;
80
+ if (state === "running") {
81
+ return;
82
+ }
83
+ if (state === "closed") {
84
+ this.log("AudioContext is closed, cannot resume", {
85
+ sessionId: this.sessionId,
86
+ state
87
+ });
88
+ return;
89
+ }
90
+ if (state === "suspended" && this.isPlaying && !this.isPaused) {
91
+ if (this.isResuming) {
92
+ this.log("AudioContext resume already in progress, skipping duplicate request", {
93
+ sessionId: this.sessionId,
94
+ state
95
+ });
96
+ return;
97
+ }
98
+ this.isResuming = true;
99
+ try {
100
+ this.log("AudioContext is suspended during playback, resuming...", {
101
+ sessionId: this.sessionId,
102
+ state,
103
+ isPlaying: this.isPlaying,
104
+ isPaused: this.isPaused
105
+ });
106
+ await this.audioContext.resume();
107
+ this.log("AudioContext resumed successfully", {
108
+ sessionId: this.sessionId,
109
+ state: this.audioContext.state
110
+ });
111
+ } catch (err) {
112
+ logger.errorWithError("[StreamingAudioPlayer] Failed to resume AudioContext:", err);
113
+ logEvent("character_player", "error", {
114
+ sessionId: this.sessionId,
115
+ event: "audio_context_resume_failed",
116
+ reason: err instanceof Error ? err.message : String(err)
117
+ });
118
+ } finally {
119
+ this.isResuming = false;
120
+ }
121
+ }
122
+ }
64
123
  addChunk(pcmData, isLast = false) {
65
124
  if (!this.audioContext) {
66
125
  logger.error("AudioContext not initialized");
67
126
  return;
68
127
  }
128
+ if (this.isPlaying && !this.isPaused && this.audioContext.state === "suspended") {
129
+ this.ensureAudioContextRunning().catch((err) => {
130
+ logger.errorWithError("[StreamingAudioPlayer] Failed to ensure AudioContext running in addChunk:", err);
131
+ });
132
+ }
69
133
  this.audioChunks.push({ data: pcmData, isLast });
70
134
  this.log(`Added chunk ${this.audioChunks.length}`, {
71
135
  size: pcmData.length,
@@ -83,7 +147,9 @@ class StreamingAudioPlayer {
83
147
  }
84
148
  if (!this.isPlaying && this.autoStartEnabled && this.audioChunks.length > 0) {
85
149
  this.log("[StreamingAudioPlayer] Auto-starting playback from addChunk");
86
- this.startPlayback();
150
+ this.startPlayback().catch((err) => {
151
+ logger.errorWithError("[StreamingAudioPlayer] Failed to start playback from addChunk:", err);
152
+ });
87
153
  } else if (this.isPlaying && !this.isPaused) {
88
154
  this.log("[StreamingAudioPlayer] Already playing, scheduling next chunk");
89
155
  this.scheduleNextChunk();
@@ -107,7 +173,7 @@ class StreamingAudioPlayer {
107
173
  this.addChunk(chunk.data, chunk.isLast);
108
174
  }
109
175
  }
110
- startPlayback() {
176
+ async startPlayback() {
111
177
  if (!this.audioContext) {
112
178
  this.log("[StreamingAudioPlayer] Cannot start playback: AudioContext not initialized");
113
179
  return;
@@ -116,6 +182,7 @@ class StreamingAudioPlayer {
116
182
  this.log("[StreamingAudioPlayer] Cannot start playback: Already playing");
117
183
  return;
118
184
  }
185
+ await this.ensureAudioContextRunning();
119
186
  this.isPlaying = true;
120
187
  this.sessionStartTime = this.audioContext.currentTime;
121
188
  this.scheduledTime = this.sessionStartTime;
@@ -126,7 +193,8 @@ class StreamingAudioPlayer {
126
193
  sessionStartTime: this.sessionStartTime,
127
194
  bufferedChunks: this.audioChunks.length,
128
195
  scheduledChunks: this.scheduledChunks,
129
- activeSources: this.activeSources.size
196
+ activeSources: this.activeSources.size,
197
+ audioContextState: this.audioContext.state
130
198
  });
131
199
  this.scheduleAllChunks();
132
200
  }
@@ -144,6 +212,11 @@ class StreamingAudioPlayer {
144
212
  this.log("[StreamingAudioPlayer] Cannot schedule chunk: Not playing or paused");
145
213
  return;
146
214
  }
215
+ if (this.audioContext.state === "suspended") {
216
+ this.ensureAudioContextRunning().catch((err) => {
217
+ logger.errorWithError("[StreamingAudioPlayer] Failed to ensure AudioContext running in scheduleNextChunk:", err);
218
+ });
219
+ }
147
220
  const chunkIndex = this.scheduledChunks;
148
221
  if (chunkIndex >= this.audioChunks.length) {
149
222
  this.log(`[StreamingAudioPlayer] No more chunks to schedule (chunkIndex: ${chunkIndex}, totalChunks: ${this.audioChunks.length})`);
@@ -345,6 +418,7 @@ class StreamingAudioPlayer {
345
418
  }
346
419
  this.isPlaying = false;
347
420
  this.isPaused = false;
421
+ this.isResuming = false;
348
422
  this.sessionStartTime = 0;
349
423
  this.scheduledTime = 0;
350
424
  for (const source of this.activeSources) {
@@ -373,7 +447,9 @@ class StreamingAudioPlayer {
373
447
  return;
374
448
  }
375
449
  this.autoStartEnabled = true;
376
- this.startPlayback();
450
+ this.startPlayback().catch((err) => {
451
+ logger.errorWithError("[StreamingAudioPlayer] Failed to start playback from play():", err);
452
+ });
377
453
  }
378
454
  markEnded() {
379
455
  var _a;
@@ -389,6 +465,10 @@ class StreamingAudioPlayer {
389
465
  }
390
466
  dispose() {
391
467
  this.stop();
468
+ if (this.audioContext && this.stateChangeHandler) {
469
+ this.audioContext.removeEventListener("statechange", this.stateChangeHandler);
470
+ this.stateChangeHandler = void 0;
471
+ }
392
472
  if (this.audioContext) {
393
473
  this.audioContext.close();
394
474
  this.audioContext = null;
@@ -27,8 +27,11 @@ export declare class StreamingAudioPlayer {
27
27
  private gainNode;
28
28
  private volume;
29
29
  private onEndedCallback?;
30
+ private stateChangeHandler?;
31
+ private isResuming;
30
32
  constructor(options?: StreamingAudioPlayerOptions);
31
33
  initialize(): Promise<void>;
34
+ private ensureAudioContextRunning;
32
35
  addChunk(pcmData: Uint8Array, isLast?: boolean): void;
33
36
  startNewSession(audioChunks: Array<{
34
37
  data: Uint8Array;
File without changes
@@ -1,5 +1,7 @@
1
1
  import { Environment } from '../types';
2
2
 
3
+ export declare const DEFAULT_SDK_CONFIG: Partial<Record<Environment, string>>;
4
+
3
5
  export declare function fetchSdkConfig(version: string): Promise<Partial<Record<Environment, string>>>;
4
6
 
5
7
  export declare function clearSdkConfigCache(): void;
@@ -27,6 +27,7 @@ export declare class AvatarView {
27
27
  private idleCurrentFrameIndex;
28
28
  private characterHandle;
29
29
  private characterId;
30
+ private isPureRenderingMode;
30
31
  private alignFlamePair;
31
32
  private generateAndAlignTransitionFrames;
32
33
  private getCachedIdleFirstFrame;
@@ -57,7 +58,8 @@ export declare class AvatarView {
57
58
  private startRealtimeRendering;
58
59
  private stopRealtimeRendering;
59
60
  dispose(): void;
60
- renderFlame(flame: Flame): Promise<void>;
61
+ renderFlame(flame: Flame, enableIdleRendering?: boolean): Promise<void>;
62
+ generateTransitionFromIdle(toFlame: Flame, frameCount: number): Promise<Flame[]>;
61
63
  private rerenderCurrentFrameWithNewCamera;
62
64
  private handleResize;
63
65
  get transform(): {
@@ -7397,19 +7397,7 @@ let isInitialized = false;
7397
7397
  const SDK_POSTHOG_INSTANCE_NAME = "spatialwalk-posthog";
7398
7398
  let sdkPosthogInstance = null;
7399
7399
  const eventQueue = [];
7400
- const FILTERED_HOSTNAMES = ["localhost", "127.0.0.1", "0.0.0.0"];
7401
- function shouldFilterHostname() {
7402
- if (typeof window === "undefined") {
7403
- return false;
7404
- }
7405
- const hostname = window.location.hostname;
7406
- return FILTERED_HOSTNAMES.includes(hostname);
7407
- }
7408
7400
  function initializePostHog(environment, version) {
7409
- if (shouldFilterHostname()) {
7410
- logger.log(`[PostHog] Tracking disabled due to filtered hostname: ${window.location.hostname}`);
7411
- return;
7412
- }
7413
7401
  const { host, apiKey, disableCompression } = getPostHogConfig(environment);
7414
7402
  if (!apiKey) {
7415
7403
  logger.warn(`[PostHog] API Key not configured for environment: ${environment}, tracking disabled`);
@@ -7425,7 +7413,6 @@ function initializePostHog(environment, version) {
7425
7413
  const logContext = idManager.getLogContext();
7426
7414
  Vo.init(apiKey, {
7427
7415
  api_host: host,
7428
- name: SDK_POSTHOG_INSTANCE_NAME,
7429
7416
  person_profiles: "identified_only",
7430
7417
  capture_pageview: false,
7431
7418
  capture_pageleave: false,
@@ -7455,7 +7442,7 @@ function initializePostHog(environment, version) {
7455
7442
  }
7456
7443
  flushEventQueue();
7457
7444
  }
7458
- });
7445
+ }, SDK_POSTHOG_INSTANCE_NAME);
7459
7446
  } catch (error) {
7460
7447
  logger.warn("[PostHog] Failed to initialize:", error instanceof Error ? error.message : String(error));
7461
7448
  }
@@ -7505,9 +7492,6 @@ function flushEventQueue() {
7505
7492
  }, 0);
7506
7493
  }
7507
7494
  function trackEvent(event, level = "info", contents = {}) {
7508
- if (shouldFilterHostname()) {
7509
- return;
7510
- }
7511
7495
  const instance = getSdkPosthogInstance();
7512
7496
  if (!instance) {
7513
7497
  eventQueue.push({ event, level, contents });
@@ -7639,7 +7623,7 @@ const _AnimationPlayer = class _AnimationPlayer {
7639
7623
  if (this.streamingPlayer) {
7640
7624
  return;
7641
7625
  }
7642
- const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-Co3xec_k.js");
7626
+ const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-BbUBoPqm.js");
7643
7627
  const { AvatarSDK: AvatarSDK2 } = await Promise.resolve().then(() => AvatarSDK$1);
7644
7628
  const audioFormat = AvatarSDK2.getAudioFormat();
7645
7629
  this.streamingPlayer = new StreamingAudioPlayer({
@@ -7786,6 +7770,10 @@ const _AnimationPlayer = class _AnimationPlayer {
7786
7770
  };
7787
7771
  __publicField(_AnimationPlayer, "audioUnlocked", false);
7788
7772
  let AnimationPlayer = _AnimationPlayer;
7773
+ const DEFAULT_SDK_CONFIG = {
7774
+ [Environment.cn]: "https://api.open.spatialwalk.top",
7775
+ [Environment.intl]: "https://api.intl.spatialwalk.cloud"
7776
+ };
7789
7777
  const configCache = {
7790
7778
  config: null,
7791
7779
  promise: null
@@ -7824,10 +7812,7 @@ async function fetchSdkConfig(version) {
7824
7812
  configCache.config = config;
7825
7813
  logger.log(`[SdkConfigLoader] SDK config fetched successfully:`, config);
7826
7814
  } catch (error) {
7827
- configCache.config = {
7828
- [Environment.cn]: "https://api.open.spatialwalk.top",
7829
- [Environment.intl]: "https://api.intl.spatialwalk.cloud"
7830
- };
7815
+ configCache.config = { ...DEFAULT_SDK_CONFIG };
7831
7816
  logger.log("[SdkConfigLoader] Using default SDK config:", configCache.config);
7832
7817
  } finally {
7833
7818
  configCache.promise = null;
@@ -8887,6 +8872,7 @@ class AvatarSDK {
8887
8872
  idManager.setAppId(appId);
8888
8873
  logger.log(`[AvatarSDK] Client ID: ${idManager.getClientId()}`);
8889
8874
  initializePostHog(configuration.environment, this._version);
8875
+ this._dynamicSdkConfig = { ...DEFAULT_SDK_CONFIG };
8890
8876
  this._fetchSdkConfig().catch((err) => {
8891
8877
  const message = err instanceof Error ? err.message : String(err);
8892
8878
  logger.warn("Failed to fetch SDK config from remote, using defaults:", message);
@@ -9062,7 +9048,7 @@ class AvatarSDK {
9062
9048
  }
9063
9049
  __publicField(AvatarSDK, "_isInitialized", false);
9064
9050
  __publicField(AvatarSDK, "_configuration", null);
9065
- __publicField(AvatarSDK, "_version", "1.0.0-beta.57");
9051
+ __publicField(AvatarSDK, "_version", "1.0.0-beta.59");
9066
9052
  __publicField(AvatarSDK, "_avatarCore", null);
9067
9053
  __publicField(AvatarSDK, "_dynamicSdkConfig", null);
9068
9054
  const AvatarSDK$1 = Object.freeze(Object.defineProperty({
@@ -11419,7 +11405,6 @@ class AvatarController {
11419
11405
  return true;
11420
11406
  }
11421
11407
  const audioContextState = ((_c = streamingPlayer.audioContext) == null ? void 0 : _c.state) || "unknown";
11422
- const isAudioContextSuspended = audioContextState === "suspended";
11423
11408
  const activeSourcesCount = ((_d = streamingPlayer.activeSources) == null ? void 0 : _d.size) || 0;
11424
11409
  const scheduledChunks = streamingPlayer.scheduledChunks || 0;
11425
11410
  const hasScheduledButNoActive = scheduledChunks > 0 && activeSourcesCount === 0;
@@ -11434,7 +11419,7 @@ class AvatarController {
11434
11419
  state.audioTimeStuckCount = 0;
11435
11420
  }
11436
11421
  state.lastAudioTime = audioTime;
11437
- const shouldReport = state.audioTimeZeroCount > this.MAX_AUDIO_TIME_ZERO_COUNT || state.audioTimeStuckCount > this.MAX_AUDIO_TIME_STUCK_COUNT || isAudioContextSuspended && this.isPlaying || hasScheduledButNoActive && this.isPlaying;
11422
+ const shouldReport = state.audioTimeZeroCount > this.MAX_AUDIO_TIME_ZERO_COUNT || state.audioTimeStuckCount > this.MAX_AUDIO_TIME_STUCK_COUNT || hasScheduledButNoActive && this.isPlaying;
11438
11423
  if (shouldReport && isNotPaused) {
11439
11424
  state.reported = true;
11440
11425
  logEvent("character_player", "error", {
@@ -11442,7 +11427,6 @@ class AvatarController {
11442
11427
  avatar_id: this.avatar.id,
11443
11428
  conversationId: ((_e2 = this.networkLayer) == null ? void 0 : _e2.getCurrentConversationId()) || void 0,
11444
11429
  audioContextState,
11445
- isAudioContextSuspended,
11446
11430
  audioTime,
11447
11431
  audioTimeZero: audioTime === 0,
11448
11432
  audioTimeZeroCount: state.audioTimeZeroCount,
@@ -13990,6 +13974,7 @@ class AvatarView {
13990
13974
  __publicField(this, "idleCurrentFrameIndex", 0);
13991
13975
  __publicField(this, "characterHandle", null);
13992
13976
  __publicField(this, "characterId");
13977
+ __publicField(this, "isPureRenderingMode", false);
13993
13978
  this.avatar = avatar;
13994
13979
  this.characterId = `${avatar.id}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
13995
13980
  if (!AvatarSDK.configuration) {
@@ -14335,6 +14320,10 @@ class AvatarView {
14335
14320
  return;
14336
14321
  }
14337
14322
  lastTime = currentTime;
14323
+ if (this.isPureRenderingMode) {
14324
+ this.idleAnimationLoopId = requestAnimationFrame(renderFrame);
14325
+ return;
14326
+ }
14338
14327
  const avatarCore = AvatarSDK.getAvatarCore();
14339
14328
  if (!avatarCore) {
14340
14329
  return;
@@ -14345,6 +14334,9 @@ class AvatarView {
14345
14334
  if (this.renderingState !== "idle") {
14346
14335
  return;
14347
14336
  }
14337
+ if (this.isPureRenderingMode) {
14338
+ return;
14339
+ }
14348
14340
  this.renderSystem.loadSplatsFromPackedData(splatData);
14349
14341
  this.renderSystem.renderFrame();
14350
14342
  }
@@ -14683,10 +14675,15 @@ class AvatarView {
14683
14675
  }
14684
14676
  }
14685
14677
  }
14686
- async renderFlame(flame) {
14678
+ async renderFlame(flame, enableIdleRendering) {
14687
14679
  if (!this.isInitialized || !this.renderSystem) {
14688
14680
  throw new Error("AvatarView not initialized");
14689
14681
  }
14682
+ if (enableIdleRendering === true) {
14683
+ this.isPureRenderingMode = false;
14684
+ return;
14685
+ }
14686
+ this.isPureRenderingMode = true;
14690
14687
  try {
14691
14688
  const processedFlame = this.avatarController.applyPostProcessingToFlame(flame);
14692
14689
  const wasmParams = convertProtoFlameToWasmParams(processedFlame);
@@ -14707,6 +14704,38 @@ class AvatarView {
14707
14704
  throw error;
14708
14705
  }
14709
14706
  }
14707
+ async generateTransitionFromIdle(toFlame, frameCount) {
14708
+ if (!this.isInitialized) {
14709
+ throw new Error("AvatarView not initialized");
14710
+ }
14711
+ if (frameCount <= 0) {
14712
+ throw new Error("Frame count must be greater than 0");
14713
+ }
14714
+ const avatarCore = AvatarSDK.getAvatarCore();
14715
+ if (!avatarCore) {
14716
+ throw new Error("AvatarCore not available");
14717
+ }
14718
+ try {
14719
+ const idleParams = await avatarCore.getCurrentFrameParams(this.idleCurrentFrameIndex, this.characterId);
14720
+ const idleFrameProto = convertWasmParamsToProtoFlame(idleParams);
14721
+ const toFlameWithPostProcessing = this.avatarController.applyPostProcessingToFlame(toFlame);
14722
+ const aligned = this.alignFlamePair(idleFrameProto, toFlameWithPostProcessing);
14723
+ const fps = APP_CONFIG.animation.fps;
14724
+ const durationMs = frameCount / fps * 1e3;
14725
+ const transitionFrames = generateTransitionFrames(
14726
+ aligned.from,
14727
+ aligned.to,
14728
+ durationMs,
14729
+ fps
14730
+ );
14731
+ transitionFrames[0] = aligned.from;
14732
+ transitionFrames[transitionFrames.length - 1] = aligned.to;
14733
+ return transitionFrames;
14734
+ } catch (error) {
14735
+ logger.error("[AvatarView] Failed to generate transition from idle:", error instanceof Error ? error.message : String(error));
14736
+ throw error;
14737
+ }
14738
+ }
14710
14739
  async rerenderCurrentFrameWithNewCamera() {
14711
14740
  if (this.avatarController.state !== AvatarState.paused || this.renderingState !== "speaking" || !this.renderSystem) {
14712
14741
  return;
@@ -14755,7 +14784,7 @@ export {
14755
14784
  LogLevel$1 as L,
14756
14785
  ResourceType as R,
14757
14786
  SPAvatarError as S,
14758
- logger as a,
14787
+ logEvent as a,
14759
14788
  Avatar as b,
14760
14789
  AvatarController as c,
14761
14790
  AvatarSDK as d,
@@ -14766,6 +14795,6 @@ export {
14766
14795
  ConversationState as i,
14767
14796
  AvatarState as j,
14768
14797
  ErrorCode as k,
14769
- logEvent as l,
14798
+ logger as l,
14770
14799
  extractResourceUrls as m
14771
14800
  };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { b, c, f, d, j, g, C, i, D, E, k, h, L, R, S, m } from "./index-cfYSlUmQ.js";
1
+ import { b, c, f, d, j, g, C, i, D, E, k, h, L, R, S, m } from "./index-B0MJ_hCJ.js";
2
2
  export {
3
3
  b as Avatar,
4
4
  c as AvatarController,
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "@spatialwalk/avatarkit",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.57",
5
- "packageManager": "pnpm@10.18.2",
4
+ "version": "1.0.0-beta.59",
6
5
  "description": "SPAvatar SDK - 3D Gaussian Splatting Avatar Rendering SDK",
7
6
  "author": "SPAvatar Team",
8
7
  "license": "MIT",
@@ -32,16 +31,6 @@
32
31
  "CHANGELOG.md",
33
32
  "dist"
34
33
  ],
35
- "scripts": {
36
- "build": "SDK_BUILD=true vite build --mode library",
37
- "dev": "vite build --mode library --watch",
38
- "clean": "rm -rf dist",
39
- "typecheck": "tsc --noEmit",
40
- "test": "cd tests && pnpm test",
41
- "test:watch": "cd tests && pnpm run test:watch",
42
- "test:e2e": "cd tests && pnpm run test:e2e",
43
- "test:perf": "cd tests && pnpm run test:perf"
44
- },
45
34
  "peerDependencies": {
46
35
  "@webgpu/types": "*"
47
36
  },
@@ -58,5 +47,15 @@
58
47
  "typescript": "^5.0.0",
59
48
  "vite": "^5.0.0",
60
49
  "vite-plugin-dts": "^4.5.4"
50
+ },
51
+ "scripts": {
52
+ "build": "SDK_BUILD=true vite build --mode library",
53
+ "dev": "vite build --mode library --watch",
54
+ "clean": "rm -rf dist",
55
+ "typecheck": "tsc --noEmit",
56
+ "test": "cd tests && pnpm test",
57
+ "test:watch": "cd tests && pnpm run test:watch",
58
+ "test:e2e": "cd tests && pnpm run test:e2e",
59
+ "test:perf": "cd tests && pnpm run test:perf"
61
60
  }
62
- }
61
+ }
@@ -1,28 +0,0 @@
1
- import { AvatarView, Flame } from '@spatialwalk/avatarkit';
2
- declare function initializeSDK(): Promise<void>;
3
- declare function createAvatarView(characterId: string, container: HTMLElement): Promise<AvatarView>;
4
- declare function fetchFlameDataFromServer(characterId: string, audioData: ArrayBuffer): Promise<Flame[]>;
5
- declare class FlameRenderer {
6
- private avatarView;
7
- private keyframes;
8
- private currentFrameIndex;
9
- private animationFrameId;
10
- private isPlaying;
11
- private fps;
12
- private frameInterval;
13
- private lastRenderTime;
14
- constructor(avatarView: AvatarView);
15
- setKeyframes(keyframes: Flame[]): void;
16
- start(): void;
17
- stop(): void;
18
- renderFrame(frameIndex: number): Promise<void>;
19
- private renderLoop;
20
- setFPS(fps: number): void;
21
- seek(frameIndex: number): void;
22
- getCurrentFrameIndex(): number;
23
- getTotalFrames(): number;
24
- }
25
- declare function main(): Promise<void>;
26
- declare function fetchAudioData(): Promise<ArrayBuffer>;
27
-
28
- export { initializeSDK, createAvatarView, fetchFlameDataFromServer, FlameRenderer, main, fetchAudioData };