Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion examples/react/functional-component-ts/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,41 @@ import { Agile, clone, Logger } from '@agile-ts/core';
import API from '@agile-ts/api';
import Event from '@agile-ts/event';

export const myStorage: any = {};

export const App = new Agile({
logConfig: { level: Logger.level.DEBUG },
localStorage: true,
});

// Register custom second Storage
App.registerStorage(
App.createStorage({
key: 'myStorage',
methods: {
get: (key: string) => {
console.log(`GET '${key}'`);
return myStorage[key];
},
set: (key: string, value: any) => {
console.log(`SET '${key}'`, value);
myStorage[key] = value;
},
remove: (key: string) => {
console.log(`DELETE '${key}'`);
delete myStorage[key];
},
},
})
);

export const MY_STATE = App.createState<string>('MyState', { key: 'my-state' }); //.persist();
export const MY_STATE_2 = App.createState<string>('MyState2', {
key: 'my-state2',
}).persist();
}).persist({
storageKeys: ['myStorage', 'localStorage'],
defaultStorageKey: 'localStorage', // where the persisted value gets loaded from (saved is it in all provided Storages (storageKeys))
});
MY_STATE_2.onLoad(() => {
console.log('On Load MY_STATE_2');
});
Expand Down
44 changes: 25 additions & 19 deletions packages/core/src/collection/collection.persistent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ export class CollectionPersistent<DataType = any> extends Persistent {
config = defineConfig(config, {
instantiate: true,
storageKeys: [],
defaultStorageKey: null,
});
this.collection = () => collection;
this.instantiatePersistent({
key: config.key,
storageKeys: config.storageKeys,
defaultStorageKey: config.defaultStorageKey,
});

// Load/Store persisted Value/s for the first Time
Expand Down Expand Up @@ -96,17 +98,19 @@ export class CollectionPersistent<DataType = any> extends Persistent {
/**
* @internal
* Loads Collection from Storage
* @param key - Prefix Key of Persisted Instances (default PersistentKey)
* @param storageKey - Prefix Key of Persisted Instances (default PersistentKey)
* @return Success?
*/
public async loadPersistedValue(key?: PersistentKey): Promise<boolean> {
public async loadPersistedValue(
storageKey?: PersistentKey
): Promise<boolean> {
if (!this.ready) return false;
const _key = key || this._key;
const _storageKey = storageKey || this._key;

// Check if Collection is Persisted
const isPersisted = await this.agileInstance().storages.get<DataType>(
_key,
this.defaultStorageKey
_storageKey,
this.config.defaultStorageKey as any
);
if (!isPersisted) return false;

Expand All @@ -119,7 +123,7 @@ export class CollectionPersistent<DataType = any> extends Persistent {

// Persist Default Group and load its Value manually to be 100% sure it got loaded
defaultGroup.persist({
instantiate: false,
loadValue: false,
followCollectionPersistKeyPattern: true,
});
if (defaultGroup.persistent?.ready) {
Expand All @@ -131,13 +135,13 @@ export class CollectionPersistent<DataType = any> extends Persistent {
for (const itemKey of defaultGroup._value) {
const itemStorageKey = CollectionPersistent.getItemStorageKey(
itemKey,
_key
_storageKey
);

// Get Storage Value
const storageValue = await this.agileInstance().storages.get<DataType>(
itemStorageKey,
this.defaultStorageKey
this.config.defaultStorageKey as any
);
if (!storageValue) continue;

Expand All @@ -149,7 +153,7 @@ export class CollectionPersistent<DataType = any> extends Persistent {
const success = await loadValuesIntoCollection();

// Persist Collection, so that the Storage Value updates dynamically if the Collection updates
if (success) await this.persistValue(_key);
if (success) await this.persistValue(_storageKey);

return success;
}
Expand All @@ -160,19 +164,19 @@ export class CollectionPersistent<DataType = any> extends Persistent {
/**
* @internal
* Sets everything up so that the Collection gets saved in the Storage
* @param key - Prefix Key of Persisted Instances (default PersistentKey)
* @param storageKey - Prefix Key of Persisted Instances (default PersistentKey)
* @return Success?
*/
public async persistValue(key?: PersistentKey): Promise<boolean> {
public async persistValue(storageKey?: PersistentKey): Promise<boolean> {
if (!this.ready) return false;
const _key = key || this._key;
const _storageKey = storageKey || this._key;
const defaultGroup = this.collection().getGroup(
this.collection().config.defaultGroupKey
);
if (!defaultGroup) return false;

// Set Collection to Persisted (in Storage)
this.agileInstance().storages.set(_key, true, this.storageKeys);
this.agileInstance().storages.set(_storageKey, true, this.storageKeys);

// Persist default Group
if (!defaultGroup.isPersisted)
Expand All @@ -181,7 +185,7 @@ export class CollectionPersistent<DataType = any> extends Persistent {
// Add sideEffect to default Group which adds and removes Items from the Storage depending on the Group Value
defaultGroup.addSideEffect(
CollectionPersistent.defaultGroupSideEffectKey,
() => this.rebuildStorageSideEffect(defaultGroup, _key),
() => this.rebuildStorageSideEffect(defaultGroup, _storageKey),
{ weight: 0 }
);

Expand All @@ -190,7 +194,7 @@ export class CollectionPersistent<DataType = any> extends Persistent {
const item = this.collection().getItem(itemKey);
const itemStorageKey = CollectionPersistent.getItemStorageKey(
itemKey,
_key
_storageKey
);
item?.persist(itemStorageKey);
}
Expand All @@ -205,19 +209,21 @@ export class CollectionPersistent<DataType = any> extends Persistent {
/**
* @internal
* Removes Collection from the Storage
* @param key - Prefix Key of Persisted Instances (default PersistentKey)
* @param storageKey - Prefix Key of Persisted Instances (default PersistentKey)
* @return Success?
*/
public async removePersistedValue(key?: PersistentKey): Promise<boolean> {
public async removePersistedValue(
storageKey?: PersistentKey
): Promise<boolean> {
if (!this.ready) return false;
const _key = key || this._key;
const _storageKey = storageKey || this._key;
const defaultGroup = this.collection().getGroup(
this.collection().config.defaultGroupKey
);
if (!defaultGroup) return false;

// Set Collection to not Persisted
this.agileInstance().storages.remove(_key, this.storageKeys);
this.agileInstance().storages.remove(_storageKey, this.storageKeys);

// Remove default Group from Storage
defaultGroup.persistent?.removePersistedValue();
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/collection/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,10 @@ export class Group<DataType = DefaultItem> extends State<Array<ItemKey>> {
}

_config = defineConfig(_config, {
instantiate: true,
loadValue: true,
followCollectionPattern: false,
storageKeys: [],
defaultStorageKey: null,
});

if (_config.followCollectionPersistKeyPattern) {
Expand All @@ -283,8 +284,9 @@ export class Group<DataType = DefaultItem> extends State<Array<ItemKey>> {
}

super.persist(key, {
instantiate: _config.instantiate,
loadValue: _config.loadValue,
storageKeys: _config.storageKeys,
defaultStorageKey: _config.defaultStorageKey,
});

return this;
Expand Down
12 changes: 8 additions & 4 deletions packages/core/src/collection/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -799,8 +799,9 @@ export class Collection<DataType = DefaultItem> {
}

_config = defineConfig(_config, {
instantiate: true,
loadValue: true,
storageKeys: [],
defaultStorageKey: null,
});

if (this.persistent)
Expand All @@ -810,9 +811,10 @@ export class Collection<DataType = DefaultItem> {

// Create persistent -> Persist Value
this.persistent = new CollectionPersistent<DataType>(this, {
instantiate: _config.instantiate,
instantiate: _config.loadValue,
storageKeys: _config.storageKeys,
key: key,
defaultStorageKey: _config.defaultStorageKey,
});

return this;
Expand Down Expand Up @@ -1279,12 +1281,14 @@ export interface HasConfigInterface {
}

/**
* @param instantiate - If Persistent gets instantiated
* @param loadValue - If Persistent loads the persisted value into the Collection
* @param storageKeys - Key/Name of Storages which gets used to persist the Collection Value (NOTE: If not passed the default Storage will be used)
* @param defaultStorageKey - Default Storage Key (if not provided it takes the first index of storageKeys or the AgileTs default Storage)
*/
export interface CollectionPersistentConfigInterface {
instantiate?: boolean;
loadValue?: boolean;
storageKeys?: StorageKey[];
defaultStorageKey?: StorageKey;
}

/**
Expand Down
12 changes: 8 additions & 4 deletions packages/core/src/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,9 @@ export class State<ValueType = any> {
}

_config = defineConfig(_config, {
instantiate: true,
loadValue: true,
storageKeys: [],
defaultStorageKey: null,
});

if (this.persistent)
Expand All @@ -408,9 +409,10 @@ export class State<ValueType = any> {

// Create persistent -> Persist Value
this.persistent = new StatePersistent<ValueType>(this, {
instantiate: _config.instantiate,
instantiate: _config.loadValue,
storageKeys: _config.storageKeys,
key: key,
defaultStorageKey: _config.defaultStorageKey,
});

return this;
Expand Down Expand Up @@ -657,12 +659,14 @@ export interface PatchConfigInterface extends StateIngestConfigInterface {
}

/**
* @param instantiate - If Persistent gets instantiated
* @param loadValue - If Persistent loads the persisted value into the State
* @param storageKeys - Key/Name of Storages which gets used to persist the State Value (NOTE: If not passed the default Storage will be used)
* @param defaultStorageKey - Default Storage Key (if not provided it takes the first index of storageKeys or the AgileTs default Storage)
*/
export interface StatePersistentConfigInterface {
instantiate?: boolean;
loadValue?: boolean;
storageKeys?: StorageKey[];
defaultStorageKey?: StorageKey;
}

export type StateWatcherCallback<T = any> = (value: T, key: string) => void;
Expand Down
Loading