@shivaedev/server 0.3.0 → 0.4.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/README.md +93 -105
- package/dist/appHost.js +1 -1
- package/dist/appHost.js.map +1 -1
- package/dist/appHostHttp.d.ts +40 -41
- package/dist/appHostHttp.d.ts.map +1 -1
- package/dist/appHostHttp.js +3 -3
- package/dist/appHostHttp.js.map +1 -1
- package/dist/development.d.ts.map +1 -1
- package/dist/development.js +2 -1
- package/dist/development.js.map +1 -1
- package/dist/hostChanges.d.ts +2 -1
- package/dist/hostChanges.d.ts.map +1 -1
- package/dist/hostChanges.js +39 -5
- package/dist/hostChanges.js.map +1 -1
- package/dist/hostRpc.d.ts +1 -1
- package/dist/hostRpc.d.ts.map +1 -1
- package/dist/hostRpc.js +4 -2
- package/dist/hostRpc.js.map +1 -1
- package/dist/hostRpcRoutes.d.ts.map +1 -1
- package/dist/hostRpcRoutes.js +6 -2
- package/dist/hostRpcRoutes.js.map +1 -1
- package/dist/nodeHttpServer.js +1 -1
- package/dist/nodeHttpServer.js.map +1 -1
- package/dist/socketRpc.d.ts +6 -0
- package/dist/socketRpc.d.ts.map +1 -0
- package/dist/socketRpc.js +27 -0
- package/dist/socketRpc.js.map +1 -0
- package/package.json +6 -6
- package/src/appHost.ts +1 -1
- package/src/appHostHttp.ts +7 -7
- package/src/development.ts +2 -1
- package/src/hostChanges.ts +56 -9
- package/src/hostRpc.ts +4 -2
- package/src/hostRpcRoutes.ts +17 -2
- package/src/nodeHttpServer.ts +1 -1
- package/src/socketRpc.ts +36 -0
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ import { appHost } from "@shivaedev/server/appHost.ts";
|
|
|
13
13
|
import { Api, Handlers, Services, migrations, sessions } from "./app.ts";
|
|
14
14
|
|
|
15
15
|
NodeRuntime.runMain(
|
|
16
|
-
|
|
16
|
+
Layer.launch(appHost({ group: Api, handlers: Handlers, services: Services, migrations: { loader: migrations }, sessions, assets: "./public" })),
|
|
17
17
|
);
|
|
18
18
|
```
|
|
19
19
|
|
|
@@ -35,7 +35,7 @@ The optional modules solve different boundaries. `runtime/` carries Effect servi
|
|
|
35
35
|
|
|
36
36
|
### Host the application
|
|
37
37
|
|
|
38
|
-
`appHost` is the server entry point for an Effect app. For a PostgreSQL app, supply the native RPC group, handler and service Layers, migration loader, session policy and static asset directory. The host completes migrations before acquiring application services, starts Node HTTP with
|
|
38
|
+
`appHost` is the server entry point for an Effect app. For a PostgreSQL app, supply the native RPC group, handler and service Layers, migration loader, session policy and static asset directory. The host completes migrations before acquiring application services, starts Node HTTP with native Effect RPC over a WebSocket upgrade at `/rpc`, and provides SQL, Reactivity and `AppChanges` to those Layers.
|
|
39
39
|
|
|
40
40
|
```ts
|
|
41
41
|
import { NodeRuntime } from "@effect/platform-node";
|
|
@@ -44,12 +44,12 @@ import { appHost } from "@shivaedev/server/appHost.ts";
|
|
|
44
44
|
import { Api, Handlers, Services, migrations, sessions } from "./app.ts";
|
|
45
45
|
|
|
46
46
|
const Server = appHost({
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
group: Api,
|
|
48
|
+
handlers: Handlers,
|
|
49
|
+
services: Services,
|
|
50
|
+
migrations: { loader: migrations },
|
|
51
|
+
sessions,
|
|
52
|
+
assets: "./public",
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
NodeRuntime.runMain(Layer.launch(Server));
|
|
@@ -65,15 +65,15 @@ Pass application HTTP endpoints through `routes`, including routes that read app
|
|
|
65
65
|
import { Effect, Layer } from "effect";
|
|
66
66
|
import { HttpMiddleware, HttpRouter, HttpServerResponse } from "effect/http";
|
|
67
67
|
|
|
68
|
-
const Routes = HttpRouter.add(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
const Routes = HttpRouter.add("*", "/.well-known/app", AppMetadata.pipe(Effect.map(HttpServerResponse.text))).pipe(
|
|
69
|
+
Layer.provide(
|
|
70
|
+
HttpRouter.middleware(
|
|
71
|
+
HttpMiddleware.cors({
|
|
72
|
+
allowedOrigins: ["*"],
|
|
73
|
+
allowedMethods: ["GET"],
|
|
74
|
+
}),
|
|
75
|
+
).layer,
|
|
76
|
+
),
|
|
77
77
|
);
|
|
78
78
|
|
|
79
79
|
const Server = appHost({ group: Api, handlers: Handlers, services: Services, routes: Routes, sessions });
|
|
@@ -89,7 +89,7 @@ RPC request bodies are limited to 1 MiB by default. Set `MAX_BODY_SIZE` to a byt
|
|
|
89
89
|
|
|
90
90
|
For a native Node HTTP route outside RPC, read the request body with `readBoundedBody` from [`@shivaedev/http`](https://github.com/ShivaeDev/platform/tree/main/packages/http#readme), which rejects oversized bodies with a typed 413 failure.
|
|
91
91
|
|
|
92
|
-
RPC uses
|
|
92
|
+
Ordinary POST RPC uses `localRpcGuard` from `@shivaedev/identity/server/local.ts`: it requires a loopback peer and Host, same-origin or absent Origin, and the NDJSON content type. The WebSocket upgrade uses the same loopback, origin and trusted-proxy checks without an HTTP body content type. Session lookup uses the upgrade's transport headers; RPC message headers cannot replace its cookie or Origin. Session middleware revalidates authenticated streams at `streamRevalidationInterval` and ends revoked subscriptions with typed `Unauthorized`. The shared socket remains open; later protected calls use the same session checks. Automatic live subscriptions also recheck the session and query policy before each hint. POST RPC has no `$changes` stream. The host applies `RequestTracing` last to every served RPC, including loopback RPC, so it wraps authentication and handlers without a per-contract tracing declaration. Existing tracing declarations run once at that outermost boundary. With a session policy, contracts declare `Authenticated` and `MaybeAuthenticated` as needed; the host supplies their implementations. For `AuthenticatedUser`, merge `authenticatedUserLayer(sessions)` from `@shivaedev/identity/server/session.ts` beside the handlers. Declared errors retain their Schema types. Applications still own resource authorization and use `rpcBoundary` when they need to map unexpected failures.
|
|
93
93
|
|
|
94
94
|
Every response from the host's native RPC endpoint carries `Cache-Control: private, no-store`, including mixed public and authenticated batches, typed failures, transport rejections, body-read failures and streams. The host sets this at the outer response boundary without inspecting batch contents.
|
|
95
95
|
|
|
@@ -103,7 +103,7 @@ Set `migrations.mode: "check"` on `appDatabase` or a database-backed `appHost` w
|
|
|
103
103
|
|
|
104
104
|
Pass `migrations.components` beside `loader` for storage managed by another engine. For pg-boss, register `pgBossSchema({ schema: "app_jobs" })` from `@shivaedev/jobs/server/schema.ts`, then start every jobs Layer with `migrate: false`. `check` and `wait` use the same `MigrationError` readout for pending ledger IDs and component names and details, including pg-boss’s installed and required versions.
|
|
105
105
|
|
|
106
|
-
The host provides Effect's native `Crypto` service (`effect/Crypto`) to preflight, deferred application construction, application services and handlers. Generate invite codes and tokens through that service; see the [secure invite code example](
|
|
106
|
+
The host provides Effect's native `Crypto` service (`effect/Crypto`) to preflight, deferred application construction, application services and handlers. Generate invite codes and tokens through that service; see the [secure invite code example](https://github.com/ShivaeDev/platform/blob/main/docs/framework/README.md#secure-invite-codes-and-tokens). Use `Random` for non-secure choices.
|
|
107
107
|
|
|
108
108
|
Supply `preflight: AppConfigLive` to `appHost` to build a native Layer before checking or applying migrations, or constructing the application. Use it to validate configuration such as app IDs, keys and invite lists. Its errors stay in the returned Layer's typed error channel, its requirements other than `Crypto` remain external requirements, and its services are available to migrations, application construction, services and RPC handlers as well as callers of the host Layer. Preflight resources close with the host scope. The option also works without migrations.
|
|
109
109
|
|
|
@@ -111,13 +111,13 @@ When construction itself touches the schema, use `appHost({ migrations, config,
|
|
|
111
111
|
|
|
112
112
|
```ts
|
|
113
113
|
const host = appHost({
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
114
|
+
config: { databaseUrl },
|
|
115
|
+
migrations: { loader: migrations, mode: "check" },
|
|
116
|
+
preflight: AppConfigLive,
|
|
117
|
+
application: Effect.gen(function* () {
|
|
118
|
+
const { routes, sessions } = yield* makeAuth();
|
|
119
|
+
return { group: Api, handlers: Handlers, services: Services, routes, sessions };
|
|
120
|
+
}),
|
|
121
121
|
});
|
|
122
122
|
```
|
|
123
123
|
|
|
@@ -127,27 +127,27 @@ Set `OTEL_EXPORTER_OTLP_ENDPOINT` or `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` to exp
|
|
|
127
127
|
|
|
128
128
|
The supported tracing variables and defaults are:
|
|
129
129
|
|
|
130
|
-
| Variable
|
|
131
|
-
|
|
|
132
|
-
| `OTEL_EXPORTER_OTLP_ENDPOINT`
|
|
133
|
-
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Base URL plus `/v1/traces`
|
|
134
|
-
| `OTEL_EXPORTER_OTLP_PROTOCOL`
|
|
135
|
-
| `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` | General protocol
|
|
136
|
-
| `OTEL_EXPORTER_OTLP_HEADERS`
|
|
137
|
-
| `OTEL_SERVICE_NAME`
|
|
138
|
-
| `OTEL_SERVICE_VERSION`
|
|
139
|
-
| `OTEL_RESOURCE_ATTRIBUTES`
|
|
140
|
-
| `OTEL_EXPORTER_OTLP_TIMEOUT`
|
|
141
|
-
| `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT`
|
|
142
|
-
| `OTEL_BSP_SCHEDULE_DELAY`
|
|
143
|
-
| `OTEL_BSP_MAX_EXPORT_BATCH_SIZE`
|
|
144
|
-
| `OTEL_BSP_EXPORT_TIMEOUT`
|
|
130
|
+
| Variable | Default | Meaning |
|
|
131
|
+
| ------------------------------------ | ----------------------------------------------- | -------------------------------------------------------------------- |
|
|
132
|
+
| `OTEL_EXPORTER_OTLP_ENDPOINT` | Unset | Collector base URL. |
|
|
133
|
+
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Base URL plus `/v1/traces` | Complete traces URL; takes precedence. |
|
|
134
|
+
| `OTEL_EXPORTER_OTLP_PROTOCOL` | `http/protobuf` | `http/protobuf` or `http/json`. |
|
|
135
|
+
| `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` | General protocol | Overrides the protocol for traces. |
|
|
136
|
+
| `OTEL_EXPORTER_OTLP_HEADERS` | Empty | Comma-separated exporter headers. |
|
|
137
|
+
| `OTEL_SERVICE_NAME` | Resource `service.name`, then `unknown_service` | Service name. |
|
|
138
|
+
| `OTEL_SERVICE_VERSION` | Resource `service.version`, otherwise unset | Service version. |
|
|
139
|
+
| `OTEL_RESOURCE_ATTRIBUTES` | Empty | Comma-separated resource attributes. |
|
|
140
|
+
| `OTEL_EXPORTER_OTLP_TIMEOUT` | `10000` ms | Timeout for each HTTP export attempt, including its response body. |
|
|
141
|
+
| `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | General timeout | Overrides the request timeout for traces. |
|
|
142
|
+
| `OTEL_BSP_SCHEDULE_DELAY` | `5000` ms | Effect tracer's batch export interval. |
|
|
143
|
+
| `OTEL_BSP_MAX_EXPORT_BATCH_SIZE` | `1000` spans | Effect tracer's batch-size trigger. |
|
|
144
|
+
| `OTEL_BSP_EXPORT_TIMEOUT` | `3000` ms | Effect tracer's shutdown flush bound, capped at the request timeout. |
|
|
145
145
|
|
|
146
146
|
Timeouts fail through the HTTP client's typed transport-error channel and use the same warning path as other transport failures. Effect retains its native retry policy; the request timeout applies to each attempt. The batch defaults follow Effect's `OtlpTracer.layer`. Its options cannot express a separate batch-operation deadline or a queue capacity, so `OTEL_BSP_EXPORT_TIMEOUT` controls shutdown only and `OTEL_BSP_MAX_QUEUE_SIZE` is unsupported. Other `OTEL_BSP_*` variables are unsupported.
|
|
147
147
|
|
|
148
148
|
On Railway, enable the per-service tracing setting separately for the web service and worker, and leave both exporter endpoint variables unset in your app's configuration. Railway documents that it injects the `OTEL_*` variables, including `OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf`, only when the app sets no endpoint of its own. The framework exports through Effect's own `effect/observability` OTLP tracer; eBPF auto-instrumentation is outside this path. For a worker, provide `otlpTracing` from `@shivaedev/server/otlpTracing.ts` to its application Layer. It batches ended Effect spans and flushes during scoped shutdown with a three-second bound by default. The first failed export logs a warning with the collector status and redacted response body, or the transport failure kind when no response arrives. Repeated failures stay quiet until a successful export. Collector connection failures and HTTP errors leave requests, jobs and shutdown successful.
|
|
149
149
|
|
|
150
|
-
Exported HTTP server spans use `{method} {route}` with `http.route` for matched RPC and router paths, including parameter templates; unmatched requests use the method alone.
|
|
150
|
+
Exported HTTP server spans use `{method} {route}` with `http.route` for matched RPC and router paths, including parameter templates; unmatched requests use the method alone. `appHost` continues incoming W3C `traceparent` context in RPC handling, including one sent by an edge proxy, whether or not an exporter is configured.
|
|
151
151
|
|
|
152
152
|
Both JSON and protobuf export serialization apply sensitive-key and credential-text redaction to span attributes, events, links, error details and resource attributes. Credential text includes JWTs, Bearer/Basic credentials, sensitive assignments including bare `sig=...` anywhere in text (with or without `?`), and complete PEM private-key blocks through their matching END marker, including RSA, EC, OPENSSH and encrypted private keys. Matches become `<redacted>`. `sig` uses the shared sensitive-key policy for attributes and text. URL query values, fragments and user information are also redacted. Exporter headers stay in the collector request, outside the spans. Applications must still avoid placing secrets in span names, free text or custom attributes.
|
|
153
153
|
|
|
@@ -167,11 +167,7 @@ Use one `publicConfig` declaration per application as the one path for server co
|
|
|
167
167
|
import { Schema } from "effect";
|
|
168
168
|
import { publicConfig } from "@shivaedev/contract/publicConfig.ts";
|
|
169
169
|
|
|
170
|
-
export const PublicConfig = publicConfig(
|
|
171
|
-
Schema.Struct({ installUrl: Schema.URL }).pipe(
|
|
172
|
-
Schema.encodeKeys({ installUrl: "INSTALL_URL" }),
|
|
173
|
-
),
|
|
174
|
-
);
|
|
170
|
+
export const PublicConfig = publicConfig(Schema.Struct({ installUrl: Schema.URL }).pipe(Schema.encodeKeys({ installUrl: "INSTALL_URL" })));
|
|
175
171
|
```
|
|
176
172
|
|
|
177
173
|
On the server, merge the declaration into the application's group and its generated handler Layer into the handlers:
|
|
@@ -184,35 +180,27 @@ import { Api, Handlers, sessions } from "./app.ts";
|
|
|
184
180
|
import { PublicConfig } from "./public-config.ts";
|
|
185
181
|
|
|
186
182
|
export const Server = appHost({
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
183
|
+
group: Api.merge(PublicConfig),
|
|
184
|
+
handlers: Layer.merge(Handlers, publicConfigLayer(PublicConfig)),
|
|
185
|
+
sessions,
|
|
190
186
|
});
|
|
191
187
|
```
|
|
192
188
|
|
|
193
189
|
`publicConfigLayer` reads `Config.schema` from the host's native ConfigProvider when the handler Layer builds. Missing or invalid required fields fail startup with a typed `ConfigError`. An optional second argument supplies a native Config path: `publicConfigLayer(PublicConfig, "PUBLIC")` reads `PUBLIC_INSTALL_URL` with the default environment provider. Only schema-declared fields are loaded and serialized; other server values never enter this response. The generated query has no session middleware, so it can supply public configuration before sign-in. Merge it alongside authenticated contracts rather than applying authentication to the merged group.
|
|
194
190
|
|
|
195
|
-
On the client, use the same
|
|
191
|
+
On the client, use the same contract `makeClient` and shared WebSocket as other queries:
|
|
196
192
|
|
|
197
193
|
```ts
|
|
198
|
-
import {
|
|
199
|
-
import { FetchHttpClient } from "effect/http";
|
|
200
|
-
import * as AtomRpc from "effect/reactivity/AtomRpc";
|
|
201
|
-
import { RpcClient, RpcSerialization } from "effect/rpc";
|
|
202
|
-
import { bind } from "@shivaedev/contract/bind.ts";
|
|
194
|
+
import { makeClient } from "@shivaedev/contract/bind.ts";
|
|
203
195
|
import { useQuery } from "@shivaedev/react/client/resultState.ts";
|
|
204
196
|
import { PublicConfig } from "./public-config.ts";
|
|
205
197
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
Layer.provide([FetchHttpClient.layer, RpcSerialization.layerNdjson]),
|
|
210
|
-
),
|
|
211
|
-
}) {}
|
|
212
|
-
const config = bind(PublicConfig, ConfigClient);
|
|
198
|
+
const { api: config } = makeClient(PublicConfig, {
|
|
199
|
+
url: new URL("/rpc", window.location.href).href,
|
|
200
|
+
});
|
|
213
201
|
|
|
214
202
|
export function usePublicConfig() {
|
|
215
|
-
|
|
203
|
+
return useQuery(config.get.query());
|
|
216
204
|
}
|
|
217
205
|
```
|
|
218
206
|
|
|
@@ -228,15 +216,15 @@ Tracing logs declared failures with `RPC failure` and their tag, and defects wit
|
|
|
228
216
|
import { Schema } from "effect";
|
|
229
217
|
|
|
230
218
|
const Contact = Schema.Struct({
|
|
231
|
-
|
|
232
|
-
|
|
219
|
+
deliveryAddress: Schema.String.annotate({ sensitive: true }),
|
|
220
|
+
recoveryCode: Schema.RedactedFromValue(Schema.String),
|
|
233
221
|
});
|
|
234
222
|
|
|
235
223
|
const Server = appHost({
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
224
|
+
group: Api,
|
|
225
|
+
handlers: Handlers,
|
|
226
|
+
sessions,
|
|
227
|
+
config: { sensitiveKeys: ["customerReference"] },
|
|
240
228
|
});
|
|
241
229
|
```
|
|
242
230
|
|
|
@@ -252,7 +240,7 @@ For native RPC serialization, `schemaSensitiveKeys(group, extraKeys?)` returns a
|
|
|
252
240
|
|
|
253
241
|
The masking primitives, `redact`, `redactWire`, `redactText`, `redactCause` and `isSensitiveKey`, live in [`@shivaedev/errors`](https://github.com/ShivaeDev/platform/tree/main/packages/errors#readme).
|
|
254
242
|
|
|
255
|
-
For a native RPC server composed without `appHost`, `requestTracingLayer({ sensitive })` accepts a key predicate; `isSensitiveKey` from `@shivaedev/errors/sensitive.ts` supplies the default credential rules. `redactingErrorReporter(reporter, sensitive?)` from `@shivaedev/errors/redactCause.ts` wraps an Effect error reporter and passes it redacted failure and defect causes while preserving reporting hints such as severity and redacted attributes.
|
|
243
|
+
For a native RPC server composed without `appHost`, `requestTracingLayer({ sensitive })` from `@shivaedev/identity/server/tracing.ts` accepts a key predicate; `isSensitiveKey` from `@shivaedev/errors/sensitive.ts` supplies the default credential rules. `redactingErrorReporter(reporter, sensitive?)` from `@shivaedev/errors/redactCause.ts` wraps an Effect error reporter and passes it redacted failure and defect causes while preserving reporting hints such as severity and redacted attributes.
|
|
256
244
|
|
|
257
245
|
### Calling outside APIs
|
|
258
246
|
|
|
@@ -270,13 +258,10 @@ class Greeting extends Context.Service<Greeting, string>()("app/Greeting") {}
|
|
|
270
258
|
|
|
271
259
|
const runtime = makePlatformRuntime(Layer.succeed(Greeting, "application"));
|
|
272
260
|
const base = await runtime.runPromise(Greeting);
|
|
273
|
-
const request = await runtime.runWithServices(
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return runtime.runPromise(Greeting);
|
|
278
|
-
},
|
|
279
|
-
);
|
|
261
|
+
const request = await runtime.runWithServices(Context.make(Greeting, "request"), async () => {
|
|
262
|
+
await Promise.resolve();
|
|
263
|
+
return runtime.runPromise(Greeting);
|
|
264
|
+
});
|
|
280
265
|
await runtime.dispose();
|
|
281
266
|
```
|
|
282
267
|
|
|
@@ -293,21 +278,21 @@ import type { IncomingMessage } from "node:http";
|
|
|
293
278
|
import { nodeSubscriptionSignal } from "@shivaedev/server/node-http/subscriptionSignal.ts";
|
|
294
279
|
|
|
295
280
|
export async function consumeSubscription(
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
281
|
+
request: Request,
|
|
282
|
+
nodeRequest: IncomingMessage,
|
|
283
|
+
procedureSignal: AbortSignal,
|
|
284
|
+
consume: (signal: AbortSignal) => Promise<void>,
|
|
300
285
|
) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
286
|
+
const subscription = nodeSubscriptionSignal({
|
|
287
|
+
nodeRequest,
|
|
288
|
+
request,
|
|
289
|
+
signals: [procedureSignal],
|
|
290
|
+
});
|
|
291
|
+
try {
|
|
292
|
+
await consume(subscription.signal);
|
|
293
|
+
} finally {
|
|
294
|
+
subscription.dispose();
|
|
295
|
+
}
|
|
311
296
|
}
|
|
312
297
|
```
|
|
313
298
|
|
|
@@ -317,29 +302,32 @@ The signal aborts on an additional signal, socket close, incomplete request clos
|
|
|
317
302
|
|
|
318
303
|
Import the module that defines the name; there is no package-root entry. Paths below follow `@shivaedev/server/`.
|
|
319
304
|
|
|
320
|
-
| Module
|
|
321
|
-
|
|
|
322
|
-
| `appHost.ts`
|
|
323
|
-
| `
|
|
324
|
-
| `
|
|
325
|
-
| `
|
|
326
|
-
| `
|
|
327
|
-
| `
|
|
305
|
+
| Module | Names and purpose |
|
|
306
|
+
| ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
307
|
+
| `appHost.ts` | `appHost`, `appDatabase`, `AppChanges`: scoped HTTP and PostgreSQL composition with loopback defaults and optional proxy trust. |
|
|
308
|
+
| `setupDatabases.ts` | `setupDatabases()`: prepare the local development and test databases. |
|
|
309
|
+
| `development.ts` | `development({ server, worker, conditions? })`, `runDevelopment(options)`: run the server, worker and Vite in watch mode. |
|
|
310
|
+
| `rpc-server/publicConfigLayer.ts` | `publicConfigLayer(declaration, path?)`: serve a `publicConfig` declaration from native Config. |
|
|
311
|
+
| `otlpTracing.ts` | `otlpTracing`: opt-in Effect OTLP trace export for worker Layers. |
|
|
312
|
+
| `schemaSensitiveKeys.ts`, `RedactionPolicy.ts` | `schemaSensitiveKeys(group, extraKeys?)`, `RedactionPolicy`: derive and provide an app's diagnostic key predicate. |
|
|
313
|
+
| `redactingDiagnostics.ts`, `redactingTracer.ts`, `redactingRpcSerialization.ts` | `redactingDiagnostics(sensitive)`, `redactRecord(values, sensitive)`, `redactingTracer(sensitive)`, `redactingRpcSerialization(wire, sensitive, maskFailure?)`: compose native diagnostic and NDJSON boundaries. |
|
|
314
|
+
| `runtime/makePlatform.ts` | `makePlatformRuntime(layer, { developmentCacheKey? })`. |
|
|
315
|
+
| `node-http/subscriptionSignal.ts` | `nodeSubscriptionSignal({ nodeRequest?, request?, signals? })`, returning `{ signal, dispose }`. |
|
|
328
316
|
|
|
329
317
|
### Install, setup and limits
|
|
330
318
|
|
|
331
319
|
```sh
|
|
332
|
-
pnpm add @shivaedev/server effect
|
|
320
|
+
pnpm add @shivaedev/server effect
|
|
333
321
|
```
|
|
334
322
|
|
|
335
323
|
Effect is the only required peer. The `node-http/`, `rpc-server/` and `runtime/` modules work without the optional peers; a module's import path is its path under `src/`. Every module is server code: the runtime uses Node's `AsyncLocalStorage`, and browser code imports contracts from `@shivaedev/contract`, identity declarations from `@shivaedev/identity` and error schemas from `@shivaedev/errors` instead.
|
|
336
324
|
|
|
337
325
|
Install the optional peers for the selected integration:
|
|
338
326
|
|
|
339
|
-
| Integration
|
|
340
|
-
|
|
|
341
|
-
| `appHost.ts`
|
|
342
|
-
|
|
327
|
+
| Integration | Additional peers |
|
|
328
|
+
| ---------------- | ----------------------------------------- |
|
|
329
|
+
| `appHost.ts` | `@effect/platform-node`, `@effect/sql-pg` |
|
|
330
|
+
| `development.ts` | `@effect/platform-node` |
|
|
343
331
|
- The package needs Node 24 or newer.
|
|
344
332
|
- `appHost` adds tracing last on its server-side copy of the group. When composing a native RPC server directly, add `RequestTracing` last on the group so it wraps authentication too; see the [native-server example](https://github.com/ShivaeDev/platform/blob/main/docs/framework/request-context.md#request-id-identity-and-logging). Middleware outside that tracing boundary is responsible for its own diagnostics.
|
|
345
333
|
- Redaction recognizes declared field names and common credential shapes. Mark sensitive fields in RPC schemas and configure extra names once with `config.sensitiveKeys`. Keep sensitive values out of ordinary prose.
|
package/dist/appHost.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as NodeCrypto from "@effect/platform-node/NodeCrypto";
|
|
2
2
|
import { Context, Layer } from "effect";
|
|
3
3
|
import { appHostHttp, deferredHost, migratedHost } from "#appHostHttp.ts";
|
|
4
4
|
import { databaseLayer } from "#databaseLayer.ts";
|
package/dist/appHost.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appHost.js","sourceRoot":"","sources":["../src/appHost.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"appHost.js","sourceRoot":"","sources":["../src/appHost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAe,KAAK,EAAE,MAAM,QAAQ,CAAC;AAMrD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAuB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIvE,MAAM,OAAO,UAAW,SAAQ,OAAO,CAAC,OAAO,EAAqD,CAAC,8BAA8B,CAAC;CAAG;AAMvI,MAAM,UAAU,WAAW,CAAI,OAA8B;IAC5D,OAAO,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAiED,MAAM,CAAC,MAAM,OAAO,GAAmB,CAkBtC,OAiBC,EACA,EAAE;IACH,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAC9E,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,EACpD,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAC/B,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC,UAAU,KAAK,SAAS;QACtC,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9H,CAAC,CAAC,YAAY,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAC1I,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,EACpD,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAC/B,CAAC;AACL,CAAC,CAAC"}
|