* Create a lazy proxy that records property accesses and method calls, * then replays them on the real DB once init completes. Supports * Drizzle's chained API: db.select().from(table).where(...). * * When `.then()` is called (i.e. the chain is awaited), the proxy * awaits _dbReady an
(
ready: Promise<any>,
chain: Array<{ prop: string | symbol; args?: any[] }>,
)
| 116 | * awaits _dbReady and replays the recorded chain on the real _db. |
| 117 | */ |
| 118 | function createLazyProxy( |
| 119 | ready: Promise<any>, |
| 120 | chain: Array<{ prop: string | symbol; args?: any[] }>, |
| 121 | ): any { |
| 122 | return new Proxy(function () {} as any, { |
| 123 | get(_target, prop) { |
| 124 | // When awaited, replay the chain on the real db |
| 125 | if (prop === "then" || prop === "catch" || prop === "finally") { |
| 126 | const promise = ready.then(() => { |
| 127 | let result: any = _db; |
| 128 | for (const step of chain) { |
| 129 | const val = result[step.prop]; |
| 130 | result = |
| 131 | typeof val === "function" ? val.apply(result, step.args) : val; |
| 132 | } |
| 133 | return result; |
| 134 | }); |
| 135 | return (promise as any)[prop].bind(promise); |
| 136 | } |
| 137 | // Symbol.toStringTag, Symbol.iterator, etc. — return another proxy |
| 138 | // Property access (e.g. db.query) — record and return another proxy |
| 139 | return createLazyProxy(ready, [...chain, { prop }]); |
| 140 | }, |
| 141 | apply(_target, _thisArg, args) { |
| 142 | // Method call (e.g. .from(table)) — record args and return another proxy |
| 143 | if (chain.length === 0) return createLazyProxy(ready, []); |
| 144 | const last = chain[chain.length - 1]; |
| 145 | const newChain = chain.slice(0, -1); |
| 146 | newChain.push({ prop: last.prop, args }); |
| 147 | return createLazyProxy(ready, newChain); |
| 148 | }, |
| 149 | }); |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * Get the Drizzle DB instance. Kicks off lazy init on first call. |