@zenstackhq/runtime 3.0.0-alpha.13 → 3.0.0-alpha.14

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.
@@ -611,6 +611,10 @@ type OnKyselyQueryArgs<Schema extends SchemaDef> = {
611
611
  proceed: ProceedKyselyQueryFunction;
612
612
  };
613
613
  type ProceedKyselyQueryFunction = (query: RootOperationNode) => Promise<QueryResult<any>>;
614
+ type OnKyselyQueryCallback<Schema extends SchemaDef> = (args: OnKyselyQueryArgs<Schema>) => Promise<QueryResult<UnknownRow>>;
615
+ type MutationInterceptionFilter<Schema extends SchemaDef> = (args: MutationHooksArgs<Schema>) => MaybePromise<MutationInterceptionFilterResult>;
616
+ type BeforeEntityMutationCallback<Schema extends SchemaDef> = (args: PluginBeforeEntityMutationArgs<Schema>) => MaybePromise<void>;
617
+ type AfterEntityMutationCallback<Schema extends SchemaDef> = (args: PluginAfterEntityMutationArgs<Schema>) => MaybePromise<void>;
614
618
  /**
615
619
  * ZenStack runtime plugin.
616
620
  */
@@ -634,18 +638,18 @@ interface RuntimePlugin<Schema extends SchemaDef = SchemaDef> {
634
638
  /**
635
639
  * Intercepts a Kysely query.
636
640
  */
637
- onKyselyQuery?: (args: OnKyselyQueryArgs<Schema>) => Promise<QueryResult<UnknownRow>>;
641
+ onKyselyQuery?: OnKyselyQueryCallback<Schema>;
638
642
  /**
639
643
  * This callback determines whether a mutation should be intercepted, and if so,
640
644
  * what data should be loaded before and after the mutation.
641
645
  */
642
- mutationInterceptionFilter?: (args: MutationHooksArgs<Schema>) => MaybePromise<MutationInterceptionFilterResult>;
646
+ mutationInterceptionFilter?: MutationInterceptionFilter<Schema>;
643
647
  /**
644
648
  * Called before an entity is mutated.
645
649
  * @param args.entity Only available if `loadBeforeMutationEntity` is set to true in the
646
650
  * return value of {@link RuntimePlugin.mutationInterceptionFilter}.
647
651
  */
648
- beforeEntityMutation?: (args: PluginBeforeEntityMutationArgs<Schema>) => MaybePromise<void>;
652
+ beforeEntityMutation?: BeforeEntityMutationCallback<Schema>;
649
653
  /**
650
654
  * Called after an entity is mutated.
651
655
  * @param args.beforeMutationEntity Only available if `loadBeforeMutationEntity` is set to true in the
@@ -653,7 +657,7 @@ interface RuntimePlugin<Schema extends SchemaDef = SchemaDef> {
653
657
  * @param args.afterMutationEntity Only available if `loadAfterMutationEntity` is set to true in the
654
658
  * return value of {@link RuntimePlugin.mutationInterceptionFilter}.
655
659
  */
656
- afterEntityMutation?: (args: PluginAfterEntityMutationArgs<Schema>) => MaybePromise<void>;
660
+ afterEntityMutation?: AfterEntityMutationCallback<Schema>;
657
661
  }
