@classytic/revenue 1.1.2 → 1.1.3
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.md +8 -7
- package/dist/application/services/index.d.mts +4 -0
- package/dist/application/services/index.mjs +3 -0
- package/dist/base-CsTlVQJe.d.mts +136 -0
- package/dist/base-DCoyIUj6.mjs +152 -0
- package/dist/category-resolver-DV83N8ok.mjs +284 -0
- package/dist/commission-split-BzB8cd39.mjs +485 -0
- package/dist/core/events.d.mts +294 -0
- package/dist/core/events.mjs +100 -0
- package/dist/core/index.d.mts +9 -0
- package/dist/core/index.mjs +8 -0
- package/dist/enums/index.d.mts +157 -0
- package/dist/enums/index.mjs +56 -0
- package/dist/errors-CorrWz7A.d.mts +787 -0
- package/dist/escrow.enums-CZGrrdg7.mjs +101 -0
- package/dist/{escrow.enums-CE0VQsfe.d.ts → escrow.enums-DwdLuuve.d.mts} +30 -28
- package/dist/idempotency-DaYcUGY1.mjs +172 -0
- package/dist/index-Dsp7H5Wb.d.mts +471 -0
- package/dist/index.d.mts +9 -0
- package/dist/index.mjs +38 -0
- package/dist/infrastructure/plugins/{index.d.ts → index.d.mts} +81 -109
- package/dist/infrastructure/plugins/index.mjs +345 -0
- package/dist/money-CvrDOijQ.mjs +271 -0
- package/dist/money-DPG8AtJ8.d.mts +112 -0
- package/dist/{payment.enums-C1BiGlRa.d.ts → payment.enums-HAuAS9Pp.d.mts} +14 -13
- package/dist/payment.enums-tEFVa-Xp.mjs +69 -0
- package/dist/plugin-BbK0OVHy.d.mts +327 -0
- package/dist/plugin-Cd_V04Em.mjs +210 -0
- package/dist/providers/index.d.mts +3 -0
- package/dist/providers/index.mjs +3 -0
- package/dist/reconciliation/{index.d.ts → index.d.mts} +90 -112
- package/dist/reconciliation/index.mjs +192 -0
- package/dist/retry-HHCOXYdn.d.mts +186 -0
- package/dist/revenue-9scqKSef.mjs +553 -0
- package/dist/schemas/index.d.mts +2665 -0
- package/dist/schemas/index.mjs +717 -0
- package/dist/schemas/validation.d.mts +375 -0
- package/dist/schemas/validation.mjs +325 -0
- package/dist/{settlement.enums-ByC1x0ye.d.ts → settlement.enums-DFhkqZEY.d.mts} +31 -29
- package/dist/settlement.schema-D5uWB5tP.d.mts +344 -0
- package/dist/settlement.service-BxuiHpNC.d.mts +594 -0
- package/dist/settlement.service-CUxbUTzT.mjs +2510 -0
- package/dist/split.enums-BrjabxIX.mjs +86 -0
- package/dist/split.enums-DmskfLOM.d.mts +43 -0
- package/dist/tax-BoCt5cEd.d.mts +61 -0
- package/dist/tax-EQ15DO81.mjs +162 -0
- package/dist/transaction.enums-pCyMFT4Z.mjs +96 -0
- package/dist/utils/{index.d.ts → index.d.mts} +91 -161
- package/dist/utils/index.mjs +346 -0
- package/package.json +38 -36
- package/dist/application/services/index.d.ts +0 -6
- package/dist/application/services/index.js +0 -3288
- package/dist/application/services/index.js.map +0 -1
- package/dist/core/events.d.ts +0 -455
- package/dist/core/events.js +0 -122
- package/dist/core/events.js.map +0 -1
- package/dist/core/index.d.ts +0 -13
- package/dist/core/index.js +0 -4591
- package/dist/core/index.js.map +0 -1
- package/dist/enums/index.d.ts +0 -159
- package/dist/enums/index.js +0 -296
- package/dist/enums/index.js.map +0 -1
- package/dist/index-DxIK0UmZ.d.ts +0 -633
- package/dist/index-EnfKzDbs.d.ts +0 -806
- package/dist/index-cLJBLUvx.d.ts +0 -478
- package/dist/index.d.ts +0 -43
- package/dist/index.js +0 -4864
- package/dist/index.js.map +0 -1
- package/dist/infrastructure/plugins/index.js +0 -292
- package/dist/infrastructure/plugins/index.js.map +0 -1
- package/dist/money-widWVD7r.d.ts +0 -111
- package/dist/plugin-Bb9HOE10.d.ts +0 -336
- package/dist/providers/index.d.ts +0 -145
- package/dist/providers/index.js +0 -141
- package/dist/providers/index.js.map +0 -1
- package/dist/reconciliation/index.js +0 -140
- package/dist/reconciliation/index.js.map +0 -1
- package/dist/retry-D4hFUwVk.d.ts +0 -194
- package/dist/schemas/index.d.ts +0 -2655
- package/dist/schemas/index.js +0 -841
- package/dist/schemas/index.js.map +0 -1
- package/dist/schemas/validation.d.ts +0 -384
- package/dist/schemas/validation.js +0 -303
- package/dist/schemas/validation.js.map +0 -1
- package/dist/settlement.schema-CpamV7ZY.d.ts +0 -343
- package/dist/split.enums-DG3TxQf9.d.ts +0 -42
- package/dist/tax-CV8A0sxl.d.ts +0 -60
- package/dist/utils/index.js +0 -1202
- package/dist/utils/index.js.map +0 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
//#region src/enums/monetization.enums.ts
|
|
2
|
+
/**
|
|
3
|
+
* Monetization Enums
|
|
4
|
+
* @classytic/revenue
|
|
5
|
+
*
|
|
6
|
+
* General monetization enums and constants
|
|
7
|
+
*/
|
|
8
|
+
const MONETIZATION_TYPES = {
|
|
9
|
+
FREE: "free",
|
|
10
|
+
PURCHASE: "purchase",
|
|
11
|
+
SUBSCRIPTION: "subscription"
|
|
12
|
+
};
|
|
13
|
+
const MONETIZATION_TYPE_VALUES = Object.values(MONETIZATION_TYPES);
|
|
14
|
+
const monetizationTypeSet = new Set(MONETIZATION_TYPE_VALUES);
|
|
15
|
+
function isMonetizationType(value) {
|
|
16
|
+
return typeof value === "string" && monetizationTypeSet.has(value);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/enums/settlement.enums.ts
|
|
21
|
+
/**
|
|
22
|
+
* Settlement Enums
|
|
23
|
+
* @classytic/revenue
|
|
24
|
+
*
|
|
25
|
+
* Enums for settlement/payout tracking
|
|
26
|
+
*/
|
|
27
|
+
const SETTLEMENT_STATUS = {
|
|
28
|
+
PENDING: "pending",
|
|
29
|
+
PROCESSING: "processing",
|
|
30
|
+
COMPLETED: "completed",
|
|
31
|
+
FAILED: "failed",
|
|
32
|
+
CANCELLED: "cancelled"
|
|
33
|
+
};
|
|
34
|
+
const SETTLEMENT_STATUS_VALUES = Object.values(SETTLEMENT_STATUS);
|
|
35
|
+
/**
|
|
36
|
+
* Type guard for settlement status
|
|
37
|
+
*/
|
|
38
|
+
function isSettlementStatus(value) {
|
|
39
|
+
return typeof value === "string" && SETTLEMENT_STATUS_VALUES.includes(value);
|
|
40
|
+
}
|
|
41
|
+
const SETTLEMENT_TYPE = {
|
|
42
|
+
SPLIT_PAYOUT: "split_payout",
|
|
43
|
+
PLATFORM_WITHDRAWAL: "platform_withdrawal",
|
|
44
|
+
MANUAL_PAYOUT: "manual_payout",
|
|
45
|
+
ESCROW_RELEASE: "escrow_release"
|
|
46
|
+
};
|
|
47
|
+
const SETTLEMENT_TYPE_VALUES = Object.values(SETTLEMENT_TYPE);
|
|
48
|
+
/**
|
|
49
|
+
* Type guard for settlement type
|
|
50
|
+
*/
|
|
51
|
+
function isSettlementType(value) {
|
|
52
|
+
return typeof value === "string" && SETTLEMENT_TYPE_VALUES.includes(value);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/enums/escrow.enums.ts
|
|
57
|
+
/**
|
|
58
|
+
* Escrow/Hold Enums
|
|
59
|
+
* @classytic/revenue
|
|
60
|
+
*
|
|
61
|
+
* Enums for platform-as-intermediary payment flow
|
|
62
|
+
*/
|
|
63
|
+
const HOLD_STATUS = {
|
|
64
|
+
PENDING: "pending",
|
|
65
|
+
HELD: "held",
|
|
66
|
+
RELEASED: "released",
|
|
67
|
+
CANCELLED: "cancelled",
|
|
68
|
+
EXPIRED: "expired",
|
|
69
|
+
PARTIALLY_RELEASED: "partially_released"
|
|
70
|
+
};
|
|
71
|
+
const HOLD_STATUS_VALUES = Object.values(HOLD_STATUS);
|
|
72
|
+
const RELEASE_REASON = {
|
|
73
|
+
PAYMENT_VERIFIED: "payment_verified",
|
|
74
|
+
MANUAL_RELEASE: "manual_release",
|
|
75
|
+
AUTO_RELEASE: "auto_release",
|
|
76
|
+
DISPUTE_RESOLVED: "dispute_resolved"
|
|
77
|
+
};
|
|
78
|
+
const RELEASE_REASON_VALUES = Object.values(RELEASE_REASON);
|
|
79
|
+
const HOLD_REASON = {
|
|
80
|
+
PAYMENT_VERIFICATION: "payment_verification",
|
|
81
|
+
FRAUD_CHECK: "fraud_check",
|
|
82
|
+
MANUAL_REVIEW: "manual_review",
|
|
83
|
+
DISPUTE: "dispute",
|
|
84
|
+
COMPLIANCE: "compliance"
|
|
85
|
+
};
|
|
86
|
+
const HOLD_REASON_VALUES = Object.values(HOLD_REASON);
|
|
87
|
+
const holdStatusSet = new Set(HOLD_STATUS_VALUES);
|
|
88
|
+
const releaseReasonSet = new Set(RELEASE_REASON_VALUES);
|
|
89
|
+
const holdReasonSet = new Set(HOLD_REASON_VALUES);
|
|
90
|
+
function isHoldStatus(value) {
|
|
91
|
+
return typeof value === "string" && holdStatusSet.has(value);
|
|
92
|
+
}
|
|
93
|
+
function isReleaseReason(value) {
|
|
94
|
+
return typeof value === "string" && releaseReasonSet.has(value);
|
|
95
|
+
}
|
|
96
|
+
function isHoldReason(value) {
|
|
97
|
+
return typeof value === "string" && holdReasonSet.has(value);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//#endregion
|
|
101
|
+
export { MONETIZATION_TYPE_VALUES as _, RELEASE_REASON as a, isHoldStatus as c, SETTLEMENT_STATUS_VALUES as d, SETTLEMENT_TYPE as f, MONETIZATION_TYPES as g, isSettlementType as h, HOLD_STATUS_VALUES as i, isReleaseReason as l, isSettlementStatus as m, HOLD_REASON_VALUES as n, RELEASE_REASON_VALUES as o, SETTLEMENT_TYPE_VALUES as p, HOLD_STATUS as r, isHoldReason as s, HOLD_REASON as t, SETTLEMENT_STATUS as u, isMonetizationType as v };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/enums/subscription.enums.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* Subscription Enums
|
|
3
4
|
* @classytic/revenue
|
|
@@ -8,13 +9,13 @@
|
|
|
8
9
|
* Subscription Status
|
|
9
10
|
*/
|
|
10
11
|
declare const SUBSCRIPTION_STATUS: {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
readonly ACTIVE: "active";
|
|
13
|
+
readonly PAUSED: "paused";
|
|
14
|
+
readonly CANCELLED: "cancelled";
|
|
15
|
+
readonly EXPIRED: "expired";
|
|
16
|
+
readonly PENDING: "pending";
|
|
17
|
+
readonly PENDING_RENEWAL: "pending_renewal";
|
|
18
|
+
readonly INACTIVE: "inactive";
|
|
18
19
|
};
|
|
19
20
|
type SubscriptionStatus = typeof SUBSCRIPTION_STATUS;
|
|
20
21
|
type SubscriptionStatusValue = SubscriptionStatus[keyof SubscriptionStatus];
|
|
@@ -23,16 +24,17 @@ declare const SUBSCRIPTION_STATUS_VALUES: SubscriptionStatusValue[];
|
|
|
23
24
|
* Supported plan intervals
|
|
24
25
|
*/
|
|
25
26
|
declare const PLAN_KEYS: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
readonly MONTHLY: "monthly";
|
|
28
|
+
readonly QUARTERLY: "quarterly";
|
|
29
|
+
readonly YEARLY: "yearly";
|
|
29
30
|
};
|
|
30
31
|
type PlanKeys = typeof PLAN_KEYS;
|
|
31
32
|
type PlanKeyValue = PlanKeys[keyof PlanKeys];
|
|
32
33
|
declare const PLAN_KEY_VALUES: PlanKeyValue[];
|
|
33
34
|
declare function isSubscriptionStatus(value: unknown): value is SubscriptionStatusValue;
|
|
34
35
|
declare function isPlanKey(value: unknown): value is PlanKeyValue;
|
|
35
|
-
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/enums/escrow.enums.d.ts
|
|
36
38
|
/**
|
|
37
39
|
* Escrow/Hold Enums
|
|
38
40
|
* @classytic/revenue
|
|
@@ -40,31 +42,31 @@ declare function isPlanKey(value: unknown): value is PlanKeyValue;
|
|
|
40
42
|
* Enums for platform-as-intermediary payment flow
|
|
41
43
|
*/
|
|
42
44
|
declare const HOLD_STATUS: {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
readonly PENDING: "pending";
|
|
46
|
+
readonly HELD: "held";
|
|
47
|
+
readonly RELEASED: "released";
|
|
48
|
+
readonly CANCELLED: "cancelled";
|
|
49
|
+
readonly EXPIRED: "expired";
|
|
50
|
+
readonly PARTIALLY_RELEASED: "partially_released";
|
|
49
51
|
};
|
|
50
52
|
type HoldStatus = typeof HOLD_STATUS;
|
|
51
53
|
type HoldStatusValue = HoldStatus[keyof HoldStatus];
|
|
52
54
|
declare const HOLD_STATUS_VALUES: HoldStatusValue[];
|
|
53
55
|
declare const RELEASE_REASON: {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
readonly PAYMENT_VERIFIED: "payment_verified";
|
|
57
|
+
readonly MANUAL_RELEASE: "manual_release";
|
|
58
|
+
readonly AUTO_RELEASE: "auto_release";
|
|
59
|
+
readonly DISPUTE_RESOLVED: "dispute_resolved";
|
|
58
60
|
};
|
|
59
61
|
type ReleaseReason = typeof RELEASE_REASON;
|
|
60
62
|
type ReleaseReasonValue = ReleaseReason[keyof ReleaseReason];
|
|
61
63
|
declare const RELEASE_REASON_VALUES: ReleaseReasonValue[];
|
|
62
64
|
declare const HOLD_REASON: {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
readonly PAYMENT_VERIFICATION: "payment_verification";
|
|
66
|
+
readonly FRAUD_CHECK: "fraud_check";
|
|
67
|
+
readonly MANUAL_REVIEW: "manual_review";
|
|
68
|
+
readonly DISPUTE: "dispute";
|
|
69
|
+
readonly COMPLIANCE: "compliance";
|
|
68
70
|
};
|
|
69
71
|
type HoldReason = typeof HOLD_REASON;
|
|
70
72
|
type HoldReasonValue = HoldReason[keyof HoldReason];
|
|
@@ -72,5 +74,5 @@ declare const HOLD_REASON_VALUES: HoldReasonValue[];
|
|
|
72
74
|
declare function isHoldStatus(value: unknown): value is HoldStatusValue;
|
|
73
75
|
declare function isReleaseReason(value: unknown): value is ReleaseReasonValue;
|
|
74
76
|
declare function isHoldReason(value: unknown): value is HoldReasonValue;
|
|
75
|
-
|
|
76
|
-
export {
|
|
77
|
+
//#endregion
|
|
78
|
+
export { SubscriptionStatusValue as C, SubscriptionStatus as S, isSubscriptionStatus as T, PLAN_KEY_VALUES as _, HoldReason as a, SUBSCRIPTION_STATUS as b, HoldStatusValue as c, ReleaseReason as d, ReleaseReasonValue as f, PLAN_KEYS as g, isReleaseReason as h, HOLD_STATUS_VALUES as i, RELEASE_REASON as l, isHoldStatus as m, HOLD_REASON_VALUES as n, HoldReasonValue as o, isHoldReason as p, HOLD_STATUS as r, HoldStatus as s, HOLD_REASON as t, RELEASE_REASON_VALUES as u, PlanKeyValue as v, isPlanKey as w, SUBSCRIPTION_STATUS_VALUES as x, PlanKeys as y };
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { d as err, v as ok } from "./commission-split-BzB8cd39.mjs";
|
|
2
|
+
import { nanoid } from "nanoid";
|
|
3
|
+
|
|
4
|
+
//#region src/shared/utils/resilience/idempotency.ts
|
|
5
|
+
/**
|
|
6
|
+
* Idempotency Utilities
|
|
7
|
+
* @classytic/revenue
|
|
8
|
+
*
|
|
9
|
+
* Prevent duplicate operations with idempotency keys
|
|
10
|
+
* Inspired by: Stripe, Amazon SQS deduplication
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Simple in-memory idempotency store
|
|
14
|
+
* Use Redis/database store in production
|
|
15
|
+
*/
|
|
16
|
+
var MemoryIdempotencyStore = class {
|
|
17
|
+
records = /* @__PURE__ */ new Map();
|
|
18
|
+
cleanupInterval = null;
|
|
19
|
+
constructor(cleanupIntervalMs = 6e4) {
|
|
20
|
+
this.cleanupInterval = setInterval(() => {
|
|
21
|
+
this.cleanup();
|
|
22
|
+
}, cleanupIntervalMs);
|
|
23
|
+
}
|
|
24
|
+
async get(key) {
|
|
25
|
+
const record = this.records.get(key);
|
|
26
|
+
if (!record) return null;
|
|
27
|
+
if (record.expiresAt < /* @__PURE__ */ new Date()) {
|
|
28
|
+
this.records.delete(key);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return record;
|
|
32
|
+
}
|
|
33
|
+
async set(key, record) {
|
|
34
|
+
this.records.set(key, record);
|
|
35
|
+
}
|
|
36
|
+
async delete(key) {
|
|
37
|
+
this.records.delete(key);
|
|
38
|
+
}
|
|
39
|
+
async exists(key) {
|
|
40
|
+
return await this.get(key) !== null;
|
|
41
|
+
}
|
|
42
|
+
cleanup() {
|
|
43
|
+
const now = /* @__PURE__ */ new Date();
|
|
44
|
+
for (const [key, record] of this.records) if (record.expiresAt < now) this.records.delete(key);
|
|
45
|
+
}
|
|
46
|
+
destroy() {
|
|
47
|
+
if (this.cleanupInterval) {
|
|
48
|
+
clearInterval(this.cleanupInterval);
|
|
49
|
+
this.cleanupInterval = null;
|
|
50
|
+
}
|
|
51
|
+
this.records.clear();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var IdempotencyError = class extends Error {
|
|
55
|
+
constructor(message, code) {
|
|
56
|
+
super(message);
|
|
57
|
+
this.code = code;
|
|
58
|
+
this.name = "IdempotencyError";
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Idempotency manager
|
|
63
|
+
*/
|
|
64
|
+
var IdempotencyManager = class {
|
|
65
|
+
store;
|
|
66
|
+
ttl;
|
|
67
|
+
prefix;
|
|
68
|
+
constructor(config = {}) {
|
|
69
|
+
this.store = config.store ?? new MemoryIdempotencyStore();
|
|
70
|
+
this.ttl = config.ttl ?? 1440 * 60 * 1e3;
|
|
71
|
+
this.prefix = config.prefix ?? "idem:";
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Generate a unique idempotency key
|
|
75
|
+
*/
|
|
76
|
+
generateKey() {
|
|
77
|
+
return `${this.prefix}${nanoid(21)}`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Hash request parameters for validation
|
|
81
|
+
* Uses deterministic JSON serialization and simple hash function
|
|
82
|
+
*/
|
|
83
|
+
hashRequest(params) {
|
|
84
|
+
let normalized;
|
|
85
|
+
if (params === null || params === void 0) normalized = null;
|
|
86
|
+
else if (typeof params === "object" && !Array.isArray(params)) normalized = Object.keys(params).sort().reduce((acc, key) => {
|
|
87
|
+
acc[key] = params[key];
|
|
88
|
+
return acc;
|
|
89
|
+
}, {});
|
|
90
|
+
else normalized = params;
|
|
91
|
+
const json = JSON.stringify(normalized);
|
|
92
|
+
let hash = 0;
|
|
93
|
+
for (let i = 0; i < json.length; i++) {
|
|
94
|
+
const char = json.charCodeAt(i);
|
|
95
|
+
hash = (hash << 5) - hash + char;
|
|
96
|
+
hash = hash & hash;
|
|
97
|
+
}
|
|
98
|
+
return Math.abs(hash).toString(36);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Execute operation with idempotency protection
|
|
102
|
+
*/
|
|
103
|
+
async execute(key, params, operation) {
|
|
104
|
+
const fullKey = key.startsWith(this.prefix) ? key : `${this.prefix}${key}`;
|
|
105
|
+
const requestHash = this.hashRequest(params);
|
|
106
|
+
const existing = await this.store.get(fullKey);
|
|
107
|
+
if (existing) {
|
|
108
|
+
if (existing.requestHash !== requestHash) return err(new IdempotencyError("Idempotency key used with different request parameters", "REQUEST_MISMATCH"));
|
|
109
|
+
if (existing.status === "completed" && existing.result !== void 0) return ok(existing.result);
|
|
110
|
+
if (existing.status === "pending") return err(new IdempotencyError("Request with this idempotency key is already in progress", "REQUEST_IN_PROGRESS"));
|
|
111
|
+
if (existing.status === "failed") await this.store.delete(fullKey);
|
|
112
|
+
}
|
|
113
|
+
const record = {
|
|
114
|
+
key: fullKey,
|
|
115
|
+
status: "pending",
|
|
116
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
117
|
+
requestHash,
|
|
118
|
+
expiresAt: new Date(Date.now() + this.ttl)
|
|
119
|
+
};
|
|
120
|
+
await this.store.set(fullKey, record);
|
|
121
|
+
try {
|
|
122
|
+
const result = await operation();
|
|
123
|
+
record.status = "completed";
|
|
124
|
+
record.result = result;
|
|
125
|
+
record.completedAt = /* @__PURE__ */ new Date();
|
|
126
|
+
await this.store.set(fullKey, record);
|
|
127
|
+
return ok(result);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
record.status = "failed";
|
|
130
|
+
await this.store.set(fullKey, record);
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if operation with key was already completed
|
|
136
|
+
*/
|
|
137
|
+
async wasCompleted(key) {
|
|
138
|
+
const fullKey = key.startsWith(this.prefix) ? key : `${this.prefix}${key}`;
|
|
139
|
+
return (await this.store.get(fullKey))?.status === "completed";
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get cached result for key
|
|
143
|
+
*/
|
|
144
|
+
async getCached(key) {
|
|
145
|
+
const fullKey = key.startsWith(this.prefix) ? key : `${this.prefix}${key}`;
|
|
146
|
+
const record = await this.store.get(fullKey);
|
|
147
|
+
return record?.status === "completed" ? record.result ?? null : null;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Invalidate a key (force re-execution on next call)
|
|
151
|
+
*/
|
|
152
|
+
async invalidate(key) {
|
|
153
|
+
const fullKey = key.startsWith(this.prefix) ? key : `${this.prefix}${key}`;
|
|
154
|
+
await this.store.delete(fullKey);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Destroy the idempotency manager and cleanup resources
|
|
158
|
+
* Call this when shutting down to prevent memory leaks
|
|
159
|
+
*/
|
|
160
|
+
destroy() {
|
|
161
|
+
if (this.store instanceof MemoryIdempotencyStore) this.store.destroy();
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Create idempotency manager
|
|
166
|
+
*/
|
|
167
|
+
function createIdempotencyManager(config) {
|
|
168
|
+
return new IdempotencyManager(config);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//#endregion
|
|
172
|
+
export { createIdempotencyManager as n, IdempotencyManager as t };
|