@fragno-dev/db 0.2.0 → 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.
- package/.turbo/turbo-build.log +34 -30
- package/CHANGELOG.md +49 -0
- package/dist/adapters/generic-sql/query/where-builder.js +1 -1
- package/dist/db-fragment-definition-builder.d.ts +31 -39
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +20 -16
- package/dist/db-fragment-definition-builder.js.map +1 -1
- package/dist/fragments/internal-fragment.d.ts +94 -8
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +56 -55
- package/dist/fragments/internal-fragment.js.map +1 -1
- package/dist/hooks/hooks.d.ts +5 -3
- package/dist/hooks/hooks.d.ts.map +1 -1
- package/dist/hooks/hooks.js +38 -37
- package/dist/hooks/hooks.js.map +1 -1
- package/dist/mod.d.ts +3 -3
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +4 -4
- package/dist/mod.js.map +1 -1
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts +367 -80
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/execute-unit-of-work.js +448 -148
- package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.d.ts +35 -11
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.js +49 -19
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
- package/dist/query/value-decoding.js +1 -1
- package/dist/schema/create.d.ts +2 -3
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +2 -5
- package/dist/schema/create.js.map +1 -1
- package/dist/schema/generate-id.d.ts +20 -0
- package/dist/schema/generate-id.d.ts.map +1 -0
- package/dist/schema/generate-id.js +28 -0
- package/dist/schema/generate-id.js.map +1 -0
- package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +1 -0
- package/src/adapters/drizzle/drizzle-adapter-sqlite3.test.ts +41 -25
- package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +39 -25
- package/src/db-fragment-definition-builder.test.ts +58 -42
- package/src/db-fragment-definition-builder.ts +78 -88
- package/src/db-fragment-instantiator.test.ts +64 -88
- package/src/db-fragment-integration.test.ts +292 -142
- package/src/fragments/internal-fragment.test.ts +272 -266
- package/src/fragments/internal-fragment.ts +155 -122
- package/src/hooks/hooks.test.ts +268 -264
- package/src/hooks/hooks.ts +74 -63
- package/src/mod.ts +14 -4
- package/src/query/unit-of-work/execute-unit-of-work.test.ts +1582 -998
- package/src/query/unit-of-work/execute-unit-of-work.ts +1746 -343
- package/src/query/unit-of-work/tx-builder.test.ts +1041 -0
- package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +269 -21
- package/src/query/unit-of-work/unit-of-work.test.ts +64 -0
- package/src/query/unit-of-work/unit-of-work.ts +65 -30
- package/src/schema/create.ts +2 -5
- package/src/schema/generate-id.test.ts +57 -0
- package/src/schema/generate-id.ts +38 -0
- package/src/shared/config.ts +0 -10
- package/src/shared/connection-pool.ts +0 -24
- package/src/shared/prisma.ts +0 -45
|
@@ -49,11 +49,12 @@ describe("Internal Fragment", () => {
|
|
|
49
49
|
|
|
50
50
|
it("should get undefined for non-existent key", async () => {
|
|
51
51
|
const result = await fragment.inContext(async function () {
|
|
52
|
-
return await this.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
return await this.handlerTx()
|
|
53
|
+
.withServiceCalls(
|
|
54
|
+
() => [fragment.services.settingsService.get(SETTINGS_NAMESPACE, "test-key")] as const,
|
|
55
|
+
)
|
|
56
|
+
.transform(({ serviceResult: [value] }) => value)
|
|
57
|
+
.execute();
|
|
57
58
|
});
|
|
58
59
|
|
|
59
60
|
expect(result).toBeUndefined();
|
|
@@ -61,23 +62,20 @@ describe("Internal Fragment", () => {
|
|
|
61
62
|
|
|
62
63
|
it("should set and get a value", async () => {
|
|
63
64
|
await fragment.inContext(async function () {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
SETTINGS_NAMESPACE,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
);
|
|
70
|
-
await executeMutate();
|
|
71
|
-
await setPromise;
|
|
72
|
-
});
|
|
65
|
+
await this.handlerTx()
|
|
66
|
+
.withServiceCalls(() => [
|
|
67
|
+
fragment.services.settingsService.set(SETTINGS_NAMESPACE, "test-key", "test-value"),
|
|
68
|
+
])
|
|
69
|
+
.execute();
|
|
73
70
|
});
|
|
74
71
|
|
|
75
72
|
const result = await fragment.inContext(async function () {
|
|
76
|
-
return await this.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
return await this.handlerTx()
|
|
74
|
+
.withServiceCalls(
|
|
75
|
+
() => [fragment.services.settingsService.get(SETTINGS_NAMESPACE, "test-key")] as const,
|
|
76
|
+
)
|
|
77
|
+
.transform(({ serviceResult: [value] }) => value)
|
|
78
|
+
.execute();
|
|
81
79
|
});
|
|
82
80
|
|
|
83
81
|
expect(result).toMatchObject({
|
|
@@ -88,23 +86,27 @@ describe("Internal Fragment", () => {
|
|
|
88
86
|
|
|
89
87
|
it("should update an existing value", async () => {
|
|
90
88
|
await fragment.inContext(async function () {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
89
|
+
await this.handlerTx()
|
|
90
|
+
.withServiceCalls(
|
|
91
|
+
() =>
|
|
92
|
+
[
|
|
93
|
+
fragment.services.settingsService.set(
|
|
94
|
+
SETTINGS_NAMESPACE,
|
|
95
|
+
"test-key",
|
|
96
|
+
"updated-value",
|
|
97
|
+
),
|
|
98
|
+
] as const,
|
|
99
|
+
)
|
|
100
|
+
.execute();
|
|
100
101
|
});
|
|
101
102
|
|
|
102
103
|
const result = await fragment.inContext(async function () {
|
|
103
|
-
return await this.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
return await this.handlerTx()
|
|
105
|
+
.withServiceCalls(
|
|
106
|
+
() => [fragment.services.settingsService.get(SETTINGS_NAMESPACE, "test-key")] as const,
|
|
107
|
+
)
|
|
108
|
+
.transform(({ serviceResult: [value] }) => value)
|
|
109
|
+
.execute();
|
|
108
110
|
});
|
|
109
111
|
|
|
110
112
|
expect(result).toMatchObject({
|
|
@@ -116,31 +118,31 @@ describe("Internal Fragment", () => {
|
|
|
116
118
|
it("should delete a value", async () => {
|
|
117
119
|
// First get the ID
|
|
118
120
|
const setting = await fragment.inContext(async function () {
|
|
119
|
-
return await this.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
return await this.handlerTx()
|
|
122
|
+
.withServiceCalls(
|
|
123
|
+
() => [fragment.services.settingsService.get(SETTINGS_NAMESPACE, "test-key")] as const,
|
|
124
|
+
)
|
|
125
|
+
.transform(({ serviceResult: [value] }) => value)
|
|
126
|
+
.execute();
|
|
124
127
|
});
|
|
125
128
|
|
|
126
129
|
expect(setting).toBeDefined();
|
|
127
130
|
|
|
128
131
|
// Delete it
|
|
129
132
|
await fragment.inContext(async function () {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
await deletePromise;
|
|
134
|
-
});
|
|
133
|
+
await this.handlerTx()
|
|
134
|
+
.withServiceCalls(() => [fragment.services.settingsService.delete(setting!.id)] as const)
|
|
135
|
+
.execute();
|
|
135
136
|
});
|
|
136
137
|
|
|
137
138
|
// Verify it's gone
|
|
138
139
|
const result = await fragment.inContext(async function () {
|
|
139
|
-
return await this.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
return await this.handlerTx()
|
|
141
|
+
.withServiceCalls(
|
|
142
|
+
() => [fragment.services.settingsService.get(SETTINGS_NAMESPACE, "test-key")] as const,
|
|
143
|
+
)
|
|
144
|
+
.transform(({ serviceResult: [value] }) => value)
|
|
145
|
+
.execute();
|
|
144
146
|
});
|
|
145
147
|
|
|
146
148
|
expect(result).toBeUndefined();
|
|
@@ -188,42 +190,44 @@ describe("Hook Service", () => {
|
|
|
188
190
|
const nonce = "test-nonce-1";
|
|
189
191
|
|
|
190
192
|
await fragment.inContext(async function () {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
193
|
+
await this.handlerTx()
|
|
194
|
+
.mutate(({ forSchema }) => {
|
|
195
|
+
const uow = forSchema(internalSchema);
|
|
196
|
+
uow.create("fragno_hooks", {
|
|
197
|
+
namespace: "test-namespace",
|
|
198
|
+
hookName: "onTest",
|
|
199
|
+
payload: { test: "data" },
|
|
200
|
+
status: "pending",
|
|
201
|
+
attempts: 0,
|
|
202
|
+
maxAttempts: 5,
|
|
203
|
+
lastAttemptAt: null,
|
|
204
|
+
nextRetryAt: null,
|
|
205
|
+
error: null,
|
|
206
|
+
nonce,
|
|
207
|
+
});
|
|
208
|
+
uow.create("fragno_hooks", {
|
|
209
|
+
namespace: "test-namespace",
|
|
210
|
+
hookName: "onTest",
|
|
211
|
+
payload: { test: "already-completed-data" },
|
|
212
|
+
status: "completed",
|
|
213
|
+
attempts: 0,
|
|
214
|
+
maxAttempts: 5,
|
|
215
|
+
lastAttemptAt: null,
|
|
216
|
+
nextRetryAt: null,
|
|
217
|
+
error: null,
|
|
218
|
+
nonce,
|
|
219
|
+
});
|
|
220
|
+
})
|
|
221
|
+
.execute();
|
|
219
222
|
});
|
|
220
223
|
|
|
221
224
|
const events = await fragment.inContext(async function () {
|
|
222
|
-
return await this.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
return await this.handlerTx()
|
|
226
|
+
.withServiceCalls(
|
|
227
|
+
() => [fragment.services.hookService.getPendingHookEvents("test-namespace")] as const,
|
|
228
|
+
)
|
|
229
|
+
.transform(({ serviceResult: [result] }) => result)
|
|
230
|
+
.execute();
|
|
227
231
|
});
|
|
228
232
|
|
|
229
233
|
expect(events).toHaveLength(1);
|
|
@@ -232,7 +236,7 @@ describe("Hook Service", () => {
|
|
|
232
236
|
payload: { test: "data" },
|
|
233
237
|
attempts: 0,
|
|
234
238
|
maxAttempts: 5,
|
|
235
|
-
nonce,
|
|
239
|
+
idempotencyKey: nonce,
|
|
236
240
|
});
|
|
237
241
|
});
|
|
238
242
|
|
|
@@ -241,41 +245,36 @@ describe("Hook Service", () => {
|
|
|
241
245
|
let eventId: FragnoId;
|
|
242
246
|
|
|
243
247
|
await fragment.inContext(async function () {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
248
|
+
await this.handlerTx()
|
|
249
|
+
.mutate(({ forSchema }) => {
|
|
250
|
+
const uow = forSchema(internalSchema);
|
|
251
|
+
eventId = uow.create("fragno_hooks", {
|
|
252
|
+
namespace: "test-namespace",
|
|
253
|
+
hookName: "onComplete",
|
|
254
|
+
payload: { test: "data" },
|
|
255
|
+
status: "pending",
|
|
256
|
+
attempts: 0,
|
|
257
|
+
maxAttempts: 5,
|
|
258
|
+
lastAttemptAt: null,
|
|
259
|
+
nextRetryAt: null,
|
|
260
|
+
error: null,
|
|
261
|
+
nonce,
|
|
262
|
+
});
|
|
263
|
+
})
|
|
264
|
+
.execute();
|
|
260
265
|
});
|
|
261
266
|
|
|
262
267
|
await fragment.inContext(async function () {
|
|
263
|
-
|
|
264
|
-
fragment.services.hookService.markHookCompleted(eventId)
|
|
265
|
-
|
|
266
|
-
});
|
|
268
|
+
await this.handlerTx()
|
|
269
|
+
.withServiceCalls(() => [fragment.services.hookService.markHookCompleted(eventId)] as const)
|
|
270
|
+
.execute();
|
|
267
271
|
});
|
|
268
272
|
|
|
269
273
|
const result = await fragment.inContext(async function () {
|
|
270
|
-
return await this.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
);
|
|
275
|
-
await executeRetrieve();
|
|
276
|
-
const [events] = await findUow.retrievalPhase;
|
|
277
|
-
return events?.[0];
|
|
278
|
-
});
|
|
274
|
+
return await this.handlerTx()
|
|
275
|
+
.withServiceCalls(() => [fragment.services.hookService.getHookById(eventId)] as const)
|
|
276
|
+
.transform(({ serviceResult: [event] }) => event)
|
|
277
|
+
.execute();
|
|
279
278
|
});
|
|
280
279
|
|
|
281
280
|
expect(result).toBeDefined();
|
|
@@ -288,41 +287,38 @@ describe("Hook Service", () => {
|
|
|
288
287
|
let eventId: FragnoId;
|
|
289
288
|
|
|
290
289
|
await fragment.inContext(async function () {
|
|
291
|
-
return
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
290
|
+
return this.handlerTx()
|
|
291
|
+
.mutate(({ forSchema }) => {
|
|
292
|
+
const uow = forSchema(internalSchema);
|
|
293
|
+
eventId = uow.create("fragno_hooks", {
|
|
294
|
+
namespace: "test-namespace",
|
|
295
|
+
hookName: "onProcess",
|
|
296
|
+
payload: { test: "data" },
|
|
297
|
+
status: "pending",
|
|
298
|
+
attempts: 0,
|
|
299
|
+
maxAttempts: 5,
|
|
300
|
+
lastAttemptAt: null,
|
|
301
|
+
nextRetryAt: null,
|
|
302
|
+
error: null,
|
|
303
|
+
nonce,
|
|
304
|
+
});
|
|
305
|
+
})
|
|
306
|
+
.execute();
|
|
307
307
|
});
|
|
308
308
|
|
|
309
309
|
await fragment.inContext(async function () {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
310
|
+
await this.handlerTx()
|
|
311
|
+
.withServiceCalls(
|
|
312
|
+
() => [fragment.services.hookService.markHookProcessing(eventId)] as const,
|
|
313
|
+
)
|
|
314
|
+
.execute();
|
|
314
315
|
});
|
|
315
316
|
|
|
316
317
|
const result = await fragment.inContext(async function () {
|
|
317
|
-
return await this.
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
);
|
|
322
|
-
await executeRetrieve();
|
|
323
|
-
const [events] = await findUow.retrievalPhase;
|
|
324
|
-
return events?.[0];
|
|
325
|
-
});
|
|
318
|
+
return await this.handlerTx()
|
|
319
|
+
.withServiceCalls(() => [fragment.services.hookService.getHookById(eventId)] as const)
|
|
320
|
+
.transform(({ serviceResult: [event] }) => event)
|
|
321
|
+
.execute();
|
|
326
322
|
});
|
|
327
323
|
|
|
328
324
|
expect(result).toBeDefined();
|
|
@@ -335,43 +331,44 @@ describe("Hook Service", () => {
|
|
|
335
331
|
let eventId: FragnoId;
|
|
336
332
|
|
|
337
333
|
await fragment.inContext(async function () {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
334
|
+
const createdId = await this.handlerTx()
|
|
335
|
+
.mutate(({ forSchema }) => {
|
|
336
|
+
const uow = forSchema(internalSchema);
|
|
337
|
+
return uow.create("fragno_hooks", {
|
|
338
|
+
namespace: "test-namespace",
|
|
339
|
+
hookName: "onFail",
|
|
340
|
+
payload: { test: "data" },
|
|
341
|
+
status: "pending",
|
|
342
|
+
attempts: 0,
|
|
343
|
+
maxAttempts: 5,
|
|
344
|
+
lastAttemptAt: null,
|
|
345
|
+
nextRetryAt: null,
|
|
346
|
+
error: null,
|
|
347
|
+
nonce,
|
|
348
|
+
});
|
|
349
|
+
})
|
|
350
|
+
.execute();
|
|
351
|
+
eventId = createdId;
|
|
354
352
|
});
|
|
355
353
|
|
|
356
354
|
const retryPolicy = new ExponentialBackoffRetryPolicy({ maxRetries: 3 });
|
|
357
355
|
|
|
358
356
|
await fragment.inContext(async function () {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
357
|
+
await this.handlerTx()
|
|
358
|
+
.withServiceCalls(
|
|
359
|
+
() =>
|
|
360
|
+
[
|
|
361
|
+
fragment.services.hookService.markHookFailed(eventId, "Test error", 0, retryPolicy),
|
|
362
|
+
] as const,
|
|
363
|
+
)
|
|
364
|
+
.execute();
|
|
363
365
|
});
|
|
364
366
|
|
|
365
367
|
const result = await fragment.inContext(async function () {
|
|
366
|
-
return await this.
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
);
|
|
371
|
-
await executeRetrieve();
|
|
372
|
-
const [events] = await findUow.retrievalPhase;
|
|
373
|
-
return events?.[0];
|
|
374
|
-
});
|
|
368
|
+
return await this.handlerTx()
|
|
369
|
+
.withServiceCalls(() => [fragment.services.hookService.getHookById(eventId)] as const)
|
|
370
|
+
.transform(({ serviceResult: [event] }) => event)
|
|
371
|
+
.execute();
|
|
375
372
|
});
|
|
376
373
|
|
|
377
374
|
expect(result).toBeDefined();
|
|
@@ -387,48 +384,49 @@ describe("Hook Service", () => {
|
|
|
387
384
|
let eventId: FragnoId;
|
|
388
385
|
|
|
389
386
|
await fragment.inContext(async function () {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
387
|
+
const createdId = await this.handlerTx()
|
|
388
|
+
.mutate(({ forSchema }) => {
|
|
389
|
+
const uow = forSchema(internalSchema);
|
|
390
|
+
return uow.create("fragno_hooks", {
|
|
391
|
+
namespace: "test-namespace",
|
|
392
|
+
hookName: "onMaxFail",
|
|
393
|
+
payload: { test: "data" },
|
|
394
|
+
status: "pending",
|
|
395
|
+
attempts: 0,
|
|
396
|
+
maxAttempts: 1,
|
|
397
|
+
lastAttemptAt: null,
|
|
398
|
+
nextRetryAt: null,
|
|
399
|
+
error: null,
|
|
400
|
+
nonce,
|
|
401
|
+
});
|
|
402
|
+
})
|
|
403
|
+
.execute();
|
|
404
|
+
eventId = createdId;
|
|
406
405
|
});
|
|
407
406
|
|
|
408
407
|
const retryPolicy = new NoRetryPolicy();
|
|
409
408
|
|
|
410
409
|
await fragment.inContext(async function () {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
410
|
+
await this.handlerTx()
|
|
411
|
+
.withServiceCalls(
|
|
412
|
+
() =>
|
|
413
|
+
[
|
|
414
|
+
fragment.services.hookService.markHookFailed(
|
|
415
|
+
eventId,
|
|
416
|
+
"Max attempts reached",
|
|
417
|
+
0,
|
|
418
|
+
retryPolicy,
|
|
419
|
+
),
|
|
420
|
+
] as const,
|
|
421
|
+
)
|
|
422
|
+
.execute();
|
|
420
423
|
});
|
|
421
424
|
|
|
422
425
|
const result = await fragment.inContext(async function () {
|
|
423
|
-
return await this.
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
);
|
|
428
|
-
await executeRetrieve();
|
|
429
|
-
const [events] = await findUow.retrievalPhase;
|
|
430
|
-
return events?.[0];
|
|
431
|
-
});
|
|
426
|
+
return await this.handlerTx()
|
|
427
|
+
.withServiceCalls(() => [fragment.services.hookService.getHookById(eventId)] as const)
|
|
428
|
+
.transform(({ serviceResult: [event] }) => event)
|
|
429
|
+
.execute();
|
|
432
430
|
});
|
|
433
431
|
|
|
434
432
|
expect(result).toBeDefined();
|
|
@@ -444,30 +442,33 @@ describe("Hook Service", () => {
|
|
|
444
442
|
const pastTime = new Date(Date.now() - 10000);
|
|
445
443
|
|
|
446
444
|
await fragment.inContext(async function () {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
445
|
+
const createdId = await this.handlerTx()
|
|
446
|
+
.mutate(({ forSchema }) => {
|
|
447
|
+
const uow = forSchema(internalSchema);
|
|
448
|
+
return uow.create("fragno_hooks", {
|
|
449
|
+
namespace: "test-namespace",
|
|
450
|
+
hookName: "onStale",
|
|
451
|
+
payload: { test: "stale" },
|
|
452
|
+
status: "pending",
|
|
453
|
+
attempts: 1,
|
|
454
|
+
maxAttempts: 5,
|
|
455
|
+
lastAttemptAt: pastTime,
|
|
456
|
+
nextRetryAt: pastTime,
|
|
457
|
+
error: "Previous error",
|
|
458
|
+
nonce,
|
|
459
|
+
});
|
|
460
|
+
})
|
|
461
|
+
.execute();
|
|
462
|
+
eventId = createdId;
|
|
463
463
|
});
|
|
464
464
|
|
|
465
465
|
const events = await fragment.inContext(async function () {
|
|
466
|
-
return await this.
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
466
|
+
return await this.handlerTx()
|
|
467
|
+
.withServiceCalls(
|
|
468
|
+
() => [fragment.services.hookService.getPendingHookEvents("test-namespace")] as const,
|
|
469
|
+
)
|
|
470
|
+
.transform(({ serviceResult: [result] }) => result)
|
|
471
|
+
.execute();
|
|
471
472
|
});
|
|
472
473
|
|
|
473
474
|
const staleEvent = events.find((e) => e.id.externalId === eventId.externalId);
|
|
@@ -480,30 +481,32 @@ describe("Hook Service", () => {
|
|
|
480
481
|
const nonce = "test-nonce-7";
|
|
481
482
|
|
|
482
483
|
await fragment.inContext(async function () {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
484
|
+
await this.handlerTx()
|
|
485
|
+
.mutate(({ forSchema }) => {
|
|
486
|
+
const uow = forSchema(internalSchema);
|
|
487
|
+
uow.create("fragno_hooks", {
|
|
488
|
+
namespace: "other-namespace",
|
|
489
|
+
hookName: "onOther",
|
|
490
|
+
payload: { test: "other" },
|
|
491
|
+
status: "pending",
|
|
492
|
+
attempts: 0,
|
|
493
|
+
maxAttempts: 5,
|
|
494
|
+
lastAttemptAt: null,
|
|
495
|
+
nextRetryAt: null,
|
|
496
|
+
error: null,
|
|
497
|
+
nonce,
|
|
498
|
+
});
|
|
499
|
+
})
|
|
500
|
+
.execute();
|
|
499
501
|
});
|
|
500
502
|
|
|
501
503
|
const events = await fragment.inContext(async function () {
|
|
502
|
-
return await this.
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
504
|
+
return await this.handlerTx()
|
|
505
|
+
.withServiceCalls(
|
|
506
|
+
() => [fragment.services.hookService.getPendingHookEvents("test-namespace")] as const,
|
|
507
|
+
)
|
|
508
|
+
.transform(({ serviceResult: [result] }) => result)
|
|
509
|
+
.execute();
|
|
507
510
|
});
|
|
508
511
|
|
|
509
512
|
const otherEvent = events.find((e) => e.hookName === "onOther");
|
|
@@ -517,30 +520,33 @@ describe("Hook Service", () => {
|
|
|
517
520
|
const futureTime = new Date(Date.now() + 60000);
|
|
518
521
|
|
|
519
522
|
await fragment.inContext(async function () {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
523
|
+
const createdId = await this.handlerTx()
|
|
524
|
+
.mutate(({ forSchema }) => {
|
|
525
|
+
const uow = forSchema(internalSchema);
|
|
526
|
+
return uow.create("fragno_hooks", {
|
|
527
|
+
namespace: "test-namespace",
|
|
528
|
+
hookName: "onFuture",
|
|
529
|
+
payload: { test: "future" },
|
|
530
|
+
status: "pending",
|
|
531
|
+
attempts: 1,
|
|
532
|
+
maxAttempts: 5,
|
|
533
|
+
lastAttemptAt: new Date(),
|
|
534
|
+
nextRetryAt: futureTime,
|
|
535
|
+
error: "Previous error",
|
|
536
|
+
nonce,
|
|
537
|
+
});
|
|
538
|
+
})
|
|
539
|
+
.execute();
|
|
540
|
+
eventId = createdId;
|
|
536
541
|
});
|
|
537
542
|
|
|
538
543
|
const events = await fragment.inContext(async function () {
|
|
539
|
-
return await this.
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
+
return await this.handlerTx()
|
|
545
|
+
.withServiceCalls(
|
|
546
|
+
() => [fragment.services.hookService.getPendingHookEvents("test-namespace")] as const,
|
|
547
|
+
)
|
|
548
|
+
.transform(({ serviceResult: [result] }) => result)
|
|
549
|
+
.execute();
|
|
544
550
|
});
|
|
545
551
|
|
|
546
552
|
const futureEvent = events.find((e) => e.id.externalId === eventId.externalId);
|