@lssm/lib.analytics 0.0.0-canary-20251206160926
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 +10 -0
- package/dist/churn/index.d.ts +2 -0
- package/dist/churn/index.js +1 -0
- package/dist/churn/predictor.d.ts +21 -0
- package/dist/churn/predictor.js +1 -0
- package/dist/cohort/index.d.ts +2 -0
- package/dist/cohort/index.js +1 -0
- package/dist/cohort/tracker.d.ts +8 -0
- package/dist/cohort/tracker.js +1 -0
- package/dist/funnel/analyzer.d.ts +9 -0
- package/dist/funnel/analyzer.js +1 -0
- package/dist/funnel/index.d.ts +2 -0
- package/dist/funnel/index.js +1 -0
- package/dist/growth/hypothesis-generator.d.ts +17 -0
- package/dist/growth/hypothesis-generator.js +1 -0
- package/dist/growth/index.d.ts +2 -0
- package/dist/growth/index.js +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +1 -0
- package/dist/lifecycle/index.d.ts +3 -0
- package/dist/lifecycle/index.js +1 -0
- package/dist/lifecycle/metric-collectors.d.ts +29 -0
- package/dist/lifecycle/metric-collectors.js +1 -0
- package/dist/lifecycle/posthog-bridge.d.ts +14 -0
- package/dist/lifecycle/posthog-bridge.js +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.js +0 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# @lssm/lib.analytics
|
|
2
|
+
|
|
3
|
+
Zero-dependency analytics toolkit used by Phase 2 AI-Native Ops. It ingests telemetry events and outputs:
|
|
4
|
+
|
|
5
|
+
- Funnel conversion reports with drop-off detection.
|
|
6
|
+
- Cohort retention curves and LTV summaries.
|
|
7
|
+
- Churn predictors that flag risky accounts.
|
|
8
|
+
- Growth hypothesis generator that suggests experiments.
|
|
9
|
+
|
|
10
|
+
All utilities operate on plain JSON events so they can run in jobs, background workers, or MCP agents without a warehouse.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ChurnPredictor as e}from"./predictor.js";export{e as ChurnPredictor};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AnalyticsEvent, ChurnSignal } from "../types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/churn/predictor.d.ts
|
|
4
|
+
interface ChurnPredictorOptions {
|
|
5
|
+
recencyWeight?: number;
|
|
6
|
+
frequencyWeight?: number;
|
|
7
|
+
errorWeight?: number;
|
|
8
|
+
decayDays?: number;
|
|
9
|
+
}
|
|
10
|
+
declare class ChurnPredictor {
|
|
11
|
+
private readonly recencyWeight;
|
|
12
|
+
private readonly frequencyWeight;
|
|
13
|
+
private readonly errorWeight;
|
|
14
|
+
private readonly decayDays;
|
|
15
|
+
constructor(options?: ChurnPredictorOptions);
|
|
16
|
+
score(events: AnalyticsEvent[]): ChurnSignal[];
|
|
17
|
+
private computeScore;
|
|
18
|
+
private drivers;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { ChurnPredictor, ChurnPredictorOptions };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"dayjs";var t=class{recencyWeight;frequencyWeight;errorWeight;decayDays;constructor(e){this.recencyWeight=e?.recencyWeight??.5,this.frequencyWeight=e?.frequencyWeight??.3,this.errorWeight=e?.errorWeight??.2,this.decayDays=e?.decayDays??14}score(e){let t=n(e,e=>e.userId),r=[];for(let[e,n]of t.entries()){let t=this.computeScore(n);r.push({userId:e,score:t,bucket:t>=.7?`high`:t>=.4?`medium`:`low`,drivers:this.drivers(n)})}return r.sort((e,t)=>t.score-e.score)}computeScore(t){if(!t.length)return 0;let n=t.sort((e,t)=>r(e)-r(t)),i=n[n.length-1];if(!i)return 0;let a=e().diff(e(i.timestamp),`day`),o=Math.max(0,1-a/this.decayDays),s=e().subtract(this.decayDays,`day`),c=n.filter(t=>e(t.timestamp).isAfter(s)),l=c.length/Math.max(this.decayDays,1),u=Math.min(1,l*5),d=c.filter(e=>e.properties?.error!==void 0||/error|failed/i.test(e.name)).length,f=Math.min(1,d/3),p=o*this.recencyWeight+u*this.frequencyWeight+(1-f)*this.errorWeight;return Number(p.toFixed(3))}drivers(t){let n=[],i=t.sort((e,t)=>r(e)-r(t)),a=i[i.length-1];if(a){let t=e().diff(e(a.timestamp),`day`);t>this.decayDays&&n.push(`Inactive for ${t} days`)}let o=t.filter(e=>e.properties?.error!==void 0||/error|failed/i.test(e.name));return o.length&&n.push(`${o.length} errors logged`),n}};function n(e,t){let n=new Map;for(let r of e){let e=t(r),i=n.get(e)??[];i.push(r),n.set(e,i)}return n}function r(e){return new Date(e.timestamp).getTime()}export{t as ChurnPredictor};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{CohortTracker as e}from"./tracker.js";export{e as CohortTracker};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnalyticsEvent, CohortAnalysis, CohortDefinition } from "../types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/cohort/tracker.d.ts
|
|
4
|
+
declare class CohortTracker {
|
|
5
|
+
analyze(events: AnalyticsEvent[], definition: CohortDefinition): CohortAnalysis;
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { CohortTracker };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"dayjs";var t=class{analyze(e,t){let a=r(e,e=>e.userId),o=new Map;for(let[e,r]of a.entries()){r.sort((e,t)=>s(e)-s(t));let a=r[0];if(!a)continue;let c=i(a.timestamp,t.bucket),l=o.get(c)??new n(c,t);l.addUser(e);for(let t of r)l.addEvent(e,t);o.set(c,l)}return{definition:t,cohorts:[...o.values()].map(e=>e.build())}}},n=class{users=new Set;retentionMap=new Map;ltv=0;constructor(e,t){this.key=e,this.definition=t}addUser(e){this.users.add(e)}addEvent(e,t){let n=a(this.key,t.timestamp,this.definition.bucket);if(n<0||n>=this.definition.periods)return;let r=this.retentionMap.get(n)??new Set;r.add(e),this.retentionMap.set(n,r);let i=typeof t.properties?.amount==`number`?t.properties.amount:0;this.ltv+=i}build(){let e=this.users.size||1,t=[];for(let n=0;n<this.definition.periods;n++){let r=this.retentionMap.get(n)?.size??0;t.push(Number((r/e).toFixed(3)))}return{cohortKey:this.key,users:this.users.size,retention:t,ltv:Number(this.ltv.toFixed(2))}}};function r(e,t){let n=new Map;for(let r of e){let e=t(r),i=n.get(e)??[];i.push(r),n.set(e,i)}return n}function i(t,n){let r=e(t);switch(n){case`day`:return r.startOf(`day`).format(`YYYY-MM-DD`);case`week`:return r.startOf(`week`).format(`YYYY-[W]WW`);case`month`:default:return r.startOf(`month`).format(`YYYY-MM`)}}function a(t,n,r){let i=o(t,r),a=e(n);switch(r){case`day`:return a.diff(i,`day`);case`week`:return a.diff(i,`week`);case`month`:default:return a.diff(i,`month`)}}function o(t,n){switch(n){case`day`:return e(t,`YYYY-MM-DD`);case`week`:return e(t.replace(`W`,``),`YYYY-ww`);case`month`:default:return e(t,`YYYY-MM`)}}function s(e){return new Date(e.timestamp).getTime()}export{t as CohortTracker};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AnalyticsEvent, FunnelAnalysis, FunnelDefinition } from "../types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/funnel/analyzer.d.ts
|
|
4
|
+
declare class FunnelAnalyzer {
|
|
5
|
+
analyze(events: AnalyticsEvent[], definition: FunnelDefinition): FunnelAnalysis;
|
|
6
|
+
private evaluateUser;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { FunnelAnalyzer };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=class{analyze(e,n){let r=(n.windowHours??72)*60*60*1e3,i=t(e),a=n.steps.map(()=>0);for(let e of i.values())this.evaluateUser(e,n.steps,r).forEach((e,t)=>{e&&(a[t]=(a[t]??0)+1)});let o=i.size;return{definition:n,totalUsers:o,steps:n.steps.map((e,t)=>{let n=t===0?o:a[t-1]||1,r=a[t]??0,i=n===0?0:Number((r/n).toFixed(3));return{step:e,count:r,conversionRate:i,dropOffRate:Number((1-i).toFixed(3))}})}}evaluateUser(e,t,n){let r=[...e].sort((e,t)=>new Date(e.timestamp).getTime()-new Date(t.timestamp).getTime()),i=Array(t.length).fill(!1),a=0,o;for(let e of r){let r=t[a];if(!r)break;if(e.name!==r.eventName||r.match&&!r.match(e))continue;let s=new Date(e.timestamp).getTime();if(a===0){o=s,i[a]=!0,a+=1;continue}o&&s-o<=n&&(i[a]=!0,a+=1)}return i}};function t(e){let t=new Map;for(let n of e){let e=t.get(n.userId)??[];e.push(n),t.set(n.userId,e)}return t}export{e as FunnelAnalyzer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{FunnelAnalyzer as e}from"./analyzer.js";export{e as FunnelAnalyzer};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { GrowthHypothesis, GrowthMetric } from "../types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/growth/hypothesis-generator.d.ts
|
|
4
|
+
interface HypothesisGeneratorOptions {
|
|
5
|
+
minDelta?: number;
|
|
6
|
+
}
|
|
7
|
+
declare class GrowthHypothesisGenerator {
|
|
8
|
+
private readonly minDelta;
|
|
9
|
+
constructor(options?: HypothesisGeneratorOptions);
|
|
10
|
+
generate(metrics: GrowthMetric[]): GrowthHypothesis[];
|
|
11
|
+
private fromMetric;
|
|
12
|
+
private delta;
|
|
13
|
+
private impact;
|
|
14
|
+
private statement;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { GrowthHypothesisGenerator, HypothesisGeneratorOptions };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=class{minDelta;constructor(e){this.minDelta=e?.minDelta??.05}generate(e){return e.map(e=>this.fromMetric(e)).filter(e=>!!e)}fromMetric(e){let t=this.delta(e);if(Math.abs(t)<this.minDelta)return null;let n=t>0?`rising`:`declining`;return{statement:this.statement(e,t,n),metric:e.name,confidence:Math.abs(t)>.2?`high`:`medium`,impact:this.impact(e)}}delta(e){if(e.previous==null)return 0;let t=e.previous||1;return(e.current-t)/Math.abs(t)}impact(e){return e.target&&e.current<e.target*.8?`high`:e.target&&e.current<e.target?`medium`:`low`}statement(e,t,n){let r=Math.abs(parseFloat((t*100).toFixed(1)));return n===`declining`?`${e.name} is down ${r}% vs last period; test new onboarding prompts to recover activation.`:`${e.name} grew ${r}% period-over-period; double down with expanded experiment or pricing test.`}};export{e as GrowthHypothesisGenerator};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{GrowthHypothesisGenerator as e}from"./hypothesis-generator.js";export{e as GrowthHypothesisGenerator};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnalyticsEvent, ChurnSignal, CohortAnalysis, CohortDefinition, CohortEvent, CohortStats, FunnelAnalysis, FunnelDefinition, FunnelStep, FunnelStepResult, GrowthHypothesis, GrowthMetric } from "./types.js";
|
|
2
|
+
import { ChurnPredictor, ChurnPredictorOptions } from "./churn/predictor.js";
|
|
3
|
+
import { CohortTracker } from "./cohort/tracker.js";
|
|
4
|
+
import { FunnelAnalyzer } from "./funnel/analyzer.js";
|
|
5
|
+
import { GrowthHypothesisGenerator, HypothesisGeneratorOptions } from "./growth/hypothesis-generator.js";
|
|
6
|
+
import { LifecycleMetricSource, LifecycleStageChangePayload, collectLifecycleMetrics, createStageChangeEvent, lifecycleEventNames, metricsToSignals } from "./lifecycle/metric-collectors.js";
|
|
7
|
+
import { PostHogLikeClient, trackLifecycleAssessment, trackLifecycleStageChange } from "./lifecycle/posthog-bridge.js";
|
|
8
|
+
export { AnalyticsEvent, ChurnPredictor, ChurnPredictorOptions, ChurnSignal, CohortAnalysis, CohortDefinition, CohortEvent, CohortStats, CohortTracker, FunnelAnalysis, FunnelAnalyzer, FunnelDefinition, FunnelStep, FunnelStepResult, GrowthHypothesis, GrowthHypothesisGenerator, GrowthMetric, HypothesisGeneratorOptions, LifecycleMetricSource, LifecycleStageChangePayload, PostHogLikeClient, collectLifecycleMetrics, createStageChangeEvent, lifecycleEventNames, metricsToSignals, trackLifecycleAssessment, trackLifecycleStageChange };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{FunnelAnalyzer as e}from"./funnel/analyzer.js";import{CohortTracker as t}from"./cohort/tracker.js";import"./cohort/index.js";import{ChurnPredictor as n}from"./churn/predictor.js";import"./churn/index.js";import{GrowthHypothesisGenerator as r}from"./growth/hypothesis-generator.js";import{collectLifecycleMetrics as i,createStageChangeEvent as a,lifecycleEventNames as o,metricsToSignals as s}from"./lifecycle/metric-collectors.js";import{trackLifecycleAssessment as c,trackLifecycleStageChange as l}from"./lifecycle/posthog-bridge.js";export{n as ChurnPredictor,t as CohortTracker,e as FunnelAnalyzer,r as GrowthHypothesisGenerator,i as collectLifecycleMetrics,a as createStageChangeEvent,o as lifecycleEventNames,s as metricsToSignals,c as trackLifecycleAssessment,l as trackLifecycleStageChange};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { LifecycleMetricSource, LifecycleStageChangePayload, collectLifecycleMetrics, createStageChangeEvent, lifecycleEventNames, metricsToSignals } from "./metric-collectors.js";
|
|
2
|
+
import { PostHogLikeClient, trackLifecycleAssessment, trackLifecycleStageChange } from "./posthog-bridge.js";
|
|
3
|
+
export { LifecycleMetricSource, LifecycleStageChangePayload, PostHogLikeClient, collectLifecycleMetrics, createStageChangeEvent, lifecycleEventNames, metricsToSignals, trackLifecycleAssessment, trackLifecycleStageChange };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{collectLifecycleMetrics as e,createStageChangeEvent as t,lifecycleEventNames as n,metricsToSignals as r}from"./metric-collectors.js";import{trackLifecycleAssessment as i,trackLifecycleStageChange as a}from"./posthog-bridge.js";export{e as collectLifecycleMetrics,t as createStageChangeEvent,n as lifecycleEventNames,r as metricsToSignals,i as trackLifecycleAssessment,a as trackLifecycleStageChange};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnalyticsEvent } from "../types.js";
|
|
2
|
+
import { LifecycleMetricSnapshot, LifecycleSignal, LifecycleStage } from "@lssm/lib.lifecycle";
|
|
3
|
+
|
|
4
|
+
//#region src/lifecycle/metric-collectors.d.ts
|
|
5
|
+
interface LifecycleMetricSource {
|
|
6
|
+
getActiveUsers(): Promise<number | undefined>;
|
|
7
|
+
getWeeklyActiveUsers?(): Promise<number | undefined>;
|
|
8
|
+
getRetentionRate?(): Promise<number | undefined>;
|
|
9
|
+
getMonthlyRecurringRevenue?(): Promise<number | undefined>;
|
|
10
|
+
getCustomerCount?(): Promise<number | undefined>;
|
|
11
|
+
getTeamSize?(): Promise<number | undefined>;
|
|
12
|
+
getBurnMultiple?(): Promise<number | undefined>;
|
|
13
|
+
}
|
|
14
|
+
declare const collectLifecycleMetrics: (source: LifecycleMetricSource) => Promise<LifecycleMetricSnapshot>;
|
|
15
|
+
declare const metricsToSignals: (metrics: LifecycleMetricSnapshot, tenantId?: string) => LifecycleSignal[];
|
|
16
|
+
declare const lifecycleEventNames: {
|
|
17
|
+
readonly assessmentRun: "lifecycle_assessment_run";
|
|
18
|
+
readonly stageChanged: "lifecycle_stage_changed";
|
|
19
|
+
readonly guidanceConsumed: "lifecycle_guidance_consumed";
|
|
20
|
+
};
|
|
21
|
+
interface LifecycleStageChangePayload {
|
|
22
|
+
tenantId?: string;
|
|
23
|
+
previousStage?: LifecycleStage;
|
|
24
|
+
nextStage: LifecycleStage;
|
|
25
|
+
confidence: number;
|
|
26
|
+
}
|
|
27
|
+
declare const createStageChangeEvent: (payload: LifecycleStageChangePayload) => AnalyticsEvent;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { LifecycleMetricSource, LifecycleStageChangePayload, collectLifecycleMetrics, createStageChangeEvent, lifecycleEventNames, metricsToSignals };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=async e=>{let[t,n,r,i,a,o,s]=await Promise.all([e.getActiveUsers(),e.getWeeklyActiveUsers?.(),e.getRetentionRate?.(),e.getMonthlyRecurringRevenue?.(),e.getCustomerCount?.(),e.getTeamSize?.(),e.getBurnMultiple?.()]);return{activeUsers:t,weeklyActiveUsers:n,retentionRate:r,monthlyRecurringRevenue:i,customerCount:a,teamSize:o,burnMultiple:s}},t=(e,t)=>Object.entries(e).filter(([,e])=>e!=null).map(([e,n])=>({id:`lifecycle-metric:${e}`,kind:`metric`,source:`analytics`,name:e,value:n,weight:1,confidence:.8,details:t?{tenantId:t}:void 0,capturedAt:new Date().toISOString()})),n={assessmentRun:`lifecycle_assessment_run`,stageChanged:`lifecycle_stage_changed`,guidanceConsumed:`lifecycle_guidance_consumed`},r=e=>({name:n.stageChanged,userId:`system`,tenantId:e.tenantId,timestamp:new Date,properties:{...e}});export{e as collectLifecycleMetrics,r as createStageChangeEvent,n as lifecycleEventNames,t as metricsToSignals};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { LifecycleAssessment } from "@lssm/lib.lifecycle";
|
|
2
|
+
|
|
3
|
+
//#region src/lifecycle/posthog-bridge.d.ts
|
|
4
|
+
interface PostHogLikeClient {
|
|
5
|
+
capture: (event: {
|
|
6
|
+
distinctId: string;
|
|
7
|
+
event: string;
|
|
8
|
+
properties?: Record<string, unknown>;
|
|
9
|
+
}) => Promise<void> | void;
|
|
10
|
+
}
|
|
11
|
+
declare const trackLifecycleAssessment: (client: PostHogLikeClient, tenantId: string, assessment: LifecycleAssessment) => Promise<void>;
|
|
12
|
+
declare const trackLifecycleStageChange: (client: PostHogLikeClient, tenantId: string, previousStage: number | undefined, nextStage: number) => Promise<void>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { PostHogLikeClient, trackLifecycleAssessment, trackLifecycleStageChange };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{lifecycleEventNames as e}from"./metric-collectors.js";const t=async(t,n,r)=>{await t.capture({distinctId:n,event:e.assessmentRun,properties:{stage:r.stage,confidence:r.confidence,axes:r.axes}})},n=async(t,n,r,i)=>{await t.capture({distinctId:n,event:e.stageChanged,properties:{previousStage:r,nextStage:i}})};export{t as trackLifecycleAssessment,n as trackLifecycleStageChange};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
interface AnalyticsEvent {
|
|
3
|
+
name: string;
|
|
4
|
+
userId: string;
|
|
5
|
+
tenantId?: string;
|
|
6
|
+
timestamp: string | Date;
|
|
7
|
+
properties?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
interface FunnelStep {
|
|
10
|
+
id: string;
|
|
11
|
+
eventName: string;
|
|
12
|
+
match?: (event: AnalyticsEvent) => boolean;
|
|
13
|
+
}
|
|
14
|
+
interface FunnelDefinition {
|
|
15
|
+
name: string;
|
|
16
|
+
steps: FunnelStep[];
|
|
17
|
+
windowHours?: number;
|
|
18
|
+
}
|
|
19
|
+
interface FunnelStepResult {
|
|
20
|
+
step: FunnelStep;
|
|
21
|
+
count: number;
|
|
22
|
+
conversionRate: number;
|
|
23
|
+
dropOffRate: number;
|
|
24
|
+
}
|
|
25
|
+
interface FunnelAnalysis {
|
|
26
|
+
definition: FunnelDefinition;
|
|
27
|
+
totalUsers: number;
|
|
28
|
+
steps: FunnelStepResult[];
|
|
29
|
+
}
|
|
30
|
+
interface CohortEvent extends AnalyticsEvent {
|
|
31
|
+
amount?: number;
|
|
32
|
+
}
|
|
33
|
+
interface CohortDefinition {
|
|
34
|
+
bucket: 'day' | 'week' | 'month';
|
|
35
|
+
periods: number;
|
|
36
|
+
startDate?: Date;
|
|
37
|
+
}
|
|
38
|
+
interface CohortStats {
|
|
39
|
+
cohortKey: string;
|
|
40
|
+
users: number;
|
|
41
|
+
retention: number[];
|
|
42
|
+
ltv: number;
|
|
43
|
+
}
|
|
44
|
+
interface CohortAnalysis {
|
|
45
|
+
definition: CohortDefinition;
|
|
46
|
+
cohorts: CohortStats[];
|
|
47
|
+
}
|
|
48
|
+
interface ChurnSignal {
|
|
49
|
+
userId: string;
|
|
50
|
+
score: number;
|
|
51
|
+
bucket: 'low' | 'medium' | 'high';
|
|
52
|
+
drivers: string[];
|
|
53
|
+
}
|
|
54
|
+
interface GrowthMetric {
|
|
55
|
+
name: string;
|
|
56
|
+
current: number;
|
|
57
|
+
previous?: number;
|
|
58
|
+
target?: number;
|
|
59
|
+
}
|
|
60
|
+
interface GrowthHypothesis {
|
|
61
|
+
statement: string;
|
|
62
|
+
metric: string;
|
|
63
|
+
confidence: 'low' | 'medium' | 'high';
|
|
64
|
+
impact: 'low' | 'medium' | 'high';
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { AnalyticsEvent, ChurnSignal, CohortAnalysis, CohortDefinition, CohortEvent, CohortStats, FunnelAnalysis, FunnelDefinition, FunnelStep, FunnelStepResult, GrowthHypothesis, GrowthMetric };
|
package/dist/types.js
ADDED
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lssm/lib.analytics",
|
|
3
|
+
"version": "0.0.0-canary-20251206160926",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
|
|
14
|
+
"build": "bun build:bundle && bun build:types",
|
|
15
|
+
"build:bundle": "tsdown",
|
|
16
|
+
"build:types": "tsc --noEmit",
|
|
17
|
+
"dev": "bun build:bundle --watch",
|
|
18
|
+
"clean": "rimraf dist .turbo",
|
|
19
|
+
"lint": "bun lint:fix",
|
|
20
|
+
"lint:fix": "eslint src --fix",
|
|
21
|
+
"lint:check": "eslint src",
|
|
22
|
+
"test": "bun run"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@lssm/lib.lifecycle": "workspace:*",
|
|
26
|
+
"dayjs": "^1.11.13"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@lssm/tool.tsdown": "workspace:*",
|
|
30
|
+
"@lssm/tool.typescript": "workspace:*",
|
|
31
|
+
"tsdown": "^0.17.0",
|
|
32
|
+
"typescript": "^5.9.3"
|
|
33
|
+
},
|
|
34
|
+
"exports": {
|
|
35
|
+
".": "./dist/index.js",
|
|
36
|
+
"./churn": "./dist/churn/index.js",
|
|
37
|
+
"./churn/predictor": "./dist/churn/predictor.js",
|
|
38
|
+
"./cohort": "./dist/cohort/index.js",
|
|
39
|
+
"./cohort/tracker": "./dist/cohort/tracker.js",
|
|
40
|
+
"./funnel": "./dist/funnel/index.js",
|
|
41
|
+
"./funnel/analyzer": "./dist/funnel/analyzer.js",
|
|
42
|
+
"./growth": "./dist/growth/index.js",
|
|
43
|
+
"./growth/hypothesis-generator": "./dist/growth/hypothesis-generator.js",
|
|
44
|
+
"./lifecycle": "./dist/lifecycle/index.js",
|
|
45
|
+
"./lifecycle/metric-collectors": "./dist/lifecycle/metric-collectors.js",
|
|
46
|
+
"./lifecycle/posthog-bridge": "./dist/lifecycle/posthog-bridge.js",
|
|
47
|
+
"./types": "./dist/types.js",
|
|
48
|
+
"./*": "./*"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
}
|
|
53
|
+
}
|