make-mp-data 2.0.1 → 2.0.2

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.
Files changed (64) hide show
  1. package/dungeons/adspend.js +96 -0
  2. package/dungeons/anon.js +104 -0
  3. package/dungeons/big.js +225 -0
  4. package/dungeons/business.js +345 -0
  5. package/dungeons/complex.js +396 -0
  6. package/dungeons/experiments.js +125 -0
  7. package/dungeons/foobar.js +241 -0
  8. package/dungeons/funnels.js +272 -0
  9. package/dungeons/gaming.js +315 -0
  10. package/dungeons/media.js +7 -7
  11. package/dungeons/mirror.js +129 -0
  12. package/dungeons/sanity.js +113 -0
  13. package/dungeons/scd.js +205 -0
  14. package/dungeons/simple.js +195 -0
  15. package/dungeons/userAgent.js +190 -0
  16. package/entry.js +57 -0
  17. package/index.js +96 -68
  18. package/lib/cli/cli.js +5 -4
  19. package/lib/core/config-validator.js +28 -12
  20. package/lib/core/context.js +147 -130
  21. package/lib/core/storage.js +45 -31
  22. package/lib/data/defaults.js +2 -2
  23. package/lib/generators/adspend.js +1 -2
  24. package/lib/generators/events.js +35 -24
  25. package/lib/generators/funnels.js +1 -2
  26. package/lib/generators/mirror.js +1 -2
  27. package/lib/orchestrators/mixpanel-sender.js +15 -7
  28. package/lib/orchestrators/user-loop.js +21 -10
  29. package/lib/orchestrators/worker-manager.js +5 -2
  30. package/lib/utils/ai.js +36 -63
  31. package/lib/utils/chart.js +5 -0
  32. package/lib/utils/instructions.txt +593 -0
  33. package/lib/utils/utils.js +162 -38
  34. package/package.json +23 -9
  35. package/types.d.ts +376 -376
  36. package/.claude/settings.local.json +0 -21
  37. package/.gcloudignore +0 -18
  38. package/.gitattributes +0 -2
  39. package/.prettierrc +0 -0
  40. package/.vscode/launch.json +0 -80
  41. package/.vscode/settings.json +0 -69
  42. package/.vscode/tasks.json +0 -12
  43. package/dungeons/customers/.gitkeep +0 -0
  44. package/env.yaml +0 -1
  45. package/lib/cloud-function.js +0 -20
  46. package/scratch.mjs +0 -62
  47. package/scripts/dana.mjs +0 -137
  48. package/scripts/deploy.sh +0 -15
  49. package/scripts/jsdoctest.js +0 -5
  50. package/scripts/new-dungeon.sh +0 -98
  51. package/scripts/new-project.mjs +0 -14
  52. package/scripts/run-index.sh +0 -2
  53. package/scripts/update-deps.sh +0 -5
  54. package/tests/benchmark/concurrency.mjs +0 -52
  55. package/tests/cli.test.js +0 -124
  56. package/tests/coverage/.gitkeep +0 -0
  57. package/tests/e2e.test.js +0 -379
  58. package/tests/int.test.js +0 -715
  59. package/tests/testCases.mjs +0 -229
  60. package/tests/testSoup.mjs +0 -28
  61. package/tests/unit.test.js +0 -910
  62. package/tmp/.gitkeep +0 -0
  63. package/tsconfig.json +0 -18
  64. package/vitest.config.js +0 -47
