effect 4.0.0-beta.98 → 4.0.0-beta.99
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 +1 -3
- package/dist/Array.js +1 -1
- package/dist/Array.js.map +1 -1
- package/dist/Graph.d.ts +1187 -196
- package/dist/Graph.d.ts.map +1 -1
- package/dist/Graph.js +1031 -283
- package/dist/Graph.js.map +1 -1
- package/dist/Iterable.d.ts.map +1 -1
- package/dist/Iterable.js +41 -1
- package/dist/Iterable.js.map +1 -1
- package/dist/Schema.js +1 -1
- package/dist/Schema.js.map +1 -1
- package/dist/internal/effect.js +9 -3
- package/dist/internal/effect.js.map +1 -1
- package/dist/unstable/ai/McpSchema.d.ts +128 -128
- package/dist/unstable/ai/McpSchema.d.ts.map +1 -1
- package/dist/unstable/ai/Tool.d.ts.map +1 -1
- package/dist/unstable/ai/Tool.js +11 -13
- package/dist/unstable/ai/Tool.js.map +1 -1
- package/dist/unstable/cli/CliConfig.d.ts +76 -0
- package/dist/unstable/cli/CliConfig.d.ts.map +1 -0
- package/dist/unstable/cli/CliConfig.js +63 -0
- package/dist/unstable/cli/CliConfig.js.map +1 -0
- package/dist/unstable/cli/CliError.d.ts.map +1 -1
- package/dist/unstable/cli/CliError.js +3 -0
- package/dist/unstable/cli/CliError.js.map +1 -1
- package/dist/unstable/cli/Command.d.ts +36 -1
- package/dist/unstable/cli/Command.d.ts.map +1 -1
- package/dist/unstable/cli/Command.js +61 -4
- package/dist/unstable/cli/Command.js.map +1 -1
- package/dist/unstable/cli/GlobalFlag.d.ts +23 -2
- package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/unstable/cli/GlobalFlag.js +20 -4
- package/dist/unstable/cli/GlobalFlag.js.map +1 -1
- package/dist/unstable/cli/Param.js +6 -2
- package/dist/unstable/cli/Param.js.map +1 -1
- package/dist/unstable/cli/index.d.ts +4 -0
- package/dist/unstable/cli/index.d.ts.map +1 -1
- package/dist/unstable/cli/index.js +4 -0
- package/dist/unstable/cli/index.js.map +1 -1
- package/dist/unstable/cli/internal/ansi.d.ts.map +1 -1
- package/dist/unstable/cli/internal/ansi.js +2 -0
- package/dist/unstable/cli/internal/ansi.js.map +1 -1
- package/dist/unstable/cli/internal/parser.js +11 -2
- package/dist/unstable/cli/internal/parser.js.map +1 -1
- package/dist/unstable/cli/internal/wizard.d.ts +13 -0
- package/dist/unstable/cli/internal/wizard.d.ts.map +1 -0
- package/dist/unstable/cli/internal/wizard.js +212 -0
- package/dist/unstable/cli/internal/wizard.js.map +1 -0
- package/dist/unstable/cluster/RunnerStorage.js +1 -1
- package/dist/unstable/cluster/RunnerStorage.js.map +1 -1
- package/dist/unstable/http/Multipart.d.ts.map +1 -1
- package/dist/unstable/http/Multipart.js +3 -1
- package/dist/unstable/http/Multipart.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
- package/dist/unstable/persistence/Redis.d.ts.map +1 -1
- package/dist/unstable/persistence/Redis.js +5 -3
- package/dist/unstable/persistence/Redis.js.map +1 -1
- package/dist/unstable/sql/SqlClient.d.ts +1 -2
- package/dist/unstable/sql/SqlClient.d.ts.map +1 -1
- package/dist/unstable/sql/SqlClient.js.map +1 -1
- package/package.json +3 -3
- package/src/Array.ts +1 -1
- package/src/Graph.ts +2967 -457
- package/src/Iterable.ts +32 -2
- package/src/Schema.ts +1 -1
- package/src/internal/effect.ts +9 -3
- package/src/unstable/ai/Tool.ts +13 -16
- package/src/unstable/cli/CliConfig.ts +85 -0
- package/src/unstable/cli/CliError.ts +3 -0
- package/src/unstable/cli/Command.ts +83 -7
- package/src/unstable/cli/GlobalFlag.ts +33 -5
- package/src/unstable/cli/Param.ts +15 -3
- package/src/unstable/cli/index.ts +5 -0
- package/src/unstable/cli/internal/ansi.ts +3 -0
- package/src/unstable/cli/internal/parser.ts +14 -2
- package/src/unstable/cli/internal/wizard.ts +283 -0
- package/src/unstable/cluster/RunnerStorage.ts +1 -1
- package/src/unstable/http/Multipart.ts +3 -1
- package/src/unstable/httpapi/HttpApiBuilder.ts +1 -1
- package/src/unstable/persistence/Redis.ts +9 -4
- package/src/unstable/sql/SqlClient.ts +1 -2
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import * as Console from "../../../Console.ts"
|
|
2
|
+
import * as Effect from "../../../Effect.ts"
|
|
3
|
+
import * as Option from "../../../Option.ts"
|
|
4
|
+
import * as Redacted from "../../../Redacted.ts"
|
|
5
|
+
import type * as Terminal from "../../../Terminal.ts"
|
|
6
|
+
import type * as CliError from "../CliError.ts"
|
|
7
|
+
import type * as Command from "../Command.ts"
|
|
8
|
+
import * as Param from "../Param.ts"
|
|
9
|
+
import * as Primitive from "../Primitive.ts"
|
|
10
|
+
import * as Prompt from "../Prompt.ts"
|
|
11
|
+
import * as Ansi from "./ansi.ts"
|
|
12
|
+
import { toImpl } from "./command.ts"
|
|
13
|
+
|
|
14
|
+
export interface Options {
|
|
15
|
+
readonly commandPath?: ReadonlyArray<string> | undefined
|
|
16
|
+
readonly prefix?: ReadonlyArray<string> | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const run: (
|
|
20
|
+
command: Command.Command.Any,
|
|
21
|
+
options?: Options
|
|
22
|
+
) => Effect.Effect<Array<string>, CliError.CliError | Terminal.QuitError, Command.Environment> = Effect.fnUntraced(
|
|
23
|
+
function*(command, options) {
|
|
24
|
+
const commandPath = options?.commandPath ?? [command.name]
|
|
25
|
+
const selected = getCommandAtPath(command, commandPath)
|
|
26
|
+
const commandLine = [...(options?.prefix ?? commandPath)]
|
|
27
|
+
yield* logCurrentCommand(commandLine)
|
|
28
|
+
yield* promptCommand(selected, commandLine, selected === command ? "ROOT" : selected.name)
|
|
29
|
+
return commandLine
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
const getCommandAtPath = (
|
|
34
|
+
command: Command.Command.Any,
|
|
35
|
+
commandPath: ReadonlyArray<string>
|
|
36
|
+
): Command.Command.Any => {
|
|
37
|
+
let current = command
|
|
38
|
+
for (const name of commandPath.slice(1)) {
|
|
39
|
+
const child = current.subcommands
|
|
40
|
+
.flatMap((group) => group.commands)
|
|
41
|
+
.find((candidate) => candidate.name === name || candidate.alias === name)
|
|
42
|
+
if (child === undefined) {
|
|
43
|
+
break
|
|
44
|
+
}
|
|
45
|
+
current = child
|
|
46
|
+
}
|
|
47
|
+
return current
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const promptCommand: (
|
|
51
|
+
command: Command.Command.Any,
|
|
52
|
+
commandLine: Array<string>,
|
|
53
|
+
sectionName: string
|
|
54
|
+
) => Effect.Effect<void, CliError.CliError | Terminal.QuitError, Command.Environment> = Effect.fnUntraced(
|
|
55
|
+
function*(command, commandLine, sectionName) {
|
|
56
|
+
const impl = toImpl(command)
|
|
57
|
+
const visibleSubcommands = command.subcommands.flatMap((group) => group.commands.filter((child) => !child.hidden))
|
|
58
|
+
const config = visibleSubcommands.length === 0 ? impl.config : impl.contextConfig
|
|
59
|
+
|
|
60
|
+
if (config.flags.length > 0) {
|
|
61
|
+
yield* Console.log(renderSection(sectionName, "FLAGS"))
|
|
62
|
+
for (const param of config.flags) {
|
|
63
|
+
commandLine.push(...yield* promptParam(param))
|
|
64
|
+
}
|
|
65
|
+
if (config.arguments.length > 0 || visibleSubcommands.length > 0) {
|
|
66
|
+
yield* logCurrentCommand(commandLine)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (config.arguments.length > 0) {
|
|
71
|
+
yield* Console.log(renderSection(sectionName, "ARGUMENTS"))
|
|
72
|
+
for (const param of config.arguments) {
|
|
73
|
+
commandLine.push(...yield* promptParam(param))
|
|
74
|
+
}
|
|
75
|
+
if (visibleSubcommands.length > 0) {
|
|
76
|
+
yield* logCurrentCommand(commandLine)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (visibleSubcommands.length === 0) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const child = yield* Prompt.run(Prompt.select({
|
|
85
|
+
message: "Command",
|
|
86
|
+
choices: visibleSubcommands.map((command) => ({
|
|
87
|
+
title: command.name,
|
|
88
|
+
value: command,
|
|
89
|
+
...(command.shortDescription !== undefined
|
|
90
|
+
? { description: command.shortDescription }
|
|
91
|
+
: command.description !== undefined
|
|
92
|
+
? { description: command.description }
|
|
93
|
+
: {})
|
|
94
|
+
}))
|
|
95
|
+
}))
|
|
96
|
+
yield* Console.log()
|
|
97
|
+
commandLine.push(child.name)
|
|
98
|
+
if (hasWizardSteps(child)) {
|
|
99
|
+
yield* logCurrentCommand(commandLine)
|
|
100
|
+
}
|
|
101
|
+
yield* promptCommand(child, commandLine, child.name)
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
const hasWizardSteps = (command: Command.Command.Any): boolean => {
|
|
106
|
+
const hasVisibleSubcommands = command.subcommands.some((group) => group.commands.some((child) => !child.hidden))
|
|
107
|
+
return hasVisibleSubcommands || toImpl(command).config.orderedParams.length > 0
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const promptParam: (
|
|
111
|
+
param: Param.Any
|
|
112
|
+
) => Effect.Effect<Array<string>, CliError.CliError | Terminal.QuitError, Command.Environment> = Effect.fnUntraced(
|
|
113
|
+
function*(param) {
|
|
114
|
+
const single = Param.getUnderlyingSingleOrThrow(param)
|
|
115
|
+
const metadata = Param.getParamMetadata(param)
|
|
116
|
+
|
|
117
|
+
if (metadata.isOptional) {
|
|
118
|
+
const include = yield* Prompt.run(Prompt.confirm({
|
|
119
|
+
message: `Set ${renderParamLabel(single)}?`,
|
|
120
|
+
initial: false
|
|
121
|
+
}))
|
|
122
|
+
if (!include) {
|
|
123
|
+
yield* Console.log()
|
|
124
|
+
return []
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const count = !metadata.isVariadic
|
|
129
|
+
? 1
|
|
130
|
+
: yield* Prompt.run(Prompt.integer({
|
|
131
|
+
message: `${renderParamLabel(single)} count`,
|
|
132
|
+
default: Option.getOrElse(metadata.variadicMin, () => 0),
|
|
133
|
+
min: Option.getOrElse(metadata.variadicMin, () => 0),
|
|
134
|
+
...(Option.isSome(metadata.variadicMax) ? { max: metadata.variadicMax.value } : {})
|
|
135
|
+
}))
|
|
136
|
+
const values: Array<string> = []
|
|
137
|
+
for (let i = 0; i < count; i++) {
|
|
138
|
+
values.push(yield* promptSingle(single))
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const parsed = single.kind === Param.flagKind
|
|
142
|
+
? {
|
|
143
|
+
flags: { [single.name]: values },
|
|
144
|
+
arguments: []
|
|
145
|
+
}
|
|
146
|
+
: {
|
|
147
|
+
flags: {},
|
|
148
|
+
arguments: values
|
|
149
|
+
}
|
|
150
|
+
yield* param.parse(parsed)
|
|
151
|
+
yield* Console.log()
|
|
152
|
+
|
|
153
|
+
if (single.kind === Param.argumentKind) {
|
|
154
|
+
return values
|
|
155
|
+
}
|
|
156
|
+
return values.flatMap((value) => [`--${single.name}`, value])
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
const promptSingle = (
|
|
161
|
+
single: Param.Single<Param.ParamKind, unknown>
|
|
162
|
+
): Effect.Effect<string, Terminal.QuitError, Command.Environment> => {
|
|
163
|
+
const message = renderParamMessage(single)
|
|
164
|
+
switch (single.primitiveType._tag) {
|
|
165
|
+
case "Boolean":
|
|
166
|
+
return Effect.map(
|
|
167
|
+
Prompt.run(Prompt.confirm({
|
|
168
|
+
message,
|
|
169
|
+
label: {
|
|
170
|
+
confirm: "true",
|
|
171
|
+
deny: "false"
|
|
172
|
+
},
|
|
173
|
+
placeholder: {
|
|
174
|
+
defaultConfirm: "(T/f)",
|
|
175
|
+
defaultDeny: "(t/F)"
|
|
176
|
+
}
|
|
177
|
+
})),
|
|
178
|
+
String
|
|
179
|
+
)
|
|
180
|
+
case "Choice": {
|
|
181
|
+
const choices = Primitive.getChoiceKeys(single.primitiveType) ?? []
|
|
182
|
+
return Prompt.run(Prompt.select({
|
|
183
|
+
message,
|
|
184
|
+
choices: choices.map((choice) => ({ title: choice, value: choice }))
|
|
185
|
+
}))
|
|
186
|
+
}
|
|
187
|
+
case "Date":
|
|
188
|
+
return Effect.map(Prompt.run(Prompt.date({ message })), (date) => date.toISOString())
|
|
189
|
+
case "Float":
|
|
190
|
+
return Effect.map(Prompt.run(Prompt.float({ message })), String)
|
|
191
|
+
case "Integer":
|
|
192
|
+
return Effect.map(Prompt.run(Prompt.integer({ message })), String)
|
|
193
|
+
case "Redacted":
|
|
194
|
+
return Effect.map(Prompt.run(Prompt.password({ message })), Redacted.value)
|
|
195
|
+
default:
|
|
196
|
+
return Prompt.run(Prompt.text({ message }))
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const formatName = (single: Param.Single<Param.ParamKind, unknown>): string =>
|
|
201
|
+
single.kind === Param.flagKind ? `--${single.name}` : single.name
|
|
202
|
+
|
|
203
|
+
const renderParamMessage = (single: Param.Single<Param.ParamKind, unknown>): string => renderParamLabel(single)
|
|
204
|
+
|
|
205
|
+
const renderParamLabel = (single: Param.Single<Param.ParamKind, unknown>): string => {
|
|
206
|
+
const description = Option.getOrUndefined(single.description)?.trim()
|
|
207
|
+
const label = single.kind === Param.flagKind && description !== undefined && description.length <= 32
|
|
208
|
+
? description
|
|
209
|
+
: humanize(single.name)
|
|
210
|
+
return single.kind === Param.flagKind ? `${label} (${formatName(single)})` : label
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const humanize = (name: string): string => {
|
|
214
|
+
const words = name.split(/[-_]+/).filter((word) => word.length > 0)
|
|
215
|
+
if (words.length === 0) return name
|
|
216
|
+
return [words[0][0].toUpperCase() + words[0].slice(1), ...words.slice(1)].join(" ")
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const logCurrentCommand = (commandLine: ReadonlyArray<string>): Effect.Effect<void> =>
|
|
220
|
+
Console.log(renderCommandBlock("Current command", commandLine, Ansi.magenta))
|
|
221
|
+
|
|
222
|
+
const renderSection = (commandName: string, section: string): string =>
|
|
223
|
+
`${Ansi.annotate(commandName.toUpperCase(), Ansi.bold, Ansi.cyanBright)} ${Ansi.annotate("·", Ansi.blackBright)} ${
|
|
224
|
+
Ansi.annotate(section, Ansi.bold, Ansi.white)
|
|
225
|
+
}`
|
|
226
|
+
|
|
227
|
+
export const renderIntroduction = (name: string, version: string, summary: string | undefined): string => {
|
|
228
|
+
const title = `${Ansi.annotate(name, Ansi.bold, Ansi.cyanBright)} ${Ansi.annotate(`v${version}`, Ansi.white)} ${
|
|
229
|
+
Ansi.annotate("· Command wizard", Ansi.bold, Ansi.white)
|
|
230
|
+
}`
|
|
231
|
+
return [
|
|
232
|
+
title,
|
|
233
|
+
...(summary === undefined || summary.length === 0 ? [] : [summary]),
|
|
234
|
+
Ansi.annotate("Build a command interactively. Press Ctrl+C to cancel.", Ansi.blackBright),
|
|
235
|
+
""
|
|
236
|
+
].join("\n")
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export const renderCompletion = (commandLine: ReadonlyArray<string>): string =>
|
|
240
|
+
renderCommandBlock("Command ready", commandLine, Ansi.cyanBright, Ansi.green)
|
|
241
|
+
|
|
242
|
+
export const renderQuit = (): string => `\n${Ansi.annotate("Wizard cancelled.", Ansi.red)}`
|
|
243
|
+
|
|
244
|
+
const renderCommandBlock = (
|
|
245
|
+
label: string,
|
|
246
|
+
commandLine: ReadonlyArray<string>,
|
|
247
|
+
commandColor: string,
|
|
248
|
+
labelColor: string = Ansi.white
|
|
249
|
+
): string => {
|
|
250
|
+
const lines = wrapCommand(commandLine)
|
|
251
|
+
return [
|
|
252
|
+
Ansi.annotate(label, Ansi.bold, labelColor),
|
|
253
|
+
...lines.map((line) => Ansi.annotate(line, commandColor)),
|
|
254
|
+
""
|
|
255
|
+
].join("\n")
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const wrapCommand = (commandLine: ReadonlyArray<string>): Array<string> => {
|
|
259
|
+
const width = 88
|
|
260
|
+
const firstIndent = " $ "
|
|
261
|
+
const continuationIndent = " "
|
|
262
|
+
const args = commandLine.map(formatShellArg)
|
|
263
|
+
const lines: Array<string> = []
|
|
264
|
+
let current = firstIndent
|
|
265
|
+
|
|
266
|
+
for (const arg of args) {
|
|
267
|
+
const separator = current === firstIndent || current === continuationIndent ? "" : " "
|
|
268
|
+
if (current.length + separator.length + arg.length > width && current !== firstIndent) {
|
|
269
|
+
lines.push(`${current} \\`)
|
|
270
|
+
current = `${continuationIndent}${arg}`
|
|
271
|
+
} else {
|
|
272
|
+
current += `${separator}${arg}`
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (current !== firstIndent) {
|
|
277
|
+
lines.push(current)
|
|
278
|
+
}
|
|
279
|
+
return lines
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const formatShellArg = (arg: string): string =>
|
|
283
|
+
/^[A-Za-z0-9_./:@%+=,-]+$/.test(arg) ? arg : `'${arg.replaceAll("'", `'"'"'`)}'`
|
|
@@ -220,7 +220,7 @@ export const makeMemory = Effect.gen(function*() {
|
|
|
220
220
|
setRunnerHealth: () => Effect.void,
|
|
221
221
|
acquire: (_address, shardIds) => {
|
|
222
222
|
acquired = Array.from(shardIds)
|
|
223
|
-
return Effect.succeed(
|
|
223
|
+
return Effect.succeed(acquired)
|
|
224
224
|
},
|
|
225
225
|
refresh: () => Effect.sync(() => acquired),
|
|
226
226
|
release: () => Effect.void,
|
|
@@ -452,7 +452,9 @@ export const makeChannel = <IE>(headers: Record<string, string>): Channel.Channe
|
|
|
452
452
|
exit = Option.some(Exit.fail(convertError(error_)))
|
|
453
453
|
},
|
|
454
454
|
onDone() {
|
|
455
|
-
|
|
455
|
+
if (Option.isNone(exit)) {
|
|
456
|
+
exit = Option.some(Exit.fail(Cause.Done()))
|
|
457
|
+
}
|
|
456
458
|
}
|
|
457
459
|
})
|
|
458
460
|
|
|
@@ -171,7 +171,7 @@ type HandlerRequirements<
|
|
|
171
171
|
> =
|
|
172
172
|
| HttpApiEndpoint.Middleware<Endpoint>
|
|
173
173
|
| HttpApiEndpoint.MiddlewareServices<Endpoint>
|
|
174
|
-
| ([R] extends [never] ? never : HttpRouter.Request<"Requires", R>)
|
|
174
|
+
| ([R] extends [never] ? never : HttpRouter.Request.From<"Requires", R>)
|
|
175
175
|
|
|
176
176
|
interface HandlerOptions {
|
|
177
177
|
readonly uninterruptible?: boolean | undefined
|
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import * as Cache from "../../Cache.ts"
|
|
13
13
|
import * as Context from "../../Context.ts"
|
|
14
|
+
import * as Duration from "../../Duration.ts"
|
|
14
15
|
import * as Effect from "../../Effect.ts"
|
|
15
16
|
import * as Equal from "../../Equal.ts"
|
|
17
|
+
import * as Exit from "../../Exit.ts"
|
|
16
18
|
import { constant, identity } from "../../Function.ts"
|
|
17
19
|
import * as Hash from "../../Hash.ts"
|
|
18
20
|
import * as Schema from "../../Schema.ts"
|
|
@@ -50,10 +52,13 @@ export const make = Effect.fnUntraced(function*(
|
|
|
50
52
|
readonly send: <A = unknown>(command: string, ...args: ReadonlyArray<string>) => Effect.Effect<A, RedisError>
|
|
51
53
|
}
|
|
52
54
|
) {
|
|
53
|
-
const scriptCache = yield* Cache.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
const scriptCache = yield* Cache.makeWith(
|
|
56
|
+
(script: Script<any>) => options.send<string>("SCRIPT", "LOAD", script.lua),
|
|
57
|
+
{
|
|
58
|
+
capacity: Number.POSITIVE_INFINITY,
|
|
59
|
+
timeToLive: (exit) => Exit.isSuccess(exit) ? Duration.infinity : Duration.zero
|
|
60
|
+
}
|
|
61
|
+
)
|
|
57
62
|
|
|
58
63
|
const eval_ = <
|
|
59
64
|
Config extends {
|
|
@@ -62,8 +62,7 @@ export interface SqlClient extends Constructor {
|
|
|
62
62
|
readonly transactionService: Context.Service<TransactionConnection, TransactionConnection.Service>
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
|
-
* Use the Reactivity service
|
|
66
|
-
* query.
|
|
65
|
+
* Use the Reactivity service to create a reactive query.
|
|
67
66
|
*/
|
|
68
67
|
readonly reactive: <A, E, R>(
|
|
69
68
|
keys: ReadonlyArray<unknown> | ReadonlyRecord<string, ReadonlyArray<unknown>>,
|