Unproxy an array
oravecz opened this issue · comments
In my code, I need to get the "raw" array from my deepsignal state, and I thought the RevertDeepSignal
type might help me get there, but while I can get a clean array back - all of the 20,000 items in that array are Proxy objects. When I pass the array to a function that has no concept of signals, it treats the array as if it were empty.
Please take a look at the demonstrate()
function below to see how I was hoping to get the raw array value back.
Note: in my particular case, I don't need the items in the arrays to be "deepsignaled", and those item's properties, and those item's properties... Just the array itself.
I'm not sure if that is an option?
interface WorkbookState {
loadingState: WorkbookLoadingState;
attributes: Attribute[];
categories: Category[];
hierarchies: Hierarchy[];
hierarchy: Hierarchy | null;
hierarchyNodes: HierarchyNode[];
lrsSegments: Segment[];
segments: Segment[];
trees: ExplicitDataSource<PlanningTreeData> | null;
workbook: Workbook | null;
}
const initialState: WorkbookState = {
attributes: [],
categories: [],
hierarchy: null,
hierarchyNodes: [],
hierarchies: [],
loadingState: WorkbookLoadingState.Initial,
lrsSegments: [],
segments: [],
trees: null,
workbook: null,
};
const store: WorkbookStore = {
state: deepSignal<WorkbookState>(initialState),
closeWorkbook,
openWorkbook,
setHierarchy,
};
const demonstrate = () => {
const attributes: Attribute[] = Object.values<Attribute>(
store.state.attributes as RevertDeepSignal<typeof store.state.attributes>,
);
// while the attributes array is properly types, attributes[n] are Proxy objects.
// when I pass them to my AttributeLookup class, they do not work because the elements are Proxy objects
const attributeLookup = new AttributeLookup(attributes);
// my current work around is to do a deep copy of property to eliminate proxies
const attributes: Attribute[] = toRaw(store.state.attributes);
}
function toRaw(val: any): any {
if (val instanceof Array) return val.map((val) => toRaw(val));
if (val instanceof Object)
return Object.fromEntries(
Object.entries(Object.assign({}, val)).map(([k, v]) => [k, toRaw(v)]),
);
return val;
}
RevertDeepSignal
is only for the types. To get the raw value of the something from the store, you need to use peek()
. The docs are here: https://github.com/luisherranz/deepsignal#peekstate-prop
const hugeArray = [
/*...*/
];
const store = deepSignal({
array: hugeArray,
});
const rawArray = peek(store, "array");
rawArray === hugeArray; // true
To stop something from being proxied, I'm thinking about a new shallow()
API. There's a beta version published here if you want to try it out, but I haven't figured out the TypeScript part yet, so you may need to do manual casting for now:
Closing this now but feel free to reopen if you have more questions related to this topic.