658
662
  type OnQueryHooks<Schema extends SchemaDef = SchemaDef> = {
659
663
  [Model in GetModels<Schema> as Uncapitalize<Model>]?: OnQueryOperationHooks<Schema, Model>;
@@ -611,6 +611,10 @@ type OnKyselyQueryArgs<Schema extends SchemaDef> = {
611
611
  proceed: ProceedKyselyQueryFunction;
612
612
  };
613
613
  type ProceedKyselyQueryFunction = (query: RootOperationNode) => Promise<QueryResult<any>>;
614
+ type OnKyselyQueryCallback<Schema extends SchemaDef> = (args: OnKyselyQueryArgs<Schema>) => Promise<QueryResult<UnknownRow>>;
615
+ type MutationInterceptionFilter<Schema extends SchemaDef> = (args: MutationHooksArgs<Schema>) => MaybePromise<MutationInterceptionFilterResult>;
616
+ type BeforeEntityMutationCallback<Schema extends SchemaDef> = (args: PluginBeforeEntityMutationArgs<Schema>) => MaybePromise<void>;
617
+ type AfterEntityMutationCallback<Schema extends SchemaDef> = (args: PluginAfterEntityMutationArgs<Schema>) => MaybePromise<void>;
614
618
  /**
615
619
  * ZenStack runtime plugin.
616
620
  */
@@ -634,18 +638,18 @@ interface RuntimePlugin<Schema extends SchemaDef = SchemaDef> {
634
638
  /**
635
639
  * Intercepts a Kysely query.
636
640
  */
637
- onKyselyQuery?: (args: OnKyselyQueryArgs<Schema>) => Promise<QueryResult<UnknownRow>>;
641
+ onKyselyQuery?: OnKyselyQueryCallback<Schema>;
638
642
  /**
639
643
  * This callback determines whether a mutation should be intercepted, and if so,
640
644
  * what data should be loaded before and after the mutation.
641
645
  */
642
- mutationInterceptionFilter?: (args: MutationHooksArgs<Schema>) => MaybePromise<MutationInterceptionFilterResult>;
646
+ mutationInterceptionFilter?: MutationInterceptionFilter<Schema>;
643
647
  /**
644
648
  * Called before an entity is mutated.
645
649
  * @param args.entity Only available if `loadBeforeMutationEntity` is set to true in the
646
650
  * return value of {@link RuntimePlugin.mutationInterceptionFilter}.
647
651
  */
648
- beforeEntityMutation?: (args: PluginBeforeEntityMutationArgs<Schema>) => MaybePromise<void>;
652
+ beforeEntityMutation?: BeforeEntityMutationCallback<Schema>;
649
653
  /**
650
654
  * Called after an entity is mutated.
651
655
  * @param args.beforeMutationEntity Only available if `loadBeforeMutationEntity` is set to true in the
@@ -653,7 +657,7 @@ interface RuntimePlugin<Schema extends SchemaDef = SchemaDef> {
653
657
  * @param args.afterMutationEntity Only available if `loadAfterMutationEntity` is set to true in the
654
658
  * return value of {@link RuntimePlugin.mutationInterceptionFilter}.
655
659
  */
656
- afterEntityMutation?: (args: PluginAfterEntityMutationArgs<Schema>) => MaybePromise<void>;
660
+ afterEntityMutation?: AfterEntityMutationCallback<Schema>;
657
661
  }
658
662
  type OnQueryHooks<Schema extends SchemaDef = SchemaDef> = {
659
663
  [Model in GetModels<Schema> as Uncapitalize<Model>]?: OnQueryOperationHooks<Schema, Model>;
package/dist/index.cjs CHANGED
@@ -2666,14 +2666,14 @@ var BaseOperationHandler = class {
2666
2666
  getField(model, field) {
2667
2667
  return getField(this.schema, model, field);
2668
2668
  }
2669
- exists(kysely, model, filter) {
2669
+ async exists(kysely, model, filter) {
2670
2670
  const idFields = getIdFields(this.schema, model);
2671
2671
  const _filter = flattenCompoundUniqueFilters(this.schema, model, filter);
2672
2672
  const query = kysely.selectFrom(model).where((eb) => eb.and(_filter)).select(idFields.map((f) => kysely.dynamic.ref(f))).limit(1).modifyEnd(this.makeContextComment({
2673
2673
  model,
2674
2674
  operation: "read"
2675
2675
  }));
2676
- return query.executeTakeFirst();
2676
+ return this.executeQueryTakeFirst(kysely, query, "exists");
2677
2677
  }
2678
2678
  async read(kysely, model, args) {
2679
2679
  let query = this.dialect.buildSelectModel((0, import_kysely8.expressionBuilder)(), model);
@@ -2850,7 +2850,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2850
2850
  model: fromRelation.model,
2851
2851
  operation: "update"
2852
2852
  }));
2853
- return query2.execute();
2853
+ return this.executeQuery(kysely, query2, "update");
2854
2854
  }, "parentUpdateTask");
2855
2855
  }
2856
2856
  }
@@ -2889,7 +2889,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
2889
2889
  model,
2890
2890
  operation: "create"
2891
2891
  }));
