@classytic/crm 0.5.0 → 0.7.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/CHANGELOG.md +124 -0
- package/dist/events.d.ts +475 -2
- package/dist/events.js +180 -59
- package/dist/index.d.ts +2095 -780
- package/dist/index.js +1787 -72
- package/package.json +8 -8
- package/dist/index2.d.ts +0 -746
- /package/dist/{rolldown-runtime.js → chunk.js} +0 -0
package/dist/events.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createEvent as createEvent$1, matchEventPattern } from "@classytic/primitives/events";
|
|
2
1
|
import { z } from "zod";
|
|
2
|
+
import { createEvent as createEvent$1, matchEventPattern } from "@classytic/primitives/events";
|
|
3
3
|
//#region src/events/event-constants.ts
|
|
4
4
|
/** PACKAGE_RULES rule 12: `package:resource.verb`. */
|
|
5
5
|
const CRM_EVENTS = {
|
|
@@ -35,6 +35,16 @@ const CRM_EVENTS = {
|
|
|
35
35
|
SUBSCRIPTION_UNSUBSCRIBED: "crm:subscription.unsubscribed",
|
|
36
36
|
SUBSCRIPTION_BOUNCED: "crm:subscription.bounced",
|
|
37
37
|
SUBSCRIPTION_COMPLAINED: "crm:subscription.complained",
|
|
38
|
+
SEQUENCE_CREATED: "crm:sequence.created",
|
|
39
|
+
SEQUENCE_ACTIVATED: "crm:sequence.active",
|
|
40
|
+
SEQUENCE_PAUSED: "crm:sequence.paused",
|
|
41
|
+
SEQUENCE_ARCHIVED: "crm:sequence.archived",
|
|
42
|
+
ENROLLMENT_CREATED: "crm:enrollment.created",
|
|
43
|
+
ENROLLMENT_STEP_SENT: "crm:enrollment.step_sent",
|
|
44
|
+
ENROLLMENT_PAUSED: "crm:enrollment.paused",
|
|
45
|
+
ENROLLMENT_RESUMED: "crm:enrollment.resumed",
|
|
46
|
+
ENROLLMENT_COMPLETED: "crm:enrollment.completed",
|
|
47
|
+
ENROLLMENT_EXITED: "crm:enrollment.exited",
|
|
38
48
|
EMAIL_EVENT_OPENED: "crm:email_event.opened",
|
|
39
49
|
EMAIL_EVENT_CLICKED: "crm:email_event.clicked",
|
|
40
50
|
EMAIL_EVENT_BOUNCED: "crm:email_event.bounced",
|
|
@@ -53,6 +63,8 @@ const CRM_EVENTS = {
|
|
|
53
63
|
OPPORTUNITY_EXTENDED: "crm:opportunity.extended",
|
|
54
64
|
ACTIVITY_RESCHEDULED: "crm:activity.rescheduled",
|
|
55
65
|
ACTIVITY_OUTCOME_RECORDED: "crm:activity.outcome_recorded",
|
|
66
|
+
SUPPRESSION_ADDED: "crm:suppression.added",
|
|
67
|
+
SUPPRESSION_REMOVED: "crm:suppression.removed",
|
|
56
68
|
CONVERSATION_CREATED: "crm:conversation.created",
|
|
57
69
|
CONVERSATION_ASSIGNED: "crm:conversation.assigned",
|
|
58
70
|
CONVERSATION_RESOLVED: "crm:conversation.resolved",
|
|
@@ -60,62 +72,11 @@ const CRM_EVENTS = {
|
|
|
60
72
|
MESSAGE_RECEIVED: "crm:message.received",
|
|
61
73
|
MESSAGE_SENT: "crm:message.sent"
|
|
62
74
|
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
* Thin wrapper around `@classytic/primitives`' `createEvent` that fills the
|
|
69
|
-
* shared `EventMeta` from a `CrmContext` (userId/actorId, organizationId,
|
|
70
|
-
* correlationId). Use this instead of importing `createEvent` directly so
|
|
71
|
-
* the `source: 'crm'` stamp + tenant scoping stay consistent.
|
|
72
|
-
*/
|
|
73
|
-
function createEvent(type, payload, ctx, meta) {
|
|
74
|
-
return createEvent$1(type, payload, {
|
|
75
|
-
source: "crm",
|
|
76
|
-
...ctx?.actorId !== void 0 ? { actorId: String(ctx.actorId) } : {},
|
|
77
|
-
...ctx?.organizationId !== void 0 ? { organizationId: String(ctx.organizationId) } : {},
|
|
78
|
-
...ctx?.correlationId !== void 0 ? { correlationId: ctx.correlationId } : {},
|
|
79
|
-
...meta
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
//#endregion
|
|
83
|
-
//#region src/events/in-process-bus.ts
|
|
84
|
-
/**
|
|
85
|
-
* In-process event bus — default fallback when no `eventTransport` is
|
|
86
|
-
* provided to `createCrm`. Structurally identical to arc's
|
|
87
|
-
* `MemoryEventTransport`; pattern matching is delegated to primitives.
|
|
88
|
-
* Handler errors are swallowed — event emission never blocks writes.
|
|
89
|
-
*/
|
|
90
|
-
var InProcessCrmBus = class {
|
|
91
|
-
name = "in-process-crm";
|
|
92
|
-
subs = [];
|
|
93
|
-
logger;
|
|
94
|
-
constructor(options) {
|
|
95
|
-
if (options?.logger) this.logger = options.logger;
|
|
96
|
-
}
|
|
97
|
-
async publish(event) {
|
|
98
|
-
const matching = this.subs.filter((s) => matchEventPattern(s.pattern, event.type));
|
|
99
|
-
for (const sub of matching) try {
|
|
100
|
-
await sub.handler(event);
|
|
101
|
-
} catch (err) {
|
|
102
|
-
this.logger?.error?.(`[crm] event handler error [${event.type}]`, { error: err instanceof Error ? err.message : String(err) });
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
async subscribe(pattern, handler) {
|
|
106
|
-
const sub = {
|
|
107
|
-
pattern,
|
|
108
|
-
handler
|
|
109
|
-
};
|
|
110
|
-
this.subs.push(sub);
|
|
111
|
-
return () => {
|
|
112
|
-
this.subs = this.subs.filter((s) => s !== sub);
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
async close() {
|
|
116
|
-
this.subs = [];
|
|
117
|
-
}
|
|
118
|
-
};
|
|
75
|
+
const SUPPRESSION_REASONS = [...[
|
|
76
|
+
"bounce",
|
|
77
|
+
"complaint",
|
|
78
|
+
"unsubscribe"
|
|
79
|
+
], "manual"];
|
|
119
80
|
//#endregion
|
|
120
81
|
//#region src/events/event-catalog.ts
|
|
121
82
|
/**
|
|
@@ -554,6 +515,22 @@ const SubscriptionComplained = defineCrmEvent({
|
|
|
554
515
|
campaignId: z.string()
|
|
555
516
|
})
|
|
556
517
|
});
|
|
518
|
+
const SuppressionAdded = defineCrmEvent({
|
|
519
|
+
name: CRM_EVENTS.SUPPRESSION_ADDED,
|
|
520
|
+
resource: "suppression",
|
|
521
|
+
description: "suppress() inserted a NEW row on the org-wide suppression list (idempotent re-suppress of an existing email emits nothing). organizationId rides event meta.",
|
|
522
|
+
zodSchema: z.object({
|
|
523
|
+
email: z.string(),
|
|
524
|
+
reason: z.enum(SUPPRESSION_REASONS),
|
|
525
|
+
source: z.string().optional()
|
|
526
|
+
})
|
|
527
|
+
});
|
|
528
|
+
const SuppressionRemoved = defineCrmEvent({
|
|
529
|
+
name: CRM_EVENTS.SUPPRESSION_REMOVED,
|
|
530
|
+
resource: "suppression",
|
|
531
|
+
description: "unsuppress() removed an email from the org-wide suppression list.",
|
|
532
|
+
zodSchema: z.object({ email: z.string() })
|
|
533
|
+
});
|
|
557
534
|
const emailEventSchema = z.object({
|
|
558
535
|
eventId: z.string(),
|
|
559
536
|
kind: z.string(),
|
|
@@ -654,6 +631,82 @@ const MessageSent = defineCrmEvent({
|
|
|
654
631
|
externalMessageId: z.string().optional()
|
|
655
632
|
})
|
|
656
633
|
});
|
|
634
|
+
const SequenceCreated = defineCrmEvent({
|
|
635
|
+
name: CRM_EVENTS.SEQUENCE_CREATED,
|
|
636
|
+
resource: "sequence",
|
|
637
|
+
description: "A sequence draft was created. Emitted by the HOST after repo.create() (the package ships no createSequence verb) — defined here so registries validate the payload.",
|
|
638
|
+
zodSchema: z.object({
|
|
639
|
+
sequenceId: z.string(),
|
|
640
|
+
name: z.string().optional()
|
|
641
|
+
})
|
|
642
|
+
});
|
|
643
|
+
const SequenceActivated = defineCrmEvent({
|
|
644
|
+
name: CRM_EVENTS.SEQUENCE_ACTIVATED,
|
|
645
|
+
resource: "sequence",
|
|
646
|
+
description: "activate() moved a sequence draft/paused → active.",
|
|
647
|
+
zodSchema: z.object({ sequenceId: z.string() })
|
|
648
|
+
});
|
|
649
|
+
const SequencePaused = defineCrmEvent({
|
|
650
|
+
name: CRM_EVENTS.SEQUENCE_PAUSED,
|
|
651
|
+
resource: "sequence",
|
|
652
|
+
description: "pause() suspended an active sequence (existing enrollments hold).",
|
|
653
|
+
zodSchema: z.object({ sequenceId: z.string() })
|
|
654
|
+
});
|
|
655
|
+
const SequenceArchived = defineCrmEvent({
|
|
656
|
+
name: CRM_EVENTS.SEQUENCE_ARCHIVED,
|
|
657
|
+
resource: "sequence",
|
|
658
|
+
description: "archive() retired a sequence — no new enrollments.",
|
|
659
|
+
zodSchema: z.object({ sequenceId: z.string() })
|
|
660
|
+
});
|
|
661
|
+
const EnrollmentCreated = defineCrmEvent({
|
|
662
|
+
name: CRM_EVENTS.ENROLLMENT_CREATED,
|
|
663
|
+
resource: "enrollment",
|
|
664
|
+
description: "enroll() attached a subject to a sequence.",
|
|
665
|
+
zodSchema: z.object({
|
|
666
|
+
enrollmentId: z.string(),
|
|
667
|
+
sequenceId: z.string(),
|
|
668
|
+
subjectId: z.string(),
|
|
669
|
+
subjectKind: z.string()
|
|
670
|
+
})
|
|
671
|
+
});
|
|
672
|
+
const EnrollmentStepSent = defineCrmEvent({
|
|
673
|
+
name: CRM_EVENTS.ENROLLMENT_STEP_SENT,
|
|
674
|
+
resource: "enrollment",
|
|
675
|
+
description: "A sequence step was delivered. Emitted by the HOST outreach layer after its send adapter succeeds + advanceStep() commits (Buffer-style pattern in CLAUDE.md) — defined here so registries validate the payload.",
|
|
676
|
+
zodSchema: z.object({
|
|
677
|
+
enrollmentId: z.string(),
|
|
678
|
+
sequenceId: z.string().optional(),
|
|
679
|
+
stepIndex: z.number(),
|
|
680
|
+
channel: z.string().optional()
|
|
681
|
+
})
|
|
682
|
+
});
|
|
683
|
+
const EnrollmentPaused = defineCrmEvent({
|
|
684
|
+
name: CRM_EVENTS.ENROLLMENT_PAUSED,
|
|
685
|
+
resource: "enrollment",
|
|
686
|
+
description: "pause() held an active enrollment.",
|
|
687
|
+
zodSchema: z.object({ enrollmentId: z.string() })
|
|
688
|
+
});
|
|
689
|
+
const EnrollmentResumed = defineCrmEvent({
|
|
690
|
+
name: CRM_EVENTS.ENROLLMENT_RESUMED,
|
|
691
|
+
resource: "enrollment",
|
|
692
|
+
description: "resume() reactivated a paused enrollment.",
|
|
693
|
+
zodSchema: z.object({ enrollmentId: z.string() })
|
|
694
|
+
});
|
|
695
|
+
const EnrollmentCompleted = defineCrmEvent({
|
|
696
|
+
name: CRM_EVENTS.ENROLLMENT_COMPLETED,
|
|
697
|
+
resource: "enrollment",
|
|
698
|
+
description: "complete() finished the final step of an enrollment.",
|
|
699
|
+
zodSchema: z.object({ enrollmentId: z.string() })
|
|
700
|
+
});
|
|
701
|
+
const EnrollmentExited = defineCrmEvent({
|
|
702
|
+
name: CRM_EVENTS.ENROLLMENT_EXITED,
|
|
703
|
+
resource: "enrollment",
|
|
704
|
+
description: "exit() removed a subject before completion (reply/unsubscribe/manual/goal).",
|
|
705
|
+
zodSchema: z.object({
|
|
706
|
+
enrollmentId: z.string(),
|
|
707
|
+
exitReason: z.string().optional()
|
|
708
|
+
})
|
|
709
|
+
});
|
|
657
710
|
const crmEventDefinitions = [
|
|
658
711
|
LeadCreated,
|
|
659
712
|
LeadStatusChanged,
|
|
@@ -700,6 +753,8 @@ const crmEventDefinitions = [
|
|
|
700
753
|
SubscriptionUnsubscribed,
|
|
701
754
|
SubscriptionBounced,
|
|
702
755
|
SubscriptionComplained,
|
|
756
|
+
SuppressionAdded,
|
|
757
|
+
SuppressionRemoved,
|
|
703
758
|
EmailEventOpened,
|
|
704
759
|
EmailEventClicked,
|
|
705
760
|
EmailEventBounced,
|
|
@@ -710,7 +765,73 @@ const crmEventDefinitions = [
|
|
|
710
765
|
ConversationResolved,
|
|
711
766
|
ConversationReopened,
|
|
712
767
|
MessageReceived,
|
|
713
|
-
MessageSent
|
|
768
|
+
MessageSent,
|
|
769
|
+
SequenceCreated,
|
|
770
|
+
SequenceActivated,
|
|
771
|
+
SequencePaused,
|
|
772
|
+
SequenceArchived,
|
|
773
|
+
EnrollmentCreated,
|
|
774
|
+
EnrollmentStepSent,
|
|
775
|
+
EnrollmentPaused,
|
|
776
|
+
EnrollmentResumed,
|
|
777
|
+
EnrollmentCompleted,
|
|
778
|
+
EnrollmentExited
|
|
714
779
|
];
|
|
715
780
|
//#endregion
|
|
716
|
-
|
|
781
|
+
//#region src/events/helpers.ts
|
|
782
|
+
/**
|
|
783
|
+
* Event creation helper.
|
|
784
|
+
*
|
|
785
|
+
* Thin wrapper around `@classytic/primitives`' `createEvent` that fills the
|
|
786
|
+
* shared `EventMeta` from a `CrmContext` (userId/actorId, organizationId,
|
|
787
|
+
* correlationId). Use this instead of importing `createEvent` directly so
|
|
788
|
+
* the `source: 'crm'` stamp + tenant scoping stay consistent.
|
|
789
|
+
*/
|
|
790
|
+
function createEvent(type, payload, ctx, meta) {
|
|
791
|
+
return createEvent$1(type, payload, {
|
|
792
|
+
source: "crm",
|
|
793
|
+
...ctx?.actorId !== void 0 ? { actorId: String(ctx.actorId) } : {},
|
|
794
|
+
...ctx?.organizationId !== void 0 ? { organizationId: String(ctx.organizationId) } : {},
|
|
795
|
+
...ctx?.correlationId !== void 0 ? { correlationId: ctx.correlationId } : {},
|
|
796
|
+
...meta
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
//#endregion
|
|
800
|
+
//#region src/events/in-process-bus.ts
|
|
801
|
+
/**
|
|
802
|
+
* In-process event bus — default fallback when no `eventTransport` is
|
|
803
|
+
* provided to `createCrm`. Structurally identical to arc's
|
|
804
|
+
* `MemoryEventTransport`; pattern matching is delegated to primitives.
|
|
805
|
+
* Handler errors are swallowed — event emission never blocks writes.
|
|
806
|
+
*/
|
|
807
|
+
var InProcessCrmBus = class {
|
|
808
|
+
name = "in-process-crm";
|
|
809
|
+
subs = [];
|
|
810
|
+
logger;
|
|
811
|
+
constructor(options) {
|
|
812
|
+
if (options?.logger) this.logger = options.logger;
|
|
813
|
+
}
|
|
814
|
+
async publish(event) {
|
|
815
|
+
const matching = this.subs.filter((s) => matchEventPattern(s.pattern, event.type));
|
|
816
|
+
for (const sub of matching) try {
|
|
817
|
+
await sub.handler(event);
|
|
818
|
+
} catch (err) {
|
|
819
|
+
this.logger?.error?.(`[crm] event handler error [${event.type}]`, { error: err instanceof Error ? err.message : String(err) });
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
async subscribe(pattern, handler) {
|
|
823
|
+
const sub = {
|
|
824
|
+
pattern,
|
|
825
|
+
handler
|
|
826
|
+
};
|
|
827
|
+
this.subs.push(sub);
|
|
828
|
+
return () => {
|
|
829
|
+
this.subs = this.subs.filter((s) => s !== sub);
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
async close() {
|
|
833
|
+
this.subs = [];
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
//#endregion
|
|
837
|
+
export { AccountAssigned, AccountCreated, AccountEnriched, AccountMerged, AccountUpdated, ActivityCancelled, ActivityCompleted, ActivityOutcomeRecorded, ActivityPlanned, ActivityRescheduled, CRM_EVENTS, CampaignActivated, CampaignArchived, CampaignCompleted, CampaignCreated, CampaignPaused, CampaignResumed, ContactAssigned, ContactCreated, ContactEnriched, ContactMerged, ContactUpdated, ConversationAssigned, ConversationCreated, ConversationReopened, ConversationResolved, EmailEventBounced, EmailEventClicked, EmailEventComplained, EmailEventOpened, EmailEventUnsubscribed, EnrollmentCompleted, EnrollmentCreated, EnrollmentExited, EnrollmentPaused, EnrollmentResumed, EnrollmentStepSent, InProcessCrmBus, LeadAssigned, LeadConverted, LeadCreated, LeadDisqualified, LeadEnriched, LeadScored, LeadStatusChanged, MessageReceived, MessageSent, NoteAdded, OpportunityAbandoned, OpportunityAmountChanged, OpportunityAssigned, OpportunityCreated, OpportunityExtended, OpportunityLost, OpportunityStageAdvanced, OpportunityStageRegressed, OpportunityWon, PipelineArchived, PipelineCreated, SequenceActivated, SequenceArchived, SequenceCreated, SequencePaused, SubscriptionBounced, SubscriptionComplained, SubscriptionConfirmed, SubscriptionCreated, SubscriptionUnsubscribed, SuppressionAdded, SuppressionRemoved, createEvent, crmEventDefinitions };
|