@spatialwalk/avatarkit 1.0.0-beta.90 → 1.0.0-beta.92
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 +12 -0
- package/dist/{StreamingAudioPlayer-GS4x7i1m.js → StreamingAudioPlayer-eQ2RRq5U.js} +1 -1
- package/dist/avatar_core_wasm-9834c91c.wasm +0 -0
- package/dist/core/AvatarController.d.ts +2 -1
- package/dist/{index-jdCd5L22.js → index-C2higMlc.js} +69 -37
- package/dist/index.js +1 -1
- package/package.json +18 -16
- package/dist/assets/cpu-benchmark-worker-C6iFEUSO.js +0 -36
- package/dist/demo/src/main.d.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ 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.92]
|
|
9
|
+
|
|
10
|
+
### ✨ Features
|
|
11
|
+
|
|
12
|
+
- **Host Mode Animation End Signal** — `yieldFramesData()` now returns a `boolean` indicating whether the server has sent all animation data for the current conversation (`end` flag from protobuf). Non-breaking: callers that ignore the return value are unaffected.
|
|
13
|
+
|
|
14
|
+
## [1.0.0-beta.91] - 2026-03-19
|
|
15
|
+
|
|
16
|
+
### 🐛 Bugfixes
|
|
17
|
+
|
|
18
|
+
- **Inline CPU Benchmark Worker** — Consumers using Vite could not build: `Could not resolve entry module "public/assets/cpu-benchmark-worker-*.js"`. Root cause: `new URL()` worker pattern in Vite library mode compiles to absolute path that downstream bundlers cannot resolve. Fixed by replacing with inline Blob URL worker.
|
|
19
|
+
|
|
8
20
|
## [1.0.0-beta.90] - 2026-03-18
|
|
9
21
|
|
|
10
22
|
### 🐛 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, l as logger, e as errorToMessage, a as logEvent } from "./index-
|
|
4
|
+
import { A as APP_CONFIG, l as logger, e as errorToMessage, a as logEvent } from "./index-C2higMlc.js";
|
|
5
5
|
class StreamingAudioPlayer {
|
|
6
6
|
// Mark if AudioContext is being resumed, avoid concurrent resume requests
|
|
7
7
|
constructor(options) {
|
|
File without changes
|
|
@@ -91,8 +91,9 @@ export declare class AvatarController {
|
|
|
91
91
|
* @param keyframesDataArray - Animation keyframes binary data array (each element is a protobuf encoded Message) or empty array to trigger audio-only mode
|
|
92
92
|
* @param conversationId - Conversation ID (required). If conversationId doesn't match current conversationId, keyframes will be discarded.
|
|
93
93
|
* Use getCurrentConversationId() to get the current conversationId.
|
|
94
|
+
* @returns `true` if the server has sent all animation data for this conversation (end signal received), `false` otherwise.
|
|
94
95
|
*/
|
|
95
|
-
yieldFramesData(keyframesDataArray: (Uint8Array | ArrayBuffer)[], conversationId: string):
|
|
96
|
+
yieldFramesData(keyframesDataArray: (Uint8Array | ArrayBuffer)[], conversationId: string): boolean;
|
|
96
97
|
/**
|
|
97
98
|
* Send animation keyframes (host mode)
|
|
98
99
|
* Stream animation keyframes data after yieldAudioData()
|
|
@@ -9495,7 +9495,7 @@ const _AnimationPlayer = class _AnimationPlayer {
|
|
|
9495
9495
|
if (this.streamingPlayer) {
|
|
9496
9496
|
return;
|
|
9497
9497
|
}
|
|
9498
|
-
const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-
|
|
9498
|
+
const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-eQ2RRq5U.js");
|
|
9499
9499
|
const { AvatarSDK: AvatarSDK2 } = await Promise.resolve().then(() => AvatarSDK$1);
|
|
9500
9500
|
const audioFormat = AvatarSDK2.getAudioFormat();
|
|
9501
9501
|
this.streamingPlayer = new StreamingAudioPlayer({
|
|
@@ -11054,24 +11054,44 @@ async function gpuBenchmark() {
|
|
|
11054
11054
|
return 0;
|
|
11055
11055
|
}
|
|
11056
11056
|
}
|
|
11057
|
+
const workerCode = `
|
|
11058
|
+
const N = 128;
|
|
11059
|
+
const A = new Float32Array(N * N);
|
|
11060
|
+
const B = new Float32Array(N * N);
|
|
11061
|
+
const C = new Float32Array(N * N);
|
|
11062
|
+
for (let i = 0; i < A.length; i++) { A[i] = (i % 100) / 100; B[i] = ((i * 7) % 100) / 100; }
|
|
11063
|
+
function bench() {
|
|
11064
|
+
for (let i = 0; i < N; i++)
|
|
11065
|
+
for (let j = 0; j < N; j++) {
|
|
11066
|
+
let s = 0;
|
|
11067
|
+
for (let k = 0; k < N; k++) s += A[i * N + k] * B[k * N + j];
|
|
11068
|
+
C[i * N + j] = s;
|
|
11069
|
+
}
|
|
11070
|
+
}
|
|
11071
|
+
self.onmessage = () => {
|
|
11072
|
+
const w = performance.now() + 1000;
|
|
11073
|
+
while (performance.now() < w) bench();
|
|
11074
|
+
let it = 0;
|
|
11075
|
+
const m = performance.now() + 1000;
|
|
11076
|
+
while (performance.now() < m) { bench(); it++; }
|
|
11077
|
+
self.postMessage({ cpuScore: it });
|
|
11078
|
+
};
|
|
11079
|
+
`;
|
|
11057
11080
|
function cpuBenchmark() {
|
|
11058
11081
|
return new Promise((resolve2) => {
|
|
11059
11082
|
try {
|
|
11060
|
-
const
|
|
11061
|
-
|
|
11062
|
-
|
|
11063
|
-
"/assets/cpu-benchmark-worker-C6iFEUSO.js",
|
|
11064
|
-
import.meta.url
|
|
11065
|
-
),
|
|
11066
|
-
{ type: "module" }
|
|
11067
|
-
);
|
|
11083
|
+
const blob = new Blob([workerCode], { type: "application/javascript" });
|
|
11084
|
+
const url = URL.createObjectURL(blob);
|
|
11085
|
+
const worker = new Worker(url, { type: "classic" });
|
|
11068
11086
|
worker.onmessage = (e2) => {
|
|
11069
11087
|
resolve2(e2.data.cpuScore);
|
|
11070
11088
|
worker.terminate();
|
|
11089
|
+
URL.revokeObjectURL(url);
|
|
11071
11090
|
};
|
|
11072
11091
|
worker.onerror = () => {
|
|
11073
11092
|
resolve2(0);
|
|
11074
11093
|
worker.terminate();
|
|
11094
|
+
URL.revokeObjectURL(url);
|
|
11075
11095
|
};
|
|
11076
11096
|
worker.postMessage("start");
|
|
11077
11097
|
} catch {
|
|
@@ -11453,7 +11473,7 @@ class AvatarSDK {
|
|
|
11453
11473
|
__publicField(AvatarSDK, "_initializationState", "uninitialized");
|
|
11454
11474
|
__publicField(AvatarSDK, "_initializingPromise", null);
|
|
11455
11475
|
__publicField(AvatarSDK, "_configuration", null);
|
|
11456
|
-
__publicField(AvatarSDK, "_version", "1.0.0-beta.
|
|
11476
|
+
__publicField(AvatarSDK, "_version", "1.0.0-beta.92");
|
|
11457
11477
|
__publicField(AvatarSDK, "_avatarCore", null);
|
|
11458
11478
|
__publicField(AvatarSDK, "_dynamicSdkConfig", null);
|
|
11459
11479
|
__publicField(AvatarSDK, "_cachedDeviceScore", null);
|
|
@@ -11884,6 +11904,8 @@ class NetworkLayer {
|
|
|
11884
11904
|
__publicField(this, "audioMetrics", this.createAudioMetrics());
|
|
11885
11905
|
__publicField(this, "isFallbackMode", false);
|
|
11886
11906
|
// 连接超时降级模式标记
|
|
11907
|
+
/** @internal 降级原因,供 AvatarController 读取 */
|
|
11908
|
+
__publicField(this, "_fallbackReason", "");
|
|
11887
11909
|
__publicField(this, "isConnecting", false);
|
|
11888
11910
|
// 避免并发连接
|
|
11889
11911
|
// 驱动服务心跳检测相关
|
|
@@ -11923,6 +11945,7 @@ class NetworkLayer {
|
|
|
11923
11945
|
}
|
|
11924
11946
|
(_b = (_a = this.dataController).onConnectionState) == null ? void 0 : _b.call(_a, ConnectionState.connecting);
|
|
11925
11947
|
this.isFallbackMode = false;
|
|
11948
|
+
this._fallbackReason = "";
|
|
11926
11949
|
this.setupWebSocketListeners();
|
|
11927
11950
|
this.isConnecting = true;
|
|
11928
11951
|
const CONNECTION_TIMEOUT_MS = 15e3;
|
|
@@ -11933,6 +11956,7 @@ class NetworkLayer {
|
|
|
11933
11956
|
var _a2, _b2;
|
|
11934
11957
|
if (!this.dataController.connected) {
|
|
11935
11958
|
this.isFallbackMode = true;
|
|
11959
|
+
this._fallbackReason = "connection_timeout";
|
|
11936
11960
|
logger.warn(`[NetworkLayer] WebSocket connection timeout (${CONNECTION_TIMEOUT_MS}ms) - entering fallback mode`);
|
|
11937
11961
|
(_b2 = (_a2 = this.dataController).onConnectionState) == null ? void 0 : _b2.call(_a2, ConnectionState.failed);
|
|
11938
11962
|
}
|
|
@@ -11950,6 +11974,7 @@ class NetworkLayer {
|
|
|
11950
11974
|
}
|
|
11951
11975
|
if (!this.isFallbackMode) {
|
|
11952
11976
|
this.isFallbackMode = true;
|
|
11977
|
+
this._fallbackReason = "connection_failed";
|
|
11953
11978
|
logger.warn("[NetworkLayer] WebSocket connection failed - entering fallback mode");
|
|
11954
11979
|
}
|
|
11955
11980
|
(_d = (_c = this.dataController).onConnectionState) == null ? void 0 : _d.call(_c, ConnectionState.failed);
|
|
@@ -12014,6 +12039,7 @@ class NetworkLayer {
|
|
|
12014
12039
|
*/
|
|
12015
12040
|
disconnect() {
|
|
12016
12041
|
this.isFallbackMode = false;
|
|
12042
|
+
this._fallbackReason = "";
|
|
12017
12043
|
this.isConnecting = false;
|
|
12018
12044
|
this.wsClient.removeAllListeners();
|
|
12019
12045
|
this.wsClient.disconnect();
|
|
@@ -12049,6 +12075,7 @@ class NetworkLayer {
|
|
|
12049
12075
|
}
|
|
12050
12076
|
if (!this.dataController.connected) {
|
|
12051
12077
|
this.isFallbackMode = false;
|
|
12078
|
+
this._fallbackReason = "";
|
|
12052
12079
|
this.dataController.setConnected(true);
|
|
12053
12080
|
(_b = (_a = this.dataController).onConnectionState) == null ? void 0 : _b.call(_a, ConnectionState.connected);
|
|
12054
12081
|
}
|
|
@@ -12645,7 +12672,7 @@ class AvatarController {
|
|
|
12645
12672
|
case AvatarState.idle:
|
|
12646
12673
|
if (this.shouldReportPlaybackStats) {
|
|
12647
12674
|
const stats = this.frameRateMonitor.getPlaybackStats();
|
|
12648
|
-
if (stats.durationMs >= 2e3) {
|
|
12675
|
+
if (stats.durationMs >= 2e3 && stats.frameCount > 0 && Math.random() < 0.3) {
|
|
12649
12676
|
const props = {
|
|
12650
12677
|
avg_fps: Number(stats.avgFps.toFixed(1)),
|
|
12651
12678
|
frame_count: stats.frameCount,
|
|
@@ -12768,7 +12795,7 @@ class AvatarController {
|
|
|
12768
12795
|
* @returns conversationId - Conversation ID for this audio session
|
|
12769
12796
|
*/
|
|
12770
12797
|
send(audioData, end = false) {
|
|
12771
|
-
var _a, _b
|
|
12798
|
+
var _a, _b;
|
|
12772
12799
|
try {
|
|
12773
12800
|
this.checkAudioContextInitialized();
|
|
12774
12801
|
} catch (error) {
|
|
@@ -12779,14 +12806,6 @@ class AvatarController {
|
|
|
12779
12806
|
(_b = this.onError) == null ? void 0 : _b.call(this, new AvatarError("Network layer not available", "NETWORK_LAYER_NOT_AVAILABLE"));
|
|
12780
12807
|
return null;
|
|
12781
12808
|
}
|
|
12782
|
-
if (!this.networkLayer.canSend()) {
|
|
12783
|
-
(_c = this.onError) == null ? void 0 : _c.call(this, new AvatarError("Service not connected", "NOT_CONNECTED"));
|
|
12784
|
-
logEvent("character_manager", "warning", {
|
|
12785
|
-
avatar_id: this.avatar.id,
|
|
12786
|
-
event: "send_not_connected"
|
|
12787
|
-
});
|
|
12788
|
-
return null;
|
|
12789
|
-
}
|
|
12790
12809
|
const networkConversationId = this.networkLayer.getCurrentConversationId();
|
|
12791
12810
|
if (this.reqEnd && this.isPlaying && networkConversationId) {
|
|
12792
12811
|
this.interrupt();
|
|
@@ -12845,12 +12864,7 @@ class AvatarController {
|
|
|
12845
12864
|
this.emit("keyframesUpdate", this.currentKeyframes);
|
|
12846
12865
|
} else {
|
|
12847
12866
|
logger.warn("[AvatarController] Empty animation data in playback - enabling fallback mode");
|
|
12848
|
-
|
|
12849
|
-
avatar_id: this.avatar.id,
|
|
12850
|
-
event: "empty_animation_data_audio_only_fallback",
|
|
12851
|
-
conversationId: this.currentConversationId
|
|
12852
|
-
});
|
|
12853
|
-
this.isFallbackMode = true;
|
|
12867
|
+
this.enableFallbackMode("empty_animation");
|
|
12854
12868
|
}
|
|
12855
12869
|
if (this.pendingAudioChunks.length === 0) {
|
|
12856
12870
|
throw new AvatarError("No audio chunks to play", "NO_AUDIO");
|
|
@@ -12923,14 +12937,16 @@ class AvatarController {
|
|
|
12923
12937
|
* @param keyframesDataArray - Animation keyframes binary data array (each element is a protobuf encoded Message) or empty array to trigger audio-only mode
|
|
12924
12938
|
* @param conversationId - Conversation ID (required). If conversationId doesn't match current conversationId, keyframes will be discarded.
|
|
12925
12939
|
* Use getCurrentConversationId() to get the current conversationId.
|
|
12940
|
+
* @returns `true` if the server has sent all animation data for this conversation (end signal received), `false` otherwise.
|
|
12926
12941
|
*/
|
|
12927
12942
|
yieldFramesData(keyframesDataArray, conversationId) {
|
|
12928
|
-
var _a, _b;
|
|
12943
|
+
var _a, _b, _c;
|
|
12929
12944
|
if (!keyframesDataArray || keyframesDataArray.length === 0) {
|
|
12930
12945
|
this.yieldKeyframes([], conversationId);
|
|
12931
|
-
return;
|
|
12946
|
+
return false;
|
|
12932
12947
|
}
|
|
12933
12948
|
let allKeyframes = [];
|
|
12949
|
+
let isEnd = false;
|
|
12934
12950
|
for (let i2 = 0; i2 < keyframesDataArray.length; i2++) {
|
|
12935
12951
|
const item = keyframesDataArray[i2];
|
|
12936
12952
|
const binaryData = item instanceof ArrayBuffer ? new Uint8Array(item) : item;
|
|
@@ -12946,6 +12962,9 @@ class AvatarController {
|
|
|
12946
12962
|
} else {
|
|
12947
12963
|
logger.warn(`[AvatarController] Message chunk ${i2 + 1} does not contain animation keyframes`);
|
|
12948
12964
|
}
|
|
12965
|
+
if ((_c = message.serverResponseAnimation) == null ? void 0 : _c.end) {
|
|
12966
|
+
isEnd = true;
|
|
12967
|
+
}
|
|
12949
12968
|
} catch (error) {
|
|
12950
12969
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
12951
12970
|
logger.error(`[AvatarController] Failed to decode animation data chunk ${i2 + 1}: ${errorMessage}`);
|
|
@@ -12963,6 +12982,7 @@ class AvatarController {
|
|
|
12963
12982
|
logger.warn(`[AvatarController] No keyframes decoded from ${keyframesDataArray.length} message chunks`);
|
|
12964
12983
|
}
|
|
12965
12984
|
this.yieldKeyframes(allKeyframes, conversationId);
|
|
12985
|
+
return isEnd;
|
|
12966
12986
|
}
|
|
12967
12987
|
/**
|
|
12968
12988
|
* Send animation keyframes (host mode)
|
|
@@ -12977,6 +12997,7 @@ class AvatarController {
|
|
|
12977
12997
|
* Use getCurrentConversationId() to get the current conversationId.
|
|
12978
12998
|
*/
|
|
12979
12999
|
yieldKeyframes(keyframes, conversationId) {
|
|
13000
|
+
var _a;
|
|
12980
13001
|
if (!conversationId || typeof conversationId !== "string") {
|
|
12981
13002
|
logger.error(`[AvatarController] yieldKeyframes requires a valid conversationId. Use getCurrentConversationId() to get the current conversationId.`);
|
|
12982
13003
|
logEvent("character_manager", "error", {
|
|
@@ -13008,12 +13029,8 @@ class AvatarController {
|
|
|
13008
13029
|
}
|
|
13009
13030
|
if (!keyframes || keyframes.length === 0) {
|
|
13010
13031
|
logger.warn("[AvatarController] Empty animation data received - enabling fallback mode");
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
event: "empty_animation_data_audio_only_fallback",
|
|
13014
|
-
conversationId
|
|
13015
|
-
});
|
|
13016
|
-
this.enableFallbackMode();
|
|
13032
|
+
const reason = ((_a = this.networkLayer) == null ? void 0 : _a._fallbackReason) || "empty_animation";
|
|
13033
|
+
this.enableFallbackMode(reason);
|
|
13017
13034
|
return;
|
|
13018
13035
|
}
|
|
13019
13036
|
const flameKeyframes = keyframes;
|
|
@@ -13029,10 +13046,10 @@ class AvatarController {
|
|
|
13029
13046
|
this.emit("keyframesUpdate", this.currentKeyframes);
|
|
13030
13047
|
if (!this.isPlaying && !this.isStartingPlayback && this.pendingAudioChunks.length > 0 && this.currentKeyframes.length > 0) {
|
|
13031
13048
|
this.startStreamingPlayback().catch((error) => {
|
|
13032
|
-
var
|
|
13049
|
+
var _a2;
|
|
13033
13050
|
this.isStartingPlayback = false;
|
|
13034
13051
|
logger.error("[AvatarController] Failed to auto-start playback:", error);
|
|
13035
|
-
(
|
|
13052
|
+
(_a2 = this.onError) == null ? void 0 : _a2.call(this, new AvatarError("Failed to start playback", "PLAYBACK_START_FAILED"));
|
|
13036
13053
|
});
|
|
13037
13054
|
}
|
|
13038
13055
|
}
|
|
@@ -13684,12 +13701,18 @@ class AvatarController {
|
|
|
13684
13701
|
* Once enabled, subsequent animation data in this session will be ignored
|
|
13685
13702
|
* @internal
|
|
13686
13703
|
*/
|
|
13687
|
-
enableFallbackMode() {
|
|
13704
|
+
enableFallbackMode(reason = "empty_animation") {
|
|
13688
13705
|
if (this.isFallbackMode) {
|
|
13689
13706
|
return;
|
|
13690
13707
|
}
|
|
13691
13708
|
logger.warn("[AvatarController] Enabling fallback mode");
|
|
13692
13709
|
this.isFallbackMode = true;
|
|
13710
|
+
logEvent("fallback_mode_entered", "warning", {
|
|
13711
|
+
avatar_id: this.avatar.id,
|
|
13712
|
+
reason,
|
|
13713
|
+
con_id: idManager.getConnectionId() || "",
|
|
13714
|
+
req_id: this.currentConversationId || ""
|
|
13715
|
+
});
|
|
13693
13716
|
if (this.isPlaying) {
|
|
13694
13717
|
this.stopPlaybackLoop();
|
|
13695
13718
|
this.emit("stopRendering");
|
|
@@ -14459,6 +14482,9 @@ class AvatarDownloader {
|
|
|
14459
14482
|
return { key, success: true, size: arrayBuffer.byteLength };
|
|
14460
14483
|
} catch (error) {
|
|
14461
14484
|
if (error instanceof Error && (error.name === "AbortError" || error.message === "Download cancelled")) {
|
|
14485
|
+
logEvent("download_avatar_assets_cancelled", "info", {
|
|
14486
|
+
avatar_id: characterMeta.characterId ?? "unknown"
|
|
14487
|
+
});
|
|
14462
14488
|
throw error;
|
|
14463
14489
|
}
|
|
14464
14490
|
if (!optional) {
|
|
@@ -14639,6 +14665,12 @@ class AvatarDownloader {
|
|
|
14639
14665
|
});
|
|
14640
14666
|
return response;
|
|
14641
14667
|
} catch (error) {
|
|
14668
|
+
if (error instanceof Error && (error.name === "AbortError" || error.message === "Request cancelled")) {
|
|
14669
|
+
logEvent("fetch_avatar_metadata_cancelled", "info", {
|
|
14670
|
+
avatar_id: characterId ?? "unknown"
|
|
14671
|
+
});
|
|
14672
|
+
throw error;
|
|
14673
|
+
}
|
|
14642
14674
|
logger.errorWithError("Failed to fetch character:", error);
|
|
14643
14675
|
if (error instanceof AvatarError) {
|
|
14644
14676
|
logEvent("fetch_avatar_metadata_failed", "error", {
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spatialwalk/avatarkit",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.92",
|
|
5
|
+
"packageManager": "pnpm@10.18.2",
|
|
5
6
|
"description": "AvatarKit SDK - 3D Gaussian Splatting Avatar Rendering SDK",
|
|
6
7
|
"author": "AvatarKit Team",
|
|
7
8
|
"license": "MIT",
|
|
@@ -43,6 +44,21 @@
|
|
|
43
44
|
"next.js",
|
|
44
45
|
"next.d.ts"
|
|
45
46
|
],
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "SDK_BUILD=true vite build --mode library && npm run build:vite-plugin && npm run build:next-plugin",
|
|
49
|
+
"build:vite-plugin": "tsc vite.ts --outDir . --module esnext --target es2020 --moduleResolution bundler --esModuleInterop --skipLibCheck --declaration --declarationMap",
|
|
50
|
+
"build:next-plugin": "tsc next.ts --outDir . --module esnext --target es2020 --moduleResolution bundler --esModuleInterop --skipLibCheck --declaration --declarationMap",
|
|
51
|
+
"dev": "vite build --mode library --watch",
|
|
52
|
+
"demo": "vite --config demo/vite.config.mjs",
|
|
53
|
+
"demo:benchmark": "vite --config benchmark-demo/vite.config.mjs",
|
|
54
|
+
"test:integration": "vite --config tests/integration-runner/vite.config.mjs",
|
|
55
|
+
"clean": "rm -rf dist",
|
|
56
|
+
"typecheck": "tsc --noEmit",
|
|
57
|
+
"test": "cd tests && pnpm test",
|
|
58
|
+
"test:watch": "cd tests && pnpm run test:watch",
|
|
59
|
+
"test:e2e": "cd tests && pnpm run test:e2e",
|
|
60
|
+
"test:perf": "cd tests && pnpm run test:perf"
|
|
61
|
+
},
|
|
46
62
|
"peerDependencies": {
|
|
47
63
|
"@webgpu/types": "*",
|
|
48
64
|
"vite": "^5.0.0",
|
|
@@ -69,19 +85,5 @@
|
|
|
69
85
|
"typescript": "^5.0.0",
|
|
70
86
|
"vite": "^5.0.0",
|
|
71
87
|
"vite-plugin-dts": "^4.5.4"
|
|
72
|
-
},
|
|
73
|
-
"scripts": {
|
|
74
|
-
"build": "SDK_BUILD=true vite build --mode library && npm run build:vite-plugin && npm run build:next-plugin",
|
|
75
|
-
"build:vite-plugin": "tsc vite.ts --outDir . --module esnext --target es2020 --moduleResolution bundler --esModuleInterop --skipLibCheck --declaration --declarationMap",
|
|
76
|
-
"build:next-plugin": "tsc next.ts --outDir . --module esnext --target es2020 --moduleResolution bundler --esModuleInterop --skipLibCheck --declaration --declarationMap",
|
|
77
|
-
"dev": "vite build --mode library --watch",
|
|
78
|
-
"demo": "vite --config demo/vite.config.mjs",
|
|
79
|
-
"demo:benchmark": "vite --config benchmark-demo/vite.config.mjs",
|
|
80
|
-
"clean": "rm -rf dist",
|
|
81
|
-
"typecheck": "tsc --noEmit",
|
|
82
|
-
"test": "cd tests && pnpm test",
|
|
83
|
-
"test:watch": "cd tests && pnpm run test:watch",
|
|
84
|
-
"test:e2e": "cd tests && pnpm run test:e2e",
|
|
85
|
-
"test:perf": "cd tests && pnpm run test:perf"
|
|
86
88
|
}
|
|
87
|
-
}
|
|
89
|
+
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
(function() {
|
|
2
|
-
"use strict";
|
|
3
|
-
const MATRIX_SIZE = 128;
|
|
4
|
-
const A = new Float32Array(MATRIX_SIZE * MATRIX_SIZE);
|
|
5
|
-
const B = new Float32Array(MATRIX_SIZE * MATRIX_SIZE);
|
|
6
|
-
const C = new Float32Array(MATRIX_SIZE * MATRIX_SIZE);
|
|
7
|
-
for (let i = 0; i < A.length; i++) {
|
|
8
|
-
A[i] = i % 100 / 100;
|
|
9
|
-
B[i] = i * 7 % 100 / 100;
|
|
10
|
-
}
|
|
11
|
-
function benchmarkMatrixMultiply() {
|
|
12
|
-
const N = MATRIX_SIZE;
|
|
13
|
-
for (let i = 0; i < N; i++) {
|
|
14
|
-
for (let j = 0; j < N; j++) {
|
|
15
|
-
let sum = 0;
|
|
16
|
-
for (let k = 0; k < N; k++) {
|
|
17
|
-
sum += A[i * N + k] * B[k * N + j];
|
|
18
|
-
}
|
|
19
|
-
C[i * N + j] = sum;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
self.onmessage = () => {
|
|
24
|
-
const warmupEnd = performance.now() + 1e3;
|
|
25
|
-
while (performance.now() < warmupEnd) {
|
|
26
|
-
benchmarkMatrixMultiply();
|
|
27
|
-
}
|
|
28
|
-
let iterations = 0;
|
|
29
|
-
const measureEnd = performance.now() + 1e3;
|
|
30
|
-
while (performance.now() < measureEnd) {
|
|
31
|
-
benchmarkMatrixMultiply();
|
|
32
|
-
iterations++;
|
|
33
|
-
}
|
|
34
|
-
self.postMessage({ cpuScore: iterations });
|
|
35
|
-
};
|
|
36
|
-
})();
|
package/dist/demo/src/main.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|