Skip to content

Instantly share code, notes, and snippets.

@dfoverdx
Last active August 17, 2023 18:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dfoverdx/d99b5581ad672a8a362a161550ae23c6 to your computer and use it in GitHub Desktop.
Save dfoverdx/d99b5581ad672a8a362a161550ae23c6 to your computer and use it in GitHub Desktop.
JavaScript/TypeScript Data Access Layer that automatically asserts the connection is ready, or waits for the connection to become ready
import Client from 'some-database-api';
import { connectionInfo } from './config';
class AsyncDatabaseClient {
constructor() {
this._connection = null;
this._initialized = Client.connect(connectionInfo).then(c => this.connection = c);
return new Proxy(this, {
get(target, prop, receiver) {
const value = Reflect.get(target, prop, receiver);
if (typeof value === 'function') {
return async (...args) => {
await target._initialized;
return value.apply(receiver, args);
};
}
return value;
}
});
}
static _single = new AsyncDatabaseClient();
static get Single() {
return this._single;
}
async fetch(query) {
return this._connection.makeRequest(query);
}
}
export default AsyncDatabaseClient.Single;
import { Client, Connection } from 'some-database-api';
import { connectionInfo } from './config';
export interface ISomeData {
someProp: string;
}
export interface ISomeQuery {
someQueryProp: string;
}
class AsyncDatabaseClient {
constructor() {
this.initialized = Client.connect(connectionInfo).then(c => this.connection = c);
return new Proxy(this, {
get(target, prop, receiver) {
const value = Reflect.get(target, prop, receiver);
if (typeof value === 'function') {
return async (...args: any[]) => {
await target.initialized;
return value.apply(receiver, args);
};
}
return value;
}
});
}
private readonly initialized: Promise<void>;
private connection!: Connection;
static readonly Single = new AsyncDatabaseClient();
fetchSomeData(query: ISomeQuery): Promise<ISomeData> {
return this.connection.makeRequest<ISomeData>(query);
}
}
export default AsyncDatabaseClient.Single;
import Client from 'some-database-api';
import { connectionInfo } from './config';
class DatabaseClient {
constructor() {
this._connection = null;
Client.connect(connectionInfo).then(c => this.connection = c);
return new Proxy(this, {
get(target, prop, receiver) {
const value = Reflect.get(target, prop, receiver);
if (typeof value === 'function') {
return (...args) => {
if (!target._connection) {
throw new Error('Connection not ready');
}
return value.apply(receiver, args);
};
}
return value;
}
});
}
static _single = new DatabaseClient();
static get Single() {
return this._single;
}
fetch(query) {
return this.connection.makeRequest(query);
}
}
export default DatabaseClient.Single;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment