all_module_ids() builds a fresh Vec<&'static str> on every call, even though TSJS_MODULES is a compile-time constant and the answer never changes.
crates/trusted-server-js/src/bundle.rs:19:
pub fn all_module_ids() -> Vec<&'static str> {
TSJS_MODULES.iter().map(|module| module.id).collect()
}
The allocation is small, but one caller makes it worth tidying: parse_single_module_filename (crates/trusted-server-core/src/publisher.rs:610) calls it and immediately does .into_iter().find(...), allocating a Vec to run a linear scan it could have run over the constant directly. That path runs per request for deferred-module filenames.
(The issue text cites crates/js/src/bundle.rs; the crate is now trusted-server-js.)
Two reasonable shapes
Pick one and say why in the pull request:
- Return an iterator —
impl Iterator<Item = &'static str>. No allocation at all, and the find caller gets simpler. Callers that genuinely want a Vec add .collect().
- Cache in a
OnceLock and return a &'static [&'static str]. OnceLock is already imported in this file, and module_meta_map() just below shows the established pattern.
The iterator version is probably the better fit here, since nothing needs a materialized Vec that cannot cheaply make one. Either is defensible; what matters is that you consider both and explain the choice.
Callers to update
There are five, all short:
crates/trusted-server-js/src/bundle.rs:143 and :157 (tests)
crates/trusted-server-core/src/publisher.rs:610 — the find scan
crates/trusted-server-core/src/publisher.rs:1970 — passes the result to concatenated_hash, which takes &[&str]
That last one is the constraint worth noticing before you start: if you return an iterator, this caller needs a .collect() to keep feeding a slice. That is fine, but it means "no allocation anywhere" is not the outcome — decide whether the change still earns itself, and say so either way.
Acceptance criteria
all_module_ids() no longer allocates on the publisher.rs:610 lookup path.
- All five call sites compile and behave identically.
- Existing bundle tests still pass; extend them if the signature change makes an existing assertion weaker.
cargo test-fastly, cargo clippy-fastly, and the JS build are unaffected (bundle.rs is generated against dist/, so a stale dist/ can produce confusing errors: run the JS build first if you see unexpected module IDs).
Context
From the production readiness audit tracked in #396. This one is a small performance and clarity cleanup rather than a correctness bug, which makes it a good first change: the behavior must stay exactly the same, so the tests tell you immediately if it did not.
all_module_ids()builds a freshVec<&'static str>on every call, even thoughTSJS_MODULESis a compile-time constant and the answer never changes.crates/trusted-server-js/src/bundle.rs:19:The allocation is small, but one caller makes it worth tidying:
parse_single_module_filename(crates/trusted-server-core/src/publisher.rs:610) calls it and immediately does.into_iter().find(...), allocating aVecto run a linear scan it could have run over the constant directly. That path runs per request for deferred-module filenames.(The issue text cites
crates/js/src/bundle.rs; the crate is nowtrusted-server-js.)Two reasonable shapes
Pick one and say why in the pull request:
impl Iterator<Item = &'static str>. No allocation at all, and thefindcaller gets simpler. Callers that genuinely want aVecadd.collect().OnceLockand return a&'static [&'static str].OnceLockis already imported in this file, andmodule_meta_map()just below shows the established pattern.The iterator version is probably the better fit here, since nothing needs a materialized
Vecthat cannot cheaply make one. Either is defensible; what matters is that you consider both and explain the choice.Callers to update
There are five, all short:
crates/trusted-server-js/src/bundle.rs:143and:157(tests)crates/trusted-server-core/src/publisher.rs:610— thefindscancrates/trusted-server-core/src/publisher.rs:1970— passes the result toconcatenated_hash, which takes&[&str]That last one is the constraint worth noticing before you start: if you return an iterator, this caller needs a
.collect()to keep feeding a slice. That is fine, but it means "no allocation anywhere" is not the outcome — decide whether the change still earns itself, and say so either way.Acceptance criteria
all_module_ids()no longer allocates on thepublisher.rs:610lookup path.cargo test-fastly,cargo clippy-fastly, and the JS build are unaffected (bundle.rsis generated againstdist/, so a staledist/can produce confusing errors: run the JS build first if you see unexpected module IDs).Context
From the production readiness audit tracked in #396. This one is a small performance and clarity cleanup rather than a correctness bug, which makes it a good first change: the behavior must stay exactly the same, so the tests tell you immediately if it did not.