@sogni-ai/expo-client 1.0.0-alpha.10
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 +69 -0
- package/README.md +411 -0
- package/dist/cjs/Account/index.d.ts +60 -0
- package/dist/cjs/Account/index.d.ts.map +1 -0
- package/dist/cjs/Account/index.js +188 -0
- package/dist/cjs/Account/index.js.map +1 -0
- package/dist/cjs/Account/types.d.ts +43 -0
- package/dist/cjs/Account/types.d.ts.map +1 -0
- package/dist/cjs/Account/types.js +18 -0
- package/dist/cjs/Account/types.js.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/events.d.ts +139 -0
- package/dist/cjs/ApiClient/WebSocketClient/events.d.ts.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/events.js +3 -0
- package/dist/cjs/ApiClient/WebSocketClient/events.js.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/index.d.ts +45 -0
- package/dist/cjs/ApiClient/WebSocketClient/index.d.ts.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/index.js +283 -0
- package/dist/cjs/ApiClient/WebSocketClient/index.js.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/normalize.d.ts +45 -0
- package/dist/cjs/ApiClient/WebSocketClient/normalize.d.ts.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/normalize.js +245 -0
- package/dist/cjs/ApiClient/WebSocketClient/normalize.js.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/types.d.ts +9 -0
- package/dist/cjs/ApiClient/WebSocketClient/types.d.ts.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/types.js +3 -0
- package/dist/cjs/ApiClient/WebSocketClient/types.js.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/wireTypes.d.ts +161 -0
- package/dist/cjs/ApiClient/WebSocketClient/wireTypes.d.ts.map +1 -0
- package/dist/cjs/ApiClient/WebSocketClient/wireTypes.js +11 -0
- package/dist/cjs/ApiClient/WebSocketClient/wireTypes.js.map +1 -0
- package/dist/cjs/ApiClient/index.d.ts +60 -0
- package/dist/cjs/ApiClient/index.d.ts.map +1 -0
- package/dist/cjs/ApiClient/index.js +87 -0
- package/dist/cjs/ApiClient/index.js.map +1 -0
- package/dist/cjs/Chat/ChatStream.d.ts +42 -0
- package/dist/cjs/Chat/ChatStream.d.ts.map +1 -0
- package/dist/cjs/Chat/ChatStream.js +146 -0
- package/dist/cjs/Chat/ChatStream.js.map +1 -0
- package/dist/cjs/Chat/index.d.ts +61 -0
- package/dist/cjs/Chat/index.d.ts.map +1 -0
- package/dist/cjs/Chat/index.js +179 -0
- package/dist/cjs/Chat/index.js.map +1 -0
- package/dist/cjs/Chat/tools.d.ts +13 -0
- package/dist/cjs/Chat/tools.d.ts.map +1 -0
- package/dist/cjs/Chat/tools.js +22 -0
- package/dist/cjs/Chat/tools.js.map +1 -0
- package/dist/cjs/Chat/types.d.ts +153 -0
- package/dist/cjs/Chat/types.d.ts.map +1 -0
- package/dist/cjs/Chat/types.js +3 -0
- package/dist/cjs/Chat/types.js.map +1 -0
- package/dist/cjs/Projects/ControlNet.d.ts +30 -0
- package/dist/cjs/Projects/ControlNet.d.ts.map +1 -0
- package/dist/cjs/Projects/ControlNet.js +45 -0
- package/dist/cjs/Projects/ControlNet.js.map +1 -0
- package/dist/cjs/Projects/createJobRequestMessage.d.ts +11 -0
- package/dist/cjs/Projects/createJobRequestMessage.d.ts.map +1 -0
- package/dist/cjs/Projects/createJobRequestMessage.js +239 -0
- package/dist/cjs/Projects/createJobRequestMessage.js.map +1 -0
- package/dist/cjs/Projects/index.d.ts +96 -0
- package/dist/cjs/Projects/index.d.ts.map +1 -0
- package/dist/cjs/Projects/index.js +536 -0
- package/dist/cjs/Projects/index.js.map +1 -0
- package/dist/cjs/Projects/restNormalize.d.ts +60 -0
- package/dist/cjs/Projects/restNormalize.d.ts.map +1 -0
- package/dist/cjs/Projects/restNormalize.js +89 -0
- package/dist/cjs/Projects/restNormalize.js.map +1 -0
- package/dist/cjs/Projects/types.d.ts +233 -0
- package/dist/cjs/Projects/types.d.ts.map +1 -0
- package/dist/cjs/Projects/types.js +3 -0
- package/dist/cjs/Projects/types.js.map +1 -0
- package/dist/cjs/Projects/utils.d.ts +23 -0
- package/dist/cjs/Projects/utils.d.ts.map +1 -0
- package/dist/cjs/Projects/utils.js +65 -0
- package/dist/cjs/Projects/utils.js.map +1 -0
- package/dist/cjs/index.d.ts +63 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +116 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lib/AuthManager/ApiKeyAuthManager.d.ts +15 -0
- package/dist/cjs/lib/AuthManager/ApiKeyAuthManager.d.ts.map +1 -0
- package/dist/cjs/lib/AuthManager/ApiKeyAuthManager.js +47 -0
- package/dist/cjs/lib/AuthManager/ApiKeyAuthManager.js.map +1 -0
- package/dist/cjs/lib/AuthManager/AuthManagerBase.d.ts +23 -0
- package/dist/cjs/lib/AuthManager/AuthManagerBase.d.ts.map +1 -0
- package/dist/cjs/lib/AuthManager/AuthManagerBase.js +14 -0
- package/dist/cjs/lib/AuthManager/AuthManagerBase.js.map +1 -0
- package/dist/cjs/lib/AuthManager/AuthStorage.d.ts +11 -0
- package/dist/cjs/lib/AuthManager/AuthStorage.d.ts.map +1 -0
- package/dist/cjs/lib/AuthManager/AuthStorage.js +50 -0
- package/dist/cjs/lib/AuthManager/AuthStorage.js.map +1 -0
- package/dist/cjs/lib/AuthManager/TokenAuthManager.d.ts +35 -0
- package/dist/cjs/lib/AuthManager/TokenAuthManager.d.ts.map +1 -0
- package/dist/cjs/lib/AuthManager/TokenAuthManager.js +164 -0
- package/dist/cjs/lib/AuthManager/TokenAuthManager.js.map +1 -0
- package/dist/cjs/lib/AuthManager/index.d.ts +7 -0
- package/dist/cjs/lib/AuthManager/index.d.ts.map +1 -0
- package/dist/cjs/lib/AuthManager/index.js +13 -0
- package/dist/cjs/lib/AuthManager/index.js.map +1 -0
- package/dist/cjs/lib/Cache.d.ts +12 -0
- package/dist/cjs/lib/Cache.d.ts.map +1 -0
- package/dist/cjs/lib/Cache.js +36 -0
- package/dist/cjs/lib/Cache.js.map +1 -0
- package/dist/cjs/lib/DefaultLogger.d.ts +17 -0
- package/dist/cjs/lib/DefaultLogger.d.ts.map +1 -0
- package/dist/cjs/lib/DefaultLogger.js +36 -0
- package/dist/cjs/lib/DefaultLogger.js.map +1 -0
- package/dist/cjs/lib/RestClient.d.ts +18 -0
- package/dist/cjs/lib/RestClient.d.ts.map +1 -0
- package/dist/cjs/lib/RestClient.js +67 -0
- package/dist/cjs/lib/RestClient.js.map +1 -0
- package/dist/cjs/lib/TypedEventEmitter.d.ts +16 -0
- package/dist/cjs/lib/TypedEventEmitter.d.ts.map +1 -0
- package/dist/cjs/lib/TypedEventEmitter.js +46 -0
- package/dist/cjs/lib/TypedEventEmitter.js.map +1 -0
- package/dist/cjs/lib/base64.d.ts +3 -0
- package/dist/cjs/lib/base64.d.ts.map +1 -0
- package/dist/cjs/lib/base64.js +21 -0
- package/dist/cjs/lib/base64.js.map +1 -0
- package/dist/cjs/lib/getUUID.d.ts +12 -0
- package/dist/cjs/lib/getUUID.d.ts.map +1 -0
- package/dist/cjs/lib/getUUID.js +29 -0
- package/dist/cjs/lib/getUUID.js.map +1 -0
- package/dist/cjs/lib/mediaInput.d.ts +33 -0
- package/dist/cjs/lib/mediaInput.d.ts.map +1 -0
- package/dist/cjs/lib/mediaInput.js +32 -0
- package/dist/cjs/lib/mediaInput.js.map +1 -0
- package/dist/cjs/lib/utils.d.ts +10 -0
- package/dist/cjs/lib/utils.d.ts.map +1 -0
- package/dist/cjs/lib/utils.js +24 -0
- package/dist/cjs/lib/utils.js.map +1 -0
- package/dist/cjs/types/ErrorData.d.ts +7 -0
- package/dist/cjs/types/ErrorData.d.ts.map +1 -0
- package/dist/cjs/types/ErrorData.js +3 -0
- package/dist/cjs/types/ErrorData.js.map +1 -0
- package/dist/cjs/types/json.d.ts +6 -0
- package/dist/cjs/types/json.d.ts.map +1 -0
- package/dist/cjs/types/json.js +3 -0
- package/dist/cjs/types/json.js.map +1 -0
- package/dist/cjs/types/token.d.ts +2 -0
- package/dist/cjs/types/token.d.ts.map +1 -0
- package/dist/cjs/types/token.js +3 -0
- package/dist/cjs/types/token.js.map +1 -0
- package/dist/cjs/version.d.ts +2 -0
- package/dist/cjs/version.d.ts.map +1 -0
- package/dist/cjs/version.js +5 -0
- package/dist/cjs/version.js.map +1 -0
- package/dist/cjs/wallet.d.ts +59 -0
- package/dist/cjs/wallet.d.ts.map +1 -0
- package/dist/cjs/wallet.js +125 -0
- package/dist/cjs/wallet.js.map +1 -0
- package/dist/esm/Account/index.js +183 -0
- package/dist/esm/Account/index.js.map +1 -0
- package/dist/esm/Account/types.js +15 -0
- package/dist/esm/Account/types.js.map +1 -0
- package/dist/esm/ApiClient/WebSocketClient/events.js +2 -0
- package/dist/esm/ApiClient/WebSocketClient/events.js.map +1 -0
- package/dist/esm/ApiClient/WebSocketClient/index.js +278 -0
- package/dist/esm/ApiClient/WebSocketClient/index.js.map +1 -0
- package/dist/esm/ApiClient/WebSocketClient/normalize.js +229 -0
- package/dist/esm/ApiClient/WebSocketClient/normalize.js.map +1 -0
- package/dist/esm/ApiClient/WebSocketClient/types.js +2 -0
- package/dist/esm/ApiClient/WebSocketClient/types.js.map +1 -0
- package/dist/esm/ApiClient/WebSocketClient/wireTypes.js +10 -0
- package/dist/esm/ApiClient/WebSocketClient/wireTypes.js.map +1 -0
- package/dist/esm/ApiClient/index.js +80 -0
- package/dist/esm/ApiClient/index.js.map +1 -0
- package/dist/esm/Chat/ChatStream.js +144 -0
- package/dist/esm/Chat/ChatStream.js.map +1 -0
- package/dist/esm/Chat/index.js +174 -0
- package/dist/esm/Chat/index.js.map +1 -0
- package/dist/esm/Chat/tools.js +19 -0
- package/dist/esm/Chat/tools.js.map +1 -0
- package/dist/esm/Chat/types.js +2 -0
- package/dist/esm/Chat/types.js.map +1 -0
- package/dist/esm/Projects/ControlNet.js +41 -0
- package/dist/esm/Projects/ControlNet.js.map +1 -0
- package/dist/esm/Projects/createJobRequestMessage.js +236 -0
- package/dist/esm/Projects/createJobRequestMessage.js.map +1 -0
- package/dist/esm/Projects/index.js +531 -0
- package/dist/esm/Projects/index.js.map +1 -0
- package/dist/esm/Projects/restNormalize.js +86 -0
- package/dist/esm/Projects/restNormalize.js.map +1 -0
- package/dist/esm/Projects/types.js +2 -0
- package/dist/esm/Projects/types.js.map +1 -0
- package/dist/esm/Projects/utils.js +55 -0
- package/dist/esm/Projects/utils.js.map +1 -0
- package/dist/esm/index.js +72 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/AuthManager/ApiKeyAuthManager.js +42 -0
- package/dist/esm/lib/AuthManager/ApiKeyAuthManager.js.map +1 -0
- package/dist/esm/lib/AuthManager/AuthManagerBase.js +9 -0
- package/dist/esm/lib/AuthManager/AuthManagerBase.js.map +1 -0
- package/dist/esm/lib/AuthManager/AuthStorage.js +13 -0
- package/dist/esm/lib/AuthManager/AuthStorage.js.map +1 -0
- package/dist/esm/lib/AuthManager/TokenAuthManager.js +159 -0
- package/dist/esm/lib/AuthManager/TokenAuthManager.js.map +1 -0
- package/dist/esm/lib/AuthManager/index.js +5 -0
- package/dist/esm/lib/AuthManager/index.js.map +1 -0
- package/dist/esm/lib/Cache.js +33 -0
- package/dist/esm/lib/Cache.js.map +1 -0
- package/dist/esm/lib/DefaultLogger.js +32 -0
- package/dist/esm/lib/DefaultLogger.js.map +1 -0
- package/dist/esm/lib/RestClient.js +62 -0
- package/dist/esm/lib/RestClient.js.map +1 -0
- package/dist/esm/lib/TypedEventEmitter.js +44 -0
- package/dist/esm/lib/TypedEventEmitter.js.map +1 -0
- package/dist/esm/lib/base64.js +17 -0
- package/dist/esm/lib/base64.js.map +1 -0
- package/dist/esm/lib/getUUID.js +26 -0
- package/dist/esm/lib/getUUID.js.map +1 -0
- package/dist/esm/lib/mediaInput.js +28 -0
- package/dist/esm/lib/mediaInput.js.map +1 -0
- package/dist/esm/lib/utils.js +19 -0
- package/dist/esm/lib/utils.js.map +1 -0
- package/dist/esm/types/ErrorData.js +2 -0
- package/dist/esm/types/ErrorData.js.map +1 -0
- package/dist/esm/types/json.js +2 -0
- package/dist/esm/types/json.js.map +1 -0
- package/dist/esm/types/token.js +2 -0
- package/dist/esm/types/token.js.map +1 -0
- package/dist/esm/version.js +2 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/esm/wallet.js +117 -0
- package/dist/esm/wallet.js.map +1 -0
- package/package.json +92 -0
- package/src/Account/index.ts +214 -0
- package/src/Account/types.ts +61 -0
- package/src/ApiClient/WebSocketClient/events.ts +168 -0
- package/src/ApiClient/WebSocketClient/index.ts +345 -0
- package/src/ApiClient/WebSocketClient/normalize.ts +287 -0
- package/src/ApiClient/WebSocketClient/types.ts +10 -0
- package/src/ApiClient/WebSocketClient/wireTypes.ts +183 -0
- package/src/ApiClient/index.ts +147 -0
- package/src/Chat/ChatStream.ts +164 -0
- package/src/Chat/index.ts +224 -0
- package/src/Chat/tools.ts +23 -0
- package/src/Chat/types.ts +165 -0
- package/src/Projects/ControlNet.ts +84 -0
- package/src/Projects/createJobRequestMessage.ts +241 -0
- package/src/Projects/index.ts +608 -0
- package/src/Projects/restNormalize.ts +154 -0
- package/src/Projects/types.ts +266 -0
- package/src/Projects/utils.ts +60 -0
- package/src/index.ts +217 -0
- package/src/lib/AuthManager/ApiKeyAuthManager.ts +52 -0
- package/src/lib/AuthManager/AuthManagerBase.ts +35 -0
- package/src/lib/AuthManager/AuthStorage.ts +21 -0
- package/src/lib/AuthManager/TokenAuthManager.ts +179 -0
- package/src/lib/AuthManager/index.ts +8 -0
- package/src/lib/Cache.ts +45 -0
- package/src/lib/DefaultLogger.ts +47 -0
- package/src/lib/RestClient.ts +77 -0
- package/src/lib/TypedEventEmitter.ts +52 -0
- package/src/lib/base64.ts +17 -0
- package/src/lib/getUUID.ts +27 -0
- package/src/lib/mediaInput.ts +54 -0
- package/src/lib/utils.ts +21 -0
- package/src/types/ErrorData.ts +7 -0
- package/src/types/json.ts +5 -0
- package/src/types/token.ts +1 -0
- package/src/version.ts +1 -0
- package/src/wallet.ts +158 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { SupernetType } from './types';
|
|
2
|
+
import { JobErrorReason } from '../../Projects/types';
|
|
3
|
+
import { LLMModelInfo, ToolCallDelta, TokenUsage } from '../../Chat/types';
|
|
4
|
+
|
|
5
|
+
export interface BalanceData {
|
|
6
|
+
settled: string;
|
|
7
|
+
credit: string;
|
|
8
|
+
debit: string;
|
|
9
|
+
net: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface SparkBalanceData extends BalanceData {
|
|
13
|
+
premiumCredit: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface Balances {
|
|
17
|
+
sogni: BalanceData;
|
|
18
|
+
spark: SparkBalanceData;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface AuthenticatedEvent {
|
|
22
|
+
username: string;
|
|
23
|
+
walletAddress: string;
|
|
24
|
+
balance: Balances;
|
|
25
|
+
isMainnet: boolean;
|
|
26
|
+
accountWasMigrated: boolean;
|
|
27
|
+
hasUnclaimedAirdrop: boolean;
|
|
28
|
+
firstLoginAfterMigration: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface BalanceUpdateEvent {
|
|
32
|
+
balance: Balances;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ChangeNetworkEvent {
|
|
36
|
+
network: SupernetType;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface ConnectedEvent {
|
|
40
|
+
network: SupernetType;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface DisconnectedEvent {
|
|
44
|
+
code?: number;
|
|
45
|
+
reason?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface ToastMessageEvent {
|
|
49
|
+
level: 'info' | 'success' | 'warning' | 'error';
|
|
50
|
+
message: string;
|
|
51
|
+
stickyID?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* === Project / job lifecycle (Phase 3). All IDs are normalized; on the wire,
|
|
55
|
+
* `jobID` is the project id and `imgID` is the job id. The rest of the SDK
|
|
56
|
+
* and consumers only see `projectId` and `jobId`. === */
|
|
57
|
+
|
|
58
|
+
export interface JobStartedEvent {
|
|
59
|
+
projectId: string;
|
|
60
|
+
jobId: string | null;
|
|
61
|
+
workerName: string | null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface JobInitiatingModelEvent {
|
|
65
|
+
projectId: string;
|
|
66
|
+
jobId: string | null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface JobLifecycleCompletedEvent {
|
|
70
|
+
projectId: string;
|
|
71
|
+
jobId: string | null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface JobProgressEvent {
|
|
75
|
+
projectId: string;
|
|
76
|
+
jobId: string;
|
|
77
|
+
/** Derived as step/stepCount in [0,1]. */
|
|
78
|
+
progress: number;
|
|
79
|
+
step: number;
|
|
80
|
+
stepCount: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface JobResultEvent {
|
|
84
|
+
projectId: string;
|
|
85
|
+
jobId: string;
|
|
86
|
+
seed: number;
|
|
87
|
+
performedStepCount: number;
|
|
88
|
+
/** True if the artist cancelled this job. The SDK turns these into JobFailed. */
|
|
89
|
+
userCanceled: boolean;
|
|
90
|
+
/** True if NSFW filter triggered. The SDK marks the job result as withheld. */
|
|
91
|
+
triggeredNSFWFilter: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface JobErrorEvent {
|
|
95
|
+
projectId: string;
|
|
96
|
+
jobId: string | null;
|
|
97
|
+
reason: JobErrorReason;
|
|
98
|
+
/** Original server-side error string, preserved for forward compat. */
|
|
99
|
+
rawCode: string;
|
|
100
|
+
message: string;
|
|
101
|
+
source: 'worker' | 'server';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface JobETAEvent {
|
|
105
|
+
projectId: string;
|
|
106
|
+
jobId: string;
|
|
107
|
+
etaSeconds: number;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface ArtistCancelConfirmationEvent {
|
|
111
|
+
projectId: string;
|
|
112
|
+
didCancel: boolean;
|
|
113
|
+
errorMessage?: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* === Chat / LLM lifecycle (Phase 4b). Chat jobs have a single jobId (no
|
|
117
|
+
* project/job split like image projects). The wire field stays jobID
|
|
118
|
+
* and we just rename to jobId for camelCase consistency. === */
|
|
119
|
+
|
|
120
|
+
export interface ChatTokensEvent {
|
|
121
|
+
jobId: string;
|
|
122
|
+
content: string;
|
|
123
|
+
role?: string;
|
|
124
|
+
finishReason?: string | null;
|
|
125
|
+
usage?: TokenUsage;
|
|
126
|
+
tool_calls?: ToolCallDelta[];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface ChatResultEvent {
|
|
130
|
+
jobId: string;
|
|
131
|
+
usage: TokenUsage;
|
|
132
|
+
timeTaken: number;
|
|
133
|
+
workerName?: string;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface ChatErrorEvent {
|
|
137
|
+
jobId: string;
|
|
138
|
+
rawCode: string;
|
|
139
|
+
message: string;
|
|
140
|
+
workerName?: string;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface SwarmLLMModelsEvent {
|
|
144
|
+
/** Map of model ID -> info. Worker counts are 0 if no workers serve the model. */
|
|
145
|
+
models: Record<string, LLMModelInfo>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Public event map for WebSocketClient. */
|
|
149
|
+
export interface SocketEventMap {
|
|
150
|
+
connected: ConnectedEvent;
|
|
151
|
+
disconnected: DisconnectedEvent;
|
|
152
|
+
authenticated: AuthenticatedEvent;
|
|
153
|
+
balanceUpdate: BalanceUpdateEvent;
|
|
154
|
+
changeNetwork: ChangeNetworkEvent;
|
|
155
|
+
toastMessage: ToastMessageEvent;
|
|
156
|
+
jobStarted: JobStartedEvent;
|
|
157
|
+
jobInitiatingModel: JobInitiatingModelEvent;
|
|
158
|
+
jobLifecycleCompleted: JobLifecycleCompletedEvent;
|
|
159
|
+
jobProgress: JobProgressEvent;
|
|
160
|
+
jobResult: JobResultEvent;
|
|
161
|
+
jobError: JobErrorEvent;
|
|
162
|
+
jobETA: JobETAEvent;
|
|
163
|
+
artistCancelConfirmation: ArtistCancelConfirmationEvent;
|
|
164
|
+
chatTokens: ChatTokensEvent;
|
|
165
|
+
chatResult: ChatResultEvent;
|
|
166
|
+
chatError: ChatErrorEvent;
|
|
167
|
+
swarmLLMModels: SwarmLLMModelsEvent;
|
|
168
|
+
}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import TypedEventEmitter from '../../lib/TypedEventEmitter';
|
|
2
|
+
import { base64Decode, base64Encode } from '../../lib/base64';
|
|
3
|
+
import { Logger } from '../../lib/DefaultLogger';
|
|
4
|
+
import { AuthManager } from '../../lib/AuthManager';
|
|
5
|
+
import { LIB_VERSION } from '../../version';
|
|
6
|
+
import { ConnectionStatus, SupernetType } from './types';
|
|
7
|
+
import { SocketEventMap } from './events';
|
|
8
|
+
import {
|
|
9
|
+
normalizeArtistCancelConfirmation,
|
|
10
|
+
normalizeAuthenticated,
|
|
11
|
+
normalizeBalanceUpdate,
|
|
12
|
+
normalizeChangeNetwork,
|
|
13
|
+
normalizeChatError,
|
|
14
|
+
normalizeChatResult,
|
|
15
|
+
normalizeChatTokens,
|
|
16
|
+
normalizeJobError,
|
|
17
|
+
normalizeJobETA,
|
|
18
|
+
normalizeJobProgress,
|
|
19
|
+
normalizeJobResult,
|
|
20
|
+
normalizeJobState,
|
|
21
|
+
normalizeSwarmLLMModels,
|
|
22
|
+
normalizeToastMessage
|
|
23
|
+
} from './normalize';
|
|
24
|
+
import {
|
|
25
|
+
RawArtistCancelConfirmation,
|
|
26
|
+
RawAuthenticated,
|
|
27
|
+
RawBalanceUpdate,
|
|
28
|
+
RawChangeNetwork,
|
|
29
|
+
RawJobError,
|
|
30
|
+
RawJobETA,
|
|
31
|
+
RawJobProgress,
|
|
32
|
+
RawJobResult,
|
|
33
|
+
RawJobState,
|
|
34
|
+
RawJobTokens,
|
|
35
|
+
RawLLMJobError,
|
|
36
|
+
RawLLMJobResult,
|
|
37
|
+
RawSwarmLLMModels,
|
|
38
|
+
RawToastMessage
|
|
39
|
+
} from './wireTypes';
|
|
40
|
+
|
|
41
|
+
const PROTOCOL_VERSION = '3.0.0';
|
|
42
|
+
const RECONNECT_DELAY_MS = 1000;
|
|
43
|
+
const MAX_RECONNECT_ATTEMPTS = 5;
|
|
44
|
+
|
|
45
|
+
/** RN WebSocket constructor accepts a third options argument with `headers`. */
|
|
46
|
+
type WebSocketCtorOptions = { headers?: Record<string, string> } | undefined;
|
|
47
|
+
type WebSocketCtor = new (
|
|
48
|
+
url: string,
|
|
49
|
+
protocols?: string | string[] | null,
|
|
50
|
+
options?: WebSocketCtorOptions
|
|
51
|
+
) => WebSocket;
|
|
52
|
+
|
|
53
|
+
/** Minimal shape of the RN AppState module — we lazy-require it. */
|
|
54
|
+
interface AppStateModule {
|
|
55
|
+
currentState?: string;
|
|
56
|
+
addEventListener(type: 'change', listener: (state: string) => void): { remove(): void };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function loadAppState(logger: Logger): AppStateModule | null {
|
|
60
|
+
try {
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
62
|
+
const rn = require('react-native');
|
|
63
|
+
return rn?.AppState ?? null;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
logger.debug('react-native not available, skipping AppState integration:', e);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
class WebSocketClient extends TypedEventEmitter<SocketEventMap> {
|
|
71
|
+
readonly appId: string;
|
|
72
|
+
readonly appSource?: string;
|
|
73
|
+
readonly baseUrl: string;
|
|
74
|
+
protected _logger: Logger;
|
|
75
|
+
private _auth: AuthManager;
|
|
76
|
+
private _supernetType: SupernetType;
|
|
77
|
+
private socket: WebSocket | null = null;
|
|
78
|
+
private _status: ConnectionStatus = 'disconnected';
|
|
79
|
+
private _reconnectAttempts = 0;
|
|
80
|
+
private _wantConnected = false;
|
|
81
|
+
private _appStateSubscription: { remove(): void } | null = null;
|
|
82
|
+
|
|
83
|
+
constructor(
|
|
84
|
+
baseUrl: string,
|
|
85
|
+
auth: AuthManager,
|
|
86
|
+
appId: string,
|
|
87
|
+
supernetType: SupernetType,
|
|
88
|
+
logger: Logger,
|
|
89
|
+
appSource?: string
|
|
90
|
+
) {
|
|
91
|
+
super();
|
|
92
|
+
this.baseUrl = normalizeBaseUrl(baseUrl);
|
|
93
|
+
this._auth = auth;
|
|
94
|
+
this.appId = appId;
|
|
95
|
+
this.appSource = appSource?.trim() || undefined;
|
|
96
|
+
this._supernetType = supernetType;
|
|
97
|
+
this._logger = logger;
|
|
98
|
+
this._subscribeAppState();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Subscribe to RN AppState 'change' events. When the app returns to the
|
|
103
|
+
* foreground, if we *want* to be connected but aren't, reconnect (and reset
|
|
104
|
+
* the backoff counter so the user immediately sees a real attempt). When
|
|
105
|
+
* the app backgrounds we do nothing — iOS will probably suspend the socket
|
|
106
|
+
* itself, and we'll reconnect on next foreground transition.
|
|
107
|
+
*/
|
|
108
|
+
private _subscribeAppState(): void {
|
|
109
|
+
const AppState = loadAppState(this._logger);
|
|
110
|
+
if (!AppState) return;
|
|
111
|
+
this._appStateSubscription = AppState.addEventListener('change', (state) => {
|
|
112
|
+
if (state !== 'active') return;
|
|
113
|
+
if (!this._wantConnected || this._status === 'connected') return;
|
|
114
|
+
this._logger.debug('App returned to foreground — reconnecting WebSocket');
|
|
115
|
+
this._reconnectAttempts = 0;
|
|
116
|
+
void this.connect();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
get supernetType(): SupernetType {
|
|
121
|
+
return this._supernetType;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
get isConnected(): boolean {
|
|
125
|
+
return this._status === 'connected';
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
get status(): ConnectionStatus {
|
|
129
|
+
return this._status;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async connect(): Promise<void> {
|
|
133
|
+
this._wantConnected = true;
|
|
134
|
+
if (this.socket) {
|
|
135
|
+
this._cleanupSocket();
|
|
136
|
+
}
|
|
137
|
+
this._status = 'connecting';
|
|
138
|
+
|
|
139
|
+
const userAgent = `Sogni/${PROTOCOL_VERSION} (sogni-expo-client) ${LIB_VERSION}`;
|
|
140
|
+
const url = new URL(this.baseUrl);
|
|
141
|
+
url.protocol = url.protocol === 'https:' || url.protocol === 'wss:' ? 'wss:' : 'ws:';
|
|
142
|
+
url.searchParams.set('appId', this.appId);
|
|
143
|
+
if (this.appSource) url.searchParams.set('appSource', this.appSource);
|
|
144
|
+
url.searchParams.set('clientName', userAgent);
|
|
145
|
+
url.searchParams.set('clientType', 'artist');
|
|
146
|
+
url.searchParams.set('forceWorkerId', this._supernetType === 'fast' ? 'fast' : '');
|
|
147
|
+
|
|
148
|
+
const auth = await this._auth.socketAuth();
|
|
149
|
+
if (auth.queryParams) {
|
|
150
|
+
for (const [k, v] of Object.entries(auth.queryParams)) {
|
|
151
|
+
url.searchParams.set(k, v);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const options: WebSocketCtorOptions = auth.headers ? { headers: auth.headers } : undefined;
|
|
156
|
+
const Ctor = (globalThis as unknown as { WebSocket: WebSocketCtor }).WebSocket;
|
|
157
|
+
if (!Ctor) {
|
|
158
|
+
throw new Error('No global WebSocket available — are you running outside of React Native?');
|
|
159
|
+
}
|
|
160
|
+
const socket = new Ctor(url.toString(), undefined, options);
|
|
161
|
+
this.socket = socket;
|
|
162
|
+
socket.onopen = () => this._handleOpen();
|
|
163
|
+
socket.onmessage = (e) => this._handleMessage(e);
|
|
164
|
+
socket.onclose = (e) => this._handleClose(e);
|
|
165
|
+
socket.onerror = (e) => this._handleError(e);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Tear down completely — closes the socket AND unsubscribes from AppState. */
|
|
169
|
+
dispose(): void {
|
|
170
|
+
this.disconnect();
|
|
171
|
+
if (this._appStateSubscription) {
|
|
172
|
+
this._appStateSubscription.remove();
|
|
173
|
+
this._appStateSubscription = null;
|
|
174
|
+
}
|
|
175
|
+
this.removeAllListeners();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
disconnect(): void {
|
|
179
|
+
this._wantConnected = false;
|
|
180
|
+
if (!this.socket) return;
|
|
181
|
+
const socket = this.socket;
|
|
182
|
+
this._cleanupSocket();
|
|
183
|
+
try {
|
|
184
|
+
socket.close(1000, 'Client disconnected');
|
|
185
|
+
} catch (e) {
|
|
186
|
+
this._logger.warn('Error closing socket:', e);
|
|
187
|
+
}
|
|
188
|
+
this._status = 'disconnected';
|
|
189
|
+
this.emit('disconnected', { code: 1000, reason: 'Client disconnected' });
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async switchNetwork(target: SupernetType): Promise<SupernetType> {
|
|
193
|
+
return new Promise<SupernetType>((resolve) => {
|
|
194
|
+
this.once('changeNetwork', ({ network }) => {
|
|
195
|
+
this._supernetType = network;
|
|
196
|
+
resolve(network);
|
|
197
|
+
});
|
|
198
|
+
void this.send('changeNetwork', target);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async send(messageType: string, data: unknown): Promise<void> {
|
|
203
|
+
if (!this.socket || this._status !== 'connected') {
|
|
204
|
+
throw new Error(`Cannot send ${messageType}: socket not connected`);
|
|
205
|
+
}
|
|
206
|
+
const envelope = JSON.stringify({
|
|
207
|
+
type: messageType,
|
|
208
|
+
data: base64Encode(JSON.stringify(data))
|
|
209
|
+
});
|
|
210
|
+
this._logger.debug('WebSocket send:', messageType, data);
|
|
211
|
+
this.socket.send(envelope);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private _handleOpen() {
|
|
215
|
+
this._status = 'connected';
|
|
216
|
+
this._reconnectAttempts = 0;
|
|
217
|
+
this.emit('connected', { network: this._supernetType });
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private _handleClose(e: { code?: number; reason?: string }) {
|
|
221
|
+
const wasConnected = this._status === 'connected';
|
|
222
|
+
this._status = 'disconnected';
|
|
223
|
+
this._cleanupSocket();
|
|
224
|
+
this.emit('disconnected', { code: e.code, reason: e.reason });
|
|
225
|
+
if (this._wantConnected && wasConnected && e.code !== 1000) {
|
|
226
|
+
this._scheduleReconnect();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private _handleError(e: unknown) {
|
|
231
|
+
this._logger.error('WebSocket error:', e);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
private _scheduleReconnect() {
|
|
235
|
+
if (this._reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
236
|
+
this._logger.warn('WebSocket reconnect attempts exhausted');
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
this._reconnectAttempts++;
|
|
240
|
+
setTimeout(() => {
|
|
241
|
+
if (this._wantConnected) {
|
|
242
|
+
void this.connect();
|
|
243
|
+
}
|
|
244
|
+
}, RECONNECT_DELAY_MS);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private _cleanupSocket() {
|
|
248
|
+
if (!this.socket) return;
|
|
249
|
+
const s = this.socket;
|
|
250
|
+
s.onopen = null;
|
|
251
|
+
s.onmessage = null;
|
|
252
|
+
s.onclose = null;
|
|
253
|
+
s.onerror = null;
|
|
254
|
+
this.socket = null;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private _handleMessage(e: MessageEvent) {
|
|
258
|
+
Promise.resolve(typeof e.data === 'string' ? e.data : (e.data as Blob).text())
|
|
259
|
+
.then((str: string) => {
|
|
260
|
+
const envelope = JSON.parse(str) as { type: string; data?: string };
|
|
261
|
+
const payload: any = envelope.data ? JSON.parse(base64Decode(envelope.data)) : null;
|
|
262
|
+
this._logger.debug('WebSocket recv:', envelope.type, payload);
|
|
263
|
+
this._dispatch(envelope.type, payload);
|
|
264
|
+
})
|
|
265
|
+
.catch((err) => this._logger.error('Failed to parse WebSocket message:', err));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private _dispatch(type: string, payload: any) {
|
|
269
|
+
switch (type) {
|
|
270
|
+
case 'authenticated':
|
|
271
|
+
this.emit('authenticated', normalizeAuthenticated(payload as RawAuthenticated));
|
|
272
|
+
break;
|
|
273
|
+
case 'balanceUpdate':
|
|
274
|
+
this.emit('balanceUpdate', normalizeBalanceUpdate(payload as RawBalanceUpdate));
|
|
275
|
+
break;
|
|
276
|
+
case 'changeNetwork':
|
|
277
|
+
this.emit('changeNetwork', normalizeChangeNetwork(payload as RawChangeNetwork));
|
|
278
|
+
break;
|
|
279
|
+
case 'toastMessage':
|
|
280
|
+
this.emit('toastMessage', normalizeToastMessage(payload as RawToastMessage));
|
|
281
|
+
break;
|
|
282
|
+
case 'jobState': {
|
|
283
|
+
const parsed = normalizeJobState(payload as RawJobState);
|
|
284
|
+
if (parsed) this.emit(parsed.kind, parsed.event as any);
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
case 'jobProgress': {
|
|
288
|
+
const ev = normalizeJobProgress(payload as RawJobProgress);
|
|
289
|
+
if (ev) this.emit('jobProgress', ev);
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
case 'jobResult': {
|
|
293
|
+
const ev = normalizeJobResult(payload as RawJobResult);
|
|
294
|
+
if (ev) this.emit('jobResult', ev);
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
case 'jobError': {
|
|
298
|
+
const ev = normalizeJobError(payload as RawJobError);
|
|
299
|
+
if (ev) this.emit('jobError', ev);
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
case 'jobETA': {
|
|
303
|
+
const ev = normalizeJobETA(payload as RawJobETA);
|
|
304
|
+
if (ev) this.emit('jobETA', ev);
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
case 'artistCancelConfirmation': {
|
|
308
|
+
const ev = normalizeArtistCancelConfirmation(payload as RawArtistCancelConfirmation);
|
|
309
|
+
if (ev) this.emit('artistCancelConfirmation', ev);
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
case 'jobTokens': {
|
|
313
|
+
const ev = normalizeChatTokens(payload as RawJobTokens);
|
|
314
|
+
if (ev) this.emit('chatTokens', ev);
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
case 'llmJobResult': {
|
|
318
|
+
const ev = normalizeChatResult(payload as RawLLMJobResult);
|
|
319
|
+
if (ev) this.emit('chatResult', ev);
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
case 'llmJobError': {
|
|
323
|
+
const ev = normalizeChatError(payload as RawLLMJobError);
|
|
324
|
+
if (ev) this.emit('chatError', ev);
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
case 'swarmLLMModels': {
|
|
328
|
+
this.emit('swarmLLMModels', normalizeSwarmLLMModels(payload as RawSwarmLLMModels));
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
default:
|
|
332
|
+
this._logger.debug('Unhandled WebSocket message type:', type);
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function normalizeBaseUrl(url: string): string {
|
|
339
|
+
const u = new URL(url);
|
|
340
|
+
if (u.protocol === 'http:' || u.protocol === 'ws:') u.protocol = 'http:';
|
|
341
|
+
else u.protocol = 'https:';
|
|
342
|
+
return u.toString();
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export default WebSocketClient;
|