@xmaxai/sdk 1.0.0 → 1.0.1

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.
@@ -1,2 +1,2 @@
1
- export { D as DragTrackController, a as DragTrackControllerOptions, R as RealtimeConnectOptions, b as RealtimeInitialState, c as RealtimeModel, d as RealtimePrewarmHandle, e as RealtimePromptState, f as RealtimeRestartOptions, g as RealtimeSession, h as RealtimeSetImageOptions, i as RealtimeSetInput, j as RealtimeSetModeOptions, k as RemoteViewHost, X as XmaxClient, l as XmaxClientFiles, m as XmaxClientOptions, n as XmaxRealtimeSession, o as createDragTrackController, q as createRemoteViewHost, r as createXmaxClient, s as getContentRect, t as mapTargetPointToCanvas, u as mapViewportPointToCoordinateSpace, v as models, w as observeDragSurfaceVideoSync, y as syncDragSurfaceToVideo } from '../index-BEgtCLkJ.cjs';
1
+ export { D as DragTrackController, a as DragTrackControllerOptions, R as RealtimeConnectOptions, b as RealtimeInitialState, c as RealtimeModel, d as RealtimePrewarmHandle, e as RealtimePromptState, f as RealtimeRestartOptions, g as RealtimeSession, h as RealtimeSetImageOptions, i as RealtimeSetInput, j as RealtimeSetModeOptions, k as RemoteViewHost, X as XmaxClient, l as XmaxClientFiles, m as XmaxClientOptions, n as XmaxRealtimeSession, o as createDragTrackController, q as createRemoteViewHost, r as createXmaxClient, s as getContentRect, t as mapTargetPointToCanvas, u as mapViewportPointToCoordinateSpace, v as models, w as observeDragSurfaceVideoSync, y as syncDragSurfaceToVideo } from '../index-Dg1ElHAj.cjs';
2
2
  import '../rtc-manager-gYDkADGw.cjs';
@@ -1,2 +1,2 @@
1
- export { D as DragTrackController, a as DragTrackControllerOptions, R as RealtimeConnectOptions, b as RealtimeInitialState, c as RealtimeModel, d as RealtimePrewarmHandle, e as RealtimePromptState, f as RealtimeRestartOptions, g as RealtimeSession, h as RealtimeSetImageOptions, i as RealtimeSetInput, j as RealtimeSetModeOptions, k as RemoteViewHost, X as XmaxClient, l as XmaxClientFiles, m as XmaxClientOptions, n as XmaxRealtimeSession, o as createDragTrackController, q as createRemoteViewHost, r as createXmaxClient, s as getContentRect, t as mapTargetPointToCanvas, u as mapViewportPointToCoordinateSpace, v as models, w as observeDragSurfaceVideoSync, y as syncDragSurfaceToVideo } from '../index-D9wwNTfP.js';
1
+ export { D as DragTrackController, a as DragTrackControllerOptions, R as RealtimeConnectOptions, b as RealtimeInitialState, c as RealtimeModel, d as RealtimePrewarmHandle, e as RealtimePromptState, f as RealtimeRestartOptions, g as RealtimeSession, h as RealtimeSetImageOptions, i as RealtimeSetInput, j as RealtimeSetModeOptions, k as RemoteViewHost, X as XmaxClient, l as XmaxClientFiles, m as XmaxClientOptions, n as XmaxRealtimeSession, o as createDragTrackController, q as createRemoteViewHost, r as createXmaxClient, s as getContentRect, t as mapTargetPointToCanvas, u as mapViewportPointToCoordinateSpace, v as models, w as observeDragSurfaceVideoSync, y as syncDragSurfaceToVideo } from '../index-Cw8C8LbO.js';
2
2
  import '../rtc-manager-gYDkADGw.js';
