XO Integration Part II
This commit is contained in:
@@ -25,10 +25,18 @@ export interface Activity {
|
||||
// Define the snapshot structure
|
||||
export type SnapshotByType = {
|
||||
[type: string]: {
|
||||
[id: string]: Activity;
|
||||
[entityId: string]: Activity;
|
||||
};
|
||||
};
|
||||
|
||||
export type ActivitiesIndexedByKey<T extends Activity = Activity> = {
|
||||
[entityId: string]: T;
|
||||
};
|
||||
|
||||
export type ActivitiesIndexedByEntityId<T extends Activity = Activity> = {
|
||||
[key: string]: T;
|
||||
};
|
||||
|
||||
// Policy type definition
|
||||
export type PolicyFunction = (
|
||||
existingActivity: Activity | undefined,
|
||||
@@ -36,6 +44,7 @@ export type PolicyFunction = (
|
||||
) => Activity;
|
||||
|
||||
export type ActivitiesEvents = {
|
||||
snapshotUpdated: undefined;
|
||||
[key: `updated:${string}`]: { activity: Activity };
|
||||
};
|
||||
|
||||
@@ -172,12 +181,17 @@ export class Activities extends EventEmitter<ActivitiesEvents> {
|
||||
/**
|
||||
* Get all activities of a specific type
|
||||
*/
|
||||
public getByType<T extends Activity>(type: T['key']): T[] {
|
||||
const activities = this.snapshot[type];
|
||||
public getByKey<T extends Activity>(
|
||||
key: T['key'],
|
||||
): ActivitiesIndexedByKey<T> {
|
||||
const activities = this.snapshot[key];
|
||||
if (!activities) {
|
||||
return [];
|
||||
return {};
|
||||
}
|
||||
return Object.values(activities) as T[];
|
||||
|
||||
// NOTE: We want to return a new object, not a reference to our current object.
|
||||
// But we only need to "clone" the first level as each activity itself is immutable.
|
||||
return { ...activities } as ActivitiesIndexedByKey<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,6 +241,9 @@ export class Activities extends EventEmitter<ActivitiesEvents> {
|
||||
|
||||
// Emit the updated activity.
|
||||
this.emit(`updated:${activity.key}`, { activity });
|
||||
|
||||
// Emit an event indicating our snapshot has been updated.
|
||||
this.emit('snapshotUpdated', undefined);
|
||||
} else if (storeKey !== this.storeKeyMap.get(snapshotKey)) {
|
||||
// If we kept the existing activity, delete the new activity from the store
|
||||
// await this.store.set(storeKey, null);
|
||||
@@ -261,6 +278,8 @@ export class Activities extends EventEmitter<ActivitiesEvents> {
|
||||
await this.processActivity(storeKey, activity);
|
||||
}
|
||||
|
||||
this.emit('snapshotUpdated', undefined);
|
||||
|
||||
return this.snapshot;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ export type StorageOpts = {
|
||||
};
|
||||
|
||||
export type StoreEvents = {
|
||||
[key: `set:${string}`]: any;
|
||||
set: { key: string; value: any };
|
||||
delete: { key: string };
|
||||
clear: undefined;
|
||||
|
||||
@@ -26,6 +26,10 @@ export class StorageLocalStorage extends BaseStorage {
|
||||
const stores = new Set<string>();
|
||||
|
||||
// Iterate through localStorage to find all stores with our dbName prefix
|
||||
// NOTE: I think this was me (Jim) just being stupid.
|
||||
// We don't want to do this - we want to over-ride "on" to emit on first subscription.
|
||||
// And then call super.on?
|
||||
/*
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
if (key && key.startsWith(prefix)) {
|
||||
@@ -35,6 +39,7 @@ export class StorageLocalStorage extends BaseStorage {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return Array.from(stores);
|
||||
}
|
||||
@@ -171,7 +176,15 @@ export class StoreLocalStorage extends BaseStore {
|
||||
encryption?: Encrypter,
|
||||
parentStorage?: StorageLocalStorage,
|
||||
) {
|
||||
return new this(dbName, storeName, encryption, parentStorage);
|
||||
const store = new this(dbName, storeName, encryption, parentStorage);
|
||||
|
||||
// Emit events for all entries.
|
||||
const allEntries = await store.all();
|
||||
Object.entries(allEntries).forEach(([key, value]) =>
|
||||
store.emit(`set:${key}`, value),
|
||||
);
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
async all<T>() {
|
||||
@@ -235,6 +248,7 @@ export class StoreLocalStorage extends BaseStore {
|
||||
// LocalStorage can only store strings, so we convert the binary data
|
||||
localStorage.setItem(fullKey, encryptedValue);
|
||||
this.emit('set', { key, value });
|
||||
this.emit(`set:${key}`, value);
|
||||
}
|
||||
|
||||
async delete(key: string) {
|
||||
|
||||
Reference in New Issue
Block a user