# DeletePromise

DeletePromise provides chainable methods for configuring DELETE operations.

The `DeletePromise` class provides a chainable interface for configuring DELETE operations before execution. It extends `Promise`, allowing you to `await` it directly or chain configuration methods.

**Returned by:** [`SurrealQueryable.delete()`](/docs/reference/javascript/api/core/surreal-queryable.md#delete)

**Source:** [query/delete.ts](https://github.com/surrealdb/surrealdb.js/blob/main/packages/sdk/src/query/delete.ts)

## Type parameters

- `T` - The result type (deleted record data)
- `J` - Boolean indicating if result is JSON (default: `false`)

## Configuration methods

### `.output()` {#output}

Specify what to return from the delete operation.

```ts title="Method Syntax"
deletePromise.output(fields)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>fields</code> <label label="required" /></td>
            <td><code>Output</code></td>
            <td><code>"NONE"</code>, <code>"BEFORE"</code>, or specific field list.</td>
        </tr>
    </tbody>
</table>

#### Returns
`DeletePromise<T, J>` - Chainable promise

#### Examples

```ts title="Return Deleted Record"
const deleted = await db.delete(new RecordId('users', 'john'))
    .output('BEFORE');
// Returns the record before deletion
```

```ts title="Return Specific Fields"
const deleted = await db.delete(new RecordId('users', 'john'))
    .output('id', 'name', 'email');
// Returns only specified fields of deleted record
```

```ts title="Return Nothing"
await db.delete(new RecordId('logs', '123'))
    .output('NONE');
// Faster when you don't need the data
```

---

### `.timeout()` {#timeout}

Set a timeout for the operation.

```ts title="Method Syntax"
deletePromise.timeout(duration)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>duration</code> <label label="required" /></td>
            <td><code><a href="/docs/reference/javascript/api/values/duration.md">Duration</a></code></td>
            <td>Maximum time to wait.</td>
        </tr>
    </tbody>
</table>

#### Returns
`DeletePromise<T, J>` - Chainable promise

#### Example

```ts
const deleted = await db.delete(new Table('users'))
    .timeout(Duration.parse('10s'));
```

---

### `.version()` {#version}

Delete at a specific version (for versioned storage engines).

```ts title="Method Syntax"
deletePromise.version(timestamp)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>timestamp</code> <label label="required" /></td>
            <td><code><a href="/docs/reference/javascript/api/values/datetime.md">DateTime</a></code></td>
            <td>The version timestamp.</td>
        </tr>
    </tbody>
</table>

#### Returns
`DeletePromise<T, J>` - Chainable promise

---

### `.retry()` {#retry}

Retry the operation with exponential backoff if it fails due to a write conflict. Off by default; passing an options object (or calling with no arguments) opts the operation in.

This overrides the connection-wide default set via the [`retry`](/docs/reference/javascript/api/types/#connectoptions) option on `ConnectOptions`.

```ts title="Method Syntax"
deletePromise.retry(options?)
```

#### Parameters
<table>
    <thead>
        <tr>
            <th>Parameter</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>options</code> <label label="optional" /></td>
            <td><code>Partial&lt;<a href="/docs/reference/javascript/api/types/#retryoptions">RetryOptions</a>&gt;</code></td>
            <td>Retry configuration. If omitted, retry is enabled with the default configuration.</td>
        </tr>
    </tbody>
</table>

#### Returns
`DeletePromise<T, J>` - Chainable promise

#### Example

```ts
await db.delete(new RecordId('users', 'john')).retry();
```

---

### `.json()` {#json}

Return result as JSON string.

```ts title="Method Syntax"
deletePromise.json()
```

#### Returns
`DeletePromise<T, true>` - Promise returning JSON string

---

### `.compile()` {#compile}

Compile the query into a `BoundQuery` without executing it.

```ts title="Method Syntax"
deletePromise.compile()
```

#### Returns
`BoundQuery<[T]>` - The compiled query

#### Example

```ts
const query = db.delete(new Table('temp_data'))
    .compile();
```

---

### `.stream()` {#stream}

Stream deleted records as they are removed.

```ts title="Method Syntax"
deletePromise.stream()
```

#### Returns
`AsyncIterableIterator` - Async iterator

## Complete examples

### Basic deletion

```ts
import { Surreal, RecordId, Table } from 'surrealdb';

const db = new Surreal();
await db.connect('ws://localhost:8000');

// Delete single record
const deleted = await db.delete(new RecordId('users', 'john'));
console.log('Deleted user:', deleted);

// Delete by range
const deleted = await db.delete(
    new RecordIdRange('users', 'a', 'f')
);
console.log(`Deleted ${deleted.length} users`);

// Delete entire table
const deleted = await db.delete(new Table('temp_data'));
console.log(`Deleted ${deleted.length} records`);
```

### Capture deleted data

```ts
// Store deleted data before removing
const user = await db.delete(new RecordId('users', 'john'))
    .output('BEFORE');

// Archive the deleted user
await db.create(new RecordId('archived_users', user.id))
    .content({
        ...user,
        deleted_at: DateTime.now()
    });
```

### Conditional deletion

```ts
// Note: WHERE clauses are not directly supported on delete promises
// Use query() for conditional deletes
const result = await db.query(
    surql`DELETE FROM users WHERE inactive = true`
).collect();

console.log(`Deleted ${result[0].result.length} inactive users`);
```

### Bulk deletion with streaming

```ts
const deletedRecords = db.delete(new Table('old_logs'));

let count = 0;
for await (const record of deletedRecords.stream()) {
    count++;
    if (count % 100 === 0) {
        console.log(`Deleted ${count} records`);
    }
}
```

### Soft delete pattern

```ts
// Instead of deleting, mark as deleted
const user = await db.update(new RecordId('users', 'john'))
    .merge({
        deleted: true,
        deleted_at: DateTime.now()
    });

// Actual delete with backup
const user = await db.delete(new RecordId('users', 'john'))
    .output('BEFORE');

if (user) {
    await db.create(new RecordId('deleted_users', user.id))
        .content(user);
}
```

### Delete with error handling

```ts
try {
    const deleted = await db.delete(new RecordId('users', 'john'));
    
    if (!deleted) {
        console.log('User not found');
    } else {
        console.log('User deleted successfully');
    }
} catch (error) {
    if (error instanceof ResponseError) {
        console.error('Delete failed:', error.message);
    }
}
```

### Performance optimisation

```ts
// Don't wait for deleted data if not needed
await db.delete(new Table('temp_cache'))
    .output('NONE');
// Faster execution
```

### Delete with timeout

```ts
// For large deletions
const deleted = await db.delete(new Table('old_logs'))
    .timeout(Duration.parse('30s'));
```

### Cascading deletes

```ts
// Delete user and all related data
const userId = new RecordId('users', 'john');

// Delete user
const user = await db.delete(userId);

// Delete related posts
await db.query(
    surql`DELETE FROM posts WHERE author = ${userId}`
).collect();

// Delete related comments
await db.query(
    surql`DELETE FROM comments WHERE author = ${userId}`
).collect();

console.log('User and related data deleted');
```

### Batch deletion

```ts
const idsToDelete = ['user1', 'user2', 'user3'];

for (const id of idsToDelete) {
    await db.delete(new RecordId('users', id));
}

// Or using query for better performance
const result = await db.query(
    surql`DELETE FROM users WHERE id IN ${idsToDelete.map(id => new RecordId('users', id))}`
).collect();
```

### Archive before delete

```ts
async function archiveAndDelete(recordId: RecordId) {
    // Get the record
    const record = await db.select(recordId);
    
    if (!record) {
        throw new Error('Record not found');
    }
    
    // Archive it
    await db.create(new RecordId('archive', record.id))
        .content({
            ...record,
            archived_at: DateTime.now()
        });
    
    // Delete original
    await db.delete(recordId).output('NONE');
    
    return record;
}

await archiveAndDelete(new RecordId('users', 'john'));
```

## Important notes

> [!WARNING]
> DELETE operations are permanent and cannot be undone. Always ensure you have backups or use the `.output('BEFORE')` method to capture data before deletion.

> [!NOTE: Tip]
> For conditional deletions, use [`db.query()`](/docs/reference/javascript/api/core/surreal-queryable.md#query) with a DELETE statement including a WHERE clause.

## Chaining pattern

```ts
const result = await db.delete(new Table('users'))
    .output('BEFORE')
    .timeout(Duration.parse('10s'));
```

## See also

- [SurrealQueryable.delete()](/docs/reference/javascript/api/core/surreal-queryable.md#delete) - Method that returns DeletePromise
- [UpdatePromise](/docs/reference/javascript/api/queries/update-promise.md) - Update records
- [Query](/docs/reference/javascript/api/queries/query.md) - Raw SurrealQL for conditional deletes
- [Query overview](/docs/reference/javascript/api/queries/) - All query builder classes
