Added support for serialization
Summary: Make sure that DataSources can be serialized directly with a single setting, just like plain state atoms Reviewed By: nikoant Differential Revision: D26944954 fbshipit-source-id: 2b0d625d7d67f27a7c2e33dd7c4b534dfa4d3e82
This commit is contained in:
committed by
Facebook GitHub Bot
parent
dd4cf9cb4a
commit
66774c90c6
@@ -13,6 +13,7 @@ import {
|
||||
property,
|
||||
sortBy as lodashSort,
|
||||
} from 'lodash';
|
||||
import {Persistable, registerStorageAtom} from '../plugin/PluginBase';
|
||||
|
||||
// If the dataSource becomes to large, after how many records will we start to drop items?
|
||||
const dropFactor = 0.1;
|
||||
@@ -91,7 +92,7 @@ export class DataSource<
|
||||
T,
|
||||
KEY extends keyof T = any,
|
||||
KEY_TYPE extends string | number | never = ExtractKeyType<T, KEY>
|
||||
> {
|
||||
> implements Persistable {
|
||||
private nextId = 0;
|
||||
private _records: Entry<T>[] = [];
|
||||
|
||||
@@ -129,6 +130,17 @@ export class DataSource<
|
||||
return this._records.map(unwrap);
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return this.records;
|
||||
}
|
||||
|
||||
deserialize(value: any[]) {
|
||||
this.clear();
|
||||
value.forEach((record) => {
|
||||
this.append(record);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a direct reference to the stored records as lookup map,
|
||||
* based on the key attribute set.
|
||||
@@ -711,8 +723,21 @@ export class DataSource<
|
||||
}
|
||||
|
||||
type CreateDataSourceOptions<T, K extends keyof T> = {
|
||||
/**
|
||||
* If a key is set, the given field of the records is assumed to be unique,
|
||||
* and it's value can be used to perform lookups and upserts.
|
||||
*/
|
||||
key?: K;
|
||||
/**
|
||||
* The maximum amount of records that this DataSource will store.
|
||||
* If the limit is exceeded, the oldest records will automatically be dropped to make place for the new ones
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* Should this state persist when exporting a plugin?
|
||||
* If set, the dataSource will be saved / loaded under the key provided
|
||||
*/
|
||||
persist?: string;
|
||||
};
|
||||
|
||||
export function createDataSource<T, KEY extends keyof T = any>(
|
||||
@@ -730,6 +755,7 @@ export function createDataSource<T, KEY extends keyof T>(
|
||||
if (options?.limit !== undefined) {
|
||||
ds.limit = options.limit;
|
||||
}
|
||||
registerStorageAtom(options?.persist, ds);
|
||||
initialSet.forEach((value) => ds.append(value));
|
||||
return ds;
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import {produce, Draft, enableMapSet} from 'immer';
|
||||
import {useState, useEffect} from 'react';
|
||||
import {getCurrentPluginInstance} from '../plugin/PluginBase';
|
||||
import {Persistable, registerStorageAtom} from '../plugin/PluginBase';
|
||||
|
||||
enableMapSet();
|
||||
|
||||
@@ -19,7 +19,7 @@ export type Atom<T> = {
|
||||
update(recipe: (draft: Draft<T>) => void): void;
|
||||
};
|
||||
|
||||
class AtomValue<T> implements Atom<T> {
|
||||
class AtomValue<T> implements Atom<T>, Persistable {
|
||||
value: T;
|
||||
listeners: ((value: T) => void)[] = [];
|
||||
|
||||
@@ -38,6 +38,14 @@ class AtomValue<T> implements Atom<T> {
|
||||
}
|
||||
}
|
||||
|
||||
deserialize(value: T) {
|
||||
this.set(value);
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return this.get();
|
||||
}
|
||||
|
||||
update(recipe: (draft: Draft<T>) => void) {
|
||||
this.set(produce(this.value, recipe));
|
||||
}
|
||||
@@ -77,15 +85,7 @@ export function createState(
|
||||
options: StateOptions = {},
|
||||
): Atom<any> {
|
||||
const atom = new AtomValue(initialValue);
|
||||
if (getCurrentPluginInstance() && options.persist) {
|
||||
const {rootStates} = getCurrentPluginInstance()!;
|
||||
if (rootStates[options.persist]) {
|
||||
throw new Error(
|
||||
`Some other state is already persisting with key "${options.persist}"`,
|
||||
);
|
||||
}
|
||||
rootStates[options.persist] = atom;
|
||||
}
|
||||
registerStorageAtom(options.persist, atom);
|
||||
return atom;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user