@mirafive/convex 2.0.0 → 2.1.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/README.md CHANGED
@@ -65,6 +65,8 @@ export const pay = mutation({
65
65
  | `mira.group(ctx, { groupId, traits? })` | The company or account |
66
66
  | `mira.revenue(ctx, { amount, currency, entryId?, subscription?, … })` | Money for the revenue ledger |
67
67
  | `mira.touchpoint(ctx, { kind, source \| channel, userId \| anonymousId, … })` | A touchpoint that is not a visit |
68
+ | `mira.dealStage(ctx, { dealId, stage, value?, userId \\ | anonymousId })` | A deal of the pipeline reached a stage (value in minor units, expected, not revenue) |
69
+ | `mira.dealLost(ctx, { dealId, reason?, userId \\ | anonymousId })` | A deal was lost |
68
70
  | `mira.schedule(ctx, events)` | Several at once (`{ method: "track", … }`) |
69
71
  | `mira.deliver(events)` | Sends now; for the internal action. Returns `{ sent, failed, errors }`, never throws. |
70
72
 
package/dist/index.d.ts CHANGED
@@ -25,9 +25,9 @@
25
25
  * await mira.revenue(ctx, { userId, amount: 4900, currency: "EUR", dedupeKey: `order:${id}:paid` });
26
26
  * ```
27
27
  */
28
- import { type EventMap, type GroupInput, type IdentifyInput, type MiraOptions, type RevenueInput, type TouchpointInput, type TrackInput } from "@mirafive/node";
28
+ import { type DealLostInput, type DealStageInput, type EventMap, type GroupInput, type IdentifyInput, type MiraOptions, type RevenueInput, type TouchpointInput, type TrackInput } from "@mirafive/node";
29
29
  export { eventIdFor, MiraError } from "@mirafive/node";
30
- export type { EventMap, GroupInput, IdentifyInput, MiraOptions, RevenueInput, TouchpointInput, TrackInput, } from "@mirafive/node";
30
+ export type { DealLostInput, DealStageInput, EventMap, GroupInput, IdentifyInput, MiraOptions, RevenueInput, TouchpointInput, TrackInput, } from "@mirafive/node";
31
31
  /** A stable key (`order:123:paid`) that becomes the event id, so a retried mutation counts once. */
32
32
  interface Dedupe {
33
33
  dedupeKey?: string;
@@ -43,7 +43,11 @@ export type MiraEvent = ({
43
43
  method: "revenue";
44
44
  } & RevenueInput & Dedupe) | ({
45
45
  method: "touchpoint";
46
- } & TouchpointInput & Dedupe);
46
+ } & TouchpointInput & Dedupe) | ({
47
+ method: "dealStage";
48
+ } & DealStageInput & Dedupe) | ({
49
+ method: "dealLost";
50
+ } & DealLostInput & Dedupe);
47
51
  /** The part of a Convex mutation or action context this package uses. */
48
52
  export interface SchedulerCtx {
49
53
  scheduler: {
@@ -72,6 +76,13 @@ export declare class MiraConvex<Events extends EventMap = EventMap> {
72
76
  /** Money for the revenue ledger. Give it a `dedupeKey` or `entryId`, so a retry counts once. */
73
77
  revenue(ctx: SchedulerCtx, input: RevenueInput & Dedupe): Promise<void>;
74
78
  touchpoint(ctx: SchedulerCtx, input: TouchpointInput & Dedupe): Promise<void>;
79
+ /**
80
+ * A deal of the pipeline reached a stage, sent after the mutation that moved it commits.
81
+ * A stable `dedupeKey` (`case:${id}:stage:${stage}`) keeps a retried mutation from counting twice.
82
+ */
83
+ dealStage(ctx: SchedulerCtx, input: DealStageInput & Dedupe): Promise<void>;
84
+ /** A deal was lost, sent after the mutation commits. */
85
+ dealLost(ctx: SchedulerCtx, input: DealLostInput & Dedupe): Promise<void>;
75
86
  /** Several events in one scheduled delivery. */
76
87
  schedule(ctx: SchedulerCtx, events: MiraEvent[]): Promise<void>;
77
88
  /**
package/dist/index.js CHANGED
@@ -29,6 +29,12 @@ class MiraConvex {
29
29
  touchpoint(ctx, input) {
30
30
  return this.schedule(ctx, [{ method: "touchpoint", ...input }]);
31
31
  }
32
+ dealStage(ctx, input) {
33
+ return this.schedule(ctx, [{ method: "dealStage", ...input }]);
34
+ }
35
+ dealLost(ctx, input) {
36
+ return this.schedule(ctx, [{ method: "dealLost", ...input }]);
37
+ }
32
38
  async schedule(ctx, events) {
33
39
  if (!events.length)
34
40
  return;
@@ -77,6 +83,12 @@ class MiraConvex {
77
83
  case "touchpoint":
78
84
  mira.touchpoint({ ...input, eventId });
79
85
  break;
86
+ case "dealStage":
87
+ mira.dealStage({ ...input, eventId });
88
+ break;
89
+ case "dealLost":
90
+ mira.dealLost({ ...input, eventId });
91
+ break;
80
92
  default:
81
93
  errors.push(`MIRA FIVE: unknown method: ${String(method)}`);
82
94
  }
@@ -94,5 +106,5 @@ export {
94
106
  eventIdFor2 as eventIdFor
95
107
  };
96
108
 
97
- //# debugId=21BF33B329BC4D5064756E2164756E21
109
+ //# debugId=059D2928FA511C6164756E2164756E21
98
110
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * `@mirafive/convex`: MIRA FIVE events from Convex mutations and actions.\n *\n * Mutations are transactional and cannot use the network, so an event is scheduled with\n * `ctx.scheduler` in the same transaction and delivered by an internal action right after it\n * commits. A mutation that rolls back sends nothing, so an order that never happened is never\n * counted. No dependency on `convex`; it runs in Convex's default runtime (no `\"use node\"`).\n *\n * ```ts\n * // convex/mira.ts\n * import { MiraConvex } from \"@mirafive/convex\";\n * import { v } from \"convex/values\";\n * import { internal } from \"./_generated/api\";\n * import { internalAction } from \"./_generated/server\";\n *\n * // The `: MiraConvex` annotation is required: it breaks the type cycle through `internal`.\n * export const mira: MiraConvex = new MiraConvex(internal.mira.deliver);\n *\n * export const deliver = internalAction({\n * args: { events: v.array(v.any()) },\n * handler: (_ctx, { events }) => mira.deliver(events),\n * });\n *\n * // convex/orders.ts, in a mutation\n * await mira.revenue(ctx, { userId, amount: 4900, currency: \"EUR\", dedupeKey: `order:${id}:paid` });\n * ```\n */\nimport {\n eventIdFor,\n Mira,\n MiraError,\n type EventMap,\n type GroupInput,\n type IdentifyInput,\n type MiraOptions,\n type RevenueInput,\n type TouchpointInput,\n type TrackInput,\n} from \"@mirafive/node\";\n\nexport { eventIdFor, MiraError } from \"@mirafive/node\";\nexport type {\n EventMap,\n GroupInput,\n IdentifyInput,\n MiraOptions,\n RevenueInput,\n TouchpointInput,\n TrackInput,\n} from \"@mirafive/node\";\n\n/** A stable key (`order:123:paid`) that becomes the event id, so a retried mutation counts once. */\ninterface Dedupe {\n dedupeKey?: string;\n}\n\n/** One event as it travels through `ctx.scheduler`: the method, its input and a dedupe key. */\nexport type MiraEvent =\n | ({ method: \"track\" } & TrackInput & Dedupe)\n | ({ method: \"identify\" } & IdentifyInput & Dedupe)\n | ({ method: \"group\" } & GroupInput & Dedupe)\n | ({ method: \"revenue\" } & RevenueInput & Dedupe)\n | ({ method: \"touchpoint\" } & TouchpointInput & Dedupe);\n\n/** The part of a Convex mutation or action context this package uses. */\nexport interface SchedulerCtx {\n scheduler: { runAfter: (delayMs: number, fn: never, args: never) => Promise<unknown> };\n}\n\nexport interface DeliverResult {\n sent: number;\n failed: number;\n errors: string[];\n}\n\n/**\n * Makes an event a Convex value: `Date`s become ISO strings and `undefined` fields disappear,\n * so `ctx.scheduler` accepts it.\n */\nconst toConvexValue = (event: MiraEvent): MiraEvent =>\n JSON.parse(JSON.stringify(event)) as MiraEvent;\n\nexport class MiraConvex<Events extends EventMap = EventMap> {\n /**\n * @param deliverFunction The internal action that calls `mira.deliver(events)`, for example\n * `internal.mira.deliver`.\n * @param options Delivery options. The key defaults to the deployment's `MIRAFIVE_SECRET_KEY`\n * (`npx convex env set MIRAFIVE_SECRET_KEY mira_sk_…`) and the host to `MIRAFIVE_HOST`.\n */\n private readonly deliverFunction: unknown;\n private readonly options: MiraOptions;\n\n constructor(deliverFunction: unknown, options: MiraOptions = {}) {\n this.deliverFunction = deliverFunction;\n this.options = options;\n }\n\n /** A custom event, sent after the current mutation commits. */\n track<Name extends keyof Events & string>(\n ctx: SchedulerCtx,\n input: TrackInput<Events, Name> & Dedupe,\n ): Promise<void> {\n return this.schedule(ctx, [{ method: \"track\", ...(input as TrackInput & Dedupe) }]);\n }\n\n identify(ctx: SchedulerCtx, input: IdentifyInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"identify\", ...input }]);\n }\n\n group(ctx: SchedulerCtx, input: GroupInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"group\", ...input }]);\n }\n\n /** Money for the revenue ledger. Give it a `dedupeKey` or `entryId`, so a retry counts once. */\n revenue(ctx: SchedulerCtx, input: RevenueInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"revenue\", ...input }]);\n }\n\n touchpoint(ctx: SchedulerCtx, input: TouchpointInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"touchpoint\", ...input }]);\n }\n\n /** Several events in one scheduled delivery. */\n async schedule(ctx: SchedulerCtx, events: MiraEvent[]): Promise<void> {\n if (!events.length) return;\n try {\n await ctx.scheduler.runAfter(\n 0,\n this.deliverFunction as never,\n {\n events: events.map(toConvexValue),\n } as never,\n );\n } catch (error) {\n // Analytics must never fail the mutation that records the real fact.\n this.options.onError?.(\n new MiraError(\"dropped\", \"could not schedule delivery\", { cause: error }),\n );\n }\n }\n\n /**\n * Sends events now and waits for delivery. The internal action's handler calls it; never call\n * it from a mutation or query (they cannot use the network). Never throws: a MIRA FIVE outage\n * must not fail your action. Problems are in `errors`.\n */\n async deliver(events: MiraEvent[]): Promise<DeliverResult> {\n const errors: string[] = [];\n const failedIds = new Set<string>();\n let invalid = 0;\n\n const mira = new Mira({\n // Actions have a time limit; fewer retries keep them short.\n maxRetries: 3,\n ...this.options,\n flushAt: 100,\n onError: (error: MiraError) => {\n errors.push(error.message);\n for (const id of error.eventIds) failedIds.add(id);\n this.options.onError?.(error);\n },\n });\n if (errors.length) return { sent: 0, failed: events.length, errors };\n\n for (const item of events) {\n const before = errors.length;\n const eventId =\n item.eventId ?? (item.dedupeKey ? await eventIdFor(item.dedupeKey) : undefined);\n const { method, dedupeKey: _, ...input } = item as MiraEvent & { method: unknown };\n switch (method) {\n case \"track\":\n mira.track({ ...(input as TrackInput), eventId });\n break;\n case \"identify\":\n mira.identify({ ...(input as IdentifyInput), eventId });\n break;\n case \"group\":\n mira.group({ ...(input as GroupInput), eventId });\n break;\n case \"revenue\":\n mira.revenue({ ...(input as RevenueInput), eventId });\n break;\n case \"touchpoint\":\n mira.touchpoint({ ...(input as TouchpointInput), eventId });\n break;\n default:\n errors.push(`MIRA FIVE: unknown method: ${String(method)}`);\n }\n if (errors.length > before) invalid += 1;\n }\n\n await mira.shutdown();\n const failed = invalid + failedIds.size;\n return { sent: Math.max(0, events.length - failed), failed, errors };\n }\n}\n"
5
+ "/**\n * `@mirafive/convex`: MIRA FIVE events from Convex mutations and actions.\n *\n * Mutations are transactional and cannot use the network, so an event is scheduled with\n * `ctx.scheduler` in the same transaction and delivered by an internal action right after it\n * commits. A mutation that rolls back sends nothing, so an order that never happened is never\n * counted. No dependency on `convex`; it runs in Convex's default runtime (no `\"use node\"`).\n *\n * ```ts\n * // convex/mira.ts\n * import { MiraConvex } from \"@mirafive/convex\";\n * import { v } from \"convex/values\";\n * import { internal } from \"./_generated/api\";\n * import { internalAction } from \"./_generated/server\";\n *\n * // The `: MiraConvex` annotation is required: it breaks the type cycle through `internal`.\n * export const mira: MiraConvex = new MiraConvex(internal.mira.deliver);\n *\n * export const deliver = internalAction({\n * args: { events: v.array(v.any()) },\n * handler: (_ctx, { events }) => mira.deliver(events),\n * });\n *\n * // convex/orders.ts, in a mutation\n * await mira.revenue(ctx, { userId, amount: 4900, currency: \"EUR\", dedupeKey: `order:${id}:paid` });\n * ```\n */\nimport {\n eventIdFor,\n Mira,\n MiraError,\n type DealLostInput,\n type DealStageInput,\n type EventMap,\n type GroupInput,\n type IdentifyInput,\n type MiraOptions,\n type RevenueInput,\n type TouchpointInput,\n type TrackInput,\n} from \"@mirafive/node\";\n\nexport { eventIdFor, MiraError } from \"@mirafive/node\";\nexport type {\n DealLostInput,\n DealStageInput,\n EventMap,\n GroupInput,\n IdentifyInput,\n MiraOptions,\n RevenueInput,\n TouchpointInput,\n TrackInput,\n} from \"@mirafive/node\";\n\n/** A stable key (`order:123:paid`) that becomes the event id, so a retried mutation counts once. */\ninterface Dedupe {\n dedupeKey?: string;\n}\n\n/** One event as it travels through `ctx.scheduler`: the method, its input and a dedupe key. */\nexport type MiraEvent =\n | ({ method: \"track\" } & TrackInput & Dedupe)\n | ({ method: \"identify\" } & IdentifyInput & Dedupe)\n | ({ method: \"group\" } & GroupInput & Dedupe)\n | ({ method: \"revenue\" } & RevenueInput & Dedupe)\n | ({ method: \"touchpoint\" } & TouchpointInput & Dedupe)\n | ({ method: \"dealStage\" } & DealStageInput & Dedupe)\n | ({ method: \"dealLost\" } & DealLostInput & Dedupe);\n\n/** The part of a Convex mutation or action context this package uses. */\nexport interface SchedulerCtx {\n scheduler: { runAfter: (delayMs: number, fn: never, args: never) => Promise<unknown> };\n}\n\nexport interface DeliverResult {\n sent: number;\n failed: number;\n errors: string[];\n}\n\n/**\n * Makes an event a Convex value: `Date`s become ISO strings and `undefined` fields disappear,\n * so `ctx.scheduler` accepts it.\n */\nconst toConvexValue = (event: MiraEvent): MiraEvent =>\n JSON.parse(JSON.stringify(event)) as MiraEvent;\n\nexport class MiraConvex<Events extends EventMap = EventMap> {\n /**\n * @param deliverFunction The internal action that calls `mira.deliver(events)`, for example\n * `internal.mira.deliver`.\n * @param options Delivery options. The key defaults to the deployment's `MIRAFIVE_SECRET_KEY`\n * (`npx convex env set MIRAFIVE_SECRET_KEY mira_sk_…`) and the host to `MIRAFIVE_HOST`.\n */\n private readonly deliverFunction: unknown;\n private readonly options: MiraOptions;\n\n constructor(deliverFunction: unknown, options: MiraOptions = {}) {\n this.deliverFunction = deliverFunction;\n this.options = options;\n }\n\n /** A custom event, sent after the current mutation commits. */\n track<Name extends keyof Events & string>(\n ctx: SchedulerCtx,\n input: TrackInput<Events, Name> & Dedupe,\n ): Promise<void> {\n return this.schedule(ctx, [{ method: \"track\", ...(input as TrackInput & Dedupe) }]);\n }\n\n identify(ctx: SchedulerCtx, input: IdentifyInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"identify\", ...input }]);\n }\n\n group(ctx: SchedulerCtx, input: GroupInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"group\", ...input }]);\n }\n\n /** Money for the revenue ledger. Give it a `dedupeKey` or `entryId`, so a retry counts once. */\n revenue(ctx: SchedulerCtx, input: RevenueInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"revenue\", ...input }]);\n }\n\n touchpoint(ctx: SchedulerCtx, input: TouchpointInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"touchpoint\", ...input }]);\n }\n\n /**\n * A deal of the pipeline reached a stage, sent after the mutation that moved it commits.\n * A stable `dedupeKey` (`case:${id}:stage:${stage}`) keeps a retried mutation from counting twice.\n */\n dealStage(ctx: SchedulerCtx, input: DealStageInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"dealStage\", ...input }]);\n }\n\n /** A deal was lost, sent after the mutation commits. */\n dealLost(ctx: SchedulerCtx, input: DealLostInput & Dedupe): Promise<void> {\n return this.schedule(ctx, [{ method: \"dealLost\", ...input }]);\n }\n\n /** Several events in one scheduled delivery. */\n async schedule(ctx: SchedulerCtx, events: MiraEvent[]): Promise<void> {\n if (!events.length) return;\n try {\n await ctx.scheduler.runAfter(\n 0,\n this.deliverFunction as never,\n {\n events: events.map(toConvexValue),\n } as never,\n );\n } catch (error) {\n // Analytics must never fail the mutation that records the real fact.\n this.options.onError?.(\n new MiraError(\"dropped\", \"could not schedule delivery\", { cause: error }),\n );\n }\n }\n\n /**\n * Sends events now and waits for delivery. The internal action's handler calls it; never call\n * it from a mutation or query (they cannot use the network). Never throws: a MIRA FIVE outage\n * must not fail your action. Problems are in `errors`.\n */\n async deliver(events: MiraEvent[]): Promise<DeliverResult> {\n const errors: string[] = [];\n const failedIds = new Set<string>();\n let invalid = 0;\n\n const mira = new Mira({\n // Actions have a time limit; fewer retries keep them short.\n maxRetries: 3,\n ...this.options,\n flushAt: 100,\n onError: (error: MiraError) => {\n errors.push(error.message);\n for (const id of error.eventIds) failedIds.add(id);\n this.options.onError?.(error);\n },\n });\n if (errors.length) return { sent: 0, failed: events.length, errors };\n\n for (const item of events) {\n const before = errors.length;\n const eventId =\n item.eventId ?? (item.dedupeKey ? await eventIdFor(item.dedupeKey) : undefined);\n const { method, dedupeKey: _, ...input } = item as MiraEvent & { method: unknown };\n switch (method) {\n case \"track\":\n mira.track({ ...(input as TrackInput), eventId });\n break;\n case \"identify\":\n mira.identify({ ...(input as IdentifyInput), eventId });\n break;\n case \"group\":\n mira.group({ ...(input as GroupInput), eventId });\n break;\n case \"revenue\":\n mira.revenue({ ...(input as RevenueInput), eventId });\n break;\n case \"touchpoint\":\n mira.touchpoint({ ...(input as TouchpointInput), eventId });\n break;\n case \"dealStage\":\n mira.dealStage({ ...(input as DealStageInput), eventId });\n break;\n case \"dealLost\":\n mira.dealLost({ ...(input as DealLostInput), eventId });\n break;\n default:\n errors.push(`MIRA FIVE: unknown method: ${String(method)}`);\n }\n if (errors.length > before) invalid += 1;\n }\n\n await mira.shutdown();\n const failed = invalid + failedIds.size;\n return { sent: Math.max(0, events.length - failed), failed, errors };\n }\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "21BF33B329BC4D5064756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "059D2928FA511C6164756E2164756E21",
9
9
  "names": []
10
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mirafive/convex",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "MIRA FIVE for Convex: track events and revenue from mutations; they are delivered by an internal action only after the transaction commits. No dependency on convex.",
5
5
  "keywords": [
6
6
  "analytics",
@@ -48,10 +48,10 @@
48
48
  "typecheck": "bun check"
49
49
  },
50
50
  "dependencies": {
51
- "@mirafive/node": "^2.0.0"
51
+ "@mirafive/node": "^2.1.0"
52
52
  },
53
53
  "devDependencies": {
54
- "@mirafive/protocol": "^2.0.0",
54
+ "@mirafive/protocol": "^2.1.0",
55
55
  "@types/bun": "^1.4.4",
56
56
  "oxfmt": "^0.77.0",
57
57
  "oxlint": "^1.92.0",