@@ -1,21 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(node:*)",
5
- "Bash(mkdir:*)",
6
- "Bash(npm install)",
7
- "Bash(npx vitest run:*)",
8
- "Bash(npm test)",
9
- "Bash(grep:*)",
10
- "Bash(rg:*)",
11
- "Bash(./scripts/new-dungeon.sh:*)",
12
- "Bash(cp:*)",
13
- "Bash(find:*)",
14
- "Bash(npm test:*)",
15
- "Bash(npm run test:*)",
16
- "Bash(npx tsc:*)",
17
- "Bash(npm start)"
18
- ],
19
- "deny": []
20
- }
21
- }
package/.gcloudignore DELETED
@@ -1,18 +0,0 @@
1
- .env
2
- scratch.mjs
3
- tsconfig.json
4
- types.d.ts
5
- tmp
6
- tests
7
- scripts
8
- data
9
- .vscode
10
- .git
11
- node_modules
12
- env.yml
13
- .prettierrc
14
- .gitattributes
15
- README.md
16
- dungeons
17
- schemas
18
- CLAUDE.md
package/.gitattributes DELETED
@@ -1,2 +0,0 @@
1
- # Auto detect text files and perform LF normalization
2
- * text=auto
package/.prettierrc DELETED
File without changes
@@ -1,80 +0,0 @@
1
- {
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- "version": "0.2.0",
6
- "configurations": [
7
- {
8
- "command": "npm run dev",
9
- "name": "scratch",
10
- "request": "launch",
11
- "type": "node-terminal"
12
- },
13
- {
14
- "type": "node",
15
- "request": "launch",
16
- "name": "run dungeon",
17
- "runtimeExecutable": "nodemon",
18
- "program": "${workspaceFolder}/index.js",
19
- "args": ["${file}"],
20
- "restart": true,
21
- "console": "integratedTerminal",
22
- "internalConsoleOptions": "neverOpen",
23
- "skipFiles": ["<node_internals>/**"],
24
- "preLaunchTask": "npm: prune",
25
- "runtimeArgs": [
26
- "--ignore",
27
- "./data"
28
- ]
29
-
30
- },
31
- {
32
- "type": "node",
33
- "request": "launch",
34
- "name": "current file",
35
- "runtimeExecutable": "nodemon",
36
- "program": "${file}",
37
- "restart": true,
38
- "console": "integratedTerminal",
39
- "internalConsoleOptions": "neverOpen",
40
- "env": {
41
- "NODE_ENV": "dev"
42
- },
43
- "runtimeArgs": ["--ignore", "./data"],
44
- },
45
- {
46
- "command": "npm run func:local",
47
- "name": "cloud local",
48
- "request": "launch",
49
- "type": "node-terminal",
50
- "env": {
51
- "NODE_ENV": "dev"
52
- }
53
- },
54
- {
55
- "type": "node",
56
- "request": "launch",
57
- "name": "sanity",
58
- "runtimeExecutable": "nodemon",
59
- "runtimeArgs": ["--inspect"],
60
- "program": "${workspaceFolder}/index.js",
61
- "args": ["--ignore", "./data/*", "./schemas/sanity.js"],
62
- "restart": true,
63
- "console": "integratedTerminal",
64
- "internalConsoleOptions": "neverOpen",
65
- "skipFiles": ["<node_internals>/**"],
66
- },
67
- {
68
- "type": "node-terminal",
69
- "request": "launch",
70
- "name": "simple",
71
- "command": "node ${workspaceFolder}/index.js --simple"
72
- },
73
- {
74
- "type": "node-terminal",
75
- "request": "launch",
76
- "name": "complex",
77
- "command": "node ${workspaceFolder}/index.js --complex"
78
- }
79
- ]
80
- }
@@ -1,69 +0,0 @@
1
- {
2
- "cSpell.words": [
3
- "adspend",
4
- "AVCHD",
5
- "chartjs",
6
- "chupacabra",
7
- "Colour",
8
- "crumn",
9
- "darr",
10
- "datagenerator",
11
- "dislikers",
12
- "Dont",
13
- "durtle",
14
- "fonk",
15
- "gameplay",
16
- "garply",
17
- "jackalope",
18
- "linny",
19
- "mbembe",
20
- "megalodon",
21
- "Miley",
22
- "mokele",
23
- "mothman",
24
- "nanodegree",
25
- "nessie",
26
- "nesty",
27
- "planthopper",
28
- "PROOMPTY",
29
- "psyllid",
30
- "tatzelwurm",
31
- "timesoup",
32
- "udacity",
33
- "unparse",
34
- "Vlogs",
35
- "weindgo",
36
- "whomacity"
37
- ],
38
- // Vitest settings
39
- "vitest.enable": true,
40
- "vitest.commandLine": "npx vitest",
41
- "vitest.include": ["tests/**/*.test.js"],
42
- "vitest.exclude": ["**/node_modules/**", "**/coverage/**", "**/data/**", "**/tmp/**"],
43
-
44
- // Test Explorer settings
45
- "testing.automaticallyOpenPeekView": "never",
46
- "testing.openTesting": "neverOpen",
47
- "js/ts.implicitProjectConfig.checkJs": true,
48
-
49
- // ESM and import settings
50
- "typescript.preferences.includePackageJsonAutoImports": "auto",
51
- "typescript.suggest.autoImports": true,
52
- "javascript.suggest.autoImports": true,
53
-
54
- // File associations
55
- "files.associations": {
56
- "*.js": "javascript",
57
- "*.mjs": "javascript",
58
- "*.cjs": "javascript"
59
- },
60
-
61
- // Search settings
62
- "search.exclude": {
63
- "**/node_modules": true,
64
- "**/coverage": true,
65
- "**/data": true,
66
- "**/tmp": true
67
- },
68
- "testing.automaticallyOpenTestResults": "neverOpen"
69
- }
@@ -1,12 +0,0 @@
1
- {
2
- "version": "2.0.0",
3
- "tasks": [
4
- {
5
- "label": "npm: prune",
6
- "type": "npm",
7
- "script": "prune",
8
- "group": "build",
9
- "problemMatcher": []
10
- }
11
- ]
12
- }
File without changes
package/env.yaml DELETED
@@ -1 +0,0 @@
1
- NODE_ENV: prod
@@ -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 };
package/scratch.mjs DELETED
@@ -1,62 +0,0 @@
1
- /*
2
- ----
3
- TO DOs
4
- ----
5
- */
6
-
7
- //!feature: fixedTimeFunnel? if set this funnel will occur for all users at the same time ['cards charged', 'charge complete']
8
- //!feature: churn ... is churnFunnel, possible to return, etc
9
- //!feature: send SCD data to mixpanel (blocked on dev)
10
- //!feature: send and map lookup tables to mixpanel (also blocked on dev)
11
- //!bug: using --mc flag reverts to --complex for some reason
12
-
13
-
14
- import main from "./index.js";
15
-
16
- import simple from './dungeons/simple.js';
17
- import funnels from './dungeons/funnels.js';
18
- import foobar from './dungeons/foobar.js';
19
- import complex from './dungeons/complex.js';
20
- import adspend from './dungeons/adspend.js'
21
-
22
- import anon from './dungeons/anon.js';
23
- import execSync from 'child_process';
24
- import mirror from './dungeons/mirror.js'
25
- // import mds from './dungeons/modern-data-stack.js'
26
- import big from './dungeons/big.js'
27
-
28
- const numEvents = 1000;
29
-
30
- /** @type {main.Config} */
31
- const spec = {
32
- ...simple,
33
- numEvents: 10_000,
34
- batchSize: 1_000,
35
- writeToDisk: "gs://dungeon_master_4/scratch",
36
- verbose: true,
37
- makeChart: false,
38
- hasAnonIds: true,
39
- hasSessionIds: true
40
- // format: "csv",
41
- // numEvents,
42
- // numUsers: numEvents / 100,
43
-
44
- };
45
-
46
-
47
- execSync.execSync('npm run prune');
48
- const RESULT = await main(spec);
49
- const {
50
- eventData,
51
- groupProfilesData,
52
- lookupTableData,
53
- mirrorEventData,
54
- scdTableData,
55
- userProfilesData,
56
- importResults,
57
- files,
58
- adSpendData
59
- } = RESULT;
60
-
61
-
62
- debugger;
package/scripts/dana.mjs DELETED
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env node
2
- import { fork } from 'child_process';
3
- import path from 'path';
4
- import dotenv from "dotenv";
5
- dotenv.config();
6
- const { NODE_ENV = "unknown" } = process.env;
7
-
8
- import main from "../index.js";
9
- import simple from '../dungeons/simple.js';
10
- import complex from '../dungeons/complex.js';
11
- import gaming from '../dungeons/customers/gaming.js';
12
- import big from '../dungeons/big.js';
13
-
14
- import Chance from 'chance';
15
- const chance = new Chance();
16
- const twentyFivePercent = () => chance.bool({ likelihood: 25 });
17
-
18
- // --- shared options ---
19
- let divisor = 1;
20
- if (NODE_ENV === "dev") divisor = 1000;
21
-
22
- const commonOptions = {
23
- numEvents: 10_000_000 / divisor,
24
- numUsers: 10_000_000 / 100 / divisor,
25
- batchSize: 200_000,
26
- hasAdSpend: false,
27
- hasAnonIds: true,
28
- hasSessionIds: true,
29
- format: "json",
30
- hasDesktopDevices: true,
31
- hasIOSDevices: true,
32
- hasAndroidDevices: true,
33
- hasBrowser: true,
34
- hasCampaigns: true,
35
- verbose: true,
36
- makeChart: false,
37
- writeToDisk: true
38
- };
39
-
40
-
41
-
42
-
43
- const allSpecs = {
44
- "simple-spec": { ...simple, ...commonOptions, name: "simple-spec" },
45
- "complex-spec": { ...complex, ...commonOptions, name: "complex-spec" },
46
- "meta-spec": { ...big, ...commonOptions, name: "meta-spec" },
47
- "fun-spec": { ...gaming, ...commonOptions, name: "fun-spec" },
48
- "bad-spec": {
49
- ...big, ...commonOptions, name: "bad-data-spec",
50
- hook: function (record, type, meta) {
51
- if (type === "event") {
52
- if (twentyFivePercent()) delete record.event;
53
- if (twentyFivePercent()) delete record.user_id;
54
- if (twentyFivePercent()) delete record.session_id;
55
- if (twentyFivePercent()) delete record.device_id;
56
- if (twentyFivePercent()) delete record.time;
57
- if (twentyFivePercent()) delete record.insert_id;
58
- }
59
- return record;
60
- }
61
- }
62
- };
63
-
64
- for (const [name, spec] of Object.entries(allSpecs)) {
65
- delete spec.groupEvents;
66
- delete spec.scdProps;
67
- delete spec.lookupTables;
68
- delete spec.groupKeys;
69
- delete spec.groupProps;
70
- delete spec.mirrorProps;
71
- delete spec.token;
72
- delete spec.secret;
73
- }
74
-
75
- const simulations = Object.entries(allSpecs).map(([name, spec]) => ({ name, spec }));
76
-
77
- // 1. If this process is a CHILD, just run the spec!
78
- if (process.env.__SIM_CHILD) {
79
- const name = process.env.__SIM_NAME;
80
- const spec = allSpecs[name];
81
- (async () => {
82
- const result = await main(spec);
83
- // Send result to parent
84
- if (process.send) process.send(result);
85
- else console.log(JSON.stringify(result));
86
- process.exit(0);
87
- })();
88
- } else {
89
- // 2. PARENT: fork a child for each simulation
90
- const { promisify } = await import('util');
91
- const limit = 5; // parallelism limit
92
- let running = 0, idx = 0, results = [];
93
-
94
- function runOne(sim) {
95
- return new Promise((resolve, reject) => {
96
- const child = fork(process.argv[1], [], {
97
- env: { ...process.env, __SIM_CHILD: "1", __SIM_NAME: sim.name },
98
- stdio: ['inherit', 'inherit', 'inherit', 'ipc']
99
- });
100
- child.on('message', (result) => resolve({ name: sim.name, result }));
101
- child.on('error', reject);
102
- child.on('exit', (code) => {
103
- if (code !== 0) reject(new Error(`Child ${sim.name} exited code ${code}`));
104
- });
105
- });
106
- }
107
-
108
- const queue = [...simulations];
109
- const resultsList = [];
110
- async function runNext() {
111
- while (running < limit && queue.length > 0) {
112
- const sim = queue.shift();
113
- running++;
114
- runOne(sim)
115
- .then(res => resultsList.push(res))
116
- .catch(e => console.error("Sim error:", e))
117
- .finally(() => {
118
- running--;
119
- runNext();
120
- });
121
- }
122
- }
123
- runNext();
124
-
125
- // Wait until all are done
126
- const wait = () => new Promise(resolve => {
127
- const check = () => {
128
- if (resultsList.length === simulations.length) resolve(resultsList);
129
- else setTimeout(check, 100);
130
- };
131
- check();
132
- });
133
- (await wait()).forEach(res => {
134
- console.log(`Finished simulation: ${res.name}`);
135
- // optionally: console.log(res.result);
136
- });
137
- }
package/scripts/deploy.sh DELETED
@@ -1,15 +0,0 @@
1
- #!/bin/bash
2
- gcloud alpha functions deploy dm4 \
3
- --runtime nodejs20 \
4
- --source . \
5
- --gen2 \
6
- --trigger-http \
7
- --no-allow-unauthenticated \
8
- --entry-point entry \
9
- --env-vars-file env.yaml \
10
- --timeout=3600 \
11
- --region=us-central1 \
12
- --max-instances=1000 \
13
- --min-instances=0 \
14
- --concurrency=1 \
15
- --memory=4G
@@ -1,5 +0,0 @@
1
- /* eslint-disable no-unused-vars */
2
- // @ts-check
3
- const module = require('../index.js');
4
-
5
- module({})
@@ -1,98 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Ensure the ./path directory exists
4
- mkdir -p ./dungeons
5
-
6
- # Generate a random file name with .js extension
7
- random_file_name=$(mktemp ./dungeons/my-file-XXXXXXXX.js)
8
-
9
- # Initial text to write to the file
10
- initial_text='
11
- import dayjs from "dayjs";
12
- import utc from "dayjs/plugin/utc.js";
13
- import "dotenv/config";
14
- import * as u from "../lib/utils/utils.js";
15
- import * as v from "ak-tools";
16
-
17
- const SEED = "my-seed";
18
- dayjs.extend(utc);
19
- const chance = u.initChance(SEED);
20
- const num_users = 25_000
21
- const days = 100
22
-
23
- /** @typedef {import("../types.d.ts").Dungeon} Config */
24
-
25
- /** @type {Config} */
26
- const config = {
27
- token: "",
28
- seed: SEED,
29
- numDays: days,
30
- numEvents: num_users * 100,
31
- numUsers: num_users,
32
- hasAnonIds: false,
33
- hasSessionIds: false,
34
- format: "json",
35
- alsoInferFunnels: true,
36
- hasLocation: true,
37
- hasAndroidDevices: true,
38
- hasIOSDevices: true,
39
- hasDesktopDevices: true,
40
- hasBrowser: true,
41
- hasCampaigns: true,
42
- isAnonymous: false,
43
- hasAdSpend: true,
44
-
45
- hasAvatar: true,
46
- makeChart: false,
47
-
48
- batchSize: 1_500_000,
49
- concurrency: 1,
50
- writeToDisk: false,
51
-
52
- funnels: [],
53
- events: [],
54
- superProps: {},
55
- userProps: {},
56
- scdProps: {},
57
- mirrorProps: {},
58
- groupKeys: [],
59
- groupProps: {},
60
- lookupTables: [],
61
- hook: function (record, type, meta) {
62
- const NOW = dayjs();
63
-
64
- if (type === "event") {
65
- const EVENT_TIME = dayjs(record.time);
66
- }
67
-
68
- if (type === "user") {
69
-
70
- }
71
-
72
- if (type === "funnel-post") {
73
-
74
- }
75
-
76
- if (type === "funnel-pre") {
77
-
78
- }
79
-
80
- if (type === "scd") {
81
-
82
- }
83
-
84
- if (type === "everything") {
85
-
86
- }
87
-
88
- return record;
89
- }
90
- };
91
-
92
- export default config;'
93
-
94
- # Write the initial text to the new file
95
- echo "$initial_text" > "$random_file_name"
96
-
97
- # Output the name of the created file
98
- echo "File created: $random_file_name"
@@ -1,14 +0,0 @@
1
- import project from "../components/project.js";
2
- import dotenv from "dotenv";
3
-
4
- dotenv.config();
5
- const OAUTH_TOKEN = process.env.OAUTH_TOKEN || "";
6
-
7
- if (!OAUTH_TOKEN) throw new Error('No OAUTH_TOKEN in .env');
8
-
9
- // @ts-ignore
10
- const createdProject = await project({
11
- oauth: OAUTH_TOKEN
12
- })
13
-
14
- console.log(createdProject);
@@ -1,2 +0,0 @@
1
- #!/bin/bash
2
- RUNTIME=local nodemon --inspect index.js --writeToDisk false -u 100 -e 10000
@@ -1,5 +0,0 @@
1
- #!/bin/bash
2
- npm i mixpanel-import@latest --save
3
- npm i ak-tools@latest --save
4
- npm i ak-fetch@latest --save
5
- npm i ak-gemini@latest --save
@@ -1,52 +0,0 @@
1
- /*
2
- ----
3
- TO DOs
4
- ----
5
- */
6
-
7
- //!feature: fixedTimeFunnel? if set this funnel will occur for all users at the same time ['cards charged', 'charge complete']
8
- //!feature: churn ... is churnFunnel, possible to return, etc
9
- //!feature: send SCD data to mixpanel (blocked on dev)
10
- //!feature: send and map lookup tables to mixpanel (also blocked on dev)
11
- //!bug: using --mc flag reverts to --complex for some reason
12
-
13
-
14
- import main from "../../index.js";
15
- import simple from '../../dungeons/simple.js';
16
-
17
- /** @typedef {import('../../types').Dungeon} Config */
18
-
19
- /** @type {Config} */
20
- const noWrites = {
21
- ...simple,
22
- numUsers: 10_000,
23
- numEvents: 250_000,
24
- writeToDisk: false,
25
- };
26
-
27
- /** @type {Config} */
28
- const yesWrites = {
29
- ...noWrites,
30
- writeToDisk: true
31
- };
32
-
33
- console.log('concurrency benchmarking');
34
-
35
- const concurrency = [1, 2, 3, 4, 5];
36
-
37
- const results = [];
38
- for (const concurrent of concurrency) {
39
- console.log(`concurrency: ${concurrent}`);
40
- // @ts-ignore
41
- const test = await main({ ...noWrites, concurrency: concurrent });
42
- results.push({ human: test.time.human, concurrency: concurrent });
43
- console.log(`\t\tdone: ${test.time.human}\n\n`);
44
- }
45
-
46
- const display = results.map((r) => {
47
- return `concurrency: ${r.concurrency} | duration: ${r.human}`;
48
- });
49
-
50
- console.log(display.join('\n\n'));
51
-
52
- debugger;