@powerhousedao/switchboard 6.0.0-staging.3 → 6.0.1-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/CHANGELOG.md +157 -11
- package/dist/src/index.js +31 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/metrics.d.ts +7 -0
- package/dist/src/metrics.d.ts.map +1 -0
- package/dist/src/metrics.js +34 -0
- package/dist/src/metrics.js.map +1 -0
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +81 -130
- package/dist/src/server.js.map +1 -1
- package/dist/src/types.d.ts +8 -18
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils.d.ts +2 -3
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +1 -31
- package/dist/src/utils.js.map +1 -1
- package/dist/test/metrics.test.d.ts +2 -0
- package/dist/test/metrics.test.d.ts.map +1 -0
- package/dist/test/metrics.test.js +121 -0
- package/dist/test/metrics.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +15 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +15 -8
- package/test/metrics.test.ts +202 -0
- package/tsconfig.json +5 -6
- package/vitest.config.ts +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,28 +1,174 @@
|
|
|
1
|
-
## 6.0.
|
|
1
|
+
## 6.0.1-staging.0 (2026-03-23)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- **examples:** add Discord webhook processor example ([fc09a4d66](https://github.com/powerhouse-inc/powerhouse/commit/fc09a4d66))
|
|
6
|
+
- **test-subscription:** adding a cli test-client for testing reactor api subscriptions ([563a8ac7d](https://github.com/powerhouse-inc/powerhouse/commit/563a8ac7d))
|
|
7
|
+
- **switchboard:** add OTel metrics export via OTEL_EXPORTER_OTLP_ENDPOINT ([52f34aa1f](https://github.com/powerhouse-inc/powerhouse/commit/52f34aa1f))
|
|
8
|
+
- reactor-hypercore example ([d5557973a](https://github.com/powerhouse-inc/powerhouse/commit/d5557973a))
|
|
9
|
+
- **renown,reactor-browser:** renown integration improvements ([a65731a73](https://github.com/powerhouse-inc/powerhouse/commit/a65731a73))
|
|
10
|
+
- **ci:** add gitops action for registry image updates ([ba91d00dd](https://github.com/powerhouse-inc/powerhouse/commit/ba91d00dd))
|
|
11
|
+
- **ci:** add registry Docker image to publish workflow ([17544abad](https://github.com/powerhouse-inc/powerhouse/commit/17544abad))
|
|
12
|
+
- opentelementry-instrumentation-reactor package ([67d5c31e5](https://github.com/powerhouse-inc/powerhouse/commit/67d5c31e5))
|
|
13
|
+
- **renown,reactor-browser,connect:** cleanup renown integration ([fe6112c2c](https://github.com/powerhouse-inc/powerhouse/commit/fe6112c2c))
|
|
14
|
+
- **connect,reactor-browser:** add dynamic package loading from HTTP registry ([f92816782](https://github.com/powerhouse-inc/powerhouse/commit/f92816782))
|
|
15
|
+
- **document-model,reactor-api,reactor-browser:** implemented remote document controller ([6299c21da](https://github.com/powerhouse-inc/powerhouse/commit/6299c21da))
|
|
16
|
+
- **switchboard,reactor-api,registry:** add runtime dynamic pacage loading from HTTP registry ([37f91250e](https://github.com/powerhouse-inc/powerhouse/commit/37f91250e))
|
|
17
|
+
- add new bundling for connect ([#2390](https://github.com/powerhouse-inc/powerhouse/pull/2390))
|
|
18
|
+
|
|
19
|
+
### 🩹 Fixes
|
|
20
|
+
|
|
21
|
+
- **reactor:** temporary fix for deleting documents and cleaning up all edges too -- very costly ([8a15a0604](https://github.com/powerhouse-inc/powerhouse/commit/8a15a0604))
|
|
22
|
+
- update workflow to use refname for tag in case it is not annotated, and provide a clear error message when there is no tag ([269758716](https://github.com/powerhouse-inc/powerhouse/commit/269758716))
|
|
23
|
+
- **builder-tools,reactor-browser:** bundling fixes ([59dfd75b6](https://github.com/powerhouse-inc/powerhouse/commit/59dfd75b6))
|
|
24
|
+
- updated pnpm-lock ([c2843dc5b](https://github.com/powerhouse-inc/powerhouse/commit/c2843dc5b))
|
|
25
|
+
- **connect:** declare dependencies ([6aa6910d3](https://github.com/powerhouse-inc/powerhouse/commit/6aa6910d3))
|
|
26
|
+
- **design-system:** removed zod dependency ([fdc7c2ef7](https://github.com/powerhouse-inc/powerhouse/commit/fdc7c2ef7))
|
|
27
|
+
- **switchboard:** avoid double /v1/metrics suffix in OTLP exporter URL ([c184093c3](https://github.com/powerhouse-inc/powerhouse/commit/c184093c3))
|
|
28
|
+
- **switchboard:** enforce OTel provider registration ordering via StartServerOptions ([c797fd242](https://github.com/powerhouse-inc/powerhouse/commit/c797fd242))
|
|
29
|
+
- **codegen:** added missing deps to boilerplate ([721dcb581](https://github.com/powerhouse-inc/powerhouse/commit/721dcb581))
|
|
30
|
+
- **switchboard:** derive exportTimeoutMillis from exportIntervalMillis ([775a77f3b](https://github.com/powerhouse-inc/powerhouse/commit/775a77f3b))
|
|
31
|
+
- **switchboard:** set exportTimeoutMillis to stay under shutdown deadline ([341d88d9e](https://github.com/powerhouse-inc/powerhouse/commit/341d88d9e))
|
|
32
|
+
- **switchboard:** address further OTel metrics review feedback ([dee185ba8](https://github.com/powerhouse-inc/powerhouse/commit/dee185ba8))
|
|
33
|
+
- **switchboard:** address OTel metrics review feedback ([c5ac016fc](https://github.com/powerhouse-inc/powerhouse/commit/c5ac016fc))
|
|
34
|
+
- **common:** added missing runtime dependencies ([b0f647f75](https://github.com/powerhouse-inc/powerhouse/commit/b0f647f75))
|
|
35
|
+
- adding build-bundle to simulate-ci-workflow ([ca93d1a2b](https://github.com/powerhouse-inc/powerhouse/commit/ca93d1a2b))
|
|
36
|
+
- **renown:** moved e2e script test to reactor-browser ([3c9b41045](https://github.com/powerhouse-inc/powerhouse/commit/3c9b41045))
|
|
37
|
+
- **registry:** resolve catalog references in Dockerfile with sed ([765e8fbdd](https://github.com/powerhouse-inc/powerhouse/commit/765e8fbdd))
|
|
38
|
+
- **registry:** copy pnpm-workspace.yaml for Docker build catalog resolution ([7407700b1](https://github.com/powerhouse-inc/powerhouse/commit/7407700b1))
|
|
39
|
+
- **reactor-browser:** removed subexports ([4cda7f44c](https://github.com/powerhouse-inc/powerhouse/commit/4cda7f44c))
|
|
40
|
+
- eslint config ([fb20b3726](https://github.com/powerhouse-inc/powerhouse/commit/fb20b3726))
|
|
41
|
+
- **vetra:** remove custom subgraphs from vetra ([3a1e3b9b0](https://github.com/powerhouse-inc/powerhouse/commit/3a1e3b9b0))
|
|
42
|
+
- resolve empty name causing silent ADD_FILE failure in drives ([b44ed0c1c](https://github.com/powerhouse-inc/powerhouse/commit/b44ed0c1c))
|
|
43
|
+
- **reactor-mcp:** adopt new reactor client interface for MCP server ([1b8e6fb19](https://github.com/powerhouse-inc/powerhouse/commit/1b8e6fb19))
|
|
44
|
+
|
|
45
|
+
### ❤️ Thank You
|
|
46
|
+
|
|
47
|
+
- acaldas @acaldas
|
|
48
|
+
- Benjamin Jordan
|
|
49
|
+
- Claude Opus 4.6
|
|
50
|
+
- Frank
|
|
51
|
+
- Guillermo Puente @gpuente
|
|
52
|
+
- Ryan Wolhuter @ryanwolhuter
|
|
53
|
+
- Samuel Hawksby-Robinson @Samyoul
|
|
54
|
+
|
|
55
|
+
## 6.0.0-staging.0 (2026-03-18)
|
|
2
56
|
|
|
3
57
|
### 🚀 Features
|
|
4
58
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
59
|
+
- **test-subscription:** adding a cli test-client for testing reactor api subscriptions ([563a8ac7d](https://github.com/powerhouse-inc/powerhouse/commit/563a8ac7d))
|
|
60
|
+
- **switchboard:** add OTel metrics export via OTEL_EXPORTER_OTLP_ENDPOINT ([52f34aa1f](https://github.com/powerhouse-inc/powerhouse/commit/52f34aa1f))
|
|
61
|
+
- reactor-hypercore example ([d5557973a](https://github.com/powerhouse-inc/powerhouse/commit/d5557973a))
|
|
62
|
+
- **renown,reactor-browser:** renown integration improvements ([a65731a73](https://github.com/powerhouse-inc/powerhouse/commit/a65731a73))
|
|
63
|
+
- **ci:** add gitops action for registry image updates ([ba91d00dd](https://github.com/powerhouse-inc/powerhouse/commit/ba91d00dd))
|
|
64
|
+
- **ci:** add registry Docker image to publish workflow ([17544abad](https://github.com/powerhouse-inc/powerhouse/commit/17544abad))
|
|
65
|
+
- opentelementry-instrumentation-reactor package ([67d5c31e5](https://github.com/powerhouse-inc/powerhouse/commit/67d5c31e5))
|
|
66
|
+
- **renown,reactor-browser,connect:** cleanup renown integration ([fe6112c2c](https://github.com/powerhouse-inc/powerhouse/commit/fe6112c2c))
|
|
67
|
+
- **connect,reactor-browser:** add dynamic package loading from HTTP registry ([f92816782](https://github.com/powerhouse-inc/powerhouse/commit/f92816782))
|
|
68
|
+
- **document-model,reactor-api,reactor-browser:** implemented remote document controller ([6299c21da](https://github.com/powerhouse-inc/powerhouse/commit/6299c21da))
|
|
69
|
+
- **switchboard,reactor-api,registry:** add runtime dynamic pacage loading from HTTP registry ([37f91250e](https://github.com/powerhouse-inc/powerhouse/commit/37f91250e))
|
|
70
|
+
- add new bundling for connect ([#2390](https://github.com/powerhouse-inc/powerhouse/pull/2390))
|
|
71
|
+
|
|
72
|
+
### 🩹 Fixes
|
|
73
|
+
|
|
74
|
+
- updated pnpm-lock ([c2843dc5b](https://github.com/powerhouse-inc/powerhouse/commit/c2843dc5b))
|
|
75
|
+
- **connect:** declare dependencies ([6aa6910d3](https://github.com/powerhouse-inc/powerhouse/commit/6aa6910d3))
|
|
76
|
+
- **design-system:** removed zod dependency ([fdc7c2ef7](https://github.com/powerhouse-inc/powerhouse/commit/fdc7c2ef7))
|
|
77
|
+
- **switchboard:** avoid double /v1/metrics suffix in OTLP exporter URL ([c184093c3](https://github.com/powerhouse-inc/powerhouse/commit/c184093c3))
|
|
78
|
+
- **switchboard:** enforce OTel provider registration ordering via StartServerOptions ([c797fd242](https://github.com/powerhouse-inc/powerhouse/commit/c797fd242))
|
|
79
|
+
- **codegen:** added missing deps to boilerplate ([721dcb581](https://github.com/powerhouse-inc/powerhouse/commit/721dcb581))
|
|
80
|
+
- **switchboard:** derive exportTimeoutMillis from exportIntervalMillis ([775a77f3b](https://github.com/powerhouse-inc/powerhouse/commit/775a77f3b))
|
|
81
|
+
- **switchboard:** set exportTimeoutMillis to stay under shutdown deadline ([341d88d9e](https://github.com/powerhouse-inc/powerhouse/commit/341d88d9e))
|
|
82
|
+
- **switchboard:** address further OTel metrics review feedback ([dee185ba8](https://github.com/powerhouse-inc/powerhouse/commit/dee185ba8))
|
|
83
|
+
- **switchboard:** address OTel metrics review feedback ([c5ac016fc](https://github.com/powerhouse-inc/powerhouse/commit/c5ac016fc))
|
|
84
|
+
- **common:** added missing runtime dependencies ([b0f647f75](https://github.com/powerhouse-inc/powerhouse/commit/b0f647f75))
|
|
85
|
+
- adding build-bundle to simulate-ci-workflow ([ca93d1a2b](https://github.com/powerhouse-inc/powerhouse/commit/ca93d1a2b))
|
|
86
|
+
- **renown:** moved e2e script test to reactor-browser ([3c9b41045](https://github.com/powerhouse-inc/powerhouse/commit/3c9b41045))
|
|
87
|
+
- **registry:** resolve catalog references in Dockerfile with sed ([765e8fbdd](https://github.com/powerhouse-inc/powerhouse/commit/765e8fbdd))
|
|
88
|
+
- **registry:** copy pnpm-workspace.yaml for Docker build catalog resolution ([7407700b1](https://github.com/powerhouse-inc/powerhouse/commit/7407700b1))
|
|
89
|
+
- **reactor-browser:** removed subexports ([4cda7f44c](https://github.com/powerhouse-inc/powerhouse/commit/4cda7f44c))
|
|
90
|
+
- eslint config ([fb20b3726](https://github.com/powerhouse-inc/powerhouse/commit/fb20b3726))
|
|
91
|
+
- **vetra:** remove custom subgraphs from vetra ([3a1e3b9b0](https://github.com/powerhouse-inc/powerhouse/commit/3a1e3b9b0))
|
|
92
|
+
- resolve empty name causing silent ADD_FILE failure in drives ([b44ed0c1c](https://github.com/powerhouse-inc/powerhouse/commit/b44ed0c1c))
|
|
93
|
+
- **reactor-mcp:** adopt new reactor client interface for MCP server ([1b8e6fb19](https://github.com/powerhouse-inc/powerhouse/commit/1b8e6fb19))
|
|
94
|
+
|
|
95
|
+
### ❤️ Thank You
|
|
96
|
+
|
|
97
|
+
- acaldas
|
|
98
|
+
- Benjamin Jordan
|
|
99
|
+
- Frank
|
|
100
|
+
- Guillermo Puente
|
|
101
|
+
- Ryan Wolhuter
|
|
102
|
+
- Samuel Hawksby-Robinson
|
|
103
|
+
|
|
104
|
+
## 6.0.1-staging.1 (2026-03-03)
|
|
105
|
+
|
|
106
|
+
This was a version bump only for @powerhousedao/switchboard to align it with other projects, there were no code changes.
|
|
107
|
+
|
|
108
|
+
## 6.0.0-dev.67 (2026-03-03)
|
|
109
|
+
|
|
110
|
+
This was a version bump only for @powerhousedao/switchboard to align it with other projects, there were no code changes.
|
|
111
|
+
|
|
112
|
+
## 6.0.0-dev.66 (2026-03-03)
|
|
113
|
+
|
|
114
|
+
### 🚀 Features
|
|
115
|
+
|
|
116
|
+
- move reactor logic from connect to reactor browser ([#2385](https://github.com/powerhouse-inc/powerhouse/pull/2385))
|
|
7
117
|
|
|
8
118
|
### ❤️ Thank You
|
|
9
119
|
|
|
10
120
|
- Ryan Wolhuter @ryanwolhuter
|
|
11
121
|
|
|
12
|
-
## 6.0.0-
|
|
122
|
+
## 6.0.0-dev.65 (2026-03-03)
|
|
123
|
+
|
|
124
|
+
This was a version bump only for @powerhousedao/switchboard to align it with other projects, there were no code changes.
|
|
125
|
+
|
|
126
|
+
## 6.0.0-dev.64 (2026-03-03)
|
|
127
|
+
|
|
128
|
+
This was a version bump only for @powerhousedao/switchboard to align it with other projects, there were no code changes.
|
|
129
|
+
|
|
130
|
+
## 6.0.0-dev.62 (2026-03-03)
|
|
13
131
|
|
|
14
132
|
### 🚀 Features
|
|
15
133
|
|
|
16
|
-
-
|
|
134
|
+
- **ci:** push academy to Harbor academy project and update k8s for academy namespace ([efbf8f58d](https://github.com/powerhouse-inc/powerhouse/commit/efbf8f58d))
|
|
135
|
+
|
|
136
|
+
### 🩹 Fixes
|
|
137
|
+
|
|
138
|
+
- cherry-picked fixes ([a73630a6a](https://github.com/powerhouse-inc/powerhouse/commit/a73630a6a))
|
|
139
|
+
- moving analytics processors to shared and fixing them, fixing other linting errors toos ([0c8f7fe98](https://github.com/powerhouse-inc/powerhouse/commit/0c8f7fe98))
|
|
17
140
|
|
|
18
141
|
### ❤️ Thank You
|
|
19
142
|
|
|
143
|
+
- Benjamin Jordan
|
|
144
|
+
- Frank
|
|
145
|
+
|
|
146
|
+
## 6.0.0-dev.61 (2026-02-27)
|
|
147
|
+
|
|
148
|
+
### 🚀 Features
|
|
149
|
+
|
|
150
|
+
- **ci:** update k8s-hosting academy image tag after docker publish ([0b98b73a9](https://github.com/powerhouse-inc/powerhouse/commit/0b98b73a9))
|
|
151
|
+
- add bundle step for ph cli ([#2375](https://github.com/powerhouse-inc/powerhouse/pull/2375))
|
|
152
|
+
|
|
153
|
+
### ❤️ Thank You
|
|
154
|
+
|
|
155
|
+
- Frank
|
|
20
156
|
- Ryan Wolhuter @ryanwolhuter
|
|
21
157
|
|
|
22
|
-
## 6.0.0-
|
|
158
|
+
## 6.0.0-dev.60 (2026-02-27)
|
|
23
159
|
|
|
24
160
|
This was a version bump only for @powerhousedao/switchboard to align it with other projects, there were no code changes.
|
|
25
161
|
|
|
162
|
+
## 6.0.0-dev.59 (2026-02-26)
|
|
163
|
+
|
|
164
|
+
### 🚀 Features
|
|
165
|
+
|
|
166
|
+
- use update-ts-references tool which also removes unused ones ([#2374](https://github.com/powerhouse-inc/powerhouse/pull/2374))
|
|
167
|
+
|
|
168
|
+
### ❤️ Thank You
|
|
169
|
+
|
|
170
|
+
- Ryan Wolhuter @ryanwolhuter
|
|
171
|
+
|
|
26
172
|
## 6.0.0-dev.58 (2026-02-25)
|
|
27
173
|
|
|
28
174
|
### 🚀 Features
|
|
@@ -510,7 +656,7 @@ This was a version bump only for @powerhousedao/switchboard to align it with oth
|
|
|
510
656
|
### 🚀 Features
|
|
511
657
|
|
|
512
658
|
- **design-system:** default styles tweaks and DocumentStateViewer ([c0a66720c](https://github.com/powerhouse-inc/powerhouse/commit/c0a66720c))
|
|
513
|
-
- **ci:** deploy staging tenant from release/staging
|
|
659
|
+
- **ci:** deploy staging tenant from release/staging/\* branches ([8761579e7](https://github.com/powerhouse-inc/powerhouse/commit/8761579e7))
|
|
514
660
|
- **ci:** add Harbor registry to docker image publishing ([f3a2fab69](https://github.com/powerhouse-inc/powerhouse/commit/f3a2fab69))
|
|
515
661
|
|
|
516
662
|
### 🩹 Fixes
|
|
@@ -3135,7 +3281,7 @@ This was a version bump only for @powerhousedao/switchboard to align it with oth
|
|
|
3135
3281
|
|
|
3136
3282
|
- **reactor-api:** init project ([#388](https://github.com/powerhouse-inc/powerhouse/pull/388))
|
|
3137
3283
|
|
|
3138
|
-
### ❤️
|
|
3284
|
+
### ❤️ Thank You
|
|
3139
3285
|
|
|
3140
3286
|
- acaldas
|
|
3141
3287
|
|
|
@@ -3149,7 +3295,7 @@ This was a version bump only for @powerhousedao/switchboard to align it with oth
|
|
|
3149
3295
|
|
|
3150
3296
|
- Updated @powerhousedao/reactor-api to 1.1.0
|
|
3151
3297
|
|
|
3152
|
-
### ❤️
|
|
3298
|
+
### ❤️ Thank You
|
|
3153
3299
|
|
|
3154
3300
|
- acaldas
|
|
3155
3301
|
|
|
@@ -3163,6 +3309,6 @@ This was a version bump only for @powerhousedao/switchboard to align it with oth
|
|
|
3163
3309
|
|
|
3164
3310
|
- Updated @powerhousedao/general-document-indexer to 1.1.0
|
|
3165
3311
|
|
|
3166
|
-
### ❤️
|
|
3312
|
+
### ❤️ Thank You
|
|
3167
3313
|
|
|
3168
|
-
- acaldas
|
|
3314
|
+
- acaldas
|
package/dist/src/index.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import * as Sentry from "@sentry/node";
|
|
3
|
+
import { childLogger } from "document-drive";
|
|
2
4
|
import { config } from "./config.js";
|
|
5
|
+
import { createMeterProviderFromEnv } from "./metrics.js";
|
|
6
|
+
import { initProfilerFromEnv } from "./profiler.js";
|
|
3
7
|
import { startSwitchboard } from "./server.js";
|
|
8
|
+
const logger = childLogger(["switchboard"]);
|
|
4
9
|
function ensureNodeVersion(minVersion = "24") {
|
|
5
10
|
const version = process.versions.node;
|
|
6
11
|
if (!version) {
|
|
@@ -13,9 +18,32 @@ function ensureNodeVersion(minVersion = "24") {
|
|
|
13
18
|
}
|
|
14
19
|
// Ensure minimum Node.js version
|
|
15
20
|
ensureNodeVersion("24");
|
|
16
|
-
|
|
21
|
+
const meterProvider = createMeterProviderFromEnv({
|
|
22
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
23
|
+
OTEL_METRIC_EXPORT_INTERVAL: process.env.OTEL_METRIC_EXPORT_INTERVAL,
|
|
24
|
+
OTEL_SERVICE_NAME: process.env.OTEL_SERVICE_NAME,
|
|
25
|
+
});
|
|
26
|
+
async function shutdown() {
|
|
17
27
|
console.log("\nShutting down...");
|
|
28
|
+
// Flush final metrics before exit. Races against a 5s deadline so an
|
|
29
|
+
// unresponsive OTLP endpoint cannot exhaust terminationGracePeriodSeconds.
|
|
30
|
+
await Promise.race([
|
|
31
|
+
meterProvider?.shutdown().catch(() => undefined),
|
|
32
|
+
new Promise((resolve) => setTimeout(resolve, 5_000)),
|
|
33
|
+
]);
|
|
18
34
|
process.exit(0);
|
|
19
|
-
}
|
|
20
|
-
|
|
35
|
+
}
|
|
36
|
+
// SIGINT: Ctrl-C in development; SIGTERM: graceful shutdown in Docker/Kubernetes
|
|
37
|
+
process.on("SIGINT", shutdown);
|
|
38
|
+
process.on("SIGTERM", shutdown);
|
|
39
|
+
if (process.env.PYROSCOPE_SERVER_ADDRESS) {
|
|
40
|
+
try {
|
|
41
|
+
await initProfilerFromEnv(process.env);
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
Sentry.captureException(e);
|
|
45
|
+
logger.error("Error starting profiler: @error", e);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
startSwitchboard({ ...config, meterProvider }).catch(console.error);
|
|
21
49
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,SAAS,iBAAiB,CAAC,UAAU,GAAG,IAAI;IAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IAED,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CACX,gBAAgB,UAAU,4CAA4C,OAAO,EAAE,CAChF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AACD,iCAAiC;AACjC,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAExB,OAAO,CAAC,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;AAE5C,SAAS,iBAAiB,CAAC,UAAU,GAAG,IAAI;IAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IAED,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CACX,gBAAgB,UAAU,4CAA4C,OAAO,EAAE,CAChF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AACD,iCAAiC;AACjC,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAExB,MAAM,aAAa,GAAG,0BAA0B,CAAC;IAC/C,2BAA2B,EAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B;IACpE,2BAA2B,EAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B;IACpE,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;CACjD,CAAC,CAAC;AAEH,KAAK,UAAU,QAAQ;IACrB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,qEAAqE;IACrE,2EAA2E;IAC3E,MAAM,OAAO,CAAC,IAAI,CAAC;QACjB,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;QAChD,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;KAC3D,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,iFAAiF;AACjF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEhC,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,gBAAgB,CAAC,EAAE,GAAG,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MeterProvider } from "@opentelemetry/sdk-metrics";
|
|
2
|
+
export declare function createMeterProviderFromEnv(env: {
|
|
3
|
+
OTEL_EXPORTER_OTLP_ENDPOINT?: string;
|
|
4
|
+
OTEL_METRIC_EXPORT_INTERVAL?: string;
|
|
5
|
+
OTEL_SERVICE_NAME?: string;
|
|
6
|
+
}): MeterProvider | undefined;
|
|
7
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/metrics.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,aAAa,EAEd,MAAM,4BAA4B,CAAC;AAKpC,wBAAgB,0BAA0B,CAAC,GAAG,EAAE;IAC9C,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,aAAa,GAAG,SAAS,CA8B5B"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
|
2
|
+
import { Resource } from "@opentelemetry/resources";
|
|
3
|
+
import { MeterProvider, PeriodicExportingMetricReader, } from "@opentelemetry/sdk-metrics";
|
|
4
|
+
import { childLogger } from "document-drive";
|
|
5
|
+
const logger = childLogger(["switchboard", "metrics"]);
|
|
6
|
+
export function createMeterProviderFromEnv(env) {
|
|
7
|
+
const endpoint = env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
8
|
+
if (!endpoint)
|
|
9
|
+
return undefined;
|
|
10
|
+
const parsed = parseInt(env.OTEL_METRIC_EXPORT_INTERVAL ?? "", 10);
|
|
11
|
+
const exportIntervalMillis = Number.isFinite(parsed) && parsed > 0 ? parsed : 5_000;
|
|
12
|
+
const base = endpoint.replace(/\/$/, "");
|
|
13
|
+
const exporterUrl = base.endsWith("/v1/metrics")
|
|
14
|
+
? base
|
|
15
|
+
: `${base}/v1/metrics`;
|
|
16
|
+
logger.info(`Initializing OpenTelemetry metrics exporter at: ${endpoint}`);
|
|
17
|
+
const meterProvider = new MeterProvider({
|
|
18
|
+
resource: new Resource({
|
|
19
|
+
"service.name": env.OTEL_SERVICE_NAME ?? "switchboard",
|
|
20
|
+
}),
|
|
21
|
+
readers: [
|
|
22
|
+
new PeriodicExportingMetricReader({
|
|
23
|
+
exporter: new OTLPMetricExporter({
|
|
24
|
+
url: exporterUrl,
|
|
25
|
+
}),
|
|
26
|
+
exportIntervalMillis,
|
|
27
|
+
exportTimeoutMillis: Math.max(exportIntervalMillis - 250, 1),
|
|
28
|
+
}),
|
|
29
|
+
],
|
|
30
|
+
});
|
|
31
|
+
logger.info(`Metrics export enabled (interval: ${exportIntervalMillis}ms)`);
|
|
32
|
+
return meterProvider;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EACL,aAAa,EACb,6BAA6B,GAC9B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;AAEvD,MAAM,UAAU,0BAA0B,CAAC,GAI1C;IACC,MAAM,QAAQ,GAAG,GAAG,CAAC,2BAA2B,CAAC;IACjD,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEhC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,2BAA2B,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACnE,MAAM,oBAAoB,GACxB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAEzD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC9C,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,GAAG,IAAI,aAAa,CAAC;IAEzB,MAAM,CAAC,IAAI,CAAC,mDAAmD,QAAQ,EAAE,CAAC,CAAC;IAC3E,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC;QACtC,QAAQ,EAAE,IAAI,QAAQ,CAAC;YACrB,cAAc,EAAE,GAAG,CAAC,iBAAiB,IAAI,aAAa;SACvD,CAAC;QACF,OAAO,EAAE;YACP,IAAI,6BAA6B,CAAC;gBAChC,QAAQ,EAAE,IAAI,kBAAkB,CAAC;oBAC/B,GAAG,EAAE,WAAW;iBACjB,CAAC;gBACF,oBAAoB;gBACpB,mBAAmB,EAAE,IAAI,CAAC,GAAG,CAAC,oBAAoB,GAAG,GAAG,EAAE,CAAC,CAAC;aAC7D,CAAC;SACH;KACF,CAAC,CAAC;IACH,MAAM,CAAC,IAAI,CAAC,qCAAqC,oBAAoB,KAAK,CAAC,CAAC;IAC5E,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
package/dist/src/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":";AA4CA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":";AA4CA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA+RzE,eAAO,MAAM,gBAAgB,GAC3B,UAAS,kBAAuB,KAC/B,OAAO,CAAC,kBAAkB,CA+C5B,CAAC;AAEF,cAAc,YAAY,CAAC"}
|
package/dist/src/server.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { httpsHooksPath } from "@powerhousedao/reactor-api";
|
|
3
|
+
import { register } from "node:module";
|
|
4
|
+
// Register HTTP/HTTPS module loader hooks for dynamic package imports
|
|
5
|
+
register(httpsHooksPath, import.meta.url);
|
|
2
6
|
import { PGlite } from "@electric-sql/pglite";
|
|
7
|
+
import { ReactorInstrumentation } from "@powerhousedao/opentelemetry-instrumentation-reactor";
|
|
3
8
|
import { ChannelScheme, EventBus, ReactorBuilder, ReactorClientBuilder, driveCollectionId, parseDriveUrl, } from "@powerhousedao/reactor";
|
|
4
|
-
import {
|
|
9
|
+
import { metrics } from "@opentelemetry/api";
|
|
10
|
+
import { HttpPackageLoader, PackageManagementService, PackagesSubgraph, VitePackageLoader, createViteLogger, getUniqueDocumentModels, initializeAndStartAPI, startViteServer, } from "@powerhousedao/reactor-api";
|
|
5
11
|
import {} from "@renown/sdk";
|
|
6
12
|
import * as Sentry from "@sentry/node";
|
|
7
|
-
import {
|
|
8
|
-
import { RedisCache } from "document-drive/cache/redis";
|
|
9
|
-
import { FilesystemStorage } from "document-drive/storage/filesystem";
|
|
10
|
-
import { PrismaStorageFactory } from "document-drive/storage/prisma";
|
|
13
|
+
import { childLogger, driveDocumentModelModule } from "document-drive";
|
|
11
14
|
import { documentModelDocumentModelModule } from "document-model";
|
|
12
15
|
import dotenv from "dotenv";
|
|
13
16
|
import express from "express";
|
|
@@ -17,20 +20,13 @@ import path from "path";
|
|
|
17
20
|
import { Pool } from "pg";
|
|
18
21
|
import { initRedis } from "./clients/redis.js";
|
|
19
22
|
import { initFeatureFlags } from "./feature-flags.js";
|
|
20
|
-
import { initProfilerFromEnv } from "./profiler.js";
|
|
21
23
|
import { initRenown } from "./renown.js";
|
|
22
|
-
import { addDefaultDrive,
|
|
24
|
+
import { addDefaultDrive, isPostgresUrl } from "./utils.js";
|
|
23
25
|
const defaultLogger = childLogger(["switchboard"]);
|
|
24
26
|
dotenv.config();
|
|
25
27
|
// Feature flag constants
|
|
26
28
|
const DOCUMENT_MODEL_SUBGRAPHS_ENABLED = "DOCUMENT_MODEL_SUBGRAPHS_ENABLED";
|
|
27
29
|
const DOCUMENT_MODEL_SUBGRAPHS_ENABLED_DEFAULT = true;
|
|
28
|
-
const REACTOR_STORAGE_V2 = "REACTOR_STORAGE_V2";
|
|
29
|
-
const REACTOR_STORAGE_V2_DEFAULT = true;
|
|
30
|
-
const ENABLE_DUAL_ACTION_CREATE = "ENABLE_DUAL_ACTION_CREATE";
|
|
31
|
-
const ENABLE_DUAL_ACTION_CREATE_DEFAULT = true;
|
|
32
|
-
const USE_NEW_DOCUMENT_MODEL_SUBGRAPH = "USE_NEW_DOCUMENT_MODEL_SUBGRAPH";
|
|
33
|
-
const USE_NEW_DOCUMENT_MODEL_SUBGRAPH_DEFAULT = true;
|
|
34
30
|
// Create a monolith express app for all subgraphs
|
|
35
31
|
const app = express();
|
|
36
32
|
if (process.env.SENTRY_DSN) {
|
|
@@ -42,47 +38,14 @@ if (process.env.SENTRY_DSN) {
|
|
|
42
38
|
Sentry.setupExpressErrorHandler(app);
|
|
43
39
|
}
|
|
44
40
|
const DEFAULT_PORT = process.env.PORT ? Number(process.env.PORT) : 4001;
|
|
45
|
-
async function initPrismaStorage(connectionString, cache) {
|
|
46
|
-
try {
|
|
47
|
-
const prismaFactory = new PrismaStorageFactory(connectionString, cache);
|
|
48
|
-
await prismaFactory.checkConnection();
|
|
49
|
-
return prismaFactory.build();
|
|
50
|
-
}
|
|
51
|
-
catch (e) {
|
|
52
|
-
const prismaConnectError = "Can't reach database server at";
|
|
53
|
-
if (e instanceof Error && e.message.includes(prismaConnectError)) {
|
|
54
|
-
const dbUrl = connectionString;
|
|
55
|
-
const safeUrl = `${dbUrl.slice(0, dbUrl.indexOf(":") + 1)}{...}${dbUrl.slice(dbUrl.indexOf("@"), dbUrl.lastIndexOf("?"))}`;
|
|
56
|
-
defaultLogger.warn("Can't reach database server at '@safeUrl'", safeUrl);
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
defaultLogger.error("@error", e);
|
|
60
|
-
}
|
|
61
|
-
throw e;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
async function initReactorStorage(cache, dbPath = "./.ph/drive-storage") {
|
|
65
|
-
const isPostgres = isPostgresUrl(dbPath);
|
|
66
|
-
try {
|
|
67
|
-
if (isPostgres) {
|
|
68
|
-
const connectionString = dbPath.includes("amazonaws") && !dbPath.includes("sslmode=no-verify")
|
|
69
|
-
? dbPath + "?sslmode=no-verify"
|
|
70
|
-
: dbPath;
|
|
71
|
-
const storage = await initPrismaStorage(connectionString, cache);
|
|
72
|
-
return { storage, storagePath: dbPath };
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
defaultLogger.warn("Falling back to filesystem storage");
|
|
77
|
-
}
|
|
78
|
-
// if url was postgres and connection failed, fallback to filesystem on default path
|
|
79
|
-
const filesystemPath = isPostgres ? "./.ph/drive-storage" : dbPath;
|
|
80
|
-
return {
|
|
81
|
-
storage: new FilesystemStorage(path.join(process.cwd(), filesystemPath)),
|
|
82
|
-
storagePath: filesystemPath,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
41
|
async function initServer(serverPort, options, renown) {
|
|
42
|
+
// Register the global MeterProvider before ReactorInstrumentation is
|
|
43
|
+
// constructed. setGlobalMeterProvider is a one-way door — once set it cannot
|
|
44
|
+
// be unset — so this must happen before initializeClient calls
|
|
45
|
+
// instrumentation.start() → createMetrics() → metrics.getMeter().
|
|
46
|
+
if (options.meterProvider) {
|
|
47
|
+
metrics.setGlobalMeterProvider(options.meterProvider);
|
|
48
|
+
}
|
|
86
49
|
const { dev, packages = [], remoteDrives = [], logger = defaultLogger, } = options;
|
|
87
50
|
const dbPath = options.dbPath ?? process.env.DATABASE_URL;
|
|
88
51
|
// start redis if configured
|
|
@@ -96,33 +59,24 @@ async function initServer(serverPort, options, renown) {
|
|
|
96
59
|
logger.error("@error", e);
|
|
97
60
|
}
|
|
98
61
|
}
|
|
99
|
-
const cache = redis ? new RedisCache(redis) : new InMemoryCache();
|
|
100
|
-
const { storage, storagePath } = await initReactorStorage(cache, dbPath);
|
|
101
62
|
// if dbPath is not configured, or it was a postgres url but the connection failed,
|
|
102
63
|
// use default path for read model storage
|
|
103
|
-
const readModelPath = !dbPath ||
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
},
|
|
118
|
-
})
|
|
119
|
-
.build();
|
|
120
|
-
// init drive server
|
|
121
|
-
await driveServer.initialize();
|
|
122
|
-
return driveServer;
|
|
123
|
-
};
|
|
64
|
+
const readModelPath = !dbPath || isPostgresUrl(dbPath) ? ".ph/read-storage" : dbPath;
|
|
65
|
+
// HTTP registry package loading
|
|
66
|
+
let httpDocumentModels = [];
|
|
67
|
+
const registryUrl = process.env.PH_REGISTRY_URL;
|
|
68
|
+
const registryPackages = process.env.PH_REGISTRY_PACKAGES;
|
|
69
|
+
let httpLoader;
|
|
70
|
+
if (registryUrl) {
|
|
71
|
+
httpLoader = new HttpPackageLoader({ registryUrl });
|
|
72
|
+
}
|
|
73
|
+
if (httpLoader && registryPackages) {
|
|
74
|
+
const packageNames = registryPackages.split(",").map((p) => p.trim());
|
|
75
|
+
httpDocumentModels = await httpLoader.loadPackages(packageNames, logger);
|
|
76
|
+
logger.info(`Loaded ${httpDocumentModels.length} HTTP document models from ${packageNames.length} packages`);
|
|
77
|
+
}
|
|
124
78
|
const reactorLogger = logger.child(["reactor"]);
|
|
125
|
-
const initializeClient = async (
|
|
79
|
+
const initializeClient = async (documentModels) => {
|
|
126
80
|
const eventBus = new EventBus();
|
|
127
81
|
const builder = new ReactorBuilder()
|
|
128
82
|
.withEventBus(eventBus)
|
|
@@ -130,8 +84,8 @@ async function initServer(serverPort, options, renown) {
|
|
|
130
84
|
documentModelDocumentModelModule,
|
|
131
85
|
driveDocumentModelModule,
|
|
132
86
|
...documentModels,
|
|
87
|
+
...httpDocumentModels,
|
|
133
88
|
]))
|
|
134
|
-
.withLegacyStorage(storage)
|
|
135
89
|
.withChannelScheme(ChannelScheme.SWITCHBOARD)
|
|
136
90
|
.withSignalHandlers()
|
|
137
91
|
.withLogger(reactorLogger);
|
|
@@ -161,12 +115,19 @@ async function initServer(serverPort, options, renown) {
|
|
|
161
115
|
builder.withKysely(kysely);
|
|
162
116
|
logger.info("Using PGlite for reactor storage");
|
|
163
117
|
}
|
|
118
|
+
if (httpLoader) {
|
|
119
|
+
builder.withDocumentModelLoader(httpLoader);
|
|
120
|
+
}
|
|
164
121
|
const clientBuilder = new ReactorClientBuilder().withReactorBuilder(builder);
|
|
165
122
|
if (renown) {
|
|
166
123
|
clientBuilder.withSigner(renown.signer);
|
|
167
124
|
}
|
|
168
125
|
const module = await clientBuilder.buildModule();
|
|
169
|
-
|
|
126
|
+
if (module.reactorModule) {
|
|
127
|
+
const instrumentation = new ReactorInstrumentation(module.reactorModule);
|
|
128
|
+
instrumentation.start();
|
|
129
|
+
reactorLogger.info("Reactor metrics instrumentation started");
|
|
130
|
+
}
|
|
170
131
|
return module;
|
|
171
132
|
};
|
|
172
133
|
let defaultDriveUrl = undefined;
|
|
@@ -181,14 +142,10 @@ async function initServer(serverPort, options, renown) {
|
|
|
181
142
|
if (!options.disableLocalPackages) {
|
|
182
143
|
packages.push(basePath);
|
|
183
144
|
}
|
|
184
|
-
//
|
|
185
|
-
const
|
|
186
|
-
// create loader with legacyReactor option
|
|
187
|
-
const packageLoader = vite
|
|
188
|
-
? VitePackageLoader.build(vite, { legacyReactor })
|
|
189
|
-
: undefined;
|
|
145
|
+
// create loader
|
|
146
|
+
const packageLoader = vite ? VitePackageLoader.build(vite) : undefined;
|
|
190
147
|
const apiLogger = logger.child(["reactor-api"]);
|
|
191
|
-
const api = await initializeAndStartAPI(
|
|
148
|
+
const api = await initializeAndStartAPI(initializeClient, {
|
|
192
149
|
express: app,
|
|
193
150
|
port: serverPort,
|
|
194
151
|
dbPath: readModelPath,
|
|
@@ -201,16 +158,40 @@ async function initServer(serverPort, options, renown) {
|
|
|
201
158
|
mcp: options.mcp ?? true,
|
|
202
159
|
logger: apiLogger,
|
|
203
160
|
enableDocumentModelSubgraphs: options.enableDocumentModelSubgraphs,
|
|
204
|
-
useNewDocumentModelSubgraph: options.useNewDocumentModelSubgraph,
|
|
205
|
-
legacyReactor,
|
|
206
161
|
}, "switchboard");
|
|
207
|
-
const { client,
|
|
162
|
+
const { client, graphqlManager, documentModelRegistry } = api;
|
|
163
|
+
// Wire up dynamic package management if HTTP loader is configured
|
|
164
|
+
if (httpLoader) {
|
|
165
|
+
const packageManagementService = new PackageManagementService({
|
|
166
|
+
defaultRegistryUrl: registryUrl,
|
|
167
|
+
httpLoader,
|
|
168
|
+
documentModelRegistry,
|
|
169
|
+
});
|
|
170
|
+
packageManagementService.setOnModelsChanged(async () => {
|
|
171
|
+
await graphqlManager.regenerateDocumentModelSubgraphs();
|
|
172
|
+
});
|
|
173
|
+
const packagesSubgraph = new PackagesSubgraph({
|
|
174
|
+
relationalDb: undefined,
|
|
175
|
+
analyticsStore: undefined,
|
|
176
|
+
reactorClient: client,
|
|
177
|
+
graphqlManager,
|
|
178
|
+
syncManager: api.syncManager,
|
|
179
|
+
path: graphqlManager.getBasePath(),
|
|
180
|
+
packageManagementService,
|
|
181
|
+
});
|
|
182
|
+
void graphqlManager
|
|
183
|
+
.registerSubgraphInstance(packagesSubgraph, "graphql", false)
|
|
184
|
+
.then(() => graphqlManager.updateRouter())
|
|
185
|
+
.catch((error) => {
|
|
186
|
+
logger.error("Failed to register packages subgraph: @error", error);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
208
189
|
// Create default drive if provided
|
|
209
190
|
if (options.drive) {
|
|
210
191
|
if (!renown) {
|
|
211
192
|
throw new Error("Cannot create default drive without Renown identity");
|
|
212
193
|
}
|
|
213
|
-
defaultDriveUrl = await addDefaultDrive(
|
|
194
|
+
defaultDriveUrl = await addDefaultDrive(client, options.drive, serverPort);
|
|
214
195
|
}
|
|
215
196
|
// add vite middleware after express app is initialized if applicable
|
|
216
197
|
if (vite) {
|
|
@@ -221,26 +202,19 @@ async function initServer(serverPort, options, renown) {
|
|
|
221
202
|
for (const remoteDriveUrl of remoteDrives) {
|
|
222
203
|
let driveId;
|
|
223
204
|
try {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const parsed = parseDriveUrl(remoteDriveUrl);
|
|
233
|
-
driveId = parsed.driveId;
|
|
234
|
-
const remoteName = `remote-drive-${driveId}-${crypto.randomUUID()}`;
|
|
235
|
-
await syncManager.add(remoteName, driveCollectionId("main", driveId), {
|
|
236
|
-
type: "gql",
|
|
237
|
-
parameters: { url: parsed.graphqlEndpoint },
|
|
238
|
-
});
|
|
239
|
-
}
|
|
205
|
+
const { syncManager } = api;
|
|
206
|
+
const parsed = parseDriveUrl(remoteDriveUrl);
|
|
207
|
+
driveId = parsed.driveId;
|
|
208
|
+
const remoteName = `remote-drive-${driveId}-${crypto.randomUUID()}`;
|
|
209
|
+
await syncManager.add(remoteName, driveCollectionId("main", driveId), {
|
|
210
|
+
type: "gql",
|
|
211
|
+
parameters: { url: parsed.graphqlEndpoint },
|
|
212
|
+
});
|
|
240
213
|
logger.debug("Remote drive @remoteDriveUrl synced", remoteDriveUrl);
|
|
241
214
|
}
|
|
242
215
|
catch (error) {
|
|
243
|
-
if (error instanceof
|
|
216
|
+
if (error instanceof Error &&
|
|
217
|
+
error.message.includes("already exists")) {
|
|
244
218
|
logger.debug("Remote drive already added: @remoteDriveUrl", remoteDriveUrl);
|
|
245
219
|
driveId = remoteDriveUrl.split("/").pop();
|
|
246
220
|
}
|
|
@@ -261,7 +235,6 @@ async function initServer(serverPort, options, renown) {
|
|
|
261
235
|
defaultDriveUrl,
|
|
262
236
|
api,
|
|
263
237
|
reactor: client,
|
|
264
|
-
legacyReactor: driveServer,
|
|
265
238
|
renown,
|
|
266
239
|
};
|
|
267
240
|
}
|
|
@@ -272,32 +245,10 @@ export const startSwitchboard = async (options = {}) => {
|
|
|
272
245
|
const enableDocumentModelSubgraphs = await featureFlags.getBooleanValue(DOCUMENT_MODEL_SUBGRAPHS_ENABLED, options.enableDocumentModelSubgraphs ??
|
|
273
246
|
DOCUMENT_MODEL_SUBGRAPHS_ENABLED_DEFAULT);
|
|
274
247
|
options.enableDocumentModelSubgraphs = enableDocumentModelSubgraphs;
|
|
275
|
-
const storageV2 = await featureFlags.getBooleanValue(REACTOR_STORAGE_V2, options.reactorOptions?.storageV2 ?? REACTOR_STORAGE_V2_DEFAULT);
|
|
276
|
-
const enableDualActionCreate = await featureFlags.getBooleanValue(ENABLE_DUAL_ACTION_CREATE, options.reactorOptions?.enableDualActionCreate ??
|
|
277
|
-
ENABLE_DUAL_ACTION_CREATE_DEFAULT);
|
|
278
|
-
const useNewDocumentModelSubgraph = await featureFlags.getBooleanValue(USE_NEW_DOCUMENT_MODEL_SUBGRAPH, options.useNewDocumentModelSubgraph ??
|
|
279
|
-
USE_NEW_DOCUMENT_MODEL_SUBGRAPH_DEFAULT);
|
|
280
|
-
options.useNewDocumentModelSubgraph = useNewDocumentModelSubgraph;
|
|
281
|
-
options.reactorOptions = {
|
|
282
|
-
enableDualActionCreate,
|
|
283
|
-
storageV2,
|
|
284
|
-
};
|
|
285
248
|
const logger = options.logger ?? defaultLogger;
|
|
286
249
|
logger.info("Feature flags: @flags", JSON.stringify({
|
|
287
250
|
DOCUMENT_MODEL_SUBGRAPHS_ENABLED: enableDocumentModelSubgraphs,
|
|
288
|
-
REACTOR_STORAGE_V2: storageV2,
|
|
289
|
-
ENABLE_DUAL_ACTION_CREATE: enableDualActionCreate,
|
|
290
|
-
USE_NEW_DOCUMENT_MODEL_SUBGRAPH: useNewDocumentModelSubgraph,
|
|
291
251
|
}, null, 2));
|
|
292
|
-
if (process.env.PYROSCOPE_SERVER_ADDRESS) {
|
|
293
|
-
try {
|
|
294
|
-
await initProfilerFromEnv(process.env);
|
|
295
|
-
}
|
|
296
|
-
catch (e) {
|
|
297
|
-
Sentry.captureException(e);
|
|
298
|
-
logger.error("Error starting profiler: @error", e);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
252
|
// Initialize Renown if identity options are provided or keypair exists
|
|
302
253
|
let renown = null;
|
|
303
254
|
try {
|