@choksheak/ts-utils 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/asNumber.cjs +3 -3
- package/asNumber.d.mts +1 -1
- package/asNumber.d.ts +1 -1
- package/asNumber.min.cjs +1 -1
- package/asNumber.min.cjs.map +1 -1
- package/asNumber.min.mjs +1 -1
- package/asNumber.min.mjs.map +1 -1
- package/asNumber.mjs +3 -3
- package/kvStore.cjs +230 -239
- package/kvStore.d.mts +142 -44
- package/kvStore.d.ts +142 -44
- package/kvStore.min.cjs +1 -1
- package/kvStore.min.cjs.map +1 -1
- package/kvStore.min.mjs +1 -1
- package/kvStore.min.mjs.map +1 -1
- package/kvStore.mjs +229 -237
- package/localStore.cjs +187 -186
- package/localStore.d.mts +135 -34
- package/localStore.d.ts +135 -34
- package/localStore.min.cjs +1 -1
- package/localStore.min.cjs.map +1 -1
- package/localStore.min.mjs +1 -1
- package/localStore.min.mjs.map +1 -1
- package/localStore.mjs +186 -184
- package/mean.cjs +3 -3
- package/mean.min.cjs +1 -1
- package/mean.min.cjs.map +1 -1
- package/mean.min.mjs +1 -1
- package/mean.min.mjs.map +1 -1
- package/mean.mjs +3 -3
- package/median.cjs +4 -4
- package/median.min.cjs +1 -1
- package/median.min.cjs.map +1 -1
- package/median.min.mjs +1 -1
- package/median.min.mjs.map +1 -1
- package/median.mjs +4 -4
- package/package.json +2 -34
- package/safeBtoa.d.mts +7 -0
- package/safeBtoa.d.ts +7 -0
- package/safeBtoa.min.cjs.map +1 -1
- package/safeBtoa.min.mjs.map +1 -1
- package/sum.cjs +3 -3
- package/sum.min.cjs +1 -1
- package/sum.min.cjs.map +1 -1
- package/sum.min.mjs +1 -1
- package/sum.min.mjs.map +1 -1
- package/sum.mjs +3 -3
- package/timer.cjs +19 -24
- package/timer.d.mts +9 -6
- package/timer.d.ts +9 -6
- package/timer.min.cjs +1 -1
- package/timer.min.cjs.map +1 -1
- package/timer.min.mjs +1 -1
- package/timer.min.mjs.map +1 -1
- package/timer.mjs +19 -23
- package/safeParseFloat.cjs +0 -33
- package/safeParseFloat.d.mts +0 -6
- package/safeParseFloat.d.ts +0 -6
- package/safeParseFloat.min.cjs +0 -2
- package/safeParseFloat.min.cjs.map +0 -1
- package/safeParseFloat.min.mjs +0 -2
- package/safeParseFloat.min.mjs.map +0 -1
- package/safeParseFloat.mjs +0 -8
- package/safeParseInt.cjs +0 -33
- package/safeParseInt.d.mts +0 -6
- package/safeParseInt.d.ts +0 -6
- package/safeParseInt.min.cjs +0 -2
- package/safeParseInt.min.cjs.map +0 -1
- package/safeParseInt.min.mjs +0 -2
- package/safeParseInt.min.mjs.map +0 -1
- package/safeParseInt.mjs +0 -8
package/localStore.mjs
CHANGED
|
@@ -35,201 +35,203 @@ function validateStoredObject(obj) {
|
|
|
35
35
|
}
|
|
36
36
|
return obj;
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
38
|
+
function createLocalStore(storeName, options) {
|
|
39
|
+
const keyPrefix = storeName + ":";
|
|
40
|
+
const defaultExpiryMs = options?.defaultExpiryMs ? durationOrMsToMs(options.defaultExpiryMs) : LocalStoreConfig.expiryMs;
|
|
41
|
+
const gcIntervalMs = options?.gcIntervalMs ? durationOrMsToMs(options.gcIntervalMs) : LocalStoreConfig.gcIntervalMs;
|
|
42
|
+
const gcMsStorageKey = `__localStore:lastGcMs:${storeName}`;
|
|
43
|
+
const obj = {
|
|
44
|
+
/** Input name for the store. */
|
|
45
|
+
storeName,
|
|
46
|
+
/**
|
|
47
|
+
* The prefix string for the local storage key which identifies items
|
|
48
|
+
* belonging to this namespace.
|
|
49
|
+
*/
|
|
50
|
+
keyPrefix,
|
|
51
|
+
/** Default expiry to use if not specified in set(). */
|
|
52
|
+
defaultExpiryMs,
|
|
53
|
+
/** Time interval for when GC's occur. */
|
|
54
|
+
gcIntervalMs,
|
|
55
|
+
/** Local storage key name for the last GC completed timestamp. */
|
|
56
|
+
gcMsStorageKey,
|
|
57
|
+
/** Set a value in the store. */
|
|
58
|
+
set(key, value, expiryDeltaMs) {
|
|
59
|
+
const nowMs = Date.now();
|
|
60
|
+
const stored = {
|
|
61
|
+
value,
|
|
62
|
+
storedMs: nowMs,
|
|
63
|
+
expiryMs: nowMs + durationOrMsToMs(expiryDeltaMs ?? defaultExpiryMs)
|
|
64
|
+
};
|
|
65
|
+
localStorage.setItem(keyPrefix + key, JSON.stringify(stored));
|
|
66
|
+
obj.gc();
|
|
67
|
+
return value;
|
|
68
|
+
},
|
|
69
|
+
/** Delete one or multiple keys. */
|
|
70
|
+
delete(key) {
|
|
71
|
+
if (typeof key === "string") {
|
|
72
|
+
localStorage.removeItem(keyPrefix + key);
|
|
73
|
+
} else {
|
|
74
|
+
for (const k of key) {
|
|
75
|
+
localStorage.removeItem(keyPrefix + k);
|
|
76
|
+
}
|
|
74
77
|
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (!stored) {
|
|
82
|
-
return void 0;
|
|
83
|
-
}
|
|
84
|
-
try {
|
|
85
|
-
const parsed = JSON.parse(stored);
|
|
86
|
-
const obj = validateStoredObject(parsed);
|
|
87
|
-
if (!obj) {
|
|
88
|
-
this.delete(k);
|
|
89
|
-
this.gc();
|
|
78
|
+
},
|
|
79
|
+
/** Mainly used to get the expiration timestamp of an object. */
|
|
80
|
+
getStoredObject(key) {
|
|
81
|
+
const k = keyPrefix + key;
|
|
82
|
+
const stored = localStorage.getItem(k);
|
|
83
|
+
if (!stored) {
|
|
90
84
|
return void 0;
|
|
91
85
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
forEach(callback) {
|
|
107
|
-
for (const k of Object.keys(localStorage)) {
|
|
108
|
-
if (!k.startsWith(this.keyPrefix)) continue;
|
|
109
|
-
const key = k.slice(this.keyPrefix.length);
|
|
110
|
-
const obj = this.getStoredObject(key);
|
|
111
|
-
if (!obj) continue;
|
|
112
|
-
callback(key, obj.value, obj.expiryMs, obj.storedMs);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Returns the number of items in the store. Note that getting the size
|
|
117
|
-
* requires iterating through the entire store because the items could expire
|
|
118
|
-
* at any time, and hence the size is a dynamic number.
|
|
119
|
-
*/
|
|
120
|
-
size() {
|
|
121
|
-
let count = 0;
|
|
122
|
-
this.forEach(() => {
|
|
123
|
-
count++;
|
|
124
|
-
});
|
|
125
|
-
return count;
|
|
126
|
-
}
|
|
127
|
-
/** Remove all items from the store. */
|
|
128
|
-
clear() {
|
|
129
|
-
for (const key of Object.keys(localStorage)) {
|
|
130
|
-
if (key.startsWith(this.keyPrefix)) {
|
|
131
|
-
localStorage.removeItem(key);
|
|
86
|
+
try {
|
|
87
|
+
const parsed = JSON.parse(stored);
|
|
88
|
+
const valid = validateStoredObject(parsed);
|
|
89
|
+
if (!valid) {
|
|
90
|
+
obj.delete(k);
|
|
91
|
+
obj.gc();
|
|
92
|
+
return void 0;
|
|
93
|
+
}
|
|
94
|
+
return valid;
|
|
95
|
+
} catch (e) {
|
|
96
|
+
console.error(`Invalid local value: ${k}=${stored}:`, e);
|
|
97
|
+
obj.delete(k);
|
|
98
|
+
obj.gc();
|
|
99
|
+
return void 0;
|
|
132
100
|
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
/** Perform garbage-collection if due, else do nothing. */
|
|
159
|
-
gc() {
|
|
160
|
-
const lastGcMs = this.lastGcMs;
|
|
161
|
-
if (!lastGcMs) {
|
|
162
|
-
this.lastGcMs = Date.now();
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
if (Date.now() < lastGcMs + this.gcIntervalMs) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
this.gcNow();
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Perform garbage collection immediately without checking whether we are
|
|
172
|
-
* due for the next GC or not.
|
|
173
|
-
*/
|
|
174
|
-
gcNow() {
|
|
175
|
-
console.log(`Starting localStore GC on ${this.storeName}`);
|
|
176
|
-
this.lastGcMs = Date.now();
|
|
177
|
-
let count = 0;
|
|
178
|
-
this.forEach((key, value, expiryMs) => {
|
|
179
|
-
if (Date.now() >= expiryMs) {
|
|
180
|
-
this.delete(key);
|
|
101
|
+
},
|
|
102
|
+
/** Get a value by key, or undefined if it does not exist. */
|
|
103
|
+
get(key) {
|
|
104
|
+
const stored = obj.getStoredObject(key);
|
|
105
|
+
return stored?.value;
|
|
106
|
+
},
|
|
107
|
+
/** Generic way to iterate through all entries. */
|
|
108
|
+
forEach(callback) {
|
|
109
|
+
for (const k of Object.keys(localStorage)) {
|
|
110
|
+
if (!k.startsWith(keyPrefix)) continue;
|
|
111
|
+
const key = k.slice(keyPrefix.length);
|
|
112
|
+
const stored = obj.getStoredObject(key);
|
|
113
|
+
if (!stored) continue;
|
|
114
|
+
callback(key, stored.value, stored.expiryMs, stored.storedMs);
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
/**
|
|
118
|
+
* Returns the number of items in the store. Note that getting the size
|
|
119
|
+
* requires iterating through the entire store because the items could expire
|
|
120
|
+
* at any time, and hence the size is a dynamic number.
|
|
121
|
+
*/
|
|
122
|
+
size() {
|
|
123
|
+
let count = 0;
|
|
124
|
+
obj.forEach(() => {
|
|
181
125
|
count++;
|
|
126
|
+
});
|
|
127
|
+
return count;
|
|
128
|
+
},
|
|
129
|
+
/** Remove all items from the store. */
|
|
130
|
+
clear() {
|
|
131
|
+
for (const key of Object.keys(localStorage)) {
|
|
132
|
+
if (key.startsWith(keyPrefix)) {
|
|
133
|
+
localStorage.removeItem(key);
|
|
134
|
+
}
|
|
182
135
|
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
136
|
+
},
|
|
137
|
+
/**
|
|
138
|
+
* Returns all items as map of key to value, mainly used for debugging dumps.
|
|
139
|
+
* The type T is applied to all values, even though they might not be of type
|
|
140
|
+
* T (in the case when you store different data types in the same store).
|
|
141
|
+
*/
|
|
142
|
+
asMap() {
|
|
143
|
+
const map = /* @__PURE__ */ new Map();
|
|
144
|
+
obj.forEach(
|
|
145
|
+
(key, value, expiryMs, storedMs) => {
|
|
146
|
+
map.set(key, { value, expiryMs, storedMs });
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
return map;
|
|
150
|
+
},
|
|
151
|
+
/** Returns the ms timestamp for the last GC (garbage collection). */
|
|
152
|
+
getLastGcMs() {
|
|
153
|
+
const lastGcMsStr = localStorage.getItem(gcMsStorageKey);
|
|
154
|
+
if (!lastGcMsStr) return 0;
|
|
155
|
+
const ms = Number(lastGcMsStr);
|
|
156
|
+
return isNaN(ms) ? 0 : ms;
|
|
157
|
+
},
|
|
158
|
+
/** Set the ms timestamp for the last GC (garbage collection). */
|
|
159
|
+
setLastGcMs(ms) {
|
|
160
|
+
localStorage.setItem(gcMsStorageKey, String(ms));
|
|
161
|
+
},
|
|
162
|
+
/** Perform garbage-collection if due, else do nothing. */
|
|
163
|
+
gc() {
|
|
164
|
+
const lastGcMs = obj.getLastGcMs();
|
|
165
|
+
if (!lastGcMs) {
|
|
166
|
+
obj.setLastGcMs(Date.now());
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (Date.now() < lastGcMs + gcIntervalMs) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
obj.gcNow();
|
|
173
|
+
},
|
|
174
|
+
/**
|
|
175
|
+
* Perform garbage collection immediately without checking whether we are
|
|
176
|
+
* due for the next GC or not.
|
|
177
|
+
*/
|
|
178
|
+
gcNow() {
|
|
179
|
+
console.log(`Starting localStore GC on ${storeName}`);
|
|
180
|
+
obj.setLastGcMs(Date.now());
|
|
181
|
+
let count = 0;
|
|
182
|
+
obj.forEach((key, value, expiryMs) => {
|
|
183
|
+
if (Date.now() >= expiryMs) {
|
|
184
|
+
obj.delete(key);
|
|
185
|
+
count++;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
console.log(
|
|
189
|
+
`Finished localStore GC on ${storeName} - deleted ${count} keys`
|
|
190
|
+
);
|
|
191
|
+
obj.setLastGcMs(Date.now());
|
|
192
|
+
},
|
|
193
|
+
/** Returns `this` casted into a StorageAdapter<T>. */
|
|
194
|
+
asStorageAdapter() {
|
|
195
|
+
return obj;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
return obj;
|
|
199
|
+
}
|
|
200
|
+
var localStore = createLocalStore(LocalStoreConfig.storeName);
|
|
224
201
|
function localStoreItem(key, expiryMs, store = localStore) {
|
|
225
|
-
|
|
226
|
-
|
|
202
|
+
const defaultExpiryMs = expiryMs && durationOrMsToMs(expiryMs);
|
|
203
|
+
const obj = {
|
|
204
|
+
key,
|
|
205
|
+
defaultExpiryMs,
|
|
206
|
+
store,
|
|
207
|
+
/** Set a value in the store. */
|
|
208
|
+
set(value, expiryDeltaMs) {
|
|
209
|
+
store.set(key, value, expiryDeltaMs ?? defaultExpiryMs);
|
|
210
|
+
},
|
|
211
|
+
/**
|
|
212
|
+
* Example usage:
|
|
213
|
+
*
|
|
214
|
+
* const { value, storedMs, expiryMs, storedMs } =
|
|
215
|
+
* await myLocalItem.getStoredObject();
|
|
216
|
+
*/
|
|
217
|
+
getStoredObject() {
|
|
218
|
+
return store.getStoredObject(key);
|
|
219
|
+
},
|
|
220
|
+
/** Get a value by key, or undefined if it does not exist. */
|
|
221
|
+
get() {
|
|
222
|
+
return store.get(key);
|
|
223
|
+
},
|
|
224
|
+
/** Delete this key from the store. */
|
|
225
|
+
delete() {
|
|
226
|
+
store.delete(key);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
return obj;
|
|
227
230
|
}
|
|
228
231
|
export {
|
|
229
|
-
LocalStore,
|
|
230
232
|
LocalStoreConfig,
|
|
231
|
-
LocalStoreItem,
|
|
232
233
|
configureLocalStore,
|
|
234
|
+
createLocalStore,
|
|
233
235
|
localStore,
|
|
234
236
|
localStoreItem
|
|
235
237
|
};
|
package/mean.cjs
CHANGED
|
@@ -25,15 +25,15 @@ __export(mean_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(mean_exports);
|
|
26
26
|
|
|
27
27
|
// src/asNumber.ts
|
|
28
|
-
function asNumber(u) {
|
|
28
|
+
function asNumber(u, defaultValue = 0) {
|
|
29
29
|
if (typeof u === "number") {
|
|
30
|
-
return isFinite(u) ? u :
|
|
30
|
+
return isFinite(u) ? u : defaultValue;
|
|
31
31
|
}
|
|
32
32
|
u = Number(u);
|
|
33
33
|
if (typeof u === "number" && isFinite(u)) {
|
|
34
34
|
return u;
|
|
35
35
|
}
|
|
36
|
-
return
|
|
36
|
+
return defaultValue;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
// src/sum.ts
|
package/mean.min.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var o=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var c=(n,r)=>{for(var e in r)o(n,e,{get:r[e],enumerable:!0})},k=(n,r,e,
|
|
1
|
+
"use strict";var o=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var c=(n,r)=>{for(var e in r)o(n,e,{get:r[e],enumerable:!0})},k=(n,r,e,m)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of b(r))!p.call(n,t)&&t!==e&&o(n,t,{get:()=>r[t],enumerable:!(m=f(r,t))||m.enumerable});return n};var s=n=>k(o({},"__esModule",{value:!0}),n);var x={};c(x,{mean:()=>w});module.exports=s(x);function u(n,r=0){return typeof n=="number"?isFinite(n)?n:r:(n=Number(n),typeof n=="number"&&isFinite(n)?n:r)}function i(n){return n.reduce((r,e)=>r+u(e),0)}function w(n){return n.length>0?i(n)/n.length:0}0&&(module.exports={mean});
|
|
2
2
|
//# sourceMappingURL=mean.min.cjs.map
|
package/mean.min.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mean.ts","../src/asNumber.ts","../src/sum.ts"],"sourcesContent":["import { sum } from \"./sum\";\n\n/**\n * Compute the mean (average) of all the numbers in the given array.\n * Non-numbers will be coerced into numbers if possible.\n */\nexport function mean(numbers: unknown[]): number {\n return numbers.length > 0 ? sum(numbers) / numbers.length : 0;\n}\n","/**\n * Coerce `u` into a number if possible, otherwise just return 0.\n */\nexport function asNumber(u: unknown): number {\n // If u is a valid number, return it.\n if (typeof u === \"number\") {\n return isFinite(u) ? u :
|
|
1
|
+
{"version":3,"sources":["../src/mean.ts","../src/asNumber.ts","../src/sum.ts"],"sourcesContent":["import { sum } from \"./sum\";\n\n/**\n * Compute the mean (average) of all the numbers in the given array.\n * Non-numbers will be coerced into numbers if possible.\n */\nexport function mean(numbers: unknown[]): number {\n return numbers.length > 0 ? sum(numbers) / numbers.length : 0;\n}\n","/**\n * Coerce `u` into a number if possible, otherwise just return 0.\n */\nexport function asNumber(u: unknown, defaultValue = 0): number {\n // If u is a valid number, return it.\n if (typeof u === \"number\") {\n return isFinite(u) ? u : defaultValue;\n }\n\n // Try to make into a number if not already a number.\n u = Number(u);\n\n // If u is a valid number, return it.\n if (typeof u === \"number\" && isFinite(u)) {\n return u;\n }\n\n // Return `defaultValue` for everything else. This is usually ok if want to\n // just ignore all other noise.\n return defaultValue;\n}\n","import { asNumber } from \"./asNumber\";\n\n/**\n * Add all the numbers together in the given array.\n * Non-numbers will be coerced into numbers if possible.\n */\nexport function sum(numbers: unknown[]): number {\n return numbers.reduce((accumulated: number, current: unknown) => {\n return accumulated + asNumber(current);\n }, 0);\n}\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,UAAAE,IAAA,eAAAC,EAAAH,GCGO,SAASI,EAASC,EAAYC,EAAe,EAAW,CAE7D,OAAI,OAAOD,GAAM,SACR,SAASA,CAAC,EAAIA,EAAIC,GAI3BD,EAAI,OAAOA,CAAC,EAGR,OAAOA,GAAM,UAAY,SAASA,CAAC,EAC9BA,EAKFC,EACT,CCdO,SAASC,EAAIC,EAA4B,CAC9C,OAAOA,EAAQ,OAAO,CAACC,EAAqBC,IACnCD,EAAcE,EAASD,CAAO,EACpC,CAAC,CACN,CFJO,SAASE,EAAKC,EAA4B,CAC/C,OAAOA,EAAQ,OAAS,EAAIC,EAAID,CAAO,EAAIA,EAAQ,OAAS,CAC9D","names":["mean_exports","__export","mean","__toCommonJS","asNumber","u","defaultValue","sum","numbers","accumulated","current","asNumber","mean","numbers","sum"]}
|
package/mean.min.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function
|
|
1
|
+
function e(n,r=0){return typeof n=="number"?isFinite(n)?n:r:(n=Number(n),typeof n=="number"&&isFinite(n)?n:r)}function t(n){return n.reduce((r,o)=>r+e(o),0)}function b(n){return n.length>0?t(n)/n.length:0}export{b as mean};
|
|
2
2
|
//# sourceMappingURL=mean.min.mjs.map
|
package/mean.min.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/asNumber.ts","../src/sum.ts","../src/mean.ts"],"sourcesContent":["/**\n * Coerce `u` into a number if possible, otherwise just return 0.\n */\nexport function asNumber(u: unknown): number {\n // If u is a valid number, return it.\n if (typeof u === \"number\") {\n return isFinite(u) ? u :
|
|
1
|
+
{"version":3,"sources":["../src/asNumber.ts","../src/sum.ts","../src/mean.ts"],"sourcesContent":["/**\n * Coerce `u` into a number if possible, otherwise just return 0.\n */\nexport function asNumber(u: unknown, defaultValue = 0): number {\n // If u is a valid number, return it.\n if (typeof u === \"number\") {\n return isFinite(u) ? u : defaultValue;\n }\n\n // Try to make into a number if not already a number.\n u = Number(u);\n\n // If u is a valid number, return it.\n if (typeof u === \"number\" && isFinite(u)) {\n return u;\n }\n\n // Return `defaultValue` for everything else. This is usually ok if want to\n // just ignore all other noise.\n return defaultValue;\n}\n","import { asNumber } from \"./asNumber\";\n\n/**\n * Add all the numbers together in the given array.\n * Non-numbers will be coerced into numbers if possible.\n */\nexport function sum(numbers: unknown[]): number {\n return numbers.reduce((accumulated: number, current: unknown) => {\n return accumulated + asNumber(current);\n }, 0);\n}\n","import { sum } from \"./sum\";\n\n/**\n * Compute the mean (average) of all the numbers in the given array.\n * Non-numbers will be coerced into numbers if possible.\n */\nexport function mean(numbers: unknown[]): number {\n return numbers.length > 0 ? sum(numbers) / numbers.length : 0;\n}\n"],"mappings":"AAGO,SAASA,EAASC,EAAYC,EAAe,EAAW,CAE7D,OAAI,OAAOD,GAAM,SACR,SAASA,CAAC,EAAIA,EAAIC,GAI3BD,EAAI,OAAOA,CAAC,EAGR,OAAOA,GAAM,UAAY,SAASA,CAAC,EAC9BA,EAKFC,EACT,CCdO,SAASC,EAAIC,EAA4B,CAC9C,OAAOA,EAAQ,OAAO,CAACC,EAAqBC,IACnCD,EAAcE,EAASD,CAAO,EACpC,CAAC,CACN,CCJO,SAASE,EAAKC,EAA4B,CAC/C,OAAOA,EAAQ,OAAS,EAAIC,EAAID,CAAO,EAAIA,EAAQ,OAAS,CAC9D","names":["asNumber","u","defaultValue","sum","numbers","accumulated","current","asNumber","mean","numbers","sum"]}
|
package/mean.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// src/asNumber.ts
|
|
2
|
-
function asNumber(u) {
|
|
2
|
+
function asNumber(u, defaultValue = 0) {
|
|
3
3
|
if (typeof u === "number") {
|
|
4
|
-
return isFinite(u) ? u :
|
|
4
|
+
return isFinite(u) ? u : defaultValue;
|
|
5
5
|
}
|
|
6
6
|
u = Number(u);
|
|
7
7
|
if (typeof u === "number" && isFinite(u)) {
|
|
8
8
|
return u;
|
|
9
9
|
}
|
|
10
|
-
return
|
|
10
|
+
return defaultValue;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
// src/sum.ts
|
package/median.cjs
CHANGED
|
@@ -25,15 +25,15 @@ __export(median_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(median_exports);
|
|
26
26
|
|
|
27
27
|
// src/asNumber.ts
|
|
28
|
-
function asNumber(u) {
|
|
28
|
+
function asNumber(u, defaultValue = 0) {
|
|
29
29
|
if (typeof u === "number") {
|
|
30
|
-
return isFinite(u) ? u :
|
|
30
|
+
return isFinite(u) ? u : defaultValue;
|
|
31
31
|
}
|
|
32
32
|
u = Number(u);
|
|
33
33
|
if (typeof u === "number" && isFinite(u)) {
|
|
34
34
|
return u;
|
|
35
35
|
}
|
|
36
|
-
return
|
|
36
|
+
return defaultValue;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
// src/median.ts
|
|
@@ -41,7 +41,7 @@ function median(numbers) {
|
|
|
41
41
|
if (numbers.length === 0) {
|
|
42
42
|
return 0;
|
|
43
43
|
}
|
|
44
|
-
const sorted = numbers.map(asNumber).slice().sort();
|
|
44
|
+
const sorted = numbers.map(asNumber).slice().sort((a, b) => a - b);
|
|
45
45
|
const middleIndex = Math.floor(sorted.length / 2);
|
|
46
46
|
if (sorted.length % 2 === 1) {
|
|
47
47
|
return sorted[middleIndex];
|
package/median.min.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var i=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var
|
|
1
|
+
"use strict";var i=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var l=(n,e)=>{for(var r in e)i(n,r,{get:e[r],enumerable:!0})},p=(n,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of c(e))!b.call(n,t)&&t!==r&&i(n,t,{get:()=>e[t],enumerable:!(o=u(e,t))||o.enumerable});return n};var a=n=>p(i({},"__esModule",{value:!0}),n);var h={};l(h,{median:()=>d});module.exports=a(h);function m(n,e=0){return typeof n=="number"?isFinite(n)?n:e:(n=Number(n),typeof n=="number"&&isFinite(n)?n:e)}function d(n){if(n.length===0)return 0;let e=n.map(m).slice().sort((s,f)=>s-f),r=Math.floor(e.length/2);if(e.length%2===1)return e[r];let o=e[r-1],t=e[r];return(o+t)/2}0&&(module.exports={median});
|
|
2
2
|
//# sourceMappingURL=median.min.cjs.map
|
package/median.min.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/median.ts","../src/asNumber.ts"],"sourcesContent":["import { asNumber } from \"./asNumber\";\n\n/**\n * Compute the median (middle number) of all the numbers in the given array.\n * Non-numbers will be coerced into numbers if possible.\n */\nexport function median(numbers: unknown[]): number {\n if (numbers.length === 0) {\n return 0;\n }\n\n // Create a copy with slice() to avoid mutating the original array.\n const sorted = numbers.map(asNumber).slice().sort();\n\n const middleIndex = Math.floor(sorted.length / 2);\n\n // Is odd length -> return middle number.\n if (sorted.length % 2 === 1) {\n return sorted[middleIndex];\n }\n\n // Is even length -> return mean of middle 2 numbers.\n const value1 = sorted[middleIndex - 1];\n const value2 = sorted[middleIndex];\n return (value1 + value2) / 2;\n}\n","/**\n * Coerce `u` into a number if possible, otherwise just return 0.\n */\nexport function asNumber(u: unknown): number {\n // If u is a valid number, return it.\n if (typeof u === \"number\") {\n return isFinite(u) ? u :
|
|
1
|
+
{"version":3,"sources":["../src/median.ts","../src/asNumber.ts"],"sourcesContent":["import { asNumber } from \"./asNumber\";\n\n/**\n * Compute the median (middle number) of all the numbers in the given array.\n * Non-numbers will be coerced into numbers if possible.\n */\nexport function median(numbers: unknown[]): number {\n if (numbers.length === 0) {\n return 0;\n }\n\n // Create a copy with slice() to avoid mutating the original array.\n const sorted = numbers\n .map(asNumber)\n .slice()\n .sort((a, b) => a - b);\n\n const middleIndex = Math.floor(sorted.length / 2);\n\n // Is odd length -> return middle number.\n if (sorted.length % 2 === 1) {\n return sorted[middleIndex];\n }\n\n // Is even length -> return mean of middle 2 numbers.\n const value1 = sorted[middleIndex - 1];\n const value2 = sorted[middleIndex];\n return (value1 + value2) / 2;\n}\n","/**\n * Coerce `u` into a number if possible, otherwise just return 0.\n */\nexport function asNumber(u: unknown, defaultValue = 0): number {\n // If u is a valid number, return it.\n if (typeof u === \"number\") {\n return isFinite(u) ? u : defaultValue;\n }\n\n // Try to make into a number if not already a number.\n u = Number(u);\n\n // If u is a valid number, return it.\n if (typeof u === \"number\" && isFinite(u)) {\n return u;\n }\n\n // Return `defaultValue` for everything else. This is usually ok if want to\n // just ignore all other noise.\n return defaultValue;\n}\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,YAAAE,IAAA,eAAAC,EAAAH,GCGO,SAASI,EAASC,EAAYC,EAAe,EAAW,CAE7D,OAAI,OAAOD,GAAM,SACR,SAASA,CAAC,EAAIA,EAAIC,GAI3BD,EAAI,OAAOA,CAAC,EAGR,OAAOA,GAAM,UAAY,SAASA,CAAC,EAC9BA,EAKFC,EACT,CDdO,SAASC,EAAOC,EAA4B,CACjD,GAAIA,EAAQ,SAAW,EACrB,MAAO,GAIT,IAAMC,EAASD,EACZ,IAAIE,CAAQ,EACZ,MAAM,EACN,KAAK,CAACC,EAAGC,IAAMD,EAAIC,CAAC,EAEjBC,EAAc,KAAK,MAAMJ,EAAO,OAAS,CAAC,EAGhD,GAAIA,EAAO,OAAS,IAAM,EACxB,OAAOA,EAAOI,CAAW,EAI3B,IAAMC,EAASL,EAAOI,EAAc,CAAC,EAC/BE,EAASN,EAAOI,CAAW,EACjC,OAAQC,EAASC,GAAU,CAC7B","names":["median_exports","__export","median","__toCommonJS","asNumber","u","defaultValue","median","numbers","sorted","asNumber","a","b","middleIndex","value1","value2"]}
|
package/median.min.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function t(n){return typeof n=="number"?isFinite(n)?n:
|
|
1
|
+
function t(n,e=0){return typeof n=="number"?isFinite(n)?n:e:(n=Number(n),typeof n=="number"&&isFinite(n)?n:e)}function c(n){if(n.length===0)return 0;let e=n.map(t).slice().sort((m,s)=>m-s),r=Math.floor(e.length/2);if(e.length%2===1)return e[r];let o=e[r-1],i=e[r];return(o+i)/2}export{c as median};
|
|
2
2
|
//# sourceMappingURL=median.min.mjs.map
|
package/median.min.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/asNumber.ts","../src/median.ts"],"sourcesContent":["/**\n * Coerce `u` into a number if possible, otherwise just return 0.\n */\nexport function asNumber(u: unknown): number {\n // If u is a valid number, return it.\n if (typeof u === \"number\") {\n return isFinite(u) ? u :
|
|
1
|
+
{"version":3,"sources":["../src/asNumber.ts","../src/median.ts"],"sourcesContent":["/**\n * Coerce `u` into a number if possible, otherwise just return 0.\n */\nexport function asNumber(u: unknown, defaultValue = 0): number {\n // If u is a valid number, return it.\n if (typeof u === \"number\") {\n return isFinite(u) ? u : defaultValue;\n }\n\n // Try to make into a number if not already a number.\n u = Number(u);\n\n // If u is a valid number, return it.\n if (typeof u === \"number\" && isFinite(u)) {\n return u;\n }\n\n // Return `defaultValue` for everything else. This is usually ok if want to\n // just ignore all other noise.\n return defaultValue;\n}\n","import { asNumber } from \"./asNumber\";\n\n/**\n * Compute the median (middle number) of all the numbers in the given array.\n * Non-numbers will be coerced into numbers if possible.\n */\nexport function median(numbers: unknown[]): number {\n if (numbers.length === 0) {\n return 0;\n }\n\n // Create a copy with slice() to avoid mutating the original array.\n const sorted = numbers\n .map(asNumber)\n .slice()\n .sort((a, b) => a - b);\n\n const middleIndex = Math.floor(sorted.length / 2);\n\n // Is odd length -> return middle number.\n if (sorted.length % 2 === 1) {\n return sorted[middleIndex];\n }\n\n // Is even length -> return mean of middle 2 numbers.\n const value1 = sorted[middleIndex - 1];\n const value2 = sorted[middleIndex];\n return (value1 + value2) / 2;\n}\n"],"mappings":"AAGO,SAASA,EAASC,EAAYC,EAAe,EAAW,CAE7D,OAAI,OAAOD,GAAM,SACR,SAASA,CAAC,EAAIA,EAAIC,GAI3BD,EAAI,OAAOA,CAAC,EAGR,OAAOA,GAAM,UAAY,SAASA,CAAC,EAC9BA,EAKFC,EACT,CCdO,SAASC,EAAOC,EAA4B,CACjD,GAAIA,EAAQ,SAAW,EACrB,MAAO,GAIT,IAAMC,EAASD,EACZ,IAAIE,CAAQ,EACZ,MAAM,EACN,KAAK,CAACC,EAAGC,IAAMD,EAAIC,CAAC,EAEjBC,EAAc,KAAK,MAAMJ,EAAO,OAAS,CAAC,EAGhD,GAAIA,EAAO,OAAS,IAAM,EACxB,OAAOA,EAAOI,CAAW,EAI3B,IAAMC,EAASL,EAAOI,EAAc,CAAC,EAC/BE,EAASN,EAAOI,CAAW,EACjC,OAAQC,EAASC,GAAU,CAC7B","names":["asNumber","u","defaultValue","median","numbers","sorted","asNumber","a","b","middleIndex","value1","value2"]}
|
package/median.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// src/asNumber.ts
|
|
2
|
-
function asNumber(u) {
|
|
2
|
+
function asNumber(u, defaultValue = 0) {
|
|
3
3
|
if (typeof u === "number") {
|
|
4
|
-
return isFinite(u) ? u :
|
|
4
|
+
return isFinite(u) ? u : defaultValue;
|
|
5
5
|
}
|
|
6
6
|
u = Number(u);
|
|
7
7
|
if (typeof u === "number" && isFinite(u)) {
|
|
8
8
|
return u;
|
|
9
9
|
}
|
|
10
|
-
return
|
|
10
|
+
return defaultValue;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
// src/median.ts
|
|
@@ -15,7 +15,7 @@ function median(numbers) {
|
|
|
15
15
|
if (numbers.length === 0) {
|
|
16
16
|
return 0;
|
|
17
17
|
}
|
|
18
|
-
const sorted = numbers.map(asNumber).slice().sort();
|
|
18
|
+
const sorted = numbers.map(asNumber).slice().sort((a, b) => a - b);
|
|
19
19
|
const middleIndex = Math.floor(sorted.length / 2);
|
|
20
20
|
if (sorted.length % 2 === 1) {
|
|
21
21
|
return sorted[middleIndex];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@choksheak/ts-utils",
|
|
3
3
|
"license": "The Unlicense",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.5",
|
|
5
5
|
"description": "Random Typescript utilities with support for full tree-shaking",
|
|
6
6
|
"private": false,
|
|
7
7
|
"sideEffects": false,
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"test:watch": "vitest",
|
|
15
15
|
"ci": "npm run lint && npm run tsc && npm run build && npm run test",
|
|
16
16
|
"ls": "lint-staged",
|
|
17
|
-
"docs": "
|
|
17
|
+
"docs": "typedoc",
|
|
18
18
|
"clean": "rm -rf dist",
|
|
19
19
|
"build": "tsup src/*",
|
|
20
20
|
"gen-types": "tsc --emitDeclarationOnly --declaration",
|
|
@@ -333,32 +333,6 @@
|
|
|
333
333
|
"default": "./safeBtoa.cjs"
|
|
334
334
|
}
|
|
335
335
|
},
|
|
336
|
-
"./safeParseFloat": {
|
|
337
|
-
"types": "./safeParseFloat.d.ts",
|
|
338
|
-
"import": {
|
|
339
|
-
"production": "./safeParseFloat.min.mjs",
|
|
340
|
-
"development": "./safeParseFloat.mjs",
|
|
341
|
-
"default": "./safeParseFloat.mjs"
|
|
342
|
-
},
|
|
343
|
-
"require": {
|
|
344
|
-
"production": "./safeParseFloat.min.cjs",
|
|
345
|
-
"development": "./safeParseFloat.cjs",
|
|
346
|
-
"default": "./safeParseFloat.cjs"
|
|
347
|
-
}
|
|
348
|
-
},
|
|
349
|
-
"./safeParseInt": {
|
|
350
|
-
"types": "./safeParseInt.d.ts",
|
|
351
|
-
"import": {
|
|
352
|
-
"production": "./safeParseInt.min.mjs",
|
|
353
|
-
"development": "./safeParseInt.mjs",
|
|
354
|
-
"default": "./safeParseInt.mjs"
|
|
355
|
-
},
|
|
356
|
-
"require": {
|
|
357
|
-
"production": "./safeParseInt.min.cjs",
|
|
358
|
-
"development": "./safeParseInt.cjs",
|
|
359
|
-
"default": "./safeParseInt.cjs"
|
|
360
|
-
}
|
|
361
|
-
},
|
|
362
336
|
"./sha256": {
|
|
363
337
|
"types": "./sha256.d.ts",
|
|
364
338
|
"import": {
|
|
@@ -510,12 +484,6 @@
|
|
|
510
484
|
"safeBtoa": [
|
|
511
485
|
"./safeBtoa.d.ts"
|
|
512
486
|
],
|
|
513
|
-
"safeParseFloat": [
|
|
514
|
-
"./safeParseFloat.d.ts"
|
|
515
|
-
],
|
|
516
|
-
"safeParseInt": [
|
|
517
|
-
"./safeParseInt.d.ts"
|
|
518
|
-
],
|
|
519
487
|
"sha256": [
|
|
520
488
|
"./sha256.d.ts"
|
|
521
489
|
],
|
package/safeBtoa.d.mts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Base 64 encode the given input string, but safely.
|
|
3
|
+
*
|
|
4
|
+
* Why using btoa() directly might not always work:
|
|
5
|
+
* btoa() expects a "binary string" where each character is represented by a
|
|
6
|
+
* single byte (0-255). Modern JavaScript strings, however, are encoded in
|
|
7
|
+
* UTF-16 and can contain characters that require more than one byte (i.e.,
|
|
8
|
+
* characters outside the Latin-1 range, such as those with code points greater
|
|
9
|
+
* than 255).
|
|
3
10
|
*/
|
|
4
11
|
declare function safeBtoa(input: string): string;
|
|
5
12
|
|