@hogsend/core 0.13.2 → 0.16.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": "@hogsend/core",
3
- "version": "0.13.2",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -32,7 +32,7 @@
32
32
  "drizzle-orm": "^0.45.2",
33
33
  "iana-db-timezones": "^0.3.0",
34
34
  "zod": "^4.4.3",
35
- "@hogsend/db": "^0.13.2"
35
+ "@hogsend/db": "^0.16.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "latest",
@@ -107,11 +107,29 @@ export interface WaitForEventOptions {
107
107
  timeout: DurationObject;
108
108
  /** Optional observability label written to `currentNodeId` while waiting. */
109
109
  label?: string;
110
+ /**
111
+ * Look BACK this far before waiting forward. The wait is normally
112
+ * forward-looking (only events pushed after it is established match), which
113
+ * leaves a gap: an event landing between two waits — or between a send and
114
+ * its wait — is never seen. With `lookback`, recent `user_events` matching
115
+ * (user, event) are checked first; a hit resolves immediately with
116
+ * `{ timedOut: false, properties }`. Keep the window tight (just the gap it
117
+ * covers, e.g. `hours(1)` between back-to-back waits) so a stale answer
118
+ * isn't mistaken for a fresh one.
119
+ */
120
+ lookback?: DurationObject;
110
121
  }
111
122
 
112
123
  export interface WaitForEventResult {
113
124
  /** `true` when the `timeout` elapsed first; `false` when the event fired. */
114
125
  timedOut: boolean;
126
+ /**
127
+ * The matched event's properties, present (best-effort) when the event
128
+ * branch fired and the pushed payload carried them. Scalars only — that is
129
+ * all the ingest pipeline puts on the wire. Branch on these to react to the
130
+ * answer (e.g. an in-email NPS score) without a separate history lookup.
131
+ */
132
+ properties?: Record<string, string | number | boolean | null>;
115
133
  }
116
134
 
117
135
  export interface JourneyContext {
@@ -1,6 +1,44 @@
1
+ import type { CriteriaBuilder } from "../conditions/builder.js";
1
2
  import type { DurationObject } from "../duration.js";
2
3
  import type { PropertyCondition } from "./conditions.js";
3
4
 
5
+ /**
6
+ * The builder surface available to a journey `where` function — property
7
+ * terminals only. Trigger/exit conditions evaluate against the TRIGGERING
8
+ * event's properties; counts, windows, and engagement belong in bucket
9
+ * criteria or `ctx.history`, not here.
10
+ */
11
+ export type JourneyWhereBuilder = Pick<CriteriaBuilder, "prop">;
12
+
13
+ /**
14
+ * Authoring form of `trigger.where` / `exitOn[].where`: the stored data form
15
+ * (`PropertyCondition[]`), or a builder function resolved ONCE at
16
+ * `defineJourney` time into the byte-identical POJOs —
17
+ * `where: (b) => b.prop("score").lte(6)`. The function never executes
18
+ * per-user, so conditions stay introspectable data everywhere downstream
19
+ * (registry, admin routes, Studio).
20
+ */
21
+ export type JourneyWhere =
22
+ | PropertyCondition[]
23
+ | ((b: JourneyWhereBuilder) => PropertyCondition | PropertyCondition[]);
24
+
25
+ /**
26
+ * What `defineJourney` ACCEPTS. The stored {@link JourneyMeta} (registry,
27
+ * schema, HTTP) keeps plain `PropertyCondition[]` — only the authoring
28
+ * surface widens.
29
+ */
30
+ export interface JourneyMetaInput
31
+ extends Omit<JourneyMeta, "trigger" | "exitOn"> {
32
+ trigger: {
33
+ event: string;
34
+ where?: JourneyWhere;
35
+ };
36
+ exitOn?: Array<{
37
+ event: string;
38
+ where?: JourneyWhere;
39
+ }>;
40
+ }
41
+
4
42
  export interface JourneyMeta {
5
43
  id: string;
6
44
  name: string;