Created
July 11, 2019 15:32
-
-
Save domenic/1ab743b3c3af907e47220af663a0903d to your computer and use it in GitHub Desktop.
Readonly Sets attempt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { languagesSet } from "./some-library.mjs"; | |
// Allowed | |
languagesSet.keys(); | |
languagesSet.entries(); | |
languagesSet.forEach(l => console.log); | |
languagesSet.size; | |
languagesSet.values(); | |
// Will throw TypeError | |
languagesSet.clear(); | |
languagesSet.add("ja-JP"); | |
languagesSet.delete("en-US"); | |
// Will throw TypeError but I wish it didn't: | |
languagesSet.has("en-US"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default class ReadonlySet extends Set { | |
#mutating = false; | |
constructor(executor) { | |
executor(this.#modify); | |
super(undefined, { | |
toValue() { | |
if (!this.#mutating) { | |
throw new TypeError("Cannot modify a ReadonlyMap"); | |
} | |
} | |
}); | |
} | |
#modify(fn) { | |
this.#mutating = true; | |
try { | |
fn(); | |
} finally { | |
this.#mutating = false; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ReadonlySet from "./readonly-set.mjs"; | |
// This library exposes the set which reflects the environment, | |
// but it doesn't allow mutating the set. | |
// For this example we'll reflect navigator.languages as a Set. | |
// Better examples welcome. | |
export const languagesSet = new ReadonlySet(modify => { | |
navigator.addEventListener("languagechange", () => modify(() => { | |
languages.clear(); | |
navigator.languages.forEach(l => languages.add(l)); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment