@reicek/neataptic-ts 0.1.26 → 0.1.27
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/.github/agents/boundary-mapper.agent.md +13 -8
- package/.github/agents/docs-scout.agent.md +14 -9
- package/.github/agents/plan-scout.agent.md +11 -6
- package/.github/agents/solid-split.agent.md +33 -17
- package/.github/copilot-instructions.md +100 -88
- package/.github/skills/educational-docs/SKILL.md +90 -40
- package/.github/skills/educational-docs/assets/mermaid-diagram-playbook.md +141 -141
- package/.github/skills/educational-docs/assets/visual-style-guide.md +1 -1
- package/.github/skills/plan-alignment/SKILL.md +1 -1
- package/.github/skills/solid-split/SKILL.md +54 -35
- package/.github/skills/solid-split/assets/docs-checklist.md +1 -1
- package/.github/skills/solid-split/assets/split-plan-template.md +41 -12
- package/.github/skills/solid-split/assets/split-workflow-checklist.md +4 -1
- package/.github/skills/test-fix-workflow/SKILL.md +12 -7
- package/.github/skills/trace-analyzer-extension/SKILL.md +1 -1
- package/.github/skills/trace-analyzer-extension/assets/extension-checklist.md +1 -1
- package/.github/skills/trace-analyzer-extension/references/analyzer-extension-workflow.md +1 -1
- package/.github/skills/trace-audit-reporting/SKILL.md +1 -1
- package/.github/skills/trace-audit-reporting/assets/performance-report-template.md +1 -1
- package/.github/skills/trace-audit-reporting/references/trace-analysis-workflow.md +1 -1
- package/.github/skills/tracker-handoff/SKILL.md +53 -5
- package/package.json +1 -1
- package/plans/Flappy_Bird_Folder_Documentation_Pass.logs.md +42 -0
- package/plans/Flappy_Bird_Folder_Documentation_Pass.md +22 -104
- package/plans/README.md +6 -2
- package/plans/Roadmap.md +35 -31
- package/plans/analyze-trace-solid-split.logs.md +35 -0
- package/plans/analyze-trace-solid-split.plans.md +21 -52
- package/plans/architecture-solid-split.logs.md +44 -0
- package/plans/architecture-solid-split.plans.md +20 -653
- package/plans/asciiMaze-typescript-repair.logs.md +35 -0
- package/plans/asciiMaze-typescript-repair.plans.md +30 -36
- package/plans/generate-docs-solid-split.logs.md +36 -0
- package/plans/generate-docs-solid-split.plans.md +21 -73
- package/plans/methods-docs.logs.md +37 -0
- package/plans/methods-docs.plans.md +22 -183
- package/plans/methods-solid-split.logs.md +41 -0
- package/plans/methods-solid-split.plans.md +23 -65
- package/plans/neat-docs.logs.md +38 -0
- package/plans/neat-docs.plans.md +21 -63
- package/plans/neat-test-surface-repair.logs.md +38 -0
- package/plans/neat-test-surface-repair.plans.md +24 -24
- package/plans/readme-first-section-pass.logs.md +63 -0
- package/plans/readme-first-section-pass.plans.md +42 -0
- package/plans/render-docs-html-solid-split.logs.md +36 -0
- package/plans/render-docs-html-solid-split.plans.md +20 -54
- package/plans/src-no-explicit-any-cleanup.logs.md +39 -0
- package/plans/src-no-explicit-any-cleanup.plans.md +23 -161
- package/plans/utils-docs.logs.md +37 -0
- package/plans/utils-docs.plans.md +20 -35
- package/src/README.md +88 -22
- package/src/architecture/README.md +94 -17
- package/src/architecture/activationArrayPool/README.md +53 -0
- package/src/architecture/activationArrayPool/activationArrayPool.ts +53 -0
- package/src/architecture/layer/README.md +94 -5
- package/src/architecture/layer/layer.ts +94 -5
- package/src/architecture/network/README.md +85 -14
- package/src/architecture/network/activate/README.md +301 -213
- package/src/architecture/network/activate/docs.order.json +9 -0
- package/src/architecture/network/activate/network.activate.utils.ts +90 -0
- package/src/architecture/network/connect/README.md +80 -3
- package/src/architecture/network/connect/docs.order.json +9 -0
- package/src/architecture/network/connect/network.connect.utils.ts +79 -0
- package/src/architecture/network/deterministic/README.md +96 -12
- package/src/architecture/network/deterministic/docs.order.json +10 -0
- package/src/architecture/network/deterministic/network.deterministic.utils.ts +90 -0
- package/src/architecture/network/evolve/README.md +286 -228
- package/src/architecture/network/evolve/docs.order.json +11 -0
- package/src/architecture/network/evolve/network.evolve.utils.ts +59 -0
- package/src/architecture/network/gating/README.md +58 -16
- package/src/architecture/network/gating/docs.order.json +9 -0
- package/src/architecture/network/gating/network.gating.utils.ts +43 -0
- package/src/architecture/network/genetic/README.md +75 -36
- package/src/architecture/network/genetic/docs.order.json +10 -0
- package/src/architecture/network/genetic/network.genetic.utils.ts +53 -17
- package/src/architecture/network/network.ts +91 -46
- package/src/architecture/network/standalone/README.md +309 -285
- package/src/architecture/network/standalone/docs.order.json +13 -0
- package/src/architecture/network/standalone/network.standalone.utils.ts +51 -28
- package/src/architecture/network.ts +94 -17
- package/src/architecture/nodePool/README.md +53 -0
- package/src/architecture/nodePool/nodePool.ts +53 -0
- package/src/methods/README.md +80 -34
- package/src/methods/methods.ts +80 -34
- package/src/methods/mutation/README.md +39 -93
- package/src/methods/mutation/mutation.ts +58 -0
- package/src/multithreading/README.md +114 -14
- package/src/multithreading/docs.order.json +5 -0
- package/src/multithreading/multi.ts +103 -7
- package/src/multithreading/types.ts +6 -1
- package/src/multithreading/workers/README.md +72 -2
- package/src/multithreading/workers/browser/README.md +39 -0
- package/src/multithreading/workers/browser/testworker.ts +40 -0
- package/src/multithreading/workers/node/README.md +50 -11
- package/src/multithreading/workers/node/docs.order.json +4 -0
- package/src/multithreading/workers/node/testworker.ts +43 -3
- package/src/multithreading/workers/workers.ts +36 -1
- package/src/neat/README.md +230 -152
- package/src/neat/adaptive/core/README.md +99 -42
- package/src/neat/adaptive/core/adaptive.core.ts +71 -14
- package/src/neat/adaptive/core/docs.order.json +8 -0
- package/src/neat/docs.order.json +9 -0
- package/src/neat/lineage/README.md +118 -16
- package/src/neat/lineage/lineage.ts +115 -13
- package/src/neat/neat.defaults.constants.ts +91 -13
- package/src/neat.ts +86 -20
- package/src/utils/README.md +71 -21
- package/src/utils/memory.ts +69 -19
- package/test/examples/asciiMaze/browser-entry/README.md +81 -8
- package/test/examples/asciiMaze/browser-entry/browser-entry.ts +81 -8
- package/test/examples/asciiMaze/dashboardManager/README.md +68 -4
- package/test/examples/asciiMaze/dashboardManager/dashboardManager.ts +68 -4
- package/test/examples/asciiMaze/evolutionEngine/README.md +1259 -1174
- package/test/examples/asciiMaze/evolutionEngine/docs.order.json +10 -0
- package/test/examples/asciiMaze/evolutionEngine/evolutionEngine.types.ts +87 -0
- package/test/examples/asciiMaze/mazeMovement/README.md +81 -4
- package/test/examples/asciiMaze/mazeMovement/mazeMovement.ts +81 -4
- package/test/examples/flappy_bird/browser-entry/README.md +64 -21
- package/test/examples/flappy_bird/browser-entry/browser-entry.ts +64 -21
- package/test/examples/flappy_bird/flappy-evolution-worker/README.md +98 -10
- package/test/examples/flappy_bird/flappy-evolution-worker/flappy-evolution-worker.ts +98 -10
- package/test/examples/flappy_bird/simulation-shared/README.md +88 -4
- package/test/examples/flappy_bird/simulation-shared/simulation-shared.types.ts +88 -4
|
@@ -1,23 +1,101 @@
|
|
|
1
1
|
import type { NeatConstructorDefaults } from './init/neat.init';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Root chapter map and public default knobs for the internal `src/neat` controller surface.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* `src/neat.ts` is the public control desk. `src/neat/` is the machine room
|
|
7
|
+
* behind it. This folder owns the controller chapters that make a run real:
|
|
8
|
+
* initialization, evaluation, evolution, mutation, speciation, telemetry,
|
|
9
|
+
* persistence, and the shared bookkeeping that keeps experiments deterministic
|
|
10
|
+
* instead of magical. Promoting the defaults file to the chapter opening is
|
|
11
|
+
* intentional because default knobs are the quickest way to make the
|
|
12
|
+
* controller's personality legible before a reader dives into implementation
|
|
13
|
+
* detail.
|
|
10
14
|
*
|
|
11
|
-
* The
|
|
15
|
+
* The most helpful reading move is to split the folder into four working
|
|
16
|
+
* lanes. `init/`, `evaluate/`, and `evolve/` explain how a population is
|
|
17
|
+
* created, scored, and replaced. `mutation/`, `selection/`, and `speciation/`
|
|
18
|
+
* explain how search pressure and diversity are managed. `telemetry/`,
|
|
19
|
+
* `lineage/`, `diversity/`, and `multiobjective/` explain how the run becomes
|
|
20
|
+
* inspectable. `export/`, `rng/`, `cache/`, `maintenance/`, and `pruning/`
|
|
21
|
+
* explain how the controller stays reproducible and tractable as experiments
|
|
22
|
+
* get larger.
|
|
12
23
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
24
|
+
* The flat root files are small bridges rather than the whole story.
|
|
25
|
+
* `neat.defaults.constants.ts` and `neat.types.ts` keep the public constructor
|
|
26
|
+
* and option bag readable. `neat.lineage.ts` and `neat.constants.ts` keep
|
|
27
|
+
* small shared logic close to the root when multiple chapters need it. The
|
|
28
|
+
* deeper folders own the heavier policy and runtime details.
|
|
17
29
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
30
|
+
* These defaults matter because they are the baseline promises the controller
|
|
31
|
+
* makes when a caller says "give me an ordinary NEAT run." Population size,
|
|
32
|
+
* mutation tempo, compatibility pressure, structural ceilings, and
|
|
33
|
+
* observability sampling are not random numbers. They are the quiet assumptions
|
|
34
|
+
* that decide whether the controller behaves like a conservative search, an
|
|
35
|
+
* exploratory search, or an unstable one.
|
|
36
|
+
*
|
|
37
|
+
* That design follows the original NEAT intuition: protect structural
|
|
38
|
+
* innovation long enough for it to compete, rather than forcing every new
|
|
39
|
+
* topology to beat established species immediately. See Stanley and
|
|
40
|
+
* Miikkulainen,
|
|
41
|
+
* [Evolving Neural Networks through Augmenting Topologies](https://nn.cs.utexas.edu/?stanley:ec02),
|
|
42
|
+
* for the background behind the compatibility and growth vocabulary that keeps
|
|
43
|
+
* surfacing across this folder.
|
|
44
|
+
*
|
|
45
|
+
* Read this root chapter in three passes. Start with this defaults file and
|
|
46
|
+
* `neat.types.ts` for the public knobs and broad contracts. Continue into
|
|
47
|
+
* `evaluate/`, `evolve/`, and `speciation/` for the live search loop. Finish
|
|
48
|
+
* with `telemetry/`, `lineage/`, `multiobjective/`, `export/`, and `rng/` when
|
|
49
|
+
* you want to inspect, replay, or compare runs rather than only advance them.
|
|
50
|
+
*
|
|
51
|
+
* ```mermaid
|
|
52
|
+
* flowchart TD
|
|
53
|
+
* classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
54
|
+
* classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
55
|
+
*
|
|
56
|
+
* Root["src/neat root"]:::accent --> Loop["init / evaluate / evolve"]:::base
|
|
57
|
+
* Root --> Pressure["mutation / selection / speciation"]:::base
|
|
58
|
+
* Root --> Observe["telemetry / lineage / diversity / multiobjective"]:::base
|
|
59
|
+
* Root --> Replay["export / rng / cache / maintenance / pruning"]:::base
|
|
60
|
+
* Root --> Bridges["root bridges<br/>defaults / types / constants"]:::base
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* ```mermaid
|
|
64
|
+
* flowchart LR
|
|
65
|
+
* classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
66
|
+
* classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
67
|
+
*
|
|
68
|
+
* Defaults[Root defaults]:::accent --> Population[popsize elitism provenance]:::base
|
|
69
|
+
* Defaults --> Variation[mutationRate mutationAmount]:::base
|
|
70
|
+
* Defaults --> Species[compatibility and weight coefficients]:::base
|
|
71
|
+
* Defaults --> Observation[diversity and novelty samples]:::base
|
|
72
|
+
* Population --> Run[Controller behavior]:::base
|
|
73
|
+
* Variation --> Run
|
|
74
|
+
* Species --> Run
|
|
75
|
+
* Observation --> Run
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* Example: build one explicit baseline options bag from the documented root
|
|
79
|
+
* defaults.
|
|
80
|
+
*
|
|
81
|
+
* ```ts
|
|
82
|
+
* const baselineOptions = {
|
|
83
|
+
* popsize: DEFAULT_POPULATION_SIZE,
|
|
84
|
+
* mutationRate: DEFAULT_MUTATION_RATE,
|
|
85
|
+
* compatibilityThreshold: DEFAULT_COMPATIBILITY_THRESHOLD,
|
|
86
|
+
* };
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* Example: keep the observability defaults visible when teaching or
|
|
90
|
+
* benchmarking runs.
|
|
91
|
+
*
|
|
92
|
+
* ```ts
|
|
93
|
+
* const observabilityDefaults = {
|
|
94
|
+
* diversityPairSample: DEFAULT_DIVERSITY_PAIR_SAMPLE,
|
|
95
|
+
* diversityGraphletSample: DEFAULT_DIVERSITY_GRAPHLET_SAMPLE,
|
|
96
|
+
* noveltyK: DEFAULT_NOVELTY_K,
|
|
97
|
+
* };
|
|
98
|
+
* ```
|
|
21
99
|
*/
|
|
22
100
|
|
|
23
101
|
/**
|
package/src/neat.ts
CHANGED
|
@@ -90,34 +90,100 @@ import * as neatTelemetryFacade from './neat/telemetry/facade/telemetry.facade';
|
|
|
90
90
|
/**
|
|
91
91
|
* Root orchestration surface for NeuroEvolution of Augmenting Topologies (NEAT) in NeatapticTS.
|
|
92
92
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
93
|
+
* This root chapter is the public control desk for the library. The
|
|
94
|
+
* architecture surfaces explain what a network graph is. The `src/neat/**`
|
|
95
|
+
* chapters explain how evaluation, reproduction, speciation, telemetry, and
|
|
96
|
+
* persistence work in detail. This file sits between those two layers and
|
|
97
|
+
* answers the first practical reader question: how do I run one evolutionary
|
|
98
|
+
* experiment without learning every subsystem in the same breath?
|
|
99
99
|
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
100
|
+
* That boundary matters because a useful NEAT run is more than "mutate a
|
|
101
|
+
* network." A controller has to keep a population alive, protect enough
|
|
102
|
+
* diversity to avoid early collapse, score genomes fairly, record what
|
|
103
|
+
* happened, and give the caller a deterministic way to pause or resume the
|
|
104
|
+
* search. The root surface is where those responsibilities become one readable
|
|
105
|
+
* workflow instead of a pile of helper calls.
|
|
105
106
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
107
|
+
* One helpful mental model is to read the controller as four shelves. The setup
|
|
108
|
+
* shelf decides population size, defaults, and reproducibility. The search
|
|
109
|
+
* shelf drives `evaluate()`, `evolve()`, and the public mutation hooks. The
|
|
110
|
+
* observability shelf exposes telemetry, lineage, diversity, species, and
|
|
111
|
+
* Pareto views. The persistence shelf turns a live run into replayable state
|
|
112
|
+
* through `toJSON()`, `exportState()`, and RNG snapshots.
|
|
113
|
+
*
|
|
114
|
+
* The chapter also exists to keep the public class orchestration-first after
|
|
115
|
+
* the internal split. `src/neat/**` now owns the heavier policy chapters:
|
|
116
|
+
* `evaluate/` scores genomes, `evolve/` creates the next generation,
|
|
117
|
+
* `speciation/` manages compatibility pressure, `telemetry/` records what the
|
|
118
|
+
* run did, and `export/` plus `rng/` keep experiments reproducible. If you can
|
|
119
|
+
* read the root workflow first, the subchapters become "why does this step
|
|
120
|
+
* work?" reads instead of "where do I even start?" reads.
|
|
121
|
+
*
|
|
122
|
+
* The guiding historical idea comes from Stanley and Miikkulainen's NEAT
|
|
123
|
+
* paper: evolve both weights and topology while protecting innovation long
|
|
124
|
+
* enough for new structures to prove useful. See Stanley and Miikkulainen,
|
|
125
|
+
* [Evolving Neural Networks through Augmenting Topologies](https://nn.cs.utexas.edu/?stanley:ec02),
|
|
126
|
+
* for the compact background behind the controller vocabulary that appears all
|
|
127
|
+
* through this surface.
|
|
128
|
+
*
|
|
129
|
+
* Read this root when you want to answer one of three questions quickly: how to
|
|
130
|
+
* start a run, how to move it forward generation by generation, or how to
|
|
131
|
+
* inspect and persist it without diving into every implementation chapter. Read
|
|
132
|
+
* the narrower `src/neat/**` READMEs when the next question becomes about one
|
|
133
|
+
* specific policy family rather than the whole experiment loop.
|
|
110
134
|
*
|
|
111
135
|
* ```mermaid
|
|
112
136
|
* flowchart LR
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
137
|
+
* classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
138
|
+
* classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
139
|
+
*
|
|
140
|
+
* Configure["Configure run<br/>sizes + fitness + options"]:::accent --> Seed["Seed or restore<br/>constructor / createPool / import"]:::base
|
|
141
|
+
* Seed --> Score["Score population<br/>evaluate()"]:::base
|
|
142
|
+
* Score --> Breed["Breed next generation<br/>evolve() / mutate()"]:::accent
|
|
143
|
+
* Breed --> Observe["Observe pressure<br/>telemetry / species / diversity / Pareto"]:::base
|
|
144
|
+
* Observe --> Persist["Persist or replay<br/>exportState() / toJSON() / RNG state"]:::base
|
|
118
145
|
* Breed --> Score
|
|
119
146
|
* ```
|
|
120
147
|
*
|
|
148
|
+
* ```mermaid
|
|
149
|
+
* flowchart TD
|
|
150
|
+
* classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
151
|
+
* classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
152
|
+
*
|
|
153
|
+
* Root["src root controller"]:::accent --> Setup["Defaults and initialization<br/>constructor / createPool / import"]:::base
|
|
154
|
+
* Root --> Search["Search loop<br/>evaluate / evolve / mutate"]:::base
|
|
155
|
+
* Root --> Observe["Diagnostics<br/>telemetry / species / lineage / Pareto"]:::base
|
|
156
|
+
* Root --> Replay["Persistence<br/>toJSON / exportState / RNG"]:::base
|
|
157
|
+
* Search --> Chapters["Detailed policy chapters<br/>src/neat/**"]:::base
|
|
158
|
+
* ```
|
|
159
|
+
*
|
|
160
|
+
* Example: start a small deterministic run and inspect the best score after one
|
|
161
|
+
* generation.
|
|
162
|
+
*
|
|
163
|
+
* ```ts
|
|
164
|
+
* const neat = new Neat(2, 1, fitness, {
|
|
165
|
+
* popsize: 50,
|
|
166
|
+
* seed: 7,
|
|
167
|
+
* fastMode: true,
|
|
168
|
+
* });
|
|
169
|
+
*
|
|
170
|
+
* await neat.evaluate();
|
|
171
|
+
* const bestGenome = await neat.evolve();
|
|
172
|
+
*
|
|
173
|
+
* console.log(bestGenome.score);
|
|
174
|
+
* ```
|
|
175
|
+
*
|
|
176
|
+
* Example: capture telemetry and a replayable snapshot after the current run
|
|
177
|
+
* step.
|
|
178
|
+
*
|
|
179
|
+
* ```ts
|
|
180
|
+
* const latestTelemetry = neat.getTelemetry().at(-1);
|
|
181
|
+
* const exportedState = neat.exportState();
|
|
182
|
+
*
|
|
183
|
+
* console.log(latestTelemetry?.generation);
|
|
184
|
+
* console.log(exportedState.neat.generation);
|
|
185
|
+
* ```
|
|
186
|
+
*
|
|
121
187
|
* Recommended reading after this root chapter:
|
|
122
188
|
* - `./neat/evaluate/README.md` for scoring flow and objective handling
|
|
123
189
|
* - `./neat/evolve/README.md` for reproduction orchestration
|
package/src/utils/README.md
CHANGED
|
@@ -1,23 +1,44 @@
|
|
|
1
1
|
# utils
|
|
2
2
|
|
|
3
|
-
Memory instrumentation
|
|
3
|
+
Memory instrumentation chapter for slab, pool, and heap comparisons.
|
|
4
4
|
|
|
5
5
|
This chapter exists for one practical learning problem: memory behavior is
|
|
6
6
|
one of the easiest parts of an evolutionary system to feel, but one of the
|
|
7
7
|
hardest parts to explain from raw runtime objects alone. Networks grow,
|
|
8
8
|
slabs reserve capacity ahead of immediate need, pools trade fresh allocation
|
|
9
9
|
pressure for reuse, and the JavaScript engine adds object overhead that is
|
|
10
|
-
|
|
10
|
+
difficult to see directly from the outside.
|
|
11
11
|
|
|
12
12
|
Instead of pretending to be a precise profiler, this boundary offers a fast,
|
|
13
13
|
educational snapshot. The goal is to make design choices visible enough that
|
|
14
|
-
readers can compare runs and ask better questions:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
readers can compare runs and ask better questions: did slab-backed storage
|
|
15
|
+
reduce object-heavy overhead, is pooling shifting pressure away from fresh
|
|
16
|
+
allocations, how much reserved typed-array capacity is currently unused, and
|
|
17
|
+
are browser or Node heap readings moving in the same direction as the
|
|
18
|
+
library-specific heuristics?
|
|
19
|
+
|
|
20
|
+
The most important design choice is scope. `memoryStats()` is not trying to
|
|
21
|
+
replace a full heap profiler. It is trying to put library-shaped numbers next
|
|
22
|
+
to runtime-shaped numbers so a reader can compare architecture decisions with
|
|
23
|
+
less guesswork. The result is intentionally strongest at trend questions such
|
|
24
|
+
as "did the slab version get leaner?" or "did pooling reduce fresh pressure?"
|
|
25
|
+
rather than forensic questions about one exact byte count.
|
|
26
|
+
|
|
27
|
+
A useful mental model is to treat the snapshot as four cooperating layers.
|
|
28
|
+
The network layer counts connections, nodes, and estimated totals. The slab
|
|
29
|
+
layer explains reserved versus used typed-array capacity. The pool layer
|
|
30
|
+
exposes reuse infrastructure. The environment layer shows the coarser browser
|
|
31
|
+
or Node counters surrounding the library's own heuristics.
|
|
32
|
+
|
|
33
|
+
The environment metrics are intentionally coarser than the network heuristics.
|
|
34
|
+
See MDN,
|
|
35
|
+
[Performance.memory](https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory),
|
|
36
|
+
and the Node.js docs,
|
|
37
|
+
[process.memoryUsage()](https://nodejs.org/api/process.html#processmemoryusage),
|
|
38
|
+
for the runtime-level counters this chapter folds alongside its own snapshot.
|
|
39
|
+
They are useful context, but they do not know the difference between live
|
|
40
|
+
network structure, reserved slab capacity, and reusable pools the way this
|
|
41
|
+
module does.
|
|
21
42
|
|
|
22
43
|
Read the chapter in three passes:
|
|
23
44
|
|
|
@@ -26,20 +47,49 @@ Read the chapter in three passes:
|
|
|
26
47
|
3. `memory.utils.ts` when you want the aggregation, environment probing, and
|
|
27
48
|
slab-accounting mechanics behind the snapshot.
|
|
28
49
|
|
|
29
|
-
Design principles:
|
|
30
|
-
|
|
31
|
-
- Lightweight: avoid deep graph walks or JSON serialization.
|
|
32
|
-
- Pay-for-use: if no networks are registered the snapshot stays small.
|
|
33
|
-
- Cross-environment: gather what the browser or Node can expose safely.
|
|
34
|
-
- Extensible: keep room for later phases that add more exact accounting.
|
|
35
|
-
|
|
36
50
|
```mermaid
|
|
37
51
|
flowchart TD
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
53
|
+
classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
54
|
+
|
|
55
|
+
Networks[Tracked or explicit networks]:::base --> Aggregation[Heuristic network aggregation]:::accent
|
|
56
|
+
Aggregation --> Snapshot[MemoryStats snapshot]:::base
|
|
57
|
+
Config[Config and allocator flags]:::base --> Snapshot
|
|
58
|
+
Environment[Browser or Node heap probes]:::base --> Snapshot
|
|
59
|
+
Snapshot --> Questions[Compare storage strategy, pooling, and capacity behavior]:::base
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```mermaid
|
|
63
|
+
flowchart LR
|
|
64
|
+
classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
65
|
+
classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
66
|
+
|
|
67
|
+
Stats[MemoryStats]:::accent --> NetworkLayer[connections nodes estimatedTotalBytes]:::base
|
|
68
|
+
Stats --> SlabLayer[slabBytes reservedBytes usedBytes fragmentationPct]:::base
|
|
69
|
+
Stats --> PoolLayer[nodePool reuse snapshot]:::base
|
|
70
|
+
Stats --> EnvironmentLayer[browser heap or Node RSS counters]:::base
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Example: register one network once, then capture snapshots later without
|
|
74
|
+
threading the target through every call.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
registerTrackedNetwork(network);
|
|
78
|
+
const snapshot = memoryStats();
|
|
79
|
+
|
|
80
|
+
console.log(snapshot.estimatedTotalBytes);
|
|
81
|
+
console.log(snapshot.slabs.fragmentationPct);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Example: compare two explicit network sets when you want the memory story to
|
|
85
|
+
stay local to one experiment.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
const baselineSnapshot = memoryStats([baselineNetwork]);
|
|
89
|
+
const pooledSnapshot = memoryStats([pooledNetwork]);
|
|
90
|
+
|
|
91
|
+
console.log(baselineSnapshot.estimatedTotalBytes);
|
|
92
|
+
console.log(pooledSnapshot.slabs.pooledFraction);
|
|
43
93
|
```
|
|
44
94
|
|
|
45
95
|
## utils/memory.ts
|
package/src/utils/memory.ts
CHANGED
|
@@ -1,22 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Memory instrumentation
|
|
2
|
+
* Memory instrumentation chapter for slab, pool, and heap comparisons.
|
|
3
3
|
*
|
|
4
4
|
* This chapter exists for one practical learning problem: memory behavior is
|
|
5
5
|
* one of the easiest parts of an evolutionary system to feel, but one of the
|
|
6
6
|
* hardest parts to explain from raw runtime objects alone. Networks grow,
|
|
7
7
|
* slabs reserve capacity ahead of immediate need, pools trade fresh allocation
|
|
8
8
|
* pressure for reuse, and the JavaScript engine adds object overhead that is
|
|
9
|
-
*
|
|
9
|
+
* difficult to see directly from the outside.
|
|
10
10
|
*
|
|
11
11
|
* Instead of pretending to be a precise profiler, this boundary offers a fast,
|
|
12
12
|
* educational snapshot. The goal is to make design choices visible enough that
|
|
13
|
-
* readers can compare runs and ask better questions:
|
|
13
|
+
* readers can compare runs and ask better questions: did slab-backed storage
|
|
14
|
+
* reduce object-heavy overhead, is pooling shifting pressure away from fresh
|
|
15
|
+
* allocations, how much reserved typed-array capacity is currently unused, and
|
|
16
|
+
* are browser or Node heap readings moving in the same direction as the
|
|
17
|
+
* library-specific heuristics?
|
|
14
18
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* -
|
|
18
|
-
*
|
|
19
|
-
*
|
|
19
|
+
* The most important design choice is scope. `memoryStats()` is not trying to
|
|
20
|
+
* replace a full heap profiler. It is trying to put library-shaped numbers next
|
|
21
|
+
* to runtime-shaped numbers so a reader can compare architecture decisions with
|
|
22
|
+
* less guesswork. The result is intentionally strongest at trend questions such
|
|
23
|
+
* as "did the slab version get leaner?" or "did pooling reduce fresh pressure?"
|
|
24
|
+
* rather than forensic questions about one exact byte count.
|
|
25
|
+
*
|
|
26
|
+
* A useful mental model is to treat the snapshot as four cooperating layers.
|
|
27
|
+
* The network layer counts connections, nodes, and estimated totals. The slab
|
|
28
|
+
* layer explains reserved versus used typed-array capacity. The pool layer
|
|
29
|
+
* exposes reuse infrastructure. The environment layer shows the coarser browser
|
|
30
|
+
* or Node counters surrounding the library's own heuristics.
|
|
31
|
+
*
|
|
32
|
+
* The environment metrics are intentionally coarser than the network heuristics.
|
|
33
|
+
* See MDN,
|
|
34
|
+
* [Performance.memory](https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory),
|
|
35
|
+
* and the Node.js docs,
|
|
36
|
+
* [process.memoryUsage()](https://nodejs.org/api/process.html#processmemoryusage),
|
|
37
|
+
* for the runtime-level counters this chapter folds alongside its own snapshot.
|
|
38
|
+
* They are useful context, but they do not know the difference between live
|
|
39
|
+
* network structure, reserved slab capacity, and reusable pools the way this
|
|
40
|
+
* module does.
|
|
20
41
|
*
|
|
21
42
|
* Read the chapter in three passes:
|
|
22
43
|
*
|
|
@@ -25,20 +46,49 @@
|
|
|
25
46
|
* 3. `memory.utils.ts` when you want the aggregation, environment probing, and
|
|
26
47
|
* slab-accounting mechanics behind the snapshot.
|
|
27
48
|
*
|
|
28
|
-
*
|
|
49
|
+
* ```mermaid
|
|
50
|
+
* flowchart TD
|
|
51
|
+
* classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
52
|
+
* classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
29
53
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
54
|
+
* Networks[Tracked or explicit networks]:::base --> Aggregation[Heuristic network aggregation]:::accent
|
|
55
|
+
* Aggregation --> Snapshot[MemoryStats snapshot]:::base
|
|
56
|
+
* Config[Config and allocator flags]:::base --> Snapshot
|
|
57
|
+
* Environment[Browser or Node heap probes]:::base --> Snapshot
|
|
58
|
+
* Snapshot --> Questions[Compare storage strategy, pooling, and capacity behavior]:::base
|
|
59
|
+
* ```
|
|
34
60
|
*
|
|
35
61
|
* ```mermaid
|
|
36
|
-
* flowchart
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
62
|
+
* flowchart LR
|
|
63
|
+
* classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
64
|
+
* classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
65
|
+
*
|
|
66
|
+
* Stats[MemoryStats]:::accent --> NetworkLayer[connections nodes estimatedTotalBytes]:::base
|
|
67
|
+
* Stats --> SlabLayer[slabBytes reservedBytes usedBytes fragmentationPct]:::base
|
|
68
|
+
* Stats --> PoolLayer[nodePool reuse snapshot]:::base
|
|
69
|
+
* Stats --> EnvironmentLayer[browser heap or Node RSS counters]:::base
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* Example: register one network once, then capture snapshots later without
|
|
73
|
+
* threading the target through every call.
|
|
74
|
+
*
|
|
75
|
+
* ```ts
|
|
76
|
+
* registerTrackedNetwork(network);
|
|
77
|
+
* const snapshot = memoryStats();
|
|
78
|
+
*
|
|
79
|
+
* console.log(snapshot.estimatedTotalBytes);
|
|
80
|
+
* console.log(snapshot.slabs.fragmentationPct);
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* Example: compare two explicit network sets when you want the memory story to
|
|
84
|
+
* stay local to one experiment.
|
|
85
|
+
*
|
|
86
|
+
* ```ts
|
|
87
|
+
* const baselineSnapshot = memoryStats([baselineNetwork]);
|
|
88
|
+
* const pooledSnapshot = memoryStats([pooledNetwork]);
|
|
89
|
+
*
|
|
90
|
+
* console.log(baselineSnapshot.estimatedTotalBytes);
|
|
91
|
+
* console.log(pooledSnapshot.slabs.pooledFraction);
|
|
42
92
|
* ```
|
|
43
93
|
*/
|
|
44
94
|
import { config } from '../config';
|
|
@@ -1,15 +1,88 @@
|
|
|
1
1
|
# browser-entry
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Browser-hosted curriculum boundary for the ASCII Maze example.
|
|
4
|
+
|
|
5
|
+
This folder is where a long-running maze experiment becomes a browser
|
|
6
|
+
experience a human can actually steer and inspect. The evolution engine still
|
|
7
|
+
owns search, scoring, and curriculum advancement. The browser-entry boundary
|
|
8
|
+
owns host elements, resize behavior, telemetry fan-out, globals
|
|
9
|
+
compatibility, and the lifecycle handle that embedding code talks to.
|
|
10
|
+
|
|
11
|
+
Read it as a boundary between two clocks. One clock belongs to the maze
|
|
12
|
+
curriculum that carries refined winners into larger procedural mazes. The
|
|
13
|
+
other clock belongs to the browser host that has to paint dashboards, react
|
|
14
|
+
to cancellation, and stay polite to resize or unload events. `browser-entry/`
|
|
15
|
+
exists so those clocks can cooperate without collapsing into one monolithic
|
|
16
|
+
demo script.
|
|
17
|
+
|
|
18
|
+
That separation matters because `index.html` is intentionally thin. The page
|
|
19
|
+
only loads the published bundle from `docs/assets`, exposes a globals bridge,
|
|
20
|
+
and then hands off to this start surface. If you want the real host/runtime
|
|
21
|
+
seam, start here instead of with the HTML shell.
|
|
22
|
+
|
|
23
|
+
A second useful mental model is ownership. This folder does not own maze
|
|
24
|
+
fitness, winner refinement, or solve thresholds. Those stay in
|
|
25
|
+
`evolutionEngine/`. The host boundary owns container resolution, dashboard
|
|
26
|
+
plumbing, cooperative abort wiring, and the stable run handle that browser
|
|
27
|
+
callers can stop, await, or subscribe to.
|
|
28
|
+
|
|
29
|
+
Read the chapter in three passes. Start with `browser-entry.ts` for the
|
|
30
|
+
public `start(...)` surface. Continue to `browser-entry.services.ts` for host
|
|
31
|
+
assembly, globals wiring, and curriculum hand-off. Finish with the constants,
|
|
32
|
+
curriculum, and host helper files when you want the browser-specific
|
|
33
|
+
mechanics rather than the public lifecycle contract.
|
|
34
|
+
|
|
35
|
+
```mermaid
|
|
36
|
+
flowchart LR
|
|
37
|
+
classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
38
|
+
classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
39
|
+
|
|
40
|
+
HtmlShell["index.html\nbundle loader"]:::base --> Globals["window globals\ncompatibility bridge"]:::base
|
|
41
|
+
Globals --> Start["start(...)\npublic browser entry"]:::accent
|
|
42
|
+
Start --> Host["host services\ndashboard + resize + container"]:::base
|
|
43
|
+
Start --> Curriculum["runBrowserEntryCurriculum\nphase orchestration"]:::base
|
|
44
|
+
Curriculum --> Engine["Evolution engine\nsearch and solve logic"]:::base
|
|
45
|
+
Host --> Handle["AsciiMazeRunHandle\nstop done telemetry"]:::base
|
|
46
|
+
Curriculum --> Handle
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```mermaid
|
|
50
|
+
flowchart TD
|
|
51
|
+
classDef base fill:#08131f,stroke:#1ea7ff,color:#dff6ff,stroke-width:1px;
|
|
52
|
+
classDef accent fill:#0f2233,stroke:#ffd166,color:#fff4cc,stroke-width:1.5px;
|
|
53
|
+
|
|
54
|
+
BrowserEntry["browser-entry/"]:::accent --> PublicApi["browser-entry.ts\npublic start surface"]:::base
|
|
55
|
+
BrowserEntry --> Services["browser-entry.services.ts\nhost and globals assembly"]:::base
|
|
56
|
+
BrowserEntry --> Curriculum["browser-entry.curriculum.services.ts\nphase hand-off"]:::base
|
|
57
|
+
BrowserEntry --> HostUtils["browser-entry.host.services.ts\nand utils"]:::base
|
|
58
|
+
BrowserEntry --> Types["browser-entry.types.ts\nrun-handle contracts"]:::base
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For background reading on the cooperative stop side of the boundary, see
|
|
62
|
+
MDN, [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController),
|
|
63
|
+
which is the browser primitive this entry layer uses to compose internal and
|
|
64
|
+
caller-provided cancellation without moving DOM concerns into the engine.
|
|
65
|
+
|
|
66
|
+
Example: boot the browser demo from embedding code and stop it later.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const handle = await start('ascii-maze-output');
|
|
70
|
+
|
|
71
|
+
setTimeout(() => handle.stop(), 5_000);
|
|
72
|
+
await handle.done;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Example: subscribe to telemetry while the curriculum advances.
|
|
4
76
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
77
|
+
```ts
|
|
78
|
+
const handle = await start('ascii-maze-output');
|
|
79
|
+
const unsubscribe = handle.onTelemetry((telemetry) => {
|
|
80
|
+
console.log(telemetry.generation, telemetry.bestFitness);
|
|
81
|
+
});
|
|
8
82
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
host boundary, start here rather than with the HTML loader.
|
|
83
|
+
await handle.done;
|
|
84
|
+
unsubscribe();
|
|
85
|
+
```
|
|
13
86
|
|
|
14
87
|
## browser-entry/browser-entry.types.ts
|
|
15
88
|
|