@idlekit/core 0.0.0-stage → 0.2.1
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/LICENSE +21 -0
- package/README.md +105 -2
- package/dist/engine/breakEternity.d.ts +1 -0
- package/dist/engine/breakEternity.js +2 -0
- package/dist/engine/breakEternity.js.map +1 -0
- package/dist/engine/breakInfinity.d.ts +1 -0
- package/dist/engine/breakInfinity.js +2 -0
- package/dist/engine/breakInfinity.js.map +1 -0
- package/dist/engine/types.d.ts +1 -0
- package/dist/engine/types.js +2 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/money/types.d.ts +1 -0
- package/dist/money/types.js +2 -0
- package/dist/money/types.js.map +1 -0
- package/dist/notation/formatMoney.d.ts +1 -0
- package/dist/notation/formatMoney.js +2 -0
- package/dist/notation/formatMoney.js.map +1 -0
- package/dist/notation/parseMoney.d.ts +1 -0
- package/dist/notation/parseMoney.js +2 -0
- package/dist/notation/parseMoney.js.map +1 -0
- package/dist/notation/suffixer.d.ts +1 -0
- package/dist/notation/suffixer.js +2 -0
- package/dist/notation/suffixer.js.map +1 -0
- package/dist/notation/visibilityTracker.d.ts +1 -0
- package/dist/notation/visibilityTracker.js +2 -0
- package/dist/notation/visibilityTracker.js.map +1 -0
- package/dist/policy/emitter.d.ts +1 -0
- package/dist/policy/emitter.js +2 -0
- package/dist/policy/emitter.js.map +1 -0
- package/dist/policy/tickMoney.d.ts +1 -0
- package/dist/policy/tickMoney.js +2 -0
- package/dist/policy/tickMoney.js.map +1 -0
- package/dist/policy/types.d.ts +1 -0
- package/dist/policy/types.js +2 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/report/compare.d.ts +17 -0
- package/dist/report/compare.js +91 -0
- package/dist/report/compare.js.map +1 -0
- package/dist/report/timeline.d.ts +16 -0
- package/dist/report/timeline.js +42 -0
- package/dist/report/timeline.js.map +1 -0
- package/dist/scenario/compile.d.ts +48 -0
- package/dist/scenario/compile.js +490 -0
- package/dist/scenario/compile.js.map +1 -0
- package/dist/scenario/concreteValidator.d.ts +16 -0
- package/dist/scenario/concreteValidator.js +52 -0
- package/dist/scenario/concreteValidator.js.map +1 -0
- package/dist/scenario/migrate.d.ts +9 -0
- package/dist/scenario/migrate.js +93 -0
- package/dist/scenario/migrate.js.map +1 -0
- package/dist/scenario/offlinePolicy.d.ts +27 -0
- package/dist/scenario/offlinePolicy.js +2 -0
- package/dist/scenario/offlinePolicy.js.map +1 -0
- package/dist/scenario/registry.d.ts +21 -0
- package/dist/scenario/registry.js +18 -0
- package/dist/scenario/registry.js.map +1 -0
- package/dist/scenario/standardSchema.d.ts +33 -0
- package/dist/scenario/standardSchema.js +36 -0
- package/dist/scenario/standardSchema.js.map +1 -0
- package/dist/scenario/types.d.ts +149 -0
- package/dist/scenario/types.js +2 -0
- package/dist/scenario/types.js.map +1 -0
- package/dist/scenario/typiaTransformMissing.d.ts +14 -0
- package/dist/scenario/typiaTransformMissing.js +25 -0
- package/dist/scenario/typiaTransformMissing.js.map +1 -0
- package/dist/scenario/validate.d.ts +11 -0
- package/dist/scenario/validate.js +551 -0
- package/dist/scenario/validate.js.map +1 -0
- package/dist/serde/moneyState.d.ts +1 -0
- package/dist/serde/moneyState.js +2 -0
- package/dist/serde/moneyState.js.map +1 -0
- package/dist/serde/simState.d.ts +72 -0
- package/dist/serde/simState.js +155 -0
- package/dist/serde/simState.js.map +1 -0
- package/dist/sim/analysis/eta.d.ts +32 -0
- package/dist/sim/analysis/eta.js +105 -0
- package/dist/sim/analysis/eta.js.map +1 -0
- package/dist/sim/analysis/growth.d.ts +24 -0
- package/dist/sim/analysis/growth.js +133 -0
- package/dist/sim/analysis/growth.js.map +1 -0
- package/dist/sim/analysis/milestones.d.ts +18 -0
- package/dist/sim/analysis/milestones.js +110 -0
- package/dist/sim/analysis/milestones.js.map +1 -0
- package/dist/sim/analysis/prestigeCycle.d.ts +24 -0
- package/dist/sim/analysis/prestigeCycle.js +76 -0
- package/dist/sim/analysis/prestigeCycle.js.map +1 -0
- package/dist/sim/analysis/ux.d.ts +60 -0
- package/dist/sim/analysis/ux.js +139 -0
- package/dist/sim/analysis/ux.js.map +1 -0
- package/dist/sim/constraints.d.ts +34 -0
- package/dist/sim/constraints.js +53 -0
- package/dist/sim/constraints.js.map +1 -0
- package/dist/sim/eventBuffer.d.ts +36 -0
- package/dist/sim/eventBuffer.js +122 -0
- package/dist/sim/eventBuffer.js.map +1 -0
- package/dist/sim/goalRead.d.ts +28 -0
- package/dist/sim/goalRead.js +43 -0
- package/dist/sim/goalRead.js.map +1 -0
- package/dist/sim/monteCarlo.d.ts +35 -0
- package/dist/sim/monteCarlo.js +66 -0
- package/dist/sim/monteCarlo.js.map +1 -0
- package/dist/sim/observation.d.ts +129 -0
- package/dist/sim/observation.js +381 -0
- package/dist/sim/observation.js.map +1 -0
- package/dist/sim/offline.d.ts +61 -0
- package/dist/sim/offline.js +223 -0
- package/dist/sim/offline.js.map +1 -0
- package/dist/sim/offlineCredit.d.ts +19 -0
- package/dist/sim/offlineCredit.js +59 -0
- package/dist/sim/offlineCredit.js.map +1 -0
- package/dist/sim/random.d.ts +3 -0
- package/dist/sim/random.js +15 -0
- package/dist/sim/random.js.map +1 -0
- package/dist/sim/runFactory.d.ts +172 -0
- package/dist/sim/runFactory.js +517 -0
- package/dist/sim/runFactory.js.map +1 -0
- package/dist/sim/session.d.ts +113 -0
- package/dist/sim/session.js +425 -0
- package/dist/sim/session.js.map +1 -0
- package/dist/sim/simulator.d.ts +10 -0
- package/dist/sim/simulator.js +175 -0
- package/dist/sim/simulator.js.map +1 -0
- package/dist/sim/step.d.ts +78 -0
- package/dist/sim/step.js +493 -0
- package/dist/sim/step.js.map +1 -0
- package/dist/sim/stepTypes.d.ts +2 -0
- package/dist/sim/stepTypes.js +2 -0
- package/dist/sim/stepTypes.js.map +1 -0
- package/dist/sim/strategy/builtins.d.ts +2 -0
- package/dist/sim/strategy/builtins.js +47 -0
- package/dist/sim/strategy/builtins.js.map +1 -0
- package/dist/sim/strategy/contracts.d.ts +43 -0
- package/dist/sim/strategy/contracts.js +44 -0
- package/dist/sim/strategy/contracts.js.map +1 -0
- package/dist/sim/strategy/greedy.d.ts +4 -0
- package/dist/sim/strategy/greedy.js +180 -0
- package/dist/sim/strategy/greedy.js.map +1 -0
- package/dist/sim/strategy/opt/objective.d.ts +15 -0
- package/dist/sim/strategy/opt/objective.js +2 -0
- package/dist/sim/strategy/opt/objective.js.map +1 -0
- package/dist/sim/strategy/opt/objectives/builtins.d.ts +2 -0
- package/dist/sim/strategy/opt/objectives/builtins.js +148 -0
- package/dist/sim/strategy/opt/objectives/builtins.js.map +1 -0
- package/dist/sim/strategy/opt/objectives/params.d.ts +14 -0
- package/dist/sim/strategy/opt/objectives/params.js +13 -0
- package/dist/sim/strategy/opt/objectives/params.js.map +1 -0
- package/dist/sim/strategy/opt/registry.d.ts +13 -0
- package/dist/sim/strategy/opt/registry.js +10 -0
- package/dist/sim/strategy/opt/registry.js.map +1 -0
- package/dist/sim/strategy/opt/runner.d.ts +30 -0
- package/dist/sim/strategy/opt/runner.js +76 -0
- package/dist/sim/strategy/opt/runner.js.map +1 -0
- package/dist/sim/strategy/opt/tuneSpec.d.ts +50 -0
- package/dist/sim/strategy/opt/tuneSpec.js +2 -0
- package/dist/sim/strategy/opt/tuneSpec.js.map +1 -0
- package/dist/sim/strategy/opt/tuner.d.ts +58 -0
- package/dist/sim/strategy/opt/tuner.js +2 -0
- package/dist/sim/strategy/opt/tuner.js.map +1 -0
- package/dist/sim/strategy/opt/tuners/randomSearch.d.ts +2 -0
- package/dist/sim/strategy/opt/tuners/randomSearch.js +169 -0
- package/dist/sim/strategy/opt/tuners/randomSearch.js.map +1 -0
- package/dist/sim/strategy/opt/validate.d.ts +8 -0
- package/dist/sim/strategy/opt/validate.js +88 -0
- package/dist/sim/strategy/opt/validate.js.map +1 -0
- package/dist/sim/strategy/params.d.ts +53 -0
- package/dist/sim/strategy/params.js +58 -0
- package/dist/sim/strategy/params.js.map +1 -0
- package/dist/sim/strategy/planner.d.ts +34 -0
- package/dist/sim/strategy/planner.js +308 -0
- package/dist/sim/strategy/planner.js.map +1 -0
- package/dist/sim/strategy/registry.d.ts +13 -0
- package/dist/sim/strategy/registry.js +14 -0
- package/dist/sim/strategy/registry.js.map +1 -0
- package/dist/sim/strategy/scripted.d.ts +7 -0
- package/dist/sim/strategy/scripted.js +55 -0
- package/dist/sim/strategy/scripted.js.map +1 -0
- package/dist/sim/strategy/stability.d.ts +45 -0
- package/dist/sim/strategy/stability.js +117 -0
- package/dist/sim/strategy/stability.js.map +1 -0
- package/dist/sim/strategy/types.d.ts +22 -0
- package/dist/sim/strategy/types.js +2 -0
- package/dist/sim/strategy/types.js.map +1 -0
- package/dist/sim/timeBoundary.d.ts +55 -0
- package/dist/sim/timeBoundary.js +96 -0
- package/dist/sim/timeBoundary.js.map +1 -0
- package/dist/sim/types.d.ts +272 -0
- package/dist/sim/types.js +18 -0
- package/dist/sim/types.js.map +1 -0
- package/dist/utils/deepClone.d.ts +7 -0
- package/dist/utils/deepClone.js +69 -0
- package/dist/utils/deepClone.js.map +1 -0
- package/package.json +58 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 imjlk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,106 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @idlekit/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Simulation and analysis primitives for idle game economy design.
|
|
4
|
+
It compiles scenarios, executes runs, and evaluates long-horizon KPIs and design-facing metrics.
|
|
5
|
+
Official support in v1: Bun `>=1.4.2` only. Node.js and browser runtimes are not part of the v1 compatibility contract.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @idlekit/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Bun `>=1.4.2`.
|
|
12
|
+
|
|
13
|
+
Use this package when you need:
|
|
14
|
+
|
|
15
|
+
- scenario validation / compilation
|
|
16
|
+
- simulation loop and `stepOnce`
|
|
17
|
+
- built-in strategies and tuning primitives
|
|
18
|
+
- growth, milestone, session-pattern, and Monte Carlo analysis
|
|
19
|
+
|
|
20
|
+
## Quick example
|
|
21
|
+
|
|
22
|
+
<!-- snippet: snippets/readme/core-quick-example.ts -->
|
|
23
|
+
```ts
|
|
24
|
+
import {
|
|
25
|
+
analyzeGrowth,
|
|
26
|
+
compileScenario,
|
|
27
|
+
createModelRegistry,
|
|
28
|
+
createNumberEngine,
|
|
29
|
+
defineModelFactory,
|
|
30
|
+
runScenario,
|
|
31
|
+
validateScenarioV1,
|
|
32
|
+
} from "@idlekit/core";
|
|
33
|
+
|
|
34
|
+
type Vars = { owned: number };
|
|
35
|
+
|
|
36
|
+
const linearFactory = defineModelFactory<number, "COIN", Vars>({
|
|
37
|
+
id: "linear",
|
|
38
|
+
version: 1,
|
|
39
|
+
create() {
|
|
40
|
+
return {
|
|
41
|
+
id: "linear",
|
|
42
|
+
version: 1,
|
|
43
|
+
income(ctx, state) {
|
|
44
|
+
return {
|
|
45
|
+
unit: ctx.unit,
|
|
46
|
+
amount: ctx.E.add(1, Number(state.vars.owned ?? 0)),
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
actions() {
|
|
50
|
+
return [];
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const registry = createModelRegistry([linearFactory]);
|
|
57
|
+
|
|
58
|
+
const scenario = {
|
|
59
|
+
schemaVersion: 1,
|
|
60
|
+
unit: { code: "COIN" },
|
|
61
|
+
policy: { mode: "drop" },
|
|
62
|
+
model: { id: "linear", version: 1 },
|
|
63
|
+
initial: {
|
|
64
|
+
wallet: { unit: "COIN", amount: "0" },
|
|
65
|
+
vars: { owned: 0 },
|
|
66
|
+
},
|
|
67
|
+
clock: { stepSec: 1, durationSec: 60 },
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const validated = validateScenarioV1(scenario, registry);
|
|
71
|
+
if (!validated.ok || !validated.scenario) {
|
|
72
|
+
throw new Error(`scenario should validate: ${JSON.stringify(validated.issues)}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const E = createNumberEngine();
|
|
76
|
+
const compiled = compileScenario({
|
|
77
|
+
E,
|
|
78
|
+
scenario: validated.scenario,
|
|
79
|
+
registry,
|
|
80
|
+
});
|
|
81
|
+
const run = runScenario(compiled);
|
|
82
|
+
const growth = analyzeGrowth({ run, series: "money", windowSec: 10 });
|
|
83
|
+
|
|
84
|
+
console.log(
|
|
85
|
+
JSON.stringify({
|
|
86
|
+
endMoney: E.toString(run.end.wallet.money.amount),
|
|
87
|
+
growthSlopePerHourLog10: growth.slopePerHourLog10,
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Runtime
|
|
93
|
+
|
|
94
|
+
For the duration of an in-memory `runScenario` or `applyOfflineSeconds` result, import `runElapsedSec` from `@idlekit/core` and read `runElapsedSec(run)`. It uses `run.stop.elapsedSec`, the sum of tick seconds. `state.t` is the absolute reward timestamp; at a large starting timestamp, `run.end.t - run.start.t` can round differently. For example, ten 0.1-second ticks starting at `1e15` simulate about one second while the timestamps differ by 1.25 seconds. Results without a stop record fall back to that timestamp difference. A step-budget stop can shorten an individual run before the requested duration; check `run.stop?.reason` or use `assertHorizonReached(run, label)` when the full horizon is required.
|
|
95
|
+
|
|
96
|
+
For `simulateSessionPattern`, read `summary.elapsedSec` for wall time, `summary.activeSec` for active tick seconds, and `summary.offlineCreditedSec` for offline reward tick seconds. The aggregate `session.run` has no per-run stop record, so `runElapsedSec(session.run)` uses the timestamp fallback. `summary.rewardSec` is also a reward timestamp difference; use the active and offline credited totals when you need simulated tick seconds.
|
|
97
|
+
|
|
98
|
+
`@idlekit/core` is maintained as a Bun-first ESM package.
|
|
99
|
+
|
|
100
|
+
## Documentation
|
|
101
|
+
|
|
102
|
+
- Repository: [github.com/imjlk/idlekit](https://github.com/imjlk/idlekit)
|
|
103
|
+
- Product roadmap: [docs/roadmap.md](https://github.com/imjlk/idlekit/blob/main/docs/roadmap.md)
|
|
104
|
+
- Scenario guide: [docs/scenario-and-tuning.md](https://github.com/imjlk/idlekit/blob/main/docs/scenario-and-tuning.md)
|
|
105
|
+
- Canonical worked example: [examples/tutorials/14-orbital-foundry-v1.json](https://github.com/imjlk/idlekit/blob/main/examples/tutorials/14-orbital-foundry-v1.json)
|
|
106
|
+
- Adapter pattern example: [examples/adapter-pattern](https://github.com/imjlk/idlekit/tree/main/examples/adapter-pattern)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BREAK_ETERNITY_EXPERIMENTAL_MESSAGE, breakEternityEngine, createBreakEternityEngine, } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakEternity.js","sourceRoot":"","sources":["../../src/engine/breakEternity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mCAAmC,EACnC,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Decimal, breakInfinityEngine, createBreakInfinityEngine, createNumberEngine, type BreakInfinityEngineOptions, type NumberEngineOptions, } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakInfinity.js","sourceRoot":"","sources":["../../src/engine/breakInfinity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,GAGnB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { Engine } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export * from "./engine/types";
|
|
2
|
+
export * from "./engine/breakInfinity";
|
|
3
|
+
export * from "./engine/breakEternity";
|
|
4
|
+
export * from "./money/types";
|
|
5
|
+
export * from "./policy/types";
|
|
6
|
+
export * from "./policy/emitter";
|
|
7
|
+
export * from "./policy/tickMoney";
|
|
8
|
+
export * from "./notation/suffixer";
|
|
9
|
+
export * from "./notation/formatMoney";
|
|
10
|
+
export * from "./notation/parseMoney";
|
|
11
|
+
export * from "./notation/visibilityTracker";
|
|
12
|
+
export * from "./serde/moneyState";
|
|
13
|
+
export * from "./serde/simState";
|
|
14
|
+
export * from "./scenario/types";
|
|
15
|
+
export * from "./scenario/registry";
|
|
16
|
+
export * from "./scenario/validate";
|
|
17
|
+
export * from "./scenario/concreteValidator";
|
|
18
|
+
export * from "./scenario/migrate";
|
|
19
|
+
export * from "./scenario/compile";
|
|
20
|
+
export * from "./sim/types";
|
|
21
|
+
export * from "./sim/simulator";
|
|
22
|
+
export * from "./sim/step";
|
|
23
|
+
export * from "./sim/stepTypes";
|
|
24
|
+
export * from "./sim/offline";
|
|
25
|
+
export * from "./sim/random";
|
|
26
|
+
export * from "./sim/session";
|
|
27
|
+
export * from "./sim/monteCarlo";
|
|
28
|
+
export * from "./sim/runFactory";
|
|
29
|
+
export * from "./sim/constraints";
|
|
30
|
+
export * from "./sim/observation";
|
|
31
|
+
export * from "./sim/strategy/types";
|
|
32
|
+
export * from "./sim/strategy/contracts";
|
|
33
|
+
export * from "./sim/strategy/stability";
|
|
34
|
+
export * from "./sim/strategy/scripted";
|
|
35
|
+
export * from "./sim/strategy/greedy";
|
|
36
|
+
export * from "./sim/strategy/planner";
|
|
37
|
+
export * from "./sim/strategy/registry";
|
|
38
|
+
export * from "./sim/strategy/params";
|
|
39
|
+
export * from "./sim/strategy/builtins";
|
|
40
|
+
export * from "./sim/strategy/opt/tuneSpec";
|
|
41
|
+
export * from "./sim/strategy/opt/validate";
|
|
42
|
+
export * from "./sim/strategy/opt/objective";
|
|
43
|
+
export * from "./sim/strategy/opt/registry";
|
|
44
|
+
export * from "./sim/strategy/opt/objectives/params";
|
|
45
|
+
export * from "./sim/strategy/opt/objectives/builtins";
|
|
46
|
+
export * from "./sim/strategy/opt/tuner";
|
|
47
|
+
export * from "./sim/strategy/opt/tuners/randomSearch";
|
|
48
|
+
export * from "./sim/strategy/opt/runner";
|
|
49
|
+
export * from "./sim/analysis/eta";
|
|
50
|
+
export * from "./sim/analysis/prestigeCycle";
|
|
51
|
+
export * from "./sim/analysis/growth";
|
|
52
|
+
export * from "./sim/analysis/milestones";
|
|
53
|
+
export * from "./sim/analysis/ux";
|
|
54
|
+
export * from "./report/timeline";
|
|
55
|
+
export * from "./report/compare";
|
|
56
|
+
export * from "./utils/deepClone";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export * from "./engine/types";
|
|
2
|
+
export * from "./engine/breakInfinity";
|
|
3
|
+
export * from "./engine/breakEternity";
|
|
4
|
+
export * from "./money/types";
|
|
5
|
+
export * from "./policy/types";
|
|
6
|
+
export * from "./policy/emitter";
|
|
7
|
+
export * from "./policy/tickMoney";
|
|
8
|
+
export * from "./notation/suffixer";
|
|
9
|
+
export * from "./notation/formatMoney";
|
|
10
|
+
export * from "./notation/parseMoney";
|
|
11
|
+
export * from "./notation/visibilityTracker";
|
|
12
|
+
export * from "./serde/moneyState";
|
|
13
|
+
export * from "./serde/simState";
|
|
14
|
+
export * from "./scenario/types";
|
|
15
|
+
export * from "./scenario/registry";
|
|
16
|
+
export * from "./scenario/validate";
|
|
17
|
+
export * from "./scenario/concreteValidator";
|
|
18
|
+
export * from "./scenario/migrate";
|
|
19
|
+
export * from "./scenario/compile";
|
|
20
|
+
export * from "./sim/types";
|
|
21
|
+
export * from "./sim/simulator";
|
|
22
|
+
export * from "./sim/step";
|
|
23
|
+
export * from "./sim/stepTypes";
|
|
24
|
+
export * from "./sim/offline";
|
|
25
|
+
export * from "./sim/random";
|
|
26
|
+
export * from "./sim/session";
|
|
27
|
+
export * from "./sim/monteCarlo";
|
|
28
|
+
export * from "./sim/runFactory";
|
|
29
|
+
export * from "./sim/constraints";
|
|
30
|
+
export * from "./sim/observation";
|
|
31
|
+
export * from "./sim/strategy/types";
|
|
32
|
+
export * from "./sim/strategy/contracts";
|
|
33
|
+
export * from "./sim/strategy/stability";
|
|
34
|
+
export * from "./sim/strategy/scripted";
|
|
35
|
+
export * from "./sim/strategy/greedy";
|
|
36
|
+
export * from "./sim/strategy/planner";
|
|
37
|
+
export * from "./sim/strategy/registry";
|
|
38
|
+
export * from "./sim/strategy/params";
|
|
39
|
+
export * from "./sim/strategy/builtins";
|
|
40
|
+
export * from "./sim/strategy/opt/tuneSpec";
|
|
41
|
+
export * from "./sim/strategy/opt/validate";
|
|
42
|
+
export * from "./sim/strategy/opt/objective";
|
|
43
|
+
export * from "./sim/strategy/opt/registry";
|
|
44
|
+
export * from "./sim/strategy/opt/objectives/params";
|
|
45
|
+
export * from "./sim/strategy/opt/objectives/builtins";
|
|
46
|
+
export * from "./sim/strategy/opt/tuner";
|
|
47
|
+
export * from "./sim/strategy/opt/tuners/randomSearch";
|
|
48
|
+
export * from "./sim/strategy/opt/runner";
|
|
49
|
+
export * from "./sim/analysis/eta";
|
|
50
|
+
export * from "./sim/analysis/prestigeCycle";
|
|
51
|
+
export * from "./sim/analysis/growth";
|
|
52
|
+
export * from "./sim/analysis/milestones";
|
|
53
|
+
export * from "./sim/analysis/ux";
|
|
54
|
+
export * from "./report/timeline";
|
|
55
|
+
export * from "./report/compare";
|
|
56
|
+
export * from "./utils/deepClone";
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,eAAe,CAAC;AAE9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAE7C,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AAEjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAElC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sCAAsC,CAAC;AACrD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0BAA0B,CAAC;AACzC,cAAc,wCAAwC,CAAC;AACvD,cAAc,2BAA2B,CAAC;AAE1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAElC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAEjC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { Money, MoneyState, Unit } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/money/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { formatMoney, type FormatMoneyOptions } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatMoney.js","sourceRoot":"","sources":["../../src/notation/formatMoney.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA2B,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { parseMoney, type ParseMoneyOptions } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseMoney.js","sourceRoot":"","sources":["../../src/notation/parseMoney.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA0B,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { alphaInfiniteIndex, alphaInfiniteSuffix, type Suffixer } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suffixer.js","sourceRoot":"","sources":["../../src/notation/suffixer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAiB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { VisibilityTracker, type VisibilityChange } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visibilityTracker.js","sourceRoot":"","sources":["../../src/notation/visibilityTracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAyB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { composeEmitters, onType, type Emitter } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/policy/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,EAAgB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { tickMoney } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tickMoney.js","sourceRoot":"","sources":["../../src/policy/tickMoney.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { CoreOptions, MoneyEvent, TickFactCounts, TickPolicy, TickResult, TickStatus } from "@idlekit/money";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/policy/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ScenarioV1 } from "../scenario/types";
|
|
2
|
+
export type CompareMetric = "endMoney" | "endNetWorth" | "etaToTargetWorth" | "droppedRate" | "timeToMilestone" | "visibleChangesPerMinute" | "maxNoRewardGapSec";
|
|
3
|
+
export type MeasuredCompareMetrics = Readonly<Partial<Record<CompareMetric, number>>>;
|
|
4
|
+
export type MeasuredDecision = "a" | "b" | "tie";
|
|
5
|
+
export declare function compareScenarios(args: {
|
|
6
|
+
a: ScenarioV1;
|
|
7
|
+
b: ScenarioV1;
|
|
8
|
+
metric: CompareMetric;
|
|
9
|
+
measured?: Readonly<{
|
|
10
|
+
a?: MeasuredCompareMetrics;
|
|
11
|
+
b?: MeasuredCompareMetrics;
|
|
12
|
+
}>;
|
|
13
|
+
measuredDecision?: (metric: CompareMetric) => MeasuredDecision | undefined;
|
|
14
|
+
}): Readonly<{
|
|
15
|
+
better: "a" | "b" | "tie";
|
|
16
|
+
detail: unknown;
|
|
17
|
+
}>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
function safeNum(input) {
|
|
2
|
+
if (typeof input === "number")
|
|
3
|
+
return input;
|
|
4
|
+
if (typeof input === "string") {
|
|
5
|
+
const n = Number(input);
|
|
6
|
+
if (Number.isFinite(n))
|
|
7
|
+
return n;
|
|
8
|
+
const m = /^\s*([+-]?\d+(?:\.\d+)?)e([+-]?\d+)\s*$/i.exec(input);
|
|
9
|
+
if (m) {
|
|
10
|
+
const mantissa = Number(m[1]);
|
|
11
|
+
const exp = Number(m[2]);
|
|
12
|
+
if (mantissa === 0)
|
|
13
|
+
return 0;
|
|
14
|
+
if (Number.isFinite(mantissa) && Number.isFinite(exp)) {
|
|
15
|
+
return Math.log10(Math.abs(mantissa)) + exp;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return Number.NaN;
|
|
20
|
+
}
|
|
21
|
+
function score(s, metric) {
|
|
22
|
+
switch (metric) {
|
|
23
|
+
case "endMoney":
|
|
24
|
+
return safeNum(s.initial.wallet.amount);
|
|
25
|
+
case "endNetWorth":
|
|
26
|
+
return safeNum(s.initial.maxMoneyEver ?? s.initial.wallet.amount);
|
|
27
|
+
case "droppedRate":
|
|
28
|
+
return -(s.policy.maxLogGap ?? 0);
|
|
29
|
+
case "etaToTargetWorth":
|
|
30
|
+
return -(s.clock.durationSec ?? Number.MAX_SAFE_INTEGER);
|
|
31
|
+
case "timeToMilestone":
|
|
32
|
+
case "visibleChangesPerMinute":
|
|
33
|
+
case "maxNoRewardGapSec":
|
|
34
|
+
return 0;
|
|
35
|
+
default:
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function measuredScore(measured, metric) {
|
|
40
|
+
if (!measured)
|
|
41
|
+
return undefined;
|
|
42
|
+
const v = measured[metric];
|
|
43
|
+
return typeof v === "number" ? v : undefined;
|
|
44
|
+
}
|
|
45
|
+
export function compareScenarios(args) {
|
|
46
|
+
const decision = args.measuredDecision?.(args.metric);
|
|
47
|
+
if (decision) {
|
|
48
|
+
const measuredA = measuredScore(args.measured?.a, args.metric);
|
|
49
|
+
const measuredB = measuredScore(args.measured?.b, args.metric);
|
|
50
|
+
return {
|
|
51
|
+
better: decision,
|
|
52
|
+
detail: {
|
|
53
|
+
aScore: measuredA,
|
|
54
|
+
bScore: measuredB,
|
|
55
|
+
metric: args.metric,
|
|
56
|
+
source: "measured",
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const measuredA = measuredScore(args.measured?.a, args.metric);
|
|
61
|
+
const measuredB = measuredScore(args.measured?.b, args.metric);
|
|
62
|
+
const useMeasured = measuredA !== undefined && measuredB !== undefined;
|
|
63
|
+
const aScore = useMeasured ? measuredA : score(args.a, args.metric);
|
|
64
|
+
const bScore = useMeasured ? measuredB : score(args.b, args.metric);
|
|
65
|
+
const higherBetter = args.metric === "endMoney" ||
|
|
66
|
+
args.metric === "endNetWorth" ||
|
|
67
|
+
args.metric === "visibleChangesPerMinute";
|
|
68
|
+
if (aScore === bScore) {
|
|
69
|
+
return {
|
|
70
|
+
better: "tie",
|
|
71
|
+
detail: {
|
|
72
|
+
aScore,
|
|
73
|
+
bScore,
|
|
74
|
+
metric: args.metric,
|
|
75
|
+
source: useMeasured ? "measured" : "static",
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
better: higherBetter
|
|
81
|
+
? (aScore > bScore ? "a" : "b")
|
|
82
|
+
: (aScore < bScore ? "a" : "b"),
|
|
83
|
+
detail: {
|
|
84
|
+
aScore,
|
|
85
|
+
bScore,
|
|
86
|
+
metric: args.metric,
|
|
87
|
+
source: useMeasured ? "measured" : "static",
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=compare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/report/compare.ts"],"names":[],"mappings":"AAcA,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAEjC,MAAM,CAAC,GAAG,0CAA0C,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjE,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,QAAQ,KAAK,CAAC;gBAAE,OAAO,CAAC,CAAC;YAC7B,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,GAAG,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC;AACpB,CAAC;AAED,SAAS,KAAK,CAAC,CAAa,EAAE,MAAqB;IACjD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,UAAU;YACb,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,KAAK,aAAa;YAChB,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpE,KAAK,aAAa;YAChB,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;QACpC,KAAK,kBAAkB;YACrB,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC3D,KAAK,iBAAiB,CAAC;QACvB,KAAK,yBAAyB,CAAC;QAC/B,KAAK,mBAAmB;YACtB,OAAO,CAAC,CAAC;QACX;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,QAA4C,EAC5C,MAAqB;IAErB,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAShC;IACC,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/D,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE;gBACN,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,MAAM,EAAE,UAAU;aACnB;SACF,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,CAAC;IAEvE,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEpE,MAAM,YAAY,GAChB,IAAI,CAAC,MAAM,KAAK,UAAU;QAC1B,IAAI,CAAC,MAAM,KAAK,aAAa;QAC7B,IAAI,CAAC,MAAM,KAAK,yBAAyB,CAAC;IAE5C,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE;gBACN,MAAM;gBACN,MAAM;gBACN,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;aAC5C;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,YAAY;YAClB,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/B,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACjC,MAAM,EAAE;YACN,MAAM;YACN,MAAM;YACN,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;SAC5C;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RunResult } from "../sim/types";
|
|
2
|
+
export type TimelinePoint = Readonly<{
|
|
3
|
+
t: number;
|
|
4
|
+
money: string;
|
|
5
|
+
netWorth?: string;
|
|
6
|
+
prestigePoints?: string;
|
|
7
|
+
notes?: string[];
|
|
8
|
+
}>;
|
|
9
|
+
export declare function buildTimeline(args: {
|
|
10
|
+
run: RunResult<any, any, any>;
|
|
11
|
+
checkpointsSec: number[];
|
|
12
|
+
formatMoney: (amount: any) => string;
|
|
13
|
+
formatNetWorth?: (amount: any) => string;
|
|
14
|
+
/** Value the selected snapshot's holdings; without a valuation, use its wallet. */
|
|
15
|
+
getNetWorth?: (state: RunResult<any, any, any>["end"]) => any;
|
|
16
|
+
}): TimelinePoint[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
function nearestAt(trace, t) {
|
|
2
|
+
if (trace.length === 0) {
|
|
3
|
+
throw new Error("trace is empty");
|
|
4
|
+
}
|
|
5
|
+
const first = trace[0];
|
|
6
|
+
if (!first) {
|
|
7
|
+
throw new Error("trace is empty");
|
|
8
|
+
}
|
|
9
|
+
let best = first;
|
|
10
|
+
let bestGap = Math.abs(best.t - t);
|
|
11
|
+
for (const row of trace) {
|
|
12
|
+
const gap = Math.abs(row.t - t);
|
|
13
|
+
if (gap < bestGap) {
|
|
14
|
+
best = row;
|
|
15
|
+
bestGap = gap;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return best;
|
|
19
|
+
}
|
|
20
|
+
export function buildTimeline(args) {
|
|
21
|
+
const trace = args.run.trace && args.run.trace.length > 0 ? args.run.trace : [args.run.start, args.run.end];
|
|
22
|
+
return args.checkpointsSec.map((t) => {
|
|
23
|
+
const s = nearestAt(trace, t);
|
|
24
|
+
const notes = [];
|
|
25
|
+
if (s.t !== t) {
|
|
26
|
+
notes.push(`nearestTrace=${s.t}`);
|
|
27
|
+
}
|
|
28
|
+
let netWorth;
|
|
29
|
+
if (args.formatNetWorth) {
|
|
30
|
+
const amount = args.getNetWorth ? args.getNetWorth(s) : s.wallet.money.amount;
|
|
31
|
+
netWorth = args.formatNetWorth(amount);
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
t,
|
|
35
|
+
money: args.formatMoney(s.wallet.money.amount),
|
|
36
|
+
netWorth,
|
|
37
|
+
prestigePoints: String(s.prestige.points),
|
|
38
|
+
notes: notes.length > 0 ? notes : undefined,
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/report/timeline.ts"],"names":[],"mappings":"AAUA,SAAS,SAAS,CAA0B,KAAmB,EAAE,CAAS;IACxE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAEnC,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChC,IAAI,GAAG,GAAG,OAAO,EAAE,CAAC;YAClB,IAAI,GAAG,GAAG,CAAC;YACX,OAAO,GAAG,GAAG,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAO7B;IACC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE5G,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACnC,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,QAA4B,CAAC;QACjC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;YAC9E,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAED,OAAO;YACL,CAAC;YACD,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;YAC9C,QAAQ;YACR,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAa,CAAC;YAChD,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;SAC5C,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Engine } from "../engine/types";
|
|
2
|
+
import type { Unit } from "../money/types";
|
|
3
|
+
import type { CompiledScenario } from "../sim/types";
|
|
4
|
+
import type { StrategyRegistry } from "../sim/strategy/registry";
|
|
5
|
+
import type { ModelRegistry } from "./registry";
|
|
6
|
+
import type { ScenarioV1 } from "./types";
|
|
7
|
+
export type CompileOptions = Readonly<{
|
|
8
|
+
allowSuffixNotation?: boolean;
|
|
9
|
+
allowUnsafeUntilExpr?: boolean;
|
|
10
|
+
}>;
|
|
11
|
+
export type StrategyParamsMode = "legacy-raw" | "validated";
|
|
12
|
+
/**
|
|
13
|
+
* Internal `StandardSchema` adapter. This is not the external Standard Schema package.
|
|
14
|
+
* `legacy-raw` checks the schema and still passes the caller object to `create`.
|
|
15
|
+
* `validated` passes `result.value`, which may be coerced or defaulted.
|
|
16
|
+
*
|
|
17
|
+
* @evidence docs/requirements/active/cli-resolved-run.md#req-pr07-resolved-run Amount comparisons use parseMoney. Strategy params stay legacy-raw unless validated is requested.
|
|
18
|
+
* @evidenceReview docs/requirements/active/cli-resolved-run.md#req-pr07-resolved-run #01b9284 Re-read the section: legacy-raw keeps the caller object, and an amount path does not use Number(rawRight).
|
|
19
|
+
*/
|
|
20
|
+
export declare function strategyCreateParams(args: {
|
|
21
|
+
raw: unknown;
|
|
22
|
+
schema?: {
|
|
23
|
+
"~standard": {
|
|
24
|
+
validate: (input: unknown) => unknown;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
mode?: StrategyParamsMode;
|
|
28
|
+
}): Readonly<{
|
|
29
|
+
mode: StrategyParamsMode;
|
|
30
|
+
params: unknown;
|
|
31
|
+
}>;
|
|
32
|
+
/** Check model params like `strategyCreateParams` in `legacy-raw` mode. The caller object is returned. */
|
|
33
|
+
export declare function modelCreateParams(args: {
|
|
34
|
+
raw: unknown;
|
|
35
|
+
schema?: {
|
|
36
|
+
"~standard": {
|
|
37
|
+
validate: (input: unknown) => unknown;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}): unknown;
|
|
41
|
+
export declare function compileScenario<N, U extends string, Vars>(args: {
|
|
42
|
+
E: Engine<N>;
|
|
43
|
+
scenario: ScenarioV1;
|
|
44
|
+
registry: ModelRegistry;
|
|
45
|
+
strategyRegistry?: StrategyRegistry;
|
|
46
|
+
unitFactory?: (code: string) => Unit<U>;
|
|
47
|
+
opts?: CompileOptions;
|
|
48
|
+
}): CompiledScenario<N, U, Vars>;
|