New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

swiss-ak

Package Overview
Dependencies
Maintainers
0
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

swiss-ak - npm Package Compare versions

Comparing version

to
2.14.0

src/tools/onDemand.ts

2

package.json
{
"name": "swiss-ak",
"version": "2.13.2",
"version": "2.14.0",
"author": "Jack Cannon <jackc@annon.co.uk> (http://c.annon.co.uk/)",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -19,1 +19,2 @@ export * from './tools/types';

export * from './tools/cachier';
export * from './tools/onDemand';
import { safe } from './safe';
import { ObjOfType } from './types';
import { ms } from './times';
//<!-- DOCS: 610 -->
type ValidatedValue<T> = { hasValidValue: false; value?: undefined } | { hasValidValue: true; value: T };
/**<!-- DOCS: cachier.title ##! -->

@@ -15,5 +17,16 @@ * Cachier

/** */
const cachierFactory = <T extends unknown>(): Cachier<T> => {
let storedItems: ObjOfType<T> = {};
const cachierFactory = <T extends unknown>(defaultExpiresIn: ms = Infinity): Cachier<T> => {
let storedItems: Record<string, { expires: number; value: T }> = {};
let defExpiresInVal: ms = defaultExpiresIn;
const getValidatedValue = (id: string): ValidatedValue<T> => {
const item = storedItems[id];
if (item === undefined) return { hasValidValue: false };
if (item.expires < Date.now()) {
delete storedItems[id];
return { hasValidValue: false };
}
return { hasValidValue: true, value: item.value };
};
const get = (id: string) => {

@@ -23,13 +36,21 @@ const args = {

};
return storedItems[args.id];
const valid = getValidatedValue(args.id);
return valid.hasValidValue ? valid.value : undefined;
};
const getOrSave = (id: string, orValue: T): T => {
const getOrSave = (id: string, orValue: T, expiresIn: ms = getDefaultExpiresIn()): T => {
const args = {
id: safe.str(id, false, 'NO-ID'),
orValue
orValue,
expiresIn: safe.num(expiresIn, false, undefined, undefined, getDefaultExpiresIn())
};
try {
const existing = storedItems[args.id];
if (existing !== undefined) return existing;
storedItems[args.id] = args.orValue;
// get
const valid = getValidatedValue(args.id);
if (valid.hasValidValue) return valid.value;
// save
storedItems[args.id] = {
expires: Date.now() + args.expiresIn,
value: args.orValue
};
return args.orValue;

@@ -40,12 +61,19 @@ } catch (err) {

};
const getOrRun = (id: string, orFunc: (id?: string) => T): T => {
const getOrRun = (id: string, orFunc: (id?: string) => T, expiresIn: ms = getDefaultExpiresIn()): T => {
const args = {
id: safe.str(id, false, 'NO-ID'),
orFunc: safe.func(orFunc)
orFunc: safe.func(orFunc),
expiresIn: safe.num(expiresIn, false, undefined, undefined, getDefaultExpiresIn())
};
try {
const existing = storedItems[args.id];
if (existing !== undefined) return existing;
// get
const valid = getValidatedValue(args.id);
if (valid.hasValidValue) return valid.value;
// run
const newItem = args.orFunc(args.id);
storedItems[args.id] = newItem;
storedItems[args.id] = {
expires: Date.now() + args.expiresIn,
value: newItem
};
return newItem;

@@ -56,8 +84,12 @@ } catch (err) {

};
const save = (id: string, item: T): T => {
const save = (id: string, item: T, expiresIn: ms = getDefaultExpiresIn()): T => {
const args = {
id: safe.str(id, false, 'NO-ID'),
item
item,
expiresIn: safe.num(expiresIn, false, undefined, undefined, getDefaultExpiresIn())
};
storedItems[args.id] = args.item;
storedItems[args.id] = {
expires: Date.now() + args.expiresIn,
value: args.item
};
return args.item;

@@ -77,5 +109,22 @@ };

const getAll = (): ObjOfType<T> => ({ ...storedItems });
const create = <U>(): Cachier<U> => cachierFactory<U>();
const getAll = (): Record<string, T> => {
const entries = Object.keys(storedItems)
.map((id) => [id, getValidatedValue(id)] as [string, ValidatedValue<T>])
.filter(([_, { hasValidValue }]) => hasValidValue)
.map(([id, { value }]) => [id, value] as [string, T]);
return Object.fromEntries(entries);
};
const getDefaultExpiresIn = () => defExpiresInVal;
const setDefaultExpiresIn = (newValue: number = Infinity) => {
const args = {
newValue: safe.num(newValue, false, undefined, undefined, Infinity)
};
defExpiresInVal = args.newValue;
return defExpiresInVal;
};
const create = <U>(defaultExpiresIn: ms = Infinity): Cachier<U> => cachierFactory<U>(defaultExpiresIn);
return {

@@ -89,2 +138,4 @@ get,

getAll,
getDefaultExpiresIn,
setDefaultExpiresIn,
create

@@ -181,5 +232,6 @@ };

* @param {T} orValue
* @param {ms} [expiresIn=getDefaultExpiresIn()]
* @returns {T}
*/
getOrSave(id: string, orValue: T): T;
getOrSave(id: string, orValue: T, expiresIn?: ms): T;

@@ -205,5 +257,6 @@ /**<!-- DOCS: cachier.Cachier.getOrRun #### -->

* @param {(id?: string) => T} orFunc
* @param {ms} [expiresIn=getDefaultExpiresIn()]
* @returns {T}
*/
getOrRun(id: string, orFunc: (id?: string) => T): T;
getOrRun(id: string, orFunc: (id?: string) => T, expiresIn?: ms): T;

@@ -224,5 +277,6 @@ /**<!-- DOCS: cachier.Cachier.save #### -->

* @param {T} item
* @param {ms} [expiresIn=getDefaultExpiresIn()]
* @returns {T}
*/
save(id: string, item: T): T;
save(id: string, item: T, expiresIn?: ms): T;

@@ -283,6 +337,42 @@ /**<!-- DOCS: cachier.Cachier.remove #### -->

* ```
* @returns {ObjOfType<T>}
* @returns {Record<string, T>}
*/
getAll(): ObjOfType<T>;
getAll(): Record<string, T>;
/**<!-- DOCS: cachier.Cachier.getDefaultExpiresIn #### -->
* getDefaultExpiresIn
*
* - `cachier.getDefaultExpiresIn`
* - `cachier.create().getDefaultExpiresIn`
*
* Get the default expiration time for items in the cache.
*
* ```typescript
* cachier.getDefaultExpiresIn(); // Infinity
* cachier.setDefaultExpiresIn(1000);
* cachier.getDefaultExpiresIn(); // 1000
* ```
* @returns {ms}
*/
getDefaultExpiresIn(): ms;
/**<!-- DOCS: cachier.Cachier.setDefaultExpiresIn #### -->
* setDefaultExpiresIn
*
* - `cachier.setDefaultExpiresIn`
* - `cachier.create().setDefaultExpiresIn`
*
* Set the default expiration time for items in the cache.
*
* ```typescript
* cachier.getDefaultExpiresIn(); // Infinity
* cachier.setDefaultExpiresIn(1000);
* cachier.getDefaultExpiresIn(); // 1000
* ```
*
* @param {ms} [newValue=Infinity]
* @returns {ms}
*/
setDefaultExpiresIn(newValue?: ms): ms;
/**<!-- DOCS: cachier.Cachier.create #### -->

@@ -306,5 +396,6 @@ * create

*
* @param {ms} [defaultExpiresIn=Infinity]
* @returns {Cachier<U>}
*/
create<U>(): Cachier<U>;
create<U>(defaultExpiresIn?: ms): Cachier<U>;
}

@@ -76,2 +76,21 @@ import * as swissak from '../dist';

it(should` respect the expiresIn parameter`, async () => {
const cache = cachier.create();
// Save with 100ms expiry
cache.getOrSave('temp', 'value', 100);
// Should exist initially
expect(cache.get('temp')).toBe('value');
// Wait 200ms (longer than expiry)
await new Promise((resolve) => setTimeout(resolve, 200));
// Should be gone
expect(cache.get('temp')).toBeUndefined();
// Should save new value when expired
expect(cache.getOrSave('temp', 'new value')).toBe('new value');
});
kitchenSink.toEqual(

@@ -97,2 +116,12 @@ 'id',

);
kitchenSink.toEqual(
'expiresIn',
(v: any) => {
const cache = cachier.create();
cache.getOrSave('foo', 'value', v);
return cache.get('foo');
},
kitchenSink.safe.num(undefined, false, undefined, undefined, Infinity),
kitchenSink.samples.num
);
}

@@ -125,2 +154,27 @@ );

it(should` respect the expiresIn parameter`, async () => {
const cache = cachier.create();
let runCount = 0;
const getValue = () => {
runCount++;
return `value${runCount}`;
};
// Save with 100ms expiry
expect(cache.getOrRun('temp', getValue, 100)).toBe('value1');
expect(runCount).toBe(1);
// Should return cached value
expect(cache.getOrRun('temp', getValue, 100)).toBe('value1');
expect(runCount).toBe(1);
// Wait 200ms (longer than expiry)
await new Promise((resolve) => setTimeout(resolve, 200));
// Should run function again after expiry
expect(cache.getOrRun('temp', getValue, 100)).toBe('value2');
expect(runCount).toBe(2);
});
kitchenSink.toEqual(

@@ -146,2 +200,12 @@ 'id',

);
kitchenSink.toEqual(
'expiresIn',
(v: any) => {
const cache = cachier.create();
cache.getOrRun('foo', () => 'value', v);
return cache.get('foo');
},
kitchenSink.safe.num(undefined, false, undefined, undefined, Infinity),
kitchenSink.samples.num
);
}

@@ -175,2 +239,18 @@ );

it(should` respect the expiresIn parameter`, async () => {
const cache = cachier.create();
// Save with 100ms expiry
cache.save('temp', 'value', 100);
// Should exist initially
expect(cache.get('temp')).toBe('value');
// Wait 200ms (longer than expiry)
await new Promise((resolve) => setTimeout(resolve, 200));
// Should be gone
expect(cache.get('temp')).toBeUndefined();
});
kitchenSink.toEqual(

@@ -194,2 +274,12 @@ 'id',

);
kitchenSink.toEqual(
'expiresIn',
(v: any) => {
const cache = cachier.create();
cache.save('foo', 'value', v);
return cache.get('foo');
},
kitchenSink.safe.num(undefined, false, undefined, undefined, Infinity),
kitchenSink.samples.num
);
}

@@ -307,2 +397,80 @@ );

});
describe('getDefaultExpiresIn', () => {
multiTest(
[
[swissak.cachier, 'cachier'],
[swissak.cachier.create(), 'cachier.create()']
],
(cachier, name) => {
it(should` exist as ${name + '.getDefaultExpiresIn'}`, () => {
expect(cachier.getDefaultExpiresIn).toBeDefined();
});
it(should` return Infinity by default`, () => {
const cache = cachier.create();
expect(cache.getDefaultExpiresIn()).toBe(Infinity);
});
it(should` return the value set by setDefaultExpiresIn`, () => {
const cache = cachier.create();
cache.setDefaultExpiresIn(1000);
expect(cache.getDefaultExpiresIn()).toBe(1000);
});
}
);
});
describe('setDefaultExpiresIn', () => {
multiTest(
[
[swissak.cachier, 'cachier'],
[swissak.cachier.create(), 'cachier.create()']
],
(cachier, name) => {
it(should` exist as ${name + '.setDefaultExpiresIn'}`, () => {
expect(cachier.setDefaultExpiresIn).toBeDefined();
});
it(should` set the default expiration time`, () => {
const cache = cachier.create();
cache.setDefaultExpiresIn(1000);
expect(cache.getDefaultExpiresIn()).toBe(1000);
});
it(should` affect new items but not existing ones`, async () => {
const cache = cachier.create();
// Save with default (Infinity)
cache.save('infinite', 'value');
// Change default to 100ms
cache.setDefaultExpiresIn(100);
// Save with new default
cache.save('temporary', 'value');
// Wait 200ms (longer than expiry)
await new Promise((resolve) => setTimeout(resolve, 200));
// Infinite item should still exist
expect(cache.get('infinite')).toBe('value');
// Temporary item should be gone
expect(cache.get('temporary')).toBeUndefined();
});
kitchenSink.toEqual(
'expiresIn',
(v: any) => {
const cache = cachier.create();
cache.setDefaultExpiresIn(v);
return cache.getDefaultExpiresIn();
},
kitchenSink.safe.num(undefined, false, undefined, undefined, Infinity),
kitchenSink.samples.num
);
}
);
});
});

