@effected/app 0.19.0 → 0.20.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/App.js +23 -3
- package/AppConfig.js +20 -3
- package/README.md +4 -4
- package/index.d.ts +44 -8
- package/package.json +10 -5
package/App.js
CHANGED
|
@@ -59,6 +59,22 @@ var App = class {
|
|
|
59
59
|
* layer, never beneath it. Underneath, the test body has no `TestClock` in
|
|
60
60
|
* its own context and `TestClock.adjust` dies as a defect — so the entries
|
|
61
61
|
* under test carry real timestamps and nothing ever expires.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { App } from "@effected/app";
|
|
66
|
+
* import { NodeServices } from "@effect/platform-node";
|
|
67
|
+
* import { Layer } from "effect";
|
|
68
|
+
*
|
|
69
|
+
* const migrations = [
|
|
70
|
+
* { id: 1, name: "runs", up: (sql) => sql`CREATE TABLE runs (id TEXT PRIMARY KEY)` },
|
|
71
|
+
* ];
|
|
72
|
+
*
|
|
73
|
+
* // Bound once, to a const: XDG dirs for "myapp", store.db and cache.db.
|
|
74
|
+
* const AppLive = App.layer({ namespace: "myapp", store: { migrations } }).pipe(
|
|
75
|
+
* Layer.provide(NodeServices.layer),
|
|
76
|
+
* );
|
|
77
|
+
* ```
|
|
62
78
|
*/
|
|
63
79
|
static layer = layer;
|
|
64
80
|
/**
|
|
@@ -73,9 +89,13 @@ var App = class {
|
|
|
73
89
|
*
|
|
74
90
|
* The documented limit: code paths that actually exercise `ensure*` **die**
|
|
75
91
|
* against `FileSystem.layerNoop` — it is a stub, not a working filesystem.
|
|
76
|
-
* `layerTest` is for testing logic that *uses* the control plane
|
|
77
|
-
* real directory behaviour
|
|
78
|
-
* `
|
|
92
|
+
* `layerTest` is for testing logic that *uses* the control plane. A test of
|
|
93
|
+
* real directory behaviour composes `AppDirs.layer` over `@effected/memfs`,
|
|
94
|
+
* whose `ensure*` members then create directories on an in-memory volume.
|
|
95
|
+
* The databases are the exception: `Store` and `Cache` open their SQLite
|
|
96
|
+
* files through the native binding, which never sees the `FileSystem`
|
|
97
|
+
* service, so a test of {@link App.layer} end to end still needs a
|
|
98
|
+
* temp-directory `HOME`.
|
|
79
99
|
*/
|
|
80
100
|
static layerTest = layerTest;
|
|
81
101
|
};
|
package/AppConfig.js
CHANGED
|
@@ -65,9 +65,7 @@ var AppConfig = class {
|
|
|
65
65
|
* `options.resolversAfter` appends, `options.systemEtc` adds the `/etc`
|
|
66
66
|
* tier behind the XDG pair, and `options.xdg: false` removes the XDG pair
|
|
67
67
|
* altogether — at which point the chain is exactly the caller's own, and
|
|
68
|
-
* the preset
|
|
69
|
-
* Dropping to `ConfigFile.layer` directly is no longer the price of an
|
|
70
|
-
* unusual chain.
|
|
68
|
+
* the preset contributes the ambient namespace and `defaultPath` alone.
|
|
71
69
|
*
|
|
72
70
|
* **The namespace is never a parameter.** It is read from the ambient
|
|
73
71
|
* `AppDirs` service at layer build time, so it is typed exactly once, in
|
|
@@ -76,6 +74,25 @@ var AppConfig = class {
|
|
|
76
74
|
*
|
|
77
75
|
* This is a layer-returning function: bind the result to a `const` and reuse
|
|
78
76
|
* that binding, or two provide sites mint two independent service instances.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* import { AppConfig } from "@effected/app";
|
|
81
|
+
* import { ConfigFile, JsonCodec } from "@effected/config-file";
|
|
82
|
+
* import { Schema } from "effect";
|
|
83
|
+
*
|
|
84
|
+
* class Settings extends Schema.Class<Settings>("Settings")({
|
|
85
|
+
* registry: Schema.String,
|
|
86
|
+
* }) {}
|
|
87
|
+
* class SettingsFile extends ConfigFile.Service<SettingsFile, Settings>()("myapp/Settings") {}
|
|
88
|
+
*
|
|
89
|
+
* // The namespace comes from the ambient `AppDirs`, provided by `App.layer`.
|
|
90
|
+
* const ConfigLive = AppConfig.layer(SettingsFile, {
|
|
91
|
+
* filename: "config.json",
|
|
92
|
+
* schema: Settings,
|
|
93
|
+
* codec: JsonCodec,
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
79
96
|
*/
|
|
80
97
|
static layer = layer;
|
|
81
98
|
};
|
package/README.md
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
The application control plane for Effect. `App.layer` gives an application its XDG-namespaced directories, a migrated SQLite state database, a TTL cache and — through `AppConfig.layer` — a config file, all pointed at the same place, with the namespace typed exactly once. It is a composition over [`@effected/xdg`](../xdg), [`@effected/store`](../store) and [`@effected/config-file`](../config-file), and nothing else.
|
|
9
9
|
|
|
10
|
-
> **Pre
|
|
11
|
-
>
|
|
12
|
-
> `1.0.0`
|
|
13
|
-
>
|
|
10
|
+
> **Pre-`1.0.0`.** This package is part of the `@effected/*` kit, built on stable
|
|
11
|
+
> Effect v4 (`effect` `^4.0.0`) and still in `0.x` development. Stable Effect
|
|
12
|
+
> makes a kit `1.0.0` possible, not automatic. To keep your `effect` and
|
|
13
|
+
> `@effect/*` versions on the line the kit is built and tested against, install
|
|
14
14
|
> [`@effected/pnpm-plugin-effect`](https://www.npmjs.com/package/@effected/pnpm-plugin-effect).
|
|
15
15
|
>
|
|
16
16
|
> **Stability: unstable.** This package's API surface is not yet considered
|
package/index.d.ts
CHANGED
|
@@ -168,6 +168,22 @@ export declare class App {
|
|
|
168
168
|
* layer, never beneath it. Underneath, the test body has no `TestClock` in
|
|
169
169
|
* its own context and `TestClock.adjust` dies as a defect — so the entries
|
|
170
170
|
* under test carry real timestamps and nothing ever expires.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* import { App } from "@effected/app";
|
|
175
|
+
* import { NodeServices } from "@effect/platform-node";
|
|
176
|
+
* import { Layer } from "effect";
|
|
177
|
+
*
|
|
178
|
+
* const migrations = [
|
|
179
|
+
* { id: 1, name: "runs", up: (sql) => sql`CREATE TABLE runs (id TEXT PRIMARY KEY)` },
|
|
180
|
+
* ];
|
|
181
|
+
*
|
|
182
|
+
* // Bound once, to a const: XDG dirs for "myapp", store.db and cache.db.
|
|
183
|
+
* const AppLive = App.layer({ namespace: "myapp", store: { migrations } }).pipe(
|
|
184
|
+
* Layer.provide(NodeServices.layer),
|
|
185
|
+
* );
|
|
186
|
+
* ```
|
|
171
187
|
*/
|
|
172
188
|
static readonly layer: (options: AppOptions) => Layer.Layer<Xdg | AppDirs | Store | Cache, AppError, FileSystem.FileSystem | Path.Path>;
|
|
173
189
|
/**
|
|
@@ -182,9 +198,13 @@ export declare class App {
|
|
|
182
198
|
*
|
|
183
199
|
* The documented limit: code paths that actually exercise `ensure*` **die**
|
|
184
200
|
* against `FileSystem.layerNoop` — it is a stub, not a working filesystem.
|
|
185
|
-
* `layerTest` is for testing logic that *uses* the control plane
|
|
186
|
-
* real directory behaviour
|
|
187
|
-
* `
|
|
201
|
+
* `layerTest` is for testing logic that *uses* the control plane. A test of
|
|
202
|
+
* real directory behaviour composes `AppDirs.layer` over `@effected/memfs`,
|
|
203
|
+
* whose `ensure*` members then create directories on an in-memory volume.
|
|
204
|
+
* The databases are the exception: `Store` and `Cache` open their SQLite
|
|
205
|
+
* files through the native binding, which never sees the `FileSystem`
|
|
206
|
+
* service, so a test of {@link App.layer} end to end still needs a
|
|
207
|
+
* temp-directory `HOME`.
|
|
188
208
|
*/
|
|
189
209
|
static readonly layerTest: (options: AppTestOptions) => Layer.Layer<Xdg | AppDirs | Store | Cache, AppError>;
|
|
190
210
|
}
|
|
@@ -260,8 +280,7 @@ interface AppConfigOptions<A, I, RR = never> {
|
|
|
260
280
|
* native probe, still behind it as the fallback. `ConfigResolver.upwardWalk`
|
|
261
281
|
* for a project-local file goes here too.
|
|
262
282
|
*
|
|
263
|
-
* Absent, the chain is
|
|
264
|
-
* unchanged: `XdgConfig.resolver`, then `XdgConfig.nativeResolver`.
|
|
283
|
+
* Absent, the chain is `XdgConfig.resolver`, then `XdgConfig.nativeResolver`.
|
|
265
284
|
*
|
|
266
285
|
* A layer is built before a CLI parses anything, so getting the parsed flag
|
|
267
286
|
* here is the one wiring question this option raises. `effect/cli`
|
|
@@ -381,9 +400,7 @@ export declare class AppConfig {
|
|
|
381
400
|
* `options.resolversAfter` appends, `options.systemEtc` adds the `/etc`
|
|
382
401
|
* tier behind the XDG pair, and `options.xdg: false` removes the XDG pair
|
|
383
402
|
* altogether — at which point the chain is exactly the caller's own, and
|
|
384
|
-
* the preset
|
|
385
|
-
* Dropping to `ConfigFile.layer` directly is no longer the price of an
|
|
386
|
-
* unusual chain.
|
|
403
|
+
* the preset contributes the ambient namespace and `defaultPath` alone.
|
|
387
404
|
*
|
|
388
405
|
* **The namespace is never a parameter.** It is read from the ambient
|
|
389
406
|
* `AppDirs` service at layer build time, so it is typed exactly once, in
|
|
@@ -392,6 +409,25 @@ export declare class AppConfig {
|
|
|
392
409
|
*
|
|
393
410
|
* This is a layer-returning function: bind the result to a `const` and reuse
|
|
394
411
|
* that binding, or two provide sites mint two independent service instances.
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```ts
|
|
415
|
+
* import { AppConfig } from "@effected/app";
|
|
416
|
+
* import { ConfigFile, JsonCodec } from "@effected/config-file";
|
|
417
|
+
* import { Schema } from "effect";
|
|
418
|
+
*
|
|
419
|
+
* class Settings extends Schema.Class<Settings>("Settings")({
|
|
420
|
+
* registry: Schema.String,
|
|
421
|
+
* }) {}
|
|
422
|
+
* class SettingsFile extends ConfigFile.Service<SettingsFile, Settings>()("myapp/Settings") {}
|
|
423
|
+
*
|
|
424
|
+
* // The namespace comes from the ambient `AppDirs`, provided by `App.layer`.
|
|
425
|
+
* const ConfigLive = AppConfig.layer(SettingsFile, {
|
|
426
|
+
* filename: "config.json",
|
|
427
|
+
* schema: Settings,
|
|
428
|
+
* codec: JsonCodec,
|
|
429
|
+
* });
|
|
430
|
+
* ```
|
|
395
431
|
*/
|
|
396
432
|
static readonly layer: <Self, A, I, RR = never>(tag: Context.Key<Self, ConfigFileShape<A>>, options: AppConfigOptions<A, I, RR>) => Layer.Layer<Self, never, FileSystem.FileSystem | Path.Path | AppDirs | Xdg | RR>;
|
|
397
433
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The application control plane for Effect: one layer wiring XDG-namespaced directories, a migrated SQLite store, a TTL cache and a config file to the same place.",
|
|
6
6
|
"keywords": [
|
|
@@ -39,10 +39,15 @@
|
|
|
39
39
|
"./package.json": "./package.json"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@effected/config-file": "^0.
|
|
43
|
-
"@effected/
|
|
44
|
-
"@effected/
|
|
45
|
-
"
|
|
42
|
+
"@effected/config-file": "^0.14.0",
|
|
43
|
+
"@effected/glob": "^0.10.0",
|
|
44
|
+
"@effected/jsonc": "^0.15.0",
|
|
45
|
+
"@effected/store": "^0.12.0",
|
|
46
|
+
"@effected/toml": "^0.11.0",
|
|
47
|
+
"@effected/walker": "^0.15.0",
|
|
48
|
+
"@effected/xdg": "^0.9.0",
|
|
49
|
+
"@effected/yaml": "^0.19.0",
|
|
50
|
+
"effect": "^4.0.0"
|
|
46
51
|
},
|
|
47
52
|
"engines": {
|
|
48
53
|
"node": ">=24.11.0"
|