make-mp-data 2.0.19 → 2.0.22
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/dungeons/big.js +7 -6
- package/dungeons/business.js +21 -3
- package/dungeons/experiments.js +8 -7
- package/dungeons/media.js +7 -7
- package/dungeons/sanity.js +8 -14
- package/dungeons/simple.js +1 -0
- package/dungeons/student-teacher.js +426 -0
- package/dungeons/userAgent.js +7 -7
- package/entry.js +19 -3
- package/index.js +107 -7
- package/lib/cli/cli.js +8 -0
- package/lib/core/config-validator.js +244 -218
- package/lib/core/context.js +31 -16
- package/lib/core/storage.js +61 -27
- package/lib/generators/events.js +41 -18
- package/lib/orchestrators/mixpanel-sender.js +5 -2
- package/lib/orchestrators/user-loop.js +212 -181
- package/lib/orchestrators/worker-manager.js +5 -2
- package/lib/templates/abbreviated.d.ts +159 -0
- package/lib/{data → templates}/defaults.js +2 -2
- package/lib/templates/instructions.txt +78 -0
- package/lib/templates/scratch-dungeon-template.js +116 -0
- package/lib/templates/verbose-schema.js +338 -0
- package/lib/utils/ai.js +42 -64
- package/lib/utils/chart.js +5 -0
- package/lib/utils/utils.js +116 -55
- package/package.json +9 -10
- package/types.d.ts +138 -125
- package/lib/cloud-function.js +0 -20
- /package/lib/{utils/prompt.txt → templates/prompt (old).txt} +0 -0
package/types.d.ts
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export interface Dungeon {
|
|
1
|
+
/**
|
|
2
|
+
* most of the time, the value of a property is a primitive
|
|
3
|
+
*/
|
|
4
|
+
type Primitives = string | number | boolean | Date | Record<string, any>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* a "validValue" can be a primitive, an array of primitives, or a function that returns a primitive
|
|
8
|
+
*/
|
|
9
|
+
export type ValueValid = Primitives | ValueValid[] | (() => ValueValid);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* main config object for the entire data generation
|
|
13
|
+
*/
|
|
14
|
+
export interface Dungeon {
|
|
16
15
|
// constants
|
|
17
16
|
token?: string;
|
|
18
17
|
seed?: string;
|
|
@@ -71,29 +70,29 @@ declare namespace main {
|
|
|
71
70
|
|
|
72
71
|
//probabilities
|
|
73
72
|
percentUsersBornInDataset?: number;
|
|
74
|
-
|
|
73
|
+
}
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
export type SCDProp = {
|
|
77
76
|
type?: string | "user" | "company_id" | "team_id" | "department_id";
|
|
78
77
|
frequency: "day" | "week" | "month" | "year";
|
|
79
78
|
values: ValueValid;
|
|
80
79
|
timing: "fixed" | "fuzzy";
|
|
81
80
|
max?: number;
|
|
82
|
-
|
|
81
|
+
};
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
/**
|
|
84
|
+
* the soup is a set of parameters that determine the distribution of events over time
|
|
85
|
+
*/
|
|
86
|
+
type soup = {
|
|
88
87
|
deviation?: number;
|
|
89
88
|
peaks?: number;
|
|
90
89
|
mean?: number;
|
|
91
|
-
|
|
90
|
+
};
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
/**
|
|
93
|
+
* the types of hooks that can be used
|
|
94
|
+
*/
|
|
95
|
+
export type hookTypes =
|
|
97
96
|
| "event"
|
|
98
97
|
| "user"
|
|
99
98
|
| "group"
|
|
@@ -109,32 +108,33 @@ declare namespace main {
|
|
|
109
108
|
| "everything"
|
|
110
109
|
| "";
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
/**
|
|
112
|
+
* a hook is a function that can be called before each entity is created, and can be used to modify attributes
|
|
113
|
+
*/
|
|
114
|
+
export type Hook<T> = (record: any, type: hookTypes, meta: any) => T;
|
|
116
115
|
|
|
117
|
-
|
|
116
|
+
export interface hookArrayOptions<T> {
|
|
118
117
|
hook?: Hook<T>;
|
|
119
118
|
type?: hookTypes;
|
|
120
119
|
filename?: string;
|
|
121
120
|
format?: "csv" | "json" | string;
|
|
122
121
|
concurrency?: number;
|
|
122
|
+
context?: Context;
|
|
123
123
|
[key: string]: any;
|
|
124
|
-
|
|
124
|
+
}
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
hookPush: (item: T | T[], ...meta) => any;
|
|
126
|
+
/**
|
|
127
|
+
* an enriched array is an array that has a hookPush method that can be used to transform-then-push items into the array
|
|
128
|
+
*/
|
|
129
|
+
export interface HookedArray<T> extends Array<T> {
|
|
130
|
+
hookPush: (item: T | T[], ...meta: any[]) => any;
|
|
131
131
|
flush: () => void;
|
|
132
132
|
getWriteDir: () => string;
|
|
133
133
|
getWritePath: () => string;
|
|
134
134
|
[key: string]: any;
|
|
135
|
-
|
|
135
|
+
}
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
export type AllData =
|
|
138
138
|
| HookedArray<EventSchema>
|
|
139
139
|
| HookedArray<UserProfile>
|
|
140
140
|
| HookedArray<GroupProfileSchema>
|
|
@@ -142,10 +142,10 @@ declare namespace main {
|
|
|
142
142
|
| HookedArray<SCDSchema>
|
|
143
143
|
| any[];
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
/**
|
|
146
|
+
* the storage object is a key-value store that holds arrays of data
|
|
147
|
+
*/
|
|
148
|
+
export interface Storage {
|
|
149
149
|
eventData?: HookedArray<EventSchema>;
|
|
150
150
|
mirrorEventData?: HookedArray<EventSchema>;
|
|
151
151
|
userProfilesData?: HookedArray<UserProfile>;
|
|
@@ -154,24 +154,24 @@ declare namespace main {
|
|
|
154
154
|
lookupTableData?: HookedArray<LookupTableSchema>[];
|
|
155
155
|
scdTableData?: HookedArray<SCDSchema>[];
|
|
156
156
|
groupEventData?: HookedArray<EventSchema>;
|
|
157
|
-
|
|
157
|
+
}
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Runtime state for tracking execution metrics and flags
|
|
161
|
+
*/
|
|
162
|
+
export interface RuntimeState {
|
|
163
163
|
operations: number;
|
|
164
164
|
eventCount: number;
|
|
165
165
|
userCount: number;
|
|
166
166
|
isBatchMode: boolean;
|
|
167
167
|
verbose: boolean;
|
|
168
168
|
isCLI: boolean;
|
|
169
|
-
|
|
169
|
+
}
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Default data factories for generating realistic test data
|
|
173
|
+
*/
|
|
174
|
+
export interface Defaults {
|
|
175
175
|
locationsUsers: () => any[];
|
|
176
176
|
locationsEvents: () => any[];
|
|
177
177
|
iOSDevices: () => any[];
|
|
@@ -179,13 +179,13 @@ declare namespace main {
|
|
|
179
179
|
desktopDevices: () => any[];
|
|
180
180
|
browsers: () => any[];
|
|
181
181
|
campaigns: () => any[];
|
|
182
|
-
|
|
182
|
+
}
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Context object that replaces global variables with dependency injection
|
|
186
|
+
* Contains validated config, storage containers, defaults, and runtime state
|
|
187
|
+
*/
|
|
188
|
+
export interface Context {
|
|
189
189
|
config: Dungeon;
|
|
190
190
|
storage: Storage | null;
|
|
191
191
|
defaults: Defaults;
|
|
@@ -193,6 +193,7 @@ declare namespace main {
|
|
|
193
193
|
runtime: RuntimeState;
|
|
194
194
|
FIXED_NOW: number;
|
|
195
195
|
FIXED_BEGIN?: number;
|
|
196
|
+
TIME_SHIFT_SECONDS: number;
|
|
196
197
|
|
|
197
198
|
// State update methods
|
|
198
199
|
incrementOperations(): void;
|
|
@@ -212,12 +213,12 @@ declare namespace main {
|
|
|
212
213
|
// Time helper methods
|
|
213
214
|
getTimeShift(): number;
|
|
214
215
|
getDaysShift(): number;
|
|
215
|
-
|
|
216
|
+
}
|
|
216
217
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
218
|
+
/**
|
|
219
|
+
* how we define events and their properties
|
|
220
|
+
*/
|
|
221
|
+
export interface EventConfig {
|
|
221
222
|
event?: string;
|
|
222
223
|
weight?: number;
|
|
223
224
|
properties?: Record<string, ValueValid>;
|
|
@@ -225,19 +226,19 @@ declare namespace main {
|
|
|
225
226
|
isChurnEvent?: boolean;
|
|
226
227
|
isSessionStartEvent?: boolean;
|
|
227
228
|
relativeTimeMs?: number;
|
|
228
|
-
|
|
229
|
+
}
|
|
229
230
|
|
|
230
|
-
|
|
231
|
+
export interface GroupEventConfig extends EventConfig {
|
|
231
232
|
frequency: number; //how often the event occurs (in days)
|
|
232
233
|
group_key: string; //the key that the group is based on
|
|
233
234
|
attribute_to_user: boolean; //if true, the event also goes to a user
|
|
234
235
|
group_size: number; //the number of users in the group
|
|
235
|
-
|
|
236
|
+
}
|
|
236
237
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
/**
|
|
239
|
+
* the generated event data
|
|
240
|
+
*/
|
|
241
|
+
export interface EventSchema {
|
|
241
242
|
event: string;
|
|
242
243
|
time: string;
|
|
243
244
|
source: string;
|
|
@@ -246,12 +247,20 @@ declare namespace main {
|
|
|
246
247
|
session_id?: string;
|
|
247
248
|
user_id?: string;
|
|
248
249
|
[key: string]: ValueValid;
|
|
249
|
-
|
|
250
|
+
}
|
|
250
251
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
252
|
+
/**
|
|
253
|
+
* how we define funnels and their properties
|
|
254
|
+
*/
|
|
255
|
+
export interface Funnel {
|
|
256
|
+
/**
|
|
257
|
+
* the name of the funnel
|
|
258
|
+
*/
|
|
259
|
+
name?: string;
|
|
260
|
+
/**
|
|
261
|
+
* the description of the funnel
|
|
262
|
+
*/
|
|
263
|
+
description?: string;
|
|
255
264
|
/**
|
|
256
265
|
* the sequence of events that define the funnel
|
|
257
266
|
*/
|
|
@@ -274,14 +283,14 @@ declare namespace main {
|
|
|
274
283
|
* how the events in the funnel are ordered for each user
|
|
275
284
|
*/
|
|
276
285
|
order?:
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
286
|
+
| "sequential"
|
|
287
|
+
| "first-fixed"
|
|
288
|
+
| "last-fixed"
|
|
289
|
+
| "random" //totally shuffled
|
|
290
|
+
| "first-and-last-fixed"
|
|
291
|
+
| "middle-fixed"
|
|
292
|
+
| "interrupted"
|
|
293
|
+
| string;
|
|
285
294
|
|
|
286
295
|
/**
|
|
287
296
|
* todo: implement this
|
|
@@ -302,13 +311,18 @@ declare namespace main {
|
|
|
302
311
|
* funnel properties go onto each event in the funnel and are held constant
|
|
303
312
|
*/
|
|
304
313
|
props?: Record<string, ValueValid>;
|
|
305
|
-
|
|
314
|
+
/**
|
|
315
|
+
* funnel conditions (user properties) are used to filter users who are eligible for the funnel
|
|
316
|
+
* these conditions must match the current user's profile for the user to be eligible for the funnel
|
|
317
|
+
*/
|
|
318
|
+
conditions?: Record<string, ValueValid>;
|
|
319
|
+
}
|
|
306
320
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
321
|
+
/**
|
|
322
|
+
* mirror props are used to show mutations of event data over time
|
|
323
|
+
* there are different strategies for how to mutate the data
|
|
324
|
+
*/
|
|
325
|
+
export interface MirrorProps {
|
|
312
326
|
/**
|
|
313
327
|
* the event that will be mutated in the new version
|
|
314
328
|
*/
|
|
@@ -325,18 +339,18 @@ declare namespace main {
|
|
|
325
339
|
* optional: for 'fill' mode, daysUnfilled will dictate where the cutoff is in the unfilled data
|
|
326
340
|
*/
|
|
327
341
|
daysUnfilled?: number;
|
|
328
|
-
|
|
342
|
+
}
|
|
329
343
|
|
|
330
|
-
|
|
344
|
+
export interface UserProfile {
|
|
331
345
|
name?: string;
|
|
332
346
|
email?: string;
|
|
333
347
|
avatar?: string;
|
|
334
348
|
created: string | undefined;
|
|
335
349
|
distinct_id: string;
|
|
336
350
|
[key: string]: ValueValid;
|
|
337
|
-
|
|
351
|
+
}
|
|
338
352
|
|
|
339
|
-
|
|
353
|
+
export interface Person {
|
|
340
354
|
name: string;
|
|
341
355
|
email?: string;
|
|
342
356
|
avatar?: string;
|
|
@@ -344,48 +358,48 @@ declare namespace main {
|
|
|
344
358
|
anonymousIds: string[];
|
|
345
359
|
sessionIds: string[];
|
|
346
360
|
distinct_id?: string;
|
|
347
|
-
|
|
361
|
+
}
|
|
348
362
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
363
|
+
/**
|
|
364
|
+
* the generated user data
|
|
365
|
+
*/
|
|
366
|
+
export interface LookupTableSchema {
|
|
353
367
|
key: string;
|
|
354
368
|
entries: number;
|
|
355
369
|
attributes: Record<string, ValueValid>;
|
|
356
|
-
|
|
370
|
+
}
|
|
357
371
|
|
|
358
|
-
|
|
372
|
+
export interface LookupTableData {
|
|
359
373
|
key: string;
|
|
360
374
|
data: any[];
|
|
361
|
-
|
|
375
|
+
}
|
|
362
376
|
|
|
363
|
-
|
|
377
|
+
export interface SCDSchema {
|
|
364
378
|
distinct_id: string;
|
|
365
379
|
insertTime: string;
|
|
366
380
|
startTime: string;
|
|
367
381
|
[key: string]: ValueValid;
|
|
368
|
-
|
|
382
|
+
}
|
|
369
383
|
|
|
370
|
-
|
|
384
|
+
export interface GroupProfileSchema {
|
|
371
385
|
key: string;
|
|
372
386
|
data: any[];
|
|
373
|
-
|
|
387
|
+
}
|
|
374
388
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
389
|
+
/**
|
|
390
|
+
* the end result of importing data into mixpanel
|
|
391
|
+
*/
|
|
392
|
+
export interface ImportResults {
|
|
379
393
|
events: ImportResult;
|
|
380
394
|
users: ImportResult;
|
|
381
395
|
groups: ImportResult[];
|
|
382
|
-
|
|
383
|
-
|
|
396
|
+
}
|
|
397
|
+
type ImportResult = import("mixpanel-import").ImportResults;
|
|
384
398
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
399
|
+
/**
|
|
400
|
+
* the end result of the data generation
|
|
401
|
+
*/
|
|
402
|
+
export type Result = {
|
|
389
403
|
eventData: EventSchema[];
|
|
390
404
|
mirrorEventData: EventSchema[];
|
|
391
405
|
userProfilesData: any[];
|
|
@@ -396,16 +410,15 @@ declare namespace main {
|
|
|
396
410
|
importResults?: ImportResults;
|
|
397
411
|
files?: string[];
|
|
398
412
|
time?: {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
413
|
+
start: number;
|
|
414
|
+
end: number;
|
|
415
|
+
delta: number;
|
|
416
|
+
human: string;
|
|
403
417
|
};
|
|
404
418
|
operations?: number;
|
|
405
419
|
eventCount?: number;
|
|
406
420
|
userCount?: number;
|
|
407
|
-
|
|
408
|
-
}
|
|
421
|
+
};
|
|
409
422
|
|
|
410
423
|
/**
|
|
411
424
|
* Mixpanel Data Generator
|
|
@@ -414,6 +427,6 @@ declare namespace main {
|
|
|
414
427
|
* import datagenerator from 'make-mp-data';
|
|
415
428
|
* const data = await datagenerator({...opts});
|
|
416
429
|
*/
|
|
417
|
-
declare function main(config:
|
|
430
|
+
declare function main(config: Dungeon): Promise<Result>;
|
|
418
431
|
|
|
419
|
-
export
|
|
432
|
+
export default main;
|
package/lib/cloud-function.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cloud Function Entry Point
|
|
3
|
-
* Provides a clean interface for Google Cloud Functions deployment
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/** @typedef {import('../types').Dungeon} Config */
|
|
7
|
-
|
|
8
|
-
import functions from '@google-cloud/functions-framework';
|
|
9
|
-
import { handleCloudFunctionEntry } from './orchestrators/worker-manager.js';
|
|
10
|
-
import main from '../index.js';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Cloud Function HTTP entry point
|
|
14
|
-
* Handles distributed data generation across multiple workers
|
|
15
|
-
*/
|
|
16
|
-
functions.http('entry', async (req, res) => {
|
|
17
|
-
await handleCloudFunctionEntry(req, res, main);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
export { handleCloudFunctionEntry, main };
|
|
File without changes
|