@powerhousedao/reactor-local 1.4.1 → 1.5.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/CHANGELOG.md CHANGED
@@ -1,11 +1,21 @@
1
- ## 1.4.1 (2024-11-11)
1
+ ## 1.5.0 (2024-11-13)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **design-system:** use intl format for datetime inputs ([d51f8099](https://github.com/powerhouse-inc/powerhouse/commit/d51f8099))
6
+ - **reactor-api, reactor-local:** support local document models on local reactor ([a9a2d27f](https://github.com/powerhouse-inc/powerhouse/commit/a9a2d27f))
2
7
 
3
8
  ### 🧱 Updated Dependencies
4
9
 
5
- - Updated @powerhousedao/general-document-indexer to 1.3.6
6
- - Updated document-model-libs to 1.111.0
7
- - Updated document-drive to 1.4.1
8
- - Updated @powerhousedao/reactor-api to 1.4.1
10
+ - Updated @powerhousedao/general-document-indexer to 1.3.8
11
+ - Updated document-model-libs to 1.113.0
12
+ - Updated document-drive to 1.4.3
13
+ - Updated @powerhousedao/reactor-api to 1.5.0
14
+
15
+ ### ❤️ Thank You
16
+
17
+ - acaldas @acaldas
18
+ - ryanwolhuter @ryanwolhuter
9
19
 
10
20
  ## 1.1.0 (2024-10-29)
11
21
 
@@ -1,6 +1,7 @@
1
1
  import path2 from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import dotenv from 'dotenv';
4
+ import { createServer } from 'vite';
4
5
  import { startAPI } from '@powerhousedao/reactor-api';
5
6
  import * as DocumentDrive from 'document-model-libs/document-drive';
6
7
  import { isFileNode, utils as utils$1, actions, documentModel } from 'document-model-libs/document-drive';
@@ -3880,10 +3881,10 @@ var FilesystemStorage = class _FilesystemStorage {
3880
3881
  };
3881
3882
  var dirname = import.meta.dirname || path2.dirname(fileURLToPath(import.meta.url));
3882
3883
  dotenv.config();
3883
- var startServer = async (options) => {
3884
- const serverPort = Number(options?.connect?.port ?? process.env.PORT ?? 4001);
3885
- const storagePath = options?.reactor?.storagePath ?? path2.join(dirname, "./file-storage");
3886
- const drive = options?.reactor?.drive ?? {
3884
+ var DefaultStartServerOptions = {
3885
+ port: 4001,
3886
+ storagePath: path2.join(dirname, "./file-storage"),
3887
+ drive: {
3887
3888
  global: {
3888
3889
  id: "powerhouse",
3889
3890
  name: "Powerhouse",
@@ -3896,34 +3897,74 @@ var startServer = async (options) => {
3896
3897
  sharingType: "public",
3897
3898
  triggers: []
3898
3899
  }
3900
+ }
3901
+ };
3902
+ var baseDocumentModels = [
3903
+ module,
3904
+ ...Object.values(DocumentModelsLibs)
3905
+ ];
3906
+ var startServer = async (options) => {
3907
+ const { port, storagePath, drive, dev } = {
3908
+ ...DefaultStartServerOptions,
3909
+ ...options
3899
3910
  };
3911
+ const serverPort = Number(process.env.PORT ?? port);
3900
3912
  const driveServer = new DocumentDriveServer(
3901
- [module, ...Object.values(DocumentModelsLibs)],
3913
+ baseDocumentModels,
3902
3914
  new FilesystemStorage(storagePath)
3903
3915
  );
3904
3916
  await driveServer.initialize();
3917
+ let driveId = drive.global.slug ?? drive.global.id;
3918
+ let driveUrl = "";
3905
3919
  try {
3906
- await driveServer.addDrive(drive);
3920
+ const driveDoc = await driveServer.addDrive(drive);
3921
+ driveId = driveDoc.state.global.slug ?? driveDoc.state.global.id;
3907
3922
  } catch (e) {
3908
3923
  if (e instanceof DriveAlreadyExistsError) {
3909
3924
  console.info("Default drive already exists. Skipping...");
3925
+ if (driveId) {
3926
+ const driveDoc = await (drive.global.slug ? driveServer.getDriveBySlug(drive.global.slug) : driveServer.getDrive(driveId));
3927
+ driveId = driveDoc.state.global.slug ?? driveDoc.state.global.id;
3928
+ }
3910
3929
  } else {
3911
3930
  throw e;
3912
3931
  }
3913
3932
  }
3914
3933
  try {
3915
- await startAPI(driveServer, {
3934
+ const app = await startAPI(driveServer, {
3916
3935
  port: serverPort
3917
3936
  });
3937
+ driveUrl = `http://localhost:${serverPort}/${driveId ? `d/${drive.global.slug ?? drive.global.id}` : ""}`;
3938
+ console.log(` \u279C Reactor: ${driveUrl}`);
3939
+ if (dev) {
3940
+ const vite = await createServer({
3941
+ server: { middlewareMode: true },
3942
+ appType: "custom",
3943
+ build: {
3944
+ rollupOptions: {
3945
+ input: []
3946
+ }
3947
+ }
3948
+ });
3949
+ app.use(vite.middlewares);
3950
+ const documentModelsPath = path2.join(process.cwd(), "./document-models");
3951
+ console.log("Loading document models from", documentModelsPath);
3952
+ const localDMs = await vite.ssrLoadModule(documentModelsPath);
3953
+ driveServer.setDocumentModels([
3954
+ ...baseDocumentModels,
3955
+ ...Object.values(localDMs)
3956
+ ]);
3957
+ }
3918
3958
  } catch (e) {
3919
3959
  console.error("App crashed", e);
3920
3960
  }
3921
3961
  return {
3922
- getDocumentPath: (driveId, documentId) => {
3923
- return path2.join(storagePath, driveId, `${documentId}.json`);
3962
+ driveUrl,
3963
+ getDocumentPath: (driveId2, documentId) => {
3964
+ return path2.join(storagePath, driveId2, `${documentId}.json`);
3924
3965
  },
3925
- addListener: (driveId, receiver, options2) => driveServer.addInternalListener(driveId, receiver, options2)
3966
+ addListener: (driveId2, receiver, options2) => driveServer.addInternalListener(driveId2, receiver, options2)
3926
3967
  };
3927
3968
  };
3928
3969
 
3929
- export { startServer };
3970
+ export { DefaultStartServerOptions, startServer };
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #! /usr/bin/env node
2
- import { startServer } from './chunk-N5JF3C3S.js';
2
+ import { startServer } from './chunk-WZVFZSEC.js';
3
3
  import { Command } from 'commander';
4
4
 
5
5
  var reactorLocalAction = (options) => {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
-
2
- export { }
1
+ export { DefaultStartServerOptions, LocalReactor, StartServerOptions, startServer } from './server.js';
2
+ import 'document-model-libs/document-drive';
3
+ import 'document-model/document';
4
+ import 'nanoevents';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { startServer } from './chunk-N5JF3C3S.js';
1
+ import { startServer } from './chunk-WZVFZSEC.js';
2
+ export { DefaultStartServerOptions, startServer } from './chunk-WZVFZSEC.js';
2
3
 
3
4
  // src/index.ts
4
5
  startServer().catch((error) => {
package/dist/server.d.ts CHANGED
@@ -232,15 +232,31 @@ type PublicPart<T> = Pick<T, PublicKeys<T>>;
232
232
  type IBaseDocumentDriveServer = PublicPart<AbstractDocumentDriveServer>;
233
233
 
234
234
  type StartServerOptions = {
235
- connect?: {
236
- port?: string | number;
237
- };
238
- reactor?: {
239
- storagePath?: string;
240
- drive?: DriveInput;
235
+ dev?: boolean;
236
+ port?: string | number;
237
+ storagePath?: string;
238
+ drive?: DriveInput;
239
+ };
240
+ declare const DefaultStartServerOptions: {
241
+ port: number;
242
+ storagePath: string;
243
+ drive: {
244
+ global: {
245
+ id: string;
246
+ name: string;
247
+ icon: string;
248
+ slug: string;
249
+ };
250
+ local: {
251
+ availableOffline: true;
252
+ listeners: never[];
253
+ sharingType: string;
254
+ triggers: never[];
255
+ };
241
256
  };
242
257
  };
243
- declare const startServer: (options?: StartServerOptions) => Promise<{
258
+ type LocalReactor = {
259
+ driveUrl: string;
244
260
  getDocumentPath: (driveId: string, documentId: string) => string;
245
261
  addListener: (driveId: string, receiver: IReceiver, options: {
246
262
  listenerId: string;
@@ -248,6 +264,7 @@ declare const startServer: (options?: StartServerOptions) => Promise<{
248
264
  block: boolean;
249
265
  filter: ListenerFilter;
250
266
  }) => Promise<InternalTransmitter>;
251
- }>;
267
+ };
268
+ declare const startServer: (options?: StartServerOptions) => Promise<LocalReactor>;
252
269
 
253
- export { type StartServerOptions, startServer };
270
+ export { DefaultStartServerOptions, type LocalReactor, type StartServerOptions, startServer };
package/dist/server.js CHANGED
@@ -1 +1 @@
1
- export { startServer } from './chunk-N5JF3C3S.js';
1
+ export { DefaultStartServerOptions, startServer } from './chunk-WZVFZSEC.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@powerhousedao/reactor-local",
3
3
  "type": "module",
4
- "version": "1.4.1",
4
+ "version": "1.5.0",
5
5
  "main": "dist/server.js",
6
6
  "bin": {
7
7
  "reactor-local": "dist/cli.js"
@@ -16,13 +16,13 @@
16
16
  "@apollo/subgraph": "^2.9.2",
17
17
  "@electric-sql/pglite": "^0.2.12",
18
18
  "@libsql/client": "^0.14.0",
19
- "@powerhousedao/general-document-indexer": "^1.3.6",
20
- "@powerhousedao/reactor-api": "^1.4.1",
19
+ "@powerhousedao/general-document-indexer": "^1.3.8",
20
+ "@powerhousedao/reactor-api": "^1.5.0",
21
21
  "@powerhousedao/scalars": "^1.9.0",
22
22
  "change-case": "^5.4.4",
23
23
  "commander": "^12.1.0",
24
24
  "document-model": "^2.6.0",
25
- "document-model-libs": "^1.111.0",
25
+ "document-model-libs": "^1.113.0",
26
26
  "dotenv": "^16.4.5",
27
27
  "drizzle-kit": "^0.25.0",
28
28
  "drizzle-orm": "^0.34.1",
@@ -35,6 +35,7 @@
35
35
  "pg": "^8.13.0",
36
36
  "sanitize-filename": "^1.6.3",
37
37
  "uuid": "^11.0.2",
38
+ "vite": "^5.4.11",
38
39
  "vite-node": "^2.1.2"
39
40
  },
40
41
  "devDependencies": {
@@ -44,7 +45,7 @@
44
45
  "@types/ms": "^0.7.34",
45
46
  "@types/node": "^22.7.5",
46
47
  "@types/pg": "^8.11.10",
47
- "document-drive": "^1.4.1",
48
+ "document-drive": "^1.4.3",
48
49
  "postcss": "^8.4.47",
49
50
  "tsup": "^8.3.0",
50
51
  "typescript": "^5.6.2",
package/src/index.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { startServer } from "./server.js";
2
2
 
3
+ export * from "./server.js";
4
+
3
5
  startServer().catch((error: unknown) => {
4
6
  throw error;
5
7
  });
package/src/server.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import dotenv from "dotenv";
4
+ import { createServer as createViteServer } from "vite";
4
5
  import { startAPI } from "@powerhousedao/reactor-api";
5
6
  import {
6
7
  DocumentDriveServer,
7
8
  DriveAlreadyExistsError,
8
9
  DriveInput,
10
+ InternalTransmitter,
9
11
  IReceiver,
10
12
  } from "document-drive";
11
13
  import { FilesystemStorage } from "document-drive/storage/filesystem";
@@ -20,20 +22,16 @@ const dirname =
20
22
  dotenv.config();
21
23
 
22
24
  export type StartServerOptions = {
23
- connect?: {
24
- port?: string | number;
25
- };
26
- reactor?: {
27
- storagePath?: string;
28
- drive?: DriveInput;
29
- };
25
+ dev?: boolean;
26
+ port?: string | number;
27
+ storagePath?: string;
28
+ drive?: DriveInput;
30
29
  };
31
30
 
32
- const startServer = async (options?: StartServerOptions) => {
33
- const serverPort = Number(options?.connect?.port ?? process.env.PORT ?? 4001);
34
- const storagePath =
35
- options?.reactor?.storagePath ?? path.join(dirname, "./file-storage");
36
- const drive = options?.reactor?.drive ?? {
31
+ export const DefaultStartServerOptions = {
32
+ port: 4001,
33
+ storagePath: path.join(dirname, "./file-storage"),
34
+ drive: {
37
35
  global: {
38
36
  id: "powerhouse",
39
37
  name: "Powerhouse",
@@ -46,22 +44,62 @@ const startServer = async (options?: StartServerOptions) => {
46
44
  sharingType: "public",
47
45
  triggers: [],
48
46
  },
47
+ },
48
+ } satisfies StartServerOptions;
49
+
50
+ export type LocalReactor = {
51
+ driveUrl: string;
52
+ getDocumentPath: (driveId: string, documentId: string) => string;
53
+ addListener: (
54
+ driveId: string,
55
+ receiver: IReceiver,
56
+ options: {
57
+ listenerId: string;
58
+ label: string;
59
+ block: boolean;
60
+ filter: ListenerFilter;
61
+ },
62
+ ) => Promise<InternalTransmitter>;
63
+ };
64
+
65
+ const baseDocumentModels = [
66
+ DocumentModelLib,
67
+ ...Object.values(DocumentModelsLibs),
68
+ ] as DocumentModel[];
69
+
70
+ const startServer = async (
71
+ options?: StartServerOptions,
72
+ ): Promise<LocalReactor> => {
73
+ const { port, storagePath, drive, dev } = {
74
+ ...DefaultStartServerOptions,
75
+ ...options,
49
76
  };
77
+ const serverPort = Number(process.env.PORT ?? port);
78
+
50
79
  // start document drive server with all available document models & filesystem storage
51
80
  const driveServer = new DocumentDriveServer(
52
- [DocumentModelLib, ...Object.values(DocumentModelsLibs)] as DocumentModel[],
81
+ baseDocumentModels,
53
82
  new FilesystemStorage(storagePath),
54
83
  );
55
84
 
56
85
  // init drive server
57
86
  await driveServer.initialize();
58
87
 
88
+ let driveId = drive.global.slug ?? drive.global.id;
89
+ let driveUrl = "";
59
90
  try {
60
91
  // add default drive
61
- await driveServer.addDrive(drive);
92
+ const driveDoc = await driveServer.addDrive(drive);
93
+ driveId = driveDoc.state.global.slug ?? driveDoc.state.global.id;
62
94
  } catch (e) {
63
95
  if (e instanceof DriveAlreadyExistsError) {
64
96
  console.info("Default drive already exists. Skipping...");
97
+ if (driveId) {
98
+ const driveDoc = await (drive.global.slug
99
+ ? driveServer.getDriveBySlug(drive.global.slug)
100
+ : driveServer.getDrive(driveId));
101
+ driveId = driveDoc.state.global.slug ?? driveDoc.state.global.id;
102
+ }
65
103
  } else {
66
104
  throw e;
67
105
  }
@@ -69,14 +107,41 @@ const startServer = async (options?: StartServerOptions) => {
69
107
 
70
108
  try {
71
109
  // start api
72
- await startAPI(driveServer, {
110
+ const app = await startAPI(driveServer, {
73
111
  port: serverPort,
74
112
  });
113
+ driveUrl = `http://localhost:${serverPort}/${driveId ? `d/${drive.global.slug ?? drive.global.id}` : ""}`;
114
+ console.log(` ➜ Reactor: ${driveUrl}`);
115
+
116
+ if (dev) {
117
+ const vite = await createViteServer({
118
+ server: { middlewareMode: true },
119
+ appType: "custom",
120
+ build: {
121
+ rollupOptions: {
122
+ input: [],
123
+ },
124
+ },
125
+ });
126
+ app.use(vite.middlewares);
127
+
128
+ const documentModelsPath = path.join(process.cwd(), "./document-models");
129
+ console.log("Loading document models from", documentModelsPath);
130
+ const localDMs = (await vite.ssrLoadModule(documentModelsPath)) as Record<
131
+ string,
132
+ DocumentModel
133
+ >;
134
+ driveServer.setDocumentModels([
135
+ ...baseDocumentModels,
136
+ ...Object.values(localDMs),
137
+ ]);
138
+ }
75
139
  } catch (e) {
76
140
  console.error("App crashed", e);
77
141
  }
78
142
 
79
143
  return {
144
+ driveUrl,
80
145
  getDocumentPath: (driveId: string, documentId: string): string => {
81
146
  return path.join(storagePath, driveId, `${documentId}.json`);
82
147
  },