@@ -1,5 +1,5 @@
1
- export { RealtimePrewarmHandle, RealtimeSession, createRemoteViewHost, createXmaxClient, observeDragSurfaceVideoSync, syncDragSurfaceToVideo } from '../chunk-7X7QCO3O.js';
2
- export { createDragTrackController, getContentRect, mapTargetPointToCanvas, mapViewportPointToCoordinateSpace, models } from '../chunk-M5QA6LWS.js';
3
- import '../chunk-PLU2YVAS.js';
1
+ export { RealtimePrewarmHandle, RealtimeSession, createRemoteViewHost, createXmaxClient, observeDragSurfaceVideoSync, syncDragSurfaceToVideo } from '../chunk-VLJZ56PT.js';
2
+ export { createDragTrackController, getContentRect, mapTargetPointToCanvas, mapViewportPointToCoordinateSpace, models } from '../chunk-V4NR6CPP.js';
3
+ import '../chunk-LCPC56BK.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
@@ -91,8 +91,13 @@ type RealtimeInitialState = {
91
91
  autoStart?: boolean;
92
92
  /** @internal Business model label in RTC start params; optional — SDK uses a default when omitted. */
93
93
  model?: string;
94
- /** MoX instant — static image generation that follows drag tracks; sent as `static_generate`. */
94
+ /** MoX instant — when `true`, sent as `static_generate` on connect start only (never cached). */
95
95
  staticGenerate?: boolean;
96
+ /**
97
+ * MoX instant — uploaded source still URL (COS). Sent as `static_image_path` on connect
98
+ * start only (never cached). Local RTC publish is still used for preview / room compatibility.
99
+ */
100
+ staticImagePath?: string;
96
101
  };
