sa2kit 1.6.35 → 1.6.37
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/dist/{chunk-SR4JFEHW.mjs → chunk-FIXZXZJ7.mjs} +113 -14
- package/dist/chunk-FIXZXZJ7.mjs.map +1 -0
- package/dist/{chunk-PMTY2AI4.js → chunk-WZFJ3S3E.js} +113 -14
- package/dist/chunk-WZFJ3S3E.js.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -16
- package/dist/index.mjs +1 -1
- package/dist/mikuFireworks3D/index.d.mts +27 -3
- package/dist/mikuFireworks3D/index.d.ts +27 -3
- package/dist/mikuFireworks3D/index.js +16 -16
- package/dist/mikuFireworks3D/index.mjs +1 -1
- package/dist/mikuFireworks3D/server/index.d.mts +1 -1
- package/dist/mikuFireworks3D/server/index.d.ts +1 -1
- package/dist/{types-Cgk9zWhO.d.mts → types-DBVDr8Mu.d.mts} +1 -0
- package/dist/{types-Cgk9zWhO.d.ts → types-DBVDr8Mu.d.ts} +1 -0
- package/package.json +1 -1
- package/dist/chunk-PMTY2AI4.js.map +0 -1
- package/dist/chunk-SR4JFEHW.mjs.map +0 -1
|
@@ -636,6 +636,7 @@ function useFireworksEngine(options) {
|
|
|
636
636
|
const containerRef = useRef(null);
|
|
637
637
|
const canvasRef = useRef(null);
|
|
638
638
|
const engineRef = useRef(null);
|
|
639
|
+
const pendingLaunchesRef = useRef([]);
|
|
639
640
|
const [fps, setFps] = useState(60);
|
|
640
641
|
const { maxParticles, maxActiveFireworks, onError, onFpsReport, onLaunch } = options || {};
|
|
641
642
|
useEffect(() => {
|
|
@@ -657,14 +658,29 @@ function useFireworksEngine(options) {
|
|
|
657
658
|
});
|
|
658
659
|
engine.start();
|
|
659
660
|
engineRef.current = engine;
|
|
661
|
+
if (pendingLaunchesRef.current.length > 0) {
|
|
662
|
+
const pending = [...pendingLaunchesRef.current];
|
|
663
|
+
pendingLaunchesRef.current = [];
|
|
664
|
+
pending.forEach((payload) => {
|
|
665
|
+
void engine.launch(payload);
|
|
666
|
+
});
|
|
667
|
+
}
|
|
660
668
|
return () => {
|
|
661
669
|
engineRef.current?.dispose();
|
|
662
670
|
engineRef.current = null;
|
|
671
|
+
pendingLaunchesRef.current = [];
|
|
663
672
|
};
|
|
664
673
|
}, [maxParticles, maxActiveFireworks, onError, onFpsReport]);
|
|
665
674
|
const launch = useCallback(
|
|
666
675
|
(payload) => {
|
|
667
|
-
|
|
676
|
+
if (!engineRef.current) {
|
|
677
|
+
pendingLaunchesRef.current.push(payload);
|
|
678
|
+
if (pendingLaunchesRef.current.length > 120) {
|
|
679
|
+
pendingLaunchesRef.current.splice(0, pendingLaunchesRef.current.length - 120);
|
|
680
|
+
}
|
|
681
|
+
} else {
|
|
682
|
+
void engineRef.current.launch(payload);
|
|
683
|
+
}
|
|
668
684
|
onLaunch?.(payload);
|
|
669
685
|
},
|
|
670
686
|
[onLaunch]
|
|
@@ -687,10 +703,12 @@ var WebSocketTransport = class {
|
|
|
687
703
|
this.socket = null;
|
|
688
704
|
this.reconnectTimer = null;
|
|
689
705
|
this.isManualClose = false;
|
|
706
|
+
this.pendingQueue = [];
|
|
690
707
|
this.config = config;
|
|
691
708
|
this.callbacks = callbacks || {};
|
|
692
709
|
this.state = {
|
|
693
710
|
connected: false,
|
|
711
|
+
joined: false,
|
|
694
712
|
onlineCount: 0,
|
|
695
713
|
roomId: config.roomId
|
|
696
714
|
};
|
|
@@ -707,7 +725,7 @@ var WebSocketTransport = class {
|
|
|
707
725
|
return;
|
|
708
726
|
}
|
|
709
727
|
this.socket.onopen = () => {
|
|
710
|
-
this.updateState({ connected: true });
|
|
728
|
+
this.updateState({ connected: true, joined: false });
|
|
711
729
|
this.send({
|
|
712
730
|
type: "join",
|
|
713
731
|
roomId: this.config.roomId,
|
|
@@ -725,12 +743,13 @@ var WebSocketTransport = class {
|
|
|
725
743
|
this.callbacks.onError?.(new Error("WebSocket transport error."));
|
|
726
744
|
};
|
|
727
745
|
this.socket.onclose = () => {
|
|
728
|
-
this.updateState({ connected: false });
|
|
746
|
+
this.updateState({ connected: false, joined: false });
|
|
729
747
|
this.scheduleReconnect();
|
|
730
748
|
};
|
|
731
749
|
}
|
|
732
750
|
disconnect() {
|
|
733
751
|
this.isManualClose = true;
|
|
752
|
+
this.pendingQueue.length = 0;
|
|
734
753
|
if (this.reconnectTimer != null) {
|
|
735
754
|
window.clearTimeout(this.reconnectTimer);
|
|
736
755
|
this.reconnectTimer = null;
|
|
@@ -759,6 +778,13 @@ var WebSocketTransport = class {
|
|
|
759
778
|
}
|
|
760
779
|
send(message) {
|
|
761
780
|
if (!this.socket || this.socket.readyState !== window.WebSocket.OPEN) {
|
|
781
|
+
if (message.type === "danmaku.send" || message.type === "firework.launch") {
|
|
782
|
+
this.pendingQueue.push(message);
|
|
783
|
+
}
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
if ((message.type === "danmaku.send" || message.type === "firework.launch") && !this.state.joined) {
|
|
787
|
+
this.pendingQueue.push(message);
|
|
762
788
|
return;
|
|
763
789
|
}
|
|
764
790
|
this.socket.send(JSON.stringify(message));
|
|
@@ -772,7 +798,8 @@ var WebSocketTransport = class {
|
|
|
772
798
|
}
|
|
773
799
|
handleServerMessage(message) {
|
|
774
800
|
if (message.type === "joined") {
|
|
775
|
-
this.updateState({ roomId: message.roomId, onlineCount: message.onlineCount });
|
|
801
|
+
this.updateState({ roomId: message.roomId, onlineCount: message.onlineCount, joined: true });
|
|
802
|
+
this.flushPendingQueue();
|
|
776
803
|
return;
|
|
777
804
|
}
|
|
778
805
|
if (message.type === "room.user_joined" || message.type === "room.user_left") {
|
|
@@ -810,6 +837,18 @@ var WebSocketTransport = class {
|
|
|
810
837
|
this.connect();
|
|
811
838
|
}, delay);
|
|
812
839
|
}
|
|
840
|
+
flushPendingQueue() {
|
|
841
|
+
if (!this.socket || this.socket.readyState !== window.WebSocket.OPEN || !this.state.joined) {
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
while (this.pendingQueue.length > 0) {
|
|
845
|
+
const message = this.pendingQueue.shift();
|
|
846
|
+
if (!message) {
|
|
847
|
+
break;
|
|
848
|
+
}
|
|
849
|
+
this.socket.send(JSON.stringify(message));
|
|
850
|
+
}
|
|
851
|
+
}
|
|
813
852
|
};
|
|
814
853
|
function parseServerMessage(raw) {
|
|
815
854
|
if (typeof raw !== "string") {
|
|
@@ -824,11 +863,12 @@ function parseServerMessage(raw) {
|
|
|
824
863
|
|
|
825
864
|
// src/mikuFireworks3D/hooks/useFireworksRealtime.ts
|
|
826
865
|
function useFireworksRealtime(options) {
|
|
827
|
-
const { config, enabled, onDanmakuBroadcast, onFireworkBroadcast, onError, onStateChange } = options;
|
|
866
|
+
const { config, enabled, onDanmakuBroadcast, onFireworkBroadcast, onSnapshot, onError, onStateChange } = options;
|
|
828
867
|
const transportRef = useRef(null);
|
|
829
868
|
const callbackRef = useRef({
|
|
830
869
|
onDanmakuBroadcast,
|
|
831
870
|
onFireworkBroadcast,
|
|
871
|
+
onSnapshot,
|
|
832
872
|
onError,
|
|
833
873
|
onStateChange
|
|
834
874
|
});
|
|
@@ -841,6 +881,7 @@ function useFireworksRealtime(options) {
|
|
|
841
881
|
const reconnectIntervalMs = config?.reconnectIntervalMs ?? 1500;
|
|
842
882
|
const [state, setState] = useState({
|
|
843
883
|
connected: false,
|
|
884
|
+
joined: false,
|
|
844
885
|
onlineCount: 0,
|
|
845
886
|
roomId
|
|
846
887
|
});
|
|
@@ -848,10 +889,11 @@ function useFireworksRealtime(options) {
|
|
|
848
889
|
callbackRef.current = {
|
|
849
890
|
onDanmakuBroadcast,
|
|
850
891
|
onFireworkBroadcast,
|
|
892
|
+
onSnapshot,
|
|
851
893
|
onError,
|
|
852
894
|
onStateChange
|
|
853
895
|
};
|
|
854
|
-
}, [onDanmakuBroadcast, onError, onFireworkBroadcast, onStateChange]);
|
|
896
|
+
}, [onDanmakuBroadcast, onError, onFireworkBroadcast, onSnapshot, onStateChange]);
|
|
855
897
|
const normalizedConfig = useMemo(() => {
|
|
856
898
|
if (!serverUrl || !roomId || !userId) {
|
|
857
899
|
return void 0;
|
|
@@ -876,6 +918,7 @@ function useFireworksRealtime(options) {
|
|
|
876
918
|
transportRef.current = null;
|
|
877
919
|
setState({
|
|
878
920
|
connected: false,
|
|
921
|
+
joined: false,
|
|
879
922
|
onlineCount: 0,
|
|
880
923
|
roomId: normalizedConfig?.roomId
|
|
881
924
|
});
|
|
@@ -897,7 +940,31 @@ function useFireworksRealtime(options) {
|
|
|
897
940
|
});
|
|
898
941
|
},
|
|
899
942
|
onFireworkBroadcast: (event) => {
|
|
900
|
-
callbackRef.current.onFireworkBroadcast?.(
|
|
943
|
+
callbackRef.current.onFireworkBroadcast?.({
|
|
944
|
+
id: event.id,
|
|
945
|
+
payload: event.payload,
|
|
946
|
+
userId: event.user.userId,
|
|
947
|
+
timestamp: event.timestamp
|
|
948
|
+
});
|
|
949
|
+
},
|
|
950
|
+
onSnapshot: (snapshot) => {
|
|
951
|
+
callbackRef.current.onSnapshot?.({
|
|
952
|
+
roomId: snapshot.roomId,
|
|
953
|
+
danmakuHistory: snapshot.danmakuHistory.map((item) => ({
|
|
954
|
+
id: item.id,
|
|
955
|
+
text: item.text,
|
|
956
|
+
color: item.color,
|
|
957
|
+
kind: item.kind,
|
|
958
|
+
userId: item.user.userId,
|
|
959
|
+
timestamp: item.timestamp
|
|
960
|
+
})),
|
|
961
|
+
fireworkHistory: snapshot.fireworkHistory.map((item) => ({
|
|
962
|
+
id: item.id,
|
|
963
|
+
payload: item.payload,
|
|
964
|
+
userId: item.user.userId,
|
|
965
|
+
timestamp: item.timestamp
|
|
966
|
+
}))
|
|
967
|
+
});
|
|
901
968
|
},
|
|
902
969
|
onError: (error) => {
|
|
903
970
|
callbackRef.current.onError?.(error);
|
|
@@ -946,6 +1013,8 @@ function MikuFireworks3D({
|
|
|
946
1013
|
const [selectedKind, setSelectedKind] = useState(defaultKind);
|
|
947
1014
|
const [avatarUrl, setAvatarUrl] = useState(defaultAvatarUrl);
|
|
948
1015
|
const [autoLaunch, setAutoLaunch] = useState(autoLaunchOnDanmaku);
|
|
1016
|
+
const seenDanmakuIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
1017
|
+
const seenFireworkIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
949
1018
|
const { containerRef, canvasRef, launch, fps } = useFireworksEngine({
|
|
950
1019
|
maxParticles,
|
|
951
1020
|
maxActiveFireworks,
|
|
@@ -963,6 +1032,10 @@ function MikuFireworks3D({
|
|
|
963
1032
|
onStateChange: onRealtimeStateChange,
|
|
964
1033
|
onError,
|
|
965
1034
|
onDanmakuBroadcast: (event) => {
|
|
1035
|
+
if (seenDanmakuIdsRef.current.has(event.id)) {
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
seenDanmakuIdsRef.current.add(event.id);
|
|
966
1039
|
addIncoming({
|
|
967
1040
|
id: event.id,
|
|
968
1041
|
userId: event.userId,
|
|
@@ -971,8 +1044,34 @@ function MikuFireworks3D({
|
|
|
971
1044
|
timestamp: event.timestamp
|
|
972
1045
|
});
|
|
973
1046
|
},
|
|
974
|
-
onFireworkBroadcast: (
|
|
975
|
-
|
|
1047
|
+
onFireworkBroadcast: (event) => {
|
|
1048
|
+
if (seenFireworkIdsRef.current.has(event.id)) {
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
seenFireworkIdsRef.current.add(event.id);
|
|
1052
|
+
launch(event.payload);
|
|
1053
|
+
},
|
|
1054
|
+
onSnapshot: (snapshot) => {
|
|
1055
|
+
for (const danmaku of snapshot.danmakuHistory) {
|
|
1056
|
+
if (seenDanmakuIdsRef.current.has(danmaku.id)) {
|
|
1057
|
+
continue;
|
|
1058
|
+
}
|
|
1059
|
+
seenDanmakuIdsRef.current.add(danmaku.id);
|
|
1060
|
+
addIncoming({
|
|
1061
|
+
id: danmaku.id,
|
|
1062
|
+
userId: danmaku.userId,
|
|
1063
|
+
text: danmaku.text,
|
|
1064
|
+
color: danmaku.color,
|
|
1065
|
+
timestamp: danmaku.timestamp
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
for (const firework of snapshot.fireworkHistory) {
|
|
1069
|
+
if (seenFireworkIdsRef.current.has(firework.id)) {
|
|
1070
|
+
continue;
|
|
1071
|
+
}
|
|
1072
|
+
seenFireworkIdsRef.current.add(firework.id);
|
|
1073
|
+
launch(firework.payload);
|
|
1074
|
+
}
|
|
976
1075
|
}
|
|
977
1076
|
});
|
|
978
1077
|
const handleLaunch = (kind) => {
|
|
@@ -980,7 +1079,7 @@ function MikuFireworks3D({
|
|
|
980
1079
|
kind,
|
|
981
1080
|
avatarUrl: kind === "avatar" ? avatarUrl || void 0 : void 0
|
|
982
1081
|
};
|
|
983
|
-
if (realtimeEnabled && realtimeApi.state.connected) {
|
|
1082
|
+
if (realtimeEnabled && realtimeApi.state.connected && realtimeApi.state.joined) {
|
|
984
1083
|
realtimeApi.sendFirework(payload);
|
|
985
1084
|
return;
|
|
986
1085
|
}
|
|
@@ -988,13 +1087,13 @@ function MikuFireworks3D({
|
|
|
988
1087
|
};
|
|
989
1088
|
const handleSendDanmaku = (text) => {
|
|
990
1089
|
const result = send(text, void 0, {
|
|
991
|
-
optimistic: !(realtimeEnabled && realtimeApi.state.connected)
|
|
1090
|
+
optimistic: !(realtimeEnabled && realtimeApi.state.connected && realtimeApi.state.joined)
|
|
992
1091
|
});
|
|
993
1092
|
if (!result) {
|
|
994
1093
|
return;
|
|
995
1094
|
}
|
|
996
1095
|
const launchKind = result.launchKind ?? selectedKind;
|
|
997
|
-
if (realtimeEnabled && realtimeApi.state.connected) {
|
|
1096
|
+
if (realtimeEnabled && realtimeApi.state.connected && realtimeApi.state.joined) {
|
|
998
1097
|
realtimeApi.sendDanmaku({
|
|
999
1098
|
text: result.message.text,
|
|
1000
1099
|
color: result.message.color,
|
|
@@ -1067,5 +1166,5 @@ function MikuFireworks3D({
|
|
|
1067
1166
|
}
|
|
1068
1167
|
|
|
1069
1168
|
export { DANMAKU_MAX_LENGTH, DANMAKU_TRACK_COUNT, DEFAULT_MAX_ACTIVE_FIREWORKS, DEFAULT_MAX_PARTICLES, DanmakuPanel, FIREWORK_KIND_LABELS, FireworksCanvas, FireworksControlPanel, MIKU_PALETTE, MikuFireworks3D, NORMAL_PALETTE, WebSocketTransport, useDanmakuController, useFireworksEngine, useFireworksRealtime };
|
|
1070
|
-
//# sourceMappingURL=chunk-
|
|
1071
|
-
//# sourceMappingURL=chunk-
|
|
1169
|
+
//# sourceMappingURL=chunk-FIXZXZJ7.mjs.map
|
|
1170
|
+
//# sourceMappingURL=chunk-FIXZXZJ7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mikuFireworks3D/components/DanmakuPanel.tsx","../src/mikuFireworks3D/components/FireworksCanvas.tsx","../src/mikuFireworks3D/constants.ts","../src/mikuFireworks3D/components/FireworksControlPanel.tsx","../src/mikuFireworks3D/hooks/useDanmakuController.ts","../src/mikuFireworks3D/utils/textureFactory.ts","../src/mikuFireworks3D/utils/colorPalettes.ts","../src/mikuFireworks3D/utils/avatarSprite.ts","../src/mikuFireworks3D/engine/patterns/avatar.ts","../src/mikuFireworks3D/engine/patterns/miku.ts","../src/mikuFireworks3D/engine/patterns/normal.ts","../src/mikuFireworks3D/engine/emitters.ts","../src/mikuFireworks3D/engine/particlePool.ts","../src/mikuFireworks3D/engine/postfx.ts","../src/mikuFireworks3D/engine/FireworksEngine.ts","../src/mikuFireworks3D/hooks/useFireworksEngine.ts","../src/mikuFireworks3D/client/WebSocketTransport.ts","../src/mikuFireworks3D/hooks/useFireworksRealtime.ts","../src/mikuFireworks3D/components/MikuFireworks3D.tsx"],"names":["React","useState","THREE","useRef","useCallback","useMemo","useEffect"],"mappings":"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","file":"chunk-FIXZXZJ7.mjs","sourcesContent":["'use client';\n\nimport React, { useState } from 'react';\n\ninterface DanmakuPanelProps {\n onSend: (text: string) => void;\n}\n\nexport function DanmakuPanel({ onSend }: DanmakuPanelProps) {\n const [text, setText] = useState('');\n\n const emit = () => {\n const value = text.trim();\n if (!value) {\n return;\n }\n onSend(value);\n setText('');\n };\n\n return (\n <div className=\"rounded-xl border border-slate-600/40 bg-slate-900/70 p-3 text-slate-100 backdrop-blur-sm\">\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={text}\n onChange={(event) => setText(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n emit();\n }\n }}\n placeholder=\"发送弹幕(支持 /miku /avatar /normal)\"\n className=\"flex-1 rounded-md border border-slate-600 bg-slate-950 px-2.5 py-2 text-sm text-slate-100 outline-none focus:border-cyan-400\"\n />\n <button\n type=\"button\"\n onClick={emit}\n className=\"rounded-md bg-cyan-400 px-3 py-2 text-sm font-medium text-slate-950 hover:bg-cyan-300\"\n >\n 发送\n </button>\n </div>\n </div>\n );\n}\n","'use client';\n\nimport React from 'react';\n\ninterface FireworksCanvasProps {\n canvasRef: React.RefObject<HTMLCanvasElement>;\n}\n\nexport function FireworksCanvas({ canvasRef }: FireworksCanvasProps) {\n return (\n <canvas\n ref={canvasRef}\n className=\"absolute inset-0 h-full w-full\"\n style={{\n background:\n 'radial-gradient(circle at 20% 20%, rgba(57,197,187,0.15) 0%, rgba(6,8,22,1) 45%, rgba(4,6,15,1) 100%)',\n }}\n />\n );\n}\n","import type { FireworkKind } from './types';\n\nexport const DEFAULT_MAX_PARTICLES = 5000;\nexport const DEFAULT_MAX_ACTIVE_FIREWORKS = 12;\n\nexport const FIREWORK_KIND_LABELS: Record<FireworkKind, string> = {\n normal: '普通烟花',\n miku: 'MIKU 主题',\n avatar: '头像烟花',\n};\n\nexport const MIKU_PALETTE = ['#39c5bb', '#66e3db', '#7ad8ff', '#b0fff8', '#8cf7e0'];\nexport const NORMAL_PALETTE = ['#ffe066', '#ff6b6b', '#4dabf7', '#c77dff', '#69db7c'];\n\nexport const DANMAKU_MAX_LENGTH = 32;\nexport const DANMAKU_TRACK_COUNT = 8;\n","'use client';\n\nimport React from 'react';\nimport { FIREWORK_KIND_LABELS } from '../constants';\nimport type { FireworkKind } from '../types';\n\ninterface FireworksControlPanelProps {\n selectedKind: FireworkKind;\n onKindChange: (kind: FireworkKind) => void;\n autoLaunchOnDanmaku: boolean;\n onAutoLaunchChange: (value: boolean) => void;\n avatarUrl: string;\n onAvatarUrlChange: (value: string) => void;\n onLaunch: () => void;\n fps: number;\n realtimeConnected?: boolean;\n onlineCount?: number;\n}\n\nexport function FireworksControlPanel({\n selectedKind,\n onKindChange,\n autoLaunchOnDanmaku,\n onAutoLaunchChange,\n avatarUrl,\n onAvatarUrlChange,\n onLaunch,\n fps,\n realtimeConnected,\n onlineCount,\n}: FireworksControlPanelProps) {\n return (\n <div className=\"rounded-xl border border-slate-600/40 bg-slate-900/70 p-3 text-slate-100 backdrop-blur-sm\">\n <div className=\"mb-3 flex flex-wrap items-center gap-2\">\n {(Object.keys(FIREWORK_KIND_LABELS) as FireworkKind[]).map((kind) => {\n const active = kind === selectedKind;\n return (\n <button\n key={kind}\n type=\"button\"\n onClick={() => onKindChange(kind)}\n className={`rounded-md px-3 py-1.5 text-sm transition ${\n active ? 'bg-cyan-500 text-slate-950' : 'bg-slate-700/70 hover:bg-slate-600/80'\n }`}\n >\n {FIREWORK_KIND_LABELS[kind]}\n </button>\n );\n })}\n\n <button\n type=\"button\"\n onClick={onLaunch}\n className=\"ml-auto rounded-md bg-emerald-400 px-3 py-1.5 text-sm font-medium text-slate-900 hover:bg-emerald-300\"\n >\n 发射烟花\n </button>\n </div>\n\n <div className=\"grid gap-2 md:grid-cols-2\">\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={autoLaunchOnDanmaku}\n onChange={(event) => onAutoLaunchChange(event.target.checked)}\n />\n 发送弹幕后自动放烟花\n </label>\n\n <div className=\"text-sm text-slate-300\">FPS: {fps}</div>\n {typeof realtimeConnected === 'boolean' ? (\n <div className=\"text-sm text-slate-300\">\n 实时状态: {realtimeConnected ? '已连接' : '未连接'}\n {typeof onlineCount === 'number' ? ` · 在线 ${onlineCount}` : ''}\n </div>\n ) : null}\n </div>\n\n {selectedKind === 'avatar' ? (\n <div className=\"mt-2\">\n <input\n type=\"url\"\n value={avatarUrl}\n onChange={(event) => onAvatarUrlChange(event.target.value)}\n placeholder=\"头像图片 URL(用于头像烟花)\"\n className=\"w-full rounded-md border border-slate-600 bg-slate-950 px-2.5 py-2 text-sm text-slate-100 outline-none focus:border-cyan-400\"\n />\n </div>\n ) : null}\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport { DANMAKU_MAX_LENGTH, DANMAKU_TRACK_COUNT } from '../constants';\nimport type { DanmakuControllerOptions, DanmakuMessage, DanmakuSendResult, FireworkKind } from '../types';\n\nexport interface DanmakuOverlayItem extends DanmakuMessage {\n track: number;\n durationMs: number;\n}\n\ninterface SendDanmakuOptions {\n optimistic?: boolean;\n}\n\nexport function useDanmakuController(options?: DanmakuControllerOptions) {\n const [items, setItems] = useState<DanmakuOverlayItem[]>([]);\n const cursorRef = useRef(0);\n\n const removeItem = useCallback((id: string) => {\n setItems((prev) => prev.filter((item) => item.id !== id));\n }, []);\n\n const addIncoming = useCallback((message: DanmakuMessage) => {\n setItems((prev) => {\n const track = cursorRef.current % DANMAKU_TRACK_COUNT;\n const item: DanmakuOverlayItem = {\n ...message,\n track,\n durationMs: 8000 + Math.floor(Math.random() * 2800),\n };\n return [...prev.slice(-40), item];\n });\n cursorRef.current += 1;\n }, []);\n\n const send = useCallback(\n (text: string, color?: string, sendOptions?: SendDanmakuOptions): DanmakuSendResult | null => {\n const trimmed = text.trim();\n if (!trimmed) {\n return null;\n }\n\n const { content, launchKind } = parseCommand(trimmed);\n const safeText = content.slice(0, DANMAKU_MAX_LENGTH);\n if (!safeText) {\n return null;\n }\n\n const message: DanmakuMessage = {\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,\n text: safeText,\n color,\n timestamp: Date.now(),\n };\n\n const optimistic = sendOptions?.optimistic ?? true;\n if (optimistic) {\n addIncoming(message);\n }\n\n options?.onSend?.(message);\n\n return {\n message,\n launchKind,\n };\n },\n [addIncoming, options]\n );\n\n return useMemo(\n () => ({\n items,\n send,\n addIncoming,\n removeItem,\n }),\n [addIncoming, items, removeItem, send]\n );\n}\n\nfunction parseCommand(text: string): { content: string; launchKind?: FireworkKind } {\n if (text.startsWith('/miku ')) {\n return { launchKind: 'miku', content: text.replace('/miku ', '').trim() };\n }\n if (text === '/miku') {\n return { launchKind: 'miku', content: 'MIKU!' };\n }\n if (text.startsWith('/avatar ')) {\n return { launchKind: 'avatar', content: text.replace('/avatar ', '').trim() };\n }\n if (text === '/avatar') {\n return { launchKind: 'avatar', content: 'Avatar Firework!' };\n }\n if (text.startsWith('/normal ')) {\n return { launchKind: 'normal', content: text.replace('/normal ', '').trim() };\n }\n if (text === '/normal') {\n return { launchKind: 'normal', content: 'Fireworks!' };\n }\n return { content: text };\n}\n","import * as THREE from 'three';\n\nexport function createCircularSpriteTexture(): THREE.CanvasTexture {\n const size = 64;\n const canvas = document.createElement('canvas');\n canvas.width = size;\n canvas.height = size;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return new THREE.CanvasTexture(canvas);\n }\n\n const center = size / 2;\n const gradient = ctx.createRadialGradient(center, center, 2, center, center, center);\n gradient.addColorStop(0, 'rgba(255,255,255,1)');\n gradient.addColorStop(0.4, 'rgba(255,255,255,0.9)');\n gradient.addColorStop(1, 'rgba(255,255,255,0)');\n\n ctx.fillStyle = gradient;\n ctx.fillRect(0, 0, size, size);\n\n const texture = new THREE.CanvasTexture(canvas);\n texture.needsUpdate = true;\n return texture;\n}\n","import { MIKU_PALETTE, NORMAL_PALETTE } from '../constants';\nimport type { FireworkKind } from '../types';\n\nexport function pickPalette(kind: FireworkKind): string[] {\n if (kind === 'miku') {\n return MIKU_PALETTE;\n }\n return NORMAL_PALETTE;\n}\n\nexport function pickRandomColor(colors: string[]): string {\n if (colors.length === 0) {\n return '#ffffff';\n }\n const index = Math.floor(Math.random() * colors.length);\n return colors[index] || '#ffffff';\n}\n","export async function sampleAvatarPoints(\n avatarUrl: string,\n sampleStep = 4,\n maxPoints = 500\n): Promise<Array<{ x: number; y: number; brightness: number }>> {\n const image = await loadImage(avatarUrl);\n const size = 64;\n const canvas = document.createElement('canvas');\n canvas.width = size;\n canvas.height = size;\n\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return [];\n }\n\n ctx.clearRect(0, 0, size, size);\n ctx.drawImage(image, 0, 0, size, size);\n\n const { data } = ctx.getImageData(0, 0, size, size);\n const points: Array<{ x: number; y: number; brightness: number }> = [];\n\n for (let y = 0; y < size; y += sampleStep) {\n for (let x = 0; x < size; x += sampleStep) {\n const index = (y * size + x) * 4;\n const alpha = data[index + 3] ?? 0;\n if (alpha < 24) {\n continue;\n }\n const r = data[index] ?? 0;\n const g = data[index + 1] ?? 0;\n const b = data[index + 2] ?? 0;\n const brightness = (r + g + b) / (3 * 255);\n points.push({ x: x - size / 2, y: size / 2 - y, brightness });\n if (points.length >= maxPoints) {\n return points;\n }\n }\n }\n\n return points;\n}\n\nfunction loadImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const image = new window.Image();\n image.crossOrigin = 'anonymous';\n image.onload = () => resolve(image);\n image.onerror = () => reject(new Error('Failed to load avatar image.'));\n image.src = url;\n });\n}\n","import { sampleAvatarPoints } from '../../utils/avatarSprite';\nimport type { SeedParticle } from './normal';\n\nexport async function createAvatarSeeds(avatarUrl: string, fallbackColor: string): Promise<SeedParticle[]> {\n const points = await sampleAvatarPoints(avatarUrl);\n\n if (points.length === 0) {\n return [];\n }\n\n return points.map((point) => {\n const spread = 0.22;\n return {\n x: 0,\n y: 0,\n z: 0,\n vx: point.x * spread + (Math.random() - 0.5) * 2.4,\n vy: point.y * spread + Math.random() * 2.2,\n vz: (Math.random() - 0.5) * 3.5,\n life: 1.1 + point.brightness * 1.6,\n color: fallbackColor,\n };\n });\n}\n","import { MIKU_PALETTE } from '../../constants';\nimport { pickRandomColor } from '../../utils/colorPalettes';\nimport type { SeedParticle } from './normal';\n\nexport function createMikuSeeds(count: number): SeedParticle[] {\n const seeds: SeedParticle[] = [];\n\n for (let i = 0; i < count; i += 1) {\n const ratio = i / Math.max(count - 1, 1);\n const angle = ratio * Math.PI * 2 * 2;\n const radial = 7 + Math.random() * 9;\n\n const spiralBoost = 3 + Math.random() * 4;\n seeds.push({\n x: 0,\n y: 0,\n z: 0,\n vx: Math.cos(angle) * radial,\n vy: Math.sin(angle * 0.5) * spiralBoost + 7,\n vz: Math.sin(angle) * radial,\n life: 1.2 + Math.random() * 1.5,\n color: pickRandomColor(MIKU_PALETTE),\n });\n }\n\n return seeds;\n}\n","export interface SeedParticle {\n x: number;\n y: number;\n z: number;\n vx: number;\n vy: number;\n vz: number;\n life: number;\n color: string;\n}\n\nexport function createNormalSeeds(count: number, color: string): SeedParticle[] {\n const seeds: SeedParticle[] = [];\n for (let i = 0; i < count; i += 1) {\n const theta = Math.random() * Math.PI * 2;\n const phi = Math.acos(2 * Math.random() - 1);\n const speed = 8 + Math.random() * 12;\n seeds.push({\n x: 0,\n y: 0,\n z: 0,\n vx: speed * Math.sin(phi) * Math.cos(theta),\n vy: speed * Math.cos(phi),\n vz: speed * Math.sin(phi) * Math.sin(theta),\n life: 1 + Math.random() * 1.6,\n color,\n });\n }\n return seeds;\n}\n","import type { FireworkKind } from '../types';\nimport { pickPalette, pickRandomColor } from '../utils/colorPalettes';\nimport { createAvatarSeeds } from './patterns/avatar';\nimport { createMikuSeeds } from './patterns/miku';\nimport { createNormalSeeds, type SeedParticle } from './patterns/normal';\n\ninterface EmitOptions {\n kind: FireworkKind;\n count: number;\n color?: string;\n avatarUrl?: string;\n}\n\nexport async function createSeedParticles(options: EmitOptions): Promise<SeedParticle[]> {\n const palette = pickPalette(options.kind);\n const color = options.color ?? pickRandomColor(palette);\n\n if (options.kind === 'miku') {\n return createMikuSeeds(options.count);\n }\n\n if (options.kind === 'avatar' && options.avatarUrl) {\n const avatarSeeds = await createAvatarSeeds(options.avatarUrl, color);\n if (avatarSeeds.length > 0) {\n return avatarSeeds;\n }\n }\n\n return createNormalSeeds(options.count, color);\n}\n","export interface ParticleState {\n x: number;\n y: number;\n z: number;\n vx: number;\n vy: number;\n vz: number;\n life: number;\n maxLife: number;\n r: number;\n g: number;\n b: number;\n}\n\nexport class ParticlePool {\n private readonly pool: ParticleState[] = [];\n\n acquire(): ParticleState {\n const reused = this.pool.pop();\n if (reused) {\n return reused;\n }\n return {\n x: 0,\n y: 0,\n z: 0,\n vx: 0,\n vy: 0,\n vz: 0,\n life: 0,\n maxLife: 1,\n r: 1,\n g: 1,\n b: 1,\n };\n }\n\n release(particle: ParticleState): void {\n this.pool.push(particle);\n }\n}\n","export interface EngineDegradePolicy {\n shouldDegrade: boolean;\n recommendedParticleScale: number;\n}\n\nexport function evaluateDegradePolicy(fps: number): EngineDegradePolicy {\n if (fps < 24) {\n return { shouldDegrade: true, recommendedParticleScale: 0.65 };\n }\n if (fps < 34) {\n return { shouldDegrade: true, recommendedParticleScale: 0.82 };\n }\n return { shouldDegrade: false, recommendedParticleScale: 1 };\n}\n","import * as THREE from 'three';\nimport { DEFAULT_MAX_ACTIVE_FIREWORKS, DEFAULT_MAX_PARTICLES } from '../constants';\nimport type { FireworkEngineOptions, FireworkLaunchPayload } from '../types';\nimport { createCircularSpriteTexture } from '../utils/textureFactory';\nimport { createSeedParticles } from './emitters';\nimport { ParticlePool, type ParticleState } from './particlePool';\nimport { evaluateDegradePolicy } from './postfx';\n\ninterface Burst {\n id: string;\n points: THREE.Points;\n geometry: THREE.BufferGeometry;\n material: THREE.PointsMaterial;\n positions: Float32Array;\n colors: Float32Array;\n particles: ParticleState[];\n}\n\ninterface FireworksEngineInit {\n canvas: HTMLCanvasElement;\n container: HTMLElement;\n options?: FireworkEngineOptions;\n}\n\nexport class FireworksEngine {\n private scene: THREE.Scene;\n private camera: THREE.PerspectiveCamera;\n private renderer: THREE.WebGLRenderer;\n private readonly canvas: HTMLCanvasElement;\n private readonly container: HTMLElement;\n private readonly pool = new ParticlePool();\n private readonly bursts: Burst[] = [];\n private readonly maxParticles: number;\n private readonly maxActiveFireworks: number;\n private readonly onError?: (error: Error) => void;\n private readonly onFpsReport?: (fps: number) => void;\n\n private animationFrameId: number | null = null;\n private lastTick = 0;\n private fpsWindow = { frames: 0, elapsed: 0, fps: 60, particleScale: 1 };\n\n private resizeObserver: ResizeObserver | null = null;\n private spriteTexture: THREE.Texture;\n\n constructor(init: FireworksEngineInit) {\n this.canvas = init.canvas;\n this.container = init.container;\n this.maxParticles = init.options?.maxParticles ?? DEFAULT_MAX_PARTICLES;\n this.maxActiveFireworks = init.options?.maxActiveFireworks ?? DEFAULT_MAX_ACTIVE_FIREWORKS;\n this.onError = init.options?.onError;\n this.onFpsReport = init.options?.onFpsReport;\n\n this.scene = new THREE.Scene();\n this.scene.background = new THREE.Color('#060816');\n\n this.camera = new THREE.PerspectiveCamera(50, 1, 0.1, 1000);\n this.camera.position.set(0, 0, 45);\n\n this.renderer = new THREE.WebGLRenderer({\n canvas: this.canvas,\n alpha: true,\n antialias: true,\n powerPreference: 'high-performance',\n });\n this.renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));\n\n this.spriteTexture = createCircularSpriteTexture();\n\n this.attachResizeObserver();\n this.resize();\n }\n\n start(): void {\n if (this.animationFrameId != null) {\n return;\n }\n this.lastTick = window.performance.now();\n this.loop();\n }\n\n stop(): void {\n if (this.animationFrameId != null) {\n window.cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n }\n\n async launch(payload: FireworkLaunchPayload): Promise<void> {\n try {\n this.enforceBurstCap();\n\n const particleBudget = Math.max(80, Math.floor(280 * this.fpsWindow.particleScale));\n const seeds = await createSeedParticles({\n kind: payload.kind,\n count: particleBudget,\n color: payload.color,\n avatarUrl: payload.avatarUrl,\n });\n\n if (seeds.length === 0) {\n return;\n }\n\n const launchPosition = payload.position ?? {\n x: (Math.random() - 0.5) * 18,\n y: -4 + Math.random() * 12,\n z: (Math.random() - 0.5) * 4,\n };\n\n const particles: ParticleState[] = [];\n const positions = new Float32Array(seeds.length * 3);\n const colors = new Float32Array(seeds.length * 3);\n\n const colorHelper = new THREE.Color();\n for (let i = 0; i < seeds.length; i += 1) {\n const seed = seeds[i];\n if (!seed) {\n continue;\n }\n const particle = this.pool.acquire();\n particle.x = launchPosition.x + seed.x;\n particle.y = launchPosition.y + seed.y;\n particle.z = launchPosition.z + seed.z;\n particle.vx = seed.vx;\n particle.vy = seed.vy;\n particle.vz = seed.vz;\n particle.life = seed.life;\n particle.maxLife = seed.life;\n\n colorHelper.set(seed.color);\n particle.r = colorHelper.r;\n particle.g = colorHelper.g;\n particle.b = colorHelper.b;\n\n particles.push(particle);\n\n const offset = i * 3;\n positions[offset] = particle.x;\n positions[offset + 1] = particle.y;\n positions[offset + 2] = particle.z;\n colors[offset] = particle.r;\n colors[offset + 1] = particle.g;\n colors[offset + 2] = particle.b;\n }\n\n if (this.totalParticleCount() + particles.length > this.maxParticles) {\n this.releaseParticles(particles);\n return;\n }\n\n const geometry = new THREE.BufferGeometry();\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));\n\n const material = new THREE.PointsMaterial({\n size: payload.kind === 'miku' ? 0.42 : 0.36,\n vertexColors: true,\n map: this.spriteTexture,\n transparent: true,\n opacity: 1,\n depthWrite: false,\n blending: THREE.AdditiveBlending,\n });\n\n const points = new THREE.Points(geometry, material);\n this.scene.add(points);\n\n const burst: Burst = {\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n points,\n geometry,\n material,\n positions,\n colors,\n particles,\n };\n\n this.bursts.push(burst);\n } catch (error) {\n this.onError?.(error instanceof Error ? error : new Error('Failed to launch firework.'));\n }\n }\n\n dispose(): void {\n this.stop();\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n for (const burst of this.bursts) {\n this.destroyBurst(burst);\n }\n this.bursts.length = 0;\n\n this.spriteTexture.dispose();\n this.renderer.dispose();\n }\n\n private loop = (): void => {\n const now = window.performance.now();\n const dt = Math.min((now - this.lastTick) / 1000, 0.05);\n this.lastTick = now;\n\n this.update(dt);\n this.renderer.render(this.scene, this.camera);\n\n this.animationFrameId = window.requestAnimationFrame(this.loop);\n };\n\n private update(dt: number): void {\n const gravity = -8.8;\n\n for (let b = this.bursts.length - 1; b >= 0; b -= 1) {\n const burst = this.bursts[b];\n if (!burst) {\n continue;\n }\n\n let alive = 0;\n for (let i = 0; i < burst.particles.length; i += 1) {\n const particle = burst.particles[i];\n if (!particle) {\n continue;\n }\n\n particle.life -= dt;\n if (particle.life <= 0) {\n continue;\n }\n\n particle.vx *= 0.992;\n particle.vy = particle.vy * 0.992 + gravity * dt;\n particle.vz *= 0.992;\n\n particle.x += particle.vx * dt;\n particle.y += particle.vy * dt;\n particle.z += particle.vz * dt;\n\n const idx = i * 3;\n burst.positions[idx] = particle.x;\n burst.positions[idx + 1] = particle.y;\n burst.positions[idx + 2] = particle.z;\n\n const alpha = Math.max(particle.life / particle.maxLife, 0);\n burst.colors[idx] = particle.r * alpha;\n burst.colors[idx + 1] = particle.g * alpha;\n burst.colors[idx + 2] = particle.b * alpha;\n\n alive += 1;\n }\n\n const positionAttr = burst.geometry.getAttribute('position') as THREE.BufferAttribute;\n const colorAttr = burst.geometry.getAttribute('color') as THREE.BufferAttribute;\n positionAttr.needsUpdate = true;\n colorAttr.needsUpdate = true;\n\n burst.material.opacity = Math.min(1, 0.22 + alive / Math.max(burst.particles.length, 1));\n\n if (alive === 0) {\n this.bursts.splice(b, 1);\n this.destroyBurst(burst);\n }\n }\n\n this.updateFpsStats(dt);\n }\n\n private updateFpsStats(dt: number): void {\n this.fpsWindow.frames += 1;\n this.fpsWindow.elapsed += dt;\n\n if (this.fpsWindow.elapsed < 0.6) {\n return;\n }\n\n const fps = this.fpsWindow.frames / this.fpsWindow.elapsed;\n this.fpsWindow.fps = fps;\n\n const policy = evaluateDegradePolicy(fps);\n this.fpsWindow.particleScale = policy.recommendedParticleScale;\n\n this.onFpsReport?.(Math.round(fps));\n\n this.fpsWindow.frames = 0;\n this.fpsWindow.elapsed = 0;\n }\n\n private totalParticleCount(): number {\n return this.bursts.reduce((sum, burst) => sum + burst.particles.length, 0);\n }\n\n private enforceBurstCap(): void {\n while (this.bursts.length >= this.maxActiveFireworks) {\n const burst = this.bursts.shift();\n if (!burst) {\n break;\n }\n this.destroyBurst(burst);\n }\n }\n\n private destroyBurst(burst: Burst): void {\n this.scene.remove(burst.points);\n burst.geometry.dispose();\n burst.material.dispose();\n this.releaseParticles(burst.particles);\n }\n\n private releaseParticles(particles: ParticleState[]): void {\n for (const particle of particles) {\n this.pool.release(particle);\n }\n }\n\n private attachResizeObserver(): void {\n this.resizeObserver = new ResizeObserver(() => this.resize());\n this.resizeObserver.observe(this.container);\n }\n\n private resize(): void {\n const width = Math.max(1, this.container.clientWidth);\n const height = Math.max(1, this.container.clientHeight);\n this.camera.aspect = width / height;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(width, height, false);\n }\n}\n","'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FireworksEngine } from '../engine/FireworksEngine';\nimport type { FireworkEngineOptions, FireworkLaunchPayload } from '../types';\n\nexport interface UseFireworksEngineOptions extends FireworkEngineOptions {\n onLaunch?: (payload: FireworkLaunchPayload) => void;\n}\n\nexport function useFireworksEngine(options?: UseFireworksEngineOptions) {\n const containerRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const engineRef = useRef<FireworksEngine | null>(null);\n const pendingLaunchesRef = useRef<FireworkLaunchPayload[]>([]);\n const [fps, setFps] = useState(60);\n const { maxParticles, maxActiveFireworks, onError, onFpsReport, onLaunch } = options || {};\n\n useEffect(() => {\n if (!containerRef.current || !canvasRef.current) {\n return;\n }\n\n const engine = new FireworksEngine({\n container: containerRef.current,\n canvas: canvasRef.current,\n options: {\n maxParticles,\n maxActiveFireworks,\n onError,\n onFpsReport: (nextFps) => {\n setFps(nextFps);\n onFpsReport?.(nextFps);\n },\n },\n });\n\n engine.start();\n engineRef.current = engine;\n if (pendingLaunchesRef.current.length > 0) {\n const pending = [...pendingLaunchesRef.current];\n pendingLaunchesRef.current = [];\n pending.forEach((payload) => {\n void engine.launch(payload);\n });\n }\n\n return () => {\n engineRef.current?.dispose();\n engineRef.current = null;\n pendingLaunchesRef.current = [];\n };\n }, [maxParticles, maxActiveFireworks, onError, onFpsReport]);\n\n const launch = useCallback(\n (payload: FireworkLaunchPayload) => {\n if (!engineRef.current) {\n pendingLaunchesRef.current.push(payload);\n if (pendingLaunchesRef.current.length > 120) {\n pendingLaunchesRef.current.splice(0, pendingLaunchesRef.current.length - 120);\n }\n } else {\n void engineRef.current.launch(payload);\n }\n onLaunch?.(payload);\n },\n [onLaunch]\n );\n\n const api = useMemo(\n () => ({\n containerRef,\n canvasRef,\n launch,\n fps,\n }),\n [fps, launch]\n );\n\n return api;\n}\n","import type {\n FireworkKind,\n FireworkLaunchPayload,\n FireworksRealtimeConfig,\n FireworksRealtimeState,\n FireworksRealtimeUser,\n} from '../types';\n\ninterface RealtimeDanmakuEvent {\n id: string;\n roomId: string;\n text: string;\n color?: string;\n kind?: FireworkKind;\n user: FireworksRealtimeUser;\n timestamp: number;\n}\n\ninterface RealtimeFireworkEvent {\n id: string;\n roomId: string;\n payload: FireworkLaunchPayload;\n user: FireworksRealtimeUser;\n timestamp: number;\n}\n\ntype ClientMessage =\n | {\n type: 'join';\n roomId: string;\n user: FireworksRealtimeUser;\n }\n | {\n type: 'leave';\n }\n | {\n type: 'danmaku.send';\n payload: {\n text: string;\n color?: string;\n kind?: FireworkKind;\n };\n }\n | {\n type: 'firework.launch';\n payload: FireworkLaunchPayload;\n };\n\ntype ServerMessage =\n | {\n type: 'joined';\n roomId: string;\n onlineCount: number;\n self: FireworksRealtimeUser;\n }\n | {\n type: 'room.snapshot';\n roomId: string;\n users: FireworksRealtimeUser[];\n danmakuHistory: RealtimeDanmakuEvent[];\n fireworkHistory: RealtimeFireworkEvent[];\n }\n | {\n type: 'room.user_joined';\n roomId: string;\n user: FireworksRealtimeUser;\n onlineCount: number;\n }\n | {\n type: 'room.user_left';\n roomId: string;\n userId: string;\n onlineCount: number;\n }\n | {\n type: 'danmaku.broadcast';\n roomId: string;\n event: RealtimeDanmakuEvent;\n }\n | {\n type: 'firework.broadcast';\n roomId: string;\n event: RealtimeFireworkEvent;\n }\n | {\n type: 'error';\n code: string;\n message: string;\n }\n | {\n type: 'pong';\n ts: number;\n };\n\nexport interface WebSocketTransportCallbacks {\n onStateChange?: (state: FireworksRealtimeState) => void;\n onDanmakuBroadcast?: (event: RealtimeDanmakuEvent) => void;\n onFireworkBroadcast?: (event: RealtimeFireworkEvent) => void;\n onSnapshot?: (snapshot: Extract<ServerMessage, { type: 'room.snapshot' }>) => void;\n onError?: (error: Error) => void;\n}\n\nexport class WebSocketTransport {\n private socket: WebSocket | null = null;\n private reconnectTimer: number | null = null;\n private isManualClose = false;\n private readonly pendingQueue: ClientMessage[] = [];\n private readonly config: FireworksRealtimeConfig;\n private readonly callbacks: WebSocketTransportCallbacks;\n private state: FireworksRealtimeState;\n\n constructor(config: FireworksRealtimeConfig, callbacks?: WebSocketTransportCallbacks) {\n this.config = config;\n this.callbacks = callbacks || {};\n this.state = {\n connected: false,\n joined: false,\n onlineCount: 0,\n roomId: config.roomId,\n };\n }\n\n connect(): void {\n if (this.socket && (this.socket.readyState === window.WebSocket.OPEN || this.socket.readyState === window.WebSocket.CONNECTING)) {\n return;\n }\n\n this.isManualClose = false;\n\n try {\n this.socket = this.config.protocols\n ? new window.WebSocket(this.config.serverUrl, this.config.protocols)\n : new window.WebSocket(this.config.serverUrl);\n } catch {\n this.callbacks.onError?.(new Error('Failed to create WebSocket connection.'));\n return;\n }\n\n this.socket.onopen = () => {\n this.updateState({ connected: true, joined: false });\n this.send({\n type: 'join',\n roomId: this.config.roomId,\n user: this.config.user,\n });\n };\n\n this.socket.onmessage = (event) => {\n const parsed = parseServerMessage(event.data);\n if (!parsed) {\n return;\n }\n this.handleServerMessage(parsed);\n };\n\n this.socket.onerror = () => {\n this.callbacks.onError?.(new Error('WebSocket transport error.'));\n };\n\n this.socket.onclose = () => {\n this.updateState({ connected: false, joined: false });\n this.scheduleReconnect();\n };\n }\n\n disconnect(): void {\n this.isManualClose = true;\n this.pendingQueue.length = 0;\n if (this.reconnectTimer != null) {\n window.clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (!this.socket) {\n return;\n }\n\n this.send({ type: 'leave' });\n this.socket.close();\n this.socket = null;\n }\n\n sendDanmaku(payload: { text: string; color?: string; kind?: FireworkKind }): void {\n this.send({\n type: 'danmaku.send',\n payload,\n });\n }\n\n sendFirework(payload: FireworkLaunchPayload): void {\n this.send({\n type: 'firework.launch',\n payload,\n });\n }\n\n getState(): FireworksRealtimeState {\n return this.state;\n }\n\n private send(message: ClientMessage): void {\n if (!this.socket || this.socket.readyState !== window.WebSocket.OPEN) {\n if (message.type === 'danmaku.send' || message.type === 'firework.launch') {\n this.pendingQueue.push(message);\n }\n return;\n }\n\n if ((message.type === 'danmaku.send' || message.type === 'firework.launch') && !this.state.joined) {\n this.pendingQueue.push(message);\n return;\n }\n\n this.socket.send(JSON.stringify(message));\n }\n\n private updateState(partial: Partial<FireworksRealtimeState>): void {\n this.state = {\n ...this.state,\n ...partial,\n };\n this.callbacks.onStateChange?.(this.state);\n }\n\n private handleServerMessage(message: ServerMessage): void {\n if (message.type === 'joined') {\n this.updateState({ roomId: message.roomId, onlineCount: message.onlineCount, joined: true });\n this.flushPendingQueue();\n return;\n }\n\n if (message.type === 'room.user_joined' || message.type === 'room.user_left') {\n this.updateState({ onlineCount: message.onlineCount, roomId: message.roomId });\n return;\n }\n\n if (message.type === 'room.snapshot') {\n this.updateState({ roomId: message.roomId, onlineCount: message.users.length });\n this.callbacks.onSnapshot?.(message);\n return;\n }\n\n if (message.type === 'danmaku.broadcast') {\n this.callbacks.onDanmakuBroadcast?.(message.event);\n return;\n }\n\n if (message.type === 'firework.broadcast') {\n this.callbacks.onFireworkBroadcast?.(message.event);\n return;\n }\n\n if (message.type === 'error') {\n this.callbacks.onError?.(new Error(`${message.code}: ${message.message}`));\n }\n }\n\n private scheduleReconnect(): void {\n const reconnect = this.config.reconnect ?? true;\n if (this.isManualClose || !reconnect) {\n return;\n }\n\n if (this.reconnectTimer != null) {\n return;\n }\n\n const delay = this.config.reconnectIntervalMs ?? 1500;\n this.reconnectTimer = window.setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, delay);\n }\n\n private flushPendingQueue(): void {\n if (!this.socket || this.socket.readyState !== window.WebSocket.OPEN || !this.state.joined) {\n return;\n }\n\n while (this.pendingQueue.length > 0) {\n const message = this.pendingQueue.shift();\n if (!message) {\n break;\n }\n this.socket.send(JSON.stringify(message));\n }\n }\n}\n\nfunction parseServerMessage(raw: unknown): ServerMessage | null {\n if (typeof raw !== 'string') {\n return null;\n }\n\n try {\n return JSON.parse(raw) as ServerMessage;\n } catch {\n return null;\n }\n}\n","'use client';\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { WebSocketTransport } from '../client/WebSocketTransport';\nimport type {\n FireworkLaunchPayload,\n FireworksRealtimeConfig,\n FireworksRealtimeState,\n FireworkKind,\n} from '../types';\n\ninterface UseFireworksRealtimeOptions {\n config?: FireworksRealtimeConfig;\n enabled?: boolean;\n onDanmakuBroadcast?: (event: {\n text: string;\n color?: string;\n kind?: FireworkKind;\n userId: string;\n timestamp: number;\n id: string;\n }) => void;\n onFireworkBroadcast?: (event: {\n id: string;\n payload: FireworkLaunchPayload;\n userId: string;\n timestamp: number;\n }) => void;\n onSnapshot?: (snapshot: {\n roomId: string;\n danmakuHistory: Array<{\n id: string;\n text: string;\n color?: string;\n kind?: FireworkKind;\n userId: string;\n timestamp: number;\n }>;\n fireworkHistory: Array<{\n id: string;\n payload: FireworkLaunchPayload;\n userId: string;\n timestamp: number;\n }>;\n }) => void;\n onError?: (error: Error) => void;\n onStateChange?: (state: FireworksRealtimeState) => void;\n}\n\nexport function useFireworksRealtime(options: UseFireworksRealtimeOptions) {\n const { config, enabled, onDanmakuBroadcast, onFireworkBroadcast, onSnapshot, onError, onStateChange } = options;\n const transportRef = useRef<WebSocketTransport | null>(null);\n const callbackRef = useRef({\n onDanmakuBroadcast,\n onFireworkBroadcast,\n onSnapshot,\n onError,\n onStateChange,\n });\n const serverUrl = config?.serverUrl ?? '';\n const roomId = config?.roomId ?? '';\n const userId = config?.user.userId ?? '';\n const nickname = config?.user.nickname ?? '';\n const avatarUrl = config?.user.avatarUrl ?? '';\n const reconnect = config?.reconnect ?? true;\n const reconnectIntervalMs = config?.reconnectIntervalMs ?? 1500;\n const [state, setState] = useState<FireworksRealtimeState>({\n connected: false,\n joined: false,\n onlineCount: 0,\n roomId,\n });\n\n useEffect(() => {\n callbackRef.current = {\n onDanmakuBroadcast,\n onFireworkBroadcast,\n onSnapshot,\n onError,\n onStateChange,\n };\n }, [onDanmakuBroadcast, onError, onFireworkBroadcast, onSnapshot, onStateChange]);\n\n const normalizedConfig = useMemo(() => {\n if (!serverUrl || !roomId || !userId) {\n return undefined;\n }\n const protocols = Array.isArray(config?.protocols)\n ? [...config.protocols]\n : config?.protocols;\n\n return {\n serverUrl,\n roomId,\n user: {\n userId,\n nickname: nickname || undefined,\n avatarUrl: avatarUrl || undefined,\n },\n protocols,\n reconnect,\n reconnectIntervalMs,\n } satisfies FireworksRealtimeConfig;\n }, [avatarUrl, config?.protocols, nickname, reconnect, reconnectIntervalMs, roomId, serverUrl, userId]);\n\n useEffect(() => {\n if (!enabled || !normalizedConfig) {\n transportRef.current?.disconnect();\n transportRef.current = null;\n setState({\n connected: false,\n joined: false,\n onlineCount: 0,\n roomId: normalizedConfig?.roomId,\n });\n return;\n }\n\n const transport = new WebSocketTransport(normalizedConfig, {\n onStateChange: (nextState) => {\n setState(nextState);\n callbackRef.current.onStateChange?.(nextState);\n },\n onDanmakuBroadcast: (event) => {\n callbackRef.current.onDanmakuBroadcast?.({\n id: event.id,\n text: event.text,\n color: event.color,\n kind: event.kind,\n userId: event.user.userId,\n timestamp: event.timestamp,\n });\n },\n onFireworkBroadcast: (event) => {\n callbackRef.current.onFireworkBroadcast?.({\n id: event.id,\n payload: event.payload,\n userId: event.user.userId,\n timestamp: event.timestamp,\n });\n },\n onSnapshot: (snapshot) => {\n callbackRef.current.onSnapshot?.({\n roomId: snapshot.roomId,\n danmakuHistory: snapshot.danmakuHistory.map((item) => ({\n id: item.id,\n text: item.text,\n color: item.color,\n kind: item.kind,\n userId: item.user.userId,\n timestamp: item.timestamp,\n })),\n fireworkHistory: snapshot.fireworkHistory.map((item) => ({\n id: item.id,\n payload: item.payload,\n userId: item.user.userId,\n timestamp: item.timestamp,\n })),\n });\n },\n onError: (error) => {\n callbackRef.current.onError?.(error);\n },\n });\n\n transport.connect();\n transportRef.current = transport;\n\n return () => {\n transport.disconnect();\n if (transportRef.current === transport) {\n transportRef.current = null;\n }\n };\n }, [enabled, normalizedConfig]);\n\n return useMemo(\n () => ({\n state,\n sendDanmaku: (payload: { text: string; color?: string; kind?: FireworkKind }) => {\n transportRef.current?.sendDanmaku(payload);\n },\n sendFirework: (payload: FireworkLaunchPayload) => {\n transportRef.current?.sendFirework(payload);\n },\n }),\n [state]\n );\n}\n","'use client';\n\nimport React, { useMemo, useRef, useState } from 'react';\nimport { DanmakuPanel } from './DanmakuPanel';\nimport { FireworksCanvas } from './FireworksCanvas';\nimport { FireworksControlPanel } from './FireworksControlPanel';\nimport { useDanmakuController } from '../hooks/useDanmakuController';\nimport { useFireworksEngine } from '../hooks/useFireworksEngine';\nimport { useFireworksRealtime } from '../hooks/useFireworksRealtime';\nimport type { FireworkKind, MikuFireworks3DProps } from '../types';\n\nexport function MikuFireworks3D({\n width = '100%',\n height = 520,\n className,\n defaultKind = 'normal',\n autoLaunchOnDanmaku = true,\n maxParticles,\n maxActiveFireworks,\n defaultAvatarUrl = '',\n onLaunch,\n onDanmakuSend,\n onError,\n onFpsReport,\n onRealtimeStateChange,\n realtime,\n}: MikuFireworks3DProps) {\n const [selectedKind, setSelectedKind] = useState<FireworkKind>(defaultKind);\n const [avatarUrl, setAvatarUrl] = useState(defaultAvatarUrl);\n const [autoLaunch, setAutoLaunch] = useState(autoLaunchOnDanmaku);\n const seenDanmakuIdsRef = useRef<Set<string>>(new Set());\n const seenFireworkIdsRef = useRef<Set<string>>(new Set());\n\n const { containerRef, canvasRef, launch, fps } = useFireworksEngine({\n maxParticles,\n maxActiveFireworks,\n onLaunch,\n onError,\n onFpsReport,\n });\n\n const { items, send, addIncoming, removeItem } = useDanmakuController({\n onSend: onDanmakuSend,\n });\n\n const realtimeEnabled = Boolean(realtime && (realtime.enabled ?? true));\n const realtimeApi = useFireworksRealtime({\n enabled: realtimeEnabled,\n config: realtime,\n onStateChange: onRealtimeStateChange,\n onError,\n onDanmakuBroadcast: (event) => {\n if (seenDanmakuIdsRef.current.has(event.id)) {\n return;\n }\n seenDanmakuIdsRef.current.add(event.id);\n addIncoming({\n id: event.id,\n userId: event.userId,\n text: event.text,\n color: event.color,\n timestamp: event.timestamp,\n });\n },\n onFireworkBroadcast: (event) => {\n if (seenFireworkIdsRef.current.has(event.id)) {\n return;\n }\n seenFireworkIdsRef.current.add(event.id);\n launch(event.payload);\n },\n onSnapshot: (snapshot) => {\n for (const danmaku of snapshot.danmakuHistory) {\n if (seenDanmakuIdsRef.current.has(danmaku.id)) {\n continue;\n }\n seenDanmakuIdsRef.current.add(danmaku.id);\n addIncoming({\n id: danmaku.id,\n userId: danmaku.userId,\n text: danmaku.text,\n color: danmaku.color,\n timestamp: danmaku.timestamp,\n });\n }\n for (const firework of snapshot.fireworkHistory) {\n if (seenFireworkIdsRef.current.has(firework.id)) {\n continue;\n }\n seenFireworkIdsRef.current.add(firework.id);\n launch(firework.payload);\n }\n },\n });\n\n const handleLaunch = (kind: FireworkKind) => {\n const payload = {\n kind,\n avatarUrl: kind === 'avatar' ? avatarUrl || undefined : undefined,\n };\n\n if (realtimeEnabled && realtimeApi.state.connected && realtimeApi.state.joined) {\n realtimeApi.sendFirework(payload);\n return;\n }\n\n launch(payload);\n };\n\n const handleSendDanmaku = (text: string) => {\n const result = send(text, undefined, {\n optimistic: !(realtimeEnabled && realtimeApi.state.connected && realtimeApi.state.joined),\n });\n if (!result) {\n return;\n }\n\n const launchKind = result.launchKind ?? selectedKind;\n if (realtimeEnabled && realtimeApi.state.connected && realtimeApi.state.joined) {\n realtimeApi.sendDanmaku({\n text: result.message.text,\n color: result.message.color,\n kind: result.launchKind,\n });\n\n if (autoLaunch) {\n realtimeApi.sendFirework({\n kind: launchKind,\n avatarUrl: launchKind === 'avatar' ? avatarUrl || undefined : undefined,\n message: result.message,\n });\n }\n return;\n }\n\n if (autoLaunch || result.launchKind) {\n launch({\n kind: launchKind,\n avatarUrl: launchKind === 'avatar' ? avatarUrl || undefined : undefined,\n message: result.message,\n });\n }\n };\n\n const containerStyle = useMemo<React.CSSProperties>(\n () => ({\n width,\n height,\n minHeight: 360,\n }),\n [height, width]\n );\n\n return (\n <div className={`mx-auto flex w-full max-w-5xl flex-col gap-3 ${className || ''}`}>\n <div ref={containerRef} className=\"relative overflow-hidden rounded-2xl border border-slate-700\" style={containerStyle}>\n <FireworksCanvas canvasRef={canvasRef} />\n\n <div className=\"pointer-events-none absolute inset-0 overflow-hidden\">\n {items.map((item) => (\n <div\n key={item.id}\n onAnimationEnd={() => removeItem(item.id)}\n className=\"absolute right-[-30%] whitespace-nowrap text-sm font-semibold text-white drop-shadow\"\n style={{\n top: `${8 + item.track * 11}%`,\n color: item.color || '#ffffff',\n animation: `sa2kit-danmaku-move ${item.durationMs}ms linear forwards`,\n }}\n >\n {item.text}\n </div>\n ))}\n </div>\n </div>\n\n <FireworksControlPanel\n selectedKind={selectedKind}\n onKindChange={setSelectedKind}\n autoLaunchOnDanmaku={autoLaunch}\n onAutoLaunchChange={setAutoLaunch}\n avatarUrl={avatarUrl}\n onAvatarUrlChange={setAvatarUrl}\n onLaunch={() => handleLaunch(selectedKind)}\n fps={fps}\n realtimeConnected={realtimeEnabled ? realtimeApi.state.connected : undefined}\n onlineCount={realtimeEnabled ? realtimeApi.state.onlineCount : undefined}\n />\n\n <DanmakuPanel onSend={handleSendDanmaku} />\n\n <style>{`\\n @keyframes sa2kit-danmaku-move {\\n 0% {\\n transform: translateX(0);\\n opacity: 1;\\n }\\n 100% {\\n transform: translateX(-160vw);\\n opacity: 0.92;\\n }\\n }\\n `}</style>\n </div>\n );\n}\n"]}
|