UNPKG

ixfx

Version:

A framework for programming interactivity

292 lines (287 loc) 7.01 kB
import { NumberTracker, PrimitiveTracker, number } from "./chunk-RS6FVVTS.js"; import { ObjectTracker, PointTracker, TrackedPointMap, point, points, unique, uniqueInstances } from "./chunk-SDJ3QNB4.js"; import { TrackedValueMap, TrackerBase } from "./chunk-7ICNCHYJ.js"; import { timeout } from "./chunk-3PQXJLTZ.js"; import { SimpleEventEmitter } from "./chunk-72EKR3DZ.js"; import { getSorter, minMaxAvg2 as minMaxAvg } from "./chunk-LKZ4HZTV.js"; import { __export } from "./chunk-L5EJU35C.js"; // src/trackers/index.ts var trackers_exports = {}; __export(trackers_exports, { FrequencyTracker: () => FrequencyTracker, IntervalTracker: () => IntervalTracker, NumberTracker: () => NumberTracker, ObjectTracker: () => ObjectTracker, PointTracker: () => PointTracker, PrimitiveTracker: () => PrimitiveTracker, RateTracker: () => RateTracker, TrackedPointMap: () => TrackedPointMap, TrackedValueMap: () => TrackedValueMap, TrackerBase: () => TrackerBase, frequency: () => frequency, interval: () => interval, number: () => number, point: () => point, points: () => points, rate: () => rate, unique: () => unique, uniqueInstances: () => uniqueInstances }); // src/trackers/FrequencyMutable.ts var FrequencyTracker = class extends SimpleEventEmitter { #store; #keyString; /** * Constructor * @param keyString Function to key items. Uses JSON.stringify by default */ constructor(keyString) { super(); this.#store = /* @__PURE__ */ new Map(); if (keyString === void 0) { keyString = (a) => { if (a === void 0) throw new Error(`Cannot create key for undefined`); return typeof a === `string` ? a : JSON.stringify(a); }; } this.#keyString = keyString; } /** * Clear data. Fires `change` event */ clear() { this.#store.clear(); this.fireEvent(`change`, { context: this }); } /** * @returns Iterator over keys (ie. groups) */ keys() { return this.#store.keys(); } /** * @returns Iterator over frequency counts */ values() { return this.#store.values(); } /** * @returns Copy of entries as an array of `[key, count]` */ toArray() { return [...this.#store.entries()]; } /** * Returns a string with keys and counts, useful for debugging. * @returns */ debugString() { let t = ``; for (const [key, count] of this.#store.entries()) { t += `${key}: ${count}, `; } if (t.endsWith(`, `)) return t.slice(0, Math.max(0, t.length - 2)); return t; } /** * * @param value Value to count * @returns Frequency of value, or _undefined_ if it does not exist */ frequencyOf(value) { if (typeof value === `string`) return this.#store.get(value); const key = this.#keyString(value); return this.#store.get(key); } /** * * @param value Value to count * @returns Relative frequency of `value`, or _undefined_ if it does not exist */ relativeFrequencyOf(value) { let freq; if (typeof value === `string`) freq = this.#store.get(value); else { const key = this.#keyString(value); freq = this.#store.get(key); } if (freq === void 0) return; const mma = this.minMaxAvg(); return freq / mma.total; } /** * @returns Copy of entries as an array */ entries() { return [...this.#store.entries()]; } /** * * @returns Returns `{min,max,avg,total}` */ minMaxAvg() { return minMaxAvg(this.entries()); } /** * * @param sortStyle Sorting style (default: _value_, ie. count) * @returns Sorted array of [key,frequency] */ entriesSorted(sortStyle = `value`) { const s = getSorter(sortStyle); return s(this.entries()); } /** * * @param values Values to add. Fires _change_ event after adding item(s) */ //eslint-disable-next-line functional/prefer-immutable-types add(...values) { if (values === void 0) throw new Error(`value parameter is undefined`); const keys = values.map((v) => this.#keyString(v)); for (const key of keys) { const score = this.#store.get(key) ?? 0; this.#store.set(key, score + 1); } this.fireEvent(`change`, { context: this }); } }; var frequency = (keyString) => new FrequencyTracker(keyString); // src/trackers/IntervalTracker.ts var IntervalTracker = class extends NumberTracker { constructor() { super(...arguments); this.lastMark = 0; } mark() { if (this.lastMark > 0) { this.seen(performance.now() - this.lastMark); } this.lastMark = performance.now(); } }; var interval = (options) => new IntervalTracker(options); // src/trackers/RateTracker.ts var RateTracker = class { #events = []; #fromTime; #resetAfterSamples; #sampleLimit; #resetTimer; constructor(opts = {}) { this.#resetAfterSamples = opts.resetAfterSamples ?? Number.MAX_SAFE_INTEGER; this.#sampleLimit = opts.sampleLimit ?? Number.MAX_SAFE_INTEGER; if (opts.timeoutInterval) { this.#resetTimer = timeout(() => { this.reset(); }, opts.timeoutInterval); } this.#fromTime = performance.now(); } /** * Mark that an event has happened */ mark() { if (this.#events.length >= this.#resetAfterSamples) { this.reset(); } else if (this.#events.length >= this.#sampleLimit) { this.#events = this.#events.slice(1); this.#fromTime = this.#events[0]; } this.#events.push(performance.now()); if (this.#resetTimer) { this.#resetTimer.start(); } } /** * Compute {min,max,avg} for the interval _between_ events. * @returns */ computeIntervals() { let intervals = []; let min = Number.MAX_SAFE_INTEGER; let max = Number.MIN_SAFE_INTEGER; let total = 0; let count = 0; let start = 0; for (let e of this.#events) { if (count > 0) { const i = e - start; min = Math.min(i, min); max = Math.max(i, max); total += i; intervals.push(i); } start = e; count++; } let avg = total / count; return { min, max, avg }; } /** * Returns the time period (in milliseconds) that encompasses * the data set. Eg, a result of 1000 means there's data that * covers a one second period. */ get elapsed() { return performance.now() - this.#fromTime; } /** * Resets the tracker. */ reset() { this.#events = []; this.#fromTime = performance.now(); } /** * Get the number of events per second */ get perSecond() { return this.#events.length / (this.elapsed / 1e3); } /** * Get the number of events per minute */ get perMinute() { return this.#events.length / (this.elapsed / 1e3 / 60); } }; var rate = (opts = {}) => new RateTracker(opts); export { FrequencyTracker, frequency, IntervalTracker, interval, RateTracker, rate, trackers_exports }; //# sourceMappingURL=chunk-SLLDL6RL.js.map