2892
- const createdEntity = await query.executeTakeFirst();
2892
+ const createdEntity = await this.executeQueryTakeFirst(kysely, query, "create");
2893
2893
  if (Object.keys(postCreateRelations).length > 0) {
2894
2894
  const relationPromises = Object.entries(postCreateRelations).map(([field, subPayload]) => {
2895
2895
  return this.processNoneOwnedRelationForCreate(kysely, model, field, subPayload, createdEntity);
@@ -3121,9 +3121,9 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3121
3121
  operation: "create"
3122
3122
  }));
3123
3123
  if (!returnData) {
3124
- const result = await query.executeTakeFirstOrThrow();
3124
+ const result = await this.executeQuery(kysely, query, "createMany");
3125
3125
  return {
3126
- count: Number(result.numInsertedOrUpdatedRows)
3126
+ count: Number(result.numAffectedRows)
3127
3127
  };
3128
3128
  } else {
3129
3129
  const idFields = getIdFields(this.schema, model);
@@ -3302,7 +3302,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3302
3302
  model,
3303
3303
  operation: "update"
3304
3304
  }));
3305
- const updatedEntity = await query.executeTakeFirst();
3305
+ const updatedEntity = await this.executeQueryTakeFirst(kysely, query, "update");
3306
3306
  if (!updatedEntity) {
3307
3307
  if (throwIfNotFound) {
3308
3308
  throw new NotFoundError(model);
@@ -3442,9 +3442,9 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3442
3442
  operation: "update"
3443
3443
  }));
3444
3444
  if (!returnData) {
3445
- const result = await query.executeTakeFirstOrThrow();
3445
+ const result = await this.executeQuery(kysely, query, "update");
3446
3446
  return {
3447
- count: Number(result.numUpdatedRows)
3447
+ count: Number(result.numAffectedRows)
3448
3448
  };
3449
3449
  } else {
3450
3450
  const idFields = getIdFields(this.schema, model);
@@ -3589,7 +3589,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3589
3589
  model: fromRelation.model,
3590
3590
  operation: "update"
3591
3591
  }));
3592
- updateResult = await query.executeTakeFirstOrThrow();
3592
+ updateResult = await this.executeQuery(kysely, query, "connect");
3593
3593
  } else {
3594
3594
  const relationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
3595
3595
  if (!relationFieldDef.array) {
@@ -3600,7 +3600,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3600
3600
  model: fromRelation.model,
3601
3601
  operation: "update"
3602
3602
  }));
3603
- await query2.execute();
3603
+ await this.executeQuery(kysely, query2, "disconnect");
3604
3604
  }
3605
3605
  const query = kysely.updateTable(model).where((eb) => eb.or(_data.map((d) => eb.and(d)))).set(keyPairs.reduce((acc, { fk, pk }) => ({
3606
3606
  ...acc,
@@ -3609,9 +3609,9 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3609
3609
  model,
3610
3610
  operation: "update"
3611
3611
  }));
3612
- updateResult = await query.executeTakeFirstOrThrow();
3612
+ updateResult = await this.executeQuery(kysely, query, "connect");
3613
3613
  }
3614
- if (_data.length > updateResult.numUpdatedRows) {
3614
+ if (_data.length > updateResult.numAffectedRows) {
3615
3615
  throw new NotFoundError(model);
3616
3616
  }
3617
3617
  }
@@ -3679,7 +3679,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3679
3679
  model: fromRelation.model,
3680
3680
  operation: "update"
3681
3681
  }));
3682
- await query.executeTakeFirstOrThrow();
3682
+ await this.executeQuery(kysely, query, "disconnect");
3683
3683
  } else {
3684
3684
  const query = kysely.updateTable(model).where(eb.and([
3685
3685
  // fk filter
@@ -3696,7 +3696,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3696
3696
  model,
3697
3697
  operation: "update"
3698
3698
  }));
3699
- await query.executeTakeFirstOrThrow();
3699
+ await this.executeQuery(kysely, query, "disconnect");
3700
3700
  }
3701
3701
  }
3702
3702
  }
@@ -3734,7 +3734,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3734
3734
  model,
3735
3735
  operation: "update"
3736
3736
  }));