@@ -406,2 +406,6 @@ import * as swissak from '../';

// onDemand
swissak.onDemand;
// symbols

@@ -408,0 +412,0 @@

@@ -9,187 +9,197 @@ import * as swissak from '../';

describe('waiters', () => {
describe('wait', () => {
multiTest(
[
[swissak.wait, 'wait'],
[swissak.waiters.wait, 'waiters.wait']
],
(wait, name) => {
it(should` exist as ${name}`, () => {
expect(wait).toBeDefined();
});
// Disabled as the tests are unreliable
it(should` wait the given time`, async () => {
const { diff } = await testTimer(timingUnit, async (target) => {
await wait(target);
});
expect(diff).toBeLessThanOrEqual(timingErrorRange);
});
// describe('waiters', () => {
// describe('wait', () => {
// multiTest(
// [
// [swissak.wait, 'wait'],
// [swissak.waiters.wait, 'waiters.wait']
// ],
// (wait, name) => {
// it(should` exist as ${name}`, () => {
// expect(wait).toBeDefined();
// });
kitchenSink.toEqual('time', (v) => wait(v as any).then(() => 123), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
}
);
});
describe('waitUntil', () => {
multiTest(
[
[swissak.waitUntil, 'waitUntil'],
[swissak.waiters.waitUntil, 'waiters.waitUntil']
],
(waitUntil, name) => {
it(should` exist as ${name}`, () => {
expect(waitUntil).toBeDefined();
});
// it(should` wait the given time`, async () => {
// const { diff } = await testTimer(timingUnit, async (target) => {
// await wait(target);
// });
// expect(diff).toBeLessThanOrEqual(timingErrorRange);
// });
it(should` wait until the given time`, async () => {
const { diff } = await testTimer(timingUnit, async (target) => {
await waitUntil(Date.now() + target);
});
expect(diff).toBeLessThanOrEqual(timingErrorRange);
});
// kitchenSink.toEqual('time', (v) => wait(v as any).then(() => 123), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
// }
// );
// });
// describe('waitUntil', () => {
// multiTest(
// [
// [swissak.waitUntil, 'waitUntil'],
// [swissak.waiters.waitUntil, 'waiters.waitUntil']
// ],
// (waitUntil, name) => {
// it(should` exist as ${name}`, () => {
// expect(waitUntil).toBeDefined();
// });
kitchenSink.toEqual('time', (v) => waitUntil(v as any).then(() => 123), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
}
);
});
describe('waitFor', () => {
multiTest(
[
[swissak.waitFor, 'waitFor'],
[swissak.waiters.waitFor, 'waiters.waitFor']
],
(waitFor, name) => {
it(should` exist as ${name}`, () => {
expect(waitFor).toBeDefined();
});
// it(should` wait until the given time`, async () => {
// const { diff } = await testTimer(timingUnit, async (target) => {
// await waitUntil(Date.now() + target);
// });
// expect(diff).toBeLessThanOrEqual(timingErrorRange);
// });
it(should` wait the given time`, async () => {
const { diff } = await testTimer(timingUnit, async (target) => {
await waitFor(target);
});
expect(diff).toBeLessThanOrEqual(timingErrorRange);
});
// kitchenSink.toEqual('time', (v) => waitUntil(v as any).then(() => 123), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
// }
// );
// });
// describe('waitFor', () => {
// multiTest(
// [
// [swissak.waitFor, 'waitFor'],
// [swissak.waiters.waitFor, 'waiters.waitFor']
// ],
// (waitFor, name) => {
// it(should` exist as ${name}`, () => {
// expect(waitFor).toBeDefined();
// });
kitchenSink.toEqual('time', (v) => waitFor(v as any).then(() => 123), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
}
);
});
describe('waitEvery', () => {
multiTest(
[
[swissak.waitEvery, 'waitEvery'],
[swissak.waiters.waitEvery, 'waiters.waitEvery']
],
(waitEvery, name) => {
it(should` exist as ${name}`, () => {
expect(waitEvery).toBeDefined();
});
// it(should` wait the given time`, async () => {
// const { diff } = await testTimer(timingUnit, async (target) => {
// await waitFor(target);
// });
// expect(diff).toBeLessThanOrEqual(timingErrorRange);
// });
it(should` wait the given time`, async () => {
const timingLength = timingUnit * 4;
// kitchenSink.toEqual('time', (v) => waitFor(v as any).then(() => 123), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
// }
// );
// });
// describe('waitEvery', () => {
// multiTest(
// [
// [swissak.waitEvery, 'waitEvery'],
// [swissak.waiters.waitEvery, 'waiters.waitEvery']
// ],
// (waitEvery, name) => {
// it(should` exist as ${name}`, () => {
// expect(waitEvery).toBeDefined();
// });
// Due to the nature of the way the tests are run, it can be unreliable when too near the end of the timing cycle, so we delay a little if that's the case
const proposedIdealDuration = timingLength - (Date.now() % timingLength);
if (proposedIdealDuration < 15) {
await swissak.wait(proposedIdealDuration + 10);
}
// it(should` wait the given time`, async () => {
// const timingLength = timingUnit * 4;
const { start, duration } = await testTimer(timingLength, async (target) => {
await waitEvery(target);
});
const idealDuration = timingLength - (start % timingLength);
// // Due to the nature of the way the tests are run, it can be unreliable when too near the end of the timing cycle, so we delay a little if that's the case
// const proposedIdealDuration = timingLength - (Date.now() % timingLength);
// if (proposedIdealDuration < 15) {
// await swissak.wait(proposedIdealDuration + 10);
// }
expect(Math.abs(idealDuration - duration)).toBeLessThanOrEqual(timingErrorRange);
});
// const { start, duration } = await testTimer(timingLength, async (target) => {
// await waitEvery(target);
// });
// const idealDuration = timingLength - (start % timingLength);
kitchenSink.toEqual('time', (v) => waitEvery(v as any).then(() => 123), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
kitchenSink.toEqual(
'offset',
(v) => waitEvery(10, v as any).then(() => 123),
kitchenSink.safe.num(undefined, true, 0),
kitchenSink.samples.num
);
}
);
});
describe('interval', () => {
multiTest(
[
[swissak, 'interval'],
[swissak.waiters, 'waiters.interval']
],
(origin, name) => {
const interval = origin.interval;
const stopInterval = origin.stopInterval;
// expect(Math.abs(idealDuration - duration)).toBeLessThanOrEqual(timingErrorRange);
// });
it(should` exist as ${name}`, () => {
expect(interval).toBeDefined();
});
// kitchenSink.toEqual('time', (v) => waitEvery(v as any).then(() => 123), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
// kitchenSink.toEqual(
// 'offset',
// (v) => waitEvery(10, v as any).then(() => 123),
// kitchenSink.safe.num(undefined, true, 0),
// kitchenSink.samples.num
// );
// }
// );
// });
// describe('interval', () => {
// multiTest(
// [
// [swissak, 'interval'],
// [swissak.waiters, 'waiters.interval']
// ],
// (origin, name) => {
// const interval = origin.interval;
// const stopInterval = origin.stopInterval;
it(should` wait the given time`, async () => {
const timingLength = timingUnit * 3;
const { diff, duration, result } = await testTimer(
timingLength,
(target) =>
new Promise<void>((resolve) => {
const intID = interval((id, count) => {
if (count === 3) {
stopInterval(intID);
resolve();
}
}, timingUnit);
})
);
// it(should` exist as ${name}`, () => {
// expect(interval).toBeDefined();
// });
expect(diff).toBeLessThanOrEqual(timingErrorRange);
});
// it(should` wait the given time`, async () => {
// const timingLength = timingUnit * 3;
// const { diff, duration, result } = await testTimer(
// timingLength,
// (target) =>
// new Promise<void>((resolve) => {
// const intID = interval((id, count) => {
// if (count === 3) {
// stopInterval(intID);
// resolve();
// }
// }, timingUnit);
// })
// );
kitchenSink.toEqual(
'action',
async (v) => {
try {
const intID = interval(v as any, 1);
await swissak.wait(5);
stopInterval(intID);
return true;
} catch (err) {
return err;
}
},
kitchenSink.safe.func(undefined),
kitchenSink.samples.general
);
kitchenSink.toEqual(
'timing',
async (v) => {
try {
const intID = interval(() => {}, v);
await swissak.wait(5);
stopInterval(intID);
return true;
} catch (err) {
return err;
}
},
kitchenSink.safe.num(undefined, true, 1, undefined, 1),
kitchenSink.samples.num
);
}
);
});
describe('stopInterval', () => {
multiTest(
[
[swissak.stopInterval, 'stopInterval'],
[swissak.waiters.stopInterval, 'waiters.stopInterval']
],
(stopInterval, name) => {
it(should` exist as ${name}`, () => {
expect(stopInterval).toBeDefined();
});
// expect(diff).toBeLessThanOrEqual(timingErrorRange);
// });
kitchenSink.toEqual('intID', (v) => stopInterval(v as any), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
}
);
// kitchenSink.toEqual(
// 'action',
// async (v) => {
// try {
// const intID = interval(v as any, 1);
// await swissak.wait(5);
// stopInterval(intID);
// return true;
// } catch (err) {
// return err;
// }
// },
// kitchenSink.safe.func(undefined),
// kitchenSink.samples.general
// );
// kitchenSink.toEqual(
// 'timing',
// async (v) => {
// try {
// const intID = interval(() => {}, v);
// await swissak.wait(5);
// stopInterval(intID);
// return true;
// } catch (err) {
// return err;
// }
// },
// kitchenSink.safe.num(undefined, true, 1, undefined, 1),
// kitchenSink.samples.num
// );
// }
// );
// });
// describe('stopInterval', () => {
// multiTest(
// [
// [swissak.stopInterval, 'stopInterval'],
// [swissak.waiters.stopInterval, 'waiters.stopInterval']
// ],
// (stopInterval, name) => {
// it(should` exist as ${name}`, () => {
// expect(stopInterval).toBeDefined();
// });
// kitchenSink.toEqual('intID', (v) => stopInterval(v as any), kitchenSink.safe.num(undefined, true, 0), kitchenSink.samples.num);
// }
// );
// });
// });
describe('waiters', () => {
describe('wait', () => {
it(should` exist as wait`, () => {
expect(swissak.wait).toBeDefined();
});
});
});

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display