@powerhousedao/reactor-local 1.27.30-dev.0 → 1.27.30-staging.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/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- export { startServer } from "./src/server.js";
2
- export { DefaultStartServerOptions, type LocalReactor, type StartServerOptions, } from "./src/types.js";
1
+ export { DefaultStartServerOptions, startServer, type LocalReactor, type StartServerOptions, } from "./src/server.js";
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EACL,yBAAyB,EACzB,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1 @@
1
- export { startServer } from "./src/server.js";
2
- export { DefaultStartServerOptions, } from "./src/types.js";
1
+ export { DefaultStartServerOptions, startServer, } from "./src/server.js";
@@ -1,4 +1,50 @@
1
- import { LocalReactor, StartServerOptions } from "./types.js";
1
+ import { type DriveInput, type IDocumentDriveServer } from "document-drive";
2
+ export type StorageOptions = {
3
+ type: "filesystem" | "memory" | "postgres" | "browser";
4
+ filesystemPath?: string;
5
+ postgresUrl?: string;
6
+ };
7
+ export type StartServerOptions = {
8
+ configFile?: string;
9
+ dev?: boolean;
10
+ port?: string | number;
11
+ storage?: StorageOptions;
12
+ dbPath?: string;
13
+ drive?: DriveInput;
14
+ packages?: string[];
15
+ https?: {
16
+ keyPath: string;
17
+ certPath: string;
18
+ } | boolean | undefined;
19
+ logLevel?: "info" | "warn" | "error" | "debug" | "verbose" | "silent";
20
+ };
21
+ export declare const DefaultStartServerOptions: {
22
+ port: number;
23
+ storage: {
24
+ type: "filesystem";
25
+ filesystemPath: string;
26
+ };
27
+ dbPath: string;
28
+ drive: {
29
+ global: {
30
+ id: string;
31
+ name: string;
32
+ icon: string;
33
+ slug: string;
34
+ };
35
+ local: {
36
+ availableOffline: true;
37
+ listeners: never[];
38
+ sharingType: string;
39
+ triggers: never[];
40
+ };
41
+ };
42
+ };
43
+ export type LocalReactor = {
44
+ driveUrl: string;
45
+ getDocumentPath: (driveId: string, documentId: string) => string;
46
+ server: IDocumentDriveServer;
47
+ };
2
48
  declare const startServer: (options?: StartServerOptions) => Promise<LocalReactor>;
3
49
  export { startServer };
4
50
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,YAAY,EACZ,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAMpB,QAAA,MAAM,WAAW,GACf,UAAU,kBAAkB,KAC3B,OAAO,CAAC,YAAY,CAsEtB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,oBAAoB,EAK1B,MAAM,gBAAgB,CAAC;AAyBxB,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EACF;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;KAClB,GACD,OAAO,GACP,SAAS,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;CACvE,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;CAqBR,CAAC;AAE/B,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACjE,MAAM,EAAE,oBAAoB,CAAC;CAC9B,CAAC;AAoCF,QAAA,MAAM,WAAW,GACf,UAAU,kBAAkB,KAC3B,OAAO,CAAC,YAAY,CAoEtB,CAAC;AAsGF,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -1,14 +1,67 @@
1
- import { startAPI } from "@powerhousedao/reactor-api";
2
- import { InMemoryCache, logger, ReactorBuilder } from "document-drive";
1
+ import { viteCommonjs } from "@originjs/vite-plugin-commonjs";
2
+ import { isSubgraphClass, startAPI, } from "@powerhousedao/reactor-api";
3
+ import { DriveAlreadyExistsError, driveDocumentModelModule, InMemoryCache, logger, MemoryStorage, ReactorBuilder, } from "document-drive";
4
+ import { BrowserStorage } from "document-drive/storage/browser";
5
+ import { FilesystemStorage } from "document-drive/storage/filesystem";
6
+ import { PrismaStorageFactory } from "document-drive/storage/prisma/factory";
7
+ import { documentModelDocumentModelModule, } from "document-model";
3
8
  import dotenv from "dotenv";
9
+ import { access } from "node:fs/promises";
4
10
  import path from "node:path";