3737
- await query.execute();
3737
+ await this.executeQuery(kysely, query, "disconnect");
3738
3738
  if (_data.length > 0) {
3739
3739
  const query2 = kysely.updateTable(model).where((eb) => eb.or(_data.map((d) => eb.and(d)))).set(keyPairs.reduce((acc, { fk, pk }) => ({
3740
3740
  ...acc,
@@ -3743,8 +3743,8 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3743
3743
  model,
3744
3744
  operation: "update"
3745
3745
  }));
3746
- const r = await query2.executeTakeFirstOrThrow();
3747
- if (_data.length > r.numUpdatedRows) {
3746
+ const r = await this.executeQuery(kysely, query2, "connect");
3747
+ if (_data.length > r.numAffectedRows) {
3748
3748
  throw new NotFoundError(model);
3749
3749
  }
3750
3750
  }
@@ -3860,9 +3860,9 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3860
3860
  model,
3861
3861
  operation: "delete"
3862
3862
  }));
3863
- const result = await query.executeTakeFirstOrThrow();
3863
+ const result = await this.executeQuery(kysely, query, "delete");
3864
3864
  return {
3865
- count: Number(result.numDeletedRows)
3865
+ count: Number(result.numAffectedRows)
3866
3866
  };
3867
3867
  }
3868
3868
  async processDelegateRelationDelete(kysely, modelDef, where, limit) {
@@ -3959,6 +3959,25 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
3959
3959
  }
3960
3960
  }
3961
3961
  }
3962
+ makeQueryId(operation) {
3963
+ return {
3964
+ queryId: `${operation}-${(0, import_cuid2.createId)()}`
3965
+ };
3966
+ }
3967
+ executeQuery(kysely, query, operation) {
3968
+ return kysely.executeQuery(query.compile(), this.makeQueryId(operation));
3969
+ }
3970
+ async executeQueryTakeFirst(kysely, query, operation) {
3971
+ const result = await kysely.executeQuery(query.compile(), this.makeQueryId(operation));
3972
+ return result.rows[0];
3973
+ }
3974
+ async executeQueryTakeFirstOrThrow(kysely, query, operation) {
3975
+ const result = await kysely.executeQuery(query.compile(), this.makeQueryId(operation));
3976
+ if (result.rows.length === 0) {
3977
+ throw new QueryError("No rows found");
3978
+ }
3979
+ return result.rows[0];
3980
+ }
3962
3981
  };
3963
3982
 
3964
3983
  // src/client/crud/operations/aggregate.ts
@@ -4031,9 +4050,9 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4031
4050
  }
4032
4051
  }
4033
4052
  }
4034
- const result = await query.executeTakeFirstOrThrow();
4053
+ const result = await this.executeQuery(this.kysely, query, "aggregate");
4035
4054
  const ret = {};
4036
- for (const [key, value] of Object.entries(result)) {
4055
+ for (const [key, value] of Object.entries(result.rows[0])) {
4037
4056
  if (key === "_count") {
4038
4057
  ret[key] = value;
4039
4058
  continue;
@@ -4095,11 +4114,12 @@ var CountOperationHandler = class extends BaseOperationHandler {
4095
4114
  });
4096
4115
  if (parsedArgs?.select && typeof parsedArgs.select === "object") {
4097
4116
  query = query.select((eb) => Object.keys(parsedArgs.select).map((key) => key === "_all" ? eb.cast(eb.fn.countAll(), "integer").as("_all") : eb.cast(eb.fn.count(import_kysely10.sql.ref(`${subQueryName}.${key}`)), "integer").as(key)));
4098
- return query.executeTakeFirstOrThrow();
4117
+ const result = await this.executeQuery(this.kysely, query, "count");
4118
+ return result.rows[0];
4099
4119
  } else {
4100
4120
  query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as("count"));
4101
- const result = await query.executeTakeFirstOrThrow();
4102
- return result.count;
4121
+ const result = await this.executeQuery(this.kysely, query, "count");
4122
+ return result.rows[0].count;
4103
4123
  }
4104
4124
  }
4105
4125
  };
@@ -4179,7 +4199,7 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
4179
4199
  throw new NotFoundError(this.model);
4180
4200
  }
4181
4201
  await this.safeTransaction(async (tx) => {
4182
- const result = await this.delete(tx, this.model, args.where, void 0);
4202
+ const result = await this.delete(tx, this.model, args.where);
4183
4203
  if (result.count === 0) {
4184
4204
  throw new NotFoundError(this.model);
4185
4205
  }
@@ -4278,8 +4298,8 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4278
4298
  }
4279
4299
  }
