deepspace 0.35.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.d.ts CHANGED
@@ -2669,7 +2669,7 @@ declare function armCronRoom(ctx: {
2669
2669
  * Persistent job queue with serial execution, progress, cancellation and retries.
2670
2670
  * Jobs run inside alarms unless listed in `backgroundJobTypes`.
2671
2671
  * Use `ctx.continue` to save a checkpoint for the next run.
2672
- * After a restart, running jobs older than 16 minutes are retried or failed.
2672
+ * After a restart, interrupted running jobs are retried or failed.
2673
2673
  */
2674
2674
 
2675
2675
  type JobStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'canceled';
@@ -2793,7 +2793,7 @@ declare abstract class JobRoom<E = Record<string, unknown>, P = unknown, R = unk
2793
2793
  private drainDueJobs;
2794
2794
  private executeJob;
2795
2795
  private makeContext;
2796
- private readStatus;
2796
+ private readRunState;
2797
2797
  /** Reauthorize every live event so role revocation does not leave a stale reader. */
2798
2798
  protected broadcast(message: ServerMessage, exclude?: WebSocket): void;
2799
2799
  private resolveAccess;
@@ -3674,6 +3674,12 @@ interface DeepSpaceAuthConfig {
3674
3674
  emailAndPassword?: boolean;
3675
3675
  /** Trusted origins for CORS */
3676
3676
  trustedOrigins?: string[];
3677
+ /**
3678
+ * Where a failed OAuth callback lands when the flow can't be tied back to
3679
+ * its own error URL (for example its state expired). Without it Better Auth
3680
+ * shows its own developer-facing error page.
3681
+ */
3682
+ errorURL?: string;
3677
3683
  /**
3678
3684
  * Server-owned fields to add to Better Auth's user model. Use `input: false`
3679
3685
  * for values that may only be populated by a database hook, and
@@ -4714,8 +4720,11 @@ declare function createDeepSpaceAuth(config: DeepSpaceAuthConfig): better_auth.A
4714
4720
  };
4715
4721
  };
4716
4722
  } | undefined;
4717
- socialProviders: Parameters<typeof betterAuth>[0]["socialProviders"];
4718
4723
  trustedOrigins: string[];
4724
+ onAPIError?: {
4725
+ errorURL: string;
4726
+ } | undefined;
4727
+ socialProviders: Parameters<typeof betterAuth>[0]["socialProviders"];
4719
4728
  user?: {
4720
4729
  additionalFields: {
4721
4730
  [x: string]: better_auth.DBFieldAttribute;
package/dist/server.js CHANGED
@@ -7384,7 +7384,7 @@ var JobRoom = class extends BaseRoom {
7384
7384
  `);
7385
7385
  this.sql.exec(`CREATE INDEX IF NOT EXISTS jobs_status_next_run ON jobs (status, next_run_at)`);
7386
7386
  this.sql.exec(`CREATE INDEX IF NOT EXISTS jobs_completed_at ON jobs (completed_at)`);
7387
- this.recoverStuckRunning();
7387
+ this.recoverStuckRunning(true);
7388
7388
  this.scheduleNextAlarm();
7389
7389
  }
7390
7390
  // ==========================================================================
@@ -7630,8 +7630,7 @@ var JobRoom = class extends BaseRoom {
7630
7630
  }
7631
7631
  async executeJob(row) {
7632
7632
  const startedAt = row.started_at ?? (/* @__PURE__ */ new Date()).toISOString();
7633
- const attemptsBefore = row.attempts;
7634
- const attempt = attemptsBefore + 1;
7633
+ const attempt = row.attempts + 1;
7635
7634
  this.sql.exec(
7636
7635
  `UPDATE jobs SET status = 'running', started_at = ?, attempts = ? WHERE id = ?`,
7637
7636
  startedAt,
@@ -7651,7 +7650,7 @@ var JobRoom = class extends BaseRoom {
7651
7650
  let result;
7652
7651
  let errorMessage;
7653
7652
  try {
7654
- const ctx = this.makeContext(row.id, controller.signal);
7653
+ const ctx = this.makeContext(row.id, attempt, controller.signal);
7655
7654
  result = await this.onJob(job, ctx);
7656
7655
  if (this.continueState) outcome = "continued";
7657
7656
  } catch (e) {
@@ -7661,8 +7660,8 @@ var JobRoom = class extends BaseRoom {
7661
7660
  } finally {
7662
7661
  this.inFlight.delete(row.id);
7663
7662
  }
7664
- const currentStatus = this.readStatus(row.id);
7665
- if (currentStatus !== "running") {
7663
+ const current = this.readRunState(row.id);
7664
+ if (current?.status !== "running" || current.attempts !== attempt) {
7666
7665
  this.continueState = null;
7667
7666
  return;
7668
7667
  }
@@ -7741,9 +7740,11 @@ var JobRoom = class extends BaseRoom {
7741
7740
  const updated = this.getJobById(row.id);
7742
7741
  if (updated) this.broadcast(serverBuild.jobFailed(updated));
7743
7742
  }
7744
- makeContext(jobId, signal) {
7743
+ makeContext(jobId, attempt, signal) {
7745
7744
  return {
7746
7745
  progress: (value, message) => {
7746
+ const current = this.readRunState(jobId);
7747
+ if (current?.status !== "running" || current.attempts !== attempt) return;
7747
7748
  const clamped = Math.max(0, Math.min(1, value));
7748
7749
  this.sql.exec(
7749
7750
  `UPDATE jobs SET progress = ?, progress_message = ? WHERE id = ?`,
@@ -7763,9 +7764,9 @@ var JobRoom = class extends BaseRoom {
7763
7764
  signal
7764
7765
  };
7765
7766
  }
7766
- readStatus(jobId) {
7767
- const row = this.sql.exec(`SELECT status FROM jobs WHERE id = ?`, jobId).toArray()[0];
7768
- return row?.status ?? null;
7767
+ readRunState(jobId) {
7768
+ const row = this.sql.exec(`SELECT status, attempts FROM jobs WHERE id = ?`, jobId).toArray()[0];
7769
+ return row ?? null;
7769
7770
  }
7770
7771
  /** Reauthorize every live event so role revocation does not leave a stale reader. */
7771
7772
  broadcast(message, exclude) {
@@ -7823,11 +7824,12 @@ var JobRoom = class extends BaseRoom {
7823
7824
  if (targets.length === 0) return;
7824
7825
  this.state.storage.setAlarm(Math.max(Math.min(...targets), now + 50));
7825
7826
  }
7826
- recoverStuckRunning() {
7827
+ recoverStuckRunning(onStartup = false) {
7827
7828
  const cutoff = new Date(Date.now() - RUNNING_STALE_MS).toISOString();
7828
7829
  const stuck = this.sql.exec(
7829
7830
  `SELECT id, attempts, max_attempts FROM jobs
7830
- WHERE status = 'running' AND (started_at IS NULL OR started_at <= ?)`,
7831
+ WHERE status = 'running' AND (? = 1 OR started_at IS NULL OR started_at <= ?)`,
7832
+ onStartup ? 1 : 0,
7831
7833
  cutoff
7832
7834
  ).toArray();
7833
7835
  for (const r of stuck) {
@@ -8832,6 +8834,7 @@ function createDeepSpaceAuth(config) {
8832
8834
  },
8833
8835
  ...config.userAdditionalFields ? { user: { additionalFields: config.userAdditionalFields } } : {},
8834
8836
  socialProviders,
8837
+ ...config.errorURL ? { onAPIError: { errorURL: config.errorURL } } : {},
8835
8838
  trustedOrigins: config.trustedOrigins ?? [
8836
8839
  "https://deep.space",
8837
8840
  "https://*.deep.space",