
Security News
OpenCode User Hit with Hostile Backlash After Reporting Free AI Loophole
An OpenCode user faced harassment after reporting a free AI usage loophole, drawing a bitter backlash in a GitHub thread that has since been deleted.
@time-provider/addon-eta
Advanced tools
Time-Provider : ETA estimation addon ~ Your single time interface for all your JavaScript / TypeScript projects.
This is the ETA (estimated time of arrival) addon for
Time-Provider. Extends the library with an
.eta facade that periodically reports progress and a projected completion time for a long-running task.
Three mutually exclusive ways to start a schedule:
withKnownTotal(total) - report progress toward a single known total (bytes downloaded,
rows processed, ...). The completion rate is estimated from reported progress over time, and the
ETA is projected from that rate.withStages(stages) - the same idea across several weighted stages of one job (e.g.
download, then process, then finalize), reported as a single overall schedule.withEstimatedDuration(expectedDurationMilliseconds) - no progress signal at all, just a
rough prior of how long the job usually takes. The ETA is
startTime + expectedDurationMilliseconds, fixed for the life of the schedule.Progress reporting (progress()/progressTo()) is pure, O(1) bookkeeping - it never triggers a
notification by itself. Notifications are delivered strictly on the configured interval
(withNotificationInterval, defaulting to 1000ms), decoupling how often progress is reported from
how often a consumer is notified.
Just like the plugin packages, this addon is tree-shakable.
It is split into a default (system/real-time) entry point and a deterministic one, so each import
pulls in only the code it needs:
@time-provider/addon-eta - for a system (real time) Time-Provider created via
@time-provider/core. Notifications run on real native timers.@time-provider/addon-eta/deterministic - for a deterministic Time-Provider
(fixed/manual/sequential) created via @time-provider/core/deterministic. Notifications run
against that runtime's own simulated clock.import { createTimeProvider } from "@time-provider/core";
import { plugin } from "@time-provider/plugin-native";
import { addon } from "@time-provider/addon-eta";
const timeProvider = createTimeProvider.for(plugin).use(addon).create();
const tracker = timeProvider.eta
.estimate()
.withKnownTotal(1_000_000) // bytes
.withNotificationInterval(500)
.start((snapshot) => {
console.log(`${snapshot.percentage.toFixed(1)}% - ETA ${snapshot.eta}`);
});
tracker.progress(65_536); // a chunk just arrived
// ...
tracker.done(); // one final notification, snapped to 100%
withStages tracks several stages of one job as a single overall schedule. Each stage declares
its own total (in whatever unit fits that stage - bytes, then rows, then steps) and a weight
relative to the other stages, normalized by dividing by their sum (not required to sum to any
particular total):
const tracker = timeProvider.eta
.estimate()
.withStages([
{ weight: 2, total: downloadBytes }, // twice as significant as what follows
{ weight: 1, total: processRows },
])
.start((snapshot) => {
// stageCompleted/stageTotal/stagePercentage are local to the current stage (its own unit) -
// a per-stage progress bar. rate/eta/remainingMilliseconds are overall, weighted across every
// stage.
console.log(`stage ${snapshot.currentStageIndex + 1}/${snapshot.stageCount}`);
});
tracker.progressTo(downloadBytes); // finish the download stage
tracker.nextStage(); // move on to processing, progress resets to 0
tracker.progress(1);
Different stages can use different raw units, which can't be meaningfully summed into one figure -
so a staged snapshot's fields deliberately don't share names with a non-staged one:
stageCompleted/stageTotal/stageRemaining/stagePercentage stay local to whichever stage is
current, while rate/eta/remainingMilliseconds are weighted across every stage
(unit-less/normalized figures, which can be combined), answering "when does the whole job
finish" rather than just the current stage.
withAlgorithm picks how the completion rate is derived from reported progress (defaults to
"windowed"):
"complete" - averaged over the entire tracked history, from the start. Simple and stable, but
a slow start (or a mid-run change of pace) permanently drags the estimate."windowed" - averaged over only the most recently reported progress, discarding older samples.
Reacts to a change in pace faster than "complete"."smoothed" - a continuously blended running average, weighted toward more recent reports
without discarding older ones outright.rate itself is always a fraction of the whole job (0-1) per millisecond, never scaled to the
tracked unit - that's what lets a multi-stage schedule combine stages using different units into
one figure.
done() - marks the job complete. The final notification reports 100% regardless of the
last reported amount, and no further notifications follow.abandon() - calls off tracking without completing it. The final notification reports
whatever progress was last recorded, as-is, with eta/remainingMilliseconds unset - there's
nothing left to project forward. rate stays set to the last measured pace.Both are idempotent: calling either again after a schedule has already ended is a no-op.
MIT
FAQs
Progress and ETA addon for Time-Provider. Inject time. Control it in tests.
The npm package @time-provider/addon-eta receives a total of 7 weekly downloads. As such, @time-provider/addon-eta popularity was classified as not popular.
We found that @time-provider/addon-eta demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
An OpenCode user faced harassment after reporting a free AI usage loophole, drawing a bitter backlash in a GitHub thread that has since been deleted.

Threat Research
/Security News
319 browser extensions installed by 13.4 million users hijack searches, capture queries, and collect referral payments from Yahoo and Bing.

Threat Research
Malicious Firefox extensions mimic Phantom, Jupiter, and Bitget wallets to steal recovery phrases and private keys, with one fetching its payload remotely.