make-mp-data 2.0.21 → 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/student-teacher.js +38 -87
- package/entry.js +6 -1
- package/index.js +34 -5
- package/lib/cli/cli.js +8 -0
- package/lib/core/config-validator.js +230 -219
- package/lib/core/storage.js +43 -10
- package/lib/orchestrators/mixpanel-sender.js +5 -2
- package/lib/orchestrators/user-loop.js +212 -181
- package/lib/templates/abbreviated.d.ts +4 -3
- package/lib/templates/instructions.txt +1 -0
- package/lib/templates/{dungeon-template.js → scratch-dungeon-template.js} +9 -3
- package/lib/templates/verbose-schema.js +31 -4
- package/lib/utils/utils.js +47 -10
- package/package.json +4 -4
- package/types.d.ts +6 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// Generated from prompt: Create a digital classroom data set where we have two types of users students and teachers and students do student actions like reading writing arithmetic homework tests and teachers do teaching actions like teach grade take attendance etc. importantly each event done by each persona should have a 'student:' or teacher: prefix to indicate that this is an event on by students or this is not done by teachers... make many unique events + funnels.
|
|
2
1
|
|
|
3
2
|
import dayjs from "dayjs";
|
|
4
3
|
import utc from "dayjs/plugin/utc.js";
|
|
@@ -24,7 +23,7 @@ const config = {
|
|
|
24
23
|
hasAnonIds: false,
|
|
25
24
|
hasSessionIds: false,
|
|
26
25
|
format: "json",
|
|
27
|
-
alsoInferFunnels:
|
|
26
|
+
alsoInferFunnels: false,
|
|
28
27
|
hasLocation: true,
|
|
29
28
|
hasAndroidDevices: true,
|
|
30
29
|
hasIOSDevices: true,
|
|
@@ -53,6 +52,9 @@ const config = {
|
|
|
53
52
|
"isFirstFunnel": true,
|
|
54
53
|
"conversionRate": 95,
|
|
55
54
|
"timeToConvert": 0.1,
|
|
55
|
+
"conditions": {
|
|
56
|
+
"role": "student"
|
|
57
|
+
},
|
|
56
58
|
"order": "sequential",
|
|
57
59
|
"props": {
|
|
58
60
|
"onboarding_source": [
|
|
@@ -69,6 +71,9 @@ const config = {
|
|
|
69
71
|
"teacher: create class",
|
|
70
72
|
"teacher: post announcement"
|
|
71
73
|
],
|
|
74
|
+
"conditions": {
|
|
75
|
+
"role": "teacher"
|
|
76
|
+
},
|
|
72
77
|
"isFirstFunnel": true,
|
|
73
78
|
"conversionRate": 98,
|
|
74
79
|
"timeToConvert": 0.2,
|
|
@@ -82,6 +87,9 @@ const config = {
|
|
|
82
87
|
"student: submit assignment",
|
|
83
88
|
"student: view grade"
|
|
84
89
|
],
|
|
90
|
+
"conditions": {
|
|
91
|
+
"role": "student"
|
|
92
|
+
},
|
|
85
93
|
"isFirstFunnel": false,
|
|
86
94
|
"conversionRate": 70,
|
|
87
95
|
"timeToConvert": 48,
|
|
@@ -92,6 +100,9 @@ const config = {
|
|
|
92
100
|
},
|
|
93
101
|
{
|
|
94
102
|
"name": "Student Takes Test",
|
|
103
|
+
"conditions": {
|
|
104
|
+
"role": "student"
|
|
105
|
+
},
|
|
95
106
|
"sequence": [
|
|
96
107
|
"student: view assignment",
|
|
97
108
|
"student: start test",
|
|
@@ -109,6 +120,9 @@ const config = {
|
|
|
109
120
|
},
|
|
110
121
|
{
|
|
111
122
|
"name": "Teacher Grades Assignment",
|
|
123
|
+
"conditions": {
|
|
124
|
+
"role": "teacher"
|
|
125
|
+
},
|
|
112
126
|
"sequence": [
|
|
113
127
|
"teacher: create assignment",
|
|
114
128
|
"teacher: assign homework",
|
|
@@ -126,10 +140,21 @@ const config = {
|
|
|
126
140
|
"teacher: start lesson",
|
|
127
141
|
"teacher: end lesson"
|
|
128
142
|
],
|
|
143
|
+
"conditions": {
|
|
144
|
+
"role": "teacher"
|
|
145
|
+
},
|
|
129
146
|
"isFirstFunnel": false,
|
|
130
147
|
"conversionRate": 99,
|
|
131
148
|
"timeToConvert": 1,
|
|
132
149
|
"order": "sequential"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"name": "all peoples doing stuf (no conditions)",
|
|
153
|
+
"sequence": [
|
|
154
|
+
"foo",
|
|
155
|
+
"bar",
|
|
156
|
+
"baz"
|
|
157
|
+
]
|
|
133
158
|
}
|
|
134
159
|
],
|
|
135
160
|
"events": [
|
|
@@ -291,6 +316,15 @@ const config = {
|
|
|
291
316
|
"Event"
|
|
292
317
|
]
|
|
293
318
|
}
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"event": "foo"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"event": "bar"
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"event": "baz"
|
|
294
328
|
}
|
|
295
329
|
],
|
|
296
330
|
"superProps": {
|
|
@@ -326,8 +360,6 @@ const config = {
|
|
|
326
360
|
"student",
|
|
327
361
|
"teacher"
|
|
328
362
|
],
|
|
329
|
-
"first_name": "chance.first.bind(chance)",
|
|
330
|
-
"last_name": "chance.last.bind(chance)"
|
|
331
363
|
},
|
|
332
364
|
"scdProps": {
|
|
333
365
|
"gpa": {
|
|
@@ -358,88 +390,7 @@ const config = {
|
|
|
358
390
|
"max": 12
|
|
359
391
|
}
|
|
360
392
|
},
|
|
361
|
-
|
|
362
|
-
[
|
|
363
|
-
"class_id",
|
|
364
|
-
100
|
|
365
|
-
]
|
|
366
|
-
],
|
|
367
|
-
"groupProps": {
|
|
368
|
-
"class_id": {
|
|
369
|
-
"teacher_name": "() => `Mrs. ${chance.last()}`",
|
|
370
|
-
"school_name": "() => `${chance.city()} ${chance.pickone(['Elementary', 'Middle School', 'High School'])}`",
|
|
371
|
-
"class_size": "weighNumRange(15, 35, 0.5)",
|
|
372
|
-
"subject_id": "range(1, 20)"
|
|
373
|
-
}
|
|
374
|
-
},
|
|
375
|
-
"lookupTables": [
|
|
376
|
-
{
|
|
377
|
-
"key": "assignment_id",
|
|
378
|
-
"entries": 500,
|
|
379
|
-
"attributes": {
|
|
380
|
-
"type": [
|
|
381
|
-
"homework",
|
|
382
|
-
"test",
|
|
383
|
-
"quiz",
|
|
384
|
-
"project",
|
|
385
|
-
"reading"
|
|
386
|
-
],
|
|
387
|
-
"difficulty": [
|
|
388
|
-
"easy",
|
|
389
|
-
"medium",
|
|
390
|
-
"hard"
|
|
391
|
-
],
|
|
392
|
-
"max_points": [
|
|
393
|
-
10,
|
|
394
|
-
20,
|
|
395
|
-
25,
|
|
396
|
-
50,
|
|
397
|
-
100
|
|
398
|
-
],
|
|
399
|
-
"subject_id": "range(1, 20)"
|
|
400
|
-
}
|
|
401
|
-
},
|
|
402
|
-
{
|
|
403
|
-
"key": "subject_id",
|
|
404
|
-
"entries": 20,
|
|
405
|
-
"attributes": {
|
|
406
|
-
"subject_name": [
|
|
407
|
-
"Mathematics",
|
|
408
|
-
"English Language Arts",
|
|
409
|
-
"Science",
|
|
410
|
-
"Social Studies",
|
|
411
|
-
"History",
|
|
412
|
-
"Art",
|
|
413
|
-
"Music",
|
|
414
|
-
"Physical Education",
|
|
415
|
-
"Computer Science",
|
|
416
|
-
"Spanish",
|
|
417
|
-
"French",
|
|
418
|
-
"German",
|
|
419
|
-
"Biology",
|
|
420
|
-
"Chemistry",
|
|
421
|
-
"Physics",
|
|
422
|
-
"Algebra",
|
|
423
|
-
"Geometry",
|
|
424
|
-
"Calculus",
|
|
425
|
-
"Literature",
|
|
426
|
-
"World History"
|
|
427
|
-
],
|
|
428
|
-
"department": [
|
|
429
|
-
"STEM",
|
|
430
|
-
"Humanities",
|
|
431
|
-
"Arts",
|
|
432
|
-
"Foreign Language"
|
|
433
|
-
],
|
|
434
|
-
"is_core_subject": [
|
|
435
|
-
true,
|
|
436
|
-
true,
|
|
437
|
-
false
|
|
438
|
-
]
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
]
|
|
442
|
-
,
|
|
393
|
+
|
|
443
394
|
|
|
444
395
|
hook: function (record, type, meta) {
|
|
445
396
|
const NOW = dayjs();
|
|
@@ -460,7 +411,7 @@ const config = {
|
|
|
460
411
|
|
|
461
412
|
}
|
|
462
413
|
|
|
463
|
-
if (type === "scd") {
|
|
414
|
+
if (type === "scd-pre") {
|
|
464
415
|
|
|
465
416
|
}
|
|
466
417
|
|
package/entry.js
CHANGED
|
@@ -17,7 +17,12 @@ import getCliParams from './lib/cli/cli.js';
|
|
|
17
17
|
if (cliConfig.complex) {
|
|
18
18
|
const complexConfig = await import('./dungeons/complex.js');
|
|
19
19
|
finalConfig = { ...complexConfig.default, ...cliConfig };
|
|
20
|
-
}
|
|
20
|
+
}
|
|
21
|
+
else if (cliConfig.sanity) {
|
|
22
|
+
const sanityConfig = await import('./dungeons/sanity.js');
|
|
23
|
+
finalConfig = { ...sanityConfig.default, ...cliConfig };
|
|
24
|
+
}
|
|
25
|
+
else if (cliConfig.simple || (!cliConfig.complex && !cliConfig.simple)) {
|
|
21
26
|
// Default to simple mode when no flags or when --simple is explicitly set
|
|
22
27
|
const simpleConfig = await import('./dungeons/simple.js');
|
|
23
28
|
finalConfig = { ...simpleConfig.default, ...cliConfig };
|
package/index.js
CHANGED
|
@@ -89,7 +89,7 @@ function displayConfigurationSummary(config) {
|
|
|
89
89
|
if (funnel.sequence) {
|
|
90
90
|
const arrow = ' → ';
|
|
91
91
|
const sequence = funnel.sequence.join(arrow);
|
|
92
|
-
const rate = funnel.conversionRate ? ` (${(funnel.conversionRate
|
|
92
|
+
const rate = funnel.conversionRate ? ` (${(funnel.conversionRate).toFixed(0)}% conversion)` : '';
|
|
93
93
|
console.log(` ${i + 1}. ${sequence}${rate}`);
|
|
94
94
|
}
|
|
95
95
|
});
|
|
@@ -194,7 +194,10 @@ async function main(config) {
|
|
|
194
194
|
await generateCharts(context);
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
// Step
|
|
197
|
+
// Step 11a: Always flush lookup tables to disk (regardless of writeToDisk setting)
|
|
198
|
+
await flushLookupTablesToDisk(storage, validatedConfig);
|
|
199
|
+
|
|
200
|
+
// Step 11b: Flush other storage containers to disk (if writeToDisk enabled)
|
|
198
201
|
if (validatedConfig.writeToDisk) {
|
|
199
202
|
await flushStorageToDisk(storage, validatedConfig);
|
|
200
203
|
}
|
|
@@ -436,7 +439,33 @@ async function generateCharts(context) {
|
|
|
436
439
|
}
|
|
437
440
|
|
|
438
441
|
/**
|
|
439
|
-
* Flush
|
|
442
|
+
* Flush lookup tables to disk (always runs, regardless of writeToDisk setting)
|
|
443
|
+
* @param {import('./types').Storage} storage - Storage containers
|
|
444
|
+
* @param {import('./types').Dungeon} config - Configuration object
|
|
445
|
+
*/
|
|
446
|
+
async function flushLookupTablesToDisk(storage, config) {
|
|
447
|
+
if (!storage.lookupTableData || !Array.isArray(storage.lookupTableData) || storage.lookupTableData.length === 0) {
|
|
448
|
+
return; // No lookup tables to flush
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (config.verbose) {
|
|
452
|
+
console.log('💾 Writing lookup tables to disk...');
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const flushPromises = [];
|
|
456
|
+
storage.lookupTableData.forEach(container => {
|
|
457
|
+
if (container?.flush) flushPromises.push(container.flush());
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
await Promise.all(flushPromises);
|
|
461
|
+
|
|
462
|
+
if (config.verbose) {
|
|
463
|
+
console.log('🗂️ Lookup tables flushed to disk successfully');
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Flush all storage containers to disk (excluding lookup tables)
|
|
440
469
|
* @param {import('./types').Storage} storage - Storage containers
|
|
441
470
|
* @param {import('./types').Dungeon} config - Configuration object
|
|
442
471
|
*/
|
|
@@ -454,8 +483,8 @@ async function flushStorageToDisk(storage, config) {
|
|
|
454
483
|
if (storage.mirrorEventData?.flush) flushPromises.push(storage.mirrorEventData.flush());
|
|
455
484
|
if (storage.groupEventData?.flush) flushPromises.push(storage.groupEventData.flush());
|
|
456
485
|
|
|
457
|
-
// Flush arrays of HookedArrays
|
|
458
|
-
[storage.scdTableData, storage.groupProfilesData
|
|
486
|
+
// Flush arrays of HookedArrays (excluding lookup tables which are handled separately)
|
|
487
|
+
[storage.scdTableData, storage.groupProfilesData].forEach(arrayOfContainers => {
|
|
459
488
|
if (Array.isArray(arrayOfContainers)) {
|
|
460
489
|
arrayOfContainers.forEach(container => {
|
|
461
490
|
if (container?.flush) flushPromises.push(container.flush());
|
package/lib/cli/cli.js
CHANGED
|
@@ -121,6 +121,14 @@ DATA MODEL: https://github.com/ak--47/make-mp-data/blob/main/default.js
|
|
|
121
121
|
type: 'boolean',
|
|
122
122
|
coerce: boolCoerce
|
|
123
123
|
})
|
|
124
|
+
.options("sanity", {
|
|
125
|
+
demandOption: false,
|
|
126
|
+
default: false,
|
|
127
|
+
describe: 'run sanity checks on the generated data',
|
|
128
|
+
alias: 'san',
|
|
129
|
+
type: 'boolean',
|
|
130
|
+
coerce: boolCoerce
|
|
131
|
+
})
|
|
124
132
|
.option("writeToDisk", {
|
|
125
133
|
demandOption: false,
|
|
126
134
|
default: true,
|