exome
Version:
State manager for deeply nested states
8 lines (7 loc) • 6.74 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../src/utils/save-state.ts", "../src/utils/load-state.ts"],
"sourcesContent": ["import { Exome, getExomeId } from \"exome\";\n\nconst replacer = (): any => {\n\tconst savedInstances: Record<string, true> = {};\n\n\treturn (_: string, value: any): any => {\n\t\t// Found an Exome instance, replace it with simple object\n\t\t// that contains `$$exome_id` property.\n\t\tif (value instanceof Exome) {\n\t\t\tconst id = getExomeId(value);\n\n\t\t\tif (!id) {\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\tif (savedInstances[id]) {\n\t\t\t\treturn {\n\t\t\t\t\t$$exome_id: id,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tsavedInstances[id] = true;\n\n\t\t\treturn {\n\t\t\t\t$$exome_id: id,\n\t\t\t\t...value,\n\t\t\t};\n\t\t}\n\n\t\treturn value;\n\t};\n};\n\n/**\n * Saves given store instance and its children (even recursive) to string that can be later restored.\n *\n * @example:\n * ```ts\n * class CounterStore extends Exome {\n * public count = 5\n *\n * public increment() {\n * this.count += 1\n * }\n * }\n *\n * saveState(new CounterStore())\n * ```\n */\nexport const saveState = (store: Exome, readable = false): string => {\n\tconst output = JSON.stringify(store, replacer(), readable ? 2 : undefined);\n\n\tif (output === undefined) {\n\t\treturn \"null\";\n\t}\n\n\treturn output;\n};\n", "import {\n\ttype Exome,\n\texomeId,\n\texomeName,\n\trunMiddleware,\n\tupdateAll,\n} from \"exome\";\n\nconst loadableExomes: Record<string, typeof Exome> = {};\n\n/**\n * For `loadState`` to know what stores to build instances from, we must make sure we register them.\n *\n * @example:\n * ```ts\n * registerLoadable({\n * CounterStore,\n * })\n * ```\n */\nexport const registerLoadable = (config: Record<string, any>): void => {\n\tObject.keys(config).forEach((key) => {\n\t\tconfig[key].prototype[exomeName] = key;\n\n\t\tloadableExomes[key] = config[key];\n\t});\n};\n\n/**\n * Loads saved store into existing store instance. It will rebuild all children stores too.\n *\n * @example:\n * ```ts\n * const counterStore = new CounterStore()\n * const savedStore = `{\"$$exome_id\":\"CounterStore-LS5WUJPF17SF\",\"count\":200}`\n *\n * loadState(counterStore, savedStore)\n * ```\n */\nexport const loadState = (store: Exome, state: string): any => {\n\tif (!state || typeof state !== \"string\") {\n\t\tthrow new Error(\n\t\t\t`State was not loaded. Passed state must be string, instead received \"${typeof state}\".`,\n\t\t);\n\t}\n\n\tconst instances = new Map<string, Exome>();\n\n\tconst output = JSON.parse(state, (key, value) => {\n\t\tif (key !== \"\" && value && typeof value === \"object\" && value.$$exome_id) {\n\t\t\tconst {\n\t\t\t\t$$exome_id: localId,\n\t\t\t\t...state\n\t\t\t}: { $$exome_id: string; [key: string]: any } = value;\n\n\t\t\tconst cachedInstance = instances.get(localId);\n\n\t\t\tif (cachedInstance) {\n\t\t\t\tfor (const key in state) {\n\t\t\t\t\tif ((cachedInstance as any)[key] !== state[key]) {\n\t\t\t\t\t\t(cachedInstance as any)[key] = state[key];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn cachedInstance;\n\t\t\t}\n\n\t\t\tconst [name] = localId.split(\"-\");\n\t\t\tconst StoreExome = loadableExomes[name];\n\n\t\t\tif (!StoreExome) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`State cannot be loaded! \"${name}\" was not registered via \\`registerLoadable\\`.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst instance = new StoreExome();\n\n\t\t\t\tconst after = runMiddleware(instance, \"LOAD_STATE\", []);\n\n\t\t\t\tinstance[exomeId] = localId;\n\n\t\t\t\tObject.assign(instance, state);\n\n\t\t\t\tinstances.set(localId, instance);\n\n\t\t\t\tafter();\n\n\t\t\t\treturn instance;\n\t\t\t} catch (e) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`State cannot be loaded! \"${name}.constructor\" has logic that prevents state from being loaded.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t});\n\n\tif (!output?.$$exome_id) {\n\t\tthrow new Error(\n\t\t\t\"State was not loaded. Passed state string is not saved Exome instance.\",\n\t\t);\n\t}\n\n\tconst { $$exome_id: rootId, ...data } = output;\n\n\tconst after = runMiddleware(store, \"LOAD_STATE\", []);\n\n\tObject.assign(store, data);\n\n\tafter();\n\n\t// Run view update after state has been loaded\n\tupdateAll();\n\n\treturn data;\n};\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,SAAAA,GAAO,cAAAC,SAAkB;AAElC,IAAMC,IAAW,MAAW;AAC3B,MAAMC,IAAuC,CAAC;AAE9C,SAAO,CAACC,GAAWC,MAAoB;AAGtC,QAAIA,aAAiBC,GAAO;AAC3B,UAAMC,IAAKC,EAAWH,CAAK;AAE3B,aAAKE,IAIDJ,EAAeI,CAAE,IACb;AAAA,QACN,YAAYA;AAAA,MACb,KAGDJ,EAAeI,CAAE,IAAI,IAEdE,EAAA;AAAA,QACN,YAAYF;AAAA,SACTF,MAbIA;AAAA,IAeT;AAEA,WAAOA;AAAA,EACR;AACD,GAkBaK,IAAY,CAACC,GAAcC,IAAW,OAAkB;AACpE,MAAMC,IAAS,KAAK,UAAUF,GAAOT,EAAS,GAAGU,IAAW,IAAI,MAAS;AAEzE,SAAIC,MAAW,SACP,SAGDA;AACR;;;ACzDA;AAAA,EAEC,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,aAAAC;AAAA,OACM;AAEP,IAAMC,IAA+C,CAAC,GAYzCC,IAAmB,CAACC,MAAsC;AACtE,SAAO,KAAKA,CAAM,EAAE,QAAQ,CAACC,MAAQ;AACpC,IAAAD,EAAOC,CAAG,EAAE,UAAUC,CAAS,IAAID,GAEnCH,EAAeG,CAAG,IAAID,EAAOC,CAAG;AAAA,EACjC,CAAC;AACF,GAaaE,IAAY,CAACC,GAAcC,MAAuB;AAC9D,MAAI,CAACA,KAAS,OAAOA,KAAU;AAC9B,UAAM,IAAI;AAAA,MACT,wEAAwE,OAAOA,CAAK;AAAA,IACrF;AAGD,MAAMC,IAAY,oBAAI,IAAmB,GAEnCC,IAAS,KAAK,MAAMF,GAAO,CAACJ,GAAKO,MAAU;AAChD,QAAIP,MAAQ,MAAMO,KAAS,OAAOA,KAAU,YAAYA,EAAM,YAAY;AACzE,UAGgDC,IAAAD,GAF/C;AAAA,oBAAYE;AAAA,MAnDhB,IAqDmDD,GAD5CJ,IAAAM,EAC4CF,GAD5C;AAAA,QADH;AAAA,UAIKG,IAAiBN,EAAU,IAAII,CAAO;AAE5C,UAAIE,GAAgB;AACnB,iBAAWX,KAAOI;AACjB,UAAKO,EAAuBX,CAAG,MAAMI,EAAMJ,CAAG,MAC5CW,EAAuBX,CAAG,IAAII,EAAMJ,CAAG;AAG1C,eAAOW;AAAA,MACR;AAEA,UAAM,CAACC,CAAI,IAAIH,EAAQ,MAAM,GAAG,GAC1BI,IAAahB,EAAee,CAAI;AAEtC,UAAI,CAACC;AACJ,cAAM,IAAI;AAAA,UACT,4BAA4BD,CAAI;AAAA,QACjC;AAGD,UAAI;AACH,YAAME,IAAW,IAAID,EAAW,GAE1BE,IAAQC,EAAcF,GAAU,cAAc,CAAC,CAAC;AAEtD,eAAAA,EAASG,CAAO,IAAIR,GAEpB,OAAO,OAAOK,GAAUV,CAAK,GAE7BC,EAAU,IAAII,GAASK,CAAQ,GAE/BC,EAAM,GAECD;AAAA,MACR,SAASI,GAAG;AACX,cAAM,IAAI;AAAA,UACT,4BAA4BN,CAAI;AAAA,QACjC;AAAA,MACD;AAAA,IACD;AAEA,WAAOL;AAAA,EACR,CAAC;AAED,MAAI,EAACD,KAAA,QAAAA,EAAQ;AACZ,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAGD,MAAwCE,IAAAF,GAAhC,cAAYa,EAzGrB,IAyGyCX,GAATY,IAAAV,EAASF,GAAT,CAAvB,gBAEFO,IAAQC,EAAcb,GAAO,cAAc,CAAC,CAAC;AAEnD,gBAAO,OAAOA,GAAOiB,CAAI,GAEzBL,EAAM,GAGNM,EAAU,GAEHD;AACR;",
"names": ["Exome", "getExomeId", "replacer", "savedInstances", "_", "value", "Exome", "id", "getExomeId", "__spreadValues", "saveState", "store", "readable", "output", "exomeId", "exomeName", "runMiddleware", "updateAll", "loadableExomes", "registerLoadable", "config", "key", "exomeName", "loadState", "store", "state", "instances", "output", "value", "_a", "localId", "__objRest", "cachedInstance", "name", "StoreExome", "instance", "after", "runMiddleware", "exomeId", "e", "rootId", "data", "updateAll"]
}