effect-start 0.25.0 → 0.26.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/package.json +18 -86
- package/dist/ChildProcess.js +0 -42
- package/dist/Commander.js +0 -410
- package/dist/ContentNegotiation.js +0 -465
- package/dist/Cookies.js +0 -371
- package/dist/Development.js +0 -94
- package/dist/Effectify.js +0 -27
- package/dist/Entity.js +0 -289
- package/dist/Fetch.js +0 -192
- package/dist/FilePathPattern.js +0 -97
- package/dist/FileRouter.js +0 -204
- package/dist/FileRouterCodegen.js +0 -298
- package/dist/FileSystem.js +0 -132
- package/dist/Http.js +0 -107
- package/dist/PathPattern.js +0 -451
- package/dist/PlatformError.js +0 -40
- package/dist/PlatformRuntime.js +0 -71
- package/dist/Route.js +0 -143
- package/dist/RouteBody.js +0 -92
- package/dist/RouteError.js +0 -76
- package/dist/RouteHook.js +0 -64
- package/dist/RouteHttp.js +0 -367
- package/dist/RouteHttpTracer.js +0 -90
- package/dist/RouteMount.js +0 -86
- package/dist/RouteSchema.js +0 -271
- package/dist/RouteSse.js +0 -94
- package/dist/RouteTree.js +0 -119
- package/dist/RouteTrie.js +0 -179
- package/dist/SchemaExtra.js +0 -99
- package/dist/Socket.js +0 -40
- package/dist/SqlIntrospect.js +0 -515
- package/dist/Start.js +0 -79
- package/dist/StartApp.js +0 -3
- package/dist/StreamExtra.js +0 -135
- package/dist/System.js +0 -38
- package/dist/TuplePathPattern.js +0 -74
- package/dist/Unique.js +0 -226
- package/dist/Values.js +0 -52
- package/dist/bun/BunBundle.js +0 -186
- package/dist/bun/BunChildProcessSpawner.js +0 -142
- package/dist/bun/BunImportTrackerPlugin.js +0 -91
- package/dist/bun/BunRoute.js +0 -157
- package/dist/bun/BunRuntime.js +0 -41
- package/dist/bun/BunServer.js +0 -285
- package/dist/bun/BunVirtualFilesPlugin.js +0 -54
- package/dist/bun/_BunEnhancedResolve.js +0 -127
- package/dist/bun/index.js +0 -5
- package/dist/bundler/Bundle.js +0 -92
- package/dist/bundler/BundleFiles.js +0 -154
- package/dist/bundler/BundleRoute.js +0 -62
- package/dist/client/Overlay.js +0 -33
- package/dist/client/ScrollState.js +0 -106
- package/dist/client/index.js +0 -97
- package/dist/console/Console.js +0 -42
- package/dist/console/ConsoleErrors.js +0 -211
- package/dist/console/ConsoleLogger.js +0 -56
- package/dist/console/ConsoleMetrics.js +0 -72
- package/dist/console/ConsoleProcess.js +0 -59
- package/dist/console/ConsoleStore.js +0 -72
- package/dist/console/ConsoleTracer.js +0 -107
- package/dist/console/Simulation.js +0 -784
- package/dist/console/index.js +0 -3
- package/dist/console/routes/tree.js +0 -30
- package/dist/datastar/actions/fetch.js +0 -536
- package/dist/datastar/actions/peek.js +0 -13
- package/dist/datastar/actions/setAll.js +0 -19
- package/dist/datastar/actions/toggleAll.js +0 -19
- package/dist/datastar/attributes/attr.js +0 -49
- package/dist/datastar/attributes/bind.js +0 -194
- package/dist/datastar/attributes/class.js +0 -54
- package/dist/datastar/attributes/computed.js +0 -25
- package/dist/datastar/attributes/effect.js +0 -10
- package/dist/datastar/attributes/indicator.js +0 -33
- package/dist/datastar/attributes/init.js +0 -27
- package/dist/datastar/attributes/jsonSignals.js +0 -33
- package/dist/datastar/attributes/on.js +0 -81
- package/dist/datastar/attributes/onIntersect.js +0 -53
- package/dist/datastar/attributes/onInterval.js +0 -31
- package/dist/datastar/attributes/onSignalPatch.js +0 -51
- package/dist/datastar/attributes/ref.js +0 -11
- package/dist/datastar/attributes/show.js +0 -32
- package/dist/datastar/attributes/signals.js +0 -18
- package/dist/datastar/attributes/style.js +0 -57
- package/dist/datastar/attributes/text.js +0 -29
- package/dist/datastar/engine.js +0 -1145
- package/dist/datastar/index.js +0 -25
- package/dist/datastar/utils.js +0 -250
- package/dist/datastar/watchers/patchElements.js +0 -486
- package/dist/datastar/watchers/patchSignals.js +0 -14
- package/dist/experimental/EncryptedCookies.js +0 -328
- package/dist/experimental/index.js +0 -1
- package/dist/hyper/Hyper.js +0 -28
- package/dist/hyper/HyperHtml.js +0 -165
- package/dist/hyper/HyperNode.js +0 -13
- package/dist/hyper/HyperRoute.js +0 -45
- package/dist/hyper/html.js +0 -30
- package/dist/hyper/index.js +0 -5
- package/dist/hyper/jsx-runtime.js +0 -14
- package/dist/index.js +0 -8
- package/dist/node/NodeFileSystem.js +0 -675
- package/dist/node/NodeUtils.js +0 -23
- package/dist/sql/Sql.js +0 -8
- package/dist/sql/bun/index.js +0 -142
- package/dist/sql/index.js +0 -1
- package/dist/sql/libsql/index.js +0 -156
- package/dist/sql/mssql/docker.js +0 -110
- package/dist/sql/mssql/index.js +0 -194
- package/dist/testing/TestLogger.js +0 -42
- package/dist/testing/index.js +0 -2
- package/dist/testing/utils.js +0 -61
- package/dist/x/cloudflare/CloudflareTunnel.js +0 -63
- package/dist/x/cloudflare/index.js +0 -1
- package/dist/x/tailscale/TailscaleTunnel.js +0 -94
- package/dist/x/tailscale/index.js +0 -1
- package/dist/x/tailwind/TailwindPlugin.js +0 -294
- package/dist/x/tailwind/compile.js +0 -210
- package/dist/x/tailwind/plugin.js +0 -17
package/dist/sql/bun/index.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect"
|
|
2
|
-
import * as Exit from "effect/Exit"
|
|
3
|
-
import * as FiberRef from "effect/FiberRef"
|
|
4
|
-
import * as GlobalValue from "effect/GlobalValue"
|
|
5
|
-
import * as Layer from "effect/Layer"
|
|
6
|
-
import * as Option from "effect/Option"
|
|
7
|
-
import * as Sql from "../Sql.js"
|
|
8
|
-
|
|
9
|
-
const errorCode = (error) => {
|
|
10
|
-
const e = error
|
|
11
|
-
if (typeof e?.errno === "string") return e.errno
|
|
12
|
-
return e?.code ?? "UNKNOWN"
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const wrapError = (error) =>
|
|
16
|
-
new Sql.SqlError({
|
|
17
|
-
code: errorCode(error),
|
|
18
|
-
message: error instanceof Error ? error.message : String(error),
|
|
19
|
-
cause: error,
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const wrap = (fn) =>
|
|
23
|
-
Effect.tryPromise({ try: () => Promise.resolve(fn()), catch: wrapError })
|
|
24
|
-
|
|
25
|
-
const makeValues = (obj, ...columns) => {
|
|
26
|
-
const items = Array.isArray(obj) ? obj : [obj]
|
|
27
|
-
const cols = columns.length > 0 ? columns : Object.keys(items[0])
|
|
28
|
-
return { value: items, columns: cols }
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const currentTransaction = GlobalValue.globalValue(
|
|
32
|
-
Symbol.for("effect-start/sql/bun/currentTransaction"),
|
|
33
|
-
() => FiberRef.unsafeMake(Option.none()),
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
const makeRun =
|
|
37
|
-
(bunSql) =>
|
|
38
|
-
(fn) =>
|
|
39
|
-
Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) =>
|
|
40
|
-
wrap(() => fn(Option.isSome(txOpt) ? txOpt.value.conn : bunSql)),
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
const makeWithTransaction =
|
|
44
|
-
(bunSql) =>
|
|
45
|
-
(self) =>
|
|
46
|
-
Effect.uninterruptibleMask((restore) =>
|
|
47
|
-
Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) => {
|
|
48
|
-
if (Option.isSome(txOpt)) {
|
|
49
|
-
const { conn, depth } = txOpt.value
|
|
50
|
-
const name = `sp_${depth}`
|
|
51
|
-
return Effect.gen(function* () {
|
|
52
|
-
yield* wrap(() => conn.unsafe(`SAVEPOINT ${name}`))
|
|
53
|
-
const exit = yield* Effect.exit(
|
|
54
|
-
restore(
|
|
55
|
-
Effect.locally(self, currentTransaction, Option.some({ conn, depth: depth + 1 })),
|
|
56
|
-
),
|
|
57
|
-
)
|
|
58
|
-
if (Exit.isSuccess(exit)) {
|
|
59
|
-
yield* wrap(() => conn.unsafe(`RELEASE SAVEPOINT ${name}`))
|
|
60
|
-
return exit.value
|
|
61
|
-
}
|
|
62
|
-
yield* wrap(() => conn.unsafe(`ROLLBACK TO SAVEPOINT ${name}`)).pipe(Effect.orDie)
|
|
63
|
-
return yield* exit
|
|
64
|
-
})
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const runTx = (conn) =>
|
|
68
|
-
Effect.gen(function* () {
|
|
69
|
-
yield* wrap(() => conn.unsafe("BEGIN"))
|
|
70
|
-
const exit = yield* Effect.exit(
|
|
71
|
-
restore(Effect.locally(self, currentTransaction, Option.some({ conn, depth: 1 }))),
|
|
72
|
-
)
|
|
73
|
-
if (Exit.isSuccess(exit)) {
|
|
74
|
-
yield* wrap(() => conn.unsafe("COMMIT"))
|
|
75
|
-
return exit.value
|
|
76
|
-
}
|
|
77
|
-
yield* wrap(() => conn.unsafe("ROLLBACK")).pipe(Effect.orDie)
|
|
78
|
-
return yield* exit
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
return Effect.matchEffect(
|
|
82
|
-
wrap(() => bunSql.reserve()),
|
|
83
|
-
{
|
|
84
|
-
onFailure: () => runTx(bunSql),
|
|
85
|
-
onSuccess: (reserved) =>
|
|
86
|
-
Effect.ensuring(
|
|
87
|
-
runTx(reserved),
|
|
88
|
-
Effect.sync(() => reserved.release()),
|
|
89
|
-
),
|
|
90
|
-
},
|
|
91
|
-
)
|
|
92
|
-
}),
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
export const layer = (
|
|
96
|
-
config,
|
|
97
|
-
) =>
|
|
98
|
-
Layer.scoped(
|
|
99
|
-
Sql.SqlClient,
|
|
100
|
-
Effect.acquireRelease(
|
|
101
|
-
Effect.try({
|
|
102
|
-
try: () => {
|
|
103
|
-
const bunSql = new Bun.SQL(config)
|
|
104
|
-
const run = makeRun(bunSql)
|
|
105
|
-
const use = (fn) =>
|
|
106
|
-
Effect.tryPromise({ try: () => Promise.resolve(fn(bunSql)), catch: wrapError })
|
|
107
|
-
return Object.assign(
|
|
108
|
-
(strings, ...values) =>
|
|
109
|
-
run((conn) => conn(strings, ...values)),
|
|
110
|
-
{
|
|
111
|
-
unsafe: (query, values) =>
|
|
112
|
-
run((conn) => conn.unsafe(query, values)),
|
|
113
|
-
values: makeValues,
|
|
114
|
-
withTransaction: makeWithTransaction(bunSql),
|
|
115
|
-
reserve: Effect.acquireRelease(
|
|
116
|
-
wrap(() => bunSql.reserve()),
|
|
117
|
-
(reserved) => Effect.sync(() => reserved.release()),
|
|
118
|
-
).pipe(
|
|
119
|
-
Effect.map(
|
|
120
|
-
(reserved) =>
|
|
121
|
-
Object.assign(
|
|
122
|
-
(strings, ...values) =>
|
|
123
|
-
wrap(() => reserved(strings, ...values)),
|
|
124
|
-
{
|
|
125
|
-
unsafe: (query, values) =>
|
|
126
|
-
wrap(() => reserved.unsafe(query, values)),
|
|
127
|
-
values: makeValues,
|
|
128
|
-
},
|
|
129
|
-
),
|
|
130
|
-
),
|
|
131
|
-
),
|
|
132
|
-
close: (options) =>
|
|
133
|
-
use((bunSql) => bunSql.close(options)),
|
|
134
|
-
use,
|
|
135
|
-
},
|
|
136
|
-
)
|
|
137
|
-
},
|
|
138
|
-
catch: wrapError,
|
|
139
|
-
}),
|
|
140
|
-
(client) => client.close().pipe(Effect.orDie),
|
|
141
|
-
),
|
|
142
|
-
)
|
package/dist/sql/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * as Sql from "./Sql.js"
|
package/dist/sql/libsql/index.js
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect"
|
|
2
|
-
import * as Exit from "effect/Exit"
|
|
3
|
-
import * as FiberRef from "effect/FiberRef"
|
|
4
|
-
import * as GlobalValue from "effect/GlobalValue"
|
|
5
|
-
import * as Layer from "effect/Layer"
|
|
6
|
-
import * as Option from "effect/Option"
|
|
7
|
-
import * as Sql from "../Sql.js"
|
|
8
|
-
|
|
9
|
-
const wrapError = (error) =>
|
|
10
|
-
new Sql.SqlError({
|
|
11
|
-
code: (error)?.code ?? "UNKNOWN",
|
|
12
|
-
message: error instanceof Error ? error.message : String(error),
|
|
13
|
-
cause: error,
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
const wrap = (fn) =>
|
|
17
|
-
Effect.tryPromise({ try: () => Promise.resolve(fn()), catch: wrapError })
|
|
18
|
-
|
|
19
|
-
const makeValues = (obj, ...columns) => {
|
|
20
|
-
const items = Array.isArray(obj) ? obj : [obj]
|
|
21
|
-
const cols = columns.length > 0 ? columns : Object.keys(items[0])
|
|
22
|
-
return { value: items, columns: cols }
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const resultSetToRows = (result) => {
|
|
26
|
-
const { columns, rows } = result
|
|
27
|
-
return rows.map((row) => {
|
|
28
|
-
const obj = {}
|
|
29
|
-
for (let i = 0; i < columns.length; i++) obj[columns[i]] = row[i]
|
|
30
|
-
return obj
|
|
31
|
-
})
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const buildQuery = (strings, values) => {
|
|
35
|
-
let sql = strings[0]
|
|
36
|
-
for (let i = 0; i < values.length; i++) sql += "?" + strings[i + 1]
|
|
37
|
-
return { sql, args: values }
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const loadLibsql = () => import("@libsql/client")
|
|
41
|
-
|
|
42
|
-
const currentTransaction = GlobalValue.globalValue(
|
|
43
|
-
Symbol.for("effect-start/sql/libsql/currentTransaction"),
|
|
44
|
-
() => FiberRef.unsafeMake(Option.none()),
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
const executeQuery = (
|
|
48
|
-
client,
|
|
49
|
-
sql,
|
|
50
|
-
args,
|
|
51
|
-
) =>
|
|
52
|
-
wrap(() => client.execute({ sql, args })).pipe(Effect.map(resultSetToRows<T>))
|
|
53
|
-
|
|
54
|
-
const runQuery = (
|
|
55
|
-
client,
|
|
56
|
-
strings,
|
|
57
|
-
values,
|
|
58
|
-
) => {
|
|
59
|
-
const { sql, args } = buildQuery(strings, values)
|
|
60
|
-
return executeQuery(client, sql, args)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const runUnsafe = (
|
|
64
|
-
client,
|
|
65
|
-
query,
|
|
66
|
-
values,
|
|
67
|
-
) =>
|
|
68
|
-
executeQuery(client, query, values ?? [])
|
|
69
|
-
|
|
70
|
-
const exec = (client, sql) =>
|
|
71
|
-
wrap(() => client.execute(sql))
|
|
72
|
-
|
|
73
|
-
const makeWithTransaction =
|
|
74
|
-
(client) =>
|
|
75
|
-
(self) =>
|
|
76
|
-
Effect.uninterruptibleMask((restore) =>
|
|
77
|
-
Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) => {
|
|
78
|
-
if (Option.isSome(txOpt)) {
|
|
79
|
-
const { depth } = txOpt.value
|
|
80
|
-
const name = `sp_${depth}`
|
|
81
|
-
return Effect.gen(function* () {
|
|
82
|
-
yield* exec(client, `SAVEPOINT ${name}`)
|
|
83
|
-
const exit = yield* Effect.exit(
|
|
84
|
-
restore(
|
|
85
|
-
Effect.locally(self, currentTransaction, Option.some({ depth: depth + 1 })),
|
|
86
|
-
),
|
|
87
|
-
)
|
|
88
|
-
if (Exit.isSuccess(exit)) {
|
|
89
|
-
yield* exec(client, `RELEASE SAVEPOINT ${name}`)
|
|
90
|
-
return exit.value
|
|
91
|
-
}
|
|
92
|
-
yield* exec(client, `ROLLBACK TO SAVEPOINT ${name}`).pipe(Effect.orDie)
|
|
93
|
-
return yield* exit
|
|
94
|
-
})
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return Effect.gen(function* () {
|
|
98
|
-
yield* exec(client, "BEGIN")
|
|
99
|
-
const exit = yield* Effect.exit(
|
|
100
|
-
restore(Effect.locally(self, currentTransaction, Option.some({ depth: 1 }))),
|
|
101
|
-
)
|
|
102
|
-
if (Exit.isSuccess(exit)) {
|
|
103
|
-
yield* exec(client, "COMMIT")
|
|
104
|
-
return exit.value
|
|
105
|
-
}
|
|
106
|
-
yield* exec(client, "ROLLBACK").pipe(Effect.orDie)
|
|
107
|
-
return yield* exit
|
|
108
|
-
})
|
|
109
|
-
}),
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
export const layer = (config) =>
|
|
113
|
-
Layer.scoped(
|
|
114
|
-
Sql.SqlClient,
|
|
115
|
-
Effect.acquireRelease(
|
|
116
|
-
wrap(() => loadLibsql()).pipe(
|
|
117
|
-
Effect.map((libsql) => {
|
|
118
|
-
const client = libsql.createClient(config)
|
|
119
|
-
const use = (fn) =>
|
|
120
|
-
Effect.tryPromise({ try: () => Promise.resolve(fn(client)), catch: wrapError })
|
|
121
|
-
return Object.assign(
|
|
122
|
-
(strings, ...values) =>
|
|
123
|
-
runQuery(client, strings, values),
|
|
124
|
-
{
|
|
125
|
-
unsafe: (query, values) =>
|
|
126
|
-
runUnsafe(client, query, values),
|
|
127
|
-
values: makeValues,
|
|
128
|
-
withTransaction: makeWithTransaction(client),
|
|
129
|
-
reserve: Effect.acquireRelease(
|
|
130
|
-
wrap(() => loadLibsql()).pipe(
|
|
131
|
-
Effect.map((m) => m.createClient(config)),
|
|
132
|
-
),
|
|
133
|
-
(reserved) => Effect.sync(() => reserved.close()),
|
|
134
|
-
).pipe(
|
|
135
|
-
Effect.map(
|
|
136
|
-
(reserved) =>
|
|
137
|
-
Object.assign(
|
|
138
|
-
(strings, ...values) =>
|
|
139
|
-
runQuery(reserved, strings, values),
|
|
140
|
-
{
|
|
141
|
-
unsafe: (query, values) =>
|
|
142
|
-
runUnsafe(reserved, query, values),
|
|
143
|
-
values: makeValues,
|
|
144
|
-
},
|
|
145
|
-
),
|
|
146
|
-
),
|
|
147
|
-
),
|
|
148
|
-
close: () => Effect.sync(() => client.close()),
|
|
149
|
-
use,
|
|
150
|
-
},
|
|
151
|
-
)
|
|
152
|
-
}),
|
|
153
|
-
),
|
|
154
|
-
(client) => client.close().pipe(Effect.orDie),
|
|
155
|
-
),
|
|
156
|
-
)
|
package/dist/sql/mssql/docker.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect"
|
|
2
|
-
import * as Stream from "effect/Stream"
|
|
3
|
-
|
|
4
|
-
import * as System from "../../System.js"
|
|
5
|
-
import * as BunChildProcessSpawner from "../../bun/BunChildProcessSpawner.js"
|
|
6
|
-
|
|
7
|
-
const PORT = 1433
|
|
8
|
-
const PASSWORD = "TestPass123"
|
|
9
|
-
const CONTAINER = "effect-start-mssql"
|
|
10
|
-
|
|
11
|
-
const exec = (
|
|
12
|
-
...args
|
|
13
|
-
) =>
|
|
14
|
-
Effect.scoped(
|
|
15
|
-
Effect.gen(function* () {
|
|
16
|
-
const handle = yield* System.spawn("docker", args, {
|
|
17
|
-
stdout: "ignore",
|
|
18
|
-
stderr: "inherit",
|
|
19
|
-
})
|
|
20
|
-
return yield* handle.exitCode
|
|
21
|
-
}),
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
const execStdout = (
|
|
25
|
-
...args
|
|
26
|
-
) =>
|
|
27
|
-
Effect.scoped(
|
|
28
|
-
Effect.gen(function* () {
|
|
29
|
-
const handle = yield* System.spawn("docker", args, {
|
|
30
|
-
stdout: "pipe",
|
|
31
|
-
stderr: "inherit",
|
|
32
|
-
})
|
|
33
|
-
const [stdout] = yield* Effect.all(
|
|
34
|
-
[handle.stdout.pipe(Stream.decodeText("utf-8"), Stream.mkString), handle.exitCode],
|
|
35
|
-
{ concurrency: 2 },
|
|
36
|
-
)
|
|
37
|
-
return stdout
|
|
38
|
-
}),
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
const containerRunning = execStdout("ps", "-q", "-f", `name=${CONTAINER}`).pipe(
|
|
42
|
-
Effect.map((stdout) => stdout.trim().length > 0),
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
const removeContainer = exec("rm", "-f", CONTAINER).pipe(Effect.ignore)
|
|
46
|
-
|
|
47
|
-
const loadMssql = () => import("mssql")
|
|
48
|
-
|
|
49
|
-
const canConnect = Effect.tryPromise({
|
|
50
|
-
try: async () => {
|
|
51
|
-
const { ConnectionPool } = await loadMssql()
|
|
52
|
-
const pool = new ConnectionPool({
|
|
53
|
-
server: "localhost",
|
|
54
|
-
user: "sa",
|
|
55
|
-
password: PASSWORD,
|
|
56
|
-
port: PORT,
|
|
57
|
-
options: { encrypt: true, trustServerCertificate: true, connectTimeout: 3000 },
|
|
58
|
-
})
|
|
59
|
-
await pool.connect()
|
|
60
|
-
await pool.close()
|
|
61
|
-
return true
|
|
62
|
-
},
|
|
63
|
-
catch: () => /** @type {const} */ false,
|
|
64
|
-
}).pipe(Effect.orElseSucceed(() => false))
|
|
65
|
-
|
|
66
|
-
const waitReady = Effect.gen(function* () {
|
|
67
|
-
const deadline = Date.now() + 60_000
|
|
68
|
-
while (Date.now() < deadline) {
|
|
69
|
-
if (yield* canConnect) return
|
|
70
|
-
yield* Effect.sleep("2 seconds")
|
|
71
|
-
}
|
|
72
|
-
return yield* Effect.fail(new Error("Timed out waiting for MSSQL"))
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
const program = Effect.gen(function* () {
|
|
76
|
-
if (yield* containerRunning) {
|
|
77
|
-
yield* Effect.log("MSSQL container already running")
|
|
78
|
-
return
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
yield* removeContainer
|
|
82
|
-
|
|
83
|
-
yield* Effect.log("Starting MSSQL container...")
|
|
84
|
-
const code = yield* exec(
|
|
85
|
-
"run",
|
|
86
|
-
"-d",
|
|
87
|
-
"--name",
|
|
88
|
-
CONTAINER,
|
|
89
|
-
"-p",
|
|
90
|
-
`${PORT}:1433`,
|
|
91
|
-
"-e",
|
|
92
|
-
"ACCEPT_EULA=Y",
|
|
93
|
-
"-e",
|
|
94
|
-
`MSSQL_SA_PASSWORD=${PASSWORD}`,
|
|
95
|
-
"mcr.microsoft.com/azure-sql-edge",
|
|
96
|
-
)
|
|
97
|
-
if (code !== 0) {
|
|
98
|
-
return yield* Effect.fail(new Error(`docker run exited with code ${code}`))
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
yield* waitReady
|
|
102
|
-
yield* Effect.log("MSSQL ready")
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
const run = (effect) =>
|
|
106
|
-
Effect.runPromise(Effect.provide(effect, BunChildProcessSpawner.layer))
|
|
107
|
-
|
|
108
|
-
export const start = () => run(program)
|
|
109
|
-
|
|
110
|
-
export const stop = () => run(removeContainer)
|
package/dist/sql/mssql/index.js
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect"
|
|
2
|
-
import * as Exit from "effect/Exit"
|
|
3
|
-
import * as FiberRef from "effect/FiberRef"
|
|
4
|
-
import * as GlobalValue from "effect/GlobalValue"
|
|
5
|
-
import * as Layer from "effect/Layer"
|
|
6
|
-
import * as Option from "effect/Option"
|
|
7
|
-
import * as Sql from "../Sql.js"
|
|
8
|
-
|
|
9
|
-
const wrapError = (error) =>
|
|
10
|
-
new Sql.SqlError({
|
|
11
|
-
code:
|
|
12
|
-
(error)?.code ??
|
|
13
|
-
((error)?.number != null ? String((error).number) : "UNKNOWN"),
|
|
14
|
-
message: error instanceof Error ? error.message : String(error),
|
|
15
|
-
cause: error,
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
const makeValues = (obj, ...columns) => {
|
|
19
|
-
const items = Array.isArray(obj) ? obj : [obj]
|
|
20
|
-
const cols = columns.length > 0 ? columns : Object.keys(items[0])
|
|
21
|
-
return { value: items, columns: cols }
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const buildQuery = (strings, values) => {
|
|
25
|
-
let text = strings[0]
|
|
26
|
-
for (let i = 0; i < values.length; i++) text += `@p${i + 1}` + strings[i + 1]
|
|
27
|
-
return { text, values }
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const addInputs = (request, values) => {
|
|
31
|
-
for (let i = 0; i < values.length; i++) {
|
|
32
|
-
request.input(`p${i + 1}`, values[i])
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const loadMssql = () => import("mssql")
|
|
37
|
-
|
|
38
|
-
const currentTransaction = GlobalValue.globalValue(
|
|
39
|
-
Symbol.for("effect-start/sql/mssql/currentTransaction"),
|
|
40
|
-
() => FiberRef.unsafeMake(Option.none()),
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
const executeQuery = (
|
|
44
|
-
pool,
|
|
45
|
-
text,
|
|
46
|
-
values,
|
|
47
|
-
) =>
|
|
48
|
-
Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) => {
|
|
49
|
-
const request = Option.isSome(txOpt) ? txOpt.value.transaction.request() : pool.request()
|
|
50
|
-
addInputs(request, values)
|
|
51
|
-
return Effect.tryPromise({
|
|
52
|
-
try: () => request.query(text),
|
|
53
|
-
catch: wrapError,
|
|
54
|
-
}).pipe(Effect.map((result) => result.recordset ?? []))
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
const runQuery = (
|
|
58
|
-
pool,
|
|
59
|
-
strings,
|
|
60
|
-
values,
|
|
61
|
-
) => {
|
|
62
|
-
const { text, values: params } = buildQuery(strings, values)
|
|
63
|
-
return executeQuery(pool, text, params)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const runUnsafe = (
|
|
67
|
-
pool,
|
|
68
|
-
query,
|
|
69
|
-
values,
|
|
70
|
-
) =>
|
|
71
|
-
Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) => {
|
|
72
|
-
const request = Option.isSome(txOpt) ? txOpt.value.transaction.request() : pool.request()
|
|
73
|
-
if (values) addInputs(request, values)
|
|
74
|
-
return Effect.tryPromise({
|
|
75
|
-
try: () => request.query(query),
|
|
76
|
-
catch: wrapError,
|
|
77
|
-
}).pipe(Effect.map((result) => result.recordset ?? []))
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
const makeWithTransaction =
|
|
81
|
-
(pool) =>
|
|
82
|
-
(self) =>
|
|
83
|
-
Effect.uninterruptibleMask((restore) =>
|
|
84
|
-
Effect.flatMap(FiberRef.get(currentTransaction), (txOpt) => {
|
|
85
|
-
if (Option.isSome(txOpt)) {
|
|
86
|
-
const { transaction, depth } = txOpt.value
|
|
87
|
-
const name = `sp_${depth}`
|
|
88
|
-
return Effect.gen(function* () {
|
|
89
|
-
const req = transaction.request()
|
|
90
|
-
yield* Effect.tryPromise({
|
|
91
|
-
try: () => req.query(`SAVE TRANSACTION ${name}`),
|
|
92
|
-
catch: wrapError,
|
|
93
|
-
})
|
|
94
|
-
const exit = yield* Effect.exit(
|
|
95
|
-
restore(
|
|
96
|
-
Effect.locally(
|
|
97
|
-
self,
|
|
98
|
-
currentTransaction,
|
|
99
|
-
Option.some({ transaction, depth: depth + 1 }),
|
|
100
|
-
),
|
|
101
|
-
),
|
|
102
|
-
)
|
|
103
|
-
if (Exit.isSuccess(exit)) {
|
|
104
|
-
return exit.value
|
|
105
|
-
}
|
|
106
|
-
const rbReq = transaction.request()
|
|
107
|
-
yield* Effect.tryPromise({
|
|
108
|
-
try: () => rbReq.query(`ROLLBACK TRANSACTION ${name}`),
|
|
109
|
-
catch: wrapError,
|
|
110
|
-
}).pipe(Effect.orDie)
|
|
111
|
-
return yield* exit
|
|
112
|
-
})
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return Effect.gen(function* () {
|
|
116
|
-
const transaction = pool.transaction()
|
|
117
|
-
yield* Effect.tryPromise({ try: () => transaction.begin(), catch: wrapError })
|
|
118
|
-
const exit = yield* Effect.exit(
|
|
119
|
-
restore(
|
|
120
|
-
Effect.locally(self, currentTransaction, Option.some({ transaction, depth: 1 })),
|
|
121
|
-
),
|
|
122
|
-
)
|
|
123
|
-
if (Exit.isSuccess(exit)) {
|
|
124
|
-
yield* Effect.tryPromise({ try: () => transaction.commit(), catch: wrapError })
|
|
125
|
-
return exit.value
|
|
126
|
-
}
|
|
127
|
-
yield* Effect.tryPromise({ try: () => transaction.rollback(), catch: wrapError }).pipe(
|
|
128
|
-
Effect.orDie,
|
|
129
|
-
)
|
|
130
|
-
return yield* exit
|
|
131
|
-
})
|
|
132
|
-
}),
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
export const layer = (config) =>
|
|
136
|
-
Layer.scoped(
|
|
137
|
-
Sql.SqlClient,
|
|
138
|
-
Effect.acquireRelease(
|
|
139
|
-
Effect.tryPromise({
|
|
140
|
-
try: async () => {
|
|
141
|
-
const mssql = await loadMssql()
|
|
142
|
-
const pool = await new mssql.ConnectionPool(config).connect()
|
|
143
|
-
return { mssql, pool }
|
|
144
|
-
},
|
|
145
|
-
catch: wrapError,
|
|
146
|
-
}).pipe(
|
|
147
|
-
Effect.map(({ mssql, pool }) => {
|
|
148
|
-
const use = (fn) =>
|
|
149
|
-
Effect.tryPromise({ try: () => Promise.resolve(fn(pool)), catch: wrapError })
|
|
150
|
-
return Object.assign(
|
|
151
|
-
(strings, ...values) =>
|
|
152
|
-
runQuery(pool, strings, values),
|
|
153
|
-
{
|
|
154
|
-
unsafe: (query, values) =>
|
|
155
|
-
runUnsafe(pool, query, values),
|
|
156
|
-
values: makeValues,
|
|
157
|
-
withTransaction: makeWithTransaction(pool),
|
|
158
|
-
reserve: Effect.acquireRelease(
|
|
159
|
-
Effect.tryPromise({
|
|
160
|
-
try: () =>
|
|
161
|
-
new mssql.ConnectionPool({
|
|
162
|
-
...config,
|
|
163
|
-
pool: { max: 1, min: 1 },
|
|
164
|
-
}).connect(),
|
|
165
|
-
catch: wrapError,
|
|
166
|
-
}),
|
|
167
|
-
(reserved) =>
|
|
168
|
-
Effect.tryPromise({ try: () => reserved.close(), catch: () => void 0 }).pipe(
|
|
169
|
-
Effect.asVoid,
|
|
170
|
-
Effect.orDie,
|
|
171
|
-
),
|
|
172
|
-
).pipe(
|
|
173
|
-
Effect.map(
|
|
174
|
-
(reserved) =>
|
|
175
|
-
Object.assign(
|
|
176
|
-
(strings, ...values) =>
|
|
177
|
-
runQuery(reserved, strings, values),
|
|
178
|
-
{
|
|
179
|
-
unsafe: (query, values) =>
|
|
180
|
-
runUnsafe(reserved, query, values),
|
|
181
|
-
values: makeValues,
|
|
182
|
-
},
|
|
183
|
-
),
|
|
184
|
-
),
|
|
185
|
-
),
|
|
186
|
-
close: () => use((pool) => pool.close()),
|
|
187
|
-
use,
|
|
188
|
-
},
|
|
189
|
-
)
|
|
190
|
-
}),
|
|
191
|
-
),
|
|
192
|
-
(client) => client.close().pipe(Effect.orDie),
|
|
193
|
-
),
|
|
194
|
-
)
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import * as Cause from "effect/Cause"
|
|
2
|
-
import * as Context from "effect/Context"
|
|
3
|
-
import * as Effect from "effect/Effect"
|
|
4
|
-
import * as FiberRef from "effect/FiberRef"
|
|
5
|
-
import * as HashSet from "effect/HashSet"
|
|
6
|
-
import * as Layer from "effect/Layer"
|
|
7
|
-
import * as Logger from "effect/Logger"
|
|
8
|
-
import * as MutableRef from "effect/MutableRef"
|
|
9
|
-
import * as Ref from "effect/Ref"
|
|
10
|
-
|
|
11
|
-
export class TestLogger extends Context.Tag("effect-start/TestLogger")() {}
|
|
12
|
-
|
|
13
|
-
export function layer() {
|
|
14
|
-
return Layer.effect(
|
|
15
|
-
TestLogger,
|
|
16
|
-
Effect.gen(function* () {
|
|
17
|
-
const messages = yield* Ref.make([])
|
|
18
|
-
const mutableRef = (messages).ref
|
|
19
|
-
|
|
20
|
-
const customLogger = Logger.make(({ message, logLevel, cause }) => {
|
|
21
|
-
const causeStr = !Cause.isEmpty(cause)
|
|
22
|
-
? ` ${Cause.pretty(cause, { renderErrorCause: true })}`
|
|
23
|
-
: ""
|
|
24
|
-
MutableRef.update(mutableRef, (msgs) => [
|
|
25
|
-
...msgs,
|
|
26
|
-
`[${logLevel._tag}] ${String(message)}${causeStr}`,
|
|
27
|
-
])
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
yield* FiberRef.update(FiberRef.currentLoggers, (loggers) =>
|
|
31
|
-
HashSet.add(HashSet.remove(loggers, Logger.defaultLogger), customLogger),
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
return { messages }
|
|
35
|
-
}),
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export const messages = Effect.gen(function* () {
|
|
40
|
-
const logger = yield* TestLogger
|
|
41
|
-
return yield* Ref.get(logger.messages)
|
|
42
|
-
})
|
package/dist/testing/index.js
DELETED