5
- import { DefaultStartServerOptions, } from "./types.js";
6
- import { addDefaultDrive, createStorage, startViteServer } from "./util.js";
7
- import { VitePackageLoader } from "./vite-loader.js";
11
+ import { createServer as createViteServer } from "vite";
12
+ const dirname = process.cwd();
8
13
  dotenv.config();
14
+ export const DefaultStartServerOptions = {
15
+ port: 4001,
16
+ storage: {
17
+ type: "filesystem",
18
+ filesystemPath: path.join(dirname, ".ph/file-storage"),
19
+ },
20
+ dbPath: path.join(dirname, ".ph/read-model.db"),
21
+ drive: {
22
+ global: {
23
+ id: "powerhouse",
24
+ name: "Powerhouse",
25
+ icon: "https://ipfs.io/ipfs/QmcaTDBYn8X2psGaXe7iQ6qd8q6oqHLgxvMX9yXf7f9uP7",
26
+ slug: "powerhouse",
27
+ },
28
+ local: {
29
+ availableOffline: true,
30
+ listeners: [],
31
+ sharingType: "public",
32
+ triggers: [],
33
+ },
34
+ },
35
+ };
36
+ const baseDocumentModelModules = [
37
+ documentModelDocumentModelModule,
38
+ driveDocumentModelModule,
39
+ ];
40
+ const createStorage = (options, cache) => {
41
+ switch (options.type) {
42
+ case "filesystem":
43
+ logger.info(`Initializing filesystem storage at '${options.filesystemPath}'.`);
44
+ return new FilesystemStorage(options.filesystemPath);
45
+ case "memory":
46
+ logger.info("Initializing memory storage.");
47
+ return new MemoryStorage();
48
+ case "postgres": {
49
+ if (!options.postgresUrl) {
50
+ throw new Error("Postgres url is required");
51
+ }
52
+ logger.info(`Initializing postgres storage at '${options.postgresUrl}'.`);
53
+ const storageFactory = new PrismaStorageFactory(options.postgresUrl, cache);
54
+ const storage = storageFactory.build();
55
+ return storage;
56
+ }
57
+ case "browser":
58
+ logger.info("Initializing browser storage.");
59
+ return new BrowserStorage();
60
+ }
61
+ };
9
62
  const startServer = async (options) => {
10
63
  process.setMaxListeners(0);
11
- const { port, storage, drive, dev, dbPath, packages = [], configFile, logLevel, } = {
64
+ const { port, storage, drive, dev, dbPath, packages, configFile, logLevel } = {
12
65
  ...DefaultStartServerOptions,
13
66
  ...options,
14
67
  };
@@ -16,39 +69,43 @@ const startServer = async (options) => {
16
69
  // be aware: this may not log anything if the log level is above info
17
70
  logger.info(`Setting log level to ${logLevel}.`);
18
71
  const serverPort = Number(process.env.PORT ?? port);
19
- // start vite server if dev
20
- const vite = dev ? await startViteServer() : undefined;
21
- // get paths to local document models
72
+ // If dev load local document models
73
+ let docModels = [];
74
+ const vite = dev
75
+ ? await startDevServer()
76
+ : undefined;
22
77
  if (vite) {
23
- // TODO get path from powerhouse config
24
- const basePath = process.cwd();
25
- packages.push(basePath);
78
+ const documentModelsPath = path.join(process.cwd(), "./document-models"); // TODO get path from powerhouse config
79
+ docModels = joinDocumentModelModules((await loadDocumentModels(documentModelsPath, vite)) ?? [], baseDocumentModelModules);
26
80
  }
27
- // create document drive server with all available document models & storage
81
+ // start document drive server with all available document models & storage
28
82
  const cache = new InMemoryCache();
29
- const driveServer = new ReactorBuilder([])
83
+ const driveServer = new ReactorBuilder(docModels)
30
84
  .withCache(cache)
31
85
  .withStorage(createStorage(storage, cache))
32
86
  .build();
33
- // init drive server + add a default drive
87
+ // init drive server
34
88
  await driveServer.initialize();
35
89
  const driveUrl = await addDefaultDrive(driveServer, drive, serverPort);
36
- // create loader
37
- let packageLoader = vite ? new VitePackageLoader(vite) : undefined;
38
90
  // start api
91
+ const packageOptions = packages?.length
92
+ ? { packages }
93
+ : configFile
94
+ ? { configFile }
95
+ : { packages: [] };
39
96
  const api = await startAPI(driveServer, {
40
97
  port: serverPort,
41
98
  dbPath,
42
99
  https: options?.https,
43
- packageLoader,
44
- configFile,
45
- packages,
100
+ ...packageOptions,
46
101
  });
47
- // add vite middleware after express app is initialized if applicable
48
102
  if (vite) {
49
103
  api.app.use(vite.middlewares);
104
+ // load local subgraphs
105
+ const subgraphsPath = path.join(process.cwd(), "./subgraphs"); // TODO get path from powerhouse config
106
+ await loadSubgraphs(subgraphsPath, vite, api.graphqlManager);
50
107
  }
51
- logger.info(` ➜ Reactor: ${driveUrl}`);
108
+ console.log(` ➜ Reactor: ${driveUrl}`);
52
109
  return {
53
110
  driveUrl,
54
111
  getDocumentPath: (driveId, documentId) => {
@@ -57,4 +114,88 @@ const startServer = async (options) => {
57
114
  server: driveServer,
58
115
  };
59
116
  };
117
+ async function addDefaultDrive(driveServer, drive, serverPort) {
118
+ let driveId = drive.global.slug ?? drive.global.id;
119
+ try {
120
+ // add default drive
121
+ const driveDoc = await driveServer.addDrive(drive);
122
+ driveId = driveDoc.state.global.slug ?? driveDoc.state.global.id;
123
+ }
124
+ catch (e) {
125
+ if (e instanceof DriveAlreadyExistsError) {
126
+ if (driveId) {
127
+ const driveDoc = await (drive.global.slug
128
+ ? driveServer.getDriveBySlug(drive.global.slug)
129
+ : driveServer.getDrive(driveId));
130
+ driveId = driveDoc.state.global.slug ?? driveDoc.state.global.id;
131
+ }
132
+ }
133
+ else {
134
+ throw e;
135
+ }
136
+ }
137
+ const driveUrl = `http://localhost:${serverPort}/${driveId ? `d/${drive.global.slug ?? drive.global.id}` : ""}`;
138
+ return driveUrl;
139
+ }
140
+ async function startDevServer() {
141
+ const vite = await createViteServer({
142
+ server: { middlewareMode: true, watch: null },
143
+ appType: "custom",
144
+ build: {
145
+ rollupOptions: {
146
+ input: [],
147
+ },
148
+ },
149
+ plugins: [viteCommonjs()],
150
+ });
151
+ return vite;
152
+ }
153
+ async function loadDocumentModels(path, vite) {
154
+ try {
155
+ console.log("> Loading document models from", path);
156
+ await access(path);
157
+ const localDMs = (await vite.ssrLoadModule(path));
158
+ const localDocumentModelModules = Object.values(localDMs);
159
+ return localDocumentModelModules;
160
+ }
161
+ catch (e) {
162
+ if (e.code === "ENOENT") {
163
+ console.warn("No local document models found");
164
+ }
165
+ else {
166
+ console.error("Error loading document models", e);
167
+ }
168
+ }
169
+ }
170
+ async function loadSubgraphs(path, vite, graphqlManager) {
171
+ try {
172
+ console.log("> Loading subgraphs from", path);
173
+ await access(path);
174
+ const localSubgraphs = await vite.ssrLoadModule(path);
175
+ for (const [name, subgraph] of Object.entries(localSubgraphs)) {
176
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
177
+ const SubgraphClass = subgraph[name];
178
+ if (isSubgraphClass(SubgraphClass)) {
179
+ await graphqlManager.registerSubgraph(SubgraphClass, "graphql");
180
+ }
181
+ }
182
+ await graphqlManager.updateRouter();
183
+ }
184
+ catch (e) {
185
+ if (e.code === "ENOENT") {
186
+ console.warn("No local document models found");
187
+ }
188
+ else {
189
+ console.error("Error loading subgraphs", e);
190
+ }
191
+ }
192
+ }
193
+ function joinDocumentModelModules(...modules) {
194
+ return modules
195
+ .flat()
196
+ .toReversed()
197
+ .reduce((acc, curr) => acc.find((dm) => dm.documentModel.id === curr.documentModel.id)
198
+ ? acc
199
+ : [...acc, curr], []);
200
+ }
60
201
  export { startServer };