make-mp-data 1.4.4 → 1.5.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/tsconfig.json CHANGED
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "include": [
13
13
  "**/*.js"
14
- , "soupTemplates.mjs", "tests/testSoup.mjs", "tests/testCases.mjs" ],
14
+ , "soupTemplates.mjs", "tests/testSoup.mjs", "tests/testCases.mjs", "tests/benchmark/concurrency.mjs" ],
15
15
  "exclude": [
16
16
  "node_modules"
17
17
  ]
package/types.d.ts CHANGED
@@ -1,33 +1,53 @@
1
1
  declare namespace main {
2
+ /**
3
+ * most of the time, the value of a property is a primitive
4
+ */
2
5
  type Primitives = string | number | boolean | Date | Record<string, any>;
3
6
 
4
- // Recursive type to handle functions returning functions that eventually return Primitives or arrays of Primitives
7
+ /**
8
+ * a "validValue" can be a primitive, an array of primitives, or a function that returns a primitive
9
+ */
5
10
  export type ValueValid = Primitives | ValueValid[] | (() => ValueValid);
6
11
 
7
- // MAIN CONFIGURATION OBJECT
12
+ /**
13
+ * main config object for the entire data generation
14
+ */
8
15
  export interface Config {
16
+ // constants
9
17
  token?: string;
10
18
  seed?: string;
11
19
  numDays?: number;
12
20
  epochStart?: number;
13
21
  epochEnd?: number;
14
22
  numEvents?: number;
15
- numUsers?: number;
16
-
17
- //switches
18
- isAnonymous?: boolean;
19
- hasLocation?: boolean;
20
- hasCampaigns?: boolean;
21
- hasAdSpend?: boolean;
22
- hasIOSDevices?: boolean;
23
- hasAndroidDevices?: boolean;
24
- hasDesktopDevices?: boolean;
25
- hasBrowser?: boolean;
26
-
27
-
28
- format?: "csv" | "json";
23
+ numUsers?: number;
24
+ format?: "csv" | "json" | string;
29
25
  region?: "US" | "EU";
30
- events?: EventConfig[]; //can also be a array of strings
26
+ concurrency?: number;
27
+ batchSize?: number;
28
+
29
+ // ids
30
+ simulationName?: string;
31
+ name?: string;
32
+
33
+ //switches
34
+ isAnonymous?: boolean;
35
+ hasAvatar?: boolean;
36
+ hasLocation?: boolean;
37
+ hasCampaigns?: boolean;
38
+ hasAdSpend?: boolean;
39
+ hasIOSDevices?: boolean;
40
+ hasAndroidDevices?: boolean;
41
+ hasDesktopDevices?: boolean;
42
+ hasBrowser?: boolean;
43
+ writeToDisk?: boolean | string;
44
+ verbose?: boolean;
45
+ hasAnonIds?: boolean;
46
+ hasSessionIds?: boolean;
47
+ makeChart?: boolean | string;
48
+
49
+ //models
50
+ events?: EventConfig[]; //| string[]; //can also be a array of strings
31
51
  superProps?: Record<string, ValueValid>;
32
52
  funnels?: Funnel[];
33
53
  userProps?: Record<string, ValueValid>;
@@ -35,23 +55,26 @@ declare namespace main {
35
55
  mirrorProps?: Record<string, MirrorProps>;
36
56
  groupKeys?: [string, number][] | [string, number, string[]][]; // [key, numGroups, [events]]
37
57
  groupProps?: Record<string, Record<string, ValueValid>>;
38
- lookupTables?: LookupTable[];
39
- writeToDisk?: boolean;
40
- simulationName?: string;
41
- verbose?: boolean;
42
- anonIds?: boolean;
43
- sessionIds?: boolean;
44
- makeChart?: boolean | string;
58
+ lookupTables?: LookupTableSchema[];
45
59
  soup?: soup;
46
60
  hook?: Hook<any>;
61
+
62
+ //allow anything to be on the config
63
+ [key: string]: any;
47
64
  }
48
65
 
66
+ /**
67
+ * the soup is a set of parameters that determine the distribution of events over time
68
+ */
49
69
  type soup = {
50
70
  deviation?: number;
51
71
  peaks?: number;
52
72
  mean?: number;
53
73
  };
54
74
 
75
+ /**
76
+ * the types of hooks that can be used
77
+ */
55
78
  type hookTypes =
56
79
  | "event"
57
80
  | "user"
@@ -61,139 +84,236 @@ declare namespace main {
61
84
  | "mirror"
62
85
  | "funnel-pre"
63
86
  | "funnel-post"
64
- | "ad-spend"
65
- | "churn"
87
+ | "ad-spend"
88
+ | "churn"
66
89
  | "";
90
+
91
+ /**
92
+ * a hook is a function that can be called before each entity is created, and can be used to modify attributes
93
+ */
67
94
  export type Hook<T> = (record: any, type: hookTypes, meta: any) => T;
68
95
 
69
- export interface EnrichArrayOptions<T> {
96
+ export interface hookArrayOptions<T> {
70
97
  hook?: Hook<T>;
71
98
  type?: hookTypes;
99
+ filename?: string;
100
+ format?: "csv" | "json" | string;
101
+ concurrency?: number;
102
+ [key: string]: any;
103
+ }
104
+
105
+ /**
106
+ * an enriched array is an array that has a hookPush method that can be used to transform-then-push items into the array
107
+ */
108
+ export interface HookedArray<T> extends Array<T> {
109
+ hookPush: (item: T | T[]) => any;
110
+ flush: () => void;
111
+ getWriteDir: () => string;
112
+ getWritePath: () => string;
72
113
  [key: string]: any;
73
114
  }
74
115
 
75
- export interface EnrichedArray<T> extends Array<T> {
76
- hookPush: (item: T) => boolean;
116
+ export type AllData =
117
+ | HookedArray<EventSchema>
118
+ | HookedArray<UserProfile>
119
+ | HookedArray<GroupProfileSchema>
120
+ | HookedArray<LookupTableSchema>
121
+ | HookedArray<SCDSchema>
122
+ | any[];
123
+
124
+ /**
125
+ * the storage object is a key-value store that holds arrays of data
126
+ */
127
+ export interface Storage {
128
+ eventData?: HookedArray<EventSchema>;
129
+ mirrorEventData?: HookedArray<EventSchema>;
130
+ userProfilesData?: HookedArray<UserProfile>;
131
+ adSpendData?: HookedArray<EventSchema>;
132
+ groupProfilesData?: HookedArray<GroupProfileSchema>[];
133
+ lookupTableData?: HookedArray<LookupTableSchema>[];
134
+ scdTableData?: HookedArray<SCDSchema>[];
77
135
  }
78
136
 
137
+ /**
138
+ * how we define events and their properties
139
+ */
79
140
  export interface EventConfig {
80
141
  event?: string;
81
142
  weight?: number;
82
143
  properties?: Record<string, ValueValid>;
83
144
  isFirstEvent?: boolean;
145
+ isChurnEvent?: boolean;
84
146
  relativeTimeMs?: number;
85
147
  }
86
148
 
87
- export interface EventSpec {
88
- event: string;
89
- time: string;
90
- insert_id: string;
91
- device_id?: string;
92
- session_id?: string;
93
- user_id?: string;
94
- [key: string]: ValueValid;
149
+ /**
150
+ * the generated event data
151
+ */
152
+ export interface EventSchema {
153
+ event: string;
154
+ time: string;
155
+ source: string;
156
+ insert_id: string;
157
+ device_id?: string;
158
+ session_id?: string;
159
+ user_id?: string;
160
+ [key: string]: ValueValid;
95
161
  }
96
162
 
163
+ /**
164
+ * how we define funnels and their properties
165
+ */
97
166
  export interface Funnel {
167
+ /**
168
+ * the sequence of events that define the funnel
169
+ */
98
170
  sequence: string[];
171
+ /**
172
+ * how likely the funnel is to be selected
173
+ */
99
174
  weight?: number;
175
+ /**
176
+ * If true, the funnel will be the first thing the user does
177
+ */
100
178
  isFirstFunnel?: boolean;
101
- /**
102
- * If true, the funnel will require the user to repeat the sequence of events in order to convert
103
- * If false, the user does not need to repeat the sequence of events in order to convert
104
- * ^ when false, users who repeat the repetitive steps are more likely to convert
105
- */
106
- requireRepeats?: boolean;
179
+ /**
180
+ * If true, the funnel will require the user to repeat the sequence of events in order to convert
181
+ * If false, the user does not need to repeat the sequence of events in order to convert
182
+ * ^ when false, users who repeat the repetitive steps are more likely to convert
183
+ */
184
+ requireRepeats?: boolean;
185
+ /**
186
+ * how the events in the funnel are ordered for each user
187
+ */
107
188
  order?:
189
+ | string
108
190
  | "sequential"
109
191
  | "first-fixed"
110
192
  | "last-fixed"
111
- | "random"
193
+ | "random" //totally shuffled
112
194
  | "first-and-last-fixed"
113
195
  | "middle-fixed"
114
- | "interrupted";
196
+ | "interrupted";
197
+
198
+ /**
199
+ * todo: implement this
200
+ * if set, the funnel might be the last thing the user does
201
+ * ^ the numerical value is the likelihood that the user will churn
202
+ * todo: allow for users to be resurrected
203
+ */
204
+ isChurnFunnel?: void | number;
205
+ /**
206
+ * the likelihood that a user will convert (0-100%)
207
+ */
115
208
  conversionRate?: number;
209
+ /**
210
+ * the time it takes (on average) to convert in hours
211
+ */
116
212
  timeToConvert?: number;
213
+ /**
214
+ * funnel properties go onto each event in the funnel and are held constant
215
+ */
117
216
  props?: Record<string, ValueValid>;
118
217
  }
119
218
 
219
+ /**
220
+ * mirror props are used to show mutations of event data over time
221
+ * there are different strategies for how to mutate the data
222
+ */
120
223
  export interface MirrorProps {
224
+ /**
225
+ * the event that will be mutated in the new version
226
+ */
121
227
  events?: string[] | "*";
122
- strategy?: "delete" | "append" | "replace" | "fill" | ""
123
- values: ValueValid[];
124
- }
125
-
126
- export interface LookupTable {
127
- key: string;
128
- entries: number;
129
- attributes: Record<string, ValueValid>;
228
+ /**
229
+ * "create" - create this key in the new version; value are chosen
230
+ * "update" - update this key in the new version; values are chosen
231
+ * "fill" - update this key in the new version, but only if the existing key is null or unset
232
+ * "delete" - delete this key in the new version; values are ignored
233
+ */
234
+ strategy?: "create" | "update" | "fill" | "delete" | "";
235
+ values?: ValueValid[];
236
+ /**
237
+ * optional: for 'fill' mode, daysUnfilled will dictate where the cutoff is in the unfilled data
238
+ */
239
+ daysUnfilled?: number;
130
240
  }
131
241
 
132
- export interface SCDTableRow {
242
+ export interface UserProfile {
243
+ name?: string;
244
+ email?: string;
245
+ avatar?: string;
246
+ created: string | undefined;
133
247
  distinct_id: string;
134
- insertTime: string;
135
- startTime: string;
136
248
  [key: string]: ValueValid;
137
249
  }
138
250
 
139
- export type Result = {
140
- eventData: EventData[];
141
- userProfilesData: any[];
142
- scdTableData: any[];
143
- groupProfilesData: GroupProfilesData[];
144
- lookupTableData: LookupTableData[];
145
- importResults?: ImportResults;
146
- files?: string[];
147
- };
251
+ export interface Person {
252
+ name: string;
253
+ email?: string;
254
+ avatar?: string;
255
+ created: string | undefined;
256
+ anonymousIds: string[];
257
+ sessionIds: string[];
258
+ distinct_id?: string;
259
+ }
148
260
 
149
- export interface EventData {
150
- event: string;
151
- source: string;
152
- time: string;
153
- device_id?: string;
154
- session_id?: string;
155
- user_id?: string;
156
- [key: string]: any;
261
+ /**
262
+ * the generated user data
263
+ */
264
+ export interface LookupTableSchema {
265
+ key: string;
266
+ entries: number;
267
+ attributes: Record<string, ValueValid>;
157
268
  }
158
269
 
159
- export interface GroupProfilesData {
270
+ export interface LookupTableData {
160
271
  key: string;
161
272
  data: any[];
162
273
  }
163
274
 
164
- export interface LookupTableData {
275
+ export interface SCDSchema {
276
+ distinct_id: string;
277
+ insertTime: string;
278
+ startTime: string;
279
+ [key: string]: ValueValid;
280
+ }
281
+
282
+ export interface GroupProfileSchema {
165
283
  key: string;
166
284
  data: any[];
167
285
  }
168
286
 
287
+ /**
288
+ * the end result of importing data into mixpanel
289
+ */
169
290
  export interface ImportResults {
170
291
  events: ImportResult;
171
292
  users: ImportResult;
172
293
  groups: ImportResult[];
173
294
  }
295
+ type ImportResult = import("mixpanel-import").ImportResults;
174
296
 
175
- export interface ImportResult {
176
- success: number;
177
- bytes: number;
178
- }
179
- export interface Person {
180
- name: string;
181
- email: string;
182
- avatar: string;
183
- created: string | undefined;
184
- anonymousIds: string[];
185
- sessionIds: string[];
186
- distinct_id?: string;
187
- }
188
-
189
- export interface UserProfile {
190
- name?: string;
191
- email?: string;
192
- avatar?: string;
193
- created: string | undefined;
194
- distinct_id: string;
195
- [key: string]: ValueValid;
196
- }
297
+ /**
298
+ * the end result of the data generation
299
+ */
300
+ export type Result = {
301
+ eventData: EventSchema[];
302
+ mirrorEventData: EventSchema[];
303
+ userProfilesData: any[];
304
+ scdTableData: any[];
305
+ adSpendData: EventSchema[];
306
+ groupProfilesData: GroupProfileSchema[];
307
+ lookupTableData: LookupTableData[];
308
+ importResults?: ImportResults;
309
+ files?: string[];
310
+ time?: {
311
+ start: number;
312
+ end: number;
313
+ delta: number;
314
+ human: string;
315
+ };
316
+ };
197
317
  }
198
318
 
199
319
  /**