@porulle/core 0.38.0 → 0.40.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@porulle/core",
3
- "version": "0.38.0",
3
+ "version": "0.40.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -104,13 +104,13 @@ export async function runBeforeHooks<T>(
104
104
  return current;
105
105
  }
106
106
 
107
- export async function runAfterHooks<T>(
108
- hooks: AfterHook<T>[],
109
- originalData: T | null,
110
- committedResult: T,
107
+ export async function runAfterHooks<TResult, TData = TResult>(
108
+ hooks: AfterHook<TResult, TData>[],
109
+ originalData: TData | null,
110
+ committedResult: TResult,
111
111
  operation: HookOperation,
112
112
  context: HookContext,
113
- runsInTransaction: (hook: AfterHook<T>) => boolean = () => false,
113
+ runsInTransaction: (hook: AfterHook<TResult, TData>) => boolean = () => false,
114
114
  ): Promise<HookReport> {
115
115
  const errors: HookError[] = [];
116
116
  for (const hook of hooks) {
@@ -50,9 +50,18 @@ export type BeforeHook<TData> = (args: {
50
50
  context: HookContext;
51
51
  }) => Promise<TData> | TData;
52
52
 
53
- export type AfterHook<TData> = (args: {
53
+ /**
54
+ * `data` is what went in, `result` is what was committed. For most operations
55
+ * those are the same shape, so `TData` defaults to `TResult` and a single type
56
+ * argument keeps its old meaning.
57
+ *
58
+ * They differ where the committed entity is not the input: a status change
59
+ * commits a hydrated order but its input is the transition itself, and a hook
60
+ * that cannot see which transition occurred cannot act on one.
61
+ */
62
+ export type AfterHook<TResult, TData = TResult> = (args: {
54
63
  data: TData | null;
55
- result: TData;
64
+ result: TResult;
56
65
  operation: HookOperation;
57
66
  context: HookContext;
58
67
  }) => Promise<void> | void;
@@ -134,7 +134,14 @@ type StatusChangeHookInput = {
134
134
  reason?: string;
135
135
  };
136
136
  type BeforeStatusChangeHook = BeforeHook<StatusChangeHookInput>;
137
- type AfterStatusChangeHook = AfterHook<HydratedOrder>;
137
+ /**
138
+ * `result` is the committed, hydrated order; `data` is the transition that
139
+ * produced it. A subscriber that must act on *which* transition occurred — the
140
+ * channel connector pushes an order to its merchant only when it leaves
141
+ * `pending_payment` — cannot read that from the order alone, because the order
142
+ * carries only the status it now has.
143
+ */
144
+ type AfterStatusChangeHook = AfterHook<HydratedOrder, StatusChangeHookInput>;
138
145
 
139
146
  function context(
140
147
  actor: Actor | null,
@@ -1254,7 +1261,7 @@ export class OrderService {
1254
1261
  const hydrated = await this.hydrateOrder(cas, ctx);
1255
1262
  const report = await runAfterHooks(
1256
1263
  afterHooks,
1257
- null,
1264
+ statusHookInput,
1258
1265
  hydrated,
1259
1266
  "statusChange",
1260
1267
  hookCtx,