97
102
  type RealtimeConnectOptions = {
98
103
  model: RealtimeModel;
@@ -126,8 +131,18 @@ type RealtimeRestartOptions = {
126
131
  /** @internal Optional business model label; SDK uses a default when omitted. */
127
132
  model?: string;
128
133
  size?: [number, number];
129
- /** MoX instant — static image generation that follows drag tracks; sent as `static_generate`. */
134
+ /**
135
+ * MoX instant — when `true`, sent as `static_generate` on this start only (never cached).
136
+ * Omit on non-Instant starts.
137
+ */
130
138
  staticGenerate?: boolean;
139
+ /**
140
+ * MoX instant — COS URL sent as `static_image_path` on this start only (never cached).
141
+ * Omit on non-Instant starts.
142
+ */
143
+ staticImagePath?: string;
144
+ /** Keep the last rendered remote frame visible while waiting for the next start output. */
145
+ preserveRemoteOutput?: boolean;
131
146
  };
132
147
  /** @deprecated Use {@link RealtimeRestartOptions} */
133
148
  type RealtimeSetModeOptions = RealtimeRestartOptions;
@@ -207,7 +222,6 @@ declare class RealtimeSession implements XmaxRealtimeSession {
207
222
  private localVideoSize;
208
223
  private currentPrompt;
209
224
  private currentGenerationModel;
210
- private currentStaticGenerate;
211
225
  private disconnected;
212
226
  private remoteViewHost;
213
227
  private dragController;
@@ -260,11 +274,18 @@ type DragTrackControllerOptions = {
260
274
  mirrored?: boolean;
261
275
  enabled?: boolean;
262
276
  onTracks: (tracks: Array<[number, number]>) => void | Promise<void>;
277
+ /** Fired once when a real drag stroke begins (first pointer down). */
278
+ onStrokeStart?: () => void | Promise<void>;
279
+ /** Fired once when a real drag stroke ends (pointer up/cancel), not on disable/destroy. */
280
+ onStrokeEnd?: () => void | Promise<void>;
263
281
  };
264
282
  declare class DragTrackController {
265
283
  private readonly container;
266
284
  private readonly canvas;
267
285
  private readonly onTracks;
286
+ private readonly onStrokeStart;
287
+ private readonly onStrokeEnd;
288
+ private strokeActive;
268
289
  private targetSize;
269
290
  private fitMode;
270
291
  private mirrored;
@@ -91,8 +91,13 @@ type RealtimeInitialState = {
91
91
  autoStart?: boolean;
92
92
  /** @internal Business model label in RTC start params; optional — SDK uses a default when omitted. */
93
93
  model?: string;
94
- /** MoX instant — static image generation that follows drag tracks; sent as `static_generate`. */
94
+ /** MoX instant — when `true`, sent as `static_generate` on connect start only (never cached). */
95
95
  staticGenerate?: boolean;
96
+ /**
97
+ * MoX instant — uploaded source still URL (COS). Sent as `static_image_path` on connect
98
+ * start only (never cached). Local RTC publish is still used for preview / room compatibility.
99
+ */
100
+ staticImagePath?: string;
96
101
  };
97
102
  type RealtimeConnectOptions = {
98
103
  model: RealtimeModel;
@@ -126,8 +131,18 @@ type RealtimeRestartOptions = {
126
131
  /** @internal Optional business model label; SDK uses a default when omitted. */
127
132
  model?: string;
128
133
  size?: [number, number];
129
- /** MoX instant — static image generation that follows drag tracks; sent as `static_generate`. */
134
+ /**
135
+ * MoX instant — when `true`, sent as `static_generate` on this start only (never cached).
136
+ * Omit on non-Instant starts.
137
+ */
130
138
  staticGenerate?: boolean;
139
+ /**
140
+ * MoX instant — COS URL sent as `static_image_path` on this start only (never cached).
141
+ * Omit on non-Instant starts.
142
+ */
143
+ staticImagePath?: string;
144
+ /** Keep the last rendered remote frame visible while waiting for the next start output. */
145
+ preserveRemoteOutput?: boolean;
131
146
  };
132
147
  /** @deprecated Use {@link RealtimeRestartOptions} */
133
148
  type RealtimeSetModeOptions = RealtimeRestartOptions;
@@ -207,7 +222,6 @@ declare class RealtimeSession implements XmaxRealtimeSession {
207
222
  private localVideoSize;
208
223
  private currentPrompt;
209
224
  private currentGenerationModel;
210
- private currentStaticGenerate;
211
225
  private disconnected;
212
226
  private remoteViewHost;
213
227
  private dragController;
@@ -260,11 +274,18 @@ type DragTrackControllerOptions = {
260
274
  mirrored?: boolean;
261
275
  enabled?: boolean;
262
276
  onTracks: (tracks: Array<[number, number]>) => void | Promise<void>;
277
+ /** Fired once when a real drag stroke begins (first pointer down). */
278
+ onStrokeStart?: () => void | Promise<void>;
279
+ /** Fired once when a real drag stroke ends (pointer up/cancel), not on disable/destroy. */
280
+ onStrokeEnd?: () => void | Promise<void>;
263
281
  };
264
282
  declare class DragTrackController {
265
283
  private readonly container;
266
284
  private readonly canvas;
267
285
  private readonly onTracks;
286
+ private readonly onStrokeStart;
287
+ private readonly onStrokeEnd;
288
+ private strokeActive;
268
289
  private targetSize;
269
290
  private fitMode;
270
291
  private mirrored;
package/dist/index.cjs CHANGED
@@ -1278,7 +1278,8 @@ var XmaxOpenClient = class {
1278
1278
  return p.data;
1279
1279
  }
1280
1280
  const mappedMessage = resolveApiErrorMessage(p.code, this.i18n.locale);
1281
- const errorMessage = mappedMessage ?? this.i18n.t("errors.requestRetry");
1281
+ const backendMessage = typeof p.message === "string" && p.message.trim() ? p.message.trim() : void 0;
1282
+ const errorMessage = mappedMessage ?? backendMessage ?? this.i18n.t("errors.requestRetry");
1282
1283
  throw new Error(errorMessage);
1283
1284
  } catch (error) {
1284
1285
  if (this.isAbortError(error)) {
@@ -1430,6 +1431,7 @@ function createStartRtcRoomEvent(input) {
1430
1431
  const resolvedPrompt = input.prompt?.trim() ?? "";
1431
1432
  const refImagePath = input.refImagePath?.trim() || input.refImage?.trim() || void 0;
1432
1433
  const useRefImage = !!refImagePath;
1434
+ const staticImagePath = input.staticImagePath?.trim() || void 0;
1433
1435
  return {
1434
1436
  event: "start",
1435
1437
  user_id: input.userId?.trim() || void 0,
@@ -1441,7 +1443,9 @@ function createStartRtcRoomEvent(input) {
1441
1443
  prompt: resolvedPrompt,
1442
1444
  ref_image_path: useRefImage ? refImagePath : void 0,
1443
1445
  ref_image: useRefImage ? refImagePath : void 0,
1444
- static_generate: input.staticGenerate === void 0 ? void 0 : input.staticGenerate,
1446
+ // Instant-only omit when false/undefined so non-instant starts never carry leftover flags.
1447
+ static_generate: input.staticGenerate === true ? true : void 0,
1448
+ static_image_path: staticImagePath,
1445
1449
  ...input.extraParams ?? {}
1446
1450
  }
1447
1451
  };
@@ -1727,7 +1731,7 @@ var _RtcManager = class _RtcManager {
1727
1731
  this.lastRemoteSei = null;
1728
1732
  this.lastRemoteSeiUserId = null;
1729
1733
  this.hasLoggedSeiSendFailure = false;
1730
- if (previousExpectedRemoteSei !== this.expectedRemoteSei && this.remoteVideoUserId) {
1734
+ if (previousExpectedRemoteSei !== this.expectedRemoteSei && this.remoteVideoUserId && !this.preserveRemoteDom) {
1731
1735
  this.pendingRemoteVideoUserId = this.remoteVideoUserId;
1732
1736
  this.remoteVideoUserId = null;
1733
1737
  }
@@ -3776,6 +3780,7 @@ function drawNeon(ctx, segs, container, targetSize, dpr, fitMode, mirrored) {
3776
3780
  }
3777
3781
  var DragTrackController = class {
3778
3782
  constructor(container, options) {
3783
+ this.strokeActive = false;
3779
3784
  this.activePointers = /* @__PURE__ */ new Map();
3780
3785
  this.lastTargetPoints = /* @__PURE__ */ new Map();
3781
3786
  this.segQueue = [];
@@ -3785,6 +3790,8 @@ var DragTrackController = class {
3785
3790
  this.resizeObserver = null;
3786
3791
  this.container = container;
3787
3792
  this.onTracks = options.onTracks;
3793
+ this.onStrokeStart = options.onStrokeStart;
3794
+ this.onStrokeEnd = options.onStrokeEnd;
3788
3795
  this.targetSize = options.targetSize;
3789
3796
  this.fitMode = options.fitMode ?? "cover";
3790
3797
  this.mirrored = options.mirrored ?? false;
@@ -3955,11 +3962,17 @@ var DragTrackController = class {
3955
3962
  this.flushTracks();
3956
3963
  }, 30);
3957
3964
  }
3958
- finishStroke() {
3965
+ finishStroke(emitEnd = false) {
3966
+ const wasActive = this.strokeActive;
3967
+ this.strokeActive = false;
3959
3968
  this.stopSampling();
3960
3969
  this.stopDrawLoop();
3961
3970
  this.segQueue.length = 0;
3962
3971
  this.clearCanvas();
3972
+ if (emitEnd && wasActive && this.onStrokeEnd) {
3973
+ Promise.resolve(this.onStrokeEnd()).catch(() => {
3974
+ });
3975
+ }
3963
3976
  }
3964
3977
  handlePointerDown(e) {
3965
3978
  if (!this.enabled) {
@@ -3983,6 +3996,12 @@ var DragTrackController = class {
3983
3996
  if (targetPoint) {
3984
3997
  this.lastTargetPoints.set(e.pointerId, targetPoint);
3985
3998
  }
3999
+ const strokeWasActive = this.strokeActive;
4000
+ this.strokeActive = true;
4001
+ if (!strokeWasActive && this.onStrokeStart) {
4002
+ Promise.resolve(this.onStrokeStart()).catch(() => {
4003
+ });
4004
+ }
3986
4005
  this.startDrawLoop();
3987
4006
  this.startSampling();
3988
4007
  }
@@ -4015,7 +4034,7 @@ var DragTrackController = class {
4015
4034
  } catch {
4016
4035
  }
4017
4036
  if (this.activePointers.size === 0) {
4018
- this.finishStroke();
4037
+ this.finishStroke(true);
4019
4038
  }
4020
4039
  }
4021
4040
  handlePointerCancel(e) {
@@ -4025,7 +4044,7 @@ var DragTrackController = class {
4025
4044
  this.activePointers.delete(e.pointerId);
4026
4045
  this.lastTargetPoints.delete(e.pointerId);
4027
4046
  if (this.activePointers.size === 0) {
4028
- this.finishStroke();
4047
+ this.finishStroke(true);
4029
4048
  }
4030
4049
  }
4031
4050
  };
@@ -4199,7 +4218,6 @@ var RealtimeSession = class _RealtimeSession {
4199
4218
  this.localVideoSize = null;
4200
4219
  this.currentPrompt = "";
4201
4220
  this.currentGenerationModel = "";
4202
- this.currentStaticGenerate = void 0;
4203
4221
  this.disconnected = false;
4204
4222
  this.remoteViewHost = null;
4205
4223
  this.dragController = null;
@@ -4335,7 +4353,6 @@ var RealtimeSession = class _RealtimeSession {
4335
4353
  const initialState = options.initialState;
4336
4354
  this.currentPrompt = resolvePromptText(initialState?.prompt);
4337
4355
  this.currentGenerationModel = resolveGenerationModel(initialState?.model);
4338
- this.currentStaticGenerate = initialState?.staticGenerate;
4339
4356
  const publishFpsOptions = {
4340
4357
  mobile: options.mobile,
4341
4358
  highQuality: true,
@@ -4362,7 +4379,8 @@ var RealtimeSession = class _RealtimeSession {
4362
4379
  model: this.currentGenerationModel || void 0,
4363
4380
  size: options.size,
4364
4381
  refImage: initialRefImageUrl,
4365
- staticGenerate: this.currentStaticGenerate
4382
+ staticGenerate: initialState?.staticGenerate,
4383
+ staticImagePath: initialState?.staticImagePath?.trim() || void 0
4366
4384
  });
4367
4385
  }
4368
4386
  }
@@ -4441,15 +4459,14 @@ var RealtimeSession = class _RealtimeSession {
4441
4459
  if (options?.model !== void 0) {
4442
4460
  this.currentGenerationModel = resolveGenerationModel(options.model);
4443
4461
  }
4444
- if (options?.staticGenerate !== void 0) {
4445
- this.currentStaticGenerate = options.staticGenerate;
4446
- }
4447
4462
  await this.runStart({
4448
4463
  prompt: this.currentPrompt || void 0,
4449
4464
  model: this.currentGenerationModel || void 0,
4450
4465
  size: options?.size,
4451
4466
  refImage: resolvedRefImage,
4452
- staticGenerate: this.currentStaticGenerate
4467
+ staticGenerate: options?.staticGenerate === true ? true : void 0,
4468
+ staticImagePath: options?.staticImagePath?.trim() || void 0,
4469
+ preserveRemoteOutput: options?.preserveRemoteOutput
4453
4470
  });
4454
4471
  } catch (error) {
4455
4472
  this.reportError(error);
@@ -4540,17 +4557,20 @@ var RealtimeSession = class _RealtimeSession {
4540
4557
  if (!this.rtc.snapshot.joined) {
4541
4558
  return;
4542
4559
  }
4560
+ const preserveRemoteOutput = options.preserveRemoteOutput ?? false;
4561
+ if (preserveRemoteOutput) {
4562
+ this.rtc.setPreserveRemoteDom(true);
4563
+ }
4543
4564
  const startPrompt = options.prompt?.trim() ?? this.currentPrompt;
4544
4565
  if (options.model !== void 0) {
4545
4566
  this.currentGenerationModel = resolveGenerationModel(options.model);
4546
4567
  }
4547
- if (options.staticGenerate !== void 0) {
4548
- this.currentStaticGenerate = options.staticGenerate;
4549
- }
4550
4568
  const modelLabel = resolveGenerationModel(this.currentGenerationModel);
4551
4569
  await this.rtc.ensurePublishedInputBeforeStart();
4552
- this.rtc.setRemoteVideoContainer(null);
4553
- this.rtc.clearRemoteVideo();
4570
+ if (!preserveRemoteOutput) {
4571
+ this.rtc.setRemoteVideoContainer(null);
4572
+ this.rtc.clearRemoteVideo();
4573
+ }
4554
4574
  const size = resolveSessionTargetSize({
4555
4575
  localVideoSize: this.localVideoSize,
4556
4576
  overrideSize: options.size ?? this.sessionSizeOverride
@@ -4571,16 +4591,21 @@ var RealtimeSession = class _RealtimeSession {
4571
4591
  size,
4572
4592
  prompt: startPrompt,
4573
4593
  refImagePath: resolveRefImagePath(options.refImage),
4574
- staticGenerate: this.currentStaticGenerate
4594
+ // Never reuse prior start — caller must pass Instant fields each time.
4595
+ staticGenerate: options.staticGenerate === true ? true : void 0,
4596
+ staticImagePath: options.staticImagePath?.trim() || void 0
4575
4597
  });
4576
- console.log("[Xmax SDK] \u771F\u5B9E\u53D1\u9001 start ->", startRoomEvent);
4577
4598
  await this.rtc.sendRoomEvent(startRoomEvent);
4578
- await this.rtc.refreshRemoteVideoBinding({ force: true });
4599
+ await this.rtc.refreshRemoteVideoBinding({ force: !preserveRemoteOutput });
4579
4600
  this.updateDragController(true);
4580
4601
  this.scheduleNotifyRemoteStream();
4581
4602
  } catch (error) {
4582
4603
  this.rtc.configureSessionSei(null);
4583
4604
  throw error;
4605
+ } finally {
4606
+ if (preserveRemoteOutput) {
4607
+ this.rtc.setPreserveRemoteDom(false);
4608
+ }
4584
4609
  }
4585
4610
  }
4586
4611
  isDragEnabled() {
@@ -4707,7 +4732,6 @@ var RealtimeSession = class _RealtimeSession {
4707
4732
  this.taskUid = null;
4708
4733
  this.currentPrompt = "";
4709
4734
  this.currentGenerationModel = "";
4710
- this.currentStaticGenerate = void 0;
4711
4735
  this.sessionTargetSize = null;
4712
4736
  this.dragController?.destroy();
4713
4737
  this.dragController = null;