@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,154 @@
1
+ /**
2
+ * Translate RawProject / RawJob shapes returned by the /v1/projects/:id
3
+ * endpoint into our public Project / Job types.
4
+ *
5
+ * Same wire-quirk pattern as the socket normalizer: the server uses `imgID`
6
+ * to mean "job id" and its `status` enum uses different values from ours.
7
+ * Everything gets translated here so the rest of the SDK only sees clean
8
+ * public shapes.
9
+ */
10
+
11
+ import { Job, JobStatus, Project, ProjectParams, ProjectStatus } from './types';
12
+ import { SupernetType } from '../ApiClient/WebSocketClient/types';
13
+
14
+ /* === Wire shapes (kept faithful to /v1/projects/:id response) === */
15
+
16
+ export type RawProjectStatus =
17
+ | 'pending'
18
+ | 'active'
19
+ | 'assigned'
20
+ | 'progress'
21
+ | 'errored'
22
+ | 'completed'
23
+ | 'cancelled';
24
+
25
+ export type RawWorkerJobStatus =
26
+ | 'pending'
27
+ | 'jobStarted'
28
+ | 'initiatingModel'
29
+ | 'jobProgress'
30
+ | 'jobCompleted'
31
+ | 'jobError'
32
+ | 'cancelled';
33
+
34
+ export interface RawAccount {
35
+ id?: string;
36
+ address?: string;
37
+ name?: string;
38
+ username?: string;
39
+ }
40
+
41
+ export interface RawWorkerJob {
42
+ id: string;
43
+ imgID?: string;
44
+ worker?: RawAccount;
45
+ createTime?: number;
46
+ startTime?: number | null;
47
+ updateTime?: number;
48
+ endTime?: number;
49
+ status: RawWorkerJobStatus;
50
+ reason?: string;
51
+ performedSteps?: number;
52
+ triggeredNSFWFilter?: boolean;
53
+ seedUsed?: number;
54
+ resultUrl?: string | null;
55
+ }
56
+
57
+ export interface RawProject {
58
+ id: string;
59
+ imageCount: number;
60
+ stepCount?: number;
61
+ previewCount?: number;
62
+ createTime?: number;
63
+ updateTime?: number;
64
+ endTime?: number;
65
+ status: RawProjectStatus;
66
+ reason?: string;
67
+ network?: SupernetType;
68
+ workerJobs?: RawWorkerJob[];
69
+ completedWorkerJobs?: RawWorkerJob[];
70
+ model?: { id?: string };
71
+ }
72
+
73
+ /* === Mappers === */
74
+
75
+ const PROJECT_STATUS_MAP: Record<RawProjectStatus, ProjectStatus> = {
76
+ pending: 'pending',
77
+ active: 'queued',
78
+ assigned: 'queued',
79
+ progress: 'processing',
80
+ errored: 'failed',
81
+ completed: 'completed',
82
+ cancelled: 'canceled'
83
+ };
84
+
85
+ const JOB_STATUS_MAP: Record<RawWorkerJobStatus, JobStatus> = {
86
+ pending: 'pending',
87
+ jobStarted: 'processing',
88
+ initiatingModel: 'initiatingModel',
89
+ jobProgress: 'processing',
90
+ jobCompleted: 'completed',
91
+ jobError: 'failed',
92
+ cancelled: 'canceled'
93
+ };
94
+
95
+ function rawJobToJob(projectId: string, raw: RawWorkerJob): Job {
96
+ return {
97
+ // Wire quirk: imgID is the job ID. Fall back to raw.id for older payloads.
98
+ id: (raw.imgID ?? raw.id ?? '').toUpperCase(),
99
+ projectId,
100
+ status: JOB_STATUS_MAP[raw.status] ?? 'pending',
101
+ progress: raw.status === 'jobCompleted' ? 1 : 0,
102
+ step: raw.performedSteps ?? 0,
103
+ stepCount: 0,
104
+ seed: raw.seedUsed ?? null,
105
+ resultUrl: raw.resultUrl ?? null,
106
+ previewUrl: null,
107
+ isNSFW: !!raw.triggeredNSFWFilter,
108
+ workerName: raw.worker?.username ?? raw.worker?.name ?? null,
109
+ error: null
110
+ };
111
+ }
112
+
113
+ /**
114
+ * Build a Project snapshot from the REST GET /v1/projects/:id payload.
115
+ * `params` is best-effort reconstructed from the few fields the server
116
+ * returns — most generation-time settings (prompt, model options, etc.)
117
+ * are NOT in the REST response, so callers that need the full params
118
+ * should pass them in via `paramsOverride` (e.g., from local storage).
119
+ */
120
+ export function rawProjectToProject(raw: RawProject, paramsOverride?: ProjectParams): Project {
121
+ const projectId = raw.id.toUpperCase();
122
+ const allJobs: RawWorkerJob[] = [...(raw.workerJobs ?? []), ...(raw.completedWorkerJobs ?? [])];
123
+ const jobsById = new Map<string, Job>();
124
+ for (const rawJob of allJobs) {
125
+ const job = rawJobToJob(projectId, rawJob);
126
+ if (!jobsById.has(job.id) || job.status === 'completed') {
127
+ jobsById.set(job.id, job);
128
+ }
129
+ }
130
+ const jobs = Array.from(jobsById.values());
131
+ const status: ProjectStatus = PROJECT_STATUS_MAP[raw.status] ?? 'pending';
132
+ const resultUrls = jobs.map((j) => j.resultUrl).filter((u): u is string => !!u);
133
+
134
+ const params: ProjectParams = paramsOverride ?? {
135
+ type: 'image',
136
+ modelId: raw.model?.id ?? '',
137
+ positivePrompt: '',
138
+ numberOfMedia: raw.imageCount || 1,
139
+ ...(raw.network ? { network: raw.network } : {})
140
+ };
141
+
142
+ return {
143
+ id: projectId,
144
+ params,
145
+ status,
146
+ progress: jobs.length ? jobs.reduce((a, j) => a + j.progress, 0) / jobs.length : 0,
147
+ eta: null,
148
+ jobs,
149
+ resultUrls,
150
+ error: null,
151
+ createdAt: raw.createTime ?? Date.now(),
152
+ updatedAt: raw.updateTime ?? Date.now()
153
+ };
154
+ }
@@ -0,0 +1,266 @@
1
+ import { SupernetType } from '../ApiClient/WebSocketClient/types';
2
+ import { TokenType } from '../types/token';
3
+ import ErrorData from '../types/ErrorData';
4
+ import { MediaInput } from '../lib/mediaInput';
5
+ import { ControlNetParams } from './ControlNet';
6
+
7
+ export type { MediaInput };
8
+ export type { ControlNetMode, ControlNetName, ControlNetParams } from './ControlNet';
9
+
10
+ export type ProjectStatus =
11
+ | 'pending'
12
+ | 'queued'
13
+ | 'processing'
14
+ | 'completed'
15
+ | 'failed'
16
+ | 'canceled';
17
+
18
+ export type JobStatus =
19
+ | 'pending'
20
+ | 'initiatingModel'
21
+ | 'processing'
22
+ | 'completed'
23
+ | 'failed'
24
+ | 'canceled';
25
+
26
+ export type JobErrorReason =
27
+ | 'serverRestarting'
28
+ | 'workerDisconnected'
29
+ | 'jobTimedOut'
30
+ | 'artistCanceled'
31
+ | 'workerCanceled'
32
+ | 'sensitiveContent'
33
+ | 'imgUploadFailure'
34
+ | 'imgDownloadFailure'
35
+ | 'unknown';
36
+
37
+ export type ImageOutputFormat = 'png' | 'jpg' | 'webp';
38
+ export type VideoOutputFormat = 'mp4';
39
+ export type AudioOutputFormat = 'mp3' | 'flac' | 'wav';
40
+
41
+ /** Parameters for creating an image generation project. */
42
+ export interface ImageProjectParams {
43
+ /** Discriminator. Defaults to 'image' if omitted. */
44
+ type?: 'image';
45
+ /** Model ID from `sogni.projects.getAvailableModels()`. */
46
+ modelId: string;
47
+ /** Required. The generation prompt. */
48
+ positivePrompt: string;
49
+ /** Optional. Negative prompt; uses server default if omitted. */
50
+ negativePrompt?: string;
51
+ /** Optional. Style prompt; uses server default if omitted. */
52
+ stylePrompt?: string;
53
+ /** Number of images to generate. */
54
+ numberOfMedia: number;
55
+ /** Number of inference steps. Optimal value depends on the model. */
56
+ steps?: number;
57
+ /** Classifier-free guidance scale. Typical values 1-15. */
58
+ guidance?: number;
59
+ /** Optional seed (Uint32). Other images in the batch get random seeds. */
60
+ seed?: number;
61
+ /** Sampler ID. Model-specific; query via getAvailableModels metadata. */
62
+ sampler?: string;
63
+ /** Scheduler ID. Model-specific. */
64
+ scheduler?: string;
65
+ /** Size preset ID, or 'custom' to use explicit width/height. */
66
+ sizePreset?: 'custom' | string;
67
+ /** Output width in pixels. Only used when sizePreset === 'custom'. */
68
+ width?: number;
69
+ /** Output height in pixels. Only used when sizePreset === 'custom'. */
70
+ height?: number;
71
+ /** 'png' | 'jpg' | 'webp'. Defaults to 'png'. */
72
+ outputFormat?: ImageOutputFormat;
73
+ /** If true, skip NSFW filtering on output images. Default false. */
74
+ disableNSFWFilter?: boolean;
75
+ /** Override the client's current Supernet ('fast' or 'relaxed'). */
76
+ network?: SupernetType;
77
+ /** Number of preview images to stream during generation. */
78
+ numberOfPreviews?: number;
79
+ /** Token type ('sogni' | 'spark'). Default 'sogni'. */
80
+ tokenType?: TokenType;
81
+ /** Optional app source label for server-side attribution. */
82
+ appSource?: string;
83
+ /** LoRA IDs to apply. Each LoRA must be available in the model's config. */
84
+ loras?: string[];
85
+ /** LoRA strength values, 1:1 with `loras`. Typical 0.0-2.0; default 1.0. */
86
+ loraStrengths?: number[];
87
+
88
+ /**
89
+ * Optional starting image for img2img workflows. The SDK uploads the image
90
+ * to the server before sending the generation request.
91
+ *
92
+ * Pass either `{uri, type, name}` (as returned by expo-image-picker) or
93
+ * a `Uint8Array` of raw bytes.
94
+ */
95
+ startingImage?: MediaInput;
96
+ /**
97
+ * How strongly the starting image should influence the result. 0..1, default 0.5.
98
+ * Higher values preserve more of the source image.
99
+ */
100
+ startingImageStrength?: number;
101
+ /**
102
+ * Multiple reference images for multi-image-aware models (GPT Image 2, Flux.2,
103
+ * Qwen Image Edit, Flux Kontext). Max count depends on the model — see
104
+ * `getMaxContextImages(modelId)`.
105
+ */
106
+ contextImages?: MediaInput[];
107
+ /**
108
+ * Apply a ControlNet to constrain generation by the given control image.
109
+ * The control image is uploaded before the generation request.
110
+ */
111
+ controlNet?: ControlNetParams;
112
+ }
113
+
114
+ /**
115
+ * Parameters for creating a video generation project.
116
+ *
117
+ * Two model families with different FPS / frame behavior:
118
+ * - **WAN 2.2** (`wan_v2.2-*`): always generates at 16 fps internally. The
119
+ * `fps` value (16 or 32) only controls post-render FILM interpolation.
120
+ * Frame count is `duration * 16 + 1` regardless of fps.
121
+ * - **LTX-2.3** (`ltx2-*`, `ltx23-*`): generates at the requested fps directly.
122
+ * Frame count is `duration * fps + 1`, snapped to the pattern `1 + n*8`.
123
+ *
124
+ * The SDK computes `frames` from `duration` + `fps` automatically using
125
+ * `calculateVideoFrames(modelId, duration, fps)`. You can override by passing
126
+ * `frames` directly.
127
+ */
128
+ export interface VideoProjectParams {
129
+ type: 'video';
130
+ /** Video model ID. Must be a `wan_v2.2-*` or `ltx2-*` / `ltx23-*` model. */
131
+ modelId: string;
132
+ positivePrompt: string;
133
+ negativePrompt?: string;
134
+ stylePrompt?: string;
135
+ /** Number of videos to generate. */
136
+ numberOfMedia: number;
137
+ /**
138
+ * Duration in seconds. WAN: 1-10s typical. LTX-2.3: 4-20s typical.
139
+ * SDK derives frames from this — only pass `frames` directly if you need
140
+ * fine-grained control.
141
+ */
142
+ duration?: number;
143
+ /**
144
+ * Frames per second. WAN: 16 or 32 (32 = post-render interpolation).
145
+ * LTX-2.3: 1-60, default 24.
146
+ */
147
+ fps?: number;
148
+ /**
149
+ * Explicit frame count. Overrides duration-derived calculation. Use this
150
+ * only if you need exact frame counts; the SDK does the math otherwise.
151
+ */
152
+ frames?: number;
153
+ steps?: number;
154
+ guidance?: number;
155
+ seed?: number;
156
+ sampler?: string;
157
+ scheduler?: string;
158
+ width?: number;
159
+ height?: number;
160
+ /** Shift parameter (model-sampler). Affects denoise distribution. */
161
+ shift?: number;
162
+ outputFormat?: VideoOutputFormat;
163
+ disableNSFWFilter?: boolean;
164
+ network?: SupernetType;
165
+ tokenType?: TokenType;
166
+ appSource?: string;
167
+ loras?: string[];
168
+ loraStrengths?: number[];
169
+ /** First-frame image (img2video). */
170
+ referenceImage?: MediaInput;
171
+ /** Last-frame image for keyframe interpolation (LTX-2.3). */
172
+ referenceImageEnd?: MediaInput;
173
+ /** Reference audio for s2v workflows. */
174
+ referenceAudio?: MediaInput;
175
+ /** Reference video for v2v workflows. */
176
+ referenceVideo?: MediaInput;
177
+ /** LTX-2.3 first-frame strength when both referenceImage and referenceImageEnd are given. */
178
+ firstFrameStrength?: number;
179
+ /** LTX-2.3 last-frame strength when both referenceImage and referenceImageEnd are given. */
180
+ lastFrameStrength?: number;
181
+ }
182
+
183
+ /** Parameters for creating an audio generation project (ACE-Step 1.5 models). */
184
+ export interface AudioProjectParams {
185
+ type: 'audio';
186
+ /** Audio model ID, e.g. 'ace_step_1.5_turbo'. */
187
+ modelId: string;
188
+ positivePrompt: string;
189
+ negativePrompt?: string;
190
+ /** Number of audio files to generate. */
191
+ numberOfMedia: number;
192
+ /** Duration in seconds. Typical range 10-600. */
193
+ duration?: number;
194
+ /** Beats per minute, 30-300. */
195
+ bpm?: number;
196
+ /** Time signature: '2', '3', '4', or '6'. */
197
+ timesignature?: string;
198
+ /** ISO language code for lyrics. */
199
+ language?: string;
200
+ /** Lyrics. Omit for instrumental. */
201
+ lyrics?: string;
202
+ /** Musical key, e.g. 'C major' or 'A minor'. */
203
+ keyscale?: string;
204
+ /** Enable AI composer mode (higher quality). Default true. */
205
+ composerMode?: boolean;
206
+ /** How closely the composer follows the prompt (0-10, default 2.0). */
207
+ promptStrength?: number;
208
+ /** Composition variation / temperature (0-2, default 0.85). */
209
+ creativity?: number;
210
+ /** Sampler shift (1-6, default 3 for turbo). */
211
+ shift?: number;
212
+ steps?: number;
213
+ guidance?: number;
214
+ seed?: number;
215
+ sampler?: string;
216
+ scheduler?: string;
217
+ outputFormat?: AudioOutputFormat;
218
+ network?: SupernetType;
219
+ tokenType?: TokenType;
220
+ appSource?: string;
221
+ }
222
+
223
+ export type ProjectParams = ImageProjectParams | VideoProjectParams | AudioProjectParams;
224
+
225
+ export interface Job {
226
+ id: string;
227
+ projectId: string;
228
+ status: JobStatus;
229
+ /** 0..1 */
230
+ progress: number;
231
+ step: number;
232
+ stepCount: number;
233
+ /** Set on completed jobs. */
234
+ seed: number | null;
235
+ /** Populated by waitForCompletion() or explicit fetchResultUrl(). */
236
+ resultUrl: string | null;
237
+ /** Server-provided preview URL (if any). */
238
+ previewUrl: string | null;
239
+ /** True if the result was withheld by the NSFW filter. */
240
+ isNSFW: boolean;
241
+ workerName: string | null;
242
+ error: ErrorData | null;
243
+ }
244
+
245
+ export interface Project {
246
+ id: string;
247
+ params: ProjectParams;
248
+ status: ProjectStatus;
249
+ /** 0..1 — average of all jobs' progress. */
250
+ progress: number;
251
+ /** Estimated seconds until completion (most recent value from server). */
252
+ eta: number | null;
253
+ jobs: Job[];
254
+ /** Populated as jobs complete and waitForCompletion fetches URLs. */
255
+ resultUrls: string[];
256
+ error: ErrorData | null;
257
+ createdAt: number;
258
+ updatedAt: number;
259
+ }
260
+
261
+ export interface AvailableModel {
262
+ id: string;
263
+ name: string;
264
+ workerCount: number;
265
+ media: 'image' | 'video' | 'audio';
266
+ }
@@ -0,0 +1,60 @@
1
+ const COMFY_MODEL_PREFIXES = ['z_image_', 'qwen_image_', 'flux2_', 'wan_', 'ace_step'];
2
+
3
+ export function isComfyModel(modelId: string): boolean {
4
+ return COMFY_MODEL_PREFIXES.some((p) => modelId.startsWith(p));
5
+ }
6
+
7
+ export function isVideoModel(modelId: string): boolean {
8
+ return isWanModel(modelId) || isLtx2Model(modelId) || isSeedanceModel(modelId);
9
+ }
10
+
11
+ export function isWanModel(modelId: string): boolean {
12
+ return modelId.startsWith('wan_v2.2-') || modelId.startsWith('wan_');
13
+ }
14
+
15
+ export function isLtx2Model(modelId: string): boolean {
16
+ return modelId.startsWith('ltx2-') || modelId.startsWith('ltx23-');
17
+ }
18
+
19
+ export function isSeedanceModel(modelId: string): boolean {
20
+ return modelId.startsWith('seedance-2-0');
21
+ }
22
+
23
+ export function isAudioModel(modelId: string): boolean {
24
+ return modelId.startsWith('ace_step_');
25
+ }
26
+
27
+ const LTX2_FRAME_STEP = 8;
28
+
29
+ /**
30
+ * Compute the actual frame count to request from the server for a given
31
+ * model, duration, and fps.
32
+ *
33
+ * - **WAN 2.2**: always uses 16 fps internally regardless of the `fps` param,
34
+ * so frames = round(duration * 16) + 1.
35
+ * - **LTX-2.3**: uses `fps` directly, then snaps the frame count to the
36
+ * pattern `1 + n*8` required by the model architecture.
37
+ * - **Seedance / other video**: uses `fps` directly.
38
+ *
39
+ * Returns the recommended frame count; the SDK passes this through to the
40
+ * server as `frames` on the keyframe payload.
41
+ */
42
+ export function calculateVideoFrames(modelId: string, duration: number, fps: number): number {
43
+ if (isWanModel(modelId)) {
44
+ return Math.round(duration * 16) + 1;
45
+ }
46
+ let frames = Math.round(duration * fps) + 1;
47
+ if (isLtx2Model(modelId)) {
48
+ const n = Math.round((frames - 1) / LTX2_FRAME_STEP);
49
+ frames = n * LTX2_FRAME_STEP + 1;
50
+ }
51
+ return frames;
52
+ }
53
+
54
+ /** Approximate per-model maximum duration in seconds. */
55
+ export function getMaxVideoDuration(modelId: string): number {
56
+ if (isWanModel(modelId)) return 10;
57
+ if (isLtx2Model(modelId)) return 20;
58
+ if (isSeedanceModel(modelId)) return 15;
59
+ return 10;
60
+ }
package/src/index.ts ADDED
@@ -0,0 +1,217 @@
1
+ import AccountApi from './Account';
2
+ import { AccountSnapshot, Balances, LoginData, MeData, SignupParams } from './Account/types';
3
+ import ChatApi from './Chat';
4
+ import ChatStream from './Chat/ChatStream';
5
+ import { parseToolCallArguments } from './Chat/tools';
6
+ import {
7
+ ChatCompletionChunk,
8
+ ChatCompletionParams,
9
+ ChatCompletionResult,
10
+ ChatMessage,
11
+ ContentPart,
12
+ ImageUrlContentPart,
13
+ LLMModelInfo,
14
+ TextContentPart,
15
+ TokenUsage,
16
+ ToolCall,
17
+ ToolCallDelta,
18
+ ToolChoice,
19
+ ToolDefinition,
20
+ ToolRound
21
+ } from './Chat/types';
22
+ import ApiClient, { ApiError, ApiErrorResponse, ApiResponse } from './ApiClient';
23
+ import { SupernetType } from './ApiClient/WebSocketClient/types';
24
+ import {
25
+ AuthenticatedEvent,
26
+ BalanceUpdateEvent,
27
+ ChangeNetworkEvent,
28
+ ConnectedEvent,
29
+ DisconnectedEvent,
30
+ ToastMessageEvent
31
+ } from './ApiClient/WebSocketClient/events';
32
+ import ProjectsApi from './Projects';
33
+ import {
34
+ AudioOutputFormat,
35
+ AudioProjectParams,
36
+ AvailableModel,
37
+ ControlNetMode,
38
+ ControlNetName,
39
+ ControlNetParams,
40
+ ImageOutputFormat,
41
+ ImageProjectParams,
42
+ Job,
43
+ JobErrorReason,
44
+ JobStatus,
45
+ MediaInput,
46
+ Project,
47
+ ProjectParams,
48
+ ProjectStatus,
49
+ VideoOutputFormat,
50
+ VideoProjectParams
51
+ } from './Projects/types';
52
+ import { DefaultLogger, Logger, LogLevel } from './lib/DefaultLogger';
53
+ import { ApiKeyAuthManager, AuthStorage, TokenAuthData, TokenAuthManager } from './lib/AuthManager';
54
+ import ErrorData from './types/ErrorData';
55
+ import { TokenType } from './types/token';
56
+ import { LIB_VERSION } from './version';
57
+
58
+ export type {
59
+ AccountSnapshot,
60
+ ApiErrorResponse,
61
+ ApiResponse,
62
+ AudioOutputFormat,
63
+ AudioProjectParams,
64
+ AuthenticatedEvent,
65
+ AuthStorage,
66
+ AvailableModel,
67
+ Balances,
68
+ BalanceUpdateEvent,
69
+ ChangeNetworkEvent,
70
+ ChatCompletionChunk,
71
+ ChatCompletionParams,
72
+ ChatCompletionResult,
73
+ ChatMessage,
74
+ ConnectedEvent,
75
+ ContentPart,
76
+ ControlNetMode,
77
+ ControlNetName,
78
+ ControlNetParams,
79
+ DisconnectedEvent,
80
+ ErrorData,
81
+ ImageOutputFormat,
82
+ ImageProjectParams,
83
+ ImageUrlContentPart,
84
+ Job,
85
+ JobErrorReason,
86
+ JobStatus,
87
+ LLMModelInfo,
88
+ LoginData,
89
+ Logger,
90
+ LogLevel,
91
+ MediaInput,
92
+ MeData,
93
+ SignupParams,
94
+ Project,
95
+ ProjectParams,
96
+ ProjectStatus,
97
+ SupernetType,
98
+ TextContentPart,
99
+ ToastMessageEvent,
100
+ TokenAuthData,
101
+ TokenType,
102
+ TokenUsage,
103
+ ToolCall,
104
+ ToolCallDelta,
105
+ ToolChoice,
106
+ ToolDefinition,
107
+ ToolRound,
108
+ VideoOutputFormat,
109
+ VideoProjectParams
110
+ };
111
+ export { ApiError, ApiKeyAuthManager, ChatStream, LIB_VERSION, parseToolCallArguments };
112
+
113
+ export interface SogniClientConfig {
114
+ /** Unique application ID. Multiple connections with the same ID will be rejected by the server. */
115
+ appId: string;
116
+ /** Optional source label for server-side attribution. */
117
+ appSource?: string;
118
+ /** Override the default REST API endpoint. Internal use. */
119
+ restEndpoint?: string;
120
+ /** Override the default WebSocket endpoint. Internal use. */
121
+ socketEndpoint?: string;
122
+ /** Which Supernet to connect to. Defaults to 'fast'. */
123
+ network?: SupernetType;
124
+ /** Connect to testnet instead of mainnet. */
125
+ testnet?: boolean;
126
+ /** API key for authentication. When provided, the client uses API key auth. */
127
+ apiKey?: string;
128
+ /** Authentication type. Defaults to 'token'. Forced to 'apiKey' when apiKey is provided. */
129
+ authType?: 'token' | 'apiKey';
130
+ /** Logger instance. Defaults to a console-backed logger at logLevel. */
131
+ logger?: Logger;
132
+ /** Log level for the default logger. Ignored if a custom logger is provided. */
133
+ logLevel?: LogLevel;
134
+ /** Custom storage adapter for token persistence. Defaults to expo-secure-store. */
135
+ authStorage?: AuthStorage;
136
+ /** Disable the WebSocket connection. Most APIs will not work without it. */
137
+ disableSocket?: boolean;
138
+ }
139
+
140
+ function assertCryptoPolyfill(): void {
141
+ if (
142
+ typeof globalThis.crypto === 'undefined' ||
143
+ typeof globalThis.crypto.getRandomValues !== 'function'
144
+ ) {
145
+ throw new Error(
146
+ "@sogni-ai/expo-client requires crypto.getRandomValues. At your app entry point (e.g. app/_layout.tsx) add:\n import { polyfillWebCrypto } from 'expo-standard-web-crypto';\n polyfillWebCrypto();\nSee README for details."
147
+ );
148
+ }
149
+ }
150
+
151
+ export class SogniClient {
152
+ apiClient: ApiClient;
153
+ account: AccountApi;
154
+ projects: ProjectsApi;
155
+ chat: ChatApi;
156
+
157
+ private constructor(client: ApiClient, options: { testnet?: boolean } = {}) {
158
+ this.apiClient = client;
159
+ this.account = new AccountApi(client, { testnet: options.testnet });
160
+ this.projects = new ProjectsApi(client);
161
+ this.chat = new ChatApi(client);
162
+ }
163
+
164
+ get isAuthenticated(): boolean {
165
+ return this.apiClient.isAuthenticated;
166
+ }
167
+
168
+ /**
169
+ * For token-based auth, restore a session from refresh+access tokens.
170
+ * Typically called once at app startup; the SDK also auto-restores from
171
+ * secure storage in `create()`, so this is only needed when migrating
172
+ * tokens from another source.
173
+ */
174
+ async setTokens(tokens: TokenAuthData): Promise<void> {
175
+ const auth = this.apiClient.auth;
176
+ if (!(auth instanceof TokenAuthManager)) {
177
+ throw new Error('setTokens can only be used with token authentication');
178
+ }
179
+ await auth.authenticate(tokens);
180
+ }
181
+
182
+ /** Disconnect and tear down resources. Instance should not be reused after dispose(). */
183
+ dispose() {
184
+ this.apiClient.dispose();
185
+ }
186
+
187
+ static async create(config: SogniClientConfig): Promise<SogniClient> {
188
+ assertCryptoPolyfill();
189
+
190
+ const restEndpoint = config.restEndpoint || 'https://api.sogni.ai';
191
+ const socketEndpoint = config.socketEndpoint || 'wss://socket.sogni.ai';
192
+ const network: SupernetType = config.network || 'fast';
193
+ const logger = config.logger || new DefaultLogger(config.logLevel || 'warn');
194
+ const authType: 'token' | 'apiKey' = config.apiKey ? 'apiKey' : config.authType || 'token';
195
+
196
+ const apiClient = new ApiClient({
197
+ baseUrl: restEndpoint,
198
+ socketUrl: socketEndpoint,
199
+ appId: config.appId,
200
+ appSource: config.appSource,
201
+ networkType: network,
202
+ authType,
203
+ logger,
204
+ authStorage: config.authStorage,
205
+ disableSocket: config.disableSocket
206
+ });
207
+
208
+ if (config.apiKey) {
209
+ const auth = apiClient.auth as ApiKeyAuthManager;
210
+ await auth.authenticate(config.apiKey);
211
+ } else if (apiClient.auth instanceof TokenAuthManager) {
212
+ await apiClient.auth.restore();
213
+ }
214
+
215
+ return new SogniClient(apiClient, { testnet: config.testnet });
216
+ }
217
+ }