@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.
Files changed (262) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +411 -0
  3. package/dist/cjs/Account/index.d.ts +60 -0
  4. package/dist/cjs/Account/index.d.ts.map +1 -0
  5. package/dist/cjs/Account/index.js +188 -0
  6. package/dist/cjs/Account/index.js.map +1 -0
  7. package/dist/cjs/Account/types.d.ts +43 -0
  8. package/dist/cjs/Account/types.d.ts.map +1 -0
  9. package/dist/cjs/Account/types.js +18 -0
  10. package/dist/cjs/Account/types.js.map +1 -0
  11. package/dist/cjs/ApiClient/WebSocketClient/events.d.ts +139 -0
  12. package/dist/cjs/ApiClient/WebSocketClient/events.d.ts.map +1 -0
  13. package/dist/cjs/ApiClient/WebSocketClient/events.js +3 -0
  14. package/dist/cjs/ApiClient/WebSocketClient/events.js.map +1 -0
  15. package/dist/cjs/ApiClient/WebSocketClient/index.d.ts +45 -0
  16. package/dist/cjs/ApiClient/WebSocketClient/index.d.ts.map +1 -0
  17. package/dist/cjs/ApiClient/WebSocketClient/index.js +283 -0
  18. package/dist/cjs/ApiClient/WebSocketClient/index.js.map +1 -0
  19. package/dist/cjs/ApiClient/WebSocketClient/normalize.d.ts +45 -0
  20. package/dist/cjs/ApiClient/WebSocketClient/normalize.d.ts.map +1 -0
  21. package/dist/cjs/ApiClient/WebSocketClient/normalize.js +245 -0
  22. package/dist/cjs/ApiClient/WebSocketClient/normalize.js.map +1 -0
  23. package/dist/cjs/ApiClient/WebSocketClient/types.d.ts +9 -0
  24. package/dist/cjs/ApiClient/WebSocketClient/types.d.ts.map +1 -0
  25. package/dist/cjs/ApiClient/WebSocketClient/types.js +3 -0
  26. package/dist/cjs/ApiClient/WebSocketClient/types.js.map +1 -0
  27. package/dist/cjs/ApiClient/WebSocketClient/wireTypes.d.ts +161 -0
  28. package/dist/cjs/ApiClient/WebSocketClient/wireTypes.d.ts.map +1 -0
  29. package/dist/cjs/ApiClient/WebSocketClient/wireTypes.js +11 -0
  30. package/dist/cjs/ApiClient/WebSocketClient/wireTypes.js.map +1 -0
  31. package/dist/cjs/ApiClient/index.d.ts +60 -0
  32. package/dist/cjs/ApiClient/index.d.ts.map +1 -0
  33. package/dist/cjs/ApiClient/index.js +87 -0
  34. package/dist/cjs/ApiClient/index.js.map +1 -0
  35. package/dist/cjs/Chat/ChatStream.d.ts +42 -0
  36. package/dist/cjs/Chat/ChatStream.d.ts.map +1 -0
  37. package/dist/cjs/Chat/ChatStream.js +146 -0
  38. package/dist/cjs/Chat/ChatStream.js.map +1 -0
  39. package/dist/cjs/Chat/index.d.ts +61 -0
  40. package/dist/cjs/Chat/index.d.ts.map +1 -0
  41. package/dist/cjs/Chat/index.js +179 -0
  42. package/dist/cjs/Chat/index.js.map +1 -0
  43. package/dist/cjs/Chat/tools.d.ts +13 -0
  44. package/dist/cjs/Chat/tools.d.ts.map +1 -0
  45. package/dist/cjs/Chat/tools.js +22 -0
  46. package/dist/cjs/Chat/tools.js.map +1 -0
  47. package/dist/cjs/Chat/types.d.ts +153 -0
  48. package/dist/cjs/Chat/types.d.ts.map +1 -0
  49. package/dist/cjs/Chat/types.js +3 -0
  50. package/dist/cjs/Chat/types.js.map +1 -0
  51. package/dist/cjs/Projects/ControlNet.d.ts +30 -0
  52. package/dist/cjs/Projects/ControlNet.d.ts.map +1 -0
  53. package/dist/cjs/Projects/ControlNet.js +45 -0
  54. package/dist/cjs/Projects/ControlNet.js.map +1 -0
  55. package/dist/cjs/Projects/createJobRequestMessage.d.ts +11 -0
  56. package/dist/cjs/Projects/createJobRequestMessage.d.ts.map +1 -0
  57. package/dist/cjs/Projects/createJobRequestMessage.js +239 -0
  58. package/dist/cjs/Projects/createJobRequestMessage.js.map +1 -0
  59. package/dist/cjs/Projects/index.d.ts +96 -0
  60. package/dist/cjs/Projects/index.d.ts.map +1 -0
  61. package/dist/cjs/Projects/index.js +536 -0
  62. package/dist/cjs/Projects/index.js.map +1 -0
  63. package/dist/cjs/Projects/restNormalize.d.ts +60 -0
  64. package/dist/cjs/Projects/restNormalize.d.ts.map +1 -0
  65. package/dist/cjs/Projects/restNormalize.js +89 -0
  66. package/dist/cjs/Projects/restNormalize.js.map +1 -0
  67. package/dist/cjs/Projects/types.d.ts +233 -0
  68. package/dist/cjs/Projects/types.d.ts.map +1 -0
  69. package/dist/cjs/Projects/types.js +3 -0
  70. package/dist/cjs/Projects/types.js.map +1 -0
  71. package/dist/cjs/Projects/utils.d.ts +23 -0
  72. package/dist/cjs/Projects/utils.d.ts.map +1 -0
  73. package/dist/cjs/Projects/utils.js +65 -0
  74. package/dist/cjs/Projects/utils.js.map +1 -0
  75. package/dist/cjs/index.d.ts +63 -0
  76. package/dist/cjs/index.d.ts.map +1 -0
  77. package/dist/cjs/index.js +116 -0
  78. package/dist/cjs/index.js.map +1 -0
  79. package/dist/cjs/lib/AuthManager/ApiKeyAuthManager.d.ts +15 -0
  80. package/dist/cjs/lib/AuthManager/ApiKeyAuthManager.d.ts.map +1 -0
  81. package/dist/cjs/lib/AuthManager/ApiKeyAuthManager.js +47 -0
  82. package/dist/cjs/lib/AuthManager/ApiKeyAuthManager.js.map +1 -0
  83. package/dist/cjs/lib/AuthManager/AuthManagerBase.d.ts +23 -0
  84. package/dist/cjs/lib/AuthManager/AuthManagerBase.d.ts.map +1 -0
  85. package/dist/cjs/lib/AuthManager/AuthManagerBase.js +14 -0
  86. package/dist/cjs/lib/AuthManager/AuthManagerBase.js.map +1 -0
  87. package/dist/cjs/lib/AuthManager/AuthStorage.d.ts +11 -0
  88. package/dist/cjs/lib/AuthManager/AuthStorage.d.ts.map +1 -0
  89. package/dist/cjs/lib/AuthManager/AuthStorage.js +50 -0
  90. package/dist/cjs/lib/AuthManager/AuthStorage.js.map +1 -0
  91. package/dist/cjs/lib/AuthManager/TokenAuthManager.d.ts +35 -0
  92. package/dist/cjs/lib/AuthManager/TokenAuthManager.d.ts.map +1 -0
  93. package/dist/cjs/lib/AuthManager/TokenAuthManager.js +164 -0
  94. package/dist/cjs/lib/AuthManager/TokenAuthManager.js.map +1 -0
  95. package/dist/cjs/lib/AuthManager/index.d.ts +7 -0
  96. package/dist/cjs/lib/AuthManager/index.d.ts.map +1 -0
  97. package/dist/cjs/lib/AuthManager/index.js +13 -0
  98. package/dist/cjs/lib/AuthManager/index.js.map +1 -0
  99. package/dist/cjs/lib/Cache.d.ts +12 -0
  100. package/dist/cjs/lib/Cache.d.ts.map +1 -0
  101. package/dist/cjs/lib/Cache.js +36 -0
  102. package/dist/cjs/lib/Cache.js.map +1 -0
  103. package/dist/cjs/lib/DefaultLogger.d.ts +17 -0
  104. package/dist/cjs/lib/DefaultLogger.d.ts.map +1 -0
  105. package/dist/cjs/lib/DefaultLogger.js +36 -0
  106. package/dist/cjs/lib/DefaultLogger.js.map +1 -0
  107. package/dist/cjs/lib/RestClient.d.ts +18 -0
  108. package/dist/cjs/lib/RestClient.d.ts.map +1 -0
  109. package/dist/cjs/lib/RestClient.js +67 -0
  110. package/dist/cjs/lib/RestClient.js.map +1 -0
  111. package/dist/cjs/lib/TypedEventEmitter.d.ts +16 -0
  112. package/dist/cjs/lib/TypedEventEmitter.d.ts.map +1 -0
  113. package/dist/cjs/lib/TypedEventEmitter.js +46 -0
  114. package/dist/cjs/lib/TypedEventEmitter.js.map +1 -0
  115. package/dist/cjs/lib/base64.d.ts +3 -0
  116. package/dist/cjs/lib/base64.d.ts.map +1 -0
  117. package/dist/cjs/lib/base64.js +21 -0
  118. package/dist/cjs/lib/base64.js.map +1 -0
  119. package/dist/cjs/lib/getUUID.d.ts +12 -0
  120. package/dist/cjs/lib/getUUID.d.ts.map +1 -0
  121. package/dist/cjs/lib/getUUID.js +29 -0
  122. package/dist/cjs/lib/getUUID.js.map +1 -0
  123. package/dist/cjs/lib/mediaInput.d.ts +33 -0
  124. package/dist/cjs/lib/mediaInput.d.ts.map +1 -0
  125. package/dist/cjs/lib/mediaInput.js +32 -0
  126. package/dist/cjs/lib/mediaInput.js.map +1 -0
  127. package/dist/cjs/lib/utils.d.ts +10 -0
  128. package/dist/cjs/lib/utils.d.ts.map +1 -0
  129. package/dist/cjs/lib/utils.js +24 -0
  130. package/dist/cjs/lib/utils.js.map +1 -0
  131. package/dist/cjs/types/ErrorData.d.ts +7 -0
  132. package/dist/cjs/types/ErrorData.d.ts.map +1 -0
  133. package/dist/cjs/types/ErrorData.js +3 -0
  134. package/dist/cjs/types/ErrorData.js.map +1 -0
  135. package/dist/cjs/types/json.d.ts +6 -0
  136. package/dist/cjs/types/json.d.ts.map +1 -0
  137. package/dist/cjs/types/json.js +3 -0
  138. package/dist/cjs/types/json.js.map +1 -0
  139. package/dist/cjs/types/token.d.ts +2 -0
  140. package/dist/cjs/types/token.d.ts.map +1 -0
  141. package/dist/cjs/types/token.js +3 -0
  142. package/dist/cjs/types/token.js.map +1 -0
  143. package/dist/cjs/version.d.ts +2 -0
  144. package/dist/cjs/version.d.ts.map +1 -0
  145. package/dist/cjs/version.js +5 -0
  146. package/dist/cjs/version.js.map +1 -0
  147. package/dist/cjs/wallet.d.ts +59 -0
  148. package/dist/cjs/wallet.d.ts.map +1 -0
  149. package/dist/cjs/wallet.js +125 -0
  150. package/dist/cjs/wallet.js.map +1 -0
  151. package/dist/esm/Account/index.js +183 -0
  152. package/dist/esm/Account/index.js.map +1 -0
  153. package/dist/esm/Account/types.js +15 -0
  154. package/dist/esm/Account/types.js.map +1 -0
  155. package/dist/esm/ApiClient/WebSocketClient/events.js +2 -0
  156. package/dist/esm/ApiClient/WebSocketClient/events.js.map +1 -0
  157. package/dist/esm/ApiClient/WebSocketClient/index.js +278 -0
  158. package/dist/esm/ApiClient/WebSocketClient/index.js.map +1 -0
  159. package/dist/esm/ApiClient/WebSocketClient/normalize.js +229 -0
  160. package/dist/esm/ApiClient/WebSocketClient/normalize.js.map +1 -0
  161. package/dist/esm/ApiClient/WebSocketClient/types.js +2 -0
  162. package/dist/esm/ApiClient/WebSocketClient/types.js.map +1 -0
  163. package/dist/esm/ApiClient/WebSocketClient/wireTypes.js +10 -0
  164. package/dist/esm/ApiClient/WebSocketClient/wireTypes.js.map +1 -0
  165. package/dist/esm/ApiClient/index.js +80 -0
  166. package/dist/esm/ApiClient/index.js.map +1 -0
  167. package/dist/esm/Chat/ChatStream.js +144 -0
  168. package/dist/esm/Chat/ChatStream.js.map +1 -0
  169. package/dist/esm/Chat/index.js +174 -0
  170. package/dist/esm/Chat/index.js.map +1 -0
  171. package/dist/esm/Chat/tools.js +19 -0
  172. package/dist/esm/Chat/tools.js.map +1 -0
  173. package/dist/esm/Chat/types.js +2 -0
  174. package/dist/esm/Chat/types.js.map +1 -0
  175. package/dist/esm/Projects/ControlNet.js +41 -0
  176. package/dist/esm/Projects/ControlNet.js.map +1 -0
  177. package/dist/esm/Projects/createJobRequestMessage.js +236 -0
  178. package/dist/esm/Projects/createJobRequestMessage.js.map +1 -0
  179. package/dist/esm/Projects/index.js +531 -0
  180. package/dist/esm/Projects/index.js.map +1 -0
  181. package/dist/esm/Projects/restNormalize.js +86 -0
  182. package/dist/esm/Projects/restNormalize.js.map +1 -0
  183. package/dist/esm/Projects/types.js +2 -0
  184. package/dist/esm/Projects/types.js.map +1 -0
  185. package/dist/esm/Projects/utils.js +55 -0
  186. package/dist/esm/Projects/utils.js.map +1 -0
  187. package/dist/esm/index.js +72 -0
  188. package/dist/esm/index.js.map +1 -0
  189. package/dist/esm/lib/AuthManager/ApiKeyAuthManager.js +42 -0
  190. package/dist/esm/lib/AuthManager/ApiKeyAuthManager.js.map +1 -0
  191. package/dist/esm/lib/AuthManager/AuthManagerBase.js +9 -0
  192. package/dist/esm/lib/AuthManager/AuthManagerBase.js.map +1 -0
  193. package/dist/esm/lib/AuthManager/AuthStorage.js +13 -0
  194. package/dist/esm/lib/AuthManager/AuthStorage.js.map +1 -0
  195. package/dist/esm/lib/AuthManager/TokenAuthManager.js +159 -0
  196. package/dist/esm/lib/AuthManager/TokenAuthManager.js.map +1 -0
  197. package/dist/esm/lib/AuthManager/index.js +5 -0
  198. package/dist/esm/lib/AuthManager/index.js.map +1 -0
  199. package/dist/esm/lib/Cache.js +33 -0
  200. package/dist/esm/lib/Cache.js.map +1 -0
  201. package/dist/esm/lib/DefaultLogger.js +32 -0
  202. package/dist/esm/lib/DefaultLogger.js.map +1 -0
  203. package/dist/esm/lib/RestClient.js +62 -0
  204. package/dist/esm/lib/RestClient.js.map +1 -0
  205. package/dist/esm/lib/TypedEventEmitter.js +44 -0
  206. package/dist/esm/lib/TypedEventEmitter.js.map +1 -0
  207. package/dist/esm/lib/base64.js +17 -0
  208. package/dist/esm/lib/base64.js.map +1 -0
  209. package/dist/esm/lib/getUUID.js +26 -0
  210. package/dist/esm/lib/getUUID.js.map +1 -0
  211. package/dist/esm/lib/mediaInput.js +28 -0
  212. package/dist/esm/lib/mediaInput.js.map +1 -0
  213. package/dist/esm/lib/utils.js +19 -0
  214. package/dist/esm/lib/utils.js.map +1 -0
  215. package/dist/esm/types/ErrorData.js +2 -0
  216. package/dist/esm/types/ErrorData.js.map +1 -0
  217. package/dist/esm/types/json.js +2 -0
  218. package/dist/esm/types/json.js.map +1 -0
  219. package/dist/esm/types/token.js +2 -0
  220. package/dist/esm/types/token.js.map +1 -0
  221. package/dist/esm/version.js +2 -0
  222. package/dist/esm/version.js.map +1 -0
  223. package/dist/esm/wallet.js +117 -0
  224. package/dist/esm/wallet.js.map +1 -0
  225. package/package.json +92 -0
  226. package/src/Account/index.ts +214 -0
  227. package/src/Account/types.ts +61 -0
  228. package/src/ApiClient/WebSocketClient/events.ts +168 -0
  229. package/src/ApiClient/WebSocketClient/index.ts +345 -0
  230. package/src/ApiClient/WebSocketClient/normalize.ts +287 -0
  231. package/src/ApiClient/WebSocketClient/types.ts +10 -0
  232. package/src/ApiClient/WebSocketClient/wireTypes.ts +183 -0
  233. package/src/ApiClient/index.ts +147 -0
  234. package/src/Chat/ChatStream.ts +164 -0
  235. package/src/Chat/index.ts +224 -0
  236. package/src/Chat/tools.ts +23 -0
  237. package/src/Chat/types.ts +165 -0
  238. package/src/Projects/ControlNet.ts +84 -0
  239. package/src/Projects/createJobRequestMessage.ts +241 -0
  240. package/src/Projects/index.ts +608 -0
  241. package/src/Projects/restNormalize.ts +154 -0
  242. package/src/Projects/types.ts +266 -0
  243. package/src/Projects/utils.ts +60 -0
  244. package/src/index.ts +217 -0
  245. package/src/lib/AuthManager/ApiKeyAuthManager.ts +52 -0
  246. package/src/lib/AuthManager/AuthManagerBase.ts +35 -0
  247. package/src/lib/AuthManager/AuthStorage.ts +21 -0
  248. package/src/lib/AuthManager/TokenAuthManager.ts +179 -0
  249. package/src/lib/AuthManager/index.ts +8 -0
  250. package/src/lib/Cache.ts +45 -0
  251. package/src/lib/DefaultLogger.ts +47 -0
  252. package/src/lib/RestClient.ts +77 -0
  253. package/src/lib/TypedEventEmitter.ts +52 -0
  254. package/src/lib/base64.ts +17 -0
  255. package/src/lib/getUUID.ts +27 -0
  256. package/src/lib/mediaInput.ts +54 -0
  257. package/src/lib/utils.ts +21 -0
  258. package/src/types/ErrorData.ts +7 -0
  259. package/src/types/json.ts +5 -0
  260. package/src/types/token.ts +1 -0
  261. package/src/version.ts +1 -0
  262. package/src/wallet.ts +158 -0
