devsess 0.1.0 → 0.2.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 +37 -24
- package/dist/async/define-cli.d.ts +4 -2
- package/dist/async/define-cli.d.ts.map +1 -1
- package/dist/async/dev-sessions.d.ts +10 -5
- package/dist/async/dev-sessions.d.ts.map +1 -1
- package/dist/async/index.d.ts +1 -0
- package/dist/async/index.d.ts.map +1 -1
- package/dist/async/index.js +49 -35
- package/dist/async/index.js.map +1 -1
- package/dist/async/platform.d.ts +41 -0
- package/dist/async/platform.d.ts.map +1 -0
- package/dist/async/run-dev-cli.d.ts +20 -0
- package/dist/async/run-dev-cli.d.ts.map +1 -0
- package/dist/async/run.d.ts +4 -4
- package/dist/async/run.d.ts.map +1 -1
- package/dist/async/session-state.d.ts +3 -1
- package/dist/async/session-state.d.ts.map +1 -1
- package/dist/chunk-AQGYVNYU.js +321 -0
- package/dist/chunk-AQGYVNYU.js.map +1 -0
- package/dist/current-session.d.ts +29 -0
- package/dist/current-session.d.ts.map +1 -0
- package/dist/dev/running-signal.d.ts +11 -0
- package/dist/dev/running-signal.d.ts.map +1 -1
- package/dist/dev-sessions.d.ts +29 -1
- package/dist/dev-sessions.d.ts.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -38
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
- package/dist/chunk-IEQZ3AJH.js +0 -282
- package/dist/chunk-IEQZ3AJH.js.map +0 -1
- package/dist/dev/define-cli.d.ts +0 -25
- package/dist/dev/define-cli.d.ts.map +0 -1
- package/dist/dev/run-dev-cli.d.ts +0 -20
- package/dist/dev/run-dev-cli.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -7,12 +7,13 @@ Scaffold dev scripts with reusable **dev sessions** and a per-session **PGlite +
|
|
|
7
7
|
- **Dev sessions** — each run reuses (or creates) a named, slug-based working directory under `.data/sessions`. Sticky dev-server ports, managed subprocesses that die with your script, and cross-service "running" signal files come built in.
|
|
8
8
|
- **A PGlite adapter** (`devsess/pglite`) — prepare a local Postgres-compatible database from your Drizzle migrations, scoped to the current dev session. Perfect for a `--lite` offline dev mode.
|
|
9
9
|
|
|
10
|
-
It
|
|
10
|
+
It runs on **Node or Bun** — devsess depends on neither directly, you supply whichever platform package's layer you use (`NodeServices.layer`/`BunServices.layer`, or the equivalent `platform` object for `devsess/async`). The examples below use the [Effect](https://effect.website) API (`devsess`); if you'd rather not deal with Effect directly, `devsess/async` exposes the same dev-session scaffolding as a plain, Promise-based API — see [API](#api).
|
|
11
11
|
|
|
12
12
|
## Install
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
bun add devsess effect @effect/platform-node
|
|
16
|
+
# or, on Bun: bun add devsess effect @effect/platform-bun
|
|
16
17
|
```
|
|
17
18
|
|
|
18
19
|
For the PGlite adapter (`devsess/pglite`), also add:
|
|
@@ -25,24 +26,24 @@ bun add @electric-sql/pglite drizzle-orm
|
|
|
25
26
|
|
|
26
27
|
```ts
|
|
27
28
|
// scripts/dev.ts
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
29
|
+
import { CurrentSession, DevSessions, getStickyPort, runManagedSubprocess } from 'devsess';
|
|
30
|
+
import { NodeRuntime, NodeServices } from '@effect/platform-node';
|
|
30
31
|
import { Effect } from 'effect';
|
|
32
|
+
import { Command, Flag } from 'effect/unstable/cli';
|
|
31
33
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
cli.Flag.withDescription('Use a per-session PGlite database'),
|
|
34
|
+
const web = Command.make(
|
|
35
|
+
'web',
|
|
36
|
+
{
|
|
37
|
+
lite: Flag.boolean('lite').pipe(
|
|
38
|
+
Flag.withDescription('Use a per-session PGlite database'),
|
|
38
39
|
),
|
|
39
40
|
},
|
|
40
|
-
|
|
41
|
+
(opts) =>
|
|
41
42
|
Effect.gen(function* () {
|
|
42
|
-
const session = yield*
|
|
43
|
+
const session = yield* CurrentSession;
|
|
43
44
|
yield* Effect.logInfo(`[dev] session: ${session.name}`);
|
|
44
45
|
|
|
45
|
-
const port = yield*
|
|
46
|
+
const port = yield* getStickyPort(session);
|
|
46
47
|
const env: Record<string, string> = { PORT: String(port) };
|
|
47
48
|
|
|
48
49
|
if (opts.lite) {
|
|
@@ -51,29 +52,38 @@ const main = defineDevCli({
|
|
|
51
52
|
env.DATABASE_LITE_PATH = litePath;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
yield*
|
|
55
|
-
}),
|
|
56
|
-
|
|
55
|
+
yield* runManagedSubprocess('bunx', ['vite'], { env });
|
|
56
|
+
}).pipe(Effect.provide(CurrentSession.layer)),
|
|
57
|
+
);
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
Command.run(web, { version: '0.1.0' }).pipe(
|
|
60
|
+
Effect.provide(DevSessions.layer),
|
|
61
|
+
Effect.provide(NodeServices.layer),
|
|
62
|
+
Effect.scoped,
|
|
63
|
+
NodeRuntime.runMain,
|
|
64
|
+
);
|
|
59
65
|
```
|
|
60
66
|
|
|
61
67
|
```bash
|
|
62
68
|
bun scripts/dev.ts --lite
|
|
63
69
|
```
|
|
64
70
|
|
|
71
|
+
`DevSessions.layer` auto-detects your project root (the nearest ancestor with a `package.json`) — no `dir` to pass. `CurrentSession.layer` sits on the handler, not around `Command.run`, so a `--help`/`--version` invocation never resolves (or creates) a session.
|
|
72
|
+
|
|
65
73
|
## Per-session PGlite
|
|
66
74
|
|
|
67
75
|
`prepareSessionPglite` builds a migration dump (if missing), hydrates a PGlite
|
|
68
76
|
client, validates and applies migrations — all scoped to the active dev session:
|
|
69
77
|
|
|
70
78
|
```ts
|
|
79
|
+
import { DevSessions, CurrentSession } from 'devsess';
|
|
71
80
|
import { prepareSessionPglite } from 'devsess/pglite';
|
|
72
81
|
|
|
73
|
-
// inside
|
|
74
|
-
const
|
|
82
|
+
// inside a handler, with CurrentSession.layer provided:
|
|
83
|
+
const sessions = yield* DevSessions;
|
|
84
|
+
const session = yield* CurrentSession;
|
|
75
85
|
const db = yield* prepareSessionPglite(session, {
|
|
76
|
-
migrationsFolder:
|
|
86
|
+
migrationsFolder: sessions.path('drizzle'),
|
|
77
87
|
});
|
|
78
88
|
// db.client — a ready PGlite client
|
|
79
89
|
// db.dataDir — its on-disk path (e.g. pass as DATABASE_LITE_PATH)
|
|
@@ -83,11 +93,14 @@ const db = yield* prepareSessionPglite(session, {
|
|
|
83
93
|
|
|
84
94
|
From `devsess` (the Effect API):
|
|
85
95
|
|
|
86
|
-
- `
|
|
87
|
-
- `
|
|
88
|
-
- `DevSessions
|
|
96
|
+
- `DevSessions` — session-store service. `.layer` auto-detects the project root; `.layerAt(rootDir)` overrides it
|
|
97
|
+
- `CurrentSession` — resolved-session service for the current run. `.layer` resolves via `DevSessions`; `.layerOf(session)` pins one
|
|
98
|
+
- `ProjectRootNotFoundError` — raised by `DevSessions.layer` when no ancestor of `process.cwd()` has a `package.json`
|
|
99
|
+
- `getStickyPort(session)`, `runManagedSubprocess(cmd, args, opts?)`, `publishRunning(data)`, `awaitRunning(pkg)` — free functions; only `getStickyPort` takes a `DevSession`
|
|
89
100
|
- `SessionState.slot(schema)` — typed per-session JSON state
|
|
90
101
|
|
|
102
|
+
Build your CLI with a stock `Command.make(...)` from `effect/unstable/cli` — devsess no longer wraps it.
|
|
103
|
+
|
|
91
104
|
From `devsess/pglite`:
|
|
92
105
|
|
|
93
106
|
- `prepareSessionPglite(session, { migrationsFolder })`
|
|
@@ -98,8 +111,8 @@ From `devsess/pglite`:
|
|
|
98
111
|
|
|
99
112
|
From `devsess/async` (a plain, Promise-based mirror of the Effect API — no `effect` imports required):
|
|
100
113
|
|
|
101
|
-
- `defineDevCli({ name, dir, options?, run })` — `run` is `async (ctx, opts) => void`, and `ctx`'s helpers return Promises instead of Effects
|
|
102
|
-
- `createDevSessions(rootDir)` — async session manager (`getSessions`, `createSession`, `getLatestOrCreate`)
|
|
114
|
+
- `defineDevCli({ name, dir, platform, options?, run })` — `run` is `async (ctx, opts) => void`, and `ctx`'s helpers return Promises instead of Effects
|
|
115
|
+
- `createDevSessions(rootDir, services)` — async session manager (`getSessions`, `createSession`, `getLatestOrCreate`)
|
|
103
116
|
- `SessionState`, `DevSession`, plus `cli` and `Schema` re-exports
|
|
104
117
|
|
|
105
118
|
See the [full documentation](https://github.com/fdarian/devsess/tree/main/apps/docs) for details.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Effect } from 'effect';
|
|
2
|
-
import { type CommandConfig } from '../dev/run-dev-cli';
|
|
3
2
|
import { runManagedSubprocess } from '../dev/subprocess';
|
|
3
|
+
import type { DevPlatform } from './platform';
|
|
4
|
+
import { type CommandConfig } from './run-dev-cli';
|
|
4
5
|
import { type DevSession } from './session';
|
|
5
|
-
/** Promise-returning mirror of the Effect core's `
|
|
6
|
+
/** Promise-returning mirror of the Effect core's free functions (`getStickyPort`, `runManagedSubprocess`, `publishRunning`, `awaitRunning`), bundled into a single per-run context. */
|
|
6
7
|
type AsyncRunContext = {
|
|
7
8
|
session: () => Promise<DevSession>;
|
|
8
9
|
getStickyPort: () => Promise<number>;
|
|
@@ -14,6 +15,7 @@ export declare const defineDevCli: (config: {
|
|
|
14
15
|
name: string;
|
|
15
16
|
dir: string;
|
|
16
17
|
options?: CommandConfig;
|
|
18
|
+
platform: DevPlatform;
|
|
17
19
|
run: (ctx: AsyncRunContext, opts: Record<string, unknown>) => Promise<void> | void;
|
|
18
20
|
}) => ((argv: string[]) => void);
|
|
19
21
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-cli.d.ts","sourceRoot":"","sources":["../../src/async/define-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"define-cli.d.ts","sourceRoot":"","sources":["../../src/async/define-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,QAAQ,CAAC;AAW5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,WAAW,CAAC;AAE5D,uLAAuL;AACvL,KAAK,eAAe,GAAG;IACtB,OAAO,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IACnC,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,oBAAoB,EAAE,CACrB,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,KAC5C,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC;IACtE,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,YAAY,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7C,CAAC;AAEF,eAAO,MAAM,YAAY,WAAY;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,WAAW,CAAC;IACtB,GAAG,EAAE,CACJ,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACzB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC1B,KAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CA6C1B,CAAC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Layer } from 'effect';
|
|
2
|
+
import type { DevServices } from './platform';
|
|
1
3
|
import { type DevSession } from './session';
|
|
2
4
|
export type DevSessionManager = {
|
|
3
5
|
readonly dir: string;
|
|
@@ -6,11 +8,14 @@ export type DevSessionManager = {
|
|
|
6
8
|
getLatestOrCreate(): Promise<DevSession>;
|
|
7
9
|
};
|
|
8
10
|
/**
|
|
9
|
-
* Creates a manager for slug-named dev session directories under
|
|
11
|
+
* Creates a manager for slug-named dev session directories under
|
|
12
|
+
* `<rootDir>/.data/sessions`, using the caller-supplied platform `services` layer
|
|
13
|
+
* (e.g. `NodeServices.layer`). Same `rootDir` convention as `DevSessions.layerAt` — the
|
|
14
|
+
* CLI facade and this one agree on where sessions live given the same root.
|
|
10
15
|
*
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
16
|
+
* `DevSessions.layerAt` only wires lazy service methods when built (no directory IO
|
|
17
|
+
* happens at build time — see `src/dev-sessions.ts`), so it's cheap to re-provide the
|
|
18
|
+
* same `layer` value on every call rather than resolving a shared runtime once.
|
|
14
19
|
*/
|
|
15
|
-
export declare const createDevSessions: (rootDir: string) => DevSessionManager;
|
|
20
|
+
export declare const createDevSessions: (rootDir: string, services: Layer.Layer<DevServices>) => DevSessionManager;
|
|
16
21
|
//# sourceMappingURL=dev-sessions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-sessions.d.ts","sourceRoot":"","sources":["../../src/async/dev-sessions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev-sessions.d.ts","sourceRoot":"","sources":["../../src/async/dev-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,WAAW,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1C,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,iBAAiB,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;CACzC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,YACpB,MAAM,YACL,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,KAChC,iBAsBF,CAAC"}
|
package/dist/async/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * as cli from 'effect/unstable/cli';
|
|
|
3
3
|
export { SessionStateError } from '../dev/session-state';
|
|
4
4
|
export { defineDevCli } from './define-cli';
|
|
5
5
|
export { createDevSessions, type DevSessionManager } from './dev-sessions';
|
|
6
|
+
export type { DevPlatform, DevServices } from './platform';
|
|
6
7
|
export type { DevSession } from './session';
|
|
7
8
|
export { SessionState } from './session-state';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/async/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAC;AAE3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/async/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAC;AAE3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/async/index.js
CHANGED
|
@@ -4,30 +4,48 @@ import {
|
|
|
4
4
|
SessionStateError,
|
|
5
5
|
awaitRunningSignal,
|
|
6
6
|
getStickyPort,
|
|
7
|
-
makeDevSessionsLayer,
|
|
8
7
|
publishRunningSignal,
|
|
9
8
|
resolveSiblingDir,
|
|
10
|
-
runDevCli,
|
|
11
9
|
runManagedSubprocess,
|
|
12
10
|
runningSignalPath
|
|
13
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-AQGYVNYU.js";
|
|
14
12
|
|
|
15
13
|
// src/async/index.ts
|
|
16
14
|
import { Schema } from "effect";
|
|
17
|
-
import * as
|
|
15
|
+
import * as cli2 from "effect/unstable/cli";
|
|
18
16
|
|
|
19
17
|
// src/async/define-cli.ts
|
|
20
|
-
import { Effect as
|
|
18
|
+
import { Effect as Effect3 } from "effect";
|
|
19
|
+
|
|
20
|
+
// src/async/run-dev-cli.ts
|
|
21
|
+
import { Effect, Layer } from "effect";
|
|
22
|
+
import * as cli from "effect/unstable/cli";
|
|
23
|
+
var runDevCli = (config) => {
|
|
24
|
+
const command = cli.Command.make(
|
|
25
|
+
config.name,
|
|
26
|
+
config.options ?? {},
|
|
27
|
+
(opts) => config.makeHandler(opts)
|
|
28
|
+
);
|
|
29
|
+
return (argv) => {
|
|
30
|
+
const layer = DevSessions.layerAt(config.dir).pipe(
|
|
31
|
+
Layer.provideMerge(config.platform.services)
|
|
32
|
+
);
|
|
33
|
+
const program = cli.Command.runWith(command, {
|
|
34
|
+
version: "0.0.0"
|
|
35
|
+
})(argv);
|
|
36
|
+
config.platform.runMain(Effect.scoped(Effect.provide(program, layer)));
|
|
37
|
+
};
|
|
38
|
+
};
|
|
21
39
|
|
|
22
40
|
// src/async/session.ts
|
|
23
|
-
import { Effect } from "effect";
|
|
41
|
+
import { Effect as Effect2 } from "effect";
|
|
24
42
|
var EFFECT_SESSION = /* @__PURE__ */ Symbol("devsess/async/DevSession#effectSession");
|
|
25
43
|
var toAsyncSession = (session) => {
|
|
26
44
|
const asyncSession = {
|
|
27
45
|
name: session.name,
|
|
28
46
|
lastModifiedAt: session.lastModifiedAt,
|
|
29
47
|
// Safe to run synchronously: the core `path` is `Effect.succeed(pathJoin(rel))`, pure.
|
|
30
|
-
path: (relativePath) =>
|
|
48
|
+
path: (relativePath) => Effect2.runSync(session.path(relativePath)),
|
|
31
49
|
toString: () => session.toString()
|
|
32
50
|
};
|
|
33
51
|
Object.defineProperty(asyncSession, EFFECT_SESSION, {
|
|
@@ -51,67 +69,63 @@ var defineDevCli = (config) => runDevCli({
|
|
|
51
69
|
name: config.name,
|
|
52
70
|
dir: config.dir,
|
|
53
71
|
options: config.options,
|
|
54
|
-
|
|
72
|
+
platform: config.platform,
|
|
73
|
+
makeHandler: (opts) => Effect3.gen(function* () {
|
|
55
74
|
const sessions = yield* DevSessions;
|
|
56
|
-
const session = yield*
|
|
57
|
-
const services = yield*
|
|
75
|
+
const session = yield* Effect3.cached(sessions.getLatestOrCreate);
|
|
76
|
+
const services = yield* Effect3.context();
|
|
58
77
|
const ctx = {
|
|
59
|
-
session: () =>
|
|
60
|
-
getStickyPort: () =>
|
|
61
|
-
|
|
78
|
+
session: () => Effect3.runPromiseWith(services)(session).then(toAsyncSession),
|
|
79
|
+
getStickyPort: () => Effect3.runPromiseWith(services)(
|
|
80
|
+
Effect3.flatMap(session, getStickyPort)
|
|
62
81
|
),
|
|
63
|
-
runManagedSubprocess: (...args) =>
|
|
64
|
-
publishRunning: (data) =>
|
|
82
|
+
runManagedSubprocess: (...args) => Effect3.runPromiseWith(services)(runManagedSubprocess(...args)),
|
|
83
|
+
publishRunning: (data) => Effect3.runPromiseWith(services)(
|
|
65
84
|
publishRunningSignal(runningSignalPath(config.dir), data)
|
|
66
85
|
),
|
|
67
|
-
awaitRunning: (pkg) =>
|
|
86
|
+
awaitRunning: (pkg) => Effect3.runPromiseWith(services)(
|
|
68
87
|
awaitRunningSignal(
|
|
69
88
|
runningSignalPath(resolveSiblingDir(pkg, config.dir)),
|
|
70
89
|
{ parse: (raw) => JSON.parse(raw) }
|
|
71
90
|
)
|
|
72
91
|
)
|
|
73
92
|
};
|
|
74
|
-
yield*
|
|
93
|
+
yield* Effect3.promise(() => Promise.resolve(config.run(ctx, opts)));
|
|
75
94
|
})
|
|
76
95
|
});
|
|
77
96
|
|
|
78
97
|
// src/async/dev-sessions.ts
|
|
79
|
-
import {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
Layer.provide(NodeServices.layer)
|
|
84
|
-
);
|
|
85
|
-
const run = (effect) => Effect3.runPromise(Effect3.provide(effect, layer));
|
|
98
|
+
import { Effect as Effect4, Layer as Layer2 } from "effect";
|
|
99
|
+
var createDevSessions = (rootDir, services) => {
|
|
100
|
+
const layer = DevSessions.layerAt(rootDir).pipe(Layer2.provide(services));
|
|
101
|
+
const run2 = (effect) => Effect4.runPromise(Effect4.provide(effect, layer));
|
|
86
102
|
return {
|
|
87
103
|
// Matches the service's own `dir`, which is `rootDir` verbatim — safe to read synchronously.
|
|
88
104
|
dir: rootDir,
|
|
89
|
-
getSessions: () =>
|
|
105
|
+
getSessions: () => run2(DevSessions.use((sessions) => sessions.getSessions)).then(
|
|
90
106
|
(sessions) => sessions.map(toAsyncSession)
|
|
91
107
|
),
|
|
92
|
-
createSession: () =>
|
|
108
|
+
createSession: () => run2(DevSessions.use((sessions) => sessions.createSession)).then(
|
|
93
109
|
toAsyncSession
|
|
94
110
|
),
|
|
95
|
-
getLatestOrCreate: () =>
|
|
111
|
+
getLatestOrCreate: () => run2(DevSessions.use((sessions) => sessions.getLatestOrCreate)).then(
|
|
96
112
|
toAsyncSession
|
|
97
113
|
)
|
|
98
114
|
};
|
|
99
115
|
};
|
|
100
116
|
|
|
101
117
|
// src/async/run.ts
|
|
102
|
-
import {
|
|
103
|
-
|
|
104
|
-
var nodeLayer = NodeServices2.layer;
|
|
105
|
-
var runNode = (effect) => Effect4.runPromise(Effect4.scoped(Effect4.provide(effect, nodeLayer)));
|
|
118
|
+
import { Effect as Effect5 } from "effect";
|
|
119
|
+
var run = (effect, services) => Effect5.runPromise(Effect5.scoped(Effect5.provide(effect, services)));
|
|
106
120
|
|
|
107
121
|
// src/async/session-state.ts
|
|
108
122
|
var SessionState2;
|
|
109
123
|
((SessionState3) => {
|
|
110
|
-
function slot(schema) {
|
|
124
|
+
function slot(schema, services) {
|
|
111
125
|
const effectSlot = SessionState.slot(schema);
|
|
112
126
|
return {
|
|
113
|
-
read: (session) =>
|
|
114
|
-
write: (session, data) =>
|
|
127
|
+
read: (session) => run(effectSlot.read(unwrapSession(session)), services),
|
|
128
|
+
write: (session, data) => run(effectSlot.write(unwrapSession(session), data), services)
|
|
115
129
|
};
|
|
116
130
|
}
|
|
117
131
|
SessionState3.slot = slot;
|
|
@@ -120,7 +134,7 @@ export {
|
|
|
120
134
|
Schema,
|
|
121
135
|
SessionState2 as SessionState,
|
|
122
136
|
SessionStateError,
|
|
123
|
-
cli,
|
|
137
|
+
cli2 as cli,
|
|
124
138
|
createDevSessions,
|
|
125
139
|
defineDevCli
|
|
126
140
|
};
|
package/dist/async/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/async/index.ts","../../src/async/define-cli.ts","../../src/async/session.ts","../../src/async/dev-sessions.ts","../../src/async/run.ts","../../src/async/session-state.ts"],"sourcesContent":["// Re-exported so consumers can declare CLI flags/arguments without a direct\n// dependency on `effect/unstable/cli`, e.g. `cli.Flag.string('local')`.\n\nexport { Schema } from 'effect';\nexport * as cli from 'effect/unstable/cli';\n\nexport { SessionStateError } from '../dev/session-state';\nexport { defineDevCli } from './define-cli';\nexport { createDevSessions, type DevSessionManager } from './dev-sessions';\nexport type { DevSession } from './session';\nexport { SessionState } from './session-state';\n","import { Effect, type Scope } from 'effect';\nimport type { FileSystem } from 'effect/FileSystem';\nimport type { Path } from 'effect/Path';\nimport type { ChildProcessSpawner } from 'effect/unstable/process/ChildProcessSpawner';\nimport { type CommandConfig, runDevCli } from '../dev/run-dev-cli';\nimport {\n\tawaitRunningSignal,\n\tpublishRunningSignal,\n\tresolveSiblingDir,\n\trunningSignalPath,\n} from '../dev/running-signal';\nimport { getStickyPort } from '../dev/sticky-port';\nimport { runManagedSubprocess } from '../dev/subprocess';\nimport { DevSessions } from '../dev-sessions';\nimport { type DevSession, toAsyncSession } from './session';\n\n/** Promise-returning mirror of the Effect core's `RunContext` (see `src/dev/define-cli.ts`). */\ntype AsyncRunContext = {\n\tsession: () => Promise<DevSession>;\n\tgetStickyPort: () => Promise<number>;\n\trunManagedSubprocess: (\n\t\t...args: Parameters<typeof runManagedSubprocess>\n\t) => Promise<Effect.Success<ReturnType<typeof runManagedSubprocess>>>;\n\tpublishRunning: (data: unknown) => Promise<void>;\n\tawaitRunning: <T>(pkg: string) => Promise<T>;\n};\n\nexport const defineDevCli = (config: {\n\tname: string;\n\tdir: string;\n\toptions?: CommandConfig;\n\trun: (\n\t\tctx: AsyncRunContext,\n\t\topts: Record<string, unknown>,\n\t) => Promise<void> | void;\n}): ((argv: string[]) => void) =>\n\trunDevCli({\n\t\tname: config.name,\n\t\tdir: config.dir,\n\t\toptions: config.options,\n\t\tmakeHandler: (opts) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst sessions = yield* DevSessions;\n\t\t\t\tconst session = yield* Effect.cached(sessions.getLatestOrCreate);\n\n\t\t\t\t// Capture the process-lifetime context (the Scope opened by `runDevCli`'s\n\t\t\t\t// outer `Effect.scoped`, plus DevSessions | FileSystem | Path | ChildProcessSpawner).\n\t\t\t\t// Running each ctx helper with this captured context — instead of a fresh,\n\t\t\t\t// transient `Effect.runPromise` per call — attaches its scoped resources\n\t\t\t\t// (managed subprocess, running-signal file) to that process-lifetime scope,\n\t\t\t\t// so they only release when the CLI process ends, not right after the Promise settles.\n\t\t\t\tconst services = yield* Effect.context<\n\t\t\t\t\tDevSessions | FileSystem | Path | ChildProcessSpawner | Scope.Scope\n\t\t\t\t>();\n\n\t\t\t\tconst ctx: AsyncRunContext = {\n\t\t\t\t\tsession: () =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(session).then(toAsyncSession),\n\t\t\t\t\tgetStickyPort: () =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(\n\t\t\t\t\t\t\tEffect.flatMap(session, getStickyPort),\n\t\t\t\t\t\t),\n\t\t\t\t\trunManagedSubprocess: (...args) =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(runManagedSubprocess(...args)),\n\t\t\t\t\tpublishRunning: (data) =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(\n\t\t\t\t\t\t\tpublishRunningSignal(runningSignalPath(config.dir), data),\n\t\t\t\t\t\t),\n\t\t\t\t\tawaitRunning: <T>(pkg: string) =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(\n\t\t\t\t\t\t\tawaitRunningSignal<T>(\n\t\t\t\t\t\t\t\trunningSignalPath(resolveSiblingDir(pkg, config.dir)),\n\t\t\t\t\t\t\t\t{ parse: (raw) => JSON.parse(raw) as T },\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t};\n\n\t\t\t\tyield* Effect.promise(() => Promise.resolve(config.run(ctx, opts)));\n\t\t\t}),\n\t});\n","import { Effect } from 'effect';\nimport type { DevSession as EffectDevSession } from '../dev-sessions';\n\n/** Non-enumerable, module-private key used to stash the Effect session on its async wrapper. */\nconst EFFECT_SESSION = Symbol('devsess/async/DevSession#effectSession');\n\nexport type DevSession = {\n\treadonly name: string;\n\treadonly lastModifiedAt: Date | null;\n\tpath(relativePath: string): string;\n\ttoString(): string;\n};\n\n/**\n * Wraps an Effect `DevSession` as a plain-async `DevSession`. The original Effect\n * session is stashed under `EFFECT_SESSION` so other async ops (e.g. `SessionState`)\n * can reuse the Effect core via `unwrapSession`.\n */\nexport const toAsyncSession = (session: EffectDevSession): DevSession => {\n\tconst asyncSession: DevSession = {\n\t\tname: session.name,\n\t\tlastModifiedAt: session.lastModifiedAt,\n\t\t// Safe to run synchronously: the core `path` is `Effect.succeed(pathJoin(rel))`, pure.\n\t\tpath: (relativePath) => Effect.runSync(session.path(relativePath)),\n\t\ttoString: () => session.toString(),\n\t};\n\n\tObject.defineProperty(asyncSession, EFFECT_SESSION, {\n\t\tvalue: session,\n\t\tenumerable: false,\n\t});\n\n\treturn asyncSession;\n};\n\n/** Recovers the Effect `DevSession` stashed by `toAsyncSession`. */\nexport const unwrapSession = (session: DevSession): EffectDevSession => {\n\tconst effectSession = (\n\t\tsession as unknown as Record<\n\t\t\ttypeof EFFECT_SESSION,\n\t\t\tEffectDevSession | undefined\n\t\t>\n\t)[EFFECT_SESSION];\n\tif (effectSession === undefined) {\n\t\tthrow new Error(\n\t\t\t'devsess/async: expected a DevSession created by this package, but the internal Effect session handle is missing',\n\t\t);\n\t}\n\treturn effectSession;\n};\n","import { NodeServices } from '@effect/platform-node';\nimport { Effect, Layer } from 'effect';\nimport { DevSessions, makeDevSessionsLayer } from '../dev-sessions';\nimport { type DevSession, toAsyncSession } from './session';\n\nexport type DevSessionManager = {\n\treadonly dir: string;\n\tgetSessions(): Promise<Array<DevSession>>;\n\tcreateSession(): Promise<DevSession>;\n\tgetLatestOrCreate(): Promise<DevSession>;\n};\n\n/**\n * Creates a manager for slug-named dev session directories under `rootDir`.\n *\n * `makeDevSessionsLayer` only wires lazy service methods when built (no directory\n * IO happens at build time — see `src/dev-sessions.ts`), so it's cheap to re-provide\n * the same `layer` value on every call rather than resolving a shared runtime once.\n */\nexport const createDevSessions = (rootDir: string): DevSessionManager => {\n\tconst layer = makeDevSessionsLayer(rootDir).pipe(\n\t\tLayer.provide(NodeServices.layer),\n\t);\n\n\tconst run = <A, E>(effect: Effect.Effect<A, E, DevSessions>): Promise<A> =>\n\t\tEffect.runPromise(Effect.provide(effect, layer));\n\n\treturn {\n\t\t// Matches the service's own `dir`, which is `rootDir` verbatim — safe to read synchronously.\n\t\tdir: rootDir,\n\t\tgetSessions: () =>\n\t\t\trun(DevSessions.use((sessions) => sessions.getSessions)).then(\n\t\t\t\t(sessions) => sessions.map(toAsyncSession),\n\t\t\t),\n\t\tcreateSession: () =>\n\t\t\trun(DevSessions.use((sessions) => sessions.createSession)).then(\n\t\t\t\ttoAsyncSession,\n\t\t\t),\n\t\tgetLatestOrCreate: () =>\n\t\t\trun(DevSessions.use((sessions) => sessions.getLatestOrCreate)).then(\n\t\t\t\ttoAsyncSession,\n\t\t\t),\n\t};\n};\n","import { NodeServices } from '@effect/platform-node';\nimport { Effect, type Scope } from 'effect';\n\nconst nodeLayer = NodeServices.layer;\n\n/** Runs an Effect that only needs the shared Node platform services (+ an optional Scope) as a Promise. */\nexport const runNode = <A, E>(\n\teffect: Effect.Effect<A, E, NodeServices.NodeServices | Scope.Scope>,\n): Promise<A> =>\n\tEffect.runPromise(Effect.scoped(Effect.provide(effect, nodeLayer)));\n","import type * as S from 'effect/Schema';\nimport { SessionState as EffectSessionState } from '../dev/session-state';\nimport { runNode } from './run';\nimport { type DevSession, unwrapSession } from './session';\n\nexport namespace SessionState {\n\t// Decoding must run without extra context (only `NodeServices | Scope` are\n\t// available via `runNode`), so schemas cannot require decoding services.\n\ttype Shape = S.Codec<unknown, unknown, never>;\n\n\texport function slot<T extends Shape>(schema: T) {\n\t\tconst effectSlot = EffectSessionState.slot(schema);\n\t\treturn {\n\t\t\tread: (session: DevSession): Promise<T['Type'] | null> =>\n\t\t\t\trunNode(effectSlot.read(unwrapSession(session))),\n\t\t\twrite: (session: DevSession, data: T['Type']): Promise<void> =>\n\t\t\t\trunNode(effectSlot.write(unwrapSession(session), data)),\n\t\t};\n\t}\n}\n"],"mappings":"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","names":["Effect","Effect","Effect","Effect","NodeServices","Effect","SessionState"]}
|
|
1
|
+
{"version":3,"sources":["../../src/async/index.ts","../../src/async/define-cli.ts","../../src/async/run-dev-cli.ts","../../src/async/session.ts","../../src/async/dev-sessions.ts","../../src/async/run.ts","../../src/async/session-state.ts"],"sourcesContent":["// Re-exported so consumers can declare CLI flags/arguments without a direct\n// dependency on `effect/unstable/cli`, e.g. `cli.Flag.string('local')`.\n\nexport { Schema } from 'effect';\nexport * as cli from 'effect/unstable/cli';\n\nexport { SessionStateError } from '../dev/session-state';\nexport { defineDevCli } from './define-cli';\nexport { createDevSessions, type DevSessionManager } from './dev-sessions';\nexport type { DevPlatform, DevServices } from './platform';\nexport type { DevSession } from './session';\nexport { SessionState } from './session-state';\n","import { Effect, type Scope } from 'effect';\nimport type { FileSystem } from 'effect/FileSystem';\nimport type { Path } from 'effect/Path';\nimport type { ChildProcessSpawner } from 'effect/unstable/process/ChildProcessSpawner';\nimport {\n\tawaitRunningSignal,\n\tpublishRunningSignal,\n\tresolveSiblingDir,\n\trunningSignalPath,\n} from '../dev/running-signal';\nimport { getStickyPort } from '../dev/sticky-port';\nimport { runManagedSubprocess } from '../dev/subprocess';\nimport { DevSessions } from '../dev-sessions';\nimport type { DevPlatform } from './platform';\nimport { type CommandConfig, runDevCli } from './run-dev-cli';\nimport { type DevSession, toAsyncSession } from './session';\n\n/** Promise-returning mirror of the Effect core's free functions (`getStickyPort`, `runManagedSubprocess`, `publishRunning`, `awaitRunning`), bundled into a single per-run context. */\ntype AsyncRunContext = {\n\tsession: () => Promise<DevSession>;\n\tgetStickyPort: () => Promise<number>;\n\trunManagedSubprocess: (\n\t\t...args: Parameters<typeof runManagedSubprocess>\n\t) => Promise<Effect.Success<ReturnType<typeof runManagedSubprocess>>>;\n\tpublishRunning: (data: unknown) => Promise<void>;\n\tawaitRunning: <T>(pkg: string) => Promise<T>;\n};\n\nexport const defineDevCli = (config: {\n\tname: string;\n\tdir: string;\n\toptions?: CommandConfig;\n\tplatform: DevPlatform;\n\trun: (\n\t\tctx: AsyncRunContext,\n\t\topts: Record<string, unknown>,\n\t) => Promise<void> | void;\n}): ((argv: string[]) => void) =>\n\trunDevCli({\n\t\tname: config.name,\n\t\tdir: config.dir,\n\t\toptions: config.options,\n\t\tplatform: config.platform,\n\t\tmakeHandler: (opts) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst sessions = yield* DevSessions;\n\t\t\t\tconst session = yield* Effect.cached(sessions.getLatestOrCreate);\n\n\t\t\t\t// Capture the process-lifetime context (the Scope opened by `runDevCli`'s\n\t\t\t\t// outer `Effect.scoped`, plus DevSessions | FileSystem | Path | ChildProcessSpawner).\n\t\t\t\t// Running each ctx helper with this captured context — instead of a fresh,\n\t\t\t\t// transient `Effect.runPromise` per call — attaches its scoped resources\n\t\t\t\t// (managed subprocess, running-signal file) to that process-lifetime scope,\n\t\t\t\t// so they only release when the CLI process ends, not right after the Promise settles.\n\t\t\t\tconst services = yield* Effect.context<\n\t\t\t\t\tDevSessions | FileSystem | Path | ChildProcessSpawner | Scope.Scope\n\t\t\t\t>();\n\n\t\t\t\tconst ctx: AsyncRunContext = {\n\t\t\t\t\tsession: () =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(session).then(toAsyncSession),\n\t\t\t\t\tgetStickyPort: () =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(\n\t\t\t\t\t\t\tEffect.flatMap(session, getStickyPort),\n\t\t\t\t\t\t),\n\t\t\t\t\trunManagedSubprocess: (...args) =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(runManagedSubprocess(...args)),\n\t\t\t\t\tpublishRunning: (data) =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(\n\t\t\t\t\t\t\tpublishRunningSignal(runningSignalPath(config.dir), data),\n\t\t\t\t\t\t),\n\t\t\t\t\tawaitRunning: <T>(pkg: string) =>\n\t\t\t\t\t\tEffect.runPromiseWith(services)(\n\t\t\t\t\t\t\tawaitRunningSignal<T>(\n\t\t\t\t\t\t\t\trunningSignalPath(resolveSiblingDir(pkg, config.dir)),\n\t\t\t\t\t\t\t\t{ parse: (raw) => JSON.parse(raw) as T },\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t};\n\n\t\t\t\tyield* Effect.promise(() => Promise.resolve(config.run(ctx, opts)));\n\t\t\t}),\n\t});\n","import { Effect, Layer, type Scope } from 'effect';\nimport * as cli from 'effect/unstable/cli';\nimport { DevSessions } from '../dev-sessions';\nimport type { DevPlatform, DevServices } from './platform';\n\nexport type CommandConfig = typeof cli.Command.make extends (\n\tname: string,\n\tconfig: infer C,\n\t...rest: Array<unknown>\n) => unknown\n\t? C\n\t: never;\n\ntype CliHandler = (\n\topts: Record<string, unknown>,\n) => Effect.Effect<void, unknown, DevSessions | DevServices | Scope.Scope>;\n\n/**\n * CLI scaffolding for the plain-async `defineDevCli` facade (`src/async/define-cli.ts`):\n * builds the `cli.Command`, wires the per-project `DevSessions` + caller-supplied\n * platform services layer, and runs it via `platform.runMain`.\n */\nexport const runDevCli = (config: {\n\tname: string;\n\tdir: string;\n\toptions?: CommandConfig;\n\tplatform: DevPlatform;\n\tmakeHandler: CliHandler;\n}): ((argv: string[]) => void) => {\n\tconst command = cli.Command.make(config.name, config.options ?? {}, (opts) =>\n\t\tconfig.makeHandler(opts as Record<string, unknown>),\n\t);\n\n\treturn (argv) => {\n\t\tconst layer = DevSessions.layerAt(config.dir).pipe(\n\t\t\tLayer.provideMerge(config.platform.services),\n\t\t);\n\n\t\tconst program = cli.Command.runWith(command, {\n\t\t\tversion: '0.0.0',\n\t\t})(argv);\n\n\t\tconfig.platform.runMain(Effect.scoped(Effect.provide(program, layer)));\n\t};\n};\n","import { Effect } from 'effect';\nimport type { DevSession as EffectDevSession } from '../dev-sessions';\n\n/** Non-enumerable, module-private key used to stash the Effect session on its async wrapper. */\nconst EFFECT_SESSION = Symbol('devsess/async/DevSession#effectSession');\n\nexport type DevSession = {\n\treadonly name: string;\n\treadonly lastModifiedAt: Date | null;\n\tpath(relativePath: string): string;\n\ttoString(): string;\n};\n\n/**\n * Wraps an Effect `DevSession` as a plain-async `DevSession`. The original Effect\n * session is stashed under `EFFECT_SESSION` so other async ops (e.g. `SessionState`)\n * can reuse the Effect core via `unwrapSession`.\n */\nexport const toAsyncSession = (session: EffectDevSession): DevSession => {\n\tconst asyncSession: DevSession = {\n\t\tname: session.name,\n\t\tlastModifiedAt: session.lastModifiedAt,\n\t\t// Safe to run synchronously: the core `path` is `Effect.succeed(pathJoin(rel))`, pure.\n\t\tpath: (relativePath) => Effect.runSync(session.path(relativePath)),\n\t\ttoString: () => session.toString(),\n\t};\n\n\tObject.defineProperty(asyncSession, EFFECT_SESSION, {\n\t\tvalue: session,\n\t\tenumerable: false,\n\t});\n\n\treturn asyncSession;\n};\n\n/** Recovers the Effect `DevSession` stashed by `toAsyncSession`. */\nexport const unwrapSession = (session: DevSession): EffectDevSession => {\n\tconst effectSession = (\n\t\tsession as unknown as Record<\n\t\t\ttypeof EFFECT_SESSION,\n\t\t\tEffectDevSession | undefined\n\t\t>\n\t)[EFFECT_SESSION];\n\tif (effectSession === undefined) {\n\t\tthrow new Error(\n\t\t\t'devsess/async: expected a DevSession created by this package, but the internal Effect session handle is missing',\n\t\t);\n\t}\n\treturn effectSession;\n};\n","import { Effect, Layer } from 'effect';\nimport { DevSessions } from '../dev-sessions';\nimport type { DevServices } from './platform';\nimport { type DevSession, toAsyncSession } from './session';\n\nexport type DevSessionManager = {\n\treadonly dir: string;\n\tgetSessions(): Promise<Array<DevSession>>;\n\tcreateSession(): Promise<DevSession>;\n\tgetLatestOrCreate(): Promise<DevSession>;\n};\n\n/**\n * Creates a manager for slug-named dev session directories under\n * `<rootDir>/.data/sessions`, using the caller-supplied platform `services` layer\n * (e.g. `NodeServices.layer`). Same `rootDir` convention as `DevSessions.layerAt` — the\n * CLI facade and this one agree on where sessions live given the same root.\n *\n * `DevSessions.layerAt` only wires lazy service methods when built (no directory IO\n * happens at build time — see `src/dev-sessions.ts`), so it's cheap to re-provide the\n * same `layer` value on every call rather than resolving a shared runtime once.\n */\nexport const createDevSessions = (\n\trootDir: string,\n\tservices: Layer.Layer<DevServices>,\n): DevSessionManager => {\n\tconst layer = DevSessions.layerAt(rootDir).pipe(Layer.provide(services));\n\n\tconst run = <A, E>(effect: Effect.Effect<A, E, DevSessions>): Promise<A> =>\n\t\tEffect.runPromise(Effect.provide(effect, layer));\n\n\treturn {\n\t\t// Matches the service's own `dir`, which is `rootDir` verbatim — safe to read synchronously.\n\t\tdir: rootDir,\n\t\tgetSessions: () =>\n\t\t\trun(DevSessions.use((sessions) => sessions.getSessions)).then(\n\t\t\t\t(sessions) => sessions.map(toAsyncSession),\n\t\t\t),\n\t\tcreateSession: () =>\n\t\t\trun(DevSessions.use((sessions) => sessions.createSession)).then(\n\t\t\t\ttoAsyncSession,\n\t\t\t),\n\t\tgetLatestOrCreate: () =>\n\t\t\trun(DevSessions.use((sessions) => sessions.getLatestOrCreate)).then(\n\t\t\t\ttoAsyncSession,\n\t\t\t),\n\t};\n};\n","import { Effect, type Layer, type Scope } from 'effect';\nimport type { DevServices } from './platform';\n\n/** Runs an Effect that only needs the caller-supplied platform services (+ an optional Scope) as a Promise. */\nexport const run = <A, E>(\n\teffect: Effect.Effect<A, E, DevServices | Scope.Scope>,\n\tservices: Layer.Layer<DevServices>,\n): Promise<A> =>\n\tEffect.runPromise(Effect.scoped(Effect.provide(effect, services)));\n","import type { Layer } from 'effect';\nimport type * as S from 'effect/Schema';\nimport { SessionState as EffectSessionState } from '../dev/session-state';\nimport type { DevServices } from './platform';\nimport { run } from './run';\nimport { type DevSession, unwrapSession } from './session';\n\nexport namespace SessionState {\n\t// Decoding must run without extra context beyond the platform `services` layer, so\n\t// schemas cannot require decoding services of their own.\n\ttype Shape = S.Codec<unknown, unknown, never>;\n\n\texport function slot<T extends Shape>(\n\t\tschema: T,\n\t\tservices: Layer.Layer<DevServices>,\n\t) {\n\t\tconst effectSlot = EffectSessionState.slot(schema);\n\t\treturn {\n\t\t\tread: (session: DevSession): Promise<T['Type'] | null> =>\n\t\t\t\trun(effectSlot.read(unwrapSession(session)), services),\n\t\t\twrite: (session: DevSession, data: T['Type']): Promise<void> =>\n\t\t\t\trun(effectSlot.write(unwrapSession(session), data), services),\n\t\t};\n\t}\n}\n"],"mappings":"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","names":["cli","Effect","Effect","Effect","Effect","Layer","Layer","run","Effect","Effect","SessionState"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Effect, Layer } from 'effect';
|
|
2
|
+
import type { FileSystem } from 'effect/FileSystem';
|
|
3
|
+
import type { Path } from 'effect/Path';
|
|
4
|
+
import type * as Runtime from 'effect/Runtime';
|
|
5
|
+
import type { Stdio } from 'effect/Stdio';
|
|
6
|
+
import type { Terminal } from 'effect/Terminal';
|
|
7
|
+
import type { ChildProcessSpawner } from 'effect/unstable/process/ChildProcessSpawner';
|
|
8
|
+
/**
|
|
9
|
+
* Core `effect` service tags this library needs from the caller-supplied platform.
|
|
10
|
+
* `effect/unstable/cli`'s `Command.runWith` pulls in `Stdio`/`Terminal` alongside the
|
|
11
|
+
* `FileSystem`/`Path`/`ChildProcessSpawner` the library's own code depends on directly.
|
|
12
|
+
*
|
|
13
|
+
* Both `@effect/platform-node`'s `NodeServices.NodeServices` and `@effect/platform-bun`'s
|
|
14
|
+
* `BunServices.BunServices` are unions of these same core tags (plus `Crypto`, which this
|
|
15
|
+
* library never uses), so either `.layer` satisfies this narrower requirement.
|
|
16
|
+
*/
|
|
17
|
+
export type DevServices = ChildProcessSpawner | FileSystem | Path | Stdio | Terminal;
|
|
18
|
+
type RunMainOptions = {
|
|
19
|
+
readonly disableErrorReporting?: boolean | undefined;
|
|
20
|
+
readonly teardown?: Runtime.Teardown | undefined;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Structurally identical to `NodeRuntime.runMain` and `BunRuntime.runMain` (both are the
|
|
24
|
+
* same function, re-exported from `@effect/platform-node-shared`), so either is assignable
|
|
25
|
+
* here with no cast.
|
|
26
|
+
*/
|
|
27
|
+
type RunMain = {
|
|
28
|
+
(options?: RunMainOptions): <E, A>(effect: Effect.Effect<A, E>) => void;
|
|
29
|
+
<E, A>(effect: Effect.Effect<A, E>, options?: RunMainOptions): void;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* The platform a caller supplies so the library depends on no platform package of its
|
|
33
|
+
* own, e.g. `{ services: NodeServices.layer, runMain: NodeRuntime.runMain }` or the `Bun`
|
|
34
|
+
* equivalents.
|
|
35
|
+
*/
|
|
36
|
+
export type DevPlatform = {
|
|
37
|
+
readonly services: Layer.Layer<DevServices>;
|
|
38
|
+
readonly runMain: RunMain;
|
|
39
|
+
};
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/async/platform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAEvF;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GACpB,mBAAmB,GACnB,UAAU,GACV,IAAI,GACJ,KAAK,GACL,QAAQ,CAAC;AAEZ,KAAK,cAAc,GAAG;IACrB,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;CACjD,CAAC;AAEF;;;;GAIG;AACH,KAAK,OAAO,GAAG;IACd,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;IACxE,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CACpE,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG;IACzB,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Effect, type Scope } from 'effect';
|
|
2
|
+
import * as cli from 'effect/unstable/cli';
|
|
3
|
+
import { DevSessions } from '../dev-sessions';
|
|
4
|
+
import type { DevPlatform, DevServices } from './platform';
|
|
5
|
+
export type CommandConfig = typeof cli.Command.make extends (name: string, config: infer C, ...rest: Array<unknown>) => unknown ? C : never;
|
|
6
|
+
type CliHandler = (opts: Record<string, unknown>) => Effect.Effect<void, unknown, DevSessions | DevServices | Scope.Scope>;
|
|
7
|
+
/**
|
|
8
|
+
* CLI scaffolding for the plain-async `defineDevCli` facade (`src/async/define-cli.ts`):
|
|
9
|
+
* builds the `cli.Command`, wires the per-project `DevSessions` + caller-supplied
|
|
10
|
+
* platform services layer, and runs it via `platform.runMain`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const runDevCli: (config: {
|
|
13
|
+
name: string;
|
|
14
|
+
dir: string;
|
|
15
|
+
options?: CommandConfig;
|
|
16
|
+
platform: DevPlatform;
|
|
17
|
+
makeHandler: CliHandler;
|
|
18
|
+
}) => ((argv: string[]) => void);
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=run-dev-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-dev-cli.d.ts","sourceRoot":"","sources":["../../src/async/run-dev-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAS,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS,CAC3D,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,EACf,GAAG,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,KACnB,OAAO,GACT,CAAC,GACD,KAAK,CAAC;AAET,KAAK,UAAU,GAAG,CACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACzB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,SAAS,WAAY;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,WAAW,CAAC;IACtB,WAAW,EAAE,UAAU,CAAC;CACxB,KAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAgB5B,CAAC"}
|
package/dist/async/run.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
/** Runs an Effect that only needs the
|
|
4
|
-
export declare const
|
|
1
|
+
import { Effect, type Layer, type Scope } from 'effect';
|
|
2
|
+
import type { DevServices } from './platform';
|
|
3
|
+
/** Runs an Effect that only needs the caller-supplied platform services (+ an optional Scope) as a Promise. */
|
|
4
|
+
export declare const run: <A, E>(effect: Effect.Effect<A, E, DevServices | Scope.Scope>, services: Layer.Layer<DevServices>) => Promise<A>;
|
|
5
5
|
//# sourceMappingURL=run.d.ts.map
|
package/dist/async/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/async/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/async/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,+GAA+G;AAC/G,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,CAAC,UACf,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,YAC5C,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,KAChC,OAAO,CAAC,CAAC,CACuD,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { Layer } from 'effect';
|
|
1
2
|
import type * as S from 'effect/Schema';
|
|
3
|
+
import type { DevServices } from './platform';
|
|
2
4
|
import { type DevSession } from './session';
|
|
3
5
|
export declare namespace SessionState {
|
|
4
6
|
type Shape = S.Codec<unknown, unknown, never>;
|
|
5
|
-
export function slot<T extends Shape>(schema: T): {
|
|
7
|
+
export function slot<T extends Shape>(schema: T, services: Layer.Layer<DevServices>): {
|
|
6
8
|
read: (session: DevSession) => Promise<T['Type'] | null>;
|
|
7
9
|
write: (session: DevSession, data: T['Type']) => Promise<void>;
|
|
8
10
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/async/session-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,CAAC,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/async/session-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,KAAK,CAAC,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,WAAW,CAAC;AAE3D,yBAAiB,YAAY,CAAC;IAG7B,KAAK,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAE9C,MAAM,UAAU,IAAI,CAAC,CAAC,SAAS,KAAK,EACnC,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;QAIjC,IAAI,YAAY,UAAU,KAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QAEtD,KAAK,YAAY,UAAU,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;MAG7D;;CACD"}
|