Add the ability to use local optimization_config#276
Conversation
…ization' To ensure consistency with other names. Most variable and function names in that file start with 'optimization' without the 'filter' prefix.
|
commit singing missed 😅 |
a69c0f0 to
e54e49d
Compare
Add unit tests covering `optimizationConfigLocal` and its members.
Introduce `optimizationConfigLocal` namespace with three members:
- `setPath(configPath)`: Sets the local config directory path. When set,
`getOptimizationPercent` and `getOptimizationConfig` read from local
files instead of downloading from remote URLs.
- `generate(configPath)`: Downloads `percent.json` and per-filter
`stats.json` from remote and saves them to `configPath`, creating
`configPath/percent.json` and `configPath/filters/{filterId}/stats.json`.
Per-filter file writes run in parallel via `Promise.all`.
- `reset()`: Clears the local config path and nulls the in-memory
`optimizationPercent` cache. Intended for restoring clean state between
tests.
GitHub shorthand installation does not trigger a build step, so dist/ must be present in the branch directly. This is a temporary measure for the PR review period. dist/ should be removed from the branch before merging, and the version should be published to npm instead.
e54e49d to
615d6e0
Compare
…onStats "Config" was ambiguous — the function returns per-filter stats (hit counts, groups), not configuration. "Stats" matches the source data (stats.json) and the new generateStats() method name.
…izationConfig
BREAKING CHANGE: exported name changed. Update all import sites:
- before: import { optimizationConfigLocal } from '@adguard/filters-compiler'
- after: import { localOptimizationConfig } from '@adguard/filters-compiler'
Noun-first naming matches the other module-level vars
(localOptimizationConfigPath, optimizationPercent).
download percent.json locally first, enabling users to edit it Before stats are fetched. downloadStatsFromPercentJson() fills in missing stats via two-steps lookup: local file → network download. Local stats.json files are preserved (never overwritten), so user edits to stats directly affect the compiled output. getOptimizationConfig() reads from in-memory cache (populated by downloadStatsFromPercentJson()) when localOptimizationConfigPath is set, instead of re-reading the file on every call.
reset() now takes an explicit configPath instead of reading stored state. getOptimizationStats() simplified: cache hit → return, else download. BREAKING CHANGE: setPath(), getOptimizationPercent() no longer exported; reset() signature changed from reset() to reset(configPath).
I will perform a force-push to exclude the changes in the |
238440f to
3e24d93
Compare
maximtop
left a comment
There was a problem hiding this comment.
I also tested the compiled package with optimization enabled. Platform generation fails on a non-optimized filter because the new code requests filters/10/stats.json and the server returns 404. Existing builder tests do not catch this because they call disableOptimization().
| describe('local optimization config', () => { | ||
| let tmpDir; | ||
|
|
||
| afterEach(() => { |
There was a problem hiding this comment.
reset is async but this afterEach does not await or return it. Also, the nested test block declares another const tmpDir, so cleanup still uses the outer tmpDir and leaves the stats test directory behind.
Please make cleanup awaited and avoid shadowing tmpDir.
There was a problem hiding this comment.
I applied your comment. Please see the changes.
By the way, should I keep using fs.promises in 'reset()` or switch to synchronous methods?
I mean that the others, like readFile, writeFile, and mkdtemp, are called either synchronously or asynchronously in the existing codebase.
In short: When should I call the node fs module synchronously or asynchronously in this project?
There was a problem hiding this comment.
In this PR, I switched to using fs.promises today for consistency (d393a90) because I had been using both.
There was a problem hiding this comment.
I applied your comment. Please see the changes.
By the way, should I keep using
fs.promisesin 'reset()` or switch to synchronous methods?I mean that the others, like
readFile,writeFile, andmkdtemp, are called either synchronously or asynchronously in the existing codebase.In short: When should I call the node
fsmodule synchronously or asynchronously in this project?
For this PR, fs.promises is the right direction. These helpers are already async and can run during build workflows, so async filesystem calls avoid blocking the event loop and keep the API consistent.
Sync fs is fine for tiny startup/config reads or test setup when it makes tests simpler, but new runtime/build-path code should generally prefer fs.promises.
Without the gate, every uncached filterId called
filters/{id}/stats.json, which 404s for non-optimized filters.
- Re-introduce optimizableFilterIds Set (lazily loaded from
percent.json on first getOptimizationStats call)
- Return null for filterIds not listed in percent.json
- Restore groups array validation on downloaded stats
- Populate optimizableFilterIds in downloadStatsFromPercentJson
- Reset optimizableFilterIds to null in reset()
- Extract PERCENT_JSON / STATS_JSON / FILTERS_DIR constants
- Add JSDoc to localOptimizationConfig and getOptimizationStats
- Move async setup from describe callbacks into beforeAll/afterAll - Remove inner const tmpDir shadowing the outer let tmpDir - Await localOptimizationConfig.reset() in cleanup hooks - Add: getOptimizationStats returns null for unlisted filterId and does not call the stats endpoint
maximtop
left a comment
There was a problem hiding this comment.
Manual review — 13 findings (mostly cosmetic/style). No bugs found, tests pass. All issues are non-blocking.
`global-require` disable was left over from old CommonJS code. No `require()` calls remain in the file. Refs #276 (comment)
First @type {Promise<Set<number>>|null} comment was orphaned — not adjacent to any declaration. The correct block preceding `optimizableFilterIdsPromise` remains. Refs #276 (comment)
Replace .then() chain with async IIFE for consistency with the rest of the codebase. Refs #276 (comment)
Sync fs call inside async mapper. Use async access() with try/catch and move download into catch block to avoid the flag variable. Refs #276 (comment)
Predicate function returns a boolean; action-verb name was misleading. Also fixes stale @param JSDoc reference (getFilterOptimizationConfig → getOptimizationStats). Refs #276 (comment)
Verbose multi-bullet descriptions replaced with brief one-liners per project convention. Refs #276 (comment)
"three exported functions" → "four exports"; drop the directory-tree block from localOptimizationConfig — ASCII art renders poorly in IDE tooltips. Refs #276 (comment) Refs #276 (comment)
It has been changed by formatter
|
|
|
When will it be merged? Does it need to await the reset reviewer? |
|
You need to move the PR to another repository. I'll post about it in our chat. |
Related: AdguardTeam/FiltersRegistry#1186