Skip to content
Snippets Groups Projects
Commit 2498e3e1 authored by Greg Fodor's avatar Greg Fodor
Browse files

Added store

parent 47133532
No related branches found
No related tags found
No related merge requests found
import uuid from "uuid/v4";
import { Validator } from "jsonschema";
const LOCAL_STORE_KEY = "___mozilla_hubs";
const STORE_STATE_CACHE_KEY = Symbol();
const validator = new Validator();
// Durable (via local-storage) schema-enforced state that is meant to be consumed via forward data flow.
// (Think flux but with way less incidental complexity, at least for now :))
const SCHEMA = {
id: "/MozillaHubsStore",
definitions: {
profile: {
type: "object",
additionalProperties: false,
properties: {
display_name: { type: "string", pattern: "^[A-Za-z0-9-]{3,32}$" },
}
}
},
type: "object",
properties: {
id: { type: "string", pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" },
profile: { "$ref": "#/definitions/profile" },
},
additionalProperties: false
}
export default class Store {
subscribers = new Set();
constructor() {
if (localStorage.getItem(LOCAL_STORE_KEY) === null) {
localStorage.setItem(LOCAL_STORE_KEY, JSON.stringify({ id: uuid() }));
}
}
get state() {
if (!this.hasOwnProperty(STORE_STATE_CACHE_KEY)) {
this[STORE_STATE_CACHE_KEY] = JSON.parse(localStorage.getItem(LOCAL_STORE_KEY));
}
return this[STORE_STATE_CACHE_KEY];
}
subscribe(subscriber) {
this.subscribers.add(subscriber);
}
update(newState) {
if (newState.id) {
console.error("Store id is immutable.");
return;
}
const finalState = { ...this.state, ...newState };
const isValid = validator.validate(finalState, SCHEMA).valid;
if (!isValid) {
console.warn(`Write of ${JSON.stringify(finalState)} to store failed schema validation.`)
return;
}
localStorage.setItem(LOCAL_STORE_KEY, JSON.stringify(finalState));
delete this[STORE_STATE_CACHE_KEY];
for (const subscriber of this.subscribers) {
subscriber();
}
return finalState;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment