@fluojs/drizzle 1.1.1 → 2.0.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/README.ko.md +56 -9
- package/README.md +56 -9
- package/dist/database.d.ts +4 -0
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +164 -26
- package/dist/module.d.ts +21 -5
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +21 -77
- package/dist/named-registration.d.ts +20 -0
- package/dist/named-registration.d.ts.map +1 -0
- package/dist/named-registration.js +84 -0
- package/dist/registration-name.d.ts +9 -0
- package/dist/registration-name.d.ts.map +1 -0
- package/dist/registration-name.js +17 -0
- package/dist/registration-providers.d.ts +44 -0
- package/dist/registration-providers.d.ts.map +1 -0
- package/dist/registration-providers.js +120 -0
- package/dist/tokens.d.ts +29 -0
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +47 -1
- package/dist/transaction.d.ts +24 -0
- package/dist/transaction.d.ts.map +1 -1
- package/dist/transaction.js +45 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -8
package/dist/database.js
CHANGED
|
@@ -121,7 +121,11 @@ class DrizzleDatabase {
|
|
|
121
121
|
* @returns The transaction-scoped database inside an active boundary, or the root database outside one.
|
|
122
122
|
*/
|
|
123
123
|
current() {
|
|
124
|
-
|
|
124
|
+
const current = this.transactions.getStore();
|
|
125
|
+
if (!current || current.transactionBoundaryOwner.closed) {
|
|
126
|
+
return this.database;
|
|
127
|
+
}
|
|
128
|
+
return current.database;
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
/** Aborts active request transactions, waits for settlement, then runs the optional dispose hook. */
|
|
@@ -185,41 +189,66 @@ class DrizzleDatabase {
|
|
|
185
189
|
async executeTransaction(fn, options, requestScoped, signal) {
|
|
186
190
|
const current = this.transactions.getStore();
|
|
187
191
|
if (current) {
|
|
192
|
+
if (current.transactionBoundaryOwner.closed) {
|
|
193
|
+
if (requestScoped) {
|
|
194
|
+
return this.executeInheritedRequestTransaction(current, fn, options, signal);
|
|
195
|
+
}
|
|
196
|
+
return this.executeManualRootTransaction(fn, options);
|
|
197
|
+
}
|
|
198
|
+
if (!requestScoped) {
|
|
199
|
+
return this.executeNestedManualTransaction(current.transactionBoundaryOwner, fn, options);
|
|
200
|
+
}
|
|
188
201
|
if (requestScoped) {
|
|
189
202
|
this.assertRequestTransactionsAvailable();
|
|
190
203
|
} else {
|
|
191
204
|
this.assertTransactionsAvailable();
|
|
192
205
|
}
|
|
193
|
-
if (options !== undefined) {
|
|
194
|
-
throw new Error(NESTED_TRANSACTION_OPTIONS_NOT_SUPPORTED_ERROR);
|
|
195
|
-
}
|
|
196
206
|
if (requestScoped) {
|
|
197
207
|
return this.executeNestedRequestTransaction(current, fn, signal);
|
|
198
208
|
}
|
|
199
|
-
return fn();
|
|
200
209
|
}
|
|
201
210
|
if (!requestScoped) {
|
|
202
211
|
return this.executeManualRootTransaction(fn, options);
|
|
203
212
|
}
|
|
204
|
-
|
|
205
|
-
if (!transactionRunner) {
|
|
206
|
-
return this.executeRequestFallback(fn, signal);
|
|
207
|
-
}
|
|
208
|
-
return this.executeRequestTransaction(transactionRunner, fn, options, signal);
|
|
213
|
+
return this.executeRequestRootTransaction(fn, options, signal);
|
|
209
214
|
}
|
|
210
215
|
async executeManualRootTransaction(fn, options) {
|
|
211
216
|
const deferredRequestTransactionSettlements = new Set();
|
|
217
|
+
const fallbackTransactionOwner = {
|
|
218
|
+
closed: false,
|
|
219
|
+
callbackSettlements: new Set(),
|
|
220
|
+
requestTransactionSettlements: new Set()
|
|
221
|
+
};
|
|
212
222
|
const activeTransactionScope = this.trackAvailableTransactionScope();
|
|
213
223
|
try {
|
|
214
224
|
const transactionRunner = this.resolveTransactionRunner();
|
|
215
225
|
if (!transactionRunner) {
|
|
216
|
-
|
|
226
|
+
try {
|
|
227
|
+
return await this.transactions.run({
|
|
228
|
+
database: this.database,
|
|
229
|
+
fallbackTransactionOwner,
|
|
230
|
+
transactionBoundaryOwner: fallbackTransactionOwner
|
|
231
|
+
}, fn);
|
|
232
|
+
} finally {
|
|
233
|
+
await this.closeTransactionBoundaryOwner(fallbackTransactionOwner);
|
|
234
|
+
}
|
|
217
235
|
}
|
|
218
|
-
return await transactionRunner(transactionDatabase =>
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
236
|
+
return await transactionRunner(async transactionDatabase => {
|
|
237
|
+
try {
|
|
238
|
+
return await this.transactions.run({
|
|
239
|
+
database: transactionDatabase,
|
|
240
|
+
deferredRequestTransactionSettlements,
|
|
241
|
+
transactionBoundaryOwner: fallbackTransactionOwner
|
|
242
|
+
}, fn);
|
|
243
|
+
} finally {
|
|
244
|
+
await this.closeTransactionBoundaryOwner(fallbackTransactionOwner);
|
|
245
|
+
}
|
|
246
|
+
}, options);
|
|
222
247
|
} finally {
|
|
248
|
+
await this.closeTransactionBoundaryOwner(fallbackTransactionOwner);
|
|
249
|
+
for (const handle of fallbackTransactionOwner.requestTransactionSettlements) {
|
|
250
|
+
this.untrackActiveRequestTransaction(handle);
|
|
251
|
+
}
|
|
223
252
|
for (const handle of deferredRequestTransactionSettlements) {
|
|
224
253
|
this.untrackActiveRequestTransaction(handle);
|
|
225
254
|
}
|
|
@@ -230,23 +259,92 @@ class DrizzleDatabase {
|
|
|
230
259
|
this.assertRequestTransactionsAvailable();
|
|
231
260
|
const abortContext = createRequestAbortContext(signal);
|
|
232
261
|
const active = this.trackActiveRequestTransaction(abortContext.controller);
|
|
262
|
+
const transactionBoundaryOwner = {
|
|
263
|
+
closed: false,
|
|
264
|
+
callbackSettlements: new Set(),
|
|
265
|
+
requestTransactionSettlements: new Set()
|
|
266
|
+
};
|
|
233
267
|
try {
|
|
234
|
-
const result = await transactionRunner(transactionDatabase =>
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
268
|
+
const result = await transactionRunner(async transactionDatabase => {
|
|
269
|
+
try {
|
|
270
|
+
return await this.transactions.run({
|
|
271
|
+
database: transactionDatabase,
|
|
272
|
+
inheritedRequestAbortSignal: signal ?? abortContext.signal,
|
|
273
|
+
requestAbortSignal: abortContext.signal,
|
|
274
|
+
transactionBoundaryOwner
|
|
275
|
+
}, () => raceWithAbort(fn, abortContext.signal));
|
|
276
|
+
} finally {
|
|
277
|
+
await this.closeTransactionBoundaryOwner(transactionBoundaryOwner);
|
|
278
|
+
}
|
|
279
|
+
}, options);
|
|
238
280
|
this.throwIfRequestAborted(abortContext.signal);
|
|
239
281
|
return result;
|
|
240
282
|
} finally {
|
|
283
|
+
transactionBoundaryOwner.closed = true;
|
|
241
284
|
abortContext.cleanup();
|
|
242
285
|
this.untrackActiveRequestTransaction(active);
|
|
243
286
|
}
|
|
244
287
|
}
|
|
288
|
+
async executeRequestRootTransaction(fn, options, signal) {
|
|
289
|
+
const transactionRunner = this.resolveTransactionRunner();
|
|
290
|
+
if (!transactionRunner) {
|
|
291
|
+
return this.executeRequestFallback(fn, signal);
|
|
292
|
+
}
|
|
293
|
+
return this.executeRequestTransaction(transactionRunner, fn, options, signal);
|
|
294
|
+
}
|
|
295
|
+
async executeInheritedRequestTransaction(current, fn, options, signal) {
|
|
296
|
+
const inheritedRequestAbortSignal = current.inheritedRequestAbortSignal ?? current.requestAbortSignal;
|
|
297
|
+
if (!inheritedRequestAbortSignal) {
|
|
298
|
+
return this.executeRequestRootTransaction(fn, options, signal);
|
|
299
|
+
}
|
|
300
|
+
const abortSignalView = createRequestAbortSignalView(inheritedRequestAbortSignal, signal);
|
|
301
|
+
try {
|
|
302
|
+
this.throwIfRequestAborted(abortSignalView.signal);
|
|
303
|
+
return await this.executeRequestRootTransaction(fn, options, abortSignalView.signal);
|
|
304
|
+
} finally {
|
|
305
|
+
abortSignalView.cleanup();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
async executeNestedManualTransaction(owner, fn, options) {
|
|
309
|
+
this.assertTransactionsAvailable();
|
|
310
|
+
if (options !== undefined) {
|
|
311
|
+
throw new Error(NESTED_TRANSACTION_OPTIONS_NOT_SUPPORTED_ERROR);
|
|
312
|
+
}
|
|
313
|
+
const callback = Promise.resolve().then(fn);
|
|
314
|
+
const removeSettlement = () => {
|
|
315
|
+
owner.callbackSettlements.delete(settlement);
|
|
316
|
+
};
|
|
317
|
+
const settlement = callback.then(removeSettlement, removeSettlement);
|
|
318
|
+
owner.callbackSettlements.add(settlement);
|
|
319
|
+
return callback;
|
|
320
|
+
}
|
|
245
321
|
async executeNestedRequestTransaction(current, fn, signal) {
|
|
322
|
+
const fallbackTransactionOwner = current.fallbackTransactionOwner;
|
|
323
|
+
if (fallbackTransactionOwner?.closed) {
|
|
324
|
+
if (current.requestAbortSignal) {
|
|
325
|
+
const abortSignalView = createRequestAbortSignalView(current.requestAbortSignal, signal);
|
|
326
|
+
try {
|
|
327
|
+
return await this.executeRequestFallback(fn, abortSignalView.signal);
|
|
328
|
+
} finally {
|
|
329
|
+
abortSignalView.cleanup();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return this.executeRequestFallback(fn, signal);
|
|
333
|
+
}
|
|
334
|
+
const runCallback = () => {
|
|
335
|
+
const callback = fn();
|
|
336
|
+
const transactionBoundaryOwner = current.transactionBoundaryOwner;
|
|
337
|
+
const removeSettlement = () => {
|
|
338
|
+
transactionBoundaryOwner.callbackSettlements.delete(settlement);
|
|
339
|
+
};
|
|
340
|
+
const settlement = callback.then(removeSettlement, removeSettlement);
|
|
341
|
+
transactionBoundaryOwner.callbackSettlements.add(settlement);
|
|
342
|
+
return callback;
|
|
343
|
+
};
|
|
246
344
|
if (current.requestAbortSignal) {
|
|
247
345
|
const abortSignalView = createRequestAbortSignalView(current.requestAbortSignal, signal);
|
|
248
346
|
try {
|
|
249
|
-
const result = await raceWithAbort(
|
|
347
|
+
const result = await raceWithAbort(runCallback, abortSignalView.signal);
|
|
250
348
|
this.throwIfRequestAborted(abortSignalView.signal);
|
|
251
349
|
return result;
|
|
252
350
|
} finally {
|
|
@@ -256,17 +354,27 @@ class DrizzleDatabase {
|
|
|
256
354
|
this.assertRequestTransactionsAvailable();
|
|
257
355
|
const abortContext = createRequestAbortContext(signal);
|
|
258
356
|
const active = this.trackActiveRequestTransaction(abortContext.controller);
|
|
259
|
-
|
|
357
|
+
let ownerDefersSettlement = false;
|
|
358
|
+
if (fallbackTransactionOwner) {
|
|
359
|
+
fallbackTransactionOwner.requestTransactionSettlements.add(active);
|
|
360
|
+
ownerDefersSettlement = true;
|
|
361
|
+
} else if (current.deferredRequestTransactionSettlements) {
|
|
362
|
+
current.deferredRequestTransactionSettlements.add(active);
|
|
363
|
+
ownerDefersSettlement = true;
|
|
364
|
+
}
|
|
260
365
|
try {
|
|
261
366
|
const result = await this.transactions.run({
|
|
262
367
|
database: current.database,
|
|
263
|
-
|
|
264
|
-
|
|
368
|
+
fallbackTransactionOwner,
|
|
369
|
+
inheritedRequestAbortSignal: current.inheritedRequestAbortSignal,
|
|
370
|
+
requestAbortSignal: abortContext.signal,
|
|
371
|
+
transactionBoundaryOwner: current.transactionBoundaryOwner
|
|
372
|
+
}, () => raceWithAbort(runCallback, abortContext.signal));
|
|
265
373
|
this.throwIfRequestAborted(abortContext.signal);
|
|
266
374
|
return result;
|
|
267
375
|
} finally {
|
|
268
376
|
abortContext.cleanup();
|
|
269
|
-
if (
|
|
377
|
+
if (ownerDefersSettlement) {
|
|
270
378
|
this.markRequestTransactionInactiveForStatus(active);
|
|
271
379
|
} else {
|
|
272
380
|
this.untrackActiveRequestTransaction(active);
|
|
@@ -276,16 +384,46 @@ class DrizzleDatabase {
|
|
|
276
384
|
async executeRequestFallback(fn, signal) {
|
|
277
385
|
this.assertRequestTransactionsAvailable();
|
|
278
386
|
const abortContext = createRequestAbortContext(signal);
|
|
387
|
+
if (abortContext.signal.aborted) {
|
|
388
|
+
const abortError = createAbortError(abortContext.signal.reason);
|
|
389
|
+
abortContext.cleanup();
|
|
390
|
+
throw abortError;
|
|
391
|
+
}
|
|
279
392
|
const active = this.trackActiveRequestTransaction(abortContext.controller);
|
|
393
|
+
const fallbackTransactionOwner = {
|
|
394
|
+
closed: false,
|
|
395
|
+
callbackSettlements: new Set(),
|
|
396
|
+
requestTransactionSettlements: new Set()
|
|
397
|
+
};
|
|
280
398
|
try {
|
|
281
|
-
const result = await raceWithAbort(
|
|
399
|
+
const result = await raceWithAbort(() => {
|
|
400
|
+
const callback = new Promise(resolve => resolve(this.transactions.run({
|
|
401
|
+
database: this.database,
|
|
402
|
+
fallbackTransactionOwner,
|
|
403
|
+
inheritedRequestAbortSignal: signal ?? abortContext.signal,
|
|
404
|
+
requestAbortSignal: abortContext.signal,
|
|
405
|
+
transactionBoundaryOwner: fallbackTransactionOwner
|
|
406
|
+
}, fn)));
|
|
407
|
+
return callback.finally(async () => {
|
|
408
|
+
await this.closeTransactionBoundaryOwner(fallbackTransactionOwner);
|
|
409
|
+
for (const handle of fallbackTransactionOwner.requestTransactionSettlements) {
|
|
410
|
+
this.untrackActiveRequestTransaction(handle);
|
|
411
|
+
}
|
|
412
|
+
this.untrackActiveRequestTransaction(active);
|
|
413
|
+
});
|
|
414
|
+
}, abortContext.signal);
|
|
282
415
|
this.throwIfRequestAborted(abortContext.signal);
|
|
283
416
|
return result;
|
|
284
417
|
} finally {
|
|
285
418
|
abortContext.cleanup();
|
|
286
|
-
this.untrackActiveRequestTransaction(active);
|
|
287
419
|
}
|
|
288
420
|
}
|
|
421
|
+
async closeTransactionBoundaryOwner(owner) {
|
|
422
|
+
while (owner.callbackSettlements.size > 0) {
|
|
423
|
+
await Promise.all(owner.callbackSettlements);
|
|
424
|
+
}
|
|
425
|
+
owner.closed = true;
|
|
426
|
+
}
|
|
289
427
|
assertRequestTransactionsAvailable() {
|
|
290
428
|
if (this.lifecycleState !== 'ready') {
|
|
291
429
|
throw new Error(REQUEST_TRANSACTION_UNAVAILABLE_ERROR);
|
package/dist/module.d.ts
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
import type { AsyncModuleOptions } from '@fluojs/core';
|
|
2
|
-
import {
|
|
2
|
+
import type { ModuleType } from '@fluojs/runtime';
|
|
3
3
|
import type { DrizzleDatabaseLike, DrizzleModuleOptions } from './types.js';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Configures an async Drizzle module registration through an injected factory.
|
|
6
|
+
*
|
|
7
|
+
* @typeParam TDatabase Root Drizzle database handle registered in the module.
|
|
8
|
+
* @typeParam TTransactionDatabase Transaction-scoped database handle resolved inside transaction callbacks.
|
|
9
|
+
* @typeParam TTransactionOptions Options forwarded to the underlying Drizzle transaction runner.
|
|
10
|
+
*/
|
|
11
|
+
export type DrizzleAsyncModuleOptions<TDatabase extends DrizzleDatabaseLike<TTransactionDatabase, TTransactionOptions>, TTransactionDatabase, TTransactionOptions> = AsyncModuleOptions<Omit<DrizzleModuleOptions<TDatabase, TTransactionDatabase, TTransactionOptions>, 'global' | 'name'>> & Pick<DrizzleModuleOptions<TDatabase, TTransactionDatabase, TTransactionOptions>, 'global' | 'name'>;
|
|
5
12
|
/**
|
|
6
13
|
* Module entrypoint for wiring a Drizzle database into the Fluo runtime lifecycle.
|
|
7
14
|
*/
|
|
8
15
|
export declare class DrizzleModule {
|
|
9
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Creates a module definition from static Drizzle options.
|
|
18
|
+
*
|
|
19
|
+
* @param options Static Drizzle registration options.
|
|
20
|
+
* @returns A runtime module definition for the requested Drizzle registration.
|
|
21
|
+
*/
|
|
10
22
|
static forRoot<TDatabase extends DrizzleDatabaseLike<TTransactionDatabase, TTransactionOptions>, TTransactionDatabase = TDatabase, TTransactionOptions = unknown>(options: DrizzleModuleOptions<TDatabase, TTransactionDatabase, TTransactionOptions>): ModuleType;
|
|
11
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Creates a module definition from DI-aware async Drizzle options.
|
|
25
|
+
*
|
|
26
|
+
* @param options Async Drizzle registration options.
|
|
27
|
+
* @returns A runtime module definition for the requested Drizzle registration.
|
|
28
|
+
*/
|
|
12
29
|
static forRootAsync<TDatabase extends DrizzleDatabaseLike<TTransactionDatabase, TTransactionOptions>, TTransactionDatabase = TDatabase, TTransactionOptions = unknown>(options: DrizzleAsyncModuleOptions<TDatabase, TTransactionDatabase, TTransactionOptions>): ModuleType;
|
|
13
30
|
}
|
|
14
|
-
export {};
|
|
15
31
|
//# sourceMappingURL=module.d.ts.map
|
package/dist/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,CACnC,SAAS,SAAS,mBAAmB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,EAChF,oBAAoB,EACpB,mBAAmB,IACjB,kBAAkB,CAAC,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,GACzH,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC;AAEtG;;GAEG;AACH,qBAAa,aAAa;IACxB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CACZ,SAAS,SAAS,mBAAmB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,EAChF,oBAAoB,GAAG,SAAS,EAChC,mBAAmB,GAAG,OAAO,EAC7B,OAAO,EAAE,oBAAoB,CAAC,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,GAAG,UAAU;IAIlG;;;;;OAKG;IACH,MAAM,CAAC,YAAY,CACjB,SAAS,SAAS,mBAAmB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,EAChF,oBAAoB,GAAG,SAAS,EAChC,mBAAmB,GAAG,OAAO,EAC7B,OAAO,EAAE,yBAAyB,CAAC,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,GAAG,UAAU;CAGxG"}
|
package/dist/module.js
CHANGED
|
@@ -1,89 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (!isObjectLike(options.database)) {
|
|
11
|
-
throw new Error('DrizzleModule requires a database option.');
|
|
12
|
-
}
|
|
13
|
-
return {
|
|
14
|
-
...options,
|
|
15
|
-
strictTransactions: options.strictTransactions ?? false
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function createRuntimeOptionsProviderValue(strictTransactions) {
|
|
19
|
-
return {
|
|
20
|
-
strictTransactions
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function createDrizzleRuntimeProviders(normalizedOptionsProvider) {
|
|
24
|
-
return [normalizedOptionsProvider, {
|
|
25
|
-
inject: [DRIZZLE_NORMALIZED_OPTIONS],
|
|
26
|
-
provide: DRIZZLE_DATABASE,
|
|
27
|
-
useFactory: options => options.database
|
|
28
|
-
}, {
|
|
29
|
-
inject: [DRIZZLE_NORMALIZED_OPTIONS],
|
|
30
|
-
provide: DRIZZLE_DISPOSE,
|
|
31
|
-
useFactory: options => options.dispose
|
|
32
|
-
}, {
|
|
33
|
-
inject: [DRIZZLE_NORMALIZED_OPTIONS],
|
|
34
|
-
provide: DRIZZLE_OPTIONS,
|
|
35
|
-
useFactory: options => createRuntimeOptionsProviderValue(options.strictTransactions)
|
|
36
|
-
}, {
|
|
37
|
-
inject: [DRIZZLE_DATABASE, DRIZZLE_DISPOSE, DRIZZLE_OPTIONS],
|
|
38
|
-
provide: DrizzleDatabase,
|
|
39
|
-
useFactory: (database, dispose, databaseOptions) => DrizzleDatabase.createFacade(database, dispose, databaseOptions)
|
|
40
|
-
}, {
|
|
41
|
-
provide: DRIZZLE_HANDLE_PROVIDER,
|
|
42
|
-
useExisting: DrizzleDatabase
|
|
43
|
-
}];
|
|
44
|
-
}
|
|
45
|
-
function createDrizzleProvidersAsync(options) {
|
|
46
|
-
const normalizedOptionsProvider = {
|
|
47
|
-
inject: options.inject,
|
|
48
|
-
provide: DRIZZLE_NORMALIZED_OPTIONS,
|
|
49
|
-
scope: 'singleton',
|
|
50
|
-
useFactory: async (...deps) => normalizeDrizzleModuleOptions({
|
|
51
|
-
...(await options.useFactory(...deps)),
|
|
52
|
-
global: options.global
|
|
53
|
-
})
|
|
54
|
-
};
|
|
55
|
-
return createDrizzleRuntimeProviders(normalizedOptionsProvider);
|
|
56
|
-
}
|
|
57
|
-
function buildDrizzleModule(options) {
|
|
58
|
-
class DrizzleRootModuleDefinition {}
|
|
59
|
-
return defineModule(DrizzleRootModuleDefinition, {
|
|
60
|
-
exports: DRIZZLE_MODULE_EXPORTS,
|
|
61
|
-
global: options.global ?? false,
|
|
62
|
-
providers: createDrizzleRuntimeProviders({
|
|
63
|
-
provide: DRIZZLE_NORMALIZED_OPTIONS,
|
|
64
|
-
useValue: normalizeDrizzleModuleOptions(options)
|
|
65
|
-
})
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
function buildDrizzleModuleAsync(options) {
|
|
69
|
-
class DrizzleAsyncModuleDefinition {}
|
|
70
|
-
return defineModule(DrizzleAsyncModuleDefinition, {
|
|
71
|
-
exports: DRIZZLE_MODULE_EXPORTS,
|
|
72
|
-
global: options.global ?? false,
|
|
73
|
-
providers: createDrizzleProvidersAsync(options)
|
|
74
|
-
});
|
|
75
|
-
}
|
|
1
|
+
import { buildDrizzleModule, buildDrizzleModuleAsync } from './named-registration.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configures an async Drizzle module registration through an injected factory.
|
|
5
|
+
*
|
|
6
|
+
* @typeParam TDatabase Root Drizzle database handle registered in the module.
|
|
7
|
+
* @typeParam TTransactionDatabase Transaction-scoped database handle resolved inside transaction callbacks.
|
|
8
|
+
* @typeParam TTransactionOptions Options forwarded to the underlying Drizzle transaction runner.
|
|
9
|
+
*/
|
|
76
10
|
|
|
77
11
|
/**
|
|
78
12
|
* Module entrypoint for wiring a Drizzle database into the Fluo runtime lifecycle.
|
|
79
13
|
*/
|
|
80
14
|
export class DrizzleModule {
|
|
81
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Creates a module definition from static Drizzle options.
|
|
17
|
+
*
|
|
18
|
+
* @param options Static Drizzle registration options.
|
|
19
|
+
* @returns A runtime module definition for the requested Drizzle registration.
|
|
20
|
+
*/
|
|
82
21
|
static forRoot(options) {
|
|
83
22
|
return buildDrizzleModule(options);
|
|
84
23
|
}
|
|
85
24
|
|
|
86
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Creates a module definition from DI-aware async Drizzle options.
|
|
27
|
+
*
|
|
28
|
+
* @param options Async Drizzle registration options.
|
|
29
|
+
* @returns A runtime module definition for the requested Drizzle registration.
|
|
30
|
+
*/
|
|
87
31
|
static forRootAsync(options) {
|
|
88
32
|
return buildDrizzleModuleAsync(options);
|
|
89
33
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ModuleType } from '@fluojs/runtime';
|
|
2
|
+
import type { DrizzleAsyncModuleOptions } from './module.js';
|
|
3
|
+
import type { DrizzleDatabaseLike, DrizzleModuleOptions } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Builds a synchronous Drizzle runtime module definition.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
* @param options Static Drizzle registration options.
|
|
9
|
+
* @returns A module definition for the default or named registration.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildDrizzleModule<TDatabase extends DrizzleDatabaseLike<TTransactionDatabase, TTransactionOptions>, TTransactionDatabase = TDatabase, TTransactionOptions = unknown>(options: DrizzleModuleOptions<TDatabase, TTransactionDatabase, TTransactionOptions>): ModuleType;
|
|
12
|
+
/**
|
|
13
|
+
* Builds an asynchronous Drizzle runtime module definition.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
* @param options Async Drizzle registration options.
|
|
17
|
+
* @returns A module definition for the default or named registration.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildDrizzleModuleAsync<TDatabase extends DrizzleDatabaseLike<TTransactionDatabase, TTransactionOptions>, TTransactionDatabase = TDatabase, TTransactionOptions = unknown>(options: DrizzleAsyncModuleOptions<TDatabase, TTransactionDatabase, TTransactionOptions>): ModuleType;
|
|
20
|
+
//# sourceMappingURL=named-registration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"named-registration.d.ts","sourceRoot":"","sources":["../src/named-registration.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAmB7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAmF5E;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,SAAS,mBAAmB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,EAChF,oBAAoB,GAAG,SAAS,EAChC,mBAAmB,GAAG,OAAO,EAC7B,OAAO,EAAE,oBAAoB,CAAC,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,GAAG,UAAU,CAajG;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,SAAS,mBAAmB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,EAChF,oBAAoB,GAAG,SAAS,EAChC,mBAAmB,GAAG,OAAO,EAC7B,OAAO,EAAE,yBAAyB,CAAC,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,GAAG,UAAU,CAUtG"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { defineModule } from '@fluojs/runtime';
|
|
2
|
+
import { DrizzleDatabase } from './database.js';
|
|
3
|
+
import { createDrizzleRuntimeProviders, getNormalizedOptionsToken, getRegistrationGuardToken } from './registration-providers.js';
|
|
4
|
+
import { normalizeDrizzleRegistrationName } from './registration-name.js';
|
|
5
|
+
import { DRIZZLE_DATABASE, DRIZZLE_DISPOSE, DRIZZLE_HANDLE_PROVIDER, DRIZZLE_OPTIONS, getDrizzleDatabaseToken, getDrizzleDisposeToken, getDrizzleHandleProviderToken, getDrizzleOptionsToken } from './tokens.js';
|
|
6
|
+
import { DrizzleTransactionInterceptor } from './transaction.js';
|
|
7
|
+
const DRIZZLE_MODULE_EXPORTS = [DrizzleDatabase, DrizzleTransactionInterceptor, DRIZZLE_HANDLE_PROVIDER, DRIZZLE_DATABASE, DRIZZLE_DISPOSE, DRIZZLE_OPTIONS];
|
|
8
|
+
function isObjectLike(value) {
|
|
9
|
+
return typeof value === 'object' && value !== null || typeof value === 'function';
|
|
10
|
+
}
|
|
11
|
+
function assertNamedRegistrationIsScoped(name, global) {
|
|
12
|
+
if (name !== undefined && global) {
|
|
13
|
+
throw new Error('Named Drizzle registrations are scoped and cannot be registered globally.');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function normalizeDrizzleModuleOptions(options) {
|
|
17
|
+
if (!isObjectLike(options.database)) {
|
|
18
|
+
throw new Error('DrizzleModule requires a database option.');
|
|
19
|
+
}
|
|
20
|
+
const name = normalizeDrizzleRegistrationName(options.name);
|
|
21
|
+
assertNamedRegistrationIsScoped(name, options.global);
|
|
22
|
+
return {
|
|
23
|
+
...options,
|
|
24
|
+
global: name === undefined ? options.global : false,
|
|
25
|
+
name,
|
|
26
|
+
strictTransactions: options.strictTransactions ?? false
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function createDrizzleProvidersAsync(options, name) {
|
|
30
|
+
const registrationGuardToken = name === undefined ? undefined : getRegistrationGuardToken(name);
|
|
31
|
+
const normalizedOptionsProvider = {
|
|
32
|
+
inject: registrationGuardToken === undefined ? options.inject : [registrationGuardToken, ...(options.inject ?? [])],
|
|
33
|
+
provide: getNormalizedOptionsToken(name),
|
|
34
|
+
scope: 'singleton',
|
|
35
|
+
useFactory: async (...dependencies) => normalizeDrizzleModuleOptions({
|
|
36
|
+
...(await options.useFactory(...(registrationGuardToken === undefined ? dependencies : dependencies.slice(1)))),
|
|
37
|
+
global: options.global,
|
|
38
|
+
name
|
|
39
|
+
})
|
|
40
|
+
};
|
|
41
|
+
return createDrizzleRuntimeProviders(normalizedOptionsProvider, name);
|
|
42
|
+
}
|
|
43
|
+
function getDrizzleModuleExports(name) {
|
|
44
|
+
return name === undefined ? DRIZZLE_MODULE_EXPORTS : [getDrizzleDatabaseToken(name), getDrizzleDisposeToken(name), getDrizzleHandleProviderToken(name), getDrizzleOptionsToken(name)];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Builds a synchronous Drizzle runtime module definition.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
* @param options Static Drizzle registration options.
|
|
52
|
+
* @returns A module definition for the default or named registration.
|
|
53
|
+
*/
|
|
54
|
+
export function buildDrizzleModule(options) {
|
|
55
|
+
const normalizedOptions = normalizeDrizzleModuleOptions(options);
|
|
56
|
+
const name = normalizedOptions.name;
|
|
57
|
+
class DrizzleRootModuleDefinition {}
|
|
58
|
+
return defineModule(DrizzleRootModuleDefinition, {
|
|
59
|
+
exports: getDrizzleModuleExports(name),
|
|
60
|
+
global: normalizedOptions.global ?? false,
|
|
61
|
+
providers: createDrizzleRuntimeProviders({
|
|
62
|
+
provide: getNormalizedOptionsToken(name),
|
|
63
|
+
useValue: normalizedOptions
|
|
64
|
+
}, name)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Builds an asynchronous Drizzle runtime module definition.
|
|
70
|
+
*
|
|
71
|
+
* @internal
|
|
72
|
+
* @param options Async Drizzle registration options.
|
|
73
|
+
* @returns A module definition for the default or named registration.
|
|
74
|
+
*/
|
|
75
|
+
export function buildDrizzleModuleAsync(options) {
|
|
76
|
+
const name = normalizeDrizzleRegistrationName(options.name);
|
|
77
|
+
assertNamedRegistrationIsScoped(name, options.global);
|
|
78
|
+
class DrizzleAsyncModuleDefinition {}
|
|
79
|
+
return defineModule(DrizzleAsyncModuleDefinition, {
|
|
80
|
+
exports: getDrizzleModuleExports(name),
|
|
81
|
+
global: name === undefined ? options.global ?? false : false,
|
|
82
|
+
providers: createDrizzleProvidersAsync(options, name)
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes a public Drizzle registration name before it becomes part of a DI token.
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
* @param name Optional registration name supplied by a module or token helper.
|
|
6
|
+
* @returns The trimmed registration name, or `undefined` for the default registration.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeDrizzleRegistrationName(name?: string): string | undefined;
|
|
9
|
+
//# sourceMappingURL=registration-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registration-name.d.ts","sourceRoot":"","sources":["../src/registration-name.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAYlF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes a public Drizzle registration name before it becomes part of a DI token.
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
* @param name Optional registration name supplied by a module or token helper.
|
|
6
|
+
* @returns The trimmed registration name, or `undefined` for the default registration.
|
|
7
|
+
*/
|
|
8
|
+
export function normalizeDrizzleRegistrationName(name) {
|
|
9
|
+
if (name === undefined) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
const normalizedName = name.trim();
|
|
13
|
+
if (normalizedName.length === 0) {
|
|
14
|
+
throw new Error('DrizzleModule name must be a non-empty string when provided.');
|
|
15
|
+
}
|
|
16
|
+
return normalizedName;
|
|
17
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Provider } from '@fluojs/di';
|
|
2
|
+
import type { DrizzleDatabaseLike, DrizzleModuleOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Normalized runtime options consumed by lifecycle-aware Drizzle providers.
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export type DrizzleRuntimeOptions = {
|
|
9
|
+
strictTransactions: boolean;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Fully normalized module options stored behind an internal registration token.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export type ResolvedDrizzleModuleOptions<TDatabase extends DrizzleDatabaseLike<TTransactionDatabase, TTransactionOptions>, TTransactionDatabase, TTransactionOptions> = Omit<DrizzleModuleOptions<TDatabase, TTransactionDatabase, TTransactionOptions>, 'strictTransactions'> & {
|
|
17
|
+
strictTransactions: boolean;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Returns the internal options token for a default or named registration.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
* @param name Optional normalized registration name.
|
|
24
|
+
* @returns The internal token that stores normalized module options.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getNormalizedOptionsToken(name?: string): symbol;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the globally stable duplicate-registration guard token for a name.
|
|
29
|
+
*
|
|
30
|
+
* @internal
|
|
31
|
+
* @param name Normalized named-registration identity.
|
|
32
|
+
* @returns The guard token shared by registrations using the same name.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getRegistrationGuardToken(name: string): symbol;
|
|
35
|
+
/**
|
|
36
|
+
* Builds the provider graph for a default or named Drizzle registration.
|
|
37
|
+
*
|
|
38
|
+
* @internal
|
|
39
|
+
* @param normalizedOptionsProvider Provider that supplies normalized module options.
|
|
40
|
+
* @param name Optional normalized registration name.
|
|
41
|
+
* @returns Providers for the registration's raw handle, lifecycle wrapper, options, and disposal hook.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createDrizzleRuntimeProviders<TDatabase extends DrizzleDatabaseLike<TTransactionDatabase, TTransactionOptions>, TTransactionDatabase, TTransactionOptions>(normalizedOptionsProvider: Provider, name?: string): Provider[];
|
|
44
|
+
//# sourceMappingURL=registration-providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registration-providers.d.ts","sourceRoot":"","sources":["../src/registration-providers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAU3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,4BAA4B,CACtC,SAAS,SAAS,mBAAmB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,EAChF,oBAAoB,EACpB,mBAAmB,IACjB,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,EAAE,oBAAoB,CAAC,GAAG;IAC3G,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CAAC;AAKF;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAoBD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,SAAS,mBAAmB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,EAChF,oBAAoB,EACpB,mBAAmB,EAEnB,yBAAyB,EAAE,QAAQ,EACnC,IAAI,CAAC,EAAE,MAAM,GACZ,QAAQ,EAAE,CAyGZ"}
|