Skip to content

Commit 1679fa9

Browse files
authored
Add Agents.md with information for AI agents (Dash-Industry-Forum#4965)
1 parent 904443d commit 1679fa9

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

AGENTS.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# AGENTS.md
2+
3+
## Project Overview
4+
5+
dash.js is the DASH Industry Forum reference client for MPEG-DASH playback in browsers.
6+
Pure JavaScript (ES2020), ESM modules (`"type": "module"`), no TypeScript in source code
7+
(TypeScript is only used to validate `index.d.ts`). Node >= 20 required.
8+
9+
## Build Commands
10+
11+
```bash
12+
npm run build # Full build: clean, typecheck, test, lint, then webpack (modern + legacy)
13+
npm run build-modern # Clean + typecheck + test + lint + webpack modern only
14+
npm run build-legacy # Clean + typecheck + test + lint + webpack
15+
npm run dev # Typecheck + webpack modern dev (watch mode)
16+
npm start # webpack-dev-server on port 3000 (opens samples/index.html)
17+
npm run lint # ESLint on src/**/*.js and test/unit/{mocks,test}/**/*.js
18+
npm run doc # Generate JSDoc documentation
19+
```
20+
21+
## Testing
22+
23+
**Frameworks:** Karma (runner) + Mocha (describe/it) + Chai (expect/assert) + Sinon (spy/stub/mock)
24+
25+
```bash
26+
# Run all unit tests (ChromeHeadless + FirefoxHeadless)
27+
npm test
28+
29+
# Run a single test or subset by grep pattern (matches describe/it names)
30+
npx karma start test/unit/config/karma.unit.conf.cjs --grep="EventBus"
31+
npx karma start test/unit/config/karma.unit.conf.cjs --grep="getOptimalRepresentationForBitrate"
32+
33+
# Run functional tests
34+
npm run test-functional
35+
```
36+
37+
There is no per-file test runner. All unit tests are bundled by Karma/webpack and run
38+
together in a headless browser. Use `--grep` to filter by test name.
39+
40+
Unit test files live in `test/unit/test/` and mirror the `src/` directory structure.
41+
Test file naming convention uses dot-separated module paths:
42+
- `core.EventBus.js` tests `src/core/EventBus.js`
43+
- `streaming.controllers.AbrController.js` tests `src/streaming/controllers/AbrController.js`
44+
- `dash.models.DashManifestModel.js` tests `src/dash/models/DashManifestModel.js`
45+
46+
## Code Style
47+
48+
### Formatting (enforced by ESLint flat config in `eslint.config.mjs`)
49+
50+
- **Indentation:** 4 spaces (including switch case bodies)
51+
- **Quotes:** Single quotes, template literals allowed
52+
- **Semicolons:** Required
53+
- **Curly braces:** Always required, even for single-line blocks (`curly: 'all'`)
54+
- **Line endings:** LF (see `.editorconfig`)
55+
- **Trailing whitespace:** Trimmed in `.js` files
56+
- **Final newline:** Required in `.js` and `.md` files
57+
- **Keyword spacing:** Space before and after keywords (`if`, `else`, `for`, etc.)
58+
- **Infix operators:** Spaces around operators (`a + b`, not `a+b`)
59+
- **No multi-spaces:** Only single spaces between tokens
60+
- **No Prettier:** Formatting is handled by ESLint rules only
61+
62+
### Imports
63+
64+
- ES module `import`/`export` syntax exclusively
65+
- Always include `.js` extension in import paths: `import Foo from './Foo.js'`
66+
- Relative paths for internal imports
67+
- Group order: external dependencies first, then internal modules
68+
- Default exports are the norm; named exports are rare
69+
70+
### Architecture Pattern — FactoryMaker
71+
72+
Most modules use the **factory function pattern**, not ES classes:
73+
74+
```js
75+
function MyController() {
76+
const context = this.context;
77+
let instance, logger, someState;
78+
79+
function setup() { /* init logic, called at bottom of factory */ }
80+
function _privateMethod() { /* underscore prefix */ }
81+
function publicMethod() { /* no prefix */ }
82+
function reset() { /* cleanup on teardown */ }
83+
84+
instance = { publicMethod, reset };
85+
setup();
86+
return instance;
87+
}
88+
MyController.__dashjs_factory_name = 'MyController';
89+
export default FactoryMaker.getSingletonFactory(MyController);
90+
```
91+
92+
Key conventions:
93+
- **Singletons** (`getSingletonFactory`): one instance per context (controllers, models)
94+
- **Class factories** (`getClassFactory`): new instance each call (value objects, processors)
95+
- **`__dashjs_factory_name`**: required static property for registration, matches the function name
96+
- **`setup()`**: called at the bottom of the factory function for initialization
97+
- **`reset()`**: cleanup method, should restore initial state
98+
- **`setConfig(config)`**: dependency injection method, receives an object with dependencies
99+
- **`instance` object**: the public API; only methods listed here are public
100+
101+
### Value Objects
102+
103+
Simple data classes in `src/*/vo/` use ES class syntax with constructor assignments
104+
and `export default ClassName`. See `src/streaming/vo/DashJSError.js` for an example.
105+
106+
### Naming Conventions
107+
108+
- **Files:** PascalCase for classes/factories (`AbrController.js`, `MediaPlayer.js`)
109+
- **Private methods:** `_underscore` prefix (`_onQualityChangeRendered`, `_commonOn`)
110+
- **Public methods:** camelCase, no prefix
111+
- **Constants:** UPPER_SNAKE_CASE for module-level constants; constant objects use PascalCase keys
112+
- **Events:** Class-based hierarchy extending `EventsBase`, string constant properties
113+
- **Loggers:** `logger = debug.getLogger(instance)` — use `logger.debug()`, `logger.info()`, `logger.warn()`, `logger.error()`
114+
115+
### Error Handling
116+
117+
- Errors are dispatched via `EventBus` as error events, not thrown
118+
- Use `DashJSError` value objects (code + message + data)
119+
- Error codes are defined as constants in `src/core/errors/Errors.js` and `src/streaming/vo/metrics/PlayList.js`
120+
- Critical errors trigger `Events.ERROR`; check `error.code` to distinguish types
121+
122+
### License Header
123+
124+
Every source file must include the BSD-3-Clause license header (approximately 30 lines)
125+
at the top of the file. See any existing source file for the exact text.
126+
127+
## Test Conventions
128+
129+
Tests follow this general pattern: import module + mocks, create `const context = {}`,
130+
instantiate singletons with `Module(context).getInstance()`, inject mocks via `setConfig()`,
131+
call `initialize()` in `beforeEach`, and call `reset()` in `afterEach`. Tests use nested
132+
`describe` blocks (one per method) and `it('Should ...', function () { ... })` blocks.
133+
134+
- **Mocks:** Hand-written in `test/unit/mocks/`, each mirrors the real class API
135+
- **Helpers:** `test/unit/helpers/``ObjectsHelper`, `VOHelper`, `SpecHelper` create dummy objects
136+
- **Assertions:** Chai `expect` style preferred; `assert` also used
137+
- **Spying/stubbing:** Sinon (`sinon.spy()`, `sinon.stub()`)
138+
- **Context:** Each test suite creates `const context = {}` and instantiates singletons against it
139+
- **Cleanup:** Always call `reset()` on instances, settings, and eventBus in `afterEach`
140+
- **Test data:** Fixtures in `test/unit/data/` (XML manifests, subtitle files, etc.)
141+
142+
## Project Structure
143+
144+
```
145+
src/
146+
├── core/ # EventBus, FactoryMaker, Settings, Debug, Utils, errors
147+
├── dash/ # DASH-specific: parser, adapter, manifest model, segment handling
148+
├── mss/ # Microsoft Smooth Streaming support
149+
├── offline/ # Offline playback / download support
150+
└── streaming/ # Core player: controllers, models, rules, protection (DRM), text, net
151+
test/
152+
├── unit/ # Unit tests (Karma + Mocha + Chai)
153+
│ ├── config/ # karma.unit.conf.cjs
154+
│ ├── data/ # Test fixtures (MPDs, subtitles)
155+
│ ├── helpers/ # ObjectsHelper, VOHelper, etc.
156+
│ ├── mocks/ # Hand-written mock classes
157+
│ └── test/ # Test files (mirrors src/ structure)
158+
└── functional/ # Functional/integration tests (real playback)
159+
build/webpack/ # Webpack configs (modern/legacy, dev/prod, UMD/ESM)
160+
```
161+
162+
## CI and Contributing
163+
164+
- PRs target the `development` branch (not `main`/`master`)
165+
- CI runs `npm run build` which executes: clean -> typecheck -> unit tests -> lint -> webpack
166+
- A pre-commit git hook runs `npm run lint` automatically
167+
- Functional tests run on LambdaTest/BrowserStack in CI for cross-browser validation
168+
- Always run `npm run build` before committing to catch test failures and lint errors
169+
- Include BSD-3-Clause header in new files; add/update unit tests for changes

0 commit comments

Comments
 (0)