@powerhousedao/switchboard 2.2.165-dev.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +8 -0
- package/CHANGELOG.md +59 -0
- package/dist/src/clients/redis.d.ts +1 -1
- package/dist/src/clients/redis.d.ts.map +1 -1
- package/dist/src/clients/redis.js +1 -5
- package/dist/src/clients/redis.js.map +1 -1
- package/dist/src/index.js +9 -5
- package/dist/src/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +4 -4
- package/src/clients/redis.ts +0 -51
- package/src/index.ts +0 -99
- package/src/install-packages.ts +0 -8
- package/src/profiler.ts +0 -25
- package/src/utils/gen-doc-model-type-defs.ts +0 -65
- package/src/utils/package-manager.ts +0 -204
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/switchboard",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.3.0",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"switchboard": "dist/src/index.js"
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"express": "^4.21.2",
|
|
22
22
|
"graphql": "^16.10.0",
|
|
23
23
|
"redis": "^4.7.0",
|
|
24
|
+
"@powerhousedao/config": "1.27.0-dev.9",
|
|
24
25
|
"@powerhousedao/reactor-api": "1.29.23-dev.2",
|
|
26
|
+
"document-model": "2.28.1-dev.9",
|
|
25
27
|
"@powerhousedao/scalars": "1.33.1-dev.7",
|
|
26
|
-
"
|
|
27
|
-
"document-drive": "1.29.11-dev.5",
|
|
28
|
-
"document-model": "2.28.1-dev.9"
|
|
28
|
+
"document-drive": "1.29.11-dev.5"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/express": "^5.0.0",
|
package/src/clients/redis.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { createClient, type RedisClientType } from "redis";
|
|
2
|
-
|
|
3
|
-
export let redisClient: RedisClientType;
|
|
4
|
-
export const initRedis = async () => {
|
|
5
|
-
if (!redisClient) {
|
|
6
|
-
const url = process.env.REDIS_TLS_URL ?? process.env.REDIS_URL;
|
|
7
|
-
if (!url) {
|
|
8
|
-
throw new Error("REDIS_TLS_URL is not set");
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const socket = url.includes("rediss")
|
|
12
|
-
? {
|
|
13
|
-
tls: true,
|
|
14
|
-
rejectUnauthorized: false,
|
|
15
|
-
}
|
|
16
|
-
: undefined;
|
|
17
|
-
|
|
18
|
-
redisClient = createClient({
|
|
19
|
-
url,
|
|
20
|
-
socket,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
redisClient.on("error", (err: string) => {
|
|
24
|
-
console.log("Redis Client Error", err);
|
|
25
|
-
throw new Error("Redis Client Error");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
redisClient.connect();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return redisClient;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const timer = setInterval(
|
|
35
|
-
async () => {
|
|
36
|
-
try {
|
|
37
|
-
if (redisClient) {
|
|
38
|
-
await redisClient.ping();
|
|
39
|
-
}
|
|
40
|
-
} catch (err) {
|
|
41
|
-
console.error("Ping Interval Error", err);
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
1000 * 60 * 4,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
export const closeRedis = () => {
|
|
48
|
-
clearInterval(timer);
|
|
49
|
-
|
|
50
|
-
redisClient.disconnect();
|
|
51
|
-
};
|
package/src/index.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { startAPI } from "@powerhousedao/reactor-api";
|
|
3
|
-
import * as Sentry from "@sentry/node";
|
|
4
|
-
import { ReactorBuilder, driveDocumentModelModule } from "document-drive";
|
|
5
|
-
import RedisCache from "document-drive/cache/redis";
|
|
6
|
-
import { PrismaStorageFactory } from "document-drive/storage/prisma";
|
|
7
|
-
import {
|
|
8
|
-
type DocumentModelModule,
|
|
9
|
-
documentModelDocumentModelModule,
|
|
10
|
-
} from "document-model";
|
|
11
|
-
import dotenv from "dotenv";
|
|
12
|
-
import express from "express";
|
|
13
|
-
import { initRedis } from "./clients/redis.js";
|
|
14
|
-
import { initProfilerFromEnv } from "./profiler.js";
|
|
15
|
-
import { PackagesManager } from "./utils/package-manager.js";
|
|
16
|
-
|
|
17
|
-
dotenv.config();
|
|
18
|
-
|
|
19
|
-
// Create a monolith express app for all subgraphs
|
|
20
|
-
const app = express();
|
|
21
|
-
|
|
22
|
-
if (process.env.SENTRY_DSN) {
|
|
23
|
-
console.log("Initialized Sentry with env:", process.env.SENTRY_ENV);
|
|
24
|
-
Sentry.init({
|
|
25
|
-
dsn: process.env.SENTRY_DSN,
|
|
26
|
-
environment: process.env.SENTRY_ENV,
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
Sentry.setupExpressErrorHandler(app);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const serverPort = process.env.PORT ? Number(process.env.PORT) : 4001;
|
|
33
|
-
|
|
34
|
-
const main = async () => {
|
|
35
|
-
if (process.env.PYROSCOPE_SERVER_ADDRESS) {
|
|
36
|
-
try {
|
|
37
|
-
await initProfilerFromEnv(process.env);
|
|
38
|
-
} catch (e) {
|
|
39
|
-
Sentry.captureException(e);
|
|
40
|
-
console.error("Error starting profiler", e);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
const packages =
|
|
46
|
-
process.env.PH_PACKAGES && process.env.PH_PACKAGES !== ""
|
|
47
|
-
? process.env.PH_PACKAGES.split(",")
|
|
48
|
-
: [];
|
|
49
|
-
const pkgManager = new PackagesManager({
|
|
50
|
-
packages,
|
|
51
|
-
});
|
|
52
|
-
const { documentModels, subgraphs } = await pkgManager.init();
|
|
53
|
-
const redis = await initRedis();
|
|
54
|
-
const connectionString = process.env.DATABASE_URL;
|
|
55
|
-
if (!connectionString) {
|
|
56
|
-
throw new Error("Please set env var DATABASE_URL");
|
|
57
|
-
}
|
|
58
|
-
const dbUrl =
|
|
59
|
-
connectionString.includes("amazonaws") &&
|
|
60
|
-
!connectionString.includes("sslmode=no-verify")
|
|
61
|
-
? connectionString + "?sslmode=no-verify"
|
|
62
|
-
: connectionString;
|
|
63
|
-
|
|
64
|
-
const redisCache = new RedisCache(redis);
|
|
65
|
-
const storageFactory = new PrismaStorageFactory(dbUrl, redisCache);
|
|
66
|
-
const storage = storageFactory.build();
|
|
67
|
-
|
|
68
|
-
const reactor = new ReactorBuilder([
|
|
69
|
-
documentModelDocumentModelModule,
|
|
70
|
-
driveDocumentModelModule,
|
|
71
|
-
...documentModels,
|
|
72
|
-
] as DocumentModelModule[])
|
|
73
|
-
.withStorage(storage)
|
|
74
|
-
.withCache(redisCache)
|
|
75
|
-
.build();
|
|
76
|
-
|
|
77
|
-
// init drive server
|
|
78
|
-
await reactor.initialize();
|
|
79
|
-
|
|
80
|
-
// Start the API with the reactor and options
|
|
81
|
-
await startAPI(reactor, {
|
|
82
|
-
express: app,
|
|
83
|
-
port: serverPort,
|
|
84
|
-
dbPath: dbUrl,
|
|
85
|
-
packages,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// start http server
|
|
89
|
-
// httpServer.listen({ port: serverPort }, () => {
|
|
90
|
-
// console.log(`Subgraph server listening on port ${serverPort}`);
|
|
91
|
-
// });
|
|
92
|
-
} catch (e) {
|
|
93
|
-
Sentry.captureException(e);
|
|
94
|
-
console.error("App crashed", e);
|
|
95
|
-
throw e;
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
main().catch(console.error);
|
package/src/install-packages.ts
DELETED
package/src/profiler.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { PyroscopeConfig } from "@pyroscope/nodejs";
|
|
2
|
-
|
|
3
|
-
export async function initProfilerFromEnv(env: typeof process.env) {
|
|
4
|
-
const {
|
|
5
|
-
PYROSCOPE_SERVER_ADDRESS: serverAddress,
|
|
6
|
-
PYROSCOPE_APPLICATION_NAME: appName,
|
|
7
|
-
PYROSCOPE_USER: basicAuthUser,
|
|
8
|
-
PYROSCOPE_PASSWORD: basicAuthPassword,
|
|
9
|
-
} = env;
|
|
10
|
-
|
|
11
|
-
const options: PyroscopeConfig = {
|
|
12
|
-
serverAddress,
|
|
13
|
-
appName,
|
|
14
|
-
basicAuthUser,
|
|
15
|
-
basicAuthPassword,
|
|
16
|
-
};
|
|
17
|
-
return initProfiler(options);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export async function initProfiler(options?: PyroscopeConfig) {
|
|
21
|
-
console.log("Initializing Pyroscope profiler at:", options?.serverAddress);
|
|
22
|
-
const Pyroscope = await import("@pyroscope/nodejs");
|
|
23
|
-
Pyroscope.init(options);
|
|
24
|
-
Pyroscope.start();
|
|
25
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { type BaseDocumentDriveServer } from "document-drive";
|
|
2
|
-
import { parse } from "graphql";
|
|
3
|
-
|
|
4
|
-
export const getDocumentModelTypeDefs = (
|
|
5
|
-
documentDriveServer: BaseDocumentDriveServer,
|
|
6
|
-
typeDefs: string,
|
|
7
|
-
) => {
|
|
8
|
-
const documentModels = documentDriveServer.getDocumentModelModules();
|
|
9
|
-
let dmSchema = "";
|
|
10
|
-
documentModels.forEach(({ documentModel }) => {
|
|
11
|
-
dmSchema += `
|
|
12
|
-
${documentModel.specifications
|
|
13
|
-
.map((specification) =>
|
|
14
|
-
specification.state.global.schema
|
|
15
|
-
.replaceAll(" Account ", ` ${documentModel.name}Account `)
|
|
16
|
-
.replaceAll(`: Account`, `: ${documentModel.name}Account`)
|
|
17
|
-
.replaceAll(`[Account!]!`, `[${documentModel.name}Account!]!`)
|
|
18
|
-
.replaceAll("scalar DateTime", "")
|
|
19
|
-
.replaceAll(/input (.*?) {[\s\S]*?}/g, ""),
|
|
20
|
-
)
|
|
21
|
-
.join("\n")};
|
|
22
|
-
|
|
23
|
-
${documentModel.specifications
|
|
24
|
-
.map((specification) =>
|
|
25
|
-
specification.state.local.schema
|
|
26
|
-
.replaceAll(" Account ", ` ${documentModel.name}Account `)
|
|
27
|
-
.replaceAll(`: Account`, `: ${documentModel.name}Account`)
|
|
28
|
-
.replaceAll(`[Account!]!`, `[${documentModel.name}Account!]!`)
|
|
29
|
-
.replaceAll("scalar DateTime", "")
|
|
30
|
-
.replaceAll(/input (.*?) {[\s\S]*?}/g, "")
|
|
31
|
-
.replaceAll("type AccountSnapshotLocalState", "")
|
|
32
|
-
.replaceAll("type BudgetStatementLocalState", "")
|
|
33
|
-
.replaceAll("type ScopeFrameworkLocalState", ""),
|
|
34
|
-
)
|
|
35
|
-
.join("\n")};
|
|
36
|
-
|
|
37
|
-
type ${documentModel.name} implements IDocument {
|
|
38
|
-
id: ID!
|
|
39
|
-
name: String!
|
|
40
|
-
documentType: String!
|
|
41
|
-
revision: Int!
|
|
42
|
-
created: DateTime!
|
|
43
|
-
lastModified: DateTime!
|
|
44
|
-
${documentModel.name !== "DocumentModel" ? `state: ${documentModel.name}State!` : ""}
|
|
45
|
-
}\n`;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// add the mutation and query types
|
|
49
|
-
const schema = `
|
|
50
|
-
scalar DateTime
|
|
51
|
-
interface IDocument {
|
|
52
|
-
name: String!
|
|
53
|
-
documentType: String!
|
|
54
|
-
revision: Int!
|
|
55
|
-
created: DateTime!
|
|
56
|
-
lastModified: DateTime!
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
${dmSchema}
|
|
60
|
-
|
|
61
|
-
${typeDefs}
|
|
62
|
-
`;
|
|
63
|
-
|
|
64
|
-
return parse(schema.replaceAll(";", ""));
|
|
65
|
-
};
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import { execSync } from "node:child_process";
|
|
2
|
-
export const installPackages = async (packages: string[]) => {
|
|
3
|
-
for (const packageName of packages) {
|
|
4
|
-
execSync(`ph install ${packageName}`);
|
|
5
|
-
}
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export const readManifest = () => {
|
|
9
|
-
const manifest = execSync(`ph manifest`).toString();
|
|
10
|
-
return manifest;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
import { getConfig } from "@powerhousedao/config/utils";
|
|
14
|
-
import { type Subgraph } from "@powerhousedao/reactor-api";
|
|
15
|
-
import { type DocumentModelModule } from "document-model";
|
|
16
|
-
import EventEmitter from "node:events";
|
|
17
|
-
import { type StatWatcher, watchFile } from "node:fs";
|
|
18
|
-
|
|
19
|
-
interface IPackagesManager {
|
|
20
|
-
onDocumentModelsChange(
|
|
21
|
-
handler: (documentModels: DocumentModelModule[]) => void,
|
|
22
|
-
): void;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
type IPackagesManagerOptions = { packages: string[] };
|
|
26
|
-
|
|
27
|
-
export async function loadDependency(packageName: string, subPath: string) {
|
|
28
|
-
const module = (await import(`${packageName}/${subPath}`)) as unknown;
|
|
29
|
-
return module;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function loadPackagesDocumentModels(packages: string[]) {
|
|
33
|
-
const loadedPackages = new Map<string, DocumentModelModule[]>();
|
|
34
|
-
for (const pkg of packages) {
|
|
35
|
-
try {
|
|
36
|
-
console.log("> Loading package:", pkg);
|
|
37
|
-
const pkgModule = (await loadDependency(pkg, "document-models")) as {
|
|
38
|
-
[key: string]: DocumentModelModule;
|
|
39
|
-
};
|
|
40
|
-
if (pkgModule) {
|
|
41
|
-
console.log(` ➜ Loaded Document Models from: ${pkg}`);
|
|
42
|
-
loadedPackages.set(pkg, Object.values(pkgModule));
|
|
43
|
-
} else {
|
|
44
|
-
console.warn(` ➜ No Document Models found: ${pkg}`);
|
|
45
|
-
}
|
|
46
|
-
} catch (e) {
|
|
47
|
-
console.error("Error loading Document Models from", pkg, e);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return loadedPackages;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function loadPackagesSubgraphs(packages: string[]) {
|
|
54
|
-
const loadedPackages = new Map<string, (typeof Subgraph)[]>();
|
|
55
|
-
for (const pkg of packages) {
|
|
56
|
-
const pkgModule = (await loadDependency(
|
|
57
|
-
pkg,
|
|
58
|
-
"subgraphs",
|
|
59
|
-
)) as (typeof Subgraph)[];
|
|
60
|
-
if (pkgModule) {
|
|
61
|
-
console.log(` ➜ Loaded Subgraphs from: ${pkg}`);
|
|
62
|
-
loadedPackages.set(pkg, pkgModule);
|
|
63
|
-
} else {
|
|
64
|
-
console.warn(` ➜ No Subgraphs found: ${pkg}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return loadedPackages;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function getUniqueDocumentModels(
|
|
71
|
-
...documentModels: DocumentModelModule[][]
|
|
72
|
-
): DocumentModelModule[] {
|
|
73
|
-
const uniqueModels = new Map<string, DocumentModelModule>();
|
|
74
|
-
|
|
75
|
-
for (const models of documentModels) {
|
|
76
|
-
for (const model of models) {
|
|
77
|
-
uniqueModels.set(model.documentModel.id, model);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return Array.from(uniqueModels.values());
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function getUniqueSubgraphs(
|
|
85
|
-
subgraphs: (typeof Subgraph)[][],
|
|
86
|
-
): (typeof Subgraph)[] {
|
|
87
|
-
const uniqueSubgraphs = new Map<string, typeof Subgraph>();
|
|
88
|
-
for (const subgraphss of subgraphs) {
|
|
89
|
-
const keys = Object.keys(subgraphss);
|
|
90
|
-
for (const key of keys) {
|
|
91
|
-
uniqueSubgraphs.set(
|
|
92
|
-
key,
|
|
93
|
-
(
|
|
94
|
-
subgraphss as unknown as Record<
|
|
95
|
-
string,
|
|
96
|
-
Record<string, typeof Subgraph>
|
|
97
|
-
>
|
|
98
|
-
)[key][key],
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return Array.from(uniqueSubgraphs.values());
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export class PackagesManager implements IPackagesManager {
|
|
106
|
-
private docModelsMap = new Map<string, DocumentModelModule[]>();
|
|
107
|
-
private subgraphsMap = new Map<string, (typeof Subgraph)[]>();
|
|
108
|
-
private configWatcher: StatWatcher | undefined;
|
|
109
|
-
private eventEmitter = new EventEmitter<{
|
|
110
|
-
documentModelsChange: DocumentModelModule[][];
|
|
111
|
-
subgraphsChange: (typeof Subgraph)[][];
|
|
112
|
-
}>();
|
|
113
|
-
|
|
114
|
-
constructor(
|
|
115
|
-
protected options: IPackagesManagerOptions,
|
|
116
|
-
protected onError?: (e: unknown) => void,
|
|
117
|
-
) {
|
|
118
|
-
this.eventEmitter.setMaxListeners(0);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
public async init() {
|
|
122
|
-
return await this.loadPackages(this.options.packages);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
private async loadPackages(packages: string[]) {
|
|
126
|
-
// install packages
|
|
127
|
-
const packagesMap = await loadPackagesDocumentModels(packages);
|
|
128
|
-
const subgraphsMap = await loadPackagesSubgraphs(packages);
|
|
129
|
-
this.updatePackagesMap(packagesMap);
|
|
130
|
-
this.updateSubgraphsMap(subgraphsMap);
|
|
131
|
-
|
|
132
|
-
return {
|
|
133
|
-
documentModels: getUniqueDocumentModels(
|
|
134
|
-
...Array.from(packagesMap.values()),
|
|
135
|
-
),
|
|
136
|
-
subgraphs: getUniqueSubgraphs(Array.from(subgraphsMap.values())),
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
private loadFromConfigFile(configFile: string) {
|
|
141
|
-
const config = getConfig(configFile);
|
|
142
|
-
const packages = config.packages;
|
|
143
|
-
|
|
144
|
-
return this.loadPackages(
|
|
145
|
-
packages?.map((pkg) => pkg.packageName) ?? [],
|
|
146
|
-
).catch(this.onError);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
private initConfigFile(configFile: string) {
|
|
150
|
-
const result = this.loadFromConfigFile(configFile);
|
|
151
|
-
|
|
152
|
-
if (!this.configWatcher) {
|
|
153
|
-
this.configWatcher = watchFile(
|
|
154
|
-
configFile,
|
|
155
|
-
{ interval: 100 },
|
|
156
|
-
(curr, prev) => {
|
|
157
|
-
if (curr.mtime === prev.mtime) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
void this.loadFromConfigFile(configFile).catch(this.onError);
|
|
161
|
-
},
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return result;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
private updatePackagesMap(packagesMap: Map<string, DocumentModelModule[]>) {
|
|
169
|
-
const oldPackages = Array.from(this.docModelsMap.keys());
|
|
170
|
-
const newPackages = Array.from(packagesMap.keys());
|
|
171
|
-
oldPackages
|
|
172
|
-
.filter((pkg) => !newPackages.includes(pkg))
|
|
173
|
-
.forEach((pkg) => {
|
|
174
|
-
console.log("> Removed package:", pkg);
|
|
175
|
-
});
|
|
176
|
-
this.docModelsMap = packagesMap;
|
|
177
|
-
const documentModels = getUniqueDocumentModels(
|
|
178
|
-
...Array.from(packagesMap.values()),
|
|
179
|
-
);
|
|
180
|
-
this.eventEmitter.emit("documentModelsChange", documentModels);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private updateSubgraphsMap(subgraphsMap: Map<string, (typeof Subgraph)[]>) {
|
|
184
|
-
const oldPackages = Array.from(this.subgraphsMap.keys());
|
|
185
|
-
const newPackages = Array.from(subgraphsMap.keys());
|
|
186
|
-
oldPackages
|
|
187
|
-
.filter((pkg) => !newPackages.includes(pkg))
|
|
188
|
-
.forEach((pkg) => {
|
|
189
|
-
console.log("> Removed Subgraphs from:", pkg);
|
|
190
|
-
});
|
|
191
|
-
this.subgraphsMap = subgraphsMap;
|
|
192
|
-
const subgraphs = getUniqueSubgraphs(Array.from(subgraphsMap.values()));
|
|
193
|
-
this.eventEmitter.emit("subgraphsChange", subgraphs);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
onDocumentModelsChange(
|
|
197
|
-
handler: (documentModels: DocumentModelModule[]) => void,
|
|
198
|
-
): void {
|
|
199
|
-
this.eventEmitter.on("documentModelsChange", handler);
|
|
200
|
-
}
|
|
201
|
-
onSubgraphsChange(handler: (subgraphs: (typeof Subgraph)[]) => void): void {
|
|
202
|
-
this.eventEmitter.on("subgraphsChange", handler);
|
|
203
|
-
}
|
|
204
|
-
}
|