@livestore/utils-dev 0.4.0-dev.7 → 0.4.0-dev.9
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/dist/.tsbuildinfo.json +1 -1
- package/dist/node/DockerComposeService/DockerComposeService.d.ts +12 -2
- package/dist/node/DockerComposeService/DockerComposeService.d.ts.map +1 -1
- package/dist/node/DockerComposeService/DockerComposeService.js +54 -17
- package/dist/node/DockerComposeService/DockerComposeService.js.map +1 -1
- package/dist/node/mod.d.ts +0 -2
- package/dist/node/mod.d.ts.map +1 -1
- package/dist/node/mod.js +0 -2
- package/dist/node/mod.js.map +1 -1
- package/dist/node-vitest/Vitest.d.ts +6 -6
- package/dist/node-vitest/Vitest.d.ts.map +1 -1
- package/dist/node-vitest/Vitest.js +2 -2
- package/dist/node-vitest/Vitest.js.map +1 -1
- package/dist/node-vitest/Vitest.test.js +12 -1
- package/dist/node-vitest/Vitest.test.js.map +1 -1
- package/dist/{node/WranglerDevServer → wrangler}/WranglerDevServer.d.ts +6 -6
- package/dist/wrangler/WranglerDevServer.d.ts.map +1 -0
- package/dist/wrangler/WranglerDevServer.js +90 -0
- package/dist/wrangler/WranglerDevServer.js.map +1 -0
- package/dist/wrangler/WranglerDevServer.test.d.ts.map +1 -0
- package/dist/wrangler/WranglerDevServer.test.js +77 -0
- package/dist/wrangler/WranglerDevServer.test.js.map +1 -0
- package/dist/wrangler/fixtures/cf-worker.d.ts.map +1 -0
- package/dist/wrangler/fixtures/cf-worker.js.map +1 -0
- package/dist/wrangler/mod.d.ts +2 -0
- package/dist/wrangler/mod.d.ts.map +1 -0
- package/dist/wrangler/mod.js +2 -0
- package/dist/wrangler/mod.js.map +1 -0
- package/package.json +7 -4
- package/src/node/DockerComposeService/DockerComposeService.ts +99 -23
- package/src/node/mod.ts +0 -7
- package/src/node-vitest/Vitest.test.ts +12 -1
- package/src/node-vitest/Vitest.ts +31 -19
- package/src/wrangler/WranglerDevServer.test.ts +133 -0
- package/src/wrangler/WranglerDevServer.ts +180 -0
- package/src/wrangler/mod.ts +6 -0
- package/dist/node/WranglerDevServer/WranglerDevServer.d.ts.map +0 -1
- package/dist/node/WranglerDevServer/WranglerDevServer.js +0 -122
- package/dist/node/WranglerDevServer/WranglerDevServer.js.map +0 -1
- package/dist/node/WranglerDevServer/WranglerDevServer.test.d.ts.map +0 -1
- package/dist/node/WranglerDevServer/WranglerDevServer.test.js +0 -179
- package/dist/node/WranglerDevServer/WranglerDevServer.test.js.map +0 -1
- package/dist/node/WranglerDevServer/fixtures/cf-worker.d.ts.map +0 -1
- package/dist/node/WranglerDevServer/fixtures/cf-worker.js.map +0 -1
- package/dist/node/WranglerDevServer/process-tree-manager.d.ts +0 -55
- package/dist/node/WranglerDevServer/process-tree-manager.d.ts.map +0 -1
- package/dist/node/WranglerDevServer/process-tree-manager.js +0 -178
- package/dist/node/WranglerDevServer/process-tree-manager.js.map +0 -1
- package/dist/node/vitest-docker-compose-setup.d.ts +0 -32
- package/dist/node/vitest-docker-compose-setup.d.ts.map +0 -1
- package/dist/node/vitest-docker-compose-setup.js +0 -131
- package/dist/node/vitest-docker-compose-setup.js.map +0 -1
- package/dist/node/vitest-wrangler-setup.d.ts +0 -27
- package/dist/node/vitest-wrangler-setup.d.ts.map +0 -1
- package/dist/node/vitest-wrangler-setup.js +0 -96
- package/dist/node/vitest-wrangler-setup.js.map +0 -1
- package/dist/node-vitest/polyfill.d.ts +0 -2
- package/dist/node-vitest/polyfill.d.ts.map +0 -1
- package/dist/node-vitest/polyfill.js +0 -3
- package/dist/node-vitest/polyfill.js.map +0 -1
- package/src/node/WranglerDevServer/WranglerDevServer.test.ts +0 -266
- package/src/node/WranglerDevServer/WranglerDevServer.ts +0 -266
- package/src/node/WranglerDevServer/process-tree-manager.ts +0 -263
- /package/dist/{node/WranglerDevServer → wrangler}/WranglerDevServer.test.d.ts +0 -0
- /package/dist/{node/WranglerDevServer → wrangler}/fixtures/cf-worker.d.ts +0 -0
- /package/dist/{node/WranglerDevServer → wrangler}/fixtures/cf-worker.js +0 -0
- /package/src/{node/WranglerDevServer → wrangler}/fixtures/cf-worker.ts +0 -0
- /package/src/{node/WranglerDevServer → wrangler}/fixtures/wrangler.toml +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Effect, FetchHttpClient, Layer } from '@livestore/utils/effect';
|
|
2
|
+
import { getFreePort, PlatformNode } from '@livestore/utils/node';
|
|
3
|
+
import { Vitest } from '@livestore/utils-dev/node-vitest';
|
|
4
|
+
import { expect } from 'vitest';
|
|
5
|
+
import { WranglerDevServerError, WranglerDevServerService, } from "./WranglerDevServer.js";
|
|
6
|
+
const testTimeout = 60_000;
|
|
7
|
+
const WranglerDevServerTest = (args = {}) => WranglerDevServerService.Default({
|
|
8
|
+
cwd: `${import.meta.dirname}/fixtures`,
|
|
9
|
+
...args,
|
|
10
|
+
}).pipe(Layer.provide(FetchHttpClient.layer));
|
|
11
|
+
Vitest.describe('WranglerDevServer', { timeout: testTimeout }, () => {
|
|
12
|
+
Vitest.describe('Basic Operations', () => {
|
|
13
|
+
const withBasicTest = (args = {}) => Vitest.makeWithTestCtx({
|
|
14
|
+
timeout: testTimeout,
|
|
15
|
+
makeLayer: () => WranglerDevServerTest(args).pipe(Layer.provide(PlatformNode.NodeContext.layer)),
|
|
16
|
+
});
|
|
17
|
+
Vitest.scopedLive('should start wrangler dev server and return port', (test) => Effect.gen(function* () {
|
|
18
|
+
const server = yield* WranglerDevServerService;
|
|
19
|
+
expect(server.port).toBeGreaterThan(0);
|
|
20
|
+
expect(server.url).toMatch(/http:\/\/127.0.0.1:\d+/);
|
|
21
|
+
}).pipe(withBasicTest()(test)));
|
|
22
|
+
Vitest.scopedLive('should use specified port when provided', (test) => Effect.andThen(getFreePort, (port) => Effect.gen(function* () {
|
|
23
|
+
const server = yield* WranglerDevServerService;
|
|
24
|
+
expect(server.port).toBe(port);
|
|
25
|
+
expect(server.url).toBe(`http://127.0.0.1:${port}`);
|
|
26
|
+
}).pipe(withBasicTest({ preferredPort: port })(test))));
|
|
27
|
+
});
|
|
28
|
+
Vitest.describe('Error Handling', () => {
|
|
29
|
+
const withErrorTest = (args = {}) => Vitest.makeWithTestCtx({
|
|
30
|
+
timeout: testTimeout,
|
|
31
|
+
makeLayer: () => WranglerDevServerTest(args).pipe(Layer.provide(PlatformNode.NodeContext.layer)),
|
|
32
|
+
});
|
|
33
|
+
Vitest.scopedLive('should handle missing wrangler.toml but should timeout', (test) => Effect.gen(function* () {
|
|
34
|
+
const error = yield* WranglerDevServerService.pipe(Effect.provide(WranglerDevServerTest({
|
|
35
|
+
cwd: '/tmp',
|
|
36
|
+
wranglerConfigPath: '/dev/null',
|
|
37
|
+
connectTimeout: '500 millis',
|
|
38
|
+
}).pipe(Layer.provide(PlatformNode.NodeContext.layer))), Effect.flip);
|
|
39
|
+
expect(error).toBeInstanceOf(WranglerDevServerError);
|
|
40
|
+
}).pipe(Vitest.withTestCtx(test)));
|
|
41
|
+
Vitest.scopedLive('should handle invalid working directory', (test) => Effect.gen(function* () {
|
|
42
|
+
const result = yield* WranglerDevServerService.pipe(Effect.provide(WranglerDevServerTest({
|
|
43
|
+
cwd: '/completely/nonexistent/directory',
|
|
44
|
+
}).pipe(Layer.provide(PlatformNode.NodeContext.layer))), Effect.either);
|
|
45
|
+
expect(result._tag).toBe('Left');
|
|
46
|
+
if (result._tag === 'Left') {
|
|
47
|
+
expect(result.left).toBeInstanceOf(WranglerDevServerError);
|
|
48
|
+
}
|
|
49
|
+
}).pipe(Vitest.withTestCtx(test)));
|
|
50
|
+
Vitest.scopedLive('should timeout if server fails to start', (test) => Effect.gen(function* () {
|
|
51
|
+
// Create a command that will never output "Ready on"
|
|
52
|
+
const result = yield* WranglerDevServerService.pipe(
|
|
53
|
+
// Override the timeout for this test to be shorter
|
|
54
|
+
Effect.timeout('5 seconds'), Effect.either);
|
|
55
|
+
// This might succeed or fail depending on actual wrangler behavior
|
|
56
|
+
// The main point is testing timeout functionality
|
|
57
|
+
expect(['Left', 'Right']).toContain(result._tag);
|
|
58
|
+
}).pipe(withErrorTest()(test)));
|
|
59
|
+
});
|
|
60
|
+
Vitest.describe('Service Pattern', () => {
|
|
61
|
+
const withServiceTest = (args = {}) => Vitest.makeWithTestCtx({
|
|
62
|
+
timeout: testTimeout,
|
|
63
|
+
makeLayer: () => WranglerDevServerTest(args).pipe(Layer.provide(PlatformNode.NodeContext.layer)),
|
|
64
|
+
});
|
|
65
|
+
Vitest.scopedLive('should work with service pattern', (test) => Effect.gen(function* () {
|
|
66
|
+
const server = yield* WranglerDevServerService;
|
|
67
|
+
expect(server.port).toBeGreaterThan(0);
|
|
68
|
+
expect(server.url).toMatch(/http:\/\/127.0.0.1:\d+/);
|
|
69
|
+
}).pipe(withServiceTest()(test)));
|
|
70
|
+
Vitest.scopedLive('should work with custom port via service', (test) => Effect.andThen(getFreePort, (port) => Effect.gen(function* () {
|
|
71
|
+
const server = yield* WranglerDevServerService;
|
|
72
|
+
expect(server.port).toBe(port);
|
|
73
|
+
expect(server.url).toBe(`http://127.0.0.1:${port}`);
|
|
74
|
+
}).pipe(withServiceTest({ preferredPort: port })(test))));
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=WranglerDevServer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WranglerDevServer.test.js","sourceRoot":"","sources":["../../src/wrangler/WranglerDevServer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cf-worker.d.ts","sourceRoot":"","sources":["../../../src/wrangler/fixtures/cf-worker.ts"],"names":[],"mappings":";oBACwB,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;;AADnD,wBAIC;AAED,qBAAa,MAAM;IACX,KAAK,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;CAGlD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cf-worker.js","sourceRoot":"","sources":["../../../src/wrangler/fixtures/cf-worker.ts"],"names":[],"mappings":"AAAA,eAAe;IACb,KAAK,CAAC,KAAK,CAAC,QAAiB;QAC3B,OAAO,IAAI,QAAQ,CAAC,6CAA6C,CAAC,CAAA;IACpE,CAAC;CACF,CAAA;AAED,MAAM,OAAO,MAAM;IACjB,KAAK,CAAC,KAAK,CAAC,QAAiB;QAC3B,OAAO,IAAI,QAAQ,CAAC,iCAAiC,CAAC,CAAA;IACxD,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/wrangler/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,iBAAiB,EACtB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,wBAAwB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/wrangler/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,wBAAwB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/utils-dev",
|
|
3
|
-
"version": "0.4.0-dev.
|
|
3
|
+
"version": "0.4.0-dev.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"./src/node-vitest/global.ts",
|
|
@@ -8,18 +8,21 @@
|
|
|
8
8
|
],
|
|
9
9
|
"exports": {
|
|
10
10
|
"./node": "./dist/node/mod.js",
|
|
11
|
-
"./node-vitest": "./dist/node-vitest/mod.js"
|
|
11
|
+
"./node-vitest": "./dist/node-vitest/mod.js",
|
|
12
|
+
"./wrangler": "./dist/wrangler/mod.js"
|
|
12
13
|
},
|
|
13
14
|
"dependencies": {
|
|
14
|
-
"@effect/opentelemetry": "0.
|
|
15
|
+
"@effect/opentelemetry": "0.57.0",
|
|
15
16
|
"@effect/vitest": "0.25.1",
|
|
17
|
+
"@iarna/toml": "2.2.5",
|
|
16
18
|
"@opentelemetry/api": "1.9.0",
|
|
17
19
|
"@opentelemetry/exporter-metrics-otlp-http": "0.203.0",
|
|
18
20
|
"@opentelemetry/exporter-trace-otlp-http": "0.203.0",
|
|
19
21
|
"@opentelemetry/sdk-metrics": "2.0.1",
|
|
20
22
|
"@opentelemetry/sdk-trace-base": "2.0.1",
|
|
21
23
|
"@opentelemetry/sdk-trace-node": "2.0.1",
|
|
22
|
-
"
|
|
24
|
+
"wrangler": "4.38.0",
|
|
25
|
+
"@livestore/utils": "0.4.0-dev.9"
|
|
23
26
|
},
|
|
24
27
|
"devDependencies": {},
|
|
25
28
|
"files": [
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type CommandExecutor,
|
|
5
5
|
Duration,
|
|
6
6
|
Effect,
|
|
7
|
+
Fiber,
|
|
7
8
|
type PlatformError,
|
|
8
9
|
Schedule,
|
|
9
10
|
Schema,
|
|
@@ -13,7 +14,7 @@ import {
|
|
|
13
14
|
|
|
14
15
|
export class DockerComposeError extends Schema.TaggedError<DockerComposeError>()('DockerComposeError', {
|
|
15
16
|
cause: Schema.Defect,
|
|
16
|
-
|
|
17
|
+
note: Schema.String,
|
|
17
18
|
}) {}
|
|
18
19
|
|
|
19
20
|
export interface DockerComposeArgs {
|
|
@@ -43,6 +44,11 @@ export interface DockerComposeOperations {
|
|
|
43
44
|
options?: StartOptions,
|
|
44
45
|
) => Effect.Effect<void, DockerComposeError | PlatformError.PlatformError, Scope.Scope>
|
|
45
46
|
readonly stop: Effect.Effect<void, DockerComposeError | PlatformError.PlatformError>
|
|
47
|
+
readonly down: (options?: {
|
|
48
|
+
readonly env?: Record<string, string>
|
|
49
|
+
readonly volumes?: boolean
|
|
50
|
+
readonly removeOrphans?: boolean
|
|
51
|
+
}) => Effect.Effect<void, DockerComposeError | PlatformError.PlatformError>
|
|
46
52
|
readonly logs: (
|
|
47
53
|
options?: LogsOptions,
|
|
48
54
|
) => Stream.Stream<string, DockerComposeError | PlatformError.PlatformError, Scope.Scope>
|
|
@@ -58,24 +64,59 @@ export class DockerComposeService extends Effect.Service<DockerComposeService>()
|
|
|
58
64
|
const pull = Effect.gen(function* () {
|
|
59
65
|
yield* Effect.log(`Pulling Docker Compose images in ${cwd}`)
|
|
60
66
|
|
|
61
|
-
|
|
67
|
+
// TODO (@IMax153) Refactor the effect command related code below as there is probably a much more elegant way to accomplish what we want here in a more effect idiomatic way.
|
|
68
|
+
const pullCommand = Command.make('docker', 'compose', 'pull').pipe(
|
|
62
69
|
Command.workingDirectory(cwd),
|
|
63
|
-
Command.
|
|
64
|
-
|
|
65
|
-
exitCode === 0
|
|
66
|
-
? Effect.void
|
|
67
|
-
: Effect.fail(
|
|
68
|
-
new DockerComposeError({
|
|
69
|
-
cause: new Error(`Docker compose pull failed with exit code ${exitCode}`),
|
|
70
|
-
message: `Docker compose pull failed with exit code ${exitCode}`,
|
|
71
|
-
}),
|
|
72
|
-
),
|
|
73
|
-
),
|
|
74
|
-
Effect.provide(commandExecutorContext),
|
|
70
|
+
Command.stdout('pipe'),
|
|
71
|
+
Command.stderr('pipe'),
|
|
75
72
|
)
|
|
76
73
|
|
|
74
|
+
const process = yield* pullCommand.pipe(Command.start, Effect.provide(commandExecutorContext))
|
|
75
|
+
|
|
76
|
+
const stdoutFiber = yield* process.stdout.pipe(
|
|
77
|
+
Stream.decodeText('utf8'),
|
|
78
|
+
Stream.runFold('', (acc, chunk) => acc + chunk),
|
|
79
|
+
Effect.fork,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
const stderrFiber = yield* process.stderr.pipe(
|
|
83
|
+
Stream.decodeText('utf8'),
|
|
84
|
+
Stream.runFold('', (acc, chunk) => acc + chunk),
|
|
85
|
+
Effect.fork,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
const exitCode = yield* process.exitCode
|
|
89
|
+
const stdout = yield* Fiber.join(stdoutFiber)
|
|
90
|
+
const stderr = yield* Fiber.join(stderrFiber)
|
|
91
|
+
|
|
92
|
+
const exitCodeNumber = Number(exitCode)
|
|
93
|
+
|
|
94
|
+
if (exitCodeNumber !== 0) {
|
|
95
|
+
const stdoutLog = stdout.length > 0 ? stdout : '<empty stdout>'
|
|
96
|
+
const stderrLog = stderr.length > 0 ? stderr : '<empty stderr>'
|
|
97
|
+
const failureMessage = [
|
|
98
|
+
`Docker compose pull failed with exit code ${exitCodeNumber} in ${cwd}`,
|
|
99
|
+
`stdout:\n${stdoutLog}`,
|
|
100
|
+
`stderr:\n${stderrLog}`,
|
|
101
|
+
].join('\n')
|
|
102
|
+
|
|
103
|
+
yield* Effect.logError(failureMessage)
|
|
104
|
+
|
|
105
|
+
return yield* new DockerComposeError({
|
|
106
|
+
cause: new Error(`Docker compose pull failed with exit code ${exitCodeNumber}`),
|
|
107
|
+
note: failureMessage,
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
77
111
|
yield* Effect.log(`Successfully pulled Docker Compose images`)
|
|
78
|
-
}).pipe(
|
|
112
|
+
}).pipe(
|
|
113
|
+
Effect.retry({
|
|
114
|
+
schedule: Schedule.exponentialBackoff10Sec,
|
|
115
|
+
while: Schema.is(DockerComposeError),
|
|
116
|
+
}),
|
|
117
|
+
Effect.withSpan('pullDockerComposeImages'),
|
|
118
|
+
Effect.scoped,
|
|
119
|
+
)
|
|
79
120
|
|
|
80
121
|
const start = (options: StartOptions = {}) =>
|
|
81
122
|
Effect.gen(function* () {
|
|
@@ -89,12 +130,14 @@ export class DockerComposeService extends Effect.Service<DockerComposeService>()
|
|
|
89
130
|
const command = yield* Command.make(baseArgs[0]!, ...baseArgs.slice(1)).pipe(
|
|
90
131
|
Command.workingDirectory(cwd),
|
|
91
132
|
Command.env(options.env ?? {}),
|
|
133
|
+
Command.stderr('inherit'),
|
|
134
|
+
Command.stdout('inherit'),
|
|
92
135
|
Command.start,
|
|
93
136
|
Effect.catchAll((cause) =>
|
|
94
137
|
Effect.fail(
|
|
95
138
|
new DockerComposeError({
|
|
96
139
|
cause,
|
|
97
|
-
|
|
140
|
+
note: `Failed to start Docker Compose services in ${cwd}`,
|
|
98
141
|
}),
|
|
99
142
|
),
|
|
100
143
|
),
|
|
@@ -103,13 +146,13 @@ export class DockerComposeService extends Effect.Service<DockerComposeService>()
|
|
|
103
146
|
|
|
104
147
|
// Wait for command completion
|
|
105
148
|
yield* command.exitCode.pipe(
|
|
106
|
-
Effect.flatMap((exitCode
|
|
149
|
+
Effect.flatMap((exitCode) =>
|
|
107
150
|
exitCode === 0
|
|
108
151
|
? Effect.void
|
|
109
152
|
: Effect.fail(
|
|
110
153
|
new DockerComposeError({
|
|
111
154
|
cause: new Error(`Docker compose exited with code ${exitCode}`),
|
|
112
|
-
|
|
155
|
+
note: `Docker Compose failed to start with exit code ${exitCode}. Env: ${JSON.stringify(options.env)}`,
|
|
113
156
|
}),
|
|
114
157
|
),
|
|
115
158
|
),
|
|
@@ -140,7 +183,7 @@ export class DockerComposeService extends Effect.Service<DockerComposeService>()
|
|
|
140
183
|
: Effect.fail(
|
|
141
184
|
new DockerComposeError({
|
|
142
185
|
cause: new Error(`Docker compose stop exited with code ${exitCode}`),
|
|
143
|
-
|
|
186
|
+
note: `Failed to stop Docker Compose services`,
|
|
144
187
|
}),
|
|
145
188
|
),
|
|
146
189
|
),
|
|
@@ -167,7 +210,7 @@ export class DockerComposeService extends Effect.Service<DockerComposeService>()
|
|
|
167
210
|
Effect.fail(
|
|
168
211
|
new DockerComposeError({
|
|
169
212
|
cause,
|
|
170
|
-
|
|
213
|
+
note: `Failed to read Docker Compose logs in ${cwd}`,
|
|
171
214
|
}),
|
|
172
215
|
),
|
|
173
216
|
),
|
|
@@ -181,13 +224,46 @@ export class DockerComposeService extends Effect.Service<DockerComposeService>()
|
|
|
181
224
|
(cause) =>
|
|
182
225
|
new DockerComposeError({
|
|
183
226
|
cause,
|
|
184
|
-
|
|
227
|
+
note: `Error reading Docker Compose logs in ${cwd}`,
|
|
185
228
|
}),
|
|
186
229
|
),
|
|
187
230
|
)
|
|
188
231
|
}).pipe(Stream.unwrapScoped)
|
|
189
232
|
|
|
190
|
-
|
|
233
|
+
const down = (options?: {
|
|
234
|
+
readonly env?: Record<string, string>
|
|
235
|
+
readonly volumes?: boolean
|
|
236
|
+
readonly removeOrphans?: boolean
|
|
237
|
+
}) =>
|
|
238
|
+
Effect.gen(function* () {
|
|
239
|
+
yield* Effect.log(`Tearing down Docker Compose services in ${cwd}`)
|
|
240
|
+
|
|
241
|
+
const baseArgs = ['docker', 'compose', 'down']
|
|
242
|
+
if (options?.volumes) baseArgs.push('-v')
|
|
243
|
+
if (options?.removeOrphans) baseArgs.push('--remove-orphans')
|
|
244
|
+
if (serviceName) baseArgs.push(serviceName)
|
|
245
|
+
|
|
246
|
+
yield* Command.make(baseArgs[0]!, ...baseArgs.slice(1)).pipe(
|
|
247
|
+
Command.workingDirectory(cwd),
|
|
248
|
+
Command.env(options?.env ?? {}),
|
|
249
|
+
Command.exitCode,
|
|
250
|
+
Effect.flatMap((exitCode: number) =>
|
|
251
|
+
exitCode === 0
|
|
252
|
+
? Effect.void
|
|
253
|
+
: Effect.fail(
|
|
254
|
+
new DockerComposeError({
|
|
255
|
+
cause: new Error(`Docker compose down exited with code ${exitCode}`),
|
|
256
|
+
note: `Failed to tear down Docker Compose services`,
|
|
257
|
+
}),
|
|
258
|
+
),
|
|
259
|
+
),
|
|
260
|
+
Effect.provide(commandExecutorContext),
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
yield* Effect.log(`Docker Compose services torn down successfully`)
|
|
264
|
+
}).pipe(Effect.withSpan('downDockerCompose'))
|
|
265
|
+
|
|
266
|
+
return { pull, start, stop, down, logs }
|
|
191
267
|
}),
|
|
192
268
|
}) {}
|
|
193
269
|
|
|
@@ -219,7 +295,7 @@ const performHealthCheck = ({
|
|
|
219
295
|
Effect.fail(
|
|
220
296
|
new DockerComposeError({
|
|
221
297
|
cause: new Error('Health check timeout'),
|
|
222
|
-
|
|
298
|
+
note: `Health check failed for ${url} after ${Duration.toMillis(timeout)}ms`,
|
|
223
299
|
}),
|
|
224
300
|
),
|
|
225
301
|
),
|
package/src/node/mod.ts
CHANGED
|
@@ -24,13 +24,6 @@ export {
|
|
|
24
24
|
startDockerComposeServicesScoped,
|
|
25
25
|
} from './DockerComposeService/DockerComposeService.ts'
|
|
26
26
|
export * as FileLogger from './FileLogger.ts'
|
|
27
|
-
export * from './WranglerDevServer/process-tree-manager.ts'
|
|
28
|
-
export {
|
|
29
|
-
type StartWranglerDevServerArgs,
|
|
30
|
-
type WranglerDevServer,
|
|
31
|
-
WranglerDevServerError,
|
|
32
|
-
WranglerDevServerService,
|
|
33
|
-
} from './WranglerDevServer/WranglerDevServer.ts'
|
|
34
27
|
|
|
35
28
|
export const OtelLiveHttp = ({
|
|
36
29
|
serviceName,
|
|
@@ -96,6 +96,17 @@ Vitest.describe('Vitest.asProp', () => {
|
|
|
96
96
|
|
|
97
97
|
return
|
|
98
98
|
}),
|
|
99
|
-
{
|
|
99
|
+
{
|
|
100
|
+
fastCheck: {
|
|
101
|
+
numRuns: 5,
|
|
102
|
+
endOnFailure: true,
|
|
103
|
+
// Provide explicit samples so the second run crosses >50. Randomly drawing five
|
|
104
|
+
// integers has ~3% chance to stay ≤ 50, which would break the `fails: true`
|
|
105
|
+
// expectation even though shrinking remains disabled. The examples keep the
|
|
106
|
+
// demo readable while leaving the remaining runs to FastCheck.
|
|
107
|
+
examples: [[5], [66]],
|
|
108
|
+
},
|
|
109
|
+
fails: true,
|
|
110
|
+
},
|
|
100
111
|
)
|
|
101
112
|
})
|
|
@@ -20,25 +20,29 @@ export * from '@effect/vitest'
|
|
|
20
20
|
|
|
21
21
|
export const DEBUGGER_ACTIVE = Boolean(process.env.DEBUGGER_ACTIVE ?? inspector.url() !== undefined)
|
|
22
22
|
|
|
23
|
-
export const makeWithTestCtx: <
|
|
24
|
-
ctxParams: WithTestCtxParams<
|
|
25
|
-
) => (
|
|
26
|
-
|
|
27
|
-
) => <
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
export const makeWithTestCtx: <ROut = never, E1 = never, RIn = never>(
|
|
24
|
+
ctxParams: WithTestCtxParams<ROut, E1, RIn>,
|
|
25
|
+
) => (testContext: Vitest.TestContext) => <A, E, R>(
|
|
26
|
+
self: Effect.Effect<A, E, R>,
|
|
27
|
+
) => Effect.Effect<
|
|
28
|
+
A,
|
|
29
|
+
E | E1 | Cause.TimeoutException,
|
|
30
|
+
// Exclude dependencies provided by `withTestCtx` from the layer dependencies
|
|
31
|
+
| Exclude<RIn, OtelTracer.OtelTracer | Scope.Scope>
|
|
32
|
+
// Exclude dependencies provided by `withTestCtx` **and** dependencies produced
|
|
33
|
+
// by the layer from the effect dependencies
|
|
34
|
+
| Exclude<R, ROut | OtelTracer.OtelTracer | Scope.Scope>
|
|
35
|
+
> = (ctxParams) => (testContext: Vitest.TestContext) => withTestCtx(testContext, ctxParams)
|
|
36
|
+
|
|
37
|
+
export type WithTestCtxParams<ROut, E1, RIn> = {
|
|
34
38
|
suffix?: string
|
|
35
|
-
makeLayer?: (testContext: Vitest.TestContext) => Layer.Layer<
|
|
39
|
+
makeLayer?: (testContext: Vitest.TestContext) => Layer.Layer<ROut, E1, RIn | Scope.Scope>
|
|
36
40
|
timeout?: Duration.DurationInput
|
|
37
41
|
forceOtel?: boolean
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
export const withTestCtx =
|
|
41
|
-
<
|
|
45
|
+
<ROut = never, E1 = never, RIn = never>(
|
|
42
46
|
testContext: Vitest.TestContext,
|
|
43
47
|
{
|
|
44
48
|
suffix,
|
|
@@ -47,23 +51,31 @@ export const withTestCtx =
|
|
|
47
51
|
forceOtel = false,
|
|
48
52
|
}: {
|
|
49
53
|
suffix?: string
|
|
50
|
-
makeLayer?: (testContext: Vitest.TestContext) => Layer.Layer<
|
|
54
|
+
makeLayer?: (testContext: Vitest.TestContext) => Layer.Layer<ROut, E1, RIn>
|
|
51
55
|
timeout?: Duration.DurationInput
|
|
52
56
|
forceOtel?: boolean
|
|
53
57
|
} = {},
|
|
54
58
|
) =>
|
|
55
|
-
<A, E>(
|
|
56
|
-
self: Effect.Effect<A, E,
|
|
57
|
-
): Effect.Effect<
|
|
59
|
+
<A, E, R>(
|
|
60
|
+
self: Effect.Effect<A, E, R>,
|
|
61
|
+
): Effect.Effect<
|
|
62
|
+
A,
|
|
63
|
+
E | E1 | Cause.TimeoutException,
|
|
64
|
+
// Exclude dependencies provided internally from the provided layer's dependencies
|
|
65
|
+
| Exclude<RIn, OtelTracer.OtelTracer | Scope.Scope>
|
|
66
|
+
// Exclude dependencies provided internally **and** dependencies produced by the
|
|
67
|
+
// provided layer from the effect dependencies
|
|
68
|
+
| Exclude<R, ROut | OtelTracer.OtelTracer | Scope.Scope>
|
|
69
|
+
> => {
|
|
58
70
|
const spanName = `${testContext.task.suite?.name}:${testContext.task.name}${suffix ? `:${suffix}` : ''}`
|
|
59
|
-
const layer = makeLayer?.(testContext)
|
|
71
|
+
const layer = makeLayer?.(testContext) ?? Layer.empty
|
|
60
72
|
|
|
61
73
|
const otelLayer =
|
|
62
74
|
DEBUGGER_ACTIVE || forceOtel
|
|
63
75
|
? OtelLiveHttp({ rootSpanName: spanName, serviceName: 'vitest-runner', skipLogUrl: false })
|
|
64
76
|
: OtelLiveDummy
|
|
65
77
|
|
|
66
|
-
const combinedLayer =
|
|
78
|
+
const combinedLayer = layer.pipe(Layer.provideMerge(otelLayer))
|
|
67
79
|
|
|
68
80
|
return self.pipe(
|
|
69
81
|
DEBUGGER_ACTIVE
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Effect, FetchHttpClient, Layer } from '@livestore/utils/effect'
|
|
2
|
+
import { getFreePort, PlatformNode } from '@livestore/utils/node'
|
|
3
|
+
import { Vitest } from '@livestore/utils-dev/node-vitest'
|
|
4
|
+
import { expect } from 'vitest'
|
|
5
|
+
import {
|
|
6
|
+
type StartWranglerDevServerArgs,
|
|
7
|
+
WranglerDevServerError,
|
|
8
|
+
WranglerDevServerService,
|
|
9
|
+
} from './WranglerDevServer.ts'
|
|
10
|
+
|
|
11
|
+
const testTimeout = 60_000
|
|
12
|
+
|
|
13
|
+
const WranglerDevServerTest = (args: Partial<StartWranglerDevServerArgs> = {}) =>
|
|
14
|
+
WranglerDevServerService.Default({
|
|
15
|
+
cwd: `${import.meta.dirname}/fixtures`,
|
|
16
|
+
...args,
|
|
17
|
+
}).pipe(Layer.provide(FetchHttpClient.layer))
|
|
18
|
+
|
|
19
|
+
Vitest.describe('WranglerDevServer', { timeout: testTimeout }, () => {
|
|
20
|
+
Vitest.describe('Basic Operations', () => {
|
|
21
|
+
const withBasicTest = (args: Partial<StartWranglerDevServerArgs> = {}) =>
|
|
22
|
+
Vitest.makeWithTestCtx({
|
|
23
|
+
timeout: testTimeout,
|
|
24
|
+
makeLayer: () => WranglerDevServerTest(args).pipe(Layer.provide(PlatformNode.NodeContext.layer)),
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
Vitest.scopedLive('should start wrangler dev server and return port', (test) =>
|
|
28
|
+
Effect.gen(function* () {
|
|
29
|
+
const server = yield* WranglerDevServerService
|
|
30
|
+
|
|
31
|
+
expect(server.port).toBeGreaterThan(0)
|
|
32
|
+
expect(server.url).toMatch(/http:\/\/127.0.0.1:\d+/)
|
|
33
|
+
}).pipe(withBasicTest()(test)),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
Vitest.scopedLive('should use specified port when provided', (test) =>
|
|
37
|
+
Effect.andThen(getFreePort, (port) =>
|
|
38
|
+
Effect.gen(function* () {
|
|
39
|
+
const server = yield* WranglerDevServerService
|
|
40
|
+
|
|
41
|
+
expect(server.port).toBe(port)
|
|
42
|
+
expect(server.url).toBe(`http://127.0.0.1:${port}`)
|
|
43
|
+
}).pipe(withBasicTest({ preferredPort: port })(test)),
|
|
44
|
+
),
|
|
45
|
+
)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
Vitest.describe('Error Handling', () => {
|
|
49
|
+
const withErrorTest = (args: Partial<StartWranglerDevServerArgs> = {}) =>
|
|
50
|
+
Vitest.makeWithTestCtx({
|
|
51
|
+
timeout: testTimeout,
|
|
52
|
+
makeLayer: () => WranglerDevServerTest(args).pipe(Layer.provide(PlatformNode.NodeContext.layer)),
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
Vitest.scopedLive('should handle missing wrangler.toml but should timeout', (test) =>
|
|
56
|
+
Effect.gen(function* () {
|
|
57
|
+
const error = yield* WranglerDevServerService.pipe(
|
|
58
|
+
Effect.provide(
|
|
59
|
+
WranglerDevServerTest({
|
|
60
|
+
cwd: '/tmp',
|
|
61
|
+
wranglerConfigPath: '/dev/null',
|
|
62
|
+
connectTimeout: '500 millis',
|
|
63
|
+
}).pipe(Layer.provide(PlatformNode.NodeContext.layer)),
|
|
64
|
+
),
|
|
65
|
+
Effect.flip,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
expect(error).toBeInstanceOf(WranglerDevServerError)
|
|
69
|
+
}).pipe(Vitest.withTestCtx(test)),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
Vitest.scopedLive('should handle invalid working directory', (test) =>
|
|
73
|
+
Effect.gen(function* () {
|
|
74
|
+
const result = yield* WranglerDevServerService.pipe(
|
|
75
|
+
Effect.provide(
|
|
76
|
+
WranglerDevServerTest({
|
|
77
|
+
cwd: '/completely/nonexistent/directory',
|
|
78
|
+
}).pipe(Layer.provide(PlatformNode.NodeContext.layer)),
|
|
79
|
+
),
|
|
80
|
+
Effect.either,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
expect(result._tag).toBe('Left')
|
|
84
|
+
if (result._tag === 'Left') {
|
|
85
|
+
expect(result.left).toBeInstanceOf(WranglerDevServerError)
|
|
86
|
+
}
|
|
87
|
+
}).pipe(Vitest.withTestCtx(test)),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
Vitest.scopedLive('should timeout if server fails to start', (test) =>
|
|
91
|
+
Effect.gen(function* () {
|
|
92
|
+
// Create a command that will never output "Ready on"
|
|
93
|
+
const result = yield* WranglerDevServerService.pipe(
|
|
94
|
+
// Override the timeout for this test to be shorter
|
|
95
|
+
Effect.timeout('5 seconds'),
|
|
96
|
+
Effect.either,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
// This might succeed or fail depending on actual wrangler behavior
|
|
100
|
+
// The main point is testing timeout functionality
|
|
101
|
+
expect(['Left', 'Right']).toContain(result._tag)
|
|
102
|
+
}).pipe(withErrorTest()(test)),
|
|
103
|
+
)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
Vitest.describe('Service Pattern', () => {
|
|
107
|
+
const withServiceTest = (args: Partial<StartWranglerDevServerArgs> = {}) =>
|
|
108
|
+
Vitest.makeWithTestCtx({
|
|
109
|
+
timeout: testTimeout,
|
|
110
|
+
makeLayer: () => WranglerDevServerTest(args).pipe(Layer.provide(PlatformNode.NodeContext.layer)),
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
Vitest.scopedLive('should work with service pattern', (test) =>
|
|
114
|
+
Effect.gen(function* () {
|
|
115
|
+
const server = yield* WranglerDevServerService
|
|
116
|
+
|
|
117
|
+
expect(server.port).toBeGreaterThan(0)
|
|
118
|
+
expect(server.url).toMatch(/http:\/\/127.0.0.1:\d+/)
|
|
119
|
+
}).pipe(withServiceTest()(test)),
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
Vitest.scopedLive('should work with custom port via service', (test) =>
|
|
123
|
+
Effect.andThen(getFreePort, (port) =>
|
|
124
|
+
Effect.gen(function* () {
|
|
125
|
+
const server = yield* WranglerDevServerService
|
|
126
|
+
|
|
127
|
+
expect(server.port).toBe(port)
|
|
128
|
+
expect(server.url).toBe(`http://127.0.0.1:${port}`)
|
|
129
|
+
}).pipe(withServiceTest({ preferredPort: port })(test)),
|
|
130
|
+
),
|
|
131
|
+
)
|
|
132
|
+
})
|
|
133
|
+
})
|