drizzle-team / drizzle-team/drizzle-orm

[FEATURE]: Transactions should support TC39 explicit resource management syntax (`using` statements)

Open
#4,546 0 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
TypeScript
Stars
35.8k
Forks
1.6k
Avg merge
2d 7h
Merged PRs (30d)
4

Description

### Feature hasn't been suggested before.

- [x] I have verified this feature I'm about to request hasn't been suggested before.

### Describe the enhancement you want to request

The stage 3 TC39 proposal named "Explicit Resource Management" adds support for the following syntax:

```js
{
await using _guard = ...;
// --snip--
} // _guard[Symbol.asyncDispose]() called
```

Currently, in order to ensure transactions are cleaned up correctly, drizzle requires a callback function to be used:

```ts
await db.transaction(async () => {
// ... do database stuff ...
});
```

This has some limitations. For example:

```ts
function example() {
let maybeValue: T | undefined;

const shouldEarlyReturn = await db.transaction(async () => {
// ... do database stuff ...

if (condition) {
return true; // Cannot return from `example` here
}

maybeValue = ...
});

// This is error prone
if (shouldEarlyReturn) {
return;
}

// ... do some other stuff ...

const value = maybeAValue!; // TypeScript cannot infer that maybeValue is definitely defined
}
```

These issues can be solved by adding support for async using statements:

```ts
function example() {
let maybeValue: T | undefined;

{
await using tx = await db.beginTrasnaction();

// ... do database stuff ...

if (condition) {
// If we need to commit stuff, call tx.commit() here. Otherwise, tx will be rolled back by default

return; // We can return directly from `example` (tx will be cleaned up automatically)
}

maybeValue = ...

await tx.commit(); // Required because `tx[Symbol.asyncDispose]` doesn't know if there was an error, so it should always assume rollback unless `tx.commit()` was called.
} // If `tx.commit()` was called, do nothing, otherwise, rollback.


maybeAValue;
// ^? let maybeValue: T
// maybeValue is correctly inferred as T (not T | undefined)
}
```

### Relevant Links

https://github.com/tc39/proposal-explicit-resource-management

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.