@spatialwalk/avatarkit 1.0.0-beta.54 → 1.0.0-beta.55

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,12 @@ 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.0.0-beta.55] - 2025-01-05
9
+
10
+ ### ✨ New Features
11
+ - **Eye Tracking Control** - Added `eyeTrackingEnabled` parameter to `PostProcessingConfig`, allowing external control of eye tracking enable/disable state in real-time
12
+ - **Point Count API** - Added `getPointCount()` method to `AvatarController` to get the point cloud count of the current character
13
+
8
14
  ## [1.0.0-beta.54] - 2025-01-05
9
15
 
10
16
  ### 🐛 Bugfix
@@ -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-PRpmBehE.js";
4
+ import { A as APP_CONFIG, e as errorToMessage, l as logEvent, a as logger } from "./index-WcnOBRys.js";
5
5
  class StreamingAudioPlayer {
6
6
  constructor(options) {
7
7
  __publicField(this, "audioContext", null);
@@ -24,6 +24,7 @@ export declare class AvatarController {
24
24
  private eventListeners;
25
25
  private renderCallback?;
26
26
  private characterHandle;
27
+ private characterId;
27
28
  private postProcessingConfig;
28
29
  private playbackLoopId;
29
30
  private lastRenderedFrameIndex;
@@ -57,7 +58,9 @@ export declare class AvatarController {
57
58
  private clearPlaybackData;
58
59
  private resetConversationIdState;
59
60
  private getEffectiveConversationId;
61
+ getPointCount(): number | null;
60
62
  setPostProcessingConfig(config: PostProcessingConfig | null): void;
63
+ private updateEyeTrackingEnabled;
61
64
  private rerenderCurrentFrame;
62
65
  setVolume(volume: number): void;
63
66
  getVolume(): number;
@@ -1338,7 +1338,6 @@ const POSTHOG_HOST_CN = "https://analytics.spatialwalk.top";
1338
1338
  const POSTHOG_API_KEY_CN = "phc_BwD9QedcHpUJ1j8XwALx2xPWQAswvELygU17J4XO5ZB";
1339
1339
  const POSTHOG_HOST_INTL = "https://i.spatialwalk.ai";
1340
1340
  const POSTHOG_API_KEY_INTL = "phc_IFTLa6Z6VhTaNvsxB7klvG2JeNwcSpnnwz8YvZRC96Q";
1341
- const POSTHOG_PROJECT_NAME = "sdk";
1342
1341
  function getPostHogConfig(environment) {
1343
1342
  if (environment === Environment.cn) {
1344
1343
  return {
@@ -7395,6 +7394,9 @@ const idManager = new IdManager();
7395
7394
  let sdkVersion = "1.0.0";
7396
7395
  let currentEnvironment = null;
7397
7396
  let isInitialized = false;
7397
+ const SDK_POSTHOG_INSTANCE_NAME = "spatialwalk-posthog";
7398
+ let sdkPosthogInstance = null;
7399
+ const eventQueue = [];
7398
7400
  const FILTERED_HOSTNAMES = ["localhost", "127.0.0.1", "0.0.0.0"];
7399
7401
  function shouldFilterHostname() {
7400
7402
  if (typeof window === "undefined") {
@@ -7423,7 +7425,7 @@ function initializePostHog(environment, version) {
7423
7425
  const logContext = idManager.getLogContext();
7424
7426
  Vo.init(apiKey, {
7425
7427
  api_host: host,
7426
- name: POSTHOG_PROJECT_NAME,
7428
+ name: SDK_POSTHOG_INSTANCE_NAME,
7427
7429
  person_profiles: "identified_only",
7428
7430
  capture_pageview: false,
7429
7431
  capture_pageleave: false,
@@ -7431,8 +7433,9 @@ function initializePostHog(environment, version) {
7431
7433
  disable_session_recording: true,
7432
7434
  autocapture: false,
7433
7435
  loaded: (posthogInstance) => {
7434
- logger.log(`[PostHog] Initialized successfully - environment: ${environment}, host: ${host}, project: ${POSTHOG_PROJECT_NAME}`);
7436
+ logger.log(`[PostHog] Initialized successfully - environment: ${environment}, host: ${host}, instance: ${SDK_POSTHOG_INSTANCE_NAME}`);
7435
7437
  isInitialized = true;
7438
+ sdkPosthogInstance = posthogInstance;
7436
7439
  if (logContext.user_id) {
7437
7440
  posthogInstance.identify(logContext.user_id, {
7438
7441
  app_id: logContext.app_id,
@@ -7450,19 +7453,67 @@ function initializePostHog(environment, version) {
7450
7453
  environment
7451
7454
  });
7452
7455
  }
7456
+ flushEventQueue();
7453
7457
  }
7454
7458
  });
7455
7459
  } catch (error) {
7456
7460
  logger.warn("[PostHog] Failed to initialize:", error instanceof Error ? error.message : String(error));
7457
7461
  }
7458
7462
  }
7463
+ function getSdkPosthogInstance() {
7464
+ var _a;
7465
+ if (sdkPosthogInstance) {
7466
+ return sdkPosthogInstance;
7467
+ }
7468
+ try {
7469
+ sdkPosthogInstance = (_a = Vo.getInstance) == null ? void 0 : _a.call(Vo, SDK_POSTHOG_INSTANCE_NAME);
7470
+ return sdkPosthogInstance;
7471
+ } catch (error) {
7472
+ return null;
7473
+ }
7474
+ }
7475
+ function flushEventQueue() {
7476
+ if (!sdkPosthogInstance || eventQueue.length === 0) {
7477
+ return;
7478
+ }
7479
+ logger.log(`[PostHog] Flushing ${eventQueue.length} queued events`);
7480
+ setTimeout(() => {
7481
+ for (const { event, level, contents } of eventQueue) {
7482
+ try {
7483
+ const logContext = idManager.getLogContext();
7484
+ const properties = {
7485
+ service_module: "sdk",
7486
+ platform: "Web",
7487
+ sdk_version: sdkVersion,
7488
+ level,
7489
+ environment: currentEnvironment || "unknown",
7490
+ app_id: logContext.app_id,
7491
+ user_id: logContext.user_id,
7492
+ client_id: logContext.client_id,
7493
+ timestamp: Date.now(),
7494
+ ...contents
7495
+ };
7496
+ if (logContext.connection_id) {
7497
+ properties.connection_id = logContext.connection_id;
7498
+ }
7499
+ sdkPosthogInstance.capture(event, properties);
7500
+ } catch (error) {
7501
+ logger.warn(`[PostHog] Failed to flush queued event ${event}:`, error instanceof Error ? error.message : String(error));
7502
+ }
7503
+ }
7504
+ eventQueue.length = 0;
7505
+ }, 0);
7506
+ }
7459
7507
  function trackEvent(event, level = "info", contents = {}) {
7460
7508
  if (shouldFilterHostname()) {
7461
7509
  return;
7462
7510
  }
7463
- if (typeof Vo === "undefined") {
7511
+ const instance = getSdkPosthogInstance();
7512
+ if (!instance) {
7513
+ eventQueue.push({ event, level, contents });
7464
7514
  return;
7465
7515
  }
7516
+ sdkPosthogInstance = instance;
7466
7517
  try {
7467
7518
  const logContext = idManager.getLogContext();
7468
7519
  const properties = {
@@ -7480,25 +7531,34 @@ function trackEvent(event, level = "info", contents = {}) {
7480
7531
  if (logContext.connection_id) {
7481
7532
  properties.connection_id = logContext.connection_id;
7482
7533
  }
7483
- Vo.capture(event, properties);
7534
+ sdkPosthogInstance.capture(event, properties);
7484
7535
  } catch (error) {
7485
7536
  logger.warn("[PostHog] Failed to track event:", error instanceof Error ? error.message : String(error));
7486
7537
  }
7487
7538
  }
7488
7539
  function cleanupPostHog() {
7489
- if (!isInitialized || typeof Vo === "undefined") {
7540
+ if (!isInitialized) {
7490
7541
  return;
7491
7542
  }
7492
7543
  try {
7493
- if (typeof Vo.shutdown === "function") {
7494
- Vo.shutdown();
7495
- } else if (typeof Vo.flush === "function") {
7496
- Vo.flush();
7544
+ const instance = getSdkPosthogInstance();
7545
+ if (!instance) {
7546
+ isInitialized = false;
7547
+ return;
7548
+ }
7549
+ sdkPosthogInstance = instance;
7550
+ if (typeof instance.shutdown === "function") {
7551
+ instance.shutdown();
7552
+ } else if (typeof instance.flush === "function") {
7553
+ instance.flush();
7497
7554
  }
7498
7555
  isInitialized = false;
7556
+ sdkPosthogInstance = null;
7499
7557
  logger.log("[PostHog] Cleaned up");
7500
7558
  } catch (error) {
7501
7559
  logger.warn("[PostHog] Failed to cleanup:", error instanceof Error ? error.message : String(error));
7560
+ isInitialized = false;
7561
+ sdkPosthogInstance = null;
7502
7562
  }
7503
7563
  }
7504
7564
  function logEvent(event, level = "info", contents = {}) {
@@ -7579,7 +7639,7 @@ const _AnimationPlayer = class _AnimationPlayer {
7579
7639
  if (this.streamingPlayer) {
7580
7640
  return;
7581
7641
  }
7582
- const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-Vmeiag0s.js");
7642
+ const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-C6hiS_B5.js");
7583
7643
  const { AvatarSDK: AvatarSDK2 } = await Promise.resolve().then(() => AvatarSDK$1);
7584
7644
  const audioFormat = AvatarSDK2.getAudioFormat();
7585
7645
  this.streamingPlayer = new StreamingAudioPlayer({
@@ -7743,10 +7803,7 @@ async function fetchSdkConfig(version) {
7743
7803
  const configUrl = `https://config.spatialwalk.top/sdk?version=${version}`;
7744
7804
  logger.log(`[SdkConfigLoader] Fetching SDK config from: ${configUrl}`);
7745
7805
  const response = await fetch(configUrl, {
7746
- method: "GET",
7747
- headers: {
7748
- "Content-Type": "application/json"
7749
- }
7806
+ method: "GET"
7750
7807
  });
7751
7808
  if (!response.ok) {
7752
7809
  throw new Error(`HTTP ${response.status} ${response.statusText}`);
@@ -8495,16 +8552,21 @@ class AvatarCoreAdapter {
8495
8552
  throw new Error(`Failed to get animation frame ${frameIndex}: ${errorMessage}`);
8496
8553
  }
8497
8554
  }
8498
- async setEyeTrackingConfig(config) {
8555
+ async setEyeTrackingConfig(config, characterId) {
8499
8556
  if (!this.isCharacterLoaded) {
8500
8557
  throw new Error("Character not loaded");
8501
8558
  }
8502
8559
  try {
8560
+ const id = characterId || "default";
8561
+ const characterHandle = this.characterHandles.get(id) || this.characterHandle;
8562
+ if (!characterHandle) {
8563
+ throw new Error(`Character not found: ${characterId || "default"}`);
8564
+ }
8503
8565
  const configPtr = this.wasmModule._malloc(12);
8504
8566
  this.wasmModule.setValue(configPtr, config.enabled ? 1 : 0, "i32");
8505
8567
  this.wasmModule.setValue(configPtr + 4, config.auto_eyelid_adjustment !== false ? 1 : 0, "i32");
8506
8568
  this.wasmModule.setValue(configPtr + 8, config.eyelid_threshold || 0.2, "float");
8507
- const result2 = this.api.setEyeTrackingConfig(this.coreHandle, this.characterHandle, configPtr);
8569
+ const result2 = this.api.setEyeTrackingConfig(this.coreHandle, characterHandle, configPtr);
8508
8570
  this.wasmModule._free(configPtr);
8509
8571
  this.checkError(result2, "avatar_core_set_eye_tracking_config");
8510
8572
  return true;
@@ -8514,12 +8576,17 @@ class AvatarCoreAdapter {
8514
8576
  throw new Error(`Failed to set eye tracking config: ${errorMessage}`);
8515
8577
  }
8516
8578
  }
8517
- async setGazeTarget(x2, y2, z2) {
8579
+ async setGazeTarget(x2, y2, z2, characterId) {
8518
8580
  if (!this.isCharacterLoaded) {
8519
8581
  throw new Error("Character not loaded");
8520
8582
  }
8521
8583
  try {
8522
- const result2 = this.api.setGazeTarget(this.coreHandle, this.characterHandle, x2, y2, z2);
8584
+ const id = characterId || "default";
8585
+ const characterHandle = this.characterHandles.get(id) || this.characterHandle;
8586
+ if (!characterHandle) {
8587
+ throw new Error(`Character not found: ${characterId || "default"}`);
8588
+ }
8589
+ const result2 = this.api.setGazeTarget(this.coreHandle, characterHandle, x2, y2, z2);
8523
8590
  this.checkError(result2, "avatar_core_set_gaze_target");
8524
8591
  return true;
8525
8592
  } catch (error) {
@@ -8608,6 +8675,32 @@ class AvatarCoreAdapter {
8608
8675
  version: ((_b = (_a = this.api).getVersion) == null ? void 0 : _b.call(_a)) || "unknown"
8609
8676
  };
8610
8677
  }
8678
+ getPointCount(characterHandle) {
8679
+ if (!this.isCharacterLoaded) {
8680
+ return null;
8681
+ }
8682
+ const handle = characterHandle || this.characterHandle;
8683
+ if (!handle) {
8684
+ return null;
8685
+ }
8686
+ try {
8687
+ const pointCountPtr = this.wasmModule._malloc(4);
8688
+ const hasAnimationPtr = this.wasmModule._malloc(1);
8689
+ const result2 = this.api.getCharacterInfo(
8690
+ handle,
8691
+ pointCountPtr,
8692
+ hasAnimationPtr
8693
+ );
8694
+ this.checkError(result2, "avatar_core_get_character_info");
8695
+ const pointCount = this.wasmModule.getValue(pointCountPtr, "i32");
8696
+ this.wasmModule._free(pointCountPtr);
8697
+ this.wasmModule._free(hasAnimationPtr);
8698
+ return pointCount;
8699
+ } catch (error) {
8700
+ logger.warn("[AvatarCoreAdapter] Failed to get point count:", error instanceof Error ? error.message : String(error));
8701
+ return null;
8702
+ }
8703
+ }
8611
8704
  removeCharacter(characterHandle, characterId) {
8612
8705
  try {
8613
8706
  if (!this.coreHandle) {
@@ -8969,7 +9062,7 @@ class AvatarSDK {
8969
9062
  }
8970
9063
  __publicField(AvatarSDK, "_isInitialized", false);
8971
9064
  __publicField(AvatarSDK, "_configuration", null);
8972
- __publicField(AvatarSDK, "_version", "1.0.0-beta.54");
9065
+ __publicField(AvatarSDK, "_version", "1.0.0-beta.55");
8973
9066
  __publicField(AvatarSDK, "_avatarCore", null);
8974
9067
  __publicField(AvatarSDK, "_dynamicSdkConfig", null);
8975
9068
  const AvatarSDK$1 = Object.freeze(Object.defineProperty({
@@ -10630,6 +10723,7 @@ class AvatarController {
10630
10723
  __publicField(this, "eventListeners", /* @__PURE__ */ new Map());
10631
10724
  __publicField(this, "renderCallback");
10632
10725
  __publicField(this, "characterHandle", null);
10726
+ __publicField(this, "characterId", null);
10633
10727
  __publicField(this, "postProcessingConfig", null);
10634
10728
  __publicField(this, "playbackLoopId", null);
10635
10729
  __publicField(this, "lastRenderedFrameIndex", -1);
@@ -11106,12 +11200,45 @@ class AvatarController {
11106
11200
  this.characterHandle = characterHandle;
11107
11201
  }
11108
11202
  }
11203
+ setCharacterId(characterId) {
11204
+ this.characterId = characterId;
11205
+ }
11206
+ getPointCount() {
11207
+ const avatarCore = AvatarSDK.getAvatarCore();
11208
+ if (!avatarCore || !this.characterHandle) {
11209
+ return null;
11210
+ }
11211
+ return avatarCore.getPointCount(this.characterHandle);
11212
+ }
11109
11213
  setPostProcessingConfig(config) {
11110
11214
  this.postProcessingConfig = config;
11215
+ if ((config == null ? void 0 : config.eyeTrackingEnabled) !== void 0) {
11216
+ this.updateEyeTrackingEnabled(config.eyeTrackingEnabled).catch((error) => {
11217
+ logger.warn("[AvatarController] Failed to update eye tracking enabled state:", error instanceof Error ? error.message : String(error));
11218
+ });
11219
+ }
11111
11220
  if (this.currentState === AvatarState.paused && this.isPlaying) {
11112
11221
  this.rerenderCurrentFrame();
11113
11222
  }
11114
11223
  }
11224
+ async updateEyeTrackingEnabled(enabled) {
11225
+ var _a;
11226
+ const avatarCore = AvatarSDK.getAvatarCore();
11227
+ if (!avatarCore || !this.characterId) {
11228
+ return;
11229
+ }
11230
+ try {
11231
+ const characterMeta = this.avatar.getCharacterMeta();
11232
+ const eyefocus = (_a = characterMeta.characterSettings) == null ? void 0 : _a.eyefocus;
11233
+ await avatarCore.setEyeTrackingConfig({
11234
+ enabled,
11235
+ auto_eyelid_adjustment: (eyefocus == null ? void 0 : eyefocus.auto_eyelid_adjustment) ?? true,
11236
+ eyelid_threshold: (eyefocus == null ? void 0 : eyefocus.eyelid_threshold) ?? 0.2
11237
+ }, this.characterId);
11238
+ } catch (error) {
11239
+ logger.warn("[AvatarController] Failed to update eye tracking enabled state:", error instanceof Error ? error.message : String(error));
11240
+ }
11241
+ }
11115
11242
  async rerenderCurrentFrameIfPaused() {
11116
11243
  if (this.currentState !== AvatarState.paused || !this.renderCallback) {
11117
11244
  return;
@@ -11808,9 +11935,16 @@ function getCacheInfo(url, response) {
11808
11935
  const cfCacheStatus = response.headers.get("cf-cache-status");
11809
11936
  const xCache = response.headers.get("x-cache");
11810
11937
  const xSwiftCacheTime = response.headers.get("x-swift-cache-time");
11811
- const age = response.headers.get("age");
11812
11938
  const cdnCacheStatus = cfCacheStatus || xCache || xSwiftCacheTime;
11813
- const isCdnCache = cdnCacheStatus && (cdnCacheStatus.toLowerCase() === "hit" || cdnCacheStatus.toLowerCase() === "hits" || cdnCacheStatus.toLowerCase().includes("hit")) || age && parseInt(age, 10) > 0;
11939
+ let isCdnCache = false;
11940
+ if (cdnCacheStatus) {
11941
+ const statusLower = cdnCacheStatus.toLowerCase();
11942
+ if (statusLower === "hit" || statusLower === "hits" || statusLower.includes("hit")) {
11943
+ if (!statusLower.includes("miss") && !statusLower.includes("dynamic") && !statusLower.includes("bypass")) {
11944
+ isCdnCache = true;
11945
+ }
11946
+ }
11947
+ }
11814
11948
  let cacheHit = false;
11815
11949
  let cacheType = "none";
11816
11950
  if (isPwaCache) {
@@ -13972,6 +14106,7 @@ class AvatarView {
13972
14106
  return this.canvas;
13973
14107
  }
13974
14108
  async initializeView(avatar) {
14109
+ var _a;
13975
14110
  try {
13976
14111
  if (APP_CONFIG.debug)
13977
14112
  logger.log("[AvatarView] Initializing avatar view...");
@@ -13992,12 +14127,35 @@ class AvatarView {
13992
14127
  logger.log("[AvatarView] Loading idle animation...");
13993
14128
  await avatarCore.loadAnimationFromBuffer(resources.characterData.idleAnimation, this.characterId);
13994
14129
  }
14130
+ const eyefocus = (_a = resources.characterSettings) == null ? void 0 : _a.eyefocus;
14131
+ if (eyefocus) {
14132
+ if (APP_CONFIG.debug)
14133
+ logger.log("[AvatarView] Configuring eye tracking...");
14134
+ try {
14135
+ await avatarCore.setEyeTrackingConfig({
14136
+ enabled: eyefocus.enabled,
14137
+ auto_eyelid_adjustment: eyefocus.auto_eyelid_adjustment,
14138
+ eyelid_threshold: eyefocus.eyelid_threshold
14139
+ }, this.characterId);
14140
+ if (eyefocus.enabled && eyefocus.targets && eyefocus.targets.length >= 3) {
14141
+ await avatarCore.setGazeTarget(
14142
+ eyefocus.targets[0],
14143
+ eyefocus.targets[1],
14144
+ eyefocus.targets[2],
14145
+ this.characterId
14146
+ );
14147
+ }
14148
+ } catch (error) {
14149
+ logger.warn("[AvatarView] Failed to configure eye tracking:", error instanceof Error ? error.message : String(error));
14150
+ }
14151
+ }
13995
14152
  this.avatarController.setRenderCallback(
13996
14153
  (splatData, frameIndex) => {
13997
14154
  this.renderRealtimeFrame(splatData, frameIndex);
13998
14155
  },
13999
14156
  this.characterHandle
14000
14157
  );
14158
+ this.avatarController.setCharacterId(this.characterId);
14001
14159
  if (APP_CONFIG.debug)
14002
14160
  logger.log("[AvatarView] Initializing render system...");
14003
14161
  const cameraConfig = this.resolveCameraConfig(resources);
@@ -14257,6 +14415,11 @@ class AvatarView {
14257
14415
  return;
14258
14416
  }
14259
14417
  }
14418
+ if (state === "transitioningToSpeaking" && this.transitionStartTime > 0 && this.transitionKeyframes.length > 0 && elapsed >= this.transitionDurationMs + 100) {
14419
+ this.setState("speaking");
14420
+ this.transitionKeyframes = [];
14421
+ this.avatarController.onTransitionComplete();
14422
+ }
14260
14423
  this.realtimeAnimationLoopId = requestAnimationFrame(renderFrame);
14261
14424
  return;
14262
14425
  }
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-PRpmBehE.js";
1
+ import { b, c, f, d, j, g, C, i, D, E, k, h, L, R, S, m } from "./index-WcnOBRys.js";
2
2
  export {
3
3
  b as Avatar,
4
4
  c as AvatarController,
@@ -14,5 +14,6 @@ export interface CameraSettings {
14
14
  }
15
15
  export interface CharacterSettings {
16
16
  eyelid: EyelidSettings;
17
+ eyefocus?: EyelidSettings;
17
18
  camera: CameraSettings;
18
19
  }
@@ -131,5 +131,6 @@ export interface PostProcessingConfig {
131
131
  };
132
132
  eyeBlink?: number;
133
133
  expressionWeight?: number;
134
+ eyeTrackingEnabled?: boolean;
134
135
  }
135
136
  export * from './character';
@@ -76,8 +76,8 @@ export declare class AvatarCoreAdapter {
76
76
  enabled: boolean;
77
77
  auto_eyelid_adjustment?: boolean;
78
78
  eyelid_threshold?: number;
79
- }): Promise<boolean>;
80
- setGazeTarget(x: number, y: number, z: number): Promise<boolean>;
79
+ }, characterId?: string): Promise<boolean>;
80
+ setGazeTarget(x: number, y: number, z: number, characterId?: string): Promise<boolean>;
81
81
  resetEyeTracking(): Promise<boolean>;
82
82
  private queryFlameInfo;
83
83
  private queryCharacterInfo;
@@ -88,6 +88,7 @@ export declare class AvatarCoreAdapter {
88
88
  characterInfo?: CharacterInfo;
89
89
  version?: string;
90
90
  };
91
+ getPointCount(characterHandle?: number): number | null;
91
92
  removeCharacter(characterHandle: number, characterId?: string): void;
92
93
  releaseCurrentCharacter(): void;
93
94
  release(): void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spatialwalk/avatarkit",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.54",
4
+ "version": "1.0.0-beta.55",
5
5
  "packageManager": "pnpm@10.18.2",
6
6
  "description": "SPAvatar SDK - 3D Gaussian Splatting Avatar Rendering SDK",
7
7
  "author": "SPAvatar Team",