stable-genius
v0.8.0
Published
`stable-genius` is a weak-key generator that ensures a unique and stable string key for each object passed to it.
Downloads
2
Readme
stable-genius
is a weak-key generator that ensures a unique and stable string
key for each object passed to it.
Inspired by weak-key
, this package
adds a little more flexibility to the way keys are generated.
Simple uage
import { weakKey } from 'stable-genius`
const obj1 = {};
const obj2 = {};
const obj3 = {};
console.log(weakKey(obj1)); // Probably something like "$1"
console.log(weakKey(obj2)); // Probably something like "$2"
console.log(weakKey(obj3)); // Probably something like "$3"
// And do it again. Once a key is assigned, it is forever stable.
console.log(weakKey(obj1)); // Probably something like "$1"
console.log(weakKey(obj2)); // Probably something like "$2"
console.log(weakKey(obj3)); // Probably something like "$3"
Customization
You can create your own weak key factory, customizing the way the unique keys are generated, and whether you wish to attach any diagnostic info.
Using a constant tag
Adding tags to the weak key can help you create distinct namespaces if you need to mix the weak keys with some other set of unique keys that may collide.
import { weakKeyFactory } from "stable-genius";
const weakKey = weakKeyFactory("my-tag");
console.log(weakKey({})); // Probably something like "$1_my-tag"
Using a variable tag
You can also use tags to add diagnostic information to the key. This way, you may have a better debugging experience when inspecting these keys.
You bear full responsibility in making sure that the object can produce the diagnostic tag, such as making sure that whichever property you access exists.
import { weakKeyFactory } from "stable-genius";
const weakKey = weakKeyFactory(
(obj) => obj.username + "@" + new Date(obj.timestamp * 1000).toISOString()
);
const obj1 = { username: "donald", timestamp: 1602305533 };
// Probably something like "$1_donald::2020-10-10T04:52:13.000Z"
console.log(weakKey(obj1));
The library comes with a TypeScript signature that allows you to enforce the type
of the object. In fact, in TypeScript, you must enforce the type of the object
in order to access any property on it, since the default type of the object is
the feature-less object
type.
interface UserAction {
username: string;
timestamp: number;
}
// weakKey is now (object: UserAction) => string
const weakKey = weakKeyFactory(
(obj: UserAction) =>
obj.username + "@" + new Date(obj.timestamp * 1000).toISOString()
);
Remember that weak keys will remain stable throughout the key's lifetime, so if you work with mutable objects, the diagnostic tag will reflect the values in the object the first time it is captured, which may not be deterministic. Again remember that you shouldn't need to rely on the exact value of the weak key.
const obj1 = { username: "donald", timestamp: 1602305533 };
// Probably something like "$1_donald::2020-10-10T04:52:13.000Z"
console.log(weakKey(obj1));
obj1.username = "mike";
// The key is stable, i.e. "$1_donald::2020-10-10T04:52:13.000Z"
console.log(weakKey(obj1));
Supplying your own key generator
The basic guarantee that weak keys will be unique for every object depends on the key generator itself. You can supply your own, but then you are also own your own with regards to the uniqueness. For example, you could use a UUID generator for "good-enough" uniqueness.
import { weakKeyFactory } from "stable-genius";
import { v4 } from "uuid";
const weakKey = weakKeyFactory("myId", (tag) => `${tag}:${v4()}`);
// Probably something like "myId:45613ca1-bf4a-457a-a9f1-6f11e69a579a"
console.log(weakKey({}));
What it is (and isn't) for
Creating weak keys is helpful when you are forced (for instance, by a third-party library) to supply strings as identifiers for things, where you actually have objects.
Weak keys are stable within an object instance's lifetime, but are not contextually stable. So don't expect that the same object instantiation in your code will receive the same key.
The only guarantee these keys offer are stability and uniqueness, and you should not depend on the actual string value of the key.
Once more, you must be working with referentially stable objects for weak keys to be useful.
What weak key generation also enables is this: It stops you from generating arbitrary IDs for a set of things that should just be considered unique by its reference.