@fragno-dev/db 0.2.1 → 0.2.2

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.
Files changed (60) hide show
  1. package/.turbo/turbo-build.log +34 -30
  2. package/CHANGELOG.md +32 -0
  3. package/dist/adapters/generic-sql/query/where-builder.js +1 -1
  4. package/dist/db-fragment-definition-builder.d.ts +27 -89
  5. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  6. package/dist/db-fragment-definition-builder.js +16 -56
  7. package/dist/db-fragment-definition-builder.js.map +1 -1
  8. package/dist/fragments/internal-fragment.d.ts +94 -8
  9. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  10. package/dist/fragments/internal-fragment.js +56 -55
  11. package/dist/fragments/internal-fragment.js.map +1 -1
  12. package/dist/hooks/hooks.d.ts +5 -3
  13. package/dist/hooks/hooks.d.ts.map +1 -1
  14. package/dist/hooks/hooks.js +38 -37
  15. package/dist/hooks/hooks.js.map +1 -1
  16. package/dist/mod.d.ts +3 -3
  17. package/dist/mod.d.ts.map +1 -1
  18. package/dist/mod.js +4 -4
  19. package/dist/mod.js.map +1 -1
  20. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +351 -100
  21. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  22. package/dist/query/unit-of-work/execute-unit-of-work.js +431 -263
  23. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  24. package/dist/query/unit-of-work/unit-of-work.d.ts +17 -8
  25. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  26. package/dist/query/unit-of-work/unit-of-work.js +24 -8
  27. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  28. package/dist/query/value-decoding.js +1 -1
  29. package/dist/schema/create.d.ts +3 -1
  30. package/dist/schema/create.d.ts.map +1 -1
  31. package/dist/schema/create.js +2 -1
  32. package/dist/schema/create.js.map +1 -1
  33. package/dist/schema/generate-id.d.ts +20 -0
  34. package/dist/schema/generate-id.d.ts.map +1 -0
  35. package/dist/schema/generate-id.js +28 -0
  36. package/dist/schema/generate-id.js.map +1 -0
  37. package/package.json +1 -1
  38. package/src/adapters/drizzle/drizzle-adapter-sqlite3.test.ts +41 -25
  39. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +39 -25
  40. package/src/db-fragment-definition-builder.test.ts +58 -42
  41. package/src/db-fragment-definition-builder.ts +58 -248
  42. package/src/db-fragment-instantiator.test.ts +64 -88
  43. package/src/db-fragment-integration.test.ts +292 -142
  44. package/src/fragments/internal-fragment.test.ts +272 -266
  45. package/src/fragments/internal-fragment.ts +155 -121
  46. package/src/hooks/hooks.test.ts +248 -256
  47. package/src/hooks/hooks.ts +74 -63
  48. package/src/mod.ts +14 -4
  49. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1494 -1464
  50. package/src/query/unit-of-work/execute-unit-of-work.ts +1685 -590
  51. package/src/query/unit-of-work/tx-builder.test.ts +1041 -0
  52. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +20 -20
  53. package/src/query/unit-of-work/unit-of-work.test.ts +64 -0
  54. package/src/query/unit-of-work/unit-of-work.ts +26 -13
  55. package/src/schema/create.ts +2 -0
  56. package/src/schema/generate-id.test.ts +57 -0
  57. package/src/schema/generate-id.ts +38 -0
  58. package/src/shared/config.ts +0 -10
  59. package/src/shared/connection-pool.ts +0 -24
  60. package/src/shared/prisma.ts +0 -45
