@happyvertical/smrt-sales 0.40.19 → 0.40.21

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.
@@ -1 +1 @@
1
- {"version":3,"file":"__smrt-register__-ck7DyZQk.js","names":[],"sources":["../../src/__smrt-register__.ts"],"sourcesContent":["import { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(\n new URL('./manifest.json', import.meta.url),\n);\n"],"mappings":""}
1
+ {"version":3,"file":"__smrt-register__-BG5Ze6GV.js","names":[],"sources":["../../src/__smrt-register__.ts"],"sourcesContent":["import { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(\n new URL('./manifest.json', import.meta.url),\n);\n"],"mappings":""}
@@ -1632,6 +1632,23 @@ var ReferralClickValidationError = class extends Error {
1632
1632
  details;
1633
1633
  code = "REFERRAL_CLICK_VALIDATION_ERROR";
1634
1634
  };
1635
+ function isTransactionHandle(db) {
1636
+ return typeof db.commit === "function" && typeof db.rollback === "function" && typeof db.isActive === "function";
1637
+ }
1638
+ function isTransactionScopedDatabase(db) {
1639
+ const capable = db;
1640
+ if (isTransactionHandle(capable)) return true;
1641
+ return typeof capable.transaction === "function" && typeof capable.beginTransaction !== "function" && typeof capable.acquireSession !== "function" && typeof capable.close !== "function";
1642
+ }
1643
+ function assertParticipatableTransaction(tx) {
1644
+ const candidate = tx;
1645
+ if (candidate === null || typeof candidate !== "object" || typeof candidate.query !== "function") throw new ReferralClickValidationError("invalid_transaction", "Referral click transaction must be an open transaction database — the callback argument of db.transaction() or an active beginTransaction() handle");
1646
+ if (isTransactionHandle(candidate)) {
1647
+ if (candidate.isActive() !== true) throw new ReferralClickValidationError("invalid_transaction", "Referral click transaction has already been committed or rolled back");
1648
+ return;
1649
+ }
1650
+ if (typeof candidate.beginTransaction === "function" || typeof candidate.acquireSession === "function" || typeof candidate.close === "function") throw new ReferralClickValidationError("invalid_transaction", "Referral click transaction received a pool-level database; pass the transaction-scoped database your db.transaction() callback received so the click joins your transaction instead of running untransacted");
1651
+ }
1635
1652
  var ReferralLinkCollection = class ReferralLinkCollection extends SmrtCollection {
1636
1653
  static _itemClass = ReferralLink;
1637
1654
  /** All links for a referrer, newest first. */
@@ -1689,6 +1706,23 @@ var ReferralLinkCollection = class ReferralLinkCollection extends SmrtCollection
1689
1706
  * returns the original touch without another increment; changed immutable
1690
1707
  * intent raises {@link ReferralClickReplayConflictError}.
1691
1708
  *
1709
+ * Transactions: by default (collection bound to a pool-level database)
1710
+ * the click opens and commits its own transaction, and the returned
1711
+ * models are re-read on the collection's database after commit. To record
1712
+ * a click inside YOUR transaction — required whenever your transaction
1713
+ * holds locks the click needs (above all the `referral_links` row it
1714
+ * increments) or created the link it resolves — either pass the
1715
+ * transaction database as {@link RecordClickInput.transaction} or call
1716
+ * `recordClick` on a collection bound to it
1717
+ * (`ReferralLinkCollection.create({ db: tx, _reuseInitializedDb: true,
1718
+ * _deferRuntimeInitialization: true })`). Both participate in the caller
1719
+ * transaction instead of nesting (a nested adapter `transaction()` takes
1720
+ * an independent pooled connection: it deadlocks undetectably on locks
1721
+ * your transaction holds and cannot see your uncommitted rows —
1722
+ * happyvertical/sdk#1108) and return models bound to it: commit/rollback
1723
+ * and durability belong to you, and refusals/replays reflect your
1724
+ * transaction's view.
1725
+ *
1692
1726
  * Evidence is canonicalized, Sales-owned `code`/`linkId`/`targetUrl` fields
1693
1727
  * are applied, and the UTF-8 bytes of that exact persisted JSON are checked
1694
1728
  * before any write. The default bound is
@@ -1702,18 +1736,40 @@ var ReferralLinkCollection = class ReferralLinkCollection extends SmrtCollection
1702
1736
  */
1703
1737
  async recordClick(input) {
1704
1738
  const request = canonicalizeClickRequest(input);
1739
+ if (input.transaction !== void 0) {
1740
+ assertParticipatableTransaction(input.transaction);
1741
+ return await this.recordClickInTransaction(await ReferralLinkCollection.createClickCollections(input.transaction), request);
1742
+ }
1705
1743
  const db = this.db;
1744
+ if (isTransactionScopedDatabase(db)) return await this.recordClickInTransaction(await ReferralLinkCollection.createClickCollections(db), request);
1706
1745
  if (typeof db.transaction !== "function") throw new ReferralClickValidationError("transaction_unavailable", "Referral click recording requires a transaction-capable database adapter");
1707
1746
  const transactionResult = await db.transaction(async (tx) => {
1708
- const deps = {
1709
- links: await ReferralLinkCollection.create({ db: tx }),
1710
- touches: await ReferralTouchCollection.create({ db: tx }),
1711
- operations: await ReferralClickOperationCollection.create({ db: tx })
1712
- };
1713
- return await this.recordClickInTransaction(deps, request);
1747
+ return await this.recordClickInTransaction(await ReferralLinkCollection.createClickCollections(tx), request);
1714
1748
  });
1715
1749
  return await this.rehydrateRecordClickResult(transactionResult);
1716
1750
  }
1751
+ /**
1752
+ * Bind the click's working collections to one transaction database. The
1753
+ * transaction is the same initialized database on a pinned connection, so
1754
+ * the lightweight-binding flags are requested (mirrors
1755
+ * `CommissionPayoutService.txOptions`). Note `SmrtCollection.create()`
1756
+ * currently forwards only whitelisted options — the two internal flags
1757
+ * are dropped there today, and it is the same-URL system-table cache that
1758
+ * keeps bootstrap DDL out of the transaction in practice; the flags make
1759
+ * the intent explicit and take effect when core forwards them.
1760
+ */
1761
+ static async createClickCollections(txDb) {
1762
+ const options = {
1763
+ db: txDb,
1764
+ _reuseInitializedDb: true,
1765
+ _deferRuntimeInitialization: true
1766
+ };
1767
+ return {
1768
+ links: await ReferralLinkCollection.create(options),
1769
+ touches: await ReferralTouchCollection.create(options),
1770
+ operations: await ReferralClickOperationCollection.create(options)
1771
+ };
1772
+ }
1717
1773
  /** Rebind public result models to the caller's database after commit. */
1718
1774
  async rehydrateRecordClickResult(result) {
1719
1775
  let link = null;
@@ -3355,4 +3411,4 @@ var ReferralQualificationService = class ReferralQualificationService {
3355
3411
  //#endregion
3356
3412
  export { ReferralClickOperation as A, ATTRIBUTION_RESOLUTION_MODES as B, ReferralTouchCollection as C, ReferralCollection as D, assertHttpTargetUrl as E, validateAttributionPolicyTerms as F, REFERRAL_STATUSES as G, REFERRAL_AGREEMENT_STATUSES as H, ATTRIBUTION_CONFLICT_BEHAVIORS as I, AttributionExceptionCollection as J, REFERRAL_TOUCH_KINDS as K, ATTRIBUTION_CREDIT_MODES as L, ReferralAgreement as M, AttributionPolicyCollection as N, Referral as O, AttributionPolicy as P, ATTRIBUTION_EXCEPTION_STATUSES as R, generateReferralCode as S, ReferralLink as T, REFERRAL_LINK_STATUSES as U, REFERRAL_AGREEMENT_APPROVAL_MODES as V, REFERRAL_PROGRAM_STATUSES as W, AttributionException as Y, REFERRAL_CODE_ALPHABET as _, ReferralAgreementExecutionService as a, ReferralClickValidationError as b, ReferrerCollection as c, ReferralTermSnapshot as d, ReferralProgramCollection as f, MAX_REFERRAL_CLICK_IDEMPOTENCY_KEY_BYTES as g, MAX_CODE_GENERATION_ATTEMPTS as h, REFERRAL_AGREEMENT_SOURCE_KIND as i, ReferralAgreementCollection as j, ReferralClickOperationCollection as k, Referrer as l, DEFAULT_REFERRAL_CLICK_EVIDENCE_MAX_BYTES as m, REFERRAL_TERMS_SNAPSHOT_KIND as n, AttributionService as o, ReferralProgram as p, REFERRER_STATUSES as q, ReferralCommissionService as r, QualifiedReferralOverrideError as s, ReferralQualificationService as t, ReferralTermSnapshotCollection as u, REFERRAL_CODE_LENGTH as v, ReferralTouch as w, ReferralLinkCollection as x, ReferralClickReplayConflictError as y, ATTRIBUTION_POLICY_STATUSES as z };
3357
3413
 
3358
- //# sourceMappingURL=referrals-CeS9N5PI.js.map
3414
+ //# sourceMappingURL=referrals-BzTlbjJH.js.map