@@ -0,0 +1,287 @@
1
+ /**
2
+ * The ONLY place where wire-level message shapes are translated into clean
3
+ * public types. Every quirk in the sogni-socket protocol gets masked here so
4
+ * the rest of the SDK and downstream apps never see them.
5
+ *
6
+ * Authoritative wire source:
7
+ * ../sogni-socket/controllers/jobsController.js
8
+ * ../sogni-socket/controllers/websocketsController.js
9
+ *
10
+ * Known quirks masked (catalog grows as later phases add events):
11
+ * - `jobID` on the wire is actually the PROJECT id (Phase 3)
12
+ * - `imgID` on the wire is actually the JOB id (Phase 3)
13
+ * - `error_message` is snake_case in an otherwise camelCase API (Phase 3)
14
+ * - `balanceUpdate` arrives in two shapes (v1 flat, v2 nested) — always
15
+ * normalized to v2 here.
16
+ * - `authenticated.tokens` similarly v1/v2 — normalized to v2.
17
+ */
18
+
19
+ import {
20
+ ArtistCancelConfirmationEvent,
21
+ AuthenticatedEvent,
22
+ BalanceUpdateEvent,
23
+ Balances,
24
+ ChangeNetworkEvent,
25
+ ChatErrorEvent,
26
+ ChatResultEvent,
27
+ ChatTokensEvent,
28
+ JobErrorEvent,
29
+ JobETAEvent,
30
+ JobInitiatingModelEvent,
31
+ JobLifecycleCompletedEvent,
32
+ JobProgressEvent,
33
+ JobResultEvent,
34
+ JobStartedEvent,
35
+ SwarmLLMModelsEvent,
36
+ ToastMessageEvent
37
+ } from './events';
38
+ import { LLMModelInfo } from '../../Chat/types';
39
+ import {
40
+ RawArtistCancelConfirmation,
41
+ RawAuthenticated,
42
+ RawBalanceUpdate,
43
+ RawBalanceV1Tokens,
44
+ RawBalanceV2Tokens,
45
+ RawChangeNetwork,
46
+ RawJobError,
47
+ RawJobETA,
48
+ RawJobProgress,
49
+ RawJobResult,
50
+ RawJobState,
51
+ RawJobTokens,
52
+ RawLLMJobError,
53
+ RawLLMJobResult,
54
+ RawSwarmLLMModels,
55
+ RawToastMessage
56
+ } from './wireTypes';
57
+ import { JobErrorReason } from '../../Projects/types';
58
+
59
+ function isV2Tokens(t: RawBalanceUpdate): t is RawBalanceV2Tokens {
60
+ return (
61
+ typeof t === 'object' && t !== null && 'sogni' in t && 'spark' in (t as RawBalanceV2Tokens)
62
+ );
63
+ }
64
+
65
+ function normalizeBalanceTokens(raw: RawBalanceUpdate): Balances {
66
+ if (isV2Tokens(raw)) {
67
+ return {
68
+ sogni: {
69
+ settled: String(raw.sogni.settled ?? '0'),
70
+ credit: String(raw.sogni.credit ?? '0'),
71
+ debit: String(raw.sogni.debit ?? '0'),
72
+ net: String(raw.sogni.net ?? '0')
73
+ },
74
+ spark: {
75
+ settled: String(raw.spark.settled ?? '0'),
76
+ credit: String(raw.spark.credit ?? '0'),
77
+ debit: String(raw.spark.debit ?? '0'),
78
+ net: String(raw.spark.net ?? '0'),
79
+ premiumCredit: String(raw.spark.premiumCredit ?? '0')
80
+ }
81
+ };
82
+ }
83
+ // v1 → synthesize v2 wrapper with empty spark
84
+ const v1 = raw as RawBalanceV1Tokens;
85
+ return {
86
+ sogni: {
87
+ settled: String(v1.settled ?? '0'),
88
+ credit: String(v1.credit ?? '0'),
89
+ debit: String(v1.debit ?? '0'),
90
+ net: String(v1.net ?? '0')
91
+ },
92
+ spark: {
93
+ settled: '0',
94
+ credit: '0',
95
+ debit: '0',
96
+ net: '0',
97
+ premiumCredit: '0'
98
+ }
99
+ };
100
+ }
101
+
102
+ export function normalizeAuthenticated(raw: RawAuthenticated): AuthenticatedEvent {
103
+ return {
104
+ username: raw.username,
105
+ walletAddress: raw.address,
106
+ balance: normalizeBalanceTokens(raw.tokens),
107
+ isMainnet: !!raw.isMainnet,
108
+ accountWasMigrated: !!raw.accountWasMigrated,
109
+ hasUnclaimedAirdrop: !!raw.hasUnclaimedAirdrop,
110
+ firstLoginAfterMigration: !!raw.firstLoginAfterMigration
111
+ };
112
+ }
113
+
114
+ export function normalizeBalanceUpdate(raw: RawBalanceUpdate): BalanceUpdateEvent {
115
+ return { balance: normalizeBalanceTokens(raw) };
116
+ }
117
+
118
+ export function normalizeChangeNetwork(raw: RawChangeNetwork): ChangeNetworkEvent {
119
+ return { network: raw.network };
120
+ }
121
+
122
+ export function normalizeToastMessage(raw: RawToastMessage): ToastMessageEvent {
123
+ return {
124
+ level: raw.type,
125
+ message: raw.message,
126
+ ...(raw.stickyID ? { stickyID: raw.stickyID } : {})
127
+ };
128
+ }
129
+
130
+ /* ============================================================================
131
+ * Project / job lifecycle normalizers.
132
+ * - wire `jobID` -> `projectId` (uppercased on both sides)
133
+ * - wire `imgID` -> `jobId`
134
+ * - wire `error_message` -> `errorMessage`
135
+ * - mixed casing on error reasons normalized to one spelling, with the raw
136
+ * code preserved in `rawCode` for forward compat
137
+ * ========================================================================== */
138
+
139
+ const upper = (s: string | undefined | null) => (s ? s.toUpperCase() : null);
140
+
141
+ export type NormalizedJobState =
142
+ | { kind: 'jobStarted'; event: JobStartedEvent }
143
+ | { kind: 'jobInitiatingModel'; event: JobInitiatingModelEvent }
144
+ | { kind: 'jobLifecycleCompleted'; event: JobLifecycleCompletedEvent };
145
+
146
+ /** Split the composite jobState message into distinct typed events. */
147
+ export function normalizeJobState(raw: RawJobState): NormalizedJobState | null {
148
+ const projectId = upper(raw.jobID);
149
+ if (!projectId) return null;
150
+ const jobId = upper(raw.imgID);
151
+ switch (raw.type) {
152
+ case 'jobStarted':
153
+ return {
154
+ kind: 'jobStarted',
155
+ event: { projectId, jobId, workerName: raw.workerName ?? null }
156
+ };
157
+ case 'initiatingModel':
158
+ return { kind: 'jobInitiatingModel', event: { projectId, jobId } };
159
+ case 'jobCompleted':
160
+ return { kind: 'jobLifecycleCompleted', event: { projectId, jobId } };
161
+ default:
162
+ return null;
163
+ }
164
+ }
165
+
166
+ export function normalizeJobProgress(raw: RawJobProgress): JobProgressEvent | null {
167
+ const projectId = upper(raw.jobID);
168
+ const jobId = upper(raw.imgID);
169
+ if (!projectId || !jobId) return null;
170
+ const stepCount = Math.max(0, raw.stepCount ?? 0);
171
+ const step = Math.max(0, raw.step ?? 0);
172
+ const progress = stepCount > 0 ? Math.min(1, step / stepCount) : 0;
173
+ return { projectId, jobId, progress, step, stepCount };
174
+ }
175
+
176
+ export function normalizeJobResult(raw: RawJobResult): JobResultEvent | null {
177
+ const projectId = upper(raw.jobID);
178
+ const jobId = upper(raw.imgID);
179
+ if (!projectId || !jobId) return null;
180
+ return {
181
+ projectId,
182
+ jobId,
183
+ seed: raw.lastSeed,
184
+ performedStepCount: raw.performedStepCount,
185
+ userCanceled: !!raw.userCanceled,
186
+ triggeredNSFWFilter: !!raw.triggeredNSFWFilter
187
+ };
188
+ }
189
+
190
+ const ERROR_REASON_MAP: Record<string, JobErrorReason> = {
191
+ serverRestarting: 'serverRestarting',
192
+ workerDisconnected: 'workerDisconnected',
193
+ jobTimedOut: 'jobTimedOut',
194
+ artistCanceled: 'artistCanceled',
195
+ workerCancelled: 'workerCanceled',
196
+ workerCanceled: 'workerCanceled',
197
+ sensitiveContent: 'sensitiveContent',
198
+ imgUploadFailure: 'imgUploadFailure',
199
+ imgDownloadFailure: 'imgDownloadFailure'
200
+ };
201
+
202
+ export function normalizeJobError(raw: RawJobError): JobErrorEvent | null {
203
+ const projectId = upper(raw.jobID);
204
+ if (!projectId) return null;
205
+ return {
206
+ projectId,
207
+ jobId: upper(raw.imgID),
208
+ reason: ERROR_REASON_MAP[raw.error] ?? 'unknown',
209
+ rawCode: raw.error,
210
+ message: raw.error_message,
211
+ source: raw.isFromWorker ? 'worker' : 'server'
212
+ };
213
+ }
214
+
215
+ export function normalizeJobETA(raw: RawJobETA): JobETAEvent | null {
216
+ const projectId = upper(raw.jobID);
217
+ const jobId = upper(raw.imgID);
218
+ if (!projectId || !jobId) return null;
219
+ return { projectId, jobId, etaSeconds: Number(raw.etaSeconds ?? 0) };
220
+ }
221
+
222
+ export function normalizeArtistCancelConfirmation(
223
+ raw: RawArtistCancelConfirmation
224
+ ): ArtistCancelConfirmationEvent | null {
225
+ const projectId = upper(raw.jobID);
226
+ if (!projectId) return null;
227
+ return {
228
+ projectId,
229
+ didCancel: !!raw.didCancel,
230
+ ...(raw.error_message ? { errorMessage: raw.error_message } : {})
231
+ };
232
+ }
233
+
234
+ /* === LLM (chat) ===
235
+ * Chat jobs have only one ID (the completion's jobID — no project/job hierarchy).
236
+ * We just rename to camelCase. */
237
+
238
+ export function normalizeChatTokens(raw: RawJobTokens): ChatTokensEvent | null {
239
+ const jobId = upper(raw.jobID);
240
+ if (!jobId) return null;
241
+ return {
242
+ jobId,
243
+ content: raw.content ?? '',
244
+ role: raw.role,
245
+ finishReason: raw.finishReason ?? null,
246
+ usage: raw.usage,
247
+ tool_calls: raw.tool_calls
248
+ };
249
+ }
250
+
251
+ export function normalizeChatResult(raw: RawLLMJobResult): ChatResultEvent | null {
252
+ const jobId = upper(raw.jobID);
253
+ if (!jobId) return null;
254
+ return {
255
+ jobId,
256
+ usage: raw.usage,
257
+ timeTaken: raw.timeTaken,
258
+ ...(raw.workerName ? { workerName: raw.workerName } : {})
259
+ };
260
+ }
261
+
262
+ export function normalizeChatError(raw: RawLLMJobError): ChatErrorEvent | null {
263
+ const jobId = upper(raw.jobID);
264
+ if (!jobId) return null;
265
+ return {
266
+ jobId,
267
+ rawCode: raw.error,
268
+ message: raw.error_message,
269
+ ...(raw.workerName ? { workerName: raw.workerName } : {})
270
+ };
271
+ }
272
+
273
+ export function normalizeSwarmLLMModels(raw: RawSwarmLLMModels): SwarmLLMModelsEvent {
274
+ const models: Record<string, LLMModelInfo> = {};
275
+ for (const [modelId, value] of Object.entries(raw || {})) {
276
+ if (typeof value === 'number') {
277
+ models[modelId] = { workers: value };
278
+ } else if (value && typeof value === 'object') {
279
+ models[modelId] = {
280
+ workers: value.workers ?? 0,
281
+ ...(value.displayName ? { displayName: value.displayName } : {}),
282
+ ...(value.contextLength ? { contextLength: value.contextLength } : {})
283
+ };
284
+ }
285
+ }
286
+ return { models };
287
+ }
@@ -0,0 +1,10 @@
1
+ export type SupernetType = 'fast' | 'relaxed';
2
+
3
+ export type ConnectionStatus = 'disconnected' | 'connecting' | 'connected';
4
+
5
+ export interface SocketAuthData {
6
+ /** Headers sent in the WebSocket upgrade request. */
7
+ headers?: Record<string, string>;
8
+ /** Query string parameters appended to the WebSocket URL. */
9
+ queryParams?: Record<string, string>;
10
+ }
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Wire-level message shapes as the sogni-socket server sends them.
3
+ * These are NOT exposed to consumers. They are translated into clean public
4
+ * types by `normalize.ts`.
5
+ *
6
+ * Authoritative source: ../sogni-socket/controllers/jobsController.js and
7
+ * ../sogni-socket/controllers/websocketsController.js.
8
+ */
9
+
10
+ /** Envelope wrapping all socket messages in both directions. */
11
+ export interface RawSocketEnvelope {
12
+ type: string;
13
+ /** base64-encoded JSON.stringify(payload) */
14
+ data: string;
15
+ }
16
+
17
+ /** `authenticated` event — sent right after the server upgrades a connection. */
18
+ export interface RawAuthenticated {
19
+ id: string;
20
+ clientType: string;
21
+ username: string;
22
+ address: string;
23
+ SID: number;
24
+ clientSID: number;
25
+ addressSID: number;
26
+ balanceVersion?: 1 | 2;
27
+ /** v1: BigNumber/string; v2: { sogni, spark } */
28
+ tokens: RawBalanceV1Tokens | RawBalanceV2Tokens;
29
+ activeProjects: string[];
30
+ unclaimedCompletedProjects: string[];
31
+ isMainnet: boolean;
32
+ accountWasMigrated: boolean;
33
+ hasUnclaimedAirdrop: boolean;
34
+ firstLoginAfterMigration: boolean;
35
+ }
36
+
37
+ export interface RawBalanceV1Tokens {
38
+ settled: string;
39
+ credit: string;
40
+ debit: string;
41
+ net: string;
42
+ }
43
+
44
+ export interface RawBalanceV2Tokens {
45
+ sogni: RawBalanceV1Tokens & { premiumCredit?: string };
46
+ spark: RawBalanceV1Tokens & { premiumCredit?: string };
47
+ }
48
+
49
+ /** `balanceUpdate` event — fired when the user's balance changes. */
50
+ export type RawBalanceUpdate = RawBalanceV1Tokens | RawBalanceV2Tokens;
51
+
52
+ /** `changeNetwork` event — confirms a network switch. */
53
+ export interface RawChangeNetwork {
54
+ network: 'fast' | 'relaxed';
55
+ }
56
+
57
+ /** `toastMessage` event — server-initiated UI message. */
58
+ export interface RawToastMessage {
59
+ type: 'info' | 'success' | 'warning' | 'error';
60
+ message: string;
61
+ autoClose?: number;
62
+ stickyID?: string;
63
+ }
64
+
65
+ /* ============================================================================
66
+ * Project / job lifecycle events. ALL of these use:
67
+ * - `jobID` (uppercase) to mean the PROJECT id
68
+ * - `imgID` (uppercase) to mean the JOB id (one image within the project)
69
+ * `normalize.ts` masks this so the rest of the SDK never sees the rename.
70
+ * ========================================================================== */
71
+
72
+ /** `jobState` event — composite. `type` field carries the actual sub-state. */
73
+ export interface RawJobState {
74
+ jobID: string;
75
+ imgID?: string;
76
+ type: 'jobStarted' | 'initiatingModel' | 'jobCompleted';
77
+ workerName?: string;
78
+ queuePosition?: number;
79
+ }
80
+
81
+ /** `jobProgress` event — fine-grained step/stepCount progress. */
82
+ export interface RawJobProgress {
83
+ jobID: string;
84
+ imgID: string;
85
+ step: number;
86
+ stepCount: number;
87
+ /** Optional preview image bytes — ignored in this SDK. */
88
+ currentImages?: unknown[];
89
+ }
90
+
91
+ /**
92
+ * `jobResult` event — terminal result for one job in a project.
93
+ * Note that `userCanceled` and `triggeredNSFWFilter` flags signal failure paths
94
+ * even though the message type is "result". Normalize splits these out.
95
+ */
96
+ export interface RawJobResult {
97
+ jobID: string;
98
+ imgID: string;
99
+ lastSeed: number;
100
+ userCanceled: boolean;
101
+ triggeredNSFWFilter: boolean;
102
+ performedStepCount: number;
103
+ interval?: number;
104
+ itsPerSecond?: number;
105
+ timings?: Record<string, number>;
106
+ }
107
+
108
+ /** `jobError` event. */
109
+ export interface RawJobError {
110
+ jobID: string;
111
+ imgID?: string;
112
+ error: string;
113
+ error_message: string;
114
+ isFromWorker: boolean;
115
+ }
116
+
117
+ /** `jobETA` event — server's running estimate of remaining seconds. */
118
+ export interface RawJobETA {
119
+ jobID: string;
120
+ imgID: string;
121
+ etaSeconds: number;
122
+ }
123
+
124
+ /** `artistCancelConfirmation` — sent after the artist requests a project cancel. */
125
+ export interface RawArtistCancelConfirmation {
126
+ jobID: string;
127
+ didCancel: boolean;
128
+ error_message?: string;
129
+ }
130
+
131
+ /* ============================================================================
132
+ * LLM (chat) events. Unlike image/video projects, chat jobs only have a single
133
+ * job ID — there's no project/job hierarchy. The wire `jobID` here is the
134
+ * completion identifier used to route streaming tokens back to the caller.
135
+ * ========================================================================== */
136
+
137
+ export interface RawToolCallDelta {
138
+ index: number;
139
+ id?: string;
140
+ type?: 'function';
141
+ function?: { name?: string; arguments?: string };
142
+ }
143
+
144
+ /** `jobTokens` — streaming chunk from an LLM completion. */
145
+ export interface RawJobTokens {
146
+ jobID: string;
147
+ content?: string;
148
+ role?: string;
149
+ finishReason?: string | null;
150
+ usage?: {
151
+ prompt_tokens: number;
152
+ completion_tokens: number;
153
+ total_tokens?: number;
154
+ };
155
+ tool_calls?: RawToolCallDelta[];
156
+ }
157
+
158
+ /** `llmJobResult` — terminal result for an LLM completion. */
159
+ export interface RawLLMJobResult {
160
+ jobID: string;
161
+ usage: {
162
+ prompt_tokens: number;
163
+ completion_tokens: number;
164
+ total_tokens?: number;
165
+ };
166
+ timeTaken: number;
167
+ workerName?: string;
168
+ cost?: unknown;
169
+ }
170
+
171
+ /** `llmJobError` — terminal error for an LLM completion. */
172
+ export interface RawLLMJobError {
173
+ jobID: string;
174
+ error: string;
175
+ error_message: string;
176
+ workerName?: string;
177
+ }
178
+
179
+ /** `swarmLLMModels` — available LLM models on the active network. */
180
+ export type RawSwarmLLMModels = Record<
181
+ string,
182
+ number | { workers: number; displayName?: string; contextLength?: number }
183
+ >;
@@ -0,0 +1,147 @@
1
+ import RestClient from '../lib/RestClient';
2
+ import TypedEventEmitter from '../lib/TypedEventEmitter';
3
+ import { JSONValue } from '../types/json';
4
+ import { Logger } from '../lib/DefaultLogger';
5
+ import { ApiKeyAuthManager, AuthManager, AuthStorage, TokenAuthManager } from '../lib/AuthManager';
6
+ import WebSocketClient from './WebSocketClient';
7
+ import { SupernetType } from './WebSocketClient/types';
8
+ import { ConnectedEvent, DisconnectedEvent } from './WebSocketClient/events';
9
+
10
+ export interface ApiResponse<D = JSONValue> {
11
+ status: 'success';
12
+ data: D;
13
+ }
14
+
15
+ export interface ApiErrorResponse {
16
+ status: 'error';
17
+ message: string;
18
+ errorCode: number;
19
+ }
20
+
21
+ export class ApiError extends Error {
22
+ status: number;
23
+ payload: ApiErrorResponse;
24
+ constructor(status: number, payload: ApiErrorResponse) {
25
+ super(payload.message);
26
+ this.status = status;
27
+ this.payload = payload;
28
+ }
29
+ }
30
+
31
+ interface ApiClientEvents {
32
+ authUpdated: boolean;
33
+ connected: ConnectedEvent;
34
+ disconnected: DisconnectedEvent;
35
+ }
36
+
37
+ export interface ApiClientOptions {
38
+ baseUrl: string;
39
+ socketUrl: string;
40
+ appId: string;
41
+ appSource?: string;
42
+ networkType: SupernetType;
43
+ logger: Logger;
44
+ authType: 'token' | 'apiKey';
45
+ authStorage?: AuthStorage;
46
+ disableSocket?: boolean;
47
+ }
48
+
49
+ class ApiClient extends TypedEventEmitter<ApiClientEvents> {
50
+ readonly appId: string;
51
+ readonly appSource?: string;
52
+ readonly logger: Logger;
53
+ private _rest: RestClient;
54
+ private _socketRest: RestClient;
55
+ private _auth: AuthManager;
56
+ private _socket: WebSocketClient;
57
+ private _disableSocket: boolean;
58
+
59
+ constructor({
60
+ baseUrl,
61
+ socketUrl,
62
+ appId,
63
+ appSource,
64
+ networkType,
65
+ authType,
66
+ logger,
67
+ authStorage,
68
+ disableSocket = false
69
+ }: ApiClientOptions) {
70
+ super();
71
+ this.appId = appId;
72
+ this.appSource = appSource?.trim() || undefined;
73
+ this.logger = logger;
74
+ this._disableSocket = disableSocket;
75
+ if (authType === 'apiKey') {
76
+ this._auth = new ApiKeyAuthManager(logger);
77
+ } else {
78
+ this._auth = new TokenAuthManager(baseUrl, logger, authStorage);
79
+ }
80
+ this._rest = new RestClient(baseUrl, this._auth, logger);
81
+ this._socketRest = new RestClient(normalizeHttpUrl(socketUrl), this._auth, logger);
82
+ this._socket = new WebSocketClient(
83
+ socketUrl,
84
+ this._auth,
85
+ appId,
86
+ networkType,
87
+ logger,
88
+ this.appSource
89
+ );
90
+ this._auth.on('updated', (isAuthenticated) => {
91
+ this.emit('authUpdated', isAuthenticated);
92
+ this._handleAuthUpdated(isAuthenticated);
93
+ });
94
+ this._socket.on('connected', (e) => this.emit('connected', e));
95
+ this._socket.on('disconnected', (e) => this.emit('disconnected', e));
96
+ }
97
+
98
+ get isAuthenticated(): boolean {
99
+ return this._auth.isAuthenticated;
100
+ }
101
+
102
+ get auth(): AuthManager {
103
+ return this._auth;
104
+ }
105
+
106
+ get rest(): RestClient {
107
+ return this._rest;
108
+ }
109
+
110
+ /** REST client bound to the socket server URL (used for model lists, image upload/download URLs, etc.). */
111
+ get socketRest(): RestClient {
112
+ return this._socketRest;
113
+ }
114
+
115
+ get socket(): WebSocketClient {
116
+ return this._socket;
117
+ }
118
+
119
+ get socketEnabled(): boolean {
120
+ return !this._disableSocket;
121
+ }
122
+
123
+ private _handleAuthUpdated(isAuthenticated: boolean) {
124
+ if (this._disableSocket) return;
125
+ if (isAuthenticated && !this._socket.isConnected) {
126
+ void this._socket.connect();
127
+ } else if (!isAuthenticated && this._socket.isConnected) {
128
+ this._socket.disconnect();
129
+ }
130
+ }
131
+
132
+ dispose() {
133
+ this._socket.dispose();
134
+ this._auth.removeAllListeners();
135
+ this.removeAllListeners();
136
+ this._auth.clear();
137
+ }
138
+ }
139
+
140
+ function normalizeHttpUrl(url: string): string {
141
+ const u = new URL(url);
142
+ if (u.protocol === 'http:' || u.protocol === 'ws:') u.protocol = 'http:';
143
+ else u.protocol = 'https:';
144
+ return u.toString();
145
+ }
146
+
147
+ export default ApiClient;