@@ -57,8 +57,11 @@ describe("Hook System", () => {
57
57
  const onBeforeMutate = vi.fn();
58
58
 
59
59
  await internalFragment.inContext(async function () {
60
- await this.uow(
61
- async ({ forSchema, executeMutate }) => {
60
+ await this.handlerTx({
61
+ onAfterMutate: onSuccess,
62
+ onBeforeMutate,
63
+ })
64
+ .mutate(({ forSchema }) => {
62
65
  const uow = forSchema(internalSchema, hooks);
63
66
 
64
67
  // Trigger a hook
@@ -71,14 +74,8 @@ describe("Hook System", () => {
71
74
  internalFragment,
72
75
  defaultRetryPolicy: new ExponentialBackoffRetryPolicy({ maxRetries: 5 }),
73
76
  });
74
-
75
- await executeMutate();
76
- },
77
- {
78
- onSuccess,
79
- onBeforeMutate,
80
- },
81
- );
77
+ })
78
+ .execute();
82
79
  });
83
80
 
84
81
  // Verify callbacks were executed
@@ -87,11 +84,12 @@ describe("Hook System", () => {
87
84
 
88
85
  // Verify hook was created
89
86
  const events = await internalFragment.inContext(async function () {
90
- return await this.uow(async ({ executeRetrieve }) => {
91
- const result = internalFragment.services.hookService.getPendingHookEvents(namespace);
92
- await executeRetrieve();
93
- return result;
94
- });
87
+ return await this.handlerTx()
88
+ .withServiceCalls(
89
+ () => [internalFragment.services.hookService.getPendingHookEvents(namespace)] as const,
90
+ )
91
+ .transform(({ serviceResult: [result] }) => result)
92
+ .execute();
95
93
  });
96
94
 
97
95
  expect(events).toHaveLength(1);
@@ -110,28 +108,29 @@ describe("Hook System", () => {
110
108
  };
111
109
 
112
110
  await internalFragment.inContext(async function () {
113
- await this.uow(async ({ forSchema, executeMutate }) => {
114
- const uow = forSchema(internalSchema, hooks);
115
-
116
- uow.triggerHook("onNoRetry", { data: "test" });
111
+ await this.handlerTx()
112
+ .mutate(({ forSchema }) => {
113
+ const uow = forSchema(internalSchema, hooks);
117
114
 
118
- prepareHookMutations(uow, {
119
- hooks,
120
- namespace,
121
- internalFragment,
122
- defaultRetryPolicy: new NoRetryPolicy(),
123
- });
115
+ uow.triggerHook("onNoRetry", { data: "test" });
124
116
 
125
- await executeMutate();
126
- });
117
+ prepareHookMutations(uow, {
118
+ hooks,
119
+ namespace,
120
+ internalFragment,
121
+ defaultRetryPolicy: new NoRetryPolicy(),
122
+ });
123
+ })
124
+ .execute();
127
125
  });
128
126
 
129
127
  const events = await internalFragment.inContext(async function () {
130
- return await this.uow(async ({ executeRetrieve }) => {
131
- const result = internalFragment.services.hookService.getPendingHookEvents(namespace);
132
- await executeRetrieve();
133
- return result;
134
- });
128
+ return await this.handlerTx()
129
+ .withServiceCalls(
130
+ () => [internalFragment.services.hookService.getPendingHookEvents(namespace)] as const,
131
+ )
132
+ .transform(({ serviceResult: [result] }) => result)
133
+ .execute();
135
134
  });
136
135
 
137
136
  expect(events).toHaveLength(1);
@@ -145,34 +144,35 @@ describe("Hook System", () => {
145
144
  };
146
145
 
147
146
  await internalFragment.inContext(async function () {
148
- await this.uow(async ({ forSchema, executeMutate }) => {
149
- const uow = forSchema(internalSchema, hooks);
150
-
151
- uow.triggerHook(
152
- "onCustomRetry",
153
- { data: "test" },
154
- {
155
- retryPolicy: new NoRetryPolicy(),
156
- },
157
- );
158
-
159
- prepareHookMutations(uow, {
160
- hooks,
161
- namespace,
162
- internalFragment,
163
- defaultRetryPolicy: new ExponentialBackoffRetryPolicy({ maxRetries: 10 }),
164
- });
165
-
166
- await executeMutate();
167
- });
147
+ await this.handlerTx()
148
+ .mutate(({ forSchema }) => {
149
+ const uow = forSchema(internalSchema, hooks);
150
+
151
+ uow.triggerHook(
152
+ "onCustomRetry",
153
+ { data: "test" },
154
+ {
155
+ retryPolicy: new NoRetryPolicy(),
156
+ },
157
+ );
158
+
159
+ prepareHookMutations(uow, {
160
+ hooks,
161
+ namespace,
162
+ internalFragment,
163
+ defaultRetryPolicy: new ExponentialBackoffRetryPolicy({ maxRetries: 10 }),
164
+ });
165
+ })
166
+ .execute();
168
167
  });
169
168
 
170
169
  const events = await internalFragment.inContext(async function () {
171
- return await this.uow(async ({ executeRetrieve }) => {
172
- const result = internalFragment.services.hookService.getPendingHookEvents(namespace);
173
- await executeRetrieve();
174
- return result;
175
- });
170
+ return await this.handlerTx()
171
+ .withServiceCalls(
172
+ () => [internalFragment.services.hookService.getPendingHookEvents(namespace)] as const,
173
+ )
174
+ .transform(({ serviceResult: [result] }) => result)
175
+ .execute();
176
176
  });
177
177
 
178
178
  expect(events[0]?.maxAttempts).toBe(1);
@@ -191,22 +191,24 @@ describe("Hook System", () => {
191
191
 
192
192
  // Create a pending hook event
193
193
  await internalFragment.inContext(async function () {
194
- await this.uow(async ({ forSchema, executeMutate }) => {
195
- const uow = forSchema(internalSchema);
196
- eventId = uow.create("fragno_hooks", {
197
- namespace,
198
- hookName: "onSuccess",
199
- payload: { email: "test@example.com" },
200
- status: "pending",
201
- attempts: 0,
202
- maxAttempts: 5,
203
- lastAttemptAt: null,
204
- nextRetryAt: null,
205
- error: null,
206
- nonce: "test-nonce",
207
- });
208
- await executeMutate();
209
- });
194
+ const createdId = await this.handlerTx()
195
+ .mutate(({ forSchema }) => {
196
+ const uow = forSchema(internalSchema);
197
+ return uow.create("fragno_hooks", {
198
+ namespace,
199
+ hookName: "onSuccess",
200
+ payload: { email: "test@example.com" },
201
+ status: "pending",
202
+ attempts: 0,
203
+ maxAttempts: 5,
204
+ lastAttemptAt: null,
205
+ nextRetryAt: null,
206
+ error: null,
207
+ nonce: "test-nonce",
208
+ });
209
+ })
210
+ .execute();
211
+ eventId = createdId;
210
212
  });
211
213
 
212
214
  // Process hooks
@@ -223,19 +225,16 @@ describe("Hook System", () => {
223
225
 
224
226
  // Verify hook context (this)
225
227
  const hookContext = hookFn.mock.contexts[0] as HookContext;
226
- expect(hookContext.nonce).toBe("test-nonce");
228
+ expect(hookContext.idempotencyKey).toBe("test-nonce");
227
229
 
228
230
  // Verify event was marked as completed
229
231
  const result = await internalFragment.inContext(async function () {
230
- return await this.uow(async ({ forSchema, executeRetrieve }) => {
231
- const uow = forSchema(internalSchema);
232
- const findUow = uow.find("fragno_hooks", (b) =>
233
- b.whereIndex("primary", (eb) => eb("id", "=", eventId)),
234
- );
235
- await executeRetrieve();
236
- const [events] = await findUow.retrievalPhase;
237
- return events?.[0];
238
- });
232
+ return await this.handlerTx()
233
+ .withServiceCalls(
234
+ () => [internalFragment.services.hookService.getHookById(eventId)] as const,
235
+ )
236
+ .transform(({ serviceResult: [event] }) => event)
237
+ .execute();
239
238
  });
240
239
 
241
240
  expect(result?.status).toBe("completed");
@@ -252,22 +251,24 @@ describe("Hook System", () => {
252
251
  let eventId: FragnoId;
253
252
 
254
253
  await internalFragment.inContext(async function () {
255
- await this.uow(async ({ forSchema, executeMutate }) => {
256
- const uow = forSchema(internalSchema);
257
- eventId = uow.create("fragno_hooks", {
258
- namespace,
259
- hookName: "onFailure",
260
- payload: { data: "test" },
261
- status: "pending",
262
- attempts: 0,
263
- maxAttempts: 5,
264
- lastAttemptAt: null,
265
- nextRetryAt: null,
266
- error: null,
267
- nonce: "test-nonce",
268
- });
269
- await executeMutate();
270
- });
254
+ const createdId = await this.handlerTx()
255
+ .mutate(({ forSchema }) => {
256
+ const uow = forSchema(internalSchema);
257
+ return uow.create("fragno_hooks", {
258
+ namespace,
259
+ hookName: "onFailure",
260
+ payload: { data: "test" },
261
+ status: "pending",
262
+ attempts: 0,
263
+ maxAttempts: 5,
264
+ lastAttemptAt: null,
265
+ nextRetryAt: null,
266
+ error: null,
267
+ nonce: "test-nonce",
268
+ });
269
+ })
270
+ .execute();
271
+ eventId = createdId;
271
272
  });
272
273
 
273
274
  await processHooks({
@@ -280,15 +281,12 @@ describe("Hook System", () => {
280
281
  expect(hookFn).toHaveBeenCalledOnce();
281
282
 
282
283
  const result = await internalFragment.inContext(async function () {
283
- return await this.uow(async ({ forSchema, executeRetrieve }) => {
284
- const uow = forSchema(internalSchema);
285
- const findUow = uow.find("fragno_hooks", (b) =>
286
- b.whereIndex("primary", (eb) => eb("id", "=", eventId)),
287
- );
288
- await executeRetrieve();
289
- const [events] = await findUow.retrievalPhase;
290
- return events?.[0];
291
- });
284
+ return await this.handlerTx()
285
+ .withServiceCalls(
286
+ () => [internalFragment.services.hookService.getHookById(eventId)] as const,
287
+ )
288
+ .transform(({ serviceResult: [event] }) => event)
289
+ .execute();
292
290
  });
293
291
 
294
292
  expect(result?.status).toBe("pending");
@@ -307,22 +305,24 @@ describe("Hook System", () => {
307
305
  let eventId: FragnoId;
308
306
 
309
307
  await internalFragment.inContext(async function () {
310
- await this.uow(async ({ forSchema, executeMutate }) => {
311
- const uow = forSchema(internalSchema);
312
- eventId = uow.create("fragno_hooks", {
313
- namespace,
314
- hookName: "onMaxRetries",
315
- payload: { data: "test" },
316
- status: "pending",
317
- attempts: 0,
318
- maxAttempts: 1,
319
- lastAttemptAt: null,
320
- nextRetryAt: null,
321
- error: null,
322
- nonce: "test-nonce",
323
- });
324
- await executeMutate();
325
- });
308
+ const createdId = await this.handlerTx()
309
+ .mutate(({ forSchema }) => {
310
+ const uow = forSchema(internalSchema);
311
+ return uow.create("fragno_hooks", {
312
+ namespace,
313
+ hookName: "onMaxRetries",
314
+ payload: { data: "test" },
315
+ status: "pending",
316
+ attempts: 0,
317
+ maxAttempts: 1,
318
+ lastAttemptAt: null,
319
+ nextRetryAt: null,
320
+ error: null,
321
+ nonce: "test-nonce",
322
+ });
323
+ })
324
+ .execute();
325
+ eventId = createdId;
326
326
  });
327
327
 
328
328
  await processHooks({
@@ -333,15 +333,12 @@ describe("Hook System", () => {
333
333
  });
334
334
 
335
335
  const result = await internalFragment.inContext(async function () {
336
- return await this.uow(async ({ forSchema, executeRetrieve }) => {
337
- const uow = forSchema(internalSchema);
338
- const findUow = uow.find("fragno_hooks", (b) =>
339
- b.whereIndex("primary", (eb) => eb("id", "=", eventId)),
340
- );
341
- await executeRetrieve();
342
- const [events] = await findUow.retrievalPhase;
343
- return events?.[0];
344
- });
336
+ return await this.handlerTx()
337
+ .withServiceCalls(
338
+ () => [internalFragment.services.hookService.getHookById(eventId)] as const,
339
+ )
340
+ .transform(({ serviceResult: [event] }) => event)
341
+ .execute();
345
342
  });
346
343
 
347
344
  expect(result?.status).toBe("failed");
@@ -358,22 +355,24 @@ describe("Hook System", () => {
358
355
  let eventId: FragnoId;
359
356
 
360
357
  await internalFragment.inContext(async function () {
361
- await this.uow(async ({ forSchema, executeMutate }) => {
362
- const uow = forSchema(internalSchema);
363
- eventId = uow.create("fragno_hooks", {
364
- namespace,
365
- hookName: "onMissing",
366
- payload: { data: "test" },
367
- status: "pending",
368
- attempts: 0,
369
- maxAttempts: 1,
370
- lastAttemptAt: null,
371
- nextRetryAt: null,
372
- error: null,
373
- nonce: "test-nonce",
374
- });
375
- await executeMutate();
376
- });
358
+ const createdId = await this.handlerTx()
359
+ .mutate(({ forSchema }) => {
360
+ const uow = forSchema(internalSchema);
361
+ return uow.create("fragno_hooks", {
362
+ namespace,
363
+ hookName: "onMissing",
364
+ payload: { data: "test" },
365
+ status: "pending",
366
+ attempts: 0,
367
+ maxAttempts: 1,
368
+ lastAttemptAt: null,
369
+ nextRetryAt: null,
370
+ error: null,
371
+ nonce: "test-nonce",
372
+ });
373
+ })
374
+ .execute();
375
+ eventId = createdId;
377
376
  });
378
377
 
379
378
  await processHooks({
@@ -384,15 +383,12 @@ describe("Hook System", () => {
384
383
  });
385
384
 
386
385
  const result = await internalFragment.inContext(async function () {
387
- return await this.uow(async ({ forSchema, executeRetrieve }) => {
388
- const uow = forSchema(internalSchema);
389
- const findUow = uow.find("fragno_hooks", (b) =>
390
- b.whereIndex("primary", (eb) => eb("id", "=", eventId)),
391
- );
392
- await executeRetrieve();
393
- const [events] = await findUow.retrievalPhase;
394
- return events?.[0];
395
- });
386
+ return await this.handlerTx()
387
+ .withServiceCalls(
388
+ () => [internalFragment.services.hookService.getHookById(eventId)] as const,
389
+ )
390
+ .transform(({ serviceResult: [event] }) => event)
391
+ .execute();
396
392
  });
397
393
 
398
394
  expect(result?.status).toBe("failed");
@@ -411,46 +407,47 @@ describe("Hook System", () => {
411
407
  };
412
408
 
413
409
  await internalFragment.inContext(async function () {
414
- await this.uow(async ({ forSchema, executeMutate }) => {
415
- const uow = forSchema(internalSchema);
416
- uow.create("fragno_hooks", {
417
- namespace,
418
- hookName: "onHook1",
419
- payload: { id: 1 },
420
- status: "pending",
421
- attempts: 0,
422
- maxAttempts: 5,
423
- lastAttemptAt: null,
424
- nextRetryAt: null,
425
- error: null,
426
- nonce: "nonce-1",
427
- });
428
- uow.create("fragno_hooks", {
429
- namespace,
430
- hookName: "onHook2",
431
- payload: { id: 2 },
432
- status: "pending",
433
- attempts: 0,
434
- maxAttempts: 5,
435
- lastAttemptAt: null,
436
- nextRetryAt: null,
437
- error: null,
438
- nonce: "nonce-2",
439
- });
440
- uow.create("fragno_hooks", {
441
- namespace,
442
- hookName: "onHook3",
443
- payload: { id: 3 },
444
- status: "pending",
445
- attempts: 0,
446
- maxAttempts: 5,
447
- lastAttemptAt: null,
448
- nextRetryAt: null,
449
- error: null,
450
- nonce: "nonce-3",
451
- });
452
- await executeMutate();
453
- });
410
+ await this.handlerTx()
411
+ .mutate(({ forSchema }) => {
412
+ const uow = forSchema(internalSchema);
413
+ uow.create("fragno_hooks", {
414
+ namespace,
415
+ hookName: "onHook1",
416
+ payload: { id: 1 },
417
+ status: "pending",
418
+ attempts: 0,
419
+ maxAttempts: 5,
420
+ lastAttemptAt: null,
421
+ nextRetryAt: null,
422
+ error: null,
423
+ nonce: "nonce-1",
424
+ });
425
+ uow.create("fragno_hooks", {
426
+ namespace,
427
+ hookName: "onHook2",
428
+ payload: { id: 2 },
429
+ status: "pending",
430
+ attempts: 0,
431
+ maxAttempts: 5,
432
+ lastAttemptAt: null,
433
+ nextRetryAt: null,
434
+ error: null,
435
+ nonce: "nonce-2",
436
+ });
437
+ uow.create("fragno_hooks", {
438
+ namespace,
439
+ hookName: "onHook3",
440
+ payload: { id: 3 },
441
+ status: "pending",
442
+ attempts: 0,
443
+ maxAttempts: 5,
444
+ lastAttemptAt: null,
445
+ nextRetryAt: null,
446
+ error: null,
447
+ nonce: "nonce-3",
448
+ });
449
+ })
450
+ .execute();
454
451
  });
455
452
 
456
453
  await processHooks({
@@ -466,15 +463,12 @@ describe("Hook System", () => {
466
463
 
467
464
  // Verify all were marked as completed
468
465
  const events = await internalFragment.inContext(async function () {
469
- return await this.uow(async ({ forSchema, executeRetrieve }) => {
470
- const uow = forSchema(internalSchema);
471
- const findUow = uow.find("fragno_hooks", (b) =>
472
- b.whereIndex("idx_namespace_status_retry", (eb) => eb("namespace", "=", namespace)),
473
- );
474
- await executeRetrieve();
475
- const [results] = await findUow.retrievalPhase;
476
- return results;
477
- });
466
+ return await this.handlerTx()
467
+ .withServiceCalls(
468
+ () => [internalFragment.services.hookService.getHooksByNamespace(namespace)] as const,
469
+ )
470
+ .transform(({ serviceResult: [result] }) => result)
471
+ .execute();
478
472
  });
479
473
 
480
474
  const completed = events.filter((e) => e.status === "completed");
@@ -493,46 +487,47 @@ describe("Hook System", () => {
493
487
  };
494
488
 
495
489
  await internalFragment.inContext(async function () {
496
- await this.uow(async ({ forSchema, executeMutate }) => {
497
- const uow = forSchema(internalSchema);
498
- uow.create("fragno_hooks", {
499
- namespace,
500
- hookName: "onHook1",
501
- payload: { id: 1 },
502
- status: "pending",
503
- attempts: 0,
504
- maxAttempts: 5,
505
- lastAttemptAt: null,
506
- nextRetryAt: null,
507
- error: null,
508
- nonce: "nonce-1",
509
- });
510
- uow.create("fragno_hooks", {
511
- namespace,
512
- hookName: "onHook2",
513
- payload: { id: 2 },
514
- status: "pending",
515
- attempts: 0,
516
- maxAttempts: 5,
517
- lastAttemptAt: null,
518
- nextRetryAt: null,
519
- error: null,
520
- nonce: "nonce-2",
521
- });
522
- uow.create("fragno_hooks", {
523
- namespace,
524
- hookName: "onHook3",
525
- payload: { id: 3 },
526
- status: "pending",
527
- attempts: 0,
528
- maxAttempts: 5,
529
- lastAttemptAt: null,
530
- nextRetryAt: null,
531
- error: null,
532
- nonce: "nonce-3",
533
- });
534
- await executeMutate();
535
- });
490
+ await this.handlerTx()
491
+ .mutate(({ forSchema }) => {
492
+ const uow = forSchema(internalSchema);
493
+ uow.create("fragno_hooks", {
494
+ namespace,
495
+ hookName: "onHook1",
496
+ payload: { id: 1 },
497
+ status: "pending",
498
+ attempts: 0,
499
+ maxAttempts: 5,
500
+ lastAttemptAt: null,
501
+ nextRetryAt: null,
502
+ error: null,
503
+ nonce: "nonce-1",
504
+ });
505
+ uow.create("fragno_hooks", {
506
+ namespace,
507
+ hookName: "onHook2",
508
+ payload: { id: 2 },
509
+ status: "pending",
510
+ attempts: 0,
511
+ maxAttempts: 5,
512
+ lastAttemptAt: null,
513
+ nextRetryAt: null,
514
+ error: null,
515
+ nonce: "nonce-2",
516
+ });
517
+ uow.create("fragno_hooks", {
518
+ namespace,
519
+ hookName: "onHook3",
520
+ payload: { id: 3 },
521
+ status: "pending",
522
+ attempts: 0,
523
+ maxAttempts: 5,
524
+ lastAttemptAt: null,
525
+ nextRetryAt: null,
526
+ error: null,
527
+ nonce: "nonce-3",
528
+ });
529
+ })
530
+ .execute();
536
531
  });
537
532
 
538
533
  await processHooks({
@@ -548,15 +543,12 @@ describe("Hook System", () => {
548
543
 
549
544
  // Verify hook1 and hook3 were completed, hook2 was marked for retry
550
545
  const events = await internalFragment.inContext(async function () {
551
- return await this.uow(async ({ forSchema, executeRetrieve }) => {
552
- const uow = forSchema(internalSchema);
553
- const findUow = uow.find("fragno_hooks", (b) =>
554
- b.whereIndex("idx_namespace_status_retry", (eb) => eb("namespace", "=", namespace)),
555
- );
556
- await executeRetrieve();
557
- const [results] = await findUow.retrievalPhase;
558
- return results;
559
- });
546
+ return await this.handlerTx()
547
+ .withServiceCalls(
548
+ () => [internalFragment.services.hookService.getHooksByNamespace(namespace)] as const,
549
+ )
550
+ .transform(({ serviceResult: [result] }) => result)
551
+ .execute();
560
552
  });
561
553
 
562
554
  const completed = events.filter((e) => e.status === "completed");