peepee
Version:
Visual Programming Language Where You Connect Ports Of One EventEmitter to Ports Of Another EventEmitter
189 lines (154 loc) • 6.66 kB
JavaScript
import { Plugin } from "plugin";
import { EventAggregator } from "events";
import { PersistentMap } from "./PersistentMap.js";
export class DatabasePlugin extends Plugin {
app;
stations;
subscriptions;
constructor() {
super();
this.subscriptions = new Set();
}
init(app) {
this.app = app;
this.portManager = app.plugins.get("PortManagerPlugin");
this.portInstances = this.portManager.portInstances;
this.startRestore();
// this.app.on('startRestore', ()=>this.startRestore())
this.app.on("fileSave", () => this.fileSave());
this.app.on("fileOpen", () => this.fileOpen());
}
stop() {
for (const unsubscribe of this.subscriptions) unsubscribe();
this.subscriptions.clear();
}
startRestore() {
//NOTICE: station gets {id, type} | metadata loads based on type | propertyKeys become available | recordStorage can now be pulled by key
const stationAggregator = new EventAggregator();
stationAggregator.define("stationReady", {
events: [
{
eventType: "recordRestored",
// filter: (record, station) => record.id === station.id,
filter: (record, station) => {
//console.log(record, station)
return record.id === station.id;
},
},
],
onComplete: (data) => this.app.emit("stationRestore", data.initialData),
});
const restoreStation = (station) => stationAggregator.start("stationReady", station.id, station);
this.app.on("recordRestored", (port) => stationAggregator.emit("recordRestored", port)); // drive data into the aggreaagator
this.stations = new PersistentMap(null, {
prefix: "pishposh-stations",
onRestored: (db) => db.forEach(restoreStation),
onRestored3: async (stations) => {
if (!this.records.ready) await records.once("ready");
for (const [id, station] of stations) {
if (!records.has(id)) records.set(id, {});
this.app.emit("stationRestore", station);
}
},
});
this.app.on("stationAdded", (data) => this.stations.set(data.id, data.serialize()));
this.app.on("stationUpdated", (data) => this.stations.set(data.id, data.serialize()));
this.app.on("stationRemoved", (id) => this.stations.delete(id));
// this.app.on("stationAdded", (data) => records.set(data.id, {}));
this.app.on("stationAdded", (data) => this.app.emit("recordAdd", data));
this.app.on("stationRemoved", (id) => this.app.emit("recordRemove", id));
const connectionAggregator = new EventAggregator();
connectionAggregator.define("connectionReady", {
events: [
// {
// eventType: "recordRestored",
// filter: (record, connection) => record.id === connection.id,
// },
{
eventType: "recordRestored",
filter: (record, station) => {
//console.log(record, station)
return record.id === station.id;
},
},
{
eventType: "portAdded",
filter: (port, connection) => port.id === connection.fromPortId,
alias: "fromPort",
},
{
eventType: "portAdded",
filter: (port, connection) => port.id === connection.toPortId,
alias: "toPort",
},
],
onComplete: (data) => this.app.emit("connectionRestore", data.initialData),
});
const restoreConnection = (connection) => connectionAggregator.start("connectionReady", connection.id, connection);
this.app.on("portAdded", (port) => connectionAggregator.emit("portAdded", port)); // drive data into the aggreaagator
this.app.on("recordRestored", (port) => connectionAggregator.emit("recordRestored", port)); // drive data into the aggreaagator
this.connections = new PersistentMap(null, {
prefix: "pishposh-connections",
onRestored: (db) => db.forEach(restoreConnection),
});
this.app.on("connectionAdded", (data) => this.connections.set(data.id, data.serialize()));
this.app.on("connectionUpdated", (data) => this.connections.set(data.id, data.serialize()));
this.app.on("connectionRemoved", (id) => this.connections.delete(id));
// this.app.on("connectionAdded", (data) => records.set(data.id, {}));
// this.app.on("connectionRemoved", (id) => records.delete(id));
this.app.on("connectionAdded", (data) => this.app.emit("recordAdd", data));
this.app.on("connectionRemoved", (id) => this.app.emit("recordRemove", id));
// keys for records are found in agent manifest files
const records = new PersistentMap(null, { prefix: "pishposh-records", onRestored: (db) => db.forEach((v, k) => this.app.emit("recordRestore", v)) });
this.records = records;
this.app.on("recordAdded", (data) => this.records.set(data.id, data.serialize()));
//this.app.on("recordAdded", (data) => console.log('recordAdded this.records.set', data.id, data.serialize()) );
this.app.on("recordUpdated", (data) => this.records.set(data.id, data.serialize()));
this.app.on("recordRemoved", (id) => this.records.delete(id));
} // start restore
async fileOpen() {
const json = await this.fileOpenJson();
this.stations.clear();
this.connections.clear();
this.records.clear();
console.warn('TODO: Ensure that loaded stations, connections, agents, gadgets, -manifests, ports, property in properties pane are stopped.')
this.stations.import(json.stations);
this.connections.import(json.connections);
this.records.import(json.records);
location.reload()
}
fileSave() {
const myData = { stations: this.stations.toJSON(), connections: this.connections.toJSON(), records: this.records.toJSON() };
const jsonString = JSON.stringify(myData, null, 2);
this.fileSaveJsonFS(jsonString, "project.json");
}
async fileOpenJson() {
const [handle] = await window.showOpenFilePicker({
types: [
{
description: "JSON Files",
accept: { "application/json": [".json"] },
},
],
});
const file = await handle.getFile();
const text = await file.text();
const data = JSON.parse(text);
console.log("Loaded JSON:", data);
return data;
}
async fileSaveJsonFS(jsonString, fileName = "project.json") {
const fileHandle = await window.showSaveFilePicker({
suggestedName: fileName,
types: [
{
description: "JSON File",
accept: { "application/json": [".json"] },
},
],
});
const writable = await fileHandle.createWritable();
await writable.write(jsonString);
await writable.close();
}
}