4280
4300
  }
4281
- const result = await query.execute();
4282
- return result.map((row) => this.postProcessRow(row));
4301
+ const result = await this.executeQuery(this.kysely, query, "groupBy");
4302
+ return result.rows.map((row) => this.postProcessRow(row));
4283
4303
  }
4284
4304
  postProcessRow(row) {
4285
4305
  const ret = {};
@@ -5282,11 +5302,11 @@ var ZenStackDriver = class {
5282
5302
  }
5283
5303
  #driver;
5284
5304
  #log;
5285
- txConnection;
5286
5305
  #initPromise;
5287
5306
  #initDone;
5288
5307
  #destroyPromise;
5289
5308
  #connections = /* @__PURE__ */ new WeakSet();
5309
+ #txConnections = /* @__PURE__ */ new WeakMap();
5290
5310
  constructor(driver, log) {
5291
5311
  this.#initDone = false;
5292
5312
  this.#driver = driver;
@@ -5327,21 +5347,30 @@ var ZenStackDriver = class {
5327
5347
  }
5328
5348
  async beginTransaction(connection, settings) {
5329
5349
  const result = await this.#driver.beginTransaction(connection, settings);
5330
- this.txConnection = connection;
5350
+ this.#txConnections.set(connection, []);
5331
5351
  return result;
5332
5352
  }
5333
- commitTransaction(connection) {
5353
+ async commitTransaction(connection) {
5334
5354
  try {
5335
- return this.#driver.commitTransaction(connection);
5336
- } finally {
5337
- this.txConnection = void 0;
5355
+ const result = await this.#driver.commitTransaction(connection);
5356
+ const callbacks = this.#txConnections.get(connection);
5357
+ this.#txConnections.delete(connection);
5358
+ if (callbacks) {
5359
+ for (const callback of callbacks) {
5360
+ await callback();
5361
+ }
5362
+ }
5363
+ return result;
5364
+ } catch (err) {
5365
+ this.#txConnections.delete(connection);
5366
+ throw err;
5338
5367
  }
5339
5368
  }
5340
- rollbackTransaction(connection) {
5369
+ async rollbackTransaction(connection) {
5341
5370
  try {
5342
- return this.#driver.rollbackTransaction(connection);
5371
+ return await this.#driver.rollbackTransaction(connection);
5343
5372
  } finally {
5344
- this.txConnection = void 0;
5373
+ this.#txConnections.delete(connection);
5345
5374
  }
5346
5375
  }
5347
5376
  async destroy() {
@@ -5419,6 +5448,22 @@ var ZenStackDriver = class {
5419
5448
  #calculateDurationMillis(startTime) {
5420
5449
  return performanceNow() - startTime;
5421
5450
  }
5451
+ isTransactionConnection(connection) {
5452
+ return this.#txConnections.has(connection);
5453
+ }
5454
+ registerTransactionCommitCallback(connection, callback) {
5455
+ if (!this.#txConnections.has(connection)) {
5456
+ return;
5457
+ }
5458
+ const callbacks = this.#txConnections.get(connection);
5459
+ if (callbacks) {
5460
+ callbacks.push(callback);
5461
+ } else {
5462
+ this.#txConnections.set(connection, [
5463
+ callback
5464
+ ]);
5465
+ }
5466
+ }
5422
5467
  };
5423
5468
  function performanceNow() {
5424
5469
  if (typeof performance !== "undefined" && typeof performance.now === "function") {
@@ -5660,7 +5705,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5660
5705
  get options() {
5661
5706
  return this.client.$options;
5662
5707
  }
5663
- async executeQuery(compiledQuery, queryId) {
5708
+ async executeQuery(compiledQuery, _queryId) {
5664
5709
  let queryNode = compiledQuery.query;
5665
5710
  let mutationInterceptionInfo;
5666
5711
  if (this.isMutationNode(queryNode) && this.hasMutationHooks) {
@@ -5671,7 +5716,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5671
5716
  await this.callBeforeMutationHooks(queryNode, mutationInterceptionInfo);
5672
5717
  }
5673
5718
  const oldQueryNode = queryNode;
5674
- if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.DeleteQueryNode.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntity) {
5719
+ if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntity) {
5675
5720
  queryNode = {
5676
5721
  ...queryNode,
5677
5722
  returning: import_kysely13.ReturningNode.create([
@@ -5680,34 +5725,49 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5680
5725
  };
5681
5726
  }
5682
5727
  const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
5683
- const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryParams, queryId);
5728
+ const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryParams);
5684
5729
  if (this.isMutationNode(queryNode)) {
5685
- await this.callAfterQueryInterceptionFilters(result, queryNode, mutationInterceptionInfo);
5730
+ await this.callAfterMutationHooks(result.result, queryNode, mutationInterceptionInfo, result.connection);
5686
5731
  }
5687
5732
  if (oldQueryNode !== queryNode) {
5688
5733
  }
5689
- return result;
5734
+ return result.result;
5690
5735
  }, "task");
5691
5736
  return task();
5692
5737
  }
5693
- proceedQueryWithKyselyInterceptors(queryNode, parameters, queryId) {
5694
- let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters, queryId), "proceed");
5695
- const hooks = this.options.plugins?.filter((plugin) => typeof plugin.onKyselyQuery === "function").map((plugin) => plugin.onKyselyQuery.bind(plugin)) ?? [];
5738
+ proceedQueryWithKyselyInterceptors(queryNode, parameters) {
5739
+ let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters), "proceed");
5740
+ const hooks = [];
5741
+ for (const plugin of this.client.$options.plugins ?? []) {
5742
+ if (plugin.onKyselyQuery) {
5743
+ hooks.push(plugin.onKyselyQuery.bind(plugin));
5744
+ }
5745
+ }
5696
5746
  for (const hook of hooks) {
5697
5747
  const _proceed = proceed;
5698
- proceed = /* @__PURE__ */ __name((query) => {
5699
- return hook({
5748
+ proceed = /* @__PURE__ */ __name(async (query) => {
5749
+ let connection;
5750
+ const _p = /* @__PURE__ */ __name(async (q) => {
5751
+ const r = await _proceed(q);
5752
+ connection = r.connection;
5753
+ return r.result;
5754
+ }, "_p");
5755
+ const hookResult = await hook({
5700
5756
  client: this.client,
5701
5757
  schema: this.client.$schema,
5702
5758
  kysely: this.kysely,
5703
5759
  query,
5704
- proceed: _proceed
5760
+ proceed: _p
5705
5761
  });
5762
+ return {
5763
+ result: hookResult,
5764
+ connection
5765
+ };
5706
5766
  }, "proceed");
5707
5767
  }
5708
5768
  return proceed(queryNode);
5709
5769
  }
5710
- async proceedQuery(query, parameters, queryId) {
5770
+ async proceedQuery(query, parameters) {
5711
5771
  const finalQuery = this.nameMapper.transformNode(query);
5712
5772
  let compiled = this.compileQuery(finalQuery);
5713
5773
  if (parameters) {
@@ -5717,7 +5777,13 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5717
5777
  };
5718
5778
  }
5719
5779
  try {
5720
- return await super.executeQuery(compiled, queryId);
5780
+ return await this.provideConnection(async (connection) => {
5781
+ const result = await connection.executeQuery(compiled);
5782
+ return {
5783
+ result,
5784
+ connection
5785
+ };
5786
+ });
5721
5787
  } catch (err) {
5722
5788
  let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
5723
5789
  if (this.options.debug) {
@@ -5820,10 +5886,11 @@ ${compiled.parameters.map((p) => (0, import_node_util2.inspect)(p)).join("\n")}`
5820
5886
  return;
5821
5887
  }
5822
5888
  if (this.options.plugins) {
5889
+ const mutationModel = this.getMutationModel(queryNode);
5823
5890
  for (const plugin of this.options.plugins) {
5824
5891
  if (plugin.beforeEntityMutation) {
5825
5892
  await plugin.beforeEntityMutation({
5826
- model: this.getMutationModel(queryNode),
5893
+ model: mutationModel,
5827
5894
  action: mutationInterceptionInfo.action,
5828
5895
  queryNode,
5829
5896
  entities: mutationInterceptionInfo.beforeMutationEntities
@@ -5832,30 +5899,45 @@ ${compiled.parameters.map((p) => (0, import_node_util2.inspect)(p)).join("\n")}`
5832
5899
  }
5833
5900
  }
5834
5901
  }
5835
- async callAfterQueryInterceptionFilters(queryResult, queryNode, mutationInterceptionInfo) {
5902
+ async callAfterMutationHooks(queryResult, queryNode, mutationInterceptionInfo, connection) {
5836
5903
  if (!mutationInterceptionInfo?.intercept) {
5837
5904
  return;
5838
5905
  }
5839
- if (this.options.plugins) {
5840
- const mutationModel = this.getMutationModel(queryNode);
5841
- for (const plugin of this.options.plugins) {
5842
- if (plugin.afterEntityMutation) {
5843
- let afterMutationEntities = void 0;
5844
- if (mutationInterceptionInfo.loadAfterMutationEntity) {
5845
- if (import_kysely13.UpdateQueryNode.is(queryNode)) {
5846
- afterMutationEntities = await this.loadEntities(mutationModel, mutationInterceptionInfo.where);
5847
- } else {
5848
- afterMutationEntities = queryResult.rows;
5849
- }
5850
- }
5851
- await plugin.afterEntityMutation({
5852
- model: this.getMutationModel(queryNode),
5906
+ const hooks = [];
5907
+ for (const plugin of this.options.plugins ?? []) {
5908
+ if (plugin.afterEntityMutation) {
5909
+ hooks.push(plugin.afterEntityMutation.bind(plugin));
5910
+ }
5911
+ }
5912
+ if (hooks.length === 0) {
5913
+ return;
5914
+ }
5915
+ const mutationModel = this.getMutationModel(queryNode);
5916
+ const inTransaction = this.driver.isTransactionConnection(connection);
5917
+ for (const hook of hooks) {
5918
+ let afterMutationEntities = void 0;
5919
+ if (mutationInterceptionInfo.loadAfterMutationEntity) {
5920
+ if (import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) {
5921
+ afterMutationEntities = queryResult.rows;
5922
+ }
5923
+ }
5924
+ const action = /* @__PURE__ */ __name(async () => {
5925
+ try {
5926
+ await hook({
5927
+ model: mutationModel,
5853
5928
  action: mutationInterceptionInfo.action,
5854
5929
  queryNode,
5855
5930
  beforeMutationEntities: mutationInterceptionInfo.beforeMutationEntities,
5856
5931
  afterMutationEntities
5857
5932
  });
5933
+ } catch (err) {
5934
+ console.error(`Error in afterEntityMutation hook for model "${mutationModel}": ${err}`);
5858
5935
  }
5936
+ }, "action");
5937
+ if (inTransaction) {
5938
+ this.driver.registerTransactionCommitCallback(connection, action);
5939
+ } else {
5940
+ await action();
5859
5941
  }
5860
5942
  }
5861
5943
  }
@@ -6494,19 +6576,26 @@ var ClientImpl = class _ClientImpl {
6494
6576
  await new SchemaDbPusher(this.schema, this.kysely).push();
6495
6577
  }
6496
6578
  $use(plugin) {
6579
+ const newPlugins = [
6580
+ ...this.$options.plugins ?? [],
6581
+ plugin
6582
+ ];
6497
6583
  const newOptions = {
6498
6584
  ...this.options,
6499
- plugins: [
6500
- ...this.options.plugins ?? [],
6501
- plugin
6502
- ]
6585
+ plugins: newPlugins
6503
6586
  };
6504
6587
  return new _ClientImpl(this.schema, newOptions, this);
6505
6588
  }
6506
6589
  $unuse(pluginId) {
6590
+ const newPlugins = [];
6591
+ for (const plugin of this.options.plugins ?? []) {
6592
+ if (plugin.id !== pluginId) {
6593
+ newPlugins.push(plugin);
6594
+ }
6595
+ }
6507
6596
  const newOptions = {
6508
6597
  ...this.options,
6509
- plugins: this.options.plugins?.filter((p) => p.id !== pluginId)
6598
+ plugins: newPlugins
6510
6599
  };
6511
6600
  return new _ClientImpl(this.schema, newOptions, this);
6512
6601
  }