effect 4.0.2 → 4.0.3
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/Context.js +3 -3
- package/dist/Context.js.map +1 -1
- package/dist/Crypto.d.ts +33 -5
- package/dist/Crypto.d.ts.map +1 -1
- package/dist/Crypto.js +8 -2
- package/dist/Crypto.js.map +1 -1
- package/dist/DateTime.d.ts +9 -6
- package/dist/DateTime.d.ts.map +1 -1
- package/dist/DateTime.js +9 -6
- package/dist/DateTime.js.map +1 -1
- package/dist/Duration.d.ts +6 -6
- package/dist/Duration.d.ts.map +1 -1
- package/dist/Duration.js +27 -8
- package/dist/Duration.js.map +1 -1
- package/dist/FileSystem.d.ts +44 -2
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js.map +1 -1
- package/dist/Schema.d.ts +473 -1
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +355 -4
- package/dist/Schema.js.map +1 -1
- package/dist/Stdio.d.ts +7 -1
- package/dist/Stdio.d.ts.map +1 -1
- package/dist/Stdio.js +1 -0
- package/dist/Stdio.js.map +1 -1
- package/dist/Stream.d.ts +11 -11
- package/dist/Stream.js +5 -5
- package/dist/ai/McpServer.d.ts +6 -0
- package/dist/ai/McpServer.d.ts.map +1 -1
- package/dist/ai/McpServer.js +65 -23
- package/dist/ai/McpServer.js.map +1 -1
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js +5 -0
- package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
- package/dist/ai/internal/mcpProtocol.js.map +1 -1
- package/dist/ai/internal/mcpRuntime.js +1 -0
- package/dist/ai/internal/mcpRuntime.js.map +1 -1
- package/dist/cli/CliOutput.d.ts +27 -0
- package/dist/cli/CliOutput.d.ts.map +1 -1
- package/dist/cli/CliOutput.js +33 -10
- package/dist/cli/CliOutput.js.map +1 -1
- package/dist/cli/Command.d.ts.map +1 -1
- package/dist/cli/Command.js +6 -3
- package/dist/cli/Command.js.map +1 -1
- package/dist/cli/Completions.d.ts +3 -3
- package/dist/cli/Completions.d.ts.map +1 -1
- package/dist/cli/Completions.js +8 -5
- package/dist/cli/Completions.js.map +1 -1
- package/dist/cli/GlobalFlag.d.ts +5 -4
- package/dist/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/cli/GlobalFlag.js +3 -3
- package/dist/cli/GlobalFlag.js.map +1 -1
- package/dist/cli/Prompt.d.ts +17 -1
- package/dist/cli/Prompt.d.ts.map +1 -1
- package/dist/cli/Prompt.js +119 -114
- package/dist/cli/Prompt.js.map +1 -1
- package/dist/cli/internal/ansi.d.ts +0 -1
- package/dist/cli/internal/ansi.d.ts.map +1 -1
- package/dist/cli/internal/ansi.js +20 -3
- package/dist/cli/internal/ansi.js.map +1 -1
- package/dist/cli/internal/completions/powershell.d.ts +2 -0
- package/dist/cli/internal/completions/powershell.d.ts.map +1 -0
- package/dist/cli/internal/completions/powershell.js +273 -0
- package/dist/cli/internal/completions/powershell.js.map +1 -0
- package/dist/cli/internal/completions/zsh.js +3 -2
- package/dist/cli/internal/completions/zsh.js.map +1 -1
- package/dist/cli/internal/wizard.d.ts +3 -3
- package/dist/cli/internal/wizard.d.ts.map +1 -1
- package/dist/cli/internal/wizard.js +21 -18
- package/dist/cli/internal/wizard.js.map +1 -1
- package/dist/cluster/ClusterSchema.d.ts +28 -0
- package/dist/cluster/ClusterSchema.d.ts.map +1 -1
- package/dist/cluster/ClusterSchema.js +30 -0
- package/dist/cluster/ClusterSchema.js.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
- package/dist/cluster/ClusterWorkflowEngine.js +10 -18
- package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
- package/dist/cluster/MessageStorage.d.ts +18 -3
- package/dist/cluster/MessageStorage.d.ts.map +1 -1
- package/dist/cluster/MessageStorage.js +31 -11
- package/dist/cluster/MessageStorage.js.map +1 -1
- package/dist/cluster/Runners.d.ts.map +1 -1
- package/dist/cluster/Runners.js +8 -2
- package/dist/cluster/Runners.js.map +1 -1
- package/dist/cluster/Sharding.d.ts.map +1 -1
- package/dist/cluster/Sharding.js +181 -62
- package/dist/cluster/Sharding.js.map +1 -1
- package/dist/cluster/SqlMessageStorage.d.ts +59 -19
- package/dist/cluster/SqlMessageStorage.d.ts.map +1 -1
- package/dist/cluster/SqlMessageStorage.js +84 -55
- package/dist/cluster/SqlMessageStorage.js.map +1 -1
- package/dist/cluster/SqlRunnerStorage.d.ts +68 -19
- package/dist/cluster/SqlRunnerStorage.d.ts.map +1 -1
- package/dist/cluster/SqlRunnerStorage.js +191 -113
- package/dist/cluster/SqlRunnerStorage.js.map +1 -1
- package/dist/cluster/internal/entityManager.js +104 -37
- package/dist/cluster/internal/entityManager.js.map +1 -1
- package/dist/http/FindMyWay/internal/router.js +3 -6
- package/dist/http/FindMyWay/internal/router.js.map +1 -1
- package/dist/http/HttpClient.d.ts +6 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/HttpClient.js +39 -2
- package/dist/http/HttpClient.js.map +1 -1
- package/dist/http/HttpTraceContext.d.ts.map +1 -1
- package/dist/http/HttpTraceContext.js +4 -2
- package/dist/http/HttpTraceContext.js.map +1 -1
- package/dist/internal/effect.js +12 -7
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/version.js +1 -1
- package/dist/net/AddressResolver.d.ts +145 -0
- package/dist/net/AddressResolver.d.ts.map +1 -0
- package/dist/net/AddressResolver.js +114 -0
- package/dist/net/AddressResolver.js.map +1 -0
- package/dist/net/Dns.d.ts +596 -0
- package/dist/net/Dns.d.ts.map +1 -0
- package/dist/net/Dns.js +549 -0
- package/dist/net/Dns.js.map +1 -0
- package/dist/net/Host.d.ts +320 -0
- package/dist/net/Host.d.ts.map +1 -0
- package/dist/net/Host.js +342 -0
- package/dist/net/Host.js.map +1 -0
- package/dist/net/IpInterface.d.ts +76 -3
- package/dist/net/IpInterface.d.ts.map +1 -1
- package/dist/net/IpInterface.js +53 -4
- package/dist/net/IpInterface.js.map +1 -1
- package/dist/net/IpNetwork.d.ts +82 -8
- package/dist/net/IpNetwork.d.ts.map +1 -1
- package/dist/net/IpNetwork.js +60 -4
- package/dist/net/IpNetwork.js.map +1 -1
- package/dist/net/NetAddress.d.ts +388 -35
- package/dist/net/NetAddress.d.ts.map +1 -1
- package/dist/net/NetAddress.js +350 -34
- package/dist/net/NetAddress.js.map +1 -1
- package/dist/net/index.d.ts +15 -0
- package/dist/net/index.d.ts.map +1 -1
- package/dist/net/index.js +15 -0
- package/dist/net/index.js.map +1 -1
- package/dist/observability/OtlpMetrics.d.ts.map +1 -1
- package/dist/observability/OtlpMetrics.js +15 -21
- package/dist/observability/OtlpMetrics.js.map +1 -1
- package/dist/observability/PrometheusMetrics.js +1 -0
- package/dist/observability/PrometheusMetrics.js.map +1 -1
- package/dist/persistence/PersistedQueue.d.ts +32 -3
- package/dist/persistence/PersistedQueue.d.ts.map +1 -1
- package/dist/persistence/PersistedQueue.js +75 -16
- package/dist/persistence/PersistedQueue.js.map +1 -1
- package/dist/rpc/RpcClient.d.ts +22 -6
- package/dist/rpc/RpcClient.d.ts.map +1 -1
- package/dist/rpc/RpcClient.js +12 -5
- package/dist/rpc/RpcClient.js.map +1 -1
- package/dist/rpc/RpcServer.d.ts +6 -0
- package/dist/rpc/RpcServer.d.ts.map +1 -1
- package/dist/rpc/RpcServer.js +42 -20
- package/dist/rpc/RpcServer.js.map +1 -1
- package/dist/socket/DatagramSocket.d.ts +456 -0
- package/dist/socket/DatagramSocket.d.ts.map +1 -0
- package/dist/socket/DatagramSocket.js +535 -0
- package/dist/socket/DatagramSocket.js.map +1 -0
- package/dist/socket/Socket.d.ts +14 -1
- package/dist/socket/Socket.d.ts.map +1 -1
- package/dist/socket/Socket.js +9 -1
- package/dist/socket/Socket.js.map +1 -1
- package/dist/socket/index.d.ts +5 -0
- package/dist/socket/index.d.ts.map +1 -1
- package/dist/socket/index.js +5 -0
- package/dist/socket/index.js.map +1 -1
- package/dist/sql/Migrator.d.ts.map +1 -1
- package/dist/sql/Migrator.js +7 -2
- package/dist/sql/Migrator.js.map +1 -1
- package/dist/sql/SqlClient.d.ts +7 -1
- package/dist/sql/SqlClient.d.ts.map +1 -1
- package/dist/sql/SqlClient.js +31 -6
- package/dist/sql/SqlClient.js.map +1 -1
- package/dist/testing/TestCrypto.d.ts +73 -0
- package/dist/testing/TestCrypto.d.ts.map +1 -0
- package/dist/testing/TestCrypto.js +87 -0
- package/dist/testing/TestCrypto.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/workflow/DurableDeferred.d.ts +54 -0
- package/dist/workflow/DurableDeferred.d.ts.map +1 -1
- package/dist/workflow/DurableDeferred.js +78 -49
- package/dist/workflow/DurableDeferred.js.map +1 -1
- package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
- package/dist/workflow/WorkflowEngine.js +2 -1
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/package.json +1 -1
- package/src/Context.ts +3 -3
- package/src/Crypto.ts +43 -9
- package/src/DateTime.ts +9 -6
- package/src/Duration.ts +36 -16
- package/src/FileSystem.ts +48 -2
- package/src/Schema.ts +669 -5
- package/src/Stdio.ts +9 -2
- package/src/Stream.ts +11 -11
- package/src/ai/McpServer.ts +63 -23
- package/src/ai/internal/mcpProtocol/v2026_07_28.ts +5 -0
- package/src/ai/internal/mcpProtocol.ts +3 -0
- package/src/ai/internal/mcpRuntime.ts +2 -0
- package/src/cli/CliOutput.ts +33 -16
- package/src/cli/Command.ts +4 -3
- package/src/cli/Completions.ts +9 -6
- package/src/cli/GlobalFlag.ts +19 -11
- package/src/cli/Prompt.ts +159 -149
- package/src/cli/internal/ansi.ts +26 -3
- package/src/cli/internal/completions/powershell.ts +322 -0
- package/src/cli/internal/completions/zsh.ts +4 -2
- package/src/cli/internal/wizard.ts +34 -26
- package/src/cluster/ClusterSchema.ts +32 -0
- package/src/cluster/ClusterWorkflowEngine.ts +13 -24
- package/src/cluster/MessageStorage.ts +45 -14
- package/src/cluster/Runners.ts +8 -2
- package/src/cluster/Sharding.ts +207 -49
- package/src/cluster/SqlMessageStorage.ts +118 -84
- package/src/cluster/SqlRunnerStorage.ts +224 -128
- package/src/cluster/internal/entityManager.ts +151 -55
- package/src/http/FindMyWay/internal/router.ts +4 -7
- package/src/http/HttpClient.ts +56 -2
- package/src/http/HttpTraceContext.ts +8 -2
- package/src/internal/effect.ts +15 -13
- package/src/internal/version.ts +1 -1
- package/src/net/AddressResolver.ts +222 -0
- package/src/net/Dns.ts +1035 -0
- package/src/net/Host.ts +472 -0
- package/src/net/IpInterface.ts +117 -7
- package/src/net/IpNetwork.ts +116 -17
- package/src/net/NetAddress.ts +611 -76
- package/src/net/index.ts +18 -0
- package/src/observability/OtlpMetrics.ts +12 -23
- package/src/observability/PrometheusMetrics.ts +1 -0
- package/src/persistence/PersistedQueue.ts +146 -53
- package/src/rpc/RpcClient.ts +41 -19
- package/src/rpc/RpcServer.ts +60 -25
- package/src/socket/DatagramSocket.ts +919 -0
- package/src/socket/Socket.ts +22 -2
- package/src/socket/index.ts +6 -0
- package/src/sql/Migrator.ts +21 -5
- package/src/sql/SqlClient.ts +39 -15
- package/src/testing/TestCrypto.ts +94 -0
- package/src/testing/index.ts +6 -0
- package/src/workflow/DurableDeferred.ts +123 -48
- package/src/workflow/WorkflowEngine.ts +2 -1
package/src/cli/internal/ansi.ts
CHANGED
|
@@ -105,9 +105,32 @@ export const blackBright = `${ESC}90m`
|
|
|
105
105
|
*/
|
|
106
106
|
export const cyanBright = `${ESC}96m`
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Wraps `text` in the given styles followed by a reset. When `colors` is
|
|
110
|
+
* `false` the text is returned unchanged, so callers gate color and style
|
|
111
|
+
* escapes in one place while cursor and erase controls stay untouched.
|
|
112
|
+
*
|
|
113
|
+
* @internal
|
|
114
|
+
*/
|
|
115
|
+
export const annotate = (colors: boolean, text: string, ...styles: Array<string | Array<string>>): string => {
|
|
116
|
+
if (!colors) return text
|
|
117
|
+
return `${styles.flat().join("")}${text}${reset}`
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Detects whether CLI output should use color and style escapes: stdout must
|
|
122
|
+
* be a TTY and `NO_COLOR` must be unset or empty.
|
|
123
|
+
*
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
export const detectColors = (): boolean => {
|
|
127
|
+
const globalProcess = (globalThis as any).process
|
|
128
|
+
return typeof globalProcess === "object" &&
|
|
129
|
+
globalProcess !== null &&
|
|
130
|
+
typeof globalProcess.stdout === "object" &&
|
|
131
|
+
globalProcess.stdout !== null &&
|
|
132
|
+
globalProcess.stdout.isTTY === true &&
|
|
133
|
+
!globalProcess.env?.NO_COLOR
|
|
111
134
|
}
|
|
112
135
|
|
|
113
136
|
export const combine = (...styles: Array<string>): Array<string> => styles
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static PowerShell completion script generator.
|
|
3
|
+
*
|
|
4
|
+
* Produces a self-contained completion script from a `CommandDescriptor`,
|
|
5
|
+
* without invoking the CLI at runtime. The script sticks to Windows
|
|
6
|
+
* PowerShell 5.1 syntax and APIs.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
import type * as Completions from "../../Completions.ts"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Encode non-ASCII and control characters as `[char]` code units. Windows
|
|
14
|
+
* PowerShell 5.1 can misread BOM-less UTF-8 as ANSI, turning some bytes into
|
|
15
|
+
* PowerShell quote delimiters.
|
|
16
|
+
*/
|
|
17
|
+
const quotePs = (s: string): string => {
|
|
18
|
+
const parts: Array<string> = []
|
|
19
|
+
let literal = ""
|
|
20
|
+
for (let i = 0; i < s.length; i++) {
|
|
21
|
+
const code = s.charCodeAt(i)
|
|
22
|
+
if (code >= 0x20 && code < 0x80) {
|
|
23
|
+
literal += s[i] === "'" ? "''" : s[i]
|
|
24
|
+
continue
|
|
25
|
+
}
|
|
26
|
+
if (literal !== "" || parts.length === 0) parts.push(`'${literal}'`)
|
|
27
|
+
literal = ""
|
|
28
|
+
parts.push(`[char]0x${code.toString(16).toUpperCase().padStart(4, "0")}`)
|
|
29
|
+
}
|
|
30
|
+
if (literal !== "" || parts.length === 0) parts.push(`'${literal}'`)
|
|
31
|
+
return parts.length === 1 ? parts[0] : `(${parts.join(" + ")})`
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const psArray = (items: ReadonlyArray<string>): string => `@(${items.map(quotePs).join(", ")})`
|
|
35
|
+
|
|
36
|
+
const psOptional = (s: string | undefined): string => s ? quotePs(s) : "$null"
|
|
37
|
+
|
|
38
|
+
const sanitize = (s: string): string => s.replace(/[^a-zA-Z0-9_]/g, "_")
|
|
39
|
+
|
|
40
|
+
const flagForms = (flag: Completions.FlagDescriptor): Array<string> => [
|
|
41
|
+
`--${flag.name}`,
|
|
42
|
+
...flag.aliases.map((alias) => alias.length === 1 ? `-${alias}` : `--${alias}`)
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
const valueFields = (type: Completions.FlagType | Completions.ArgumentType): string =>
|
|
46
|
+
`values = ${psArray(type._tag === "Choice" ? type.values : [])}; ` +
|
|
47
|
+
`pathType = ${type._tag === "Path" ? quotePs(type.pathType) : "$null"}`
|
|
48
|
+
|
|
49
|
+
const flagEntry = (flag: Completions.FlagDescriptor): string =>
|
|
50
|
+
`@{ name = ${quotePs(flag.name)}; forms = ${psArray(flagForms(flag))}; ` +
|
|
51
|
+
`takesValue = $${flag.type._tag !== "Boolean"}; ${valueFields(flag.type)}; ` +
|
|
52
|
+
`description = ${psOptional(flag.description)} }`
|
|
53
|
+
|
|
54
|
+
const argumentEntry = (argument: Completions.ArgumentDescriptor): string =>
|
|
55
|
+
`@{ name = ${quotePs(argument.name)}; variadic = $${argument.variadic}; ${valueFields(argument.type)}; ` +
|
|
56
|
+
`description = ${psOptional(argument.description)} }`
|
|
57
|
+
|
|
58
|
+
const pushList = (lines: Array<string>, field: string, entries: ReadonlyArray<string>): void => {
|
|
59
|
+
if (entries.length === 0) {
|
|
60
|
+
lines.push(` ${field} = @()`)
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
lines.push(` ${field} = @(`)
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
lines.push(` ${entry}`)
|
|
66
|
+
}
|
|
67
|
+
lines.push(` )`)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Emit one context per subcommand path. Subcommands are case-sensitive, so
|
|
72
|
+
* contexts go in an ordinal hashtable instead of a hash literal, whose keys
|
|
73
|
+
* ignore case.
|
|
74
|
+
*/
|
|
75
|
+
const generateContexts = (
|
|
76
|
+
dataName: string,
|
|
77
|
+
descriptor: Completions.CommandDescriptor,
|
|
78
|
+
path: ReadonlyArray<string>,
|
|
79
|
+
lines: Array<string>,
|
|
80
|
+
seen: Set<string>
|
|
81
|
+
): void => {
|
|
82
|
+
const key = path.join(" ")
|
|
83
|
+
if (seen.has(key)) return
|
|
84
|
+
seen.add(key)
|
|
85
|
+
lines.push(`${dataName}[${quotePs(key)}] = @{`)
|
|
86
|
+
pushList(
|
|
87
|
+
lines,
|
|
88
|
+
"subcommands",
|
|
89
|
+
descriptor.subcommands.map((sub) =>
|
|
90
|
+
`@{ name = ${quotePs(sub.name)}; description = ${psOptional(sub.description)} }`
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
pushList(lines, "flags", descriptor.flags.map(flagEntry))
|
|
94
|
+
pushList(lines, "arguments", descriptor.arguments.map(argumentEntry))
|
|
95
|
+
lines.push(`}`)
|
|
96
|
+
for (const sub of descriptor.subcommands) {
|
|
97
|
+
generateContexts(dataName, sub, [...path, sub.name], lines, seen)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Replay the committed words with the CLI lexer and parser rules: `--`, short
|
|
103
|
+
* flag clusters, inline values, boolean literals, negative numbers, and
|
|
104
|
+
* subcommand selection by the first value only.
|
|
105
|
+
*/
|
|
106
|
+
const completer = (dataName: string): string =>
|
|
107
|
+
String.raw` param($wordToComplete, $commandAst, $cursorPosition)
|
|
108
|
+
|
|
109
|
+
$spec = ${dataName}
|
|
110
|
+
$results = [System.Collections.Generic.List[System.Management.Automation.CompletionResult]]::new()
|
|
111
|
+
$booleanLiterals = @('true', 'yes', 'on', '1', 'y', 'false', 'no', 'off', '0', 'n')
|
|
112
|
+
|
|
113
|
+
$index = {
|
|
114
|
+
param($context)
|
|
115
|
+
$lookup = [hashtable]::new([System.StringComparer]::Ordinal)
|
|
116
|
+
foreach ($flag in $context.flags) {
|
|
117
|
+
foreach ($form in $flag.forms) { $lookup[$form] = $flag }
|
|
118
|
+
}
|
|
119
|
+
$lookup
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
$add = {
|
|
123
|
+
param([string]$value, [string]$type, $tooltip, [string]$typed, [string]$textPrefix)
|
|
124
|
+
if (-not $value.StartsWith($typed, [System.StringComparison]::OrdinalIgnoreCase)) { return }
|
|
125
|
+
$text = $value
|
|
126
|
+
if ($value -notmatch '^[\w./:%+=\\-]+$') { $text = "'" + ($value -replace "['\u2018-\u201b]", '$0$0') + "'" }
|
|
127
|
+
$text = $textPrefix + $text
|
|
128
|
+
$label = $value
|
|
129
|
+
if (-not $label) { $label = $text }
|
|
130
|
+
if (-not $tooltip) { $tooltip = $label }
|
|
131
|
+
$results.Add([System.Management.Automation.CompletionResult]::new($text, $label, $type, $tooltip))
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
$addValues = {
|
|
135
|
+
param($entry, [string]$typed, [string]$textPrefix)
|
|
136
|
+
foreach ($value in $entry.values) {
|
|
137
|
+
if ($textPrefix -eq '' -and (& $optionLike $value)) { continue }
|
|
138
|
+
& $add $value 'ParameterValue' $entry.description $typed $textPrefix
|
|
139
|
+
}
|
|
140
|
+
if ($entry.pathType) {
|
|
141
|
+
foreach ($file in [System.Management.Automation.CompletionCompleters]::CompleteFilename($typed)) {
|
|
142
|
+
if ($entry.pathType -eq 'directory' -and $file.ResultType -ne 'ProviderContainer') { continue }
|
|
143
|
+
$results.Add([System.Management.Automation.CompletionResult]::new($textPrefix + $file.CompletionText, $file.ListItemText, $file.ResultType, $file.ToolTip))
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
$addFlags = {
|
|
149
|
+
param([string]$typed)
|
|
150
|
+
foreach ($flag in $context.flags) {
|
|
151
|
+
if ($used.ContainsKey($flag.name)) { continue }
|
|
152
|
+
foreach ($form in $flag.forms) {
|
|
153
|
+
& $add $form 'ParameterName' $flag.description $typed ''
|
|
154
|
+
}
|
|
155
|
+
if (-not $flag.takesValue) {
|
|
156
|
+
$tooltip = $null
|
|
157
|
+
if ($flag.description) { $tooltip = 'Disable ' + $flag.name }
|
|
158
|
+
& $add ('--no-' + $flag.name) 'ParameterName' $tooltip $typed ''
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# As in the CLI lexer, nothing after '--' is an option, and negative numbers
|
|
164
|
+
# and a lone '-' are values.
|
|
165
|
+
$optionLike = {
|
|
166
|
+
param([string]$word)
|
|
167
|
+
-not $endOfOptions -and $word -match '^-.' -and $word -notmatch '^-(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$'
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
# A typed value that has no candidates completes to itself, so the engine
|
|
171
|
+
# does not fall back to listing files.
|
|
172
|
+
$keepTyped = {
|
|
173
|
+
if ($results.Count -eq 0 -and $current) {
|
|
174
|
+
$results.Add([System.Management.Automation.CompletionResult]::new($current, $current, 'ParameterValue', $current))
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
$path = ''
|
|
179
|
+
$context = $spec[$path]
|
|
180
|
+
$lookup = & $index $context
|
|
181
|
+
$used = [hashtable]::new([System.StringComparer]::Ordinal)
|
|
182
|
+
$pending = $null
|
|
183
|
+
$endOfOptions = $false
|
|
184
|
+
$position = 0
|
|
185
|
+
|
|
186
|
+
# The engine strips the quotes from a quoted word.
|
|
187
|
+
$typed = [string]$wordToComplete
|
|
188
|
+
if ($typed -match '^([''"])(.*?)\1?$') { $typed = $Matches[2] }
|
|
189
|
+
$current = $null
|
|
190
|
+
|
|
191
|
+
$elements = $commandAst.CommandElements
|
|
192
|
+
for ($i = 1; $i -lt $elements.Count; $i++) {
|
|
193
|
+
$element = $elements[$i]
|
|
194
|
+
$word = $element.Extent.Text
|
|
195
|
+
if ($element -is [System.Management.Automation.Language.StringConstantExpressionAst]) { $word = $element.Value }
|
|
196
|
+
if ($element.Extent.EndOffset -ge $cursorPosition) {
|
|
197
|
+
if ($element -is [System.Management.Automation.Language.ConstantExpressionAst] -and $element.Extent.StartOffset -le $cursorPosition) {
|
|
198
|
+
$current = $element.Extent.Text
|
|
199
|
+
if ($element.Extent.EndOffset -eq $cursorPosition) { $typed = $word }
|
|
200
|
+
}
|
|
201
|
+
break
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
# A flag takes the next word as its value unless it is an option or '--';
|
|
205
|
+
# a boolean flag only takes a boolean literal.
|
|
206
|
+
$isOption = & $optionLike $word
|
|
207
|
+
if ($null -ne $pending) {
|
|
208
|
+
$flag = $pending
|
|
209
|
+
$pending = $null
|
|
210
|
+
if ($flag.takesValue) {
|
|
211
|
+
if (-not $isOption) { continue }
|
|
212
|
+
} elseif ($booleanLiterals -ccontains $word) { continue }
|
|
213
|
+
}
|
|
214
|
+
if ($endOfOptions) { $position++; continue }
|
|
215
|
+
if ($word -ceq '--') { $endOfOptions = $true; continue }
|
|
216
|
+
|
|
217
|
+
if ($isOption) {
|
|
218
|
+
$hasValue = $word.Contains('=')
|
|
219
|
+
if ($hasValue) {
|
|
220
|
+
$forms = @($word.Substring(0, $word.IndexOf('=')))
|
|
221
|
+
} elseif ($word.StartsWith('--')) {
|
|
222
|
+
$forms = @($word)
|
|
223
|
+
} else {
|
|
224
|
+
$forms = @(foreach ($char in $word.Substring(1).ToCharArray()) { '-' + $char })
|
|
225
|
+
}
|
|
226
|
+
foreach ($form in $forms) {
|
|
227
|
+
$pending = $null
|
|
228
|
+
$flag = $lookup[$form]
|
|
229
|
+
if ($null -eq $flag) {
|
|
230
|
+
if ($form.StartsWith('--no-')) {
|
|
231
|
+
$name = $form.Substring(5)
|
|
232
|
+
$flag = $lookup['--' + $name]
|
|
233
|
+
if ($null -ne $flag -and -not $flag.takesValue -and $flag.name -ceq $name) { $used[$name] = $true }
|
|
234
|
+
}
|
|
235
|
+
continue
|
|
236
|
+
}
|
|
237
|
+
$used[$flag.name] = $true
|
|
238
|
+
if (-not $hasValue) { $pending = $flag }
|
|
239
|
+
}
|
|
240
|
+
continue
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if ($position -eq 0 -and $context.subcommands.name -ccontains $word) {
|
|
244
|
+
if ($path) { $path = $path + ' ' + $word } else { $path = $word }
|
|
245
|
+
$context = $spec[$path]
|
|
246
|
+
$lookup = & $index $context
|
|
247
|
+
$used = [hashtable]::new([System.StringComparer]::Ordinal)
|
|
248
|
+
continue
|
|
249
|
+
}
|
|
250
|
+
$position++
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
$typedIsOption = & $optionLike $typed
|
|
254
|
+
if ($null -ne $pending -and $pending.takesValue -and -not $typedIsOption) {
|
|
255
|
+
& $addValues $pending $typed ''
|
|
256
|
+
& $keepTyped
|
|
257
|
+
return $results
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if ($typedIsOption) {
|
|
261
|
+
if ($typed -match '^(-[^=]+)=(.*)$') {
|
|
262
|
+
$form = $Matches[1]
|
|
263
|
+
$flag = $lookup[$form]
|
|
264
|
+
if ($null -ne $flag -and $flag.takesValue) {
|
|
265
|
+
& $addValues $flag $Matches[2] ($form + '=')
|
|
266
|
+
& $keepTyped
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
& $addFlags $typed
|
|
270
|
+
}
|
|
271
|
+
return $results
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (-not $endOfOptions -and $position -eq 0) {
|
|
275
|
+
foreach ($sub in $context.subcommands) {
|
|
276
|
+
& $add $sub.name 'Command' $sub.description $typed ''
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
$arguments = $context.arguments
|
|
281
|
+
if ($position -lt $arguments.Count) {
|
|
282
|
+
& $addValues $arguments[$position] $typed ''
|
|
283
|
+
} elseif ($arguments.Count -gt 0 -and $arguments[-1].variadic) {
|
|
284
|
+
& $addValues $arguments[-1] $typed ''
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (-not $endOfOptions) {
|
|
288
|
+
& $addFlags $typed
|
|
289
|
+
}
|
|
290
|
+
return $results`
|
|
291
|
+
|
|
292
|
+
/** @internal */
|
|
293
|
+
export const generate = (
|
|
294
|
+
executableName: string,
|
|
295
|
+
descriptor: Completions.CommandDescriptor
|
|
296
|
+
): string => {
|
|
297
|
+
const dataName = `$global:_${sanitize(executableName)}_Completions`
|
|
298
|
+
const lines: Array<string> = []
|
|
299
|
+
|
|
300
|
+
lines.push(`###-begin-${executableName}-completions-###`)
|
|
301
|
+
lines.push(`#`)
|
|
302
|
+
lines.push(`# Static completion script for PowerShell`)
|
|
303
|
+
lines.push(`#`)
|
|
304
|
+
lines.push(`# Installation:`)
|
|
305
|
+
// `>>` on Windows PowerShell 5.1 appends UTF-16LE to the profile, so the
|
|
306
|
+
// script goes in its own file.
|
|
307
|
+
lines.push(`# ${executableName} --completions powershell > ${executableName}-completion.ps1`)
|
|
308
|
+
lines.push(`# then add this line to your $PROFILE (use the full path to the file):`)
|
|
309
|
+
lines.push(`# . <PATH>\\${executableName}-completion.ps1`)
|
|
310
|
+
lines.push(`#`)
|
|
311
|
+
lines.push(``)
|
|
312
|
+
lines.push(`${dataName} = [hashtable]::new([System.StringComparer]::Ordinal)`)
|
|
313
|
+
generateContexts(dataName, descriptor, [], lines, new Set())
|
|
314
|
+
lines.push(``)
|
|
315
|
+
lines.push(`Register-ArgumentCompleter -Native -CommandName ${quotePs(executableName)} -ScriptBlock {`)
|
|
316
|
+
lines.push(completer(dataName))
|
|
317
|
+
lines.push(`}`)
|
|
318
|
+
lines.push(``)
|
|
319
|
+
lines.push(`###-end-${executableName}-completions-###`)
|
|
320
|
+
|
|
321
|
+
return lines.join("\n")
|
|
322
|
+
}
|
|
@@ -14,6 +14,8 @@ import type * as Completions from "../../Completions.ts"
|
|
|
14
14
|
|
|
15
15
|
const escapeZsh = (s: string): string => s.replace(/\\/g, "\\\\").replace(/'/g, "'\\''").replace(/:/g, "\\:")
|
|
16
16
|
|
|
17
|
+
const escapeZshExplanation = (s: string): string => escapeZsh(s).replace(/]/g, "\\]")
|
|
18
|
+
|
|
17
19
|
/** Escape choices for the second parse of a Zsh `_arguments` action. */
|
|
18
20
|
const escapeZshChoice = (s: string): string => s.replace(/[^A-Za-z0-9_.,/@%+-]/gu, "\\$&").replace(/'/g, "'\\''")
|
|
19
21
|
|
|
@@ -69,7 +71,7 @@ const argAction = (type: Completions.ArgumentType): string => {
|
|
|
69
71
|
*/
|
|
70
72
|
const flagSpecs = (flag: Completions.FlagDescriptor): Array<string> => {
|
|
71
73
|
const specs: Array<string> = []
|
|
72
|
-
const desc = flag.description ? `[${
|
|
74
|
+
const desc = flag.description ? `[${escapeZshExplanation(flag.description)}]` : ""
|
|
73
75
|
const action = valueAction(flag.type)
|
|
74
76
|
const excl = `(${allForms(flag).join(" ")})`
|
|
75
77
|
|
|
@@ -84,7 +86,7 @@ const flagSpecs = (flag: Completions.FlagDescriptor): Array<string> => {
|
|
|
84
86
|
|
|
85
87
|
// Boolean negation
|
|
86
88
|
if (flag.type._tag === "Boolean") {
|
|
87
|
-
const negDesc = flag.description ? `[${
|
|
89
|
+
const negDesc = flag.description ? `[${escapeZshExplanation(`Disable ${flag.name}`)}]` : ""
|
|
88
90
|
specs.push(`'${excl}--no-${flag.name}${negDesc}'`)
|
|
89
91
|
}
|
|
90
92
|
|
|
@@ -34,8 +34,9 @@ export const run: (
|
|
|
34
34
|
const commandPath = options?.commandPath ?? [command.name]
|
|
35
35
|
const selected = getCommandAtPath(command, commandPath)
|
|
36
36
|
const commandLine = (options?.prefix ?? commandPath).map((value) => commandLineArg(value))
|
|
37
|
-
yield*
|
|
38
|
-
yield*
|
|
37
|
+
const { colors } = yield* Prompt.Theme
|
|
38
|
+
yield* logCurrentCommand(commandLine, colors)
|
|
39
|
+
yield* promptCommand(selected, commandLine, selected === command ? "ROOT" : selected.name, colors)
|
|
39
40
|
return {
|
|
40
41
|
args: commandLine.map((arg) => arg.value),
|
|
41
42
|
displayArgs: commandLine.map((arg) => arg.displayValue)
|
|
@@ -63,30 +64,31 @@ const getCommandAtPath = (
|
|
|
63
64
|
const promptCommand: (
|
|
64
65
|
command: Command.Command.Any,
|
|
65
66
|
commandLine: Array<CommandLineArg>,
|
|
66
|
-
sectionName: string
|
|
67
|
+
sectionName: string,
|
|
68
|
+
colors: boolean
|
|
67
69
|
) => Effect.Effect<void, CliError.CliError | Terminal.QuitError, Command.Environment> = Effect.fnUntraced(
|
|
68
|
-
function*(command, commandLine, sectionName) {
|
|
70
|
+
function*(command, commandLine, sectionName, colors) {
|
|
69
71
|
const impl = toImpl(command)
|
|
70
72
|
const visibleSubcommands = command.subcommands.flatMap((group) => group.commands.filter((child) => !child.unlisted))
|
|
71
73
|
const config = visibleSubcommands.length === 0 ? impl.config : impl.contextConfig
|
|
72
74
|
|
|
73
75
|
if (config.flags.length > 0) {
|
|
74
|
-
yield* Console.log(renderSection(sectionName, "FLAGS"))
|
|
76
|
+
yield* Console.log(renderSection(sectionName, "FLAGS", colors))
|
|
75
77
|
for (const param of config.flags) {
|
|
76
78
|
commandLine.push(...yield* promptParam(param))
|
|
77
79
|
}
|
|
78
80
|
if (config.arguments.length > 0 || visibleSubcommands.length > 0) {
|
|
79
|
-
yield* logCurrentCommand(commandLine)
|
|
81
|
+
yield* logCurrentCommand(commandLine, colors)
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
if (config.arguments.length > 0) {
|
|
84
|
-
yield* Console.log(renderSection(sectionName, "ARGUMENTS"))
|
|
86
|
+
yield* Console.log(renderSection(sectionName, "ARGUMENTS", colors))
|
|
85
87
|
for (const param of config.arguments) {
|
|
86
88
|
commandLine.push(...yield* promptParam(param))
|
|
87
89
|
}
|
|
88
90
|
if (visibleSubcommands.length > 0) {
|
|
89
|
-
yield* logCurrentCommand(commandLine)
|
|
91
|
+
yield* logCurrentCommand(commandLine, colors)
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
|
|
@@ -109,9 +111,9 @@ const promptCommand: (
|
|
|
109
111
|
yield* Console.log()
|
|
110
112
|
commandLine.push(commandLineArg(child.name))
|
|
111
113
|
if (hasWizardSteps(child)) {
|
|
112
|
-
yield* logCurrentCommand(commandLine)
|
|
114
|
+
yield* logCurrentCommand(commandLine, colors)
|
|
113
115
|
}
|
|
114
|
-
yield* promptCommand(child, commandLine, child.name)
|
|
116
|
+
yield* promptCommand(child, commandLine, child.name, colors)
|
|
115
117
|
}
|
|
116
118
|
)
|
|
117
119
|
|
|
@@ -244,41 +246,47 @@ const humanize = (name: string): string => {
|
|
|
244
246
|
return [words[0][0].toUpperCase() + words[0].slice(1), ...words.slice(1)].join(" ")
|
|
245
247
|
}
|
|
246
248
|
|
|
247
|
-
const logCurrentCommand = (commandLine: ReadonlyArray<CommandLineArg
|
|
248
|
-
Console.log(renderCommandBlock("Current command", commandLine.map((arg) => arg.displayValue), Ansi.magenta))
|
|
249
|
+
const logCurrentCommand = (commandLine: ReadonlyArray<CommandLineArg>, colors: boolean): Effect.Effect<void> =>
|
|
250
|
+
Console.log(renderCommandBlock("Current command", commandLine.map((arg) => arg.displayValue), colors, Ansi.magenta))
|
|
249
251
|
|
|
250
|
-
const renderSection = (commandName: string, section: string): string =>
|
|
251
|
-
`${Ansi.annotate(commandName.toUpperCase(), Ansi.bold, Ansi.cyanBright)} ${
|
|
252
|
-
Ansi.annotate(
|
|
253
|
-
}`
|
|
252
|
+
const renderSection = (commandName: string, section: string, colors: boolean): string =>
|
|
253
|
+
`${Ansi.annotate(colors, commandName.toUpperCase(), Ansi.bold, Ansi.cyanBright)} ${
|
|
254
|
+
Ansi.annotate(colors, "·", Ansi.blackBright)
|
|
255
|
+
} ${Ansi.annotate(colors, section, Ansi.bold, Ansi.white)}`
|
|
254
256
|
|
|
255
|
-
export const renderIntroduction = (
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
257
|
+
export const renderIntroduction = (
|
|
258
|
+
name: string,
|
|
259
|
+
version: string,
|
|
260
|
+
summary: string | undefined,
|
|
261
|
+
colors: boolean
|
|
262
|
+
): string => {
|
|
263
|
+
const title = `${Ansi.annotate(colors, name, Ansi.bold, Ansi.cyanBright)} ${
|
|
264
|
+
Ansi.annotate(colors, `v${version}`, Ansi.white)
|
|
265
|
+
} ${Ansi.annotate(colors, "· Command wizard", Ansi.bold, Ansi.white)}`
|
|
259
266
|
return [
|
|
260
267
|
title,
|
|
261
268
|
...(summary === undefined || summary.length === 0 ? [] : [summary]),
|
|
262
|
-
Ansi.annotate("Build a command interactively. Press Ctrl+C to cancel.", Ansi.blackBright),
|
|
269
|
+
Ansi.annotate(colors, "Build a command interactively. Press Ctrl+C to cancel.", Ansi.blackBright),
|
|
263
270
|
""
|
|
264
271
|
].join("\n")
|
|
265
272
|
}
|
|
266
273
|
|
|
267
|
-
export const renderCompletion = (commandLine: ReadonlyArray<string
|
|
268
|
-
renderCommandBlock("Command ready", commandLine, Ansi.cyanBright, Ansi.green)
|
|
274
|
+
export const renderCompletion = (commandLine: ReadonlyArray<string>, colors: boolean): string =>
|
|
275
|
+
renderCommandBlock("Command ready", commandLine, colors, Ansi.cyanBright, Ansi.green)
|
|
269
276
|
|
|
270
|
-
export const renderQuit = (): string => `\n${Ansi.annotate("Wizard cancelled.", Ansi.red)}`
|
|
277
|
+
export const renderQuit = (colors: boolean): string => `\n${Ansi.annotate(colors, "Wizard cancelled.", Ansi.red)}`
|
|
271
278
|
|
|
272
279
|
const renderCommandBlock = (
|
|
273
280
|
label: string,
|
|
274
281
|
commandLine: ReadonlyArray<string>,
|
|
282
|
+
colors: boolean,
|
|
275
283
|
commandColor: string,
|
|
276
284
|
labelColor: string = Ansi.white
|
|
277
285
|
): string => {
|
|
278
286
|
const lines = wrapCommand(commandLine)
|
|
279
287
|
return [
|
|
280
|
-
Ansi.annotate(label, Ansi.bold, labelColor),
|
|
281
|
-
...lines.map((line) => Ansi.annotate(line, commandColor)),
|
|
288
|
+
Ansi.annotate(colors, label, Ansi.bold, labelColor),
|
|
289
|
+
...lines.map((line) => Ansi.annotate(colors, line, commandColor)),
|
|
282
290
|
""
|
|
283
291
|
].join("\n")
|
|
284
292
|
}
|
|
@@ -62,11 +62,22 @@ export const Persisted = Context.Reference<boolean>("effect/cluster/ClusterSchem
|
|
|
62
62
|
* The default value is `false`. When `true`, entity handling wraps server
|
|
63
63
|
* writes with the configured storage transaction.
|
|
64
64
|
*
|
|
65
|
+
* Persisted requests deliver terminal replies and mark requests processed only
|
|
66
|
+
* after commit or clean rollback. Success replies are saved in the transaction;
|
|
67
|
+
* failures are saved after rollback. If commit reports failure, a stored success
|
|
68
|
+
* reply is recovered. Otherwise, commit or rollback failures retry the request
|
|
69
|
+
* without delivering a reply. Handlers must tolerate retries.
|
|
70
|
+
*
|
|
65
71
|
* **Gotchas**
|
|
66
72
|
*
|
|
67
73
|
* This annotation has transactional behavior only when the configured
|
|
68
74
|
* `MessageStorage` implements it.
|
|
69
75
|
*
|
|
76
|
+
* Stream chunks are saved and delivered immediately, even if the transaction
|
|
77
|
+
* later rolls back. A handler returning a `Deferred` commits before its reply
|
|
78
|
+
* is saved. Non-persisted requests save no reply; successes are delivered when
|
|
79
|
+
* the handler exits, and failures after the transaction exits.
|
|
80
|
+
*
|
|
70
81
|
* @stability unstable
|
|
71
82
|
* @category services
|
|
72
83
|
* @since 4.0.0
|
|
@@ -95,6 +106,27 @@ export const Uninterruptible = Context.Reference<boolean | "client" | "server">(
|
|
|
95
106
|
{ defaultValue: constFalse }
|
|
96
107
|
)
|
|
97
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Annotation that interrupts a cluster request when entity termination starts,
|
|
111
|
+
* rather than waiting for the termination grace period to expire.
|
|
112
|
+
*
|
|
113
|
+
* **Details**
|
|
114
|
+
*
|
|
115
|
+
* The default value is `false`. Use for long-lived requests that cannot finish
|
|
116
|
+
* on their own. Persisted requests resume under the next owner without saving
|
|
117
|
+
* the interruption as a reply. Non-persisted requests receive an interrupt exit.
|
|
118
|
+
*
|
|
119
|
+
* Server-side `Uninterruptible` takes precedence over this annotation.
|
|
120
|
+
*
|
|
121
|
+
* @stability unstable
|
|
122
|
+
* @category services
|
|
123
|
+
* @since 4.0.0
|
|
124
|
+
*/
|
|
125
|
+
export const InterruptOnTermination = Context.Reference<boolean>(
|
|
126
|
+
"effect/cluster/ClusterSchema/InterruptOnTermination",
|
|
127
|
+
{ defaultValue: constFalse }
|
|
128
|
+
)
|
|
129
|
+
|
|
98
130
|
/**
|
|
99
131
|
* Returns whether the `Uninterruptible` annotation applies to server-side
|
|
100
132
|
* request handling for the provided context.
|
|
@@ -15,7 +15,6 @@ import * as Effect from "../Effect.ts"
|
|
|
15
15
|
import * as Exit from "../Exit.ts"
|
|
16
16
|
import * as Fiber from "../Fiber.ts"
|
|
17
17
|
import * as Headers from "../http/Headers.ts"
|
|
18
|
-
import * as Latch from "../Latch.ts"
|
|
19
18
|
import * as Layer from "../Layer.ts"
|
|
20
19
|
import * as Option from "../Option.ts"
|
|
21
20
|
import * as PrimaryKey from "../PrimaryKey.ts"
|
|
@@ -132,7 +131,6 @@ export const make = Effect.gen(function*() {
|
|
|
132
131
|
readonly context: Context.Context<any>
|
|
133
132
|
}>()
|
|
134
133
|
const interruptedActivities = new Set<string>()
|
|
135
|
-
const activityLatches = new Map<string, Latch.Latch>()
|
|
136
134
|
const deferredState = WorkflowEngine.makeDeferredState()
|
|
137
135
|
// Rebuilds share an activation; overlapping activations have separate results.
|
|
138
136
|
// Weak keys do not retain scopes, but contexts captured by clients, activities,
|
|
@@ -476,23 +474,19 @@ export const make = Effect.gen(function*() {
|
|
|
476
474
|
const activityId = `${executionId}/${payload.name}`
|
|
477
475
|
const instance = WorkflowEngine.WorkflowInstance.initial(workflow, executionId)
|
|
478
476
|
interruptedActivities.delete(activityId)
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
)
|
|
492
|
-
return yield* entry.activity.executeEncoded.pipe(
|
|
493
|
-
Effect.provideContext(context)
|
|
494
|
-
)
|
|
495
|
-
}).pipe(
|
|
477
|
+
const entry = activities.get(activityId)
|
|
478
|
+
if (!entry) {
|
|
479
|
+
// Replay may never register a losing race activity. Answer it
|
|
480
|
+
// without waiting; a later registration can reset this reply.
|
|
481
|
+
return Effect.succeed(new Workflow.Suspended({})).pipe(Rpc.wrap({ fork: true }))
|
|
482
|
+
}
|
|
483
|
+
const context = entry.context.pipe(
|
|
484
|
+
Context.add(WorkflowEngine.WorkflowInstance, instance),
|
|
485
|
+
Context.add(CurrentActivationScope, activation),
|
|
486
|
+
Context.add(Activity.CurrentAttempt, payload.attempt)
|
|
487
|
+
)
|
|
488
|
+
return entry.activity.executeEncoded.pipe(
|
|
489
|
+
Effect.provideContext(context),
|
|
496
490
|
Workflow.intoResult,
|
|
497
491
|
Effect.catchCause((cause) => {
|
|
498
492
|
// we only want to store interrupts as suspends when the
|
|
@@ -633,11 +627,6 @@ export const make = Effect.gen(function*() {
|
|
|
633
627
|
while (true) {
|
|
634
628
|
if (!activities.has(activityId)) {
|
|
635
629
|
activities.set(activityId, { activity, context: services })
|
|
636
|
-
const latch = activityLatches.get(activityId)
|
|
637
|
-
if (latch) {
|
|
638
|
-
yield* latch.open
|
|
639
|
-
activityLatches.delete(activityId)
|
|
640
|
-
}
|
|
641
630
|
}
|
|
642
631
|
const result = yield* Effect.orDie(
|
|
643
632
|
client.activity({
|