Skip to content

Commit

Permalink
Use non-registered symbols as weak map keys.
Browse files Browse the repository at this point in the history
This is now baseline as of 2023 so we ought to be able to use it. We use
symbols to prevent internal abstractions from being leaked into code
authored by integrators — for that, we just need an opaque token. But,
because weak maps previously needed to be keyed with an _object_, we
just created a dummy object as our key.

Now, we can take the more modern approach of keying with a symbol.

Closes #192.
  • Loading branch information
theengineear committed Oct 22, 2024
1 parent ed1ae2d commit 855c928
Showing 1 changed file with 27 additions and 31 deletions.
58 changes: 27 additions & 31 deletions x-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ export default class XElement extends HTMLElement {

/** Internal implementation details for template engine. */
class TemplateEngine {
static #UNSET = Symbol('unset'); // Ensures a unique, initial comparison.
static #UNSET = Symbol(); // Ensures a unique, initial comparison.
static #ATTRIBUTE_PREFIXES = {
attribute: 'x-element-attribute-',
boolean: 'x-element-boolean-',
Expand All @@ -1027,8 +1027,8 @@ class TemplateEngine {
static #interface = null;
static #stateMap = new WeakMap(); // Maps nodes to internal state.
static #analysisMap = new WeakMap(); // Maps strings to cached computations.
static #resultMap = new WeakMap(); // Maps references to results.
static #updaterMap = new WeakMap(); // Maps references to updaters.
static #resultMap = new WeakMap(); // Maps symbols to results.
static #updaterMap = new WeakMap(); // Maps symbols to updaters.

/**
* Declare HTML markup to be interpolated.
Expand All @@ -1040,10 +1040,10 @@ class TemplateEngine {
* @returns {any}
*/
static html(strings, ...values) {
const reference = TemplateEngine.#createReference();
const symbol = Symbol();
const result = TemplateEngine.#createResult('html', strings, values);
TemplateEngine.#resultMap.set(reference, result);
return reference;
TemplateEngine.#resultMap.set(symbol, result);
return symbol;
}

/**
Expand All @@ -1056,10 +1056,10 @@ class TemplateEngine {
* @returns {any}
*/
static svg(strings, ...values) {
const reference = TemplateEngine.#createReference();
const symbol = Symbol();
const result = TemplateEngine.#createResult('svg', strings, values);
TemplateEngine.#resultMap.set(reference, result);
return reference;
TemplateEngine.#resultMap.set(symbol, result);
return symbol;
}

/**
Expand Down Expand Up @@ -1097,11 +1097,11 @@ class TemplateEngine {
* @returns {any}
*/
static ifDefined(value) {
const reference = TemplateEngine.#createReference();
const symbol = Symbol();
const updater = (type, lastValue, details) => TemplateEngine.#ifDefined(type, value, lastValue, details);
updater.value = value;
TemplateEngine.#updaterMap.set(reference, updater);
return reference;
TemplateEngine.#updaterMap.set(symbol, updater);
return symbol;
}

/**
Expand All @@ -1115,11 +1115,11 @@ class TemplateEngine {
* @returns {any}
*/
static nullish(value) {
const reference = TemplateEngine.#createReference();
const symbol = Symbol();
const updater = (type, lastValue, details) => TemplateEngine.#nullish(type, value, lastValue, details);
updater.value = value;
TemplateEngine.#updaterMap.set(reference, updater);
return reference;
TemplateEngine.#updaterMap.set(symbol, updater);
return symbol;
}

/**
Expand All @@ -1135,11 +1135,11 @@ class TemplateEngine {
* @returns {any}
*/
static live(value) {
const reference = TemplateEngine.#createReference();
const symbol = Symbol();
const updater = (type, lastValue, details) => TemplateEngine.#live(type, value, lastValue, details);
updater.value = value;
TemplateEngine.#updaterMap.set(reference, updater);
return reference;
TemplateEngine.#updaterMap.set(symbol, updater);
return symbol;
}

/**
Expand All @@ -1153,11 +1153,11 @@ class TemplateEngine {
* @returns {any}
*/
static unsafeHTML(value) {
const reference = TemplateEngine.#createReference();
const symbol = Symbol();
const updater = (type, lastValue, details) => TemplateEngine.#unsafeHTML(type, value, lastValue, details);
updater.value = value;
TemplateEngine.#updaterMap.set(reference, updater);
return reference;
TemplateEngine.#updaterMap.set(symbol, updater);
return symbol;
}

/**
Expand All @@ -1175,11 +1175,11 @@ class TemplateEngine {
* @returns {any}
*/
static unsafeSVG(value) {
const reference = TemplateEngine.#createReference();
const symbol = Symbol();
const updater = (type, lastValue, details) => TemplateEngine.#unsafeSVG(type, value, lastValue, details);
updater.value = value;
TemplateEngine.#updaterMap.set(reference, updater);
return reference;
TemplateEngine.#updaterMap.set(symbol, updater);
return symbol;
}

/**
Expand Down Expand Up @@ -1260,12 +1260,12 @@ class TemplateEngine {
}

static #mapOrRepeat(value, identify, callback, name) {
const reference = TemplateEngine.#createReference();
const symbol = Symbol();
const context = { identify, callback };
const updater = (type, lastValue, details) => TemplateEngine.#map(type, value, lastValue, details, context, name);
updater.value = value;
TemplateEngine.#updaterMap.set(reference, updater);
return reference;
TemplateEngine.#updaterMap.set(symbol, updater);
return symbol;
}

static #exhaustString(string, state) {
Expand Down Expand Up @@ -1756,10 +1756,6 @@ class TemplateEngine {
}
}

static #createReference() {
return Object.create(null);
}

static #setIfMissing(map, key, callback) {
// Values set in this file are ALL truthy, so "get" is used (versus "has").
let value = map.get(key);
Expand Down

0 comments on commit 855c928

Please sign in to comment.