forked from profectus/Profectus
Make noPersist work on objects as well
This commit is contained in:
parent
8ebfb85360
commit
80722bd64b
1 changed files with 41 additions and 3 deletions
|
@ -46,6 +46,11 @@ export const SaveDataPath = Symbol("SaveDataPath");
|
||||||
*/
|
*/
|
||||||
export const CheckNaN = Symbol("CheckNaN");
|
export const CheckNaN = Symbol("CheckNaN");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A symbol used to flag objects that should not be checked for persistent values.
|
||||||
|
*/
|
||||||
|
export const SkipPersistence = Symbol("SkipPersistence");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a union of things that should be safely stringifiable without needing special processes or knowing what to load them in as.
|
* This is a union of things that should be safely stringifiable without needing special processes or knowing what to load them in as.
|
||||||
* - Decimals aren't allowed because we'd need to know to parse them back.
|
* - Decimals aren't allowed because we'd need to know to parse them back.
|
||||||
|
@ -196,12 +201,42 @@ export function isPersistent(value: unknown): value is Persistent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unwraps the non-persistent ref inside of persistent refs, to be passed to other features without duplicating values in the save data object.
|
* Unwraps the non-persistent ref inside of persistent refs, to be passed to other features without duplicating values in the save data object.
|
||||||
* @param persistent The persistent ref to unwrap
|
* @param persistent The persistent ref to unwrap, or an object to ignore all persistent refs within
|
||||||
*/
|
*/
|
||||||
export function noPersist<T extends Persistent<S>, S extends State>(
|
export function noPersist<T extends Persistent<S>, S extends State>(
|
||||||
persistent: T
|
persistent: T
|
||||||
): T[typeof NonPersistent] {
|
): T[typeof NonPersistent];
|
||||||
return persistent[NonPersistent];
|
export function noPersist<T extends object>(persistent: T): T;
|
||||||
|
export function noPersist<T extends Persistent<S>, S extends State>(persistent: T | object) {
|
||||||
|
// Check for proxy state so if it's a lazy proxy we don't evaluate it's function
|
||||||
|
// Lazy proxies are not persistent refs themselves, so we know we want to wrap them
|
||||||
|
return !(ProxyState in persistent) && NonPersistent in persistent
|
||||||
|
? persistent[NonPersistent]
|
||||||
|
: new Proxy(persistent, {
|
||||||
|
get(target, p) {
|
||||||
|
if (p === PersistentState) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (p === SkipPersistence) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return target[p as keyof typeof target];
|
||||||
|
},
|
||||||
|
set(target, key, value) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(target as Record<PropertyKey, any>)[key] = value;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
has(target, key) {
|
||||||
|
if (key === PersistentState) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (key == SkipPersistence) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return Reflect.has(target, key);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,6 +261,9 @@ globalBus.on("addLayer", (layer: GenericLayer, saveData: Record<string, unknown>
|
||||||
Object.keys(obj).forEach(key => {
|
Object.keys(obj).forEach(key => {
|
||||||
let value = obj[key];
|
let value = obj[key];
|
||||||
if (value != null && typeof value === "object") {
|
if (value != null && typeof value === "object") {
|
||||||
|
if ((value as Record<PropertyKey, unknown>)[SkipPersistence] === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (ProxyState in value) {
|
if (ProxyState in value) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
value = (value as any)[ProxyState] as object;
|
value = (value as any)[ProxyState] as object;
|
||||||
|
|
Loading…
Reference in a new issue