@btravstack/prisma 0.9.0 → 0.11.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 +27 -7
- package/dist/index.cjs +32 -44
- package/dist/index.d.cts +5 -22
- package/dist/index.d.mts +5 -22
- package/dist/index.mjs +34 -46
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ generated from your schema. Node `>=22`.
|
|
|
22
22
|
<!-- doctest: group=order-api -->
|
|
23
23
|
<!-- doctest: prelude
|
|
24
24
|
import { Env } from "@btravstack/config";
|
|
25
|
-
import { Logger
|
|
25
|
+
import { Logger } from "@btravstack/core";
|
|
26
26
|
import { Module } from "@btravstack/di";
|
|
27
27
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
28
28
|
|
|
@@ -46,14 +46,15 @@ const database = prismaDatabase("OrderDatabase")({
|
|
|
46
46
|
});
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
That is the whole surface. `database`
|
|
50
|
-
root
|
|
49
|
+
That is the whole surface. `database` is a **module** carrying the port a
|
|
50
|
+
composition root reads; the provider binding `DATABASE_URL`, the resourceful
|
|
51
|
+
client provider, the health check and the engine-tracing loader are inside it:
|
|
51
52
|
|
|
52
53
|
```ts
|
|
53
54
|
export const PersistenceModule = Module("Persistence")({
|
|
54
55
|
imports: [database],
|
|
55
56
|
exports: [database.port],
|
|
56
|
-
needs: [Env, Logger
|
|
57
|
+
needs: [Env, Logger],
|
|
57
58
|
});
|
|
58
59
|
```
|
|
59
60
|
|
|
@@ -72,6 +73,17 @@ port is typed by exactly what it returns.
|
|
|
72
73
|
reachable — build it in your own `client` arrow and ignore the one passed in.
|
|
73
74
|
- **The pool's lifetime.** The provider is _resourceful_, so `release` closes it
|
|
74
75
|
on every exit path, including a boot that fails after it ran.
|
|
76
|
+
- **A health check**, named after the starter — `SELECT 1` through `$queryRaw`,
|
|
77
|
+
folded into the kernel's `GET /healthz` with nothing wired. `/readyz` does not
|
|
78
|
+
read it: failing readiness on a dependency every replica shares removes them
|
|
79
|
+
all at once.
|
|
80
|
+
- **Engine tracing, offered rather than registered.** The starter contributes a
|
|
81
|
+
loader for the optional `@prisma/instrumentation` peer to `Instrumentations`;
|
|
82
|
+
composing `@btravstack/observability/otel` is what turns it on, and a graph
|
|
83
|
+
with no SDK never imports it. A missing peer is a `debug` line, never silence.
|
|
84
|
+
- **Every query handed to `Observers`**, so composing `observability()` writes
|
|
85
|
+
the failures as lines and `otel()` mints the instruments — with no flag here
|
|
86
|
+
and no port list to satisfy when you compose neither.
|
|
75
87
|
|
|
76
88
|
## What it does not
|
|
77
89
|
|
|
@@ -89,9 +101,17 @@ package's.
|
|
|
89
101
|
|
|
90
102
|
## Options
|
|
91
103
|
|
|
92
|
-
| Option
|
|
93
|
-
|
|
|
94
|
-
| `
|
|
104
|
+
| Option | Where | What it is |
|
|
105
|
+
| -------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
106
|
+
| `name` | `prismaDatabase(name)` | the port's id and the health check's name — required |
|
|
107
|
+
| `client` | `prismaDatabase(name)({ client })` | builds your client from the driver adapter this package built from the URL — required |
|
|
108
|
+
| `DATABASE_URL` | environment, read by `prismaDatabase(name)` | the connection string — required, validated at graph build; blank is an error, exit `78` |
|
|
109
|
+
|
|
110
|
+
There is **no `instrumented` flag**: observation is a set port every call is
|
|
111
|
+
handed to, so a graph composing no observability pays one inert call and no
|
|
112
|
+
port list. The full table — defaults, semantics and the reasoning — lives on
|
|
113
|
+
[the reference page](https://btravstack.github.io/btravstack/reference/prisma),
|
|
114
|
+
which is this list's one detailed home.
|
|
95
115
|
|
|
96
116
|
## License
|
|
97
117
|
|
package/dist/index.cjs
CHANGED
|
@@ -30,27 +30,25 @@ let unthrown = require("unthrown");
|
|
|
30
30
|
* rejection propagates to `@unthrown/prisma`'s `try*` twin without this file
|
|
31
31
|
* needing a `no-throw` exemption.
|
|
32
32
|
*/
|
|
33
|
-
const instrument = (client,
|
|
34
|
-
const operations = meter.createCounter("btravstack.database.operations", { description: "Database queries, by model, operation and outcome" });
|
|
33
|
+
const instrument = (client, observers) => {
|
|
35
34
|
return client.$extends({ query: { $allModels: { $allOperations: ({ model, operation, args, query }) => {
|
|
36
|
-
const
|
|
35
|
+
const settle = (0, _btravstack_core.observe)(observers, {
|
|
36
|
+
component: "database",
|
|
37
|
+
name: operation,
|
|
38
|
+
attributes: {
|
|
39
|
+
model: model ?? "raw",
|
|
40
|
+
operation
|
|
41
|
+
},
|
|
42
|
+
traced: false
|
|
43
|
+
});
|
|
37
44
|
return query(args).then((value) => {
|
|
38
|
-
|
|
39
|
-
model: label,
|
|
40
|
-
operation,
|
|
41
|
-
outcome: "ok"
|
|
42
|
-
});
|
|
45
|
+
settle({ outcome: "ok" });
|
|
43
46
|
return value;
|
|
44
47
|
}, (cause) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
outcome: "error"
|
|
48
|
+
settle({
|
|
49
|
+
outcome: "error",
|
|
50
|
+
cause
|
|
49
51
|
});
|
|
50
|
-
logger.error("a database query failed", {
|
|
51
|
-
model: label,
|
|
52
|
-
operation
|
|
53
|
-
}, cause);
|
|
54
52
|
return Promise.reject(cause);
|
|
55
53
|
});
|
|
56
54
|
} } } });
|
|
@@ -83,6 +81,11 @@ const defaultLoader = async () => (await import("@prisma/instrumentation")).Pris
|
|
|
83
81
|
* **The skip is logged, not silent.** Telemetry you believe you have and do not
|
|
84
82
|
* is worse than none, so the one path that quietly produces no spans says so at
|
|
85
83
|
* `debug` — the level for something that is a choice rather than a fault.
|
|
84
|
+
*
|
|
85
|
+
* This is the one place in this package that still holds a `Logger`, and it is
|
|
86
|
+
* why the module needs one: it is a STARTUP fact rather than an operation, so
|
|
87
|
+
* the `Observers` seam has nothing to settle. An observer writes lines about
|
|
88
|
+
* operations that fail; a missing optional peer is neither.
|
|
86
89
|
*/
|
|
87
90
|
const loadPrismaInstrumentation = async (logger, load = defaultLoader) => {
|
|
88
91
|
try {
|
|
@@ -114,27 +117,21 @@ const loadPrismaInstrumentation = async (logger, load = defaultLoader) => {
|
|
|
114
117
|
* against this same URL *before the process starts*; an application that
|
|
115
118
|
* migrates itself at boot races every other replica.
|
|
116
119
|
*/
|
|
117
|
-
const prismaDatabase = (name) => ({ client
|
|
120
|
+
const prismaDatabase = (name) => ({ client }) => {
|
|
118
121
|
const config = _btravstack_config.Config.provider(`${name}Config`)(_btravstack_config.Config.object({ url: _btravstack_config.Config.string("DATABASE_URL") }));
|
|
119
122
|
const DatabasePort = (0, _btravstack_di.Port)(name);
|
|
120
123
|
const open = (url) => client(new _prisma_adapter_pg.PrismaPg({ connectionString: url }));
|
|
121
124
|
const port = DatabasePort;
|
|
122
|
-
const
|
|
125
|
+
const clientProvider = (0, _btravstack_di.Provider)(port)({
|
|
123
126
|
inject: {
|
|
124
127
|
settings: config.port,
|
|
125
|
-
|
|
126
|
-
meter: _btravstack_core.Meter
|
|
128
|
+
observers: _btravstack_core.Observers
|
|
127
129
|
},
|
|
128
|
-
acquire: ({ settings,
|
|
129
|
-
return (0, unthrown.fromSafePromise)(Promise.resolve(instrument(open(settings.url),
|
|
130
|
+
acquire: ({ settings, observers }) => {
|
|
131
|
+
return (0, unthrown.fromSafePromise)(Promise.resolve(instrument(open(settings.url), observers)));
|
|
130
132
|
},
|
|
131
133
|
release: (db) => db.$disconnect()
|
|
132
134
|
});
|
|
133
|
-
const plainProvider = (0, _btravstack_di.Provider)(port)({
|
|
134
|
-
inject: { settings: config.port },
|
|
135
|
-
acquire: ({ settings }) => (0, unthrown.OkAsync)(open(settings.url)),
|
|
136
|
-
release: (db) => db.$disconnect()
|
|
137
|
-
});
|
|
138
135
|
const healthCheck = _btravstack_di.Provider.member(_btravstack_core.HealthChecks)({
|
|
139
136
|
inject: { db: port },
|
|
140
137
|
sync: ({ db }) => ({
|
|
@@ -146,15 +143,15 @@ const prismaDatabase = (name) => ({ client, instrumented }) => {
|
|
|
146
143
|
inject: { logger: _btravstack_core.Logger },
|
|
147
144
|
sync: ({ logger }) => () => loadPrismaInstrumentation(logger)
|
|
148
145
|
});
|
|
149
|
-
const
|
|
150
|
-
needs: [
|
|
151
|
-
_btravstack_config.Env,
|
|
152
|
-
_btravstack_core.Logger,
|
|
153
|
-
_btravstack_core.Meter
|
|
154
|
-
],
|
|
146
|
+
const chosen = (0, _btravstack_di.Module)(name)({
|
|
147
|
+
needs: [_btravstack_config.Env, _btravstack_core.Logger],
|
|
155
148
|
provides: [
|
|
156
149
|
config,
|
|
157
|
-
|
|
150
|
+
_btravstack_di.Provider.member(_btravstack_core.Observers)({
|
|
151
|
+
inject: {},
|
|
152
|
+
value: _btravstack_core.noObserver
|
|
153
|
+
}),
|
|
154
|
+
clientProvider,
|
|
158
155
|
healthCheck,
|
|
159
156
|
instrumentation
|
|
160
157
|
],
|
|
@@ -164,16 +161,7 @@ const prismaDatabase = (name) => ({ client, instrumented }) => {
|
|
|
164
161
|
_btravstack_core.Instrumentations
|
|
165
162
|
]
|
|
166
163
|
});
|
|
167
|
-
|
|
168
|
-
needs: [_btravstack_config.Env],
|
|
169
|
-
provides: [
|
|
170
|
-
config,
|
|
171
|
-
plainProvider,
|
|
172
|
-
healthCheck
|
|
173
|
-
],
|
|
174
|
-
exports: [DatabasePort, _btravstack_core.HealthChecks]
|
|
175
|
-
});
|
|
176
|
-
return Object.assign(instrumented !== false ? instrumentedModule : plainModule, { port: DatabasePort });
|
|
164
|
+
return Object.assign(chosen, { port: DatabasePort });
|
|
177
165
|
};
|
|
178
166
|
//#endregion
|
|
179
167
|
exports.prismaDatabase = prismaDatabase;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Env } from "@btravstack/config";
|
|
2
|
-
import { HealthChecks, Instrumentations, Logger,
|
|
2
|
+
import { HealthChecks, Instrumentations, Logger, Observers } from "@btravstack/core";
|
|
3
3
|
import { Module, PortClassOf } from "@btravstack/di";
|
|
4
4
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
5
5
|
//#region src/prisma.d.ts
|
|
@@ -20,7 +20,7 @@ type PrismaLike = {
|
|
|
20
20
|
readonly $queryRaw: (query: TemplateStringsArray, ...values: unknown[]) => Promise<unknown>;
|
|
21
21
|
};
|
|
22
22
|
/** What {@link prismaDatabase} is handed. */
|
|
23
|
-
type PrismaOptions<C extends PrismaLike
|
|
23
|
+
type PrismaOptions<C extends PrismaLike> = {
|
|
24
24
|
/**
|
|
25
25
|
* Builds the client from the driver adapter, which is already constructed
|
|
26
26
|
* from the environment's URL.
|
|
@@ -31,19 +31,6 @@ type PrismaOptions<C extends PrismaLike, Instrumented extends boolean> = {
|
|
|
31
31
|
* the returned type is exactly the one the application will hold.
|
|
32
32
|
*/
|
|
33
33
|
readonly client: (adapter: PrismaPg) => C;
|
|
34
|
-
/**
|
|
35
|
-
* Span, count and log every query. **Default `true`**, `false` opts out — the
|
|
36
|
-
* same shape as `cache`, `mailer` and `storage`, and as `StartOptions`'
|
|
37
|
-
* `signals` and `probes`.
|
|
38
|
-
*
|
|
39
|
-
* On by default because telemetry that is missing is discovered during an
|
|
40
|
-
* incident. The cost is stated rather than hidden: instrumenting puts
|
|
41
|
-
* `Logger`, `Meter` and `Tracer` in the provider's dependencies, so a root
|
|
42
|
-
* without `observability()` and `otel()` gets a compile error naming all
|
|
43
|
-
* three. It also turns on Prisma's own engine-level tracing when
|
|
44
|
-
* `@prisma/instrumentation` is installed — no wiring at the root.
|
|
45
|
-
*/
|
|
46
|
-
readonly instrumented?: Instrumented;
|
|
47
34
|
};
|
|
48
35
|
/**
|
|
49
36
|
* A Prisma client whose pool is the application scope's.
|
|
@@ -63,15 +50,11 @@ type PrismaOptions<C extends PrismaLike, Instrumented extends boolean> = {
|
|
|
63
50
|
* against this same URL *before the process starts*; an application that
|
|
64
51
|
* migrates itself at boot races every other replica.
|
|
65
52
|
*/
|
|
66
|
-
declare const prismaDatabase: <const N extends string>(name: N) => <C extends PrismaLike
|
|
67
|
-
readonly url: string;
|
|
68
|
-
}>> | Exclude<Logger, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
69
|
-
readonly url: string;
|
|
70
|
-
}>> | Exclude<Meter, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
53
|
+
declare const prismaDatabase: <const N extends string>(name: N) => <C extends PrismaLike>({ client }: PrismaOptions<C>) => Module<HealthChecks | Instrumentations | (PortClassOf<N, C> extends (infer T) ? T extends PortClassOf<N, C> ? T extends import("@btravstack/di").AnyPort ? InstanceType<T> : T extends import("@btravstack/di").AnyProvider ? InstanceType<T["port"]> : never : never : never), import("@btravstack/config").ConfigInvalid, Exclude<Env, HealthChecks | Instrumentations | Observers | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
71
54
|
readonly url: string;
|
|
72
|
-
}
|
|
55
|
+
}>> | Exclude<Logger, HealthChecks | Instrumentations | Observers | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
73
56
|
readonly url: string;
|
|
74
|
-
}>>>
|
|
57
|
+
}>>> & {
|
|
75
58
|
readonly port: PortClassOf<N, C>;
|
|
76
59
|
};
|
|
77
60
|
//#endregion
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Env } from "@btravstack/config";
|
|
2
|
-
import { HealthChecks, Instrumentations, Logger,
|
|
2
|
+
import { HealthChecks, Instrumentations, Logger, Observers } from "@btravstack/core";
|
|
3
3
|
import { Module, PortClassOf } from "@btravstack/di";
|
|
4
4
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
5
5
|
//#region src/prisma.d.ts
|
|
@@ -20,7 +20,7 @@ type PrismaLike = {
|
|
|
20
20
|
readonly $queryRaw: (query: TemplateStringsArray, ...values: unknown[]) => Promise<unknown>;
|
|
21
21
|
};
|
|
22
22
|
/** What {@link prismaDatabase} is handed. */
|
|
23
|
-
type PrismaOptions<C extends PrismaLike
|
|
23
|
+
type PrismaOptions<C extends PrismaLike> = {
|
|
24
24
|
/**
|
|
25
25
|
* Builds the client from the driver adapter, which is already constructed
|
|
26
26
|
* from the environment's URL.
|
|
@@ -31,19 +31,6 @@ type PrismaOptions<C extends PrismaLike, Instrumented extends boolean> = {
|
|
|
31
31
|
* the returned type is exactly the one the application will hold.
|
|
32
32
|
*/
|
|
33
33
|
readonly client: (adapter: PrismaPg) => C;
|
|
34
|
-
/**
|
|
35
|
-
* Span, count and log every query. **Default `true`**, `false` opts out — the
|
|
36
|
-
* same shape as `cache`, `mailer` and `storage`, and as `StartOptions`'
|
|
37
|
-
* `signals` and `probes`.
|
|
38
|
-
*
|
|
39
|
-
* On by default because telemetry that is missing is discovered during an
|
|
40
|
-
* incident. The cost is stated rather than hidden: instrumenting puts
|
|
41
|
-
* `Logger`, `Meter` and `Tracer` in the provider's dependencies, so a root
|
|
42
|
-
* without `observability()` and `otel()` gets a compile error naming all
|
|
43
|
-
* three. It also turns on Prisma's own engine-level tracing when
|
|
44
|
-
* `@prisma/instrumentation` is installed — no wiring at the root.
|
|
45
|
-
*/
|
|
46
|
-
readonly instrumented?: Instrumented;
|
|
47
34
|
};
|
|
48
35
|
/**
|
|
49
36
|
* A Prisma client whose pool is the application scope's.
|
|
@@ -63,15 +50,11 @@ type PrismaOptions<C extends PrismaLike, Instrumented extends boolean> = {
|
|
|
63
50
|
* against this same URL *before the process starts*; an application that
|
|
64
51
|
* migrates itself at boot races every other replica.
|
|
65
52
|
*/
|
|
66
|
-
declare const prismaDatabase: <const N extends string>(name: N) => <C extends PrismaLike
|
|
67
|
-
readonly url: string;
|
|
68
|
-
}>> | Exclude<Logger, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
69
|
-
readonly url: string;
|
|
70
|
-
}>> | Exclude<Meter, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
53
|
+
declare const prismaDatabase: <const N extends string>(name: N) => <C extends PrismaLike>({ client }: PrismaOptions<C>) => Module<HealthChecks | Instrumentations | (PortClassOf<N, C> extends (infer T) ? T extends PortClassOf<N, C> ? T extends import("@btravstack/di").AnyPort ? InstanceType<T> : T extends import("@btravstack/di").AnyProvider ? InstanceType<T["port"]> : never : never : never), import("@btravstack/config").ConfigInvalid, Exclude<Env, HealthChecks | Instrumentations | Observers | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
71
54
|
readonly url: string;
|
|
72
|
-
}
|
|
55
|
+
}>> | Exclude<Logger, HealthChecks | Instrumentations | Observers | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
73
56
|
readonly url: string;
|
|
74
|
-
}>>>
|
|
57
|
+
}>>> & {
|
|
75
58
|
readonly port: PortClassOf<N, C>;
|
|
76
59
|
};
|
|
77
60
|
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Config, Env } from "@btravstack/config";
|
|
2
|
-
import { HealthCheckFailed, HealthChecks, Instrumentations, Logger,
|
|
2
|
+
import { HealthCheckFailed, HealthChecks, Instrumentations, Logger, Observers, noObserver, observe } from "@btravstack/core";
|
|
3
3
|
import { Module, Port, Provider } from "@btravstack/di";
|
|
4
4
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
5
|
-
import {
|
|
5
|
+
import { fromPromise, fromSafePromise } from "unthrown";
|
|
6
6
|
//#region src/instrument.ts
|
|
7
7
|
/**
|
|
8
8
|
* Every query, wrapped: a span around it, a count of how it came out, and a log
|
|
@@ -29,27 +29,25 @@ import { OkAsync, fromPromise, fromSafePromise } from "unthrown";
|
|
|
29
29
|
* rejection propagates to `@unthrown/prisma`'s `try*` twin without this file
|
|
30
30
|
* needing a `no-throw` exemption.
|
|
31
31
|
*/
|
|
32
|
-
const instrument = (client,
|
|
33
|
-
const operations = meter.createCounter("btravstack.database.operations", { description: "Database queries, by model, operation and outcome" });
|
|
32
|
+
const instrument = (client, observers) => {
|
|
34
33
|
return client.$extends({ query: { $allModels: { $allOperations: ({ model, operation, args, query }) => {
|
|
35
|
-
const
|
|
34
|
+
const settle = observe(observers, {
|
|
35
|
+
component: "database",
|
|
36
|
+
name: operation,
|
|
37
|
+
attributes: {
|
|
38
|
+
model: model ?? "raw",
|
|
39
|
+
operation
|
|
40
|
+
},
|
|
41
|
+
traced: false
|
|
42
|
+
});
|
|
36
43
|
return query(args).then((value) => {
|
|
37
|
-
|
|
38
|
-
model: label,
|
|
39
|
-
operation,
|
|
40
|
-
outcome: "ok"
|
|
41
|
-
});
|
|
44
|
+
settle({ outcome: "ok" });
|
|
42
45
|
return value;
|
|
43
46
|
}, (cause) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
outcome: "error"
|
|
47
|
+
settle({
|
|
48
|
+
outcome: "error",
|
|
49
|
+
cause
|
|
48
50
|
});
|
|
49
|
-
logger.error("a database query failed", {
|
|
50
|
-
model: label,
|
|
51
|
-
operation
|
|
52
|
-
}, cause);
|
|
53
51
|
return Promise.reject(cause);
|
|
54
52
|
});
|
|
55
53
|
} } } });
|
|
@@ -82,6 +80,11 @@ const defaultLoader = async () => (await import("@prisma/instrumentation")).Pris
|
|
|
82
80
|
* **The skip is logged, not silent.** Telemetry you believe you have and do not
|
|
83
81
|
* is worse than none, so the one path that quietly produces no spans says so at
|
|
84
82
|
* `debug` — the level for something that is a choice rather than a fault.
|
|
83
|
+
*
|
|
84
|
+
* This is the one place in this package that still holds a `Logger`, and it is
|
|
85
|
+
* why the module needs one: it is a STARTUP fact rather than an operation, so
|
|
86
|
+
* the `Observers` seam has nothing to settle. An observer writes lines about
|
|
87
|
+
* operations that fail; a missing optional peer is neither.
|
|
85
88
|
*/
|
|
86
89
|
const loadPrismaInstrumentation = async (logger, load = defaultLoader) => {
|
|
87
90
|
try {
|
|
@@ -113,27 +116,21 @@ const loadPrismaInstrumentation = async (logger, load = defaultLoader) => {
|
|
|
113
116
|
* against this same URL *before the process starts*; an application that
|
|
114
117
|
* migrates itself at boot races every other replica.
|
|
115
118
|
*/
|
|
116
|
-
const prismaDatabase = (name) => ({ client
|
|
119
|
+
const prismaDatabase = (name) => ({ client }) => {
|
|
117
120
|
const config = Config.provider(`${name}Config`)(Config.object({ url: Config.string("DATABASE_URL") }));
|
|
118
121
|
const DatabasePort = Port(name);
|
|
119
122
|
const open = (url) => client(new PrismaPg({ connectionString: url }));
|
|
120
123
|
const port = DatabasePort;
|
|
121
|
-
const
|
|
124
|
+
const clientProvider = Provider(port)({
|
|
122
125
|
inject: {
|
|
123
126
|
settings: config.port,
|
|
124
|
-
|
|
125
|
-
meter: Meter
|
|
127
|
+
observers: Observers
|
|
126
128
|
},
|
|
127
|
-
acquire: ({ settings,
|
|
128
|
-
return fromSafePromise(Promise.resolve(instrument(open(settings.url),
|
|
129
|
+
acquire: ({ settings, observers }) => {
|
|
130
|
+
return fromSafePromise(Promise.resolve(instrument(open(settings.url), observers)));
|
|
129
131
|
},
|
|
130
132
|
release: (db) => db.$disconnect()
|
|
131
133
|
});
|
|
132
|
-
const plainProvider = Provider(port)({
|
|
133
|
-
inject: { settings: config.port },
|
|
134
|
-
acquire: ({ settings }) => OkAsync(open(settings.url)),
|
|
135
|
-
release: (db) => db.$disconnect()
|
|
136
|
-
});
|
|
137
134
|
const healthCheck = Provider.member(HealthChecks)({
|
|
138
135
|
inject: { db: port },
|
|
139
136
|
sync: ({ db }) => ({
|
|
@@ -145,15 +142,15 @@ const prismaDatabase = (name) => ({ client, instrumented }) => {
|
|
|
145
142
|
inject: { logger: Logger },
|
|
146
143
|
sync: ({ logger }) => () => loadPrismaInstrumentation(logger)
|
|
147
144
|
});
|
|
148
|
-
const
|
|
149
|
-
needs: [
|
|
150
|
-
Env,
|
|
151
|
-
Logger,
|
|
152
|
-
Meter
|
|
153
|
-
],
|
|
145
|
+
const chosen = Module(name)({
|
|
146
|
+
needs: [Env, Logger],
|
|
154
147
|
provides: [
|
|
155
148
|
config,
|
|
156
|
-
|
|
149
|
+
Provider.member(Observers)({
|
|
150
|
+
inject: {},
|
|
151
|
+
value: noObserver
|
|
152
|
+
}),
|
|
153
|
+
clientProvider,
|
|
157
154
|
healthCheck,
|
|
158
155
|
instrumentation
|
|
159
156
|
],
|
|
@@ -163,16 +160,7 @@ const prismaDatabase = (name) => ({ client, instrumented }) => {
|
|
|
163
160
|
Instrumentations
|
|
164
161
|
]
|
|
165
162
|
});
|
|
166
|
-
|
|
167
|
-
needs: [Env],
|
|
168
|
-
provides: [
|
|
169
|
-
config,
|
|
170
|
-
plainProvider,
|
|
171
|
-
healthCheck
|
|
172
|
-
],
|
|
173
|
-
exports: [DatabasePort, HealthChecks]
|
|
174
|
-
});
|
|
175
|
-
return Object.assign(instrumented !== false ? instrumentedModule : plainModule, { port: DatabasePort });
|
|
163
|
+
return Object.assign(chosen, { port: DatabasePort });
|
|
176
164
|
};
|
|
177
165
|
//#endregion
|
|
178
166
|
export { prismaDatabase };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btravstack/prisma",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "The Prisma starter for @btravstack/core: DATABASE_URL through Config, the Postgres driver adapter, and a client whose pool is the application scope's",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"database",
|
|
@@ -53,17 +53,17 @@
|
|
|
53
53
|
"typescript": "7.0.2",
|
|
54
54
|
"unthrown": "5.7.0",
|
|
55
55
|
"vitest": "4.1.11",
|
|
56
|
-
"@btravstack/config": "0.
|
|
57
|
-
"@btravstack/core": "0.
|
|
58
|
-
"@btravstack/di": "0.
|
|
56
|
+
"@btravstack/config": "0.11.0",
|
|
57
|
+
"@btravstack/core": "0.11.0",
|
|
58
|
+
"@btravstack/di": "0.11.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@prisma/adapter-pg": "^7.0.0",
|
|
62
62
|
"@prisma/instrumentation": "^7.0.0",
|
|
63
63
|
"unthrown": "^5.0.0",
|
|
64
|
-
"@btravstack/config": "^0.
|
|
65
|
-
"@btravstack/core": "^0.
|
|
66
|
-
"@btravstack/di": "^0.
|
|
64
|
+
"@btravstack/config": "^0.11.0",
|
|
65
|
+
"@btravstack/core": "^0.11.0",
|
|
66
|
+
"@btravstack/di": "^0.11.0"
|
|
67
67
|
},
|
|
68
68
|
"peerDependenciesMeta": {
|
|
69
69
|
"@prisma/instrumentation": {
|