Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
itemsholdr
Advanced tools
Cache-based wrapper around localStorage.
ItemsHoldr instances intentionally implement the DOM Storage
interface (except for the hacky string- and number-based indexing).
You can use them wherever you would use localStorage
.
ItemsHoldr adds a layer of caching and value-based hooks that makes it useful for applications where state isn't always saved immediately.
It also defaults values to undefined
instead of null
for sanity.
const itemsHolder = new ItemsHoldr();
itemsHolder.setItem("name", "Blue");
itemsHolder.getItem("name"); // "Blue"
autoSave
Whether values should be saved immediately upon being set.
An internal reference to a storage container is kept that defaults to localStorage
.
Keys won't be saved to that container until .saveItem(key)
or saveAll()
are called.
Providing autoSave
changes that behavior to always save the items to the internal container.
const itemsHolder = new ItemsHoldr({
autoSave: true,
});
itemsHolder.setItem("name", "Blue");
localStorage.getItem("name"); // "Blue"
defaults
Default attributes for item values.
These are applied to all items, and will be overridden per item by an item-specific values
.
const itemsHolder = new ItemsHoldr({
defaults: {
valueDefault: "Red",
},
});
itemsHolder.getItem("name"); // "Red"
prefix
Prefix to add before keys in storage.
Useful to distinguish keys from other stored items in the same storage container, such as a webpage's localStorage
.
const itemsHolder = new ItemsHoldr({
prefix: "MyState::",
});
itemsHolder.saveItem("name", "Red");
Object.keys(localStorage); // ["MyState::name"]
storage
Storage object to use instead of the global localStorage.
This can be anything that satisfies the Storage
API and acts like localStorage
.
ItemsHoldr exposes a createStorage
that can be useful for testing.
import { createStorage, ItemsHoldr } from "itemsholdr";
const storage = createStorage();
const itemsHolder = new ItemsHoldr({
storage,
});
itemsHolder.saveItem("name", "Red");
storage.getItem("name"); // "Red"
storage.name; // "Red"
values
Initial settings for item values to store.
These are factored on top of defaults
for created items.
const itemsHolder = new ItemsHoldr({
values: {
name: {
valueDefault: "Blue",
},
},
});
itemsHolder.getItem("name"); // "Blue"
Declaring items with defaults
and/or values
allows for individual settings applied to that item.
These are also applied when using .addItem(name, settings)
.
maximum
Maximum value the item may equal if a number.
If set to something higher, it will immediately be set to the maximum
.
const itemsHolder = new ItemsHoldr({
values: {
coins: {
maximum: 100,
},
},
});
itemsHolder.setItem("coins", 101);
itemsHolder.getItem("coins"); // 100
onMaximum
Callback for when the value reaches the maximum value.
Takes in the value before capped to the the maximum
.
const itemsHolder = new ItemsHoldr({
values: {
coins: {
maximum: 100,
onMaximum: (coins) => {
console.log("Got", coins, "coins.");
},
},
},
});
// Got 101 coins.
itemsHolder.setItem("coins", 101);
itemsHolder.getItem("coins"); // 100
minimum
Minimum value the item may equal if a number.
If set to something lower, it will immediately be set to the minimum
.
const itemsHolder = new ItemsHoldr({
values: {
lives: {
minimum: 100,
},
},
});
itemsHolder.setItem("lives", -1);
itemsHolder.getItem("lives"); // 0
onMinimum
Callback for when the value reaches the minimum value.
Takes in the value before floored to the the minimum
.
const itemsHolder = new ItemsHoldr({
values: {
lives: {
minimum: 0,
onMinimum: (lives) => {
console.log("Dropped to", lives, "lives.");
},
},
},
});
// Dropped to -1 lives.
itemsHolder.setItem("lives", -1);
itemsHolder.getItem("lives"); // 0
modularity
Maximum number to modulo the value against if a number.
If set to something higher, it will be reduced by modularity
until less than.
const itemsHolder = new ItemsHoldr({
values: {
coins: {
modularity: 100,
},
},
});
itemsHolder.setItem("coins", 250);
itemsHolder.getItem("coins"); // 50
onModular
Callback for when the value reaches modularity.
Unlike onMaximum
, this will be repeatedly called while the value is greater, decreasing by modularity
each time.
const itemsHolder = new ItemsHoldr({
values: {
coins: {
modularity: 100,
onModular: (reduced) => {
console.log("Reduced", coins, "coins.");
},
},
},
});
// Reduced 100 coins.
// Reduced 50 coins.
itemsHolder.setItem("coins", 250);
itemsHolder.getItem("coins"); // 50
triggers
A mapping of values to callbacks that should be triggered when the value is equal to them. These all take in the item's value.
const logForSpeed = (speed: number) => {
console.log("Achieved", speed, "speed.");
};
const itemsHolder = new ItemsHoldr({
values: {
speed: {
triggers: {
0: logForSpeed,
10: logForSpeed,
},
},
},
});
// Achieved 0 speed.
itemsHolder.setItem("coins", 0);
itemsHolder.setItem("coins", 5);
// Achieved 10 speed.
itemsHolder.setItem("coins", 10);
valueDefault
An initial value to use if before any is set.
Will be overridden by what's in storage
if storeLocally
is true.
const itemsHolder = new ItemsHoldr({
values: {
name: {
valueDefault: "Blue",
},
},
});
itemsHolder.getItem("name"); // "Blue"
addItem
Parameters:
name: string
: Unique key to store the item under.settings: Object
(optional): Any additional settings for the item.Adds a new item to storage. If an existing item exists under the same, its settings are discarded.
const itemsHolder = new ItemsHoldr();
itemsHolder.addItem("name", {
valueDefault: "Blue",
});
itemsHolder.getItem("name"); // "Blue"
getItem
Parameters:
key: string
: Key of an item.Gets the value under the name.
Unlike localStorage
, this will throw an error if the item doesn't exist.
Use hasKey
if you want to check whether an item exists.
removeItem
Parameters:
key: string
: Key of an item.Removes the item under that key from storage.
If getItem
is called after removeItem
with the same key, it's as if the item was never added in the first place.
Any settings passed into the constructor will be re-applied.
const itemsHolder = new ItemsHoldr({
defaults: {
valueDefault: "Blue",
},
});
itemsHolder.setItem("name", "Blue");
itemsHolder.removeItem("name");
itemsHolder.getItem("name"); // "Red"
setItem
Parameters:
key: string
: Key of an item.Sets the value of an item. If the item doesn't yet exist, it's created.
const itemsHolder = new ItemsHoldr();
itemsHolder.setItem("name", "Blue");
itemsHolder.getItem("name"); // "Blue"
increase
Parameters:
key: string
: Key of an item.amount: number | string
Amount to increase by (by default, 1
).Increases the value of an item as a number or string.
This uses the native +
operator regardless of the value type.
const itemsHolder = new ItemsHoldr();
itemsHolder.setItem("coins", 7);
itemsHolder.increase("coins", 3);
itemsHolder.getItem("coins"); // 10
decrease
Parameters:
key: string
: Key of an item.amount: number
Amount to decreases by (by default, 1
).Decreases the value of an item as a number.
This uses the native -
operator regardless of the value type.
const itemsHolder = new ItemsHoldr();
itemsHolder.setItem("coins", 7);
itemsHolder.decrease("coins", 3);
itemsHolder.getItem("coins"); // 4
toggle
Parameters:
key: string
: Key of an item.Toggles whether an item is true or false. This evaluates the item in a ternary for truthiness.
const itemsHolder = new ItemsHoldr();
itemsHolder.setItem("alive", false);
itemsHolder.toggle("alive");
itemsHolder.getItem("alive"); // true
hasKey
Parameters:
key: string
: Key of an item.Gets whether an item exists under the key.
const itemsHolder = new ItemsHoldr();
itemsHolder.setItem("alive", false);
itemsHolder.hasKey("alive"); // true
itemsHolder.hasKey("unknown"); // false
exportItems
Gets a summary of keys and their values.
const itemsHolder = new ItemsHoldr();
itemsHolder.setItem("alive", false);
itemsHolder.setItem("coins", 10);
itemsHolder.setItem("name", "Blue");
/*
{
alive: false,
coins: 10,
name: "Blue",
}
*/
itemsHolder.exportItems();
clear
Completely clears all items.
This is equivalent to calling removeItem
on all keys.
Any settings passed into the constructor will be re-applied.
const itemsHolder = new ItemsHoldr({
defaults: {
valueDefault: "Blue",
},
});
itemsHolder.setItem("name", "Blue");
itemsHolder.clear();
itemsHolder.getItem("name"); // "Red"
saveItem
Parameters:
key: string
: Name of an item.Manually saves an item's value to storage, ignoring autoSave
settings.
const itemsHolder = new ItemsHoldr();
itemsHolder.setItem("name", "Blue");
localStorage.getItem("name"); // null
itemsHolder.saveItem("name");
localStorage.getItem("name"); // "Blue"
saveAll
Manually saves all items to storage, ignoring autoSave
settings.
const itemsHolder = new ItemsHoldr();
itemsHolder.setItem("name", "Blue");
localStorage.getItem("name"); // null
itemsHolder.saveAll();
localStorage.getItem("name"); // "Blue"
This repository is a portion of the EightBittr monorepo. See its docs/Development.md for details on how to get started. 💖
yarn run test
Tests are written in Mocha and Chai.
Their files are written using alongside source files under src/
and named *.test.ts?
.
Whenever you add, remove, or rename a *.test.t*
file under src/
, watch
will re-run yarn run test:setup
to regenerate the list of static test files in test/index.html
.
You can open that file in a browser to debug through the tests, or run yarn test:run
to run them in headless Chrome.
FAQs
Cache-based wrapper around localStorage.
We found that itemsholdr demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.