@shivaedev/server 0.2.0 → 0.3.1
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 +105 -87
- package/dist/AppHostFactory.d.ts +9 -8
- package/dist/AppHostFactory.d.ts.map +1 -1
- package/dist/AppHostInput.d.ts +4 -3
- package/dist/AppHostInput.d.ts.map +1 -1
- package/dist/appHost.d.ts +30 -5
- package/dist/appHost.d.ts.map +1 -1
- package/dist/appHost.js +4 -3
- package/dist/appHost.js.map +1 -1
- package/dist/appHostHttp.d.ts +45 -47
- package/dist/appHostHttp.d.ts.map +1 -1
- package/dist/appHostHttp.js +13 -42
- 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/healthRoute.d.ts.map +1 -1
- package/dist/healthRoute.js +3 -2
- package/dist/healthRoute.js.map +1 -1
- package/dist/hostApplicationRoutes.d.ts +3 -0
- package/dist/hostApplicationRoutes.d.ts.map +1 -0
- package/dist/hostApplicationRoutes.js +6 -0
- package/dist/hostApplicationRoutes.js.map +1 -0
- package/dist/hostChanges.js +1 -1
- package/dist/hostChanges.js.map +1 -1
- package/dist/hostOptions.d.ts +6 -2
- package/dist/hostOptions.d.ts.map +1 -1
- package/dist/hostRpc.d.ts +11 -0
- package/dist/hostRpc.d.ts.map +1 -0
- package/dist/hostRpc.js +20 -0
- package/dist/hostRpc.js.map +1 -0
- package/dist/hostRpcRoutes.d.ts +23 -0
- package/dist/hostRpcRoutes.d.ts.map +1 -0
- package/dist/hostRpcRoutes.js +29 -0
- package/dist/hostRpcRoutes.js.map +1 -0
- package/dist/nativeClientOrigins.d.ts +2 -1
- package/dist/nativeClientOrigins.d.ts.map +1 -1
- package/dist/nativeClientOrigins.js +11 -5
- package/dist/nativeClientOrigins.js.map +1 -1
- package/dist/nodeHttpServer.d.ts +7 -0
- package/dist/nodeHttpServer.d.ts.map +1 -0
- package/dist/nodeHttpServer.js +15 -0
- package/dist/nodeHttpServer.js.map +1 -0
- package/dist/otlpHttpClient.d.ts.map +1 -1
- package/dist/otlpHttpClient.js +2 -1
- package/dist/otlpHttpClient.js.map +1 -1
- package/package.json +12 -11
- package/src/AppHostFactory.ts +47 -44
- package/src/AppHostInput.ts +27 -4
- package/src/appHost.ts +25 -7
- package/src/appHostHttp.ts +68 -72
- package/src/development.ts +2 -1
- package/src/healthRoute.ts +3 -2
- package/src/hostApplicationRoutes.ts +8 -0
- package/src/hostChanges.ts +2 -2
- package/src/hostOptions.ts +20 -2
- package/src/hostRpc.ts +26 -0
- package/src/hostRpcRoutes.ts +57 -0
- package/src/nativeClientOrigins.ts +16 -5
- package/src/nodeHttpServer.ts +24 -0
- package/src/otlpHttpClient.ts +2 -1
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
|
|
|
@@ -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));
|
|
@@ -59,7 +59,29 @@ NodeRuntime.runMain(Layer.launch(Server));
|
|
|
59
59
|
|
|
60
60
|
Omit `services` when the app has no service Layer of its own. The host uses `Layer.empty`; handler requirements remain explicit, and a migrated host still provides its database services to handlers. Annotated options that declare service outputs, errors or requirements must supply a `services` Layer.
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
Pass application HTTP endpoints through `routes`, including routes that read app services. Use `handlers` for RPC implementations and their middleware Layers. `routes` accepts native HTTP router Layers; the host supplies `services` during route construction and request handling, preserves route Layer build errors and leaves missing services in the host’s requirement type.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { Effect, Layer } from "effect";
|
|
66
|
+
import { HttpMiddleware, HttpRouter, HttpServerResponse } from "effect/http";
|
|
67
|
+
|
|
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
|
+
);
|
|
78
|
+
|
|
79
|
+
const Server = appHost({ group: Api, handlers: Handlers, services: Services, routes: Routes, sessions });
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`AppMetadata` is an app service supplied by `Services`. Register `OPTIONS` or `"*"` for a route whose native `HttpMiddleware.cors` must answer preflight. The host restricts foreign-origin preflights only on `rpcPath` (default `/rpc`) and `/api/auth/*`, including `/api/auth` itself. Application endpoints own their CORS policy. `nativeOrigins` lists exact native-client origins admitted by the host’s RPC and auth CORS policy; other foreign origins receive 403 on those paths.
|
|
83
|
+
|
|
84
|
+
`assets` accepts a directory string or native `HttpStaticServer.layer` options. For a browser app whose routes must also work on direct navigation or reload, use `{ root: "dist", spa: true }` or merge `HttpStaticServer.layer({ root: "dist", spa: true })` from `effect/http` into `routes`. The [starter](https://github.com/ShivaeDev/platform/tree/main/examples/starter) uses `routes` for static assets and Better Auth at `/api/auth/*`, with provider-owned cookies and the host's RPC session middleware.
|
|
63
85
|
|
|
64
86
|
The listener uses `HOST` or `127.0.0.1`, uses `PORT` or 3000, and reads `DATABASE_URL`. Set overrides in the one `config` object: `host`, `port` (0 selects an ephemeral port), `trustedProxy`, `maxBodySize`, `databaseUrl` (an Effect `Redacted<string>`), `applicationName`, and optional `changes`. Migration options accept `table` and `lockTimeout` (default `effect_sql_migrations` and five seconds). Native Layer failures remain in the build error channel; missing application dependencies remain in the requirement type.
|
|
65
87
|
|
|
@@ -67,7 +89,7 @@ RPC request bodies are limited to 1 MiB by default. Set `MAX_BODY_SIZE` to a byt
|
|
|
67
89
|
|
|
68
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.
|
|
69
91
|
|
|
70
|
-
RPC uses
|
|
92
|
+
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. Session lookup uses transport headers. 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.
|
|
71
93
|
|
|
72
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.
|
|
73
95
|
|
|
@@ -81,19 +103,21 @@ Set `migrations.mode: "check"` on `appDatabase` or a database-backed `appHost` w
|
|
|
81
103
|
|
|
82
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.
|
|
83
105
|
|
|
84
|
-
|
|
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
|
+
|
|
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.
|
|
85
109
|
|
|
86
110
|
When construction itself touches the schema, use `appHost({ migrations, config, application })`. `application` is a native Effect that returns the HTTP host options (`group`, handler and service Layers, session policy, and optional HTTP config). The host first builds `appDatabase`, then evaluates this Effect in the host scope with SQL, Reactivity and `AppChanges` available. A failed migration or schema-current check prevents construction. Initialization requirements and errors stay in the returned Layer's types, and acquired resources close with the host scope.
|
|
87
111
|
|
|
88
112
|
```ts
|
|
89
113
|
const host = appHost({
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
+
}),
|
|
97
121
|
});
|
|
98
122
|
```
|
|
99
123
|
|
|
@@ -103,27 +127,27 @@ Set `OTEL_EXPORTER_OTLP_ENDPOINT` or `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` to exp
|
|
|
103
127
|
|
|
104
128
|
The supported tracing variables and defaults are:
|
|
105
129
|
|
|
106
|
-
| Variable
|
|
107
|
-
|
|
|
108
|
-
| `OTEL_EXPORTER_OTLP_ENDPOINT`
|
|
109
|
-
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Base URL plus `/v1/traces`
|
|
110
|
-
| `OTEL_EXPORTER_OTLP_PROTOCOL`
|
|
111
|
-
| `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` | General protocol
|
|
112
|
-
| `OTEL_EXPORTER_OTLP_HEADERS`
|
|
113
|
-
| `OTEL_SERVICE_NAME`
|
|
114
|
-
| `OTEL_SERVICE_VERSION`
|
|
115
|
-
| `OTEL_RESOURCE_ATTRIBUTES`
|
|
116
|
-
| `OTEL_EXPORTER_OTLP_TIMEOUT`
|
|
117
|
-
| `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT`
|
|
118
|
-
| `OTEL_BSP_SCHEDULE_DELAY`
|
|
119
|
-
| `OTEL_BSP_MAX_EXPORT_BATCH_SIZE`
|
|
120
|
-
| `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. |
|
|
121
145
|
|
|
122
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.
|
|
123
147
|
|
|
124
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.
|
|
125
149
|
|
|
126
|
-
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.
|
|
127
151
|
|
|
128
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.
|
|
129
153
|
|
|
@@ -143,11 +167,7 @@ Use one `publicConfig` declaration per application as the one path for server co
|
|
|
143
167
|
import { Schema } from "effect";
|
|
144
168
|
import { publicConfig } from "@shivaedev/contract/publicConfig.ts";
|
|
145
169
|
|
|
146
|
-
export const PublicConfig = publicConfig(
|
|
147
|
-
Schema.Struct({ installUrl: Schema.URL }).pipe(
|
|
148
|
-
Schema.encodeKeys({ installUrl: "INSTALL_URL" }),
|
|
149
|
-
),
|
|
150
|
-
);
|
|
170
|
+
export const PublicConfig = publicConfig(Schema.Struct({ installUrl: Schema.URL }).pipe(Schema.encodeKeys({ installUrl: "INSTALL_URL" })));
|
|
151
171
|
```
|
|
152
172
|
|
|
153
173
|
On the server, merge the declaration into the application's group and its generated handler Layer into the handlers:
|
|
@@ -160,9 +180,9 @@ import { Api, Handlers, sessions } from "./app.ts";
|
|
|
160
180
|
import { PublicConfig } from "./public-config.ts";
|
|
161
181
|
|
|
162
182
|
export const Server = appHost({
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
183
|
+
group: Api.merge(PublicConfig),
|
|
184
|
+
handlers: Layer.merge(Handlers, publicConfigLayer(PublicConfig)),
|
|
185
|
+
sessions,
|
|
166
186
|
});
|
|
167
187
|
```
|
|
168
188
|
|
|
@@ -180,15 +200,13 @@ import { useQuery } from "@shivaedev/react/client/resultState.ts";
|
|
|
180
200
|
import { PublicConfig } from "./public-config.ts";
|
|
181
201
|
|
|
182
202
|
class ConfigClient extends AtomRpc.Service<ConfigClient>()("app/ConfigClient", {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
Layer.provide([FetchHttpClient.layer, RpcSerialization.layerNdjson]),
|
|
186
|
-
),
|
|
203
|
+
group: PublicConfig,
|
|
204
|
+
protocol: RpcClient.layerProtocolHttp({ url: "/rpc" }).pipe(Layer.provide([FetchHttpClient.layer, RpcSerialization.layerNdjson])),
|
|
187
205
|
}) {}
|
|
188
206
|
const config = bind(PublicConfig, ConfigClient);
|
|
189
207
|
|
|
190
208
|
export function usePublicConfig() {
|
|
191
|
-
|
|
209
|
+
return useQuery(config.get.query());
|
|
192
210
|
}
|
|
193
211
|
```
|
|
194
212
|
|
|
@@ -204,15 +222,15 @@ Tracing logs declared failures with `RPC failure` and their tag, and defects wit
|
|
|
204
222
|
import { Schema } from "effect";
|
|
205
223
|
|
|
206
224
|
const Contact = Schema.Struct({
|
|
207
|
-
|
|
208
|
-
|
|
225
|
+
deliveryAddress: Schema.String.annotate({ sensitive: true }),
|
|
226
|
+
recoveryCode: Schema.RedactedFromValue(Schema.String),
|
|
209
227
|
});
|
|
210
228
|
|
|
211
229
|
const Server = appHost({
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
230
|
+
group: Api,
|
|
231
|
+
handlers: Handlers,
|
|
232
|
+
sessions,
|
|
233
|
+
config: { sensitiveKeys: ["customerReference"] },
|
|
216
234
|
});
|
|
217
235
|
```
|
|
218
236
|
|
|
@@ -228,7 +246,7 @@ For native RPC serialization, `schemaSensitiveKeys(group, extraKeys?)` returns a
|
|
|
228
246
|
|
|
229
247
|
The masking primitives, `redact`, `redactWire`, `redactText`, `redactCause` and `isSensitiveKey`, live in [`@shivaedev/errors`](https://github.com/ShivaeDev/platform/tree/main/packages/errors#readme).
|
|
230
248
|
|
|
231
|
-
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.
|
|
249
|
+
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.
|
|
232
250
|
|
|
233
251
|
### Calling outside APIs
|
|
234
252
|
|
|
@@ -246,13 +264,10 @@ class Greeting extends Context.Service<Greeting, string>()("app/Greeting") {}
|
|
|
246
264
|
|
|
247
265
|
const runtime = makePlatformRuntime(Layer.succeed(Greeting, "application"));
|
|
248
266
|
const base = await runtime.runPromise(Greeting);
|
|
249
|
-
const request = await runtime.runWithServices(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
return runtime.runPromise(Greeting);
|
|
254
|
-
},
|
|
255
|
-
);
|
|
267
|
+
const request = await runtime.runWithServices(Context.make(Greeting, "request"), async () => {
|
|
268
|
+
await Promise.resolve();
|
|
269
|
+
return runtime.runPromise(Greeting);
|
|
270
|
+
});
|
|
256
271
|
await runtime.dispose();
|
|
257
272
|
```
|
|
258
273
|
|
|
@@ -269,21 +284,21 @@ import type { IncomingMessage } from "node:http";
|
|
|
269
284
|
import { nodeSubscriptionSignal } from "@shivaedev/server/node-http/subscriptionSignal.ts";
|
|
270
285
|
|
|
271
286
|
export async function consumeSubscription(
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
287
|
+
request: Request,
|
|
288
|
+
nodeRequest: IncomingMessage,
|
|
289
|
+
procedureSignal: AbortSignal,
|
|
290
|
+
consume: (signal: AbortSignal) => Promise<void>,
|
|
276
291
|
) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
292
|
+
const subscription = nodeSubscriptionSignal({
|
|
293
|
+
nodeRequest,
|
|
294
|
+
request,
|
|
295
|
+
signals: [procedureSignal],
|
|
296
|
+
});
|
|
297
|
+
try {
|
|
298
|
+
await consume(subscription.signal);
|
|
299
|
+
} finally {
|
|
300
|
+
subscription.dispose();
|
|
301
|
+
}
|
|
287
302
|
}
|
|
288
303
|
```
|
|
289
304
|
|
|
@@ -293,29 +308,32 @@ The signal aborts on an additional signal, socket close, incomplete request clos
|
|
|
293
308
|
|
|
294
309
|
Import the module that defines the name; there is no package-root entry. Paths below follow `@shivaedev/server/`.
|
|
295
310
|
|
|
296
|
-
| Module
|
|
297
|
-
|
|
|
298
|
-
| `appHost.ts`
|
|
299
|
-
| `
|
|
300
|
-
| `
|
|
301
|
-
| `
|
|
302
|
-
| `
|
|
303
|
-
| `
|
|
311
|
+
| Module | Names and purpose |
|
|
312
|
+
| ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
313
|
+
| `appHost.ts` | `appHost`, `appDatabase`, `AppChanges`: scoped HTTP and PostgreSQL composition with loopback defaults and optional proxy trust. |
|
|
314
|
+
| `setupDatabases.ts` | `setupDatabases()`: prepare the local development and test databases. |
|
|
315
|
+
| `development.ts` | `development({ server, worker, conditions? })`, `runDevelopment(options)`: run the server, worker and Vite in watch mode. |
|
|
316
|
+
| `rpc-server/publicConfigLayer.ts` | `publicConfigLayer(declaration, path?)`: serve a `publicConfig` declaration from native Config. |
|
|
317
|
+
| `otlpTracing.ts` | `otlpTracing`: opt-in Effect OTLP trace export for worker Layers. |
|
|
318
|
+
| `schemaSensitiveKeys.ts`, `RedactionPolicy.ts` | `schemaSensitiveKeys(group, extraKeys?)`, `RedactionPolicy`: derive and provide an app's diagnostic key predicate. |
|
|
319
|
+
| `redactingDiagnostics.ts`, `redactingTracer.ts`, `redactingRpcSerialization.ts` | `redactingDiagnostics(sensitive)`, `redactRecord(values, sensitive)`, `redactingTracer(sensitive)`, `redactingRpcSerialization(wire, sensitive, maskFailure?)`: compose native diagnostic and NDJSON boundaries. |
|
|
320
|
+
| `runtime/makePlatform.ts` | `makePlatformRuntime(layer, { developmentCacheKey? })`. |
|
|
321
|
+
| `node-http/subscriptionSignal.ts` | `nodeSubscriptionSignal({ nodeRequest?, request?, signals? })`, returning `{ signal, dispose }`. |
|
|
304
322
|
|
|
305
323
|
### Install, setup and limits
|
|
306
324
|
|
|
307
325
|
```sh
|
|
308
|
-
pnpm add @shivaedev/server effect
|
|
326
|
+
pnpm add @shivaedev/server effect
|
|
309
327
|
```
|
|
310
328
|
|
|
311
329
|
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.
|
|
312
330
|
|
|
313
331
|
Install the optional peers for the selected integration:
|
|
314
332
|
|
|
315
|
-
| Integration
|
|
316
|
-
|
|
|
317
|
-
| `appHost.ts`
|
|
318
|
-
|
|
333
|
+
| Integration | Additional peers |
|
|
334
|
+
| ---------------- | ----------------------------------------- |
|
|
335
|
+
| `appHost.ts` | `@effect/platform-node`, `@effect/sql-pg` |
|
|
336
|
+
| `development.ts` | `@effect/platform-node` |
|
|
319
337
|
- The package needs Node 24 or newer.
|
|
320
338
|
- `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.
|
|
321
339
|
- 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/AppHostFactory.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Crypto, Layer } from "effect";
|
|
2
2
|
import type { Rpc } from "effect/rpc";
|
|
3
3
|
import type { SessionShape } from "@shivaedev/identity/server/session.ts";
|
|
4
|
-
import type {
|
|
5
|
-
import type { AppDatabaseOptions,
|
|
4
|
+
import type { AppHostInput } from "#AppHostInput.ts";
|
|
5
|
+
import type { AppDatabaseOptions, AppHttpHostOptions } from "#appHost.ts";
|
|
6
6
|
import type { appHostHttp, deferredHost } from "#appHostHttp.ts";
|
|
7
|
-
type
|
|
7
|
+
import type { HostRouteRequirements } from "#hostOptions.ts";
|
|
8
|
+
type PreflightHost<THost extends Layer.Any, TServices, TError, TRequirements> = Layer.Layer<Layer.Success<THost> | TServices, Layer.Error<THost> | TError, Exclude<Layer.Services<THost>, TServices | Crypto.Crypto> | Exclude<TRequirements, Crypto.Crypto>>;
|
|
8
9
|
export interface AppHostFactory {
|
|
9
|
-
<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TSession extends SessionShape = SessionShape, TApplicationError = never, TApplicationRequirements = never, TPreflight = never, TPreflightError = never, TPreflightRequirements = never>(options:
|
|
10
|
-
readonly
|
|
11
|
-
})
|
|
12
|
-
<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TSession extends SessionShape = SessionShape, TPreflight = never, TPreflightError = never, TPreflightRequirements = never>(options: AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession, TPreflight, TPreflightError, TPreflightRequirements>): PreflightHost<ReturnType<typeof appHostHttp<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>>, NoInfer<TPreflight>, NoInfer<TPreflightError>, NoInfer<TPreflightRequirements>>;
|
|
10
|
+
<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TSession extends SessionShape = SessionShape, TApplicationError = never, TApplicationRequirements = never, TPreflight = never, TPreflightError = never, TPreflightRequirements = never, TRouteError = never, TRouteRequirements = HostRouteRequirements>(options: AppHostInput<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession, TApplicationError, TApplicationRequirements, TPreflight, TPreflightError, TPreflightRequirements, TRouteError, TRouteRequirements> & {
|
|
11
|
+
readonly migrations: AppDatabaseOptions<TMigrations>["migrations"];
|
|
12
|
+
}): PreflightHost<ReturnType<typeof deferredHost<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession, TApplicationError, TApplicationRequirements, TRouteError, TRouteRequirements>>, NoInfer<TPreflight>, NoInfer<TPreflightError>, NoInfer<TPreflightRequirements>>;
|
|
13
|
+
<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TSession extends SessionShape = SessionShape, TPreflight = never, TPreflightError = never, TPreflightRequirements = never, TRouteError = never, TRouteRequirements = HostRouteRequirements>(options: AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession, TPreflight, TPreflightError, TPreflightRequirements, TRouteError, TRouteRequirements>): PreflightHost<ReturnType<typeof appHostHttp<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession, TRouteError, TRouteRequirements>>, NoInfer<TPreflight>, NoInfer<TPreflightError>, NoInfer<TPreflightRequirements>>;
|
|
13
14
|
}
|
|
14
15
|
export {};
|
|
15
16
|
//# sourceMappingURL=AppHostFactory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppHostFactory.d.ts","sourceRoot":"","sources":["../src/AppHostFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"AppHostFactory.d.ts","sourceRoot":"","sources":["../src/AppHostFactory.ts"],"names":[],"mappings":"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"}
|
package/dist/AppHostInput.d.ts
CHANGED
|
@@ -2,12 +2,13 @@ import type { Effect, Layer } from "effect";
|
|
|
2
2
|
import type { Rpc } from "effect/rpc";
|
|
3
3
|
import type { SessionShape } from "@shivaedev/identity/server/session.ts";
|
|
4
4
|
import type { AppDatabaseOptions, AppHostOptions, AppHttpHostOptions, AppLocalHostOptions } from "#appHost.ts";
|
|
5
|
+
import type { HostRouteRequirements } from "#hostOptions.ts";
|
|
5
6
|
export type HostPreflight<TServices = never, TError = never, TRequirements = never> = {
|
|
6
7
|
readonly preflight: Layer.Layer<TServices, TError, TRequirements>;
|
|
7
8
|
} | ([TServices | TError | TRequirements] extends [never] ? {
|
|
8
9
|
readonly preflight?: never;
|
|
9
10
|
} : never);
|
|
10
|
-
export type AppHostInput<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TSession extends SessionShape = SessionShape, TApplicationError = never, TApplicationRequirements = never, TPreflight = never, TPreflightError = never, TPreflightRequirements = never> = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> & ((AppDatabaseOptions<TMigrations> & {
|
|
11
|
-
readonly application: Effect.Effect<AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>, TApplicationError, TApplicationRequirements>;
|
|
12
|
-
}) | AppHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession, TPreflight, TPreflightError, TPreflightRequirements> | AppLocalHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TPreflight, TPreflightError, TPreflightRequirements> | AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession, TPreflight, TPreflightError, TPreflightRequirements>);
|
|
11
|
+
export type AppHostInput<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TSession extends SessionShape = SessionShape, TApplicationError = never, TApplicationRequirements = never, TPreflight = never, TPreflightError = never, TPreflightRequirements = never, TRouteError = never, TRouteRequirements = HostRouteRequirements> = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> & ((AppDatabaseOptions<TMigrations> & {
|
|
12
|
+
readonly application: Effect.Effect<AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession, never, never, never, TRouteError, TRouteRequirements>, TApplicationError, TApplicationRequirements>;
|
|
13
|
+
}) | AppHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession, TPreflight, TPreflightError, TPreflightRequirements, TRouteError, TRouteRequirements> | AppLocalHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TPreflight, TPreflightError, TPreflightRequirements, TRouteError, TRouteRequirements> | AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession, TPreflight, TPreflightError, TPreflightRequirements, TRouteError, TRouteRequirements>);
|
|
13
14
|
//# sourceMappingURL=AppHostInput.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppHostInput.d.ts","sourceRoot":"","sources":["../src/AppHostInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"AppHostInput.d.ts","sourceRoot":"","sources":["../src/AppHostInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC/G,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,MAAM,aAAa,CAAC,SAAS,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,aAAa,GAAG,KAAK,IAC/E;IAAE,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,CAAA;CAAE,GACrE,CAAC,CAAC,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG,KAAK,CAAC,CAAC;AAEnG,MAAM,MAAM,YAAY,CACvB,KAAK,SAAS,GAAG,CAAC,GAAG,EACrB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,SAAS,GAAG,KAAK,EACjB,aAAa,GAAG,KAAK,EACrB,oBAAoB,GAAG,KAAK,EAC5B,WAAW,GAAG,KAAK,EACnB,QAAQ,SAAS,YAAY,GAAG,YAAY,EAC5C,iBAAiB,GAAG,KAAK,EACzB,wBAAwB,GAAG,KAAK,EAChC,UAAU,GAAG,KAAK,EAClB,eAAe,GAAG,KAAK,EACvB,sBAAsB,GAAG,KAAK,EAC9B,WAAW,GAAG,KAAK,EACnB,kBAAkB,GAAG,qBAAqB,IACvC,aAAa,CAAC,UAAU,EAAE,eAAe,EAAE,sBAAsB,CAAC,GACrE,CACG,CAAC,kBAAkB,CAAC,WAAW,CAAC,GAAG;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAClC,kBAAkB,CACjB,KAAK,EACL,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,QAAQ,EACR,KAAK,EACL,KAAK,EACL,KAAK,EACL,WAAW,EACX,kBAAkB,CAClB,EACD,iBAAiB,EACjB,wBAAwB,CACxB,CAAC;CACD,CAAC,GACF,cAAc,CACd,KAAK,EACL,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,WAAW,EACX,QAAQ,EACR,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,kBAAkB,CACjB,GACD,mBAAmB,CACnB,KAAK,EACL,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,kBAAkB,CACjB,GACD,kBAAkB,CAClB,KAAK,EACL,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,kBAAkB,CACjB,CACH,CAAC"}
|
package/dist/appHost.d.ts
CHANGED
|
@@ -4,13 +4,37 @@ import type { SessionPolicy, SessionShape } from "@shivaedev/identity/server/ses
|
|
|
4
4
|
import type { AppHostFactory } from "#AppHostFactory.ts";
|
|
5
5
|
import type { HostPreflight } from "#AppHostInput.ts";
|
|
6
6
|
import { type DatabaseConfig } from "#databaseLayer.ts";
|
|
7
|
-
import type {
|
|
7
|
+
import type { HostCoreOptions, HostPolicy, HostRouteRequirements, HostRoutes } from "#hostOptions.ts";
|
|
8
8
|
import type { MigrationOptions } from "#MigrationOptions.ts";
|
|
9
9
|
declare const AppChanges_base: Context.ServiceClass<AppChanges, "@shivaedev/server/AppChanges", {
|
|
10
10
|
resync: Effect.Effect<number, never, never>;
|
|
11
|
-
stream: (keys: readonly import("@shivaedev/
|
|
11
|
+
stream: (keys: readonly import("@shivaedev/changes/keys.ts").Key[], context?: import("@shivaedev/changes/keys.ts").KeyContext) => import("effect/Stream").Stream<{
|
|
12
12
|
readonly _tag: "Changed";
|
|
13
13
|
readonly keys: readonly ({
|
|
14
|
+
readonly _tag: "Bucket";
|
|
15
|
+
readonly collection: string;
|
|
16
|
+
readonly field: string;
|
|
17
|
+
readonly value: string | number;
|
|
18
|
+
} | {
|
|
19
|
+
readonly _tag: "List";
|
|
20
|
+
readonly collection: string;
|
|
21
|
+
} | {
|
|
22
|
+
readonly _tag: "Item";
|
|
23
|
+
readonly collection: string;
|
|
24
|
+
readonly id: string | number;
|
|
25
|
+
})[];
|
|
26
|
+
readonly queryIndexes?: readonly number[] | undefined;
|
|
27
|
+
} | {
|
|
28
|
+
readonly _tag: "Resync";
|
|
29
|
+
}, never, never>;
|
|
30
|
+
subscribe: (subscription: import("@shivaedev/contract/querySubscription.ts").QuerySubscription, context?: import("@shivaedev/changes/keys.ts").KeyContext) => import("effect/Stream").Stream<{
|
|
31
|
+
readonly _tag: "Changed";
|
|
32
|
+
readonly keys: readonly ({
|
|
33
|
+
readonly _tag: "Bucket";
|
|
34
|
+
readonly collection: string;
|
|
35
|
+
readonly field: string;
|
|
36
|
+
readonly value: string | number;
|
|
37
|
+
} | {
|
|
14
38
|
readonly _tag: "List";
|
|
15
39
|
readonly collection: string;
|
|
16
40
|
} | {
|
|
@@ -18,6 +42,7 @@ declare const AppChanges_base: Context.ServiceClass<AppChanges, "@shivaedev/serv
|
|
|
18
42
|
readonly collection: string;
|
|
19
43
|
readonly id: string | number;
|
|
20
44
|
})[];
|
|
45
|
+
readonly queryIndexes?: readonly number[] | undefined;
|
|
21
46
|
} | {
|
|
22
47
|
readonly _tag: "Resync";
|
|
23
48
|
}, never, never>;
|
|
@@ -29,17 +54,17 @@ export interface AppDatabaseOptions<R = never> {
|
|
|
29
54
|
readonly migrations: MigrationOptions<R>;
|
|
30
55
|
}
|
|
31
56
|
export declare function appDatabase<R>(options: AppDatabaseOptions<R>): Layer.Layer<AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient, import("effect/Config").ConfigError | import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, Exclude<Exclude<R, import("effect/Scope").Scope>, import("@effect/sql-pg/PgClient").PgClient | import("effect/sql/SqlClient").SqlClient>>;
|
|
32
|
-
export type AppHostOptions<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TSession extends SessionShape = SessionShape, TPreflight = never, TPreflightError = never, TPreflightRequirements = never> = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> &
|
|
57
|
+
export type AppHostOptions<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TSession extends SessionShape = SessionShape, TPreflight = never, TPreflightError = never, TPreflightRequirements = never, TRouteError = never, TRouteRequirements = HostRouteRequirements> = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> & HostCoreOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & HostRoutes<TRouteError, TRouteRequirements> & {
|
|
33
58
|
readonly migrations: AppDatabaseOptions<TMigrations>["migrations"];
|
|
34
59
|
readonly policy?: undefined;
|
|
35
60
|
readonly sessions: SessionPolicy<TSession>;
|
|
36
61
|
};
|
|
37
|
-
export type AppLocalHostOptions<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TPreflight = never, TPreflightError = never, TPreflightRequirements = never> = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> &
|
|
62
|
+
export type AppLocalHostOptions<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TPreflight = never, TPreflightError = never, TPreflightRequirements = never, TRouteError = never, TRouteRequirements = HostRouteRequirements> = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> & HostCoreOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & HostRoutes<TRouteError, TRouteRequirements> & {
|
|
38
63
|
readonly migrations: AppDatabaseOptions<TMigrations>["migrations"];
|
|
39
64
|
readonly policy: "loopback";
|
|
40
65
|
readonly sessions?: never;
|
|
41
66
|
};
|
|
42
|
-
export type AppHttpHostOptions<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TSession extends SessionShape = SessionShape, TPreflight = never, TPreflightError = never, TPreflightRequirements = never> = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> &
|
|
67
|
+
export type AppHttpHostOptions<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TSession extends SessionShape = SessionShape, TPreflight = never, TPreflightError = never, TPreflightRequirements = never, TRouteError = never, TRouteRequirements = HostRouteRequirements> = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> & HostCoreOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & HostRoutes<TRouteError, TRouteRequirements> & HostPolicy<TSession> & {
|
|
43
68
|
readonly migrations?: undefined;
|
|
44
69
|
};
|
|
45
70
|
export declare const appHost: AppHostFactory;
|
package/dist/appHost.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appHost.d.ts","sourceRoot":"","sources":["../src/appHost.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"appHost.d.ts","sourceRoot":"","sources":["../src/appHost.ts"],"names":[],"mappings":"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"}
|
package/dist/appHost.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as NodeCrypto from "@effect/platform-node/NodeCrypto";
|
|
1
2
|
import { Context, Layer } from "effect";
|
|
2
3
|
import { appHostHttp, deferredHost, migratedHost } from "#appHostHttp.ts";
|
|
3
4
|
import { databaseLayer } from "#databaseLayer.ts";
|
|
@@ -8,10 +9,10 @@ export function appDatabase(options) {
|
|
|
8
9
|
}
|
|
9
10
|
export const appHost = (options) => {
|
|
10
11
|
if ("application" in options) {
|
|
11
|
-
return deferredHost(options.application, appDatabase(options), AppChanges).pipe(Layer.provideMerge(options.preflight ?? Layer.empty));
|
|
12
|
+
return deferredHost(options.application, appDatabase(options), AppChanges).pipe(Layer.provideMerge(options.preflight ?? Layer.empty), Layer.provide(NodeCrypto.layer));
|
|
12
13
|
}
|
|
13
14
|
return options.migrations === undefined
|
|
14
|
-
? appHostHttp(options, AppChanges).pipe(Layer.provideMerge(options.preflight ?? Layer.empty))
|
|
15
|
-
: migratedHost({ ...options, migrations: options.migrations }, appDatabase({ ...options, migrations: options.migrations }), AppChanges).pipe(Layer.provideMerge(options.preflight ?? Layer.empty));
|
|
15
|
+
? appHostHttp(options, AppChanges).pipe(Layer.provideMerge(options.preflight ?? Layer.empty), Layer.provide(NodeCrypto.layer))
|
|
16
|
+
: migratedHost({ ...options, migrations: options.migrations }, appDatabase({ ...options, migrations: options.migrations }), AppChanges).pipe(Layer.provideMerge(options.preflight ?? Layer.empty), Layer.provide(NodeCrypto.layer));
|
|
16
17
|
};
|
|
17
18
|
//# sourceMappingURL=appHost.js.map
|
package/dist/appHost.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appHost.js","sourceRoot":"","sources":["../src/appHost.ts"],"names":[],"mappings":"AAAA,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;
|
|
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"}
|