apps 0.0.1-beta.6 → 0.0.1-beta.61
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 +24 -21
- package/framework-reference.json +1 -1
- package/js/chunk-2A26IT3X.js +171 -0
- package/js/chunk-4HYFEAR7.js +49 -0
- package/js/chunk-5FHWNLCI.js +88 -0
- package/js/{chunk-M3B3DE4K.js → chunk-74YVXBKY.js} +463 -218
- package/js/{chunk-MNMNLXBL.js → chunk-7QBUFK6I.js} +316 -69
- package/js/{chunk-SB4HEPNJ.js → chunk-A4RQSTHG.js} +883 -189
- package/js/{chunk-T7GKZBLP.js → chunk-ANN7H2FL.js} +67 -55
- package/js/{chunk-NKLWZJLE.js → chunk-AQU56EPI.js} +9 -5
- package/js/chunk-CDXQDN7W.js +92 -0
- package/js/{chunk-UK573G7W.js → chunk-EOPQ727L.js} +87 -51
- package/js/{chunk-27F7W2LG.js → chunk-H2CJWXA3.js} +2 -2
- package/js/{chunk-JU7VHODU.js → chunk-H72MEDMN.js} +65 -10
- package/js/{chunk-CDL5PM2Q.js → chunk-IFJU5SYQ.js} +19082 -18402
- package/js/{chunk-VFZKSM3T.js → chunk-JPEUKEV4.js} +3 -3
- package/js/{chunk-RFVIONFX.js → chunk-JSAZHHWI.js} +79 -41
- package/js/{chunk-RJDDBDSN.js → chunk-K6P2US3D.js} +635 -89
- package/js/{chunk-5T57N25Q.js → chunk-KGCTYL2S.js} +511 -63
- package/js/{chunk-KUMBKVJD.js → chunk-KLYSEHUD.js} +2 -2
- package/js/chunk-MWKHKOTL.js +240 -0
- package/js/chunk-NFHURZBA.js +340 -0
- package/js/chunk-OD3KFKZD.js +1617 -0
- package/js/{chunk-57RKNWL2.js → chunk-PD6I2SDG.js} +4 -4
- package/js/{chunk-ITM77QPO.js → chunk-QE4JSN3X.js} +126 -31
- package/js/chunk-S34PXQUC.js +266 -0
- package/js/{chunk-B3EOZTK3.js → chunk-TLWLJ7PD.js} +2227 -453
- package/js/{chunk-IJX4CYZO.js → chunk-TUMGL2OC.js} +228 -264
- package/js/{chunk-ECQFRCH4.js → chunk-VHUR5HUL.js} +4 -3
- package/js/{chunk-IPI4MFSN.js → chunk-XBG7HHXC.js} +2 -2
- package/js/client.js +142 -94
- package/js/contracts.js +103 -26
- package/js/effect.js +19 -19
- package/js/{es-APDZKREY.js → es-DIULA3ZF.js} +62 -1659
- package/js/graphql.js +50 -40
- package/js/host.js +83 -58
- package/js/index.js +90 -61
- package/js/mcp/effect.js +23 -21
- package/js/mcp/stdio.js +44 -34
- package/js/mcp.js +76 -53
- package/js/openapi.js +4050 -1354
- package/js/react.js +2 -3
- package/js/skills/effect.js +6 -3
- package/js/skills.js +208 -81
- package/js/storage/facet.js +1 -540
- package/js/ui/auth/contracts.js +2 -2
- package/js/ui/auth.js +5 -5
- package/js/ui/contracts.js +5 -4
- package/js/ui/serving.js +8517 -214
- package/package.json +2 -3
- package/runtime.json +1 -1
- package/types/app-cache/src/index.d.ts +10 -1
- package/types/apps/src/contracts/api-response-error.d.ts +4 -0
- package/types/apps/src/contracts/app.d.ts +7 -3
- package/types/apps/src/contracts/cache.d.ts +20 -0
- package/types/apps/src/contracts/context.d.ts +19 -11
- package/types/apps/src/contracts/elicitation.d.ts +6 -6
- package/types/apps/src/contracts/events.d.ts +93 -0
- package/types/apps/src/contracts/failure.d.ts +30 -1
- package/types/apps/src/contracts/graphql.d.ts +2 -1
- package/types/apps/src/contracts/host.d.ts +48 -13
- package/types/apps/src/contracts/live.d.ts +2 -0
- package/types/apps/src/contracts/mcp.d.ts +80 -10
- package/types/apps/src/contracts/network.d.ts +84 -0
- package/types/apps/src/contracts/openapi-compile.d.ts +82 -3
- package/types/apps/src/contracts/openapi.d.ts +41 -9
- package/types/apps/src/contracts/operations.d.ts +8 -4
- package/types/apps/src/contracts/protocol-version.d.ts +2 -2
- package/types/apps/src/contracts/protocols/1.d.ts +733 -81
- package/types/apps/src/contracts/protocols/10.d.ts +1450 -0
- package/types/apps/src/contracts/protocols/2.d.ts +69 -26
- package/types/apps/src/contracts/protocols/3.d.ts +133 -33
- package/types/apps/src/contracts/protocols/4.d.ts +122 -45
- package/types/apps/src/contracts/protocols/5.d.ts +1200 -0
- package/types/apps/src/contracts/protocols/6.d.ts +1629 -0
- package/types/apps/src/contracts/protocols/7.d.ts +1785 -0
- package/types/apps/src/contracts/protocols/8.d.ts +1182 -0
- package/types/apps/src/contracts/protocols/9.d.ts +1104 -0
- package/types/apps/src/contracts/protocols/current.d.ts +2476 -0
- package/types/apps/src/contracts/protocols/oauth-6.d.ts +74 -0
- package/types/apps/src/contracts/protocols/oauth.d.ts +134 -0
- package/types/apps/src/contracts/provider-error.d.ts +9 -0
- package/types/apps/src/contracts/provider.d.ts +115 -10
- package/types/apps/src/contracts/skills.d.ts +50 -13
- package/types/apps/src/contracts/sql.d.ts +58 -0
- package/types/apps/src/contracts/ui.d.ts +19 -1
- package/types/apps/src/contracts/workflows.d.ts +6 -0
- package/types/apps/src/facet.d.ts +4 -5
- package/types/apps/src/host.d.ts +5 -0
- package/types/apps/src/implementation/account-router.d.ts +4 -3
- package/types/apps/src/implementation/authoring.d.ts +25 -5
- package/types/apps/src/implementation/browser-scripts.gen.d.ts +6 -0
- package/types/apps/src/implementation/cache.d.ts +4 -0
- package/types/apps/src/implementation/catalog-cache.d.ts +35 -4
- package/types/apps/src/implementation/elicitation.d.ts +18 -15
- package/types/apps/src/implementation/events.d.ts +59 -0
- package/types/apps/src/implementation/failure-detail.d.ts +25 -3
- package/types/apps/src/implementation/graphql-catalog.d.ts +3 -3
- package/types/apps/src/implementation/graphql.d.ts +4 -3
- package/types/apps/src/implementation/input-problems.d.ts +6 -2
- package/types/apps/src/implementation/invocation-timing.d.ts +16 -0
- package/types/apps/src/implementation/live.d.ts +2 -2
- package/types/apps/src/implementation/mcp-call.d.ts +6 -5
- package/types/apps/src/implementation/mcp-catalog.d.ts +6 -4
- package/types/apps/src/implementation/mcp-client.d.ts +17 -9
- package/types/apps/src/implementation/mcp-stdio.d.ts +1 -1
- package/types/apps/src/implementation/mcp-tools.d.ts +2 -1
- package/types/apps/src/implementation/mcp.d.ts +20 -9
- package/types/apps/src/implementation/network.d.ts +16 -0
- package/types/apps/src/implementation/openapi-compile.d.ts +26 -6
- package/types/apps/src/implementation/openapi-document.d.ts +46 -19
- package/types/apps/src/implementation/openapi-names.d.ts +9 -4
- package/types/apps/src/implementation/openapi-request.d.ts +10 -2
- package/types/apps/src/implementation/openapi-source.d.ts +18 -0
- package/types/apps/src/implementation/openapi-upgrade.d.ts +4 -0
- package/types/apps/src/implementation/operations.d.ts +17 -2
- package/types/apps/src/implementation/optimistic.d.ts +1 -1
- package/types/apps/src/implementation/protocol-operations.d.ts +3 -0
- package/types/apps/src/implementation/provider-error.d.ts +28 -1
- package/types/apps/src/implementation/provider.d.ts +19 -5
- package/types/apps/src/implementation/query-commit.d.ts +1 -1
- package/types/apps/src/implementation/router-catalog.d.ts +11 -13
- package/types/apps/src/implementation/router.d.ts +16 -5
- package/types/apps/src/implementation/runtime-yield.d.ts +7 -0
- package/types/apps/src/implementation/schema.d.ts +90 -10
- package/types/apps/src/implementation/skills.d.ts +18 -24
- package/types/apps/src/implementation/sql.d.ts +71 -0
- package/types/apps/src/implementation/ui-account-notice.d.ts +9 -0
- package/types/apps/src/implementation/ui-auth.d.ts +1 -1
- package/types/apps/src/implementation/ui-client.d.ts +2 -2
- package/types/apps/src/implementation/ui-document.d.ts +5 -0
- package/types/apps/src/implementation/ui-errors.d.ts +1 -1
- package/types/apps/src/implementation/ui-serving.d.ts +11 -5
- package/types/apps/src/implementation/ui-watch.d.ts +1 -1
- package/types/apps/src/implementation/upstream-error.d.ts +7 -0
- package/types/apps/src/implementation/webhooks.d.ts +1 -1
- package/types/apps/src/implementation/workflows.d.ts +1 -1
- package/types/apps/src/index.d.ts +30 -12
- package/types/apps/src/mcp.d.ts +20 -1
- package/types/apps/src/openapi.d.ts +1 -1
- package/types/apps/src/react.d.ts +1 -1
- package/types/apps/src/skills.d.ts +10 -8
- package/types/telemetry/src/app-records.d.ts +42 -0
- package/types/telemetry/src/browser-operations.d.ts +7 -4
- package/types/telemetry/src/browser.d.ts +8 -3
- package/types/telemetry/src/config.d.ts +2 -2
- package/types/telemetry/src/index.d.ts +1 -0
- package/types/telemetry/src/layer.d.ts +2 -2
- package/types/telemetry/src/ownership.d.ts +56 -0
- package/types/telemetry/src/recorded-failure.d.ts +29 -0
- package/types/telemetry/src/relay.d.ts +11 -3
- package/types/telemetry/src/transport.d.ts +8 -1
- package/types/utils/src/api-error.d.ts +55 -0
- package/types/utils/src/connection-failure.d.ts +33 -0
- package/types/utils/src/recorded-message.d.ts +18 -0
- package/types/utils/src/user-facing-error.d.ts +83 -0
- package/js/chunk-6BSSI67S.js +0 -224
- package/js/chunk-MKWZPDR6.js +0 -63
- package/js/chunk-N7YDVXYJ.js +0 -186
- package/js/chunk-OE3QQTSB.js +0 -222
- package/js/chunk-PJJ24GU7.js +0 -877
- package/js/chunk-PZB6T6KU.js +0 -19
- package/js/chunk-R3EV5FTO.js +0 -97
- package/js/chunk-ZQINWV4W.js +0 -630
- package/types/app-data/src/implementation/cursor.d.ts +0 -10
- package/types/app-data/src/implementation/index-key.d.ts +0 -7
- package/types/app-data/src/implementation/promise.d.ts +0 -68
- package/types/app-data/src/implementation/range.d.ts +0 -8
- package/types/app-data/src/implementation/schema.d.ts +0 -18
- package/types/app-data/src/implementation/sqlite.d.ts +0 -11
- package/types/app-data/src/index.d.ts +0 -4
- package/types/apps/src/contracts/storage.d.ts +0 -68
- package/types/apps/src/implementation/storage.d.ts +0 -15
|
@@ -1,37 +1,46 @@
|
|
|
1
1
|
import {
|
|
2
2
|
makeCache
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AQU56EPI.js";
|
|
4
4
|
import {
|
|
5
5
|
accountSecrets,
|
|
6
6
|
boundFailureMessage,
|
|
7
7
|
describeFailure,
|
|
8
8
|
failureDetail,
|
|
9
|
+
leavingProviderError,
|
|
10
|
+
parseMcpError,
|
|
11
|
+
parseSkillLoadFailed,
|
|
9
12
|
readCatalog,
|
|
10
13
|
routerSkills
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-7QBUFK6I.js";
|
|
15
|
+
import {
|
|
16
|
+
appInvocationFetch
|
|
17
|
+
} from "./chunk-4HYFEAR7.js";
|
|
12
18
|
import {
|
|
13
19
|
folderSkillsEffect
|
|
14
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-XBG7HHXC.js";
|
|
15
21
|
import {
|
|
16
|
-
|
|
22
|
+
ResponseStatusError,
|
|
23
|
+
declaredEvents,
|
|
17
24
|
isApp,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import {
|
|
22
|
-
parseDatabaseSchema
|
|
23
|
-
} from "./chunk-ZQINWV4W.js";
|
|
25
|
+
makeEmitter,
|
|
26
|
+
toEffectApp
|
|
27
|
+
} from "./chunk-S34PXQUC.js";
|
|
24
28
|
import {
|
|
25
29
|
declaredOperations,
|
|
26
|
-
fromPromise,
|
|
27
30
|
locate,
|
|
28
|
-
nativeOperation
|
|
29
|
-
|
|
30
|
-
} from "./chunk-T7GKZBLP.js";
|
|
31
|
+
nativeOperation
|
|
32
|
+
} from "./chunk-ANN7H2FL.js";
|
|
31
33
|
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
accountProviderError,
|
|
35
|
+
appCode,
|
|
36
|
+
fromPromise,
|
|
37
|
+
httpProviderError,
|
|
38
|
+
method,
|
|
39
|
+
parseProviderError,
|
|
40
|
+
toPromise
|
|
41
|
+
} from "./chunk-2A26IT3X.js";
|
|
34
42
|
import {
|
|
43
|
+
AccountCheckResult,
|
|
35
44
|
DeclaredProvider,
|
|
36
45
|
DeclaredRequirements,
|
|
37
46
|
ElicitationFailed,
|
|
@@ -58,9 +67,9 @@ import {
|
|
|
58
67
|
HostedWebhook,
|
|
59
68
|
HostedWorkflow,
|
|
60
69
|
InvocationDeadline,
|
|
70
|
+
InvocationTimingSink,
|
|
61
71
|
ManualWebhookSetup,
|
|
62
72
|
ManyAccounts,
|
|
63
|
-
McpError,
|
|
64
73
|
NonRetryableError,
|
|
65
74
|
OpenapiResponseError,
|
|
66
75
|
ResolvedAccounts,
|
|
@@ -76,42 +85,82 @@ import {
|
|
|
76
85
|
approvalElicitation,
|
|
77
86
|
defaultWebhookTransportLimits,
|
|
78
87
|
maxInputProblems,
|
|
88
|
+
migrationsDirectory,
|
|
89
|
+
reservedTablePrefix,
|
|
79
90
|
workflowDurationMillis
|
|
80
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-TLWLJ7PD.js";
|
|
81
92
|
import {
|
|
82
93
|
CacheError
|
|
83
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-MWKHKOTL.js";
|
|
84
95
|
import {
|
|
85
96
|
AppSkills,
|
|
86
|
-
SkillFile
|
|
87
|
-
|
|
88
|
-
} from "./chunk-JU7VHODU.js";
|
|
89
|
-
import {
|
|
90
|
-
captureTelemetry,
|
|
91
|
-
invocationFetch
|
|
92
|
-
} from "./chunk-RJDDBDSN.js";
|
|
97
|
+
SkillFile
|
|
98
|
+
} from "./chunk-H72MEDMN.js";
|
|
93
99
|
import {
|
|
100
|
+
allowedValues,
|
|
94
101
|
decoderOf,
|
|
102
|
+
echoableKey,
|
|
95
103
|
importedJsonSchema,
|
|
104
|
+
importedSchemaKeys,
|
|
96
105
|
jsonSchemaDecoder,
|
|
97
|
-
jsonSchemaDocument
|
|
98
|
-
|
|
106
|
+
jsonSchemaDocument,
|
|
107
|
+
maxAlternativeKeys,
|
|
108
|
+
missingKey,
|
|
109
|
+
missingKeyText,
|
|
110
|
+
objectShape,
|
|
111
|
+
unionShape
|
|
112
|
+
} from "./chunk-KGCTYL2S.js";
|
|
113
|
+
import {
|
|
114
|
+
captureTelemetry,
|
|
115
|
+
makeOwnershipAccounting,
|
|
116
|
+
measuredSpan,
|
|
117
|
+
owned
|
|
118
|
+
} from "./chunk-K6P2US3D.js";
|
|
99
119
|
import {
|
|
100
120
|
JsonObject,
|
|
101
121
|
JsonValue
|
|
102
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-H2CJWXA3.js";
|
|
103
123
|
import {
|
|
124
|
+
Base64_exports,
|
|
104
125
|
Cause_exports,
|
|
105
126
|
Clock_exports,
|
|
106
127
|
Effect_exports,
|
|
107
|
-
Encoding_exports,
|
|
108
128
|
Match_exports,
|
|
109
129
|
Option_exports,
|
|
110
130
|
Redacted_exports,
|
|
131
|
+
SchemaAST_exports,
|
|
111
132
|
SchemaIssue_exports,
|
|
112
133
|
Schema_exports,
|
|
113
134
|
Stream_exports
|
|
114
|
-
} from "./chunk-
|
|
135
|
+
} from "./chunk-IFJU5SYQ.js";
|
|
136
|
+
|
|
137
|
+
// src/implementation/invocation-timing.ts
|
|
138
|
+
var elicitationWaitSpan = "app.elicitation.wait";
|
|
139
|
+
var workflowControlSpan = "app.workflow.control";
|
|
140
|
+
var timedInvocation = (operation) => (effect) => Effect_exports.gen(function* () {
|
|
141
|
+
const report = yield* InvocationTimingSink;
|
|
142
|
+
return yield* effect.pipe(
|
|
143
|
+
measuredSpan(`app.${operation}`, {}, (start) => {
|
|
144
|
+
const accounting = makeOwnershipAccounting(start, "executor");
|
|
145
|
+
return {
|
|
146
|
+
around: accounting.observe,
|
|
147
|
+
end: (end, span) => {
|
|
148
|
+
const spent = accounting.read(end);
|
|
149
|
+
report({
|
|
150
|
+
elapsedMs: Number(end - start) / 1e6,
|
|
151
|
+
upstreamMs: spent.upstream,
|
|
152
|
+
elicitationMs: spent.person,
|
|
153
|
+
authoredMs: spent.app
|
|
154
|
+
});
|
|
155
|
+
span.attribute("executor.upstream.wait_ms", spent.upstream);
|
|
156
|
+
span.attribute("executor.elicitation.wait_ms", spent.person);
|
|
157
|
+
span.attribute("executor.authored_ms", spent.app);
|
|
158
|
+
span.attribute("executor.overhead_ms", spent.executor);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
})
|
|
162
|
+
);
|
|
163
|
+
});
|
|
115
164
|
|
|
116
165
|
// src/implementation/elicitation.ts
|
|
117
166
|
var prepareElicitation = (input) => Effect_exports.gen(function* () {
|
|
@@ -139,13 +188,17 @@ var prepareElicitation = (input) => Effect_exports.gen(function* () {
|
|
|
139
188
|
});
|
|
140
189
|
return { request, respond };
|
|
141
190
|
});
|
|
142
|
-
var makeElicit = (handler, signal) => toPromise(
|
|
191
|
+
var makeElicit = (handler, signal, telemetry) => toPromise(
|
|
143
192
|
(input) => Effect_exports.gen(function* () {
|
|
144
193
|
if (handler === void 0) return yield* new ElicitationFailed({ reason: "unavailable" });
|
|
145
194
|
const form = yield* prepareElicitation(input);
|
|
146
|
-
return yield* handler(form.request, signal).pipe(
|
|
195
|
+
return yield* handler(form.request, signal).pipe(
|
|
196
|
+
owned("person", elicitationWaitSpan),
|
|
197
|
+
Effect_exports.flatMap(form.respond)
|
|
198
|
+
);
|
|
147
199
|
}),
|
|
148
|
-
signal
|
|
200
|
+
signal,
|
|
201
|
+
telemetry
|
|
149
202
|
);
|
|
150
203
|
|
|
151
204
|
// src/contracts/approval.ts
|
|
@@ -231,10 +284,7 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
231
284
|
);
|
|
232
285
|
const step2 = yield* fresh(stepId, AbortSignal.any([signal, controller.signal]));
|
|
233
286
|
const result = yield* workflowSafe(
|
|
234
|
-
|
|
235
|
-
try: () => callback(step2.context),
|
|
236
|
-
catch: (error) => error
|
|
237
|
-
}),
|
|
287
|
+
fromPromise(callback, "step")(step2.context),
|
|
238
288
|
step2.secrets
|
|
239
289
|
);
|
|
240
290
|
return yield* Schema_exports.decodeUnknownEffect(WorkflowValue)(result).pipe(
|
|
@@ -315,15 +365,144 @@ var makeWorkflowContext = (execution, definition, fresh, signal) => Effect_expor
|
|
|
315
365
|
});
|
|
316
366
|
|
|
317
367
|
// src/implementation/input-problems.ts
|
|
318
|
-
var
|
|
368
|
+
var nativeObjectShape = (ast, limit) => objectShape(
|
|
369
|
+
ast.propertySignatures.flatMap(
|
|
370
|
+
({ name, type }) => typeof name === "string" ? [{ name, optional: SchemaAST_exports.isOptional(SchemaAST_exports.toEncoded(type)) }] : []
|
|
371
|
+
),
|
|
372
|
+
ast.indexSignatures.length > 0,
|
|
373
|
+
limit
|
|
374
|
+
);
|
|
375
|
+
var unionMembers = (ast) => SchemaAST_exports.isUnion(ast) ? ast.types.flatMap(unionMembers) : SchemaAST_exports.isUndefined(ast) || SchemaAST_exports.isVoid(ast) ? [] : [ast];
|
|
376
|
+
var fixedValues = (ast) => {
|
|
377
|
+
if (SchemaAST_exports.isLiteral(ast)) return [ast.literal];
|
|
378
|
+
if (SchemaAST_exports.isEnum(ast)) return ast.enums.map(([, value]) => value);
|
|
379
|
+
if (!SchemaAST_exports.isUnion(ast)) return void 0;
|
|
380
|
+
const members = unionMembers(ast).map(fixedValues);
|
|
381
|
+
return members.length > 0 && members.every((values) => values !== void 0) ? members.flat() : void 0;
|
|
382
|
+
};
|
|
383
|
+
var describeMember = (ast) => Match_exports.value(ast).pipe(
|
|
384
|
+
Match_exports.when(
|
|
385
|
+
SchemaAST_exports.isObjects,
|
|
386
|
+
(objects) => objects.propertySignatures.length > 0 ? nativeObjectShape(objects, maxAlternativeKeys) : "object"
|
|
387
|
+
),
|
|
388
|
+
Match_exports.when(SchemaAST_exports.isArrays, () => "array"),
|
|
389
|
+
Match_exports.when(SchemaAST_exports.isTemplateLiteral, () => "a string matching a template"),
|
|
390
|
+
Match_exports.when(SchemaAST_exports.isString, () => "string"),
|
|
391
|
+
Match_exports.when(SchemaAST_exports.isNumber, () => "number"),
|
|
392
|
+
Match_exports.when(SchemaAST_exports.isBoolean, () => "boolean"),
|
|
393
|
+
Match_exports.when(SchemaAST_exports.isNull, () => "null"),
|
|
394
|
+
Match_exports.orElse(() => "a value with other constraints")
|
|
395
|
+
);
|
|
396
|
+
var memberSelector = (members) => {
|
|
397
|
+
const [first] = members;
|
|
398
|
+
if (members.length < 2 || first === void 0 || !SchemaAST_exports.isObjects(first)) return void 0;
|
|
399
|
+
return first.propertySignatures.map(({ name }) => name).find(
|
|
400
|
+
(name) => typeof name === "string" && members.every(
|
|
401
|
+
(member) => SchemaAST_exports.isObjects(member) && member.propertySignatures.some(
|
|
402
|
+
(property) => property.name === name && fixedValues(SchemaAST_exports.toEncoded(property.type)) !== void 0
|
|
403
|
+
)
|
|
404
|
+
)
|
|
405
|
+
);
|
|
406
|
+
};
|
|
407
|
+
var unionExpectation = (ast) => {
|
|
408
|
+
const members = unionMembers(ast);
|
|
409
|
+
const fixed = members.map(fixedValues);
|
|
410
|
+
const values = fixed.flatMap((memberValues) => memberValues === void 0 ? [] : memberValues);
|
|
411
|
+
const others = members.filter((_, index) => fixed[index] === void 0);
|
|
412
|
+
if (others.length === 0) return allowedValues(values);
|
|
413
|
+
return unionShape(
|
|
414
|
+
[
|
|
415
|
+
...values.length === 0 ? [] : [allowedValues(values)],
|
|
416
|
+
...new Set(others.map(describeMember))
|
|
417
|
+
],
|
|
418
|
+
memberSelector(members)
|
|
419
|
+
);
|
|
420
|
+
};
|
|
421
|
+
var expectedUnion = (ast) => `Expected ${unionExpectation(ast)}`;
|
|
422
|
+
var expectedValue = (ast) => {
|
|
423
|
+
const encoded = SchemaAST_exports.toEncoded(ast);
|
|
424
|
+
const values = fixedValues(encoded);
|
|
425
|
+
if (values !== void 0) return allowedValues(values);
|
|
426
|
+
const members = unionMembers(encoded);
|
|
427
|
+
const [only] = members;
|
|
428
|
+
if (only === void 0) return void 0;
|
|
429
|
+
if (members.length > 1 && SchemaAST_exports.isUnion(encoded)) return unionExpectation(encoded);
|
|
430
|
+
if (SchemaAST_exports.isObjects(only) && only.propertySignatures.length > 0)
|
|
431
|
+
return nativeObjectShape(only);
|
|
432
|
+
const described = describeMember(only);
|
|
433
|
+
return described === "a value with other constraints" ? void 0 : described;
|
|
434
|
+
};
|
|
435
|
+
var leafHook = (issue) => SchemaIssue_exports.hasInput(issue) ? "Invalid value" : Match_exports.value(issue).pipe(
|
|
436
|
+
Match_exports.tag("InvalidType", ({ ast }) => {
|
|
437
|
+
const values = fixedValues(ast);
|
|
438
|
+
return values !== void 0 ? `Expected ${allowedValues(values)}` : SchemaAST_exports.isObjects(ast) && ast.propertySignatures.length > 0 ? `Expected ${nativeObjectShape(ast)}` : SchemaIssue_exports.defaultLeafHook(issue);
|
|
439
|
+
}),
|
|
440
|
+
Match_exports.orElse(SchemaIssue_exports.defaultLeafHook)
|
|
441
|
+
);
|
|
319
442
|
var checkHook = (issue) => SchemaIssue_exports.hasInput(issue) || SchemaIssue_exports.hasInput(issue.issue) ? SchemaIssue_exports.defaultCheckHook(issue) ?? "Invalid value" : SchemaIssue_exports.defaultCheckHook(issue);
|
|
320
443
|
var format = SchemaIssue_exports.makeFormatterStandardSchemaV1({ leafHook, checkHook });
|
|
321
|
-
var
|
|
322
|
-
var
|
|
444
|
+
var declaredKey = (parent, key) => parent !== void 0 && SchemaAST_exports.isObjects(parent) ? parent.propertySignatures.find(({ name }) => name === key)?.type : void 0;
|
|
445
|
+
var nativeKeys = (parent) => (key) => parent.indexSignatures.length > 0 || parent.propertySignatures.some(({ name }) => name === key);
|
|
446
|
+
var located = (issue, path, parent) => Match_exports.value(issue).pipe(
|
|
447
|
+
Match_exports.tag("Pointer", (pointer) => {
|
|
448
|
+
const declared = pointer.issue._tag === "MissingKey" && pointer.path.length === 1 ? declaredKey(parent, pointer.path[0]) : void 0;
|
|
449
|
+
return declared === void 0 || parent === void 0 || !SchemaAST_exports.isObjects(parent) ? located(pointer.issue, [...path, ...pointer.path]) : [
|
|
450
|
+
{
|
|
451
|
+
path: [...path, ...pointer.path],
|
|
452
|
+
message: missingKey(expectedValue(declared)),
|
|
453
|
+
accepts: nativeKeys(parent)
|
|
454
|
+
}
|
|
455
|
+
];
|
|
456
|
+
}),
|
|
457
|
+
Match_exports.tag(
|
|
458
|
+
"Composite",
|
|
459
|
+
({ ast, issues }) => issues.flatMap((issue2) => located(issue2, path, ast))
|
|
460
|
+
),
|
|
461
|
+
Match_exports.tag("Encoding", (encoding) => located(encoding.issue, path)),
|
|
462
|
+
Match_exports.tag(
|
|
463
|
+
"AnyOf",
|
|
464
|
+
({ ast, issues }) => issues.length === 0 ? [{ path, message: expectedUnion(ast) }] : issues.flatMap((issue2) => located(issue2, path))
|
|
465
|
+
),
|
|
466
|
+
Match_exports.orElse((issue2) => {
|
|
467
|
+
const accepts = issue2._tag === "Filter" ? importedSchemaKeys(issue2.filter) : void 0;
|
|
468
|
+
return format(issue2).issues.map((problem) => ({
|
|
469
|
+
path: [
|
|
470
|
+
...path,
|
|
471
|
+
...(problem.path ?? []).map((key) => typeof key === "object" ? key.key : key)
|
|
472
|
+
],
|
|
473
|
+
message: problem.message,
|
|
474
|
+
...accepts === void 0 ? {} : { accepts }
|
|
475
|
+
}));
|
|
476
|
+
})
|
|
477
|
+
);
|
|
478
|
+
var segment = (key) => typeof key === "number" ? `[${key}]` : typeof key === "string" && echoableKey(key) ? `.${key}` : "[key]";
|
|
479
|
+
var rendered = (path) => `input${path.map(segment).join("")}`;
|
|
480
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
481
|
+
var valueAt = (input, path) => path.reduce(
|
|
482
|
+
(value, key) => Array.isArray(value) && typeof key === "number" ? value[key] : isRecord(value) && typeof key === "string" && Object.hasOwn(value, key) ? value[key] : void 0,
|
|
483
|
+
input
|
|
484
|
+
);
|
|
485
|
+
var spelling = (key) => key.toLowerCase().replace(/[-_]/g, "");
|
|
486
|
+
var suppliedElsewhere = (input, path, accepts) => {
|
|
487
|
+
const key = path.at(-1);
|
|
488
|
+
if (typeof key !== "string" || !echoableKey(key)) return void 0;
|
|
489
|
+
const at = path.slice(0, -1);
|
|
490
|
+
const holder = valueAt(input, at);
|
|
491
|
+
if (!isRecord(holder)) return void 0;
|
|
492
|
+
const candidates = Object.keys(holder).filter((name) => echoableKey(name) && !accepts(name));
|
|
493
|
+
const respelled = candidates.find((name) => name !== key && spelling(name) === spelling(key));
|
|
494
|
+
const deeper = candidates.find((name) => {
|
|
495
|
+
const child = holder[name];
|
|
496
|
+
return isRecord(child) && Object.hasOwn(child, key);
|
|
497
|
+
});
|
|
498
|
+
const found = respelled !== void 0 ? [...at, respelled] : deeper !== void 0 ? [...at, deeper, key] : void 0;
|
|
499
|
+
return found === void 0 ? void 0 : `The input has ${String(found.at(-1))} at ${rendered(found)}; did you mean ${rendered(path)}?`;
|
|
500
|
+
};
|
|
501
|
+
var inputInvalid = (error, input) => {
|
|
323
502
|
if (!Schema_exports.isSchemaError(error)) return new HostInputInvalid();
|
|
324
|
-
const problems =
|
|
325
|
-
const
|
|
326
|
-
return `${
|
|
503
|
+
const problems = located(error.issue, []).slice(0, maxInputProblems).map(({ path, message, accepts }) => {
|
|
504
|
+
const elsewhere = accepts !== void 0 && message.startsWith(missingKeyText) ? suppliedElsewhere(input, path, accepts) : void 0;
|
|
505
|
+
return `${rendered(path)}: ${message}${elsewhere === void 0 ? "" : `. ${elsewhere}`}`.slice(
|
|
327
506
|
0,
|
|
328
507
|
512
|
|
329
508
|
);
|
|
@@ -430,7 +609,7 @@ var dispatchWebhook = (definition, command, context, accounts) => Effect_exports
|
|
|
430
609
|
yield* invoke(hook.unregister, { ...input, state });
|
|
431
610
|
return null;
|
|
432
611
|
}
|
|
433
|
-
const body = yield* Effect_exports.fromResult(
|
|
612
|
+
const body = yield* Effect_exports.fromResult(Base64_exports.decode(command.request.body)).pipe(
|
|
434
613
|
Effect_exports.mapError(() => new HostInputInvalid())
|
|
435
614
|
);
|
|
436
615
|
if (body.byteLength > defaultWebhookTransportLimits.maxBodyBytes)
|
|
@@ -463,7 +642,8 @@ var dispatchWebhook = (definition, command, context, accounts) => Effect_exports
|
|
|
463
642
|
return yield* new HostOutputInvalid();
|
|
464
643
|
chunks.push(chunk);
|
|
465
644
|
})
|
|
466
|
-
)
|
|
645
|
+
),
|
|
646
|
+
appCode("webhook")
|
|
467
647
|
);
|
|
468
648
|
const bytes = new Uint8Array(size);
|
|
469
649
|
let offset = 0;
|
|
@@ -479,30 +659,389 @@ var dispatchWebhook = (definition, command, context, accounts) => Effect_exports
|
|
|
479
659
|
() => Schema_exports.decodeUnknownEffect(WebhookResponseData)({
|
|
480
660
|
status: response.status,
|
|
481
661
|
headers,
|
|
482
|
-
body:
|
|
662
|
+
body: Base64_exports.encode(new Uint8Array(bytes))
|
|
483
663
|
}),
|
|
484
664
|
new HostOutputInvalid()
|
|
485
665
|
);
|
|
486
666
|
});
|
|
487
667
|
|
|
668
|
+
// src/implementation/sql.ts
|
|
669
|
+
var receipts = `${reservedTablePrefix}step_receipts`;
|
|
670
|
+
var stepEvents = `${reservedTablePrefix}step_events`;
|
|
671
|
+
var migrationsTable = `${reservedTablePrefix}migrations`;
|
|
672
|
+
var legacyRows = `${reservedTablePrefix}legacy_rows`;
|
|
673
|
+
var materialize = (cursor) => {
|
|
674
|
+
const rows = cursor.toArray();
|
|
675
|
+
return {
|
|
676
|
+
columnNames: cursor.columnNames,
|
|
677
|
+
rowsRead: cursor.rowsRead,
|
|
678
|
+
rowsWritten: cursor.rowsWritten,
|
|
679
|
+
toArray: () => [...rows],
|
|
680
|
+
one: () => {
|
|
681
|
+
if (rows.length !== 1)
|
|
682
|
+
throw new Error(`Expected exactly one row, but the statement returned ${rows.length}.`);
|
|
683
|
+
return rows[0];
|
|
684
|
+
},
|
|
685
|
+
[Symbol.iterator]: () => rows[Symbol.iterator]()
|
|
686
|
+
};
|
|
687
|
+
};
|
|
688
|
+
var isThenable = (value) => (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
|
|
689
|
+
var missingDatabase = () => {
|
|
690
|
+
throw new Error(
|
|
691
|
+
`This app has no database. Add its first migration, such as ${migrationsDirectory}/0001_create_notes.sql with a CREATE TABLE statement, and deploy again.`
|
|
692
|
+
);
|
|
693
|
+
};
|
|
694
|
+
var noDatabase = { exec: missingDatabase, transaction: missingDatabase };
|
|
695
|
+
var settings = [
|
|
696
|
+
"foreign_keys",
|
|
697
|
+
"defer_foreign_keys",
|
|
698
|
+
"ignore_check_constraints",
|
|
699
|
+
"legacy_alter_table",
|
|
700
|
+
"recursive_triggers",
|
|
701
|
+
"reverse_unordered_selects"
|
|
702
|
+
];
|
|
703
|
+
var readSettings = (storage) => new Map(
|
|
704
|
+
settings.map((name) => [name, Number(storage.sql.exec(`PRAGMA ${name}`).toArray()[0]?.[name])])
|
|
705
|
+
);
|
|
706
|
+
var changedSetting = (storage, baseline) => {
|
|
707
|
+
const current = readSettings(storage);
|
|
708
|
+
return settings.find((name) => current.get(name) !== baseline.get(name));
|
|
709
|
+
};
|
|
710
|
+
var restoreSettings = (storage, baseline) => {
|
|
711
|
+
const current = readSettings(storage);
|
|
712
|
+
for (const [name, value] of baseline)
|
|
713
|
+
if (current.get(name) !== value) storage.sql.exec(`PRAGMA ${name} = ${value}`);
|
|
714
|
+
storage.sql.exec("PRAGMA case_sensitive_like = OFF");
|
|
715
|
+
};
|
|
716
|
+
var ReadRolledBack = class extends Error {
|
|
717
|
+
};
|
|
718
|
+
var authorSql = (storage, options) => {
|
|
719
|
+
let closed = false;
|
|
720
|
+
const live = () => {
|
|
721
|
+
if (closed || options.signal.aborted)
|
|
722
|
+
throw new Error("This call has ended, so its ctx.sql no longer runs statements.");
|
|
723
|
+
};
|
|
724
|
+
let open = false;
|
|
725
|
+
let transactions = 0;
|
|
726
|
+
const baseline = readSettings(storage);
|
|
727
|
+
const checkSettings = () => {
|
|
728
|
+
const changed = changedSetting(storage, baseline);
|
|
729
|
+
if (changed !== void 0)
|
|
730
|
+
throw refuse(
|
|
731
|
+
new Error(
|
|
732
|
+
`SQLite connection settings belong to Executor, so app code cannot change PRAGMA ${changed}; the statement was rolled back. Migrations may change settings while they run.`
|
|
733
|
+
)
|
|
734
|
+
);
|
|
735
|
+
};
|
|
736
|
+
const changes = () => Number(storage.sql.exec("SELECT total_changes() AS n").toArray()[0]?.n);
|
|
737
|
+
let violation;
|
|
738
|
+
const refuse = (error) => {
|
|
739
|
+
if (open) violation ??= error;
|
|
740
|
+
return error;
|
|
741
|
+
};
|
|
742
|
+
const run = (query, bindings, mode) => {
|
|
743
|
+
try {
|
|
744
|
+
return runStatement(query, bindings, mode);
|
|
745
|
+
} finally {
|
|
746
|
+
restoreSettings(storage, baseline);
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
const runStatement = (query, bindings, mode) => {
|
|
750
|
+
live();
|
|
751
|
+
if (mode === "write") {
|
|
752
|
+
const statement = () => {
|
|
753
|
+
const cursor = materialize(storage.sql.exec(query, ...bindings));
|
|
754
|
+
checkSettings();
|
|
755
|
+
return cursor;
|
|
756
|
+
};
|
|
757
|
+
if (!open) return storage.transactionSync(statement);
|
|
758
|
+
try {
|
|
759
|
+
return statement();
|
|
760
|
+
} catch (error) {
|
|
761
|
+
refuse(error instanceof Error ? error : new Error(String(error)));
|
|
762
|
+
throw error;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (open) {
|
|
766
|
+
return runStatement(query, bindings, "write");
|
|
767
|
+
}
|
|
768
|
+
const before = changes();
|
|
769
|
+
let read;
|
|
770
|
+
let changed = false;
|
|
771
|
+
try {
|
|
772
|
+
storage.transactionSync(() => {
|
|
773
|
+
read = materialize(storage.sql.exec(query, ...bindings));
|
|
774
|
+
changed = changes() !== before;
|
|
775
|
+
checkSettings();
|
|
776
|
+
throw new ReadRolledBack();
|
|
777
|
+
});
|
|
778
|
+
} catch (error) {
|
|
779
|
+
if (!(error instanceof ReadRolledBack)) throw error;
|
|
780
|
+
}
|
|
781
|
+
if (changed || read === void 0)
|
|
782
|
+
throw new Error(
|
|
783
|
+
options.step !== void 0 ? "A workflow step mutation writes only inside ctx.sql.transaction(...), so a retried step applies its writes once." : "Queries are read-only. Change data from a mutation."
|
|
784
|
+
);
|
|
785
|
+
return read;
|
|
786
|
+
};
|
|
787
|
+
const reader = {
|
|
788
|
+
exec: (query, ...bindings) => run(query, bindings, "read")
|
|
789
|
+
};
|
|
790
|
+
const transactionHandle = () => {
|
|
791
|
+
let active = true;
|
|
792
|
+
const tx = {
|
|
793
|
+
exec: (query, ...bindings) => {
|
|
794
|
+
if (!active)
|
|
795
|
+
throw new Error("This transaction has ended, so its tx no longer runs statements.");
|
|
796
|
+
return run(query, bindings, "write");
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
return {
|
|
800
|
+
tx,
|
|
801
|
+
end: () => {
|
|
802
|
+
active = false;
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
};
|
|
806
|
+
const transaction = (work) => {
|
|
807
|
+
live();
|
|
808
|
+
if (open) throw new Error("ctx.sql.transaction(...) cannot be nested.");
|
|
809
|
+
const step = options.step;
|
|
810
|
+
if (step !== void 0 && transactions > 0)
|
|
811
|
+
throw new Error(
|
|
812
|
+
"A workflow step mutation opens at most one ctx.sql.transaction(...), which records the step's result."
|
|
813
|
+
);
|
|
814
|
+
transactions += 1;
|
|
815
|
+
violation = void 0;
|
|
816
|
+
const handle = transactionHandle();
|
|
817
|
+
const emittedBefore = options.emitted?.length;
|
|
818
|
+
const discardEmitted = () => {
|
|
819
|
+
if (options.emitted !== void 0 && emittedBefore !== void 0)
|
|
820
|
+
options.emitted.length = emittedBefore;
|
|
821
|
+
};
|
|
822
|
+
const body = () => {
|
|
823
|
+
open = true;
|
|
824
|
+
try {
|
|
825
|
+
const complete = () => {
|
|
826
|
+
const value = work(handle.tx);
|
|
827
|
+
if (isThenable(value))
|
|
828
|
+
throw new Error(
|
|
829
|
+
"ctx.sql.transaction(...) callbacks are synchronous and cannot await. Call outside services before or after the transaction."
|
|
830
|
+
);
|
|
831
|
+
if (violation !== void 0) throw violation;
|
|
832
|
+
return value;
|
|
833
|
+
};
|
|
834
|
+
if (step === void 0) return complete();
|
|
835
|
+
storage.sql.exec(
|
|
836
|
+
`CREATE TABLE IF NOT EXISTS ${receipts} (id TEXT PRIMARY KEY, fingerprint TEXT NOT NULL, result TEXT NOT NULL) WITHOUT ROWID`
|
|
837
|
+
);
|
|
838
|
+
const saved = storage.sql.exec(`SELECT fingerprint, result FROM ${receipts} WHERE id = ?`, step.key).toArray()[0];
|
|
839
|
+
storage.sql.exec(
|
|
840
|
+
`CREATE TABLE IF NOT EXISTS ${stepEvents} (id TEXT PRIMARY KEY, events TEXT NOT NULL) WITHOUT ROWID`
|
|
841
|
+
);
|
|
842
|
+
if (saved !== void 0) {
|
|
843
|
+
if (saved.fingerprint !== step.fingerprint)
|
|
844
|
+
throw new Error("This workflow step already ran with different input.");
|
|
845
|
+
const replayed = storage.sql.exec(`SELECT events FROM ${stepEvents} WHERE id = ?`, step.key).toArray()[0];
|
|
846
|
+
if (replayed !== void 0 && options.emitted !== void 0)
|
|
847
|
+
options.emitted.push(...JSON.parse(String(replayed.events)));
|
|
848
|
+
return JSON.parse(String(saved.result));
|
|
849
|
+
}
|
|
850
|
+
const encoded = JSON.stringify(complete() ?? null);
|
|
851
|
+
const emitted = options.emitted?.slice(emittedBefore ?? 0) ?? [];
|
|
852
|
+
if (emitted.length > 0)
|
|
853
|
+
storage.sql.exec(
|
|
854
|
+
`INSERT INTO ${stepEvents} (id, events) VALUES (?, ?)`,
|
|
855
|
+
step.key,
|
|
856
|
+
JSON.stringify(emitted)
|
|
857
|
+
);
|
|
858
|
+
storage.sql.exec(
|
|
859
|
+
`INSERT INTO ${receipts} (id, fingerprint, result) VALUES (?, ?, ?)`,
|
|
860
|
+
step.key,
|
|
861
|
+
step.fingerprint,
|
|
862
|
+
encoded
|
|
863
|
+
);
|
|
864
|
+
return JSON.parse(encoded);
|
|
865
|
+
} finally {
|
|
866
|
+
open = false;
|
|
867
|
+
handle.end();
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
try {
|
|
871
|
+
return storage.transactionSync(body);
|
|
872
|
+
} catch (error) {
|
|
873
|
+
discardEmitted();
|
|
874
|
+
throw error;
|
|
875
|
+
}
|
|
876
|
+
};
|
|
877
|
+
const writer = {
|
|
878
|
+
// A step's writes go through its one transaction, which also records its receipt.
|
|
879
|
+
exec: (query, ...bindings) => run(query, bindings, options.step ? "read" : "write"),
|
|
880
|
+
transaction
|
|
881
|
+
};
|
|
882
|
+
return {
|
|
883
|
+
reader,
|
|
884
|
+
writer,
|
|
885
|
+
close: () => {
|
|
886
|
+
closed = true;
|
|
887
|
+
}
|
|
888
|
+
};
|
|
889
|
+
};
|
|
890
|
+
var MigrationFileInvalid = class extends Schema_exports.TaggedError()(
|
|
891
|
+
"MigrationFileInvalid",
|
|
892
|
+
{ path: Schema_exports.String, reason: Schema_exports.String }
|
|
893
|
+
) {
|
|
894
|
+
get message() {
|
|
895
|
+
return `${this.path}: ${this.reason}`;
|
|
896
|
+
}
|
|
897
|
+
};
|
|
898
|
+
var MigrationHistoryChanged = class extends Schema_exports.TaggedError()(
|
|
899
|
+
"MigrationHistoryChanged",
|
|
900
|
+
{ reason: Schema_exports.String }
|
|
901
|
+
) {
|
|
902
|
+
get message() {
|
|
903
|
+
return `${this.reason} Applied migrations cannot change: restore the original file and add a new migration instead. Nothing was applied; the previous deployment is still active.`;
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
var MigrationFailed = class extends Schema_exports.TaggedError()("MigrationFailed", {
|
|
907
|
+
path: Schema_exports.String,
|
|
908
|
+
reason: Schema_exports.String
|
|
909
|
+
}) {
|
|
910
|
+
get message() {
|
|
911
|
+
return `${this.path} failed: ${this.reason}. No migrations were applied; the previous deployment is still active.`;
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
var migrationName = /^(\d+)_[A-Za-z0-9_-]+\.sql$/;
|
|
915
|
+
var sha256 = (text) => (
|
|
916
|
+
// oxlint-disable-next-line executor/authored-code-through-adapter -- Web Crypto
|
|
917
|
+
Effect_exports.promise(() => crypto.subtle.digest("SHA-256", new TextEncoder().encode(text))).pipe(
|
|
918
|
+
Effect_exports.map(
|
|
919
|
+
(digest) => Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("")
|
|
920
|
+
)
|
|
921
|
+
)
|
|
922
|
+
);
|
|
923
|
+
var hasMigrations = (files) => files.some(
|
|
924
|
+
(file) => file.path.startsWith(`${migrationsDirectory}/`) && file.path.endsWith(".sql")
|
|
925
|
+
);
|
|
926
|
+
var migrationsOf = (files) => Effect_exports.gen(function* () {
|
|
927
|
+
const found = [];
|
|
928
|
+
for (const file of files) {
|
|
929
|
+
if (!file.path.startsWith(`${migrationsDirectory}/`) || !file.path.endsWith(".sql")) continue;
|
|
930
|
+
const name = file.path.slice(migrationsDirectory.length + 1);
|
|
931
|
+
const match = migrationName.exec(name);
|
|
932
|
+
if (name.includes("/") || match === null)
|
|
933
|
+
return yield* new MigrationFileInvalid({
|
|
934
|
+
path: file.path,
|
|
935
|
+
reason: "migrations are files directly in migrations/ named like 0001_create_notes.sql: a number that orders them, an underscore, then a name."
|
|
936
|
+
});
|
|
937
|
+
const content = file.content.replaceAll("\r\n", "\n");
|
|
938
|
+
found.push({
|
|
939
|
+
path: file.path,
|
|
940
|
+
order: Number(match[1]),
|
|
941
|
+
content,
|
|
942
|
+
hash: yield* sha256(content)
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
const ordered = [...found].sort((left, right) => left.order - right.order);
|
|
946
|
+
for (const [index, migration] of ordered.entries()) {
|
|
947
|
+
const previous = ordered[index - 1];
|
|
948
|
+
if (previous !== void 0 && previous.order === migration.order)
|
|
949
|
+
return yield* new MigrationFileInvalid({
|
|
950
|
+
path: migration.path,
|
|
951
|
+
reason: `it has the same number as ${previous.path}; give each migration its own number.`
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
return ordered;
|
|
955
|
+
});
|
|
956
|
+
var History = Schema_exports.Array(
|
|
957
|
+
Schema_exports.Struct({ id: Schema_exports.Number, path: Schema_exports.String, hash: Schema_exports.String })
|
|
958
|
+
);
|
|
959
|
+
var migrate = (storage, files) => Effect_exports.gen(function* () {
|
|
960
|
+
const migrations = yield* migrationsOf(files);
|
|
961
|
+
const baseline = readSettings(storage);
|
|
962
|
+
return yield* Effect_exports.sync(
|
|
963
|
+
() => storage.transactionSync(() => {
|
|
964
|
+
storage.sql.exec(
|
|
965
|
+
`CREATE TABLE IF NOT EXISTS ${migrationsTable} (id INTEGER PRIMARY KEY, path TEXT NOT NULL, hash TEXT NOT NULL, applied_at TEXT NOT NULL)`
|
|
966
|
+
);
|
|
967
|
+
const stored = storage.sql.exec("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'app_rows'").toArray().length > 0;
|
|
968
|
+
storage.sql.exec(`DROP VIEW IF EXISTS ${legacyRows}`);
|
|
969
|
+
storage.sql.exec(
|
|
970
|
+
`CREATE VIEW ${legacyRows} (table_name, id, body) AS ${stored ? "SELECT table_name, id, body FROM app_rows" : "SELECT '', '', '' WHERE 0"}`
|
|
971
|
+
);
|
|
972
|
+
const history = Schema_exports.decodeUnknownSync(History)(
|
|
973
|
+
storage.sql.exec(`SELECT id, path, hash FROM ${migrationsTable} ORDER BY id`).toArray()
|
|
974
|
+
);
|
|
975
|
+
for (const [index, applied] of history.entries()) {
|
|
976
|
+
const current = migrations[index];
|
|
977
|
+
if (current === void 0)
|
|
978
|
+
throw new MigrationHistoryChanged({
|
|
979
|
+
reason: `${applied.path} was applied to this app's database but is no longer in migrations/.`
|
|
980
|
+
});
|
|
981
|
+
if (current.path !== applied.path)
|
|
982
|
+
throw new MigrationHistoryChanged({
|
|
983
|
+
reason: `Migration ${index + 1} was applied as ${applied.path}, but the build has ${current.path} in its place.`
|
|
984
|
+
});
|
|
985
|
+
if (current.hash !== applied.hash)
|
|
986
|
+
throw new MigrationHistoryChanged({
|
|
987
|
+
reason: `${applied.path} changed after it was applied to this app's database.`
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
const pending = migrations.slice(history.length);
|
|
991
|
+
const appliedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
992
|
+
for (const [offset, migration] of pending.entries()) {
|
|
993
|
+
try {
|
|
994
|
+
storage.sql.exec(migration.content);
|
|
995
|
+
} catch (error) {
|
|
996
|
+
throw new MigrationFailed({
|
|
997
|
+
path: migration.path,
|
|
998
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
storage.sql.exec(
|
|
1002
|
+
`INSERT INTO ${migrationsTable} (id, path, hash, applied_at) VALUES (?, ?, ?, ?)`,
|
|
1003
|
+
history.length + offset + 1,
|
|
1004
|
+
migration.path,
|
|
1005
|
+
migration.hash,
|
|
1006
|
+
appliedAt
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
return pending.map((migration, offset) => ({
|
|
1010
|
+
id: history.length + offset + 1,
|
|
1011
|
+
name: migration.path
|
|
1012
|
+
}));
|
|
1013
|
+
})
|
|
1014
|
+
).pipe(
|
|
1015
|
+
// Both are thrown inside the transaction so that it rolls back; they are expected failures.
|
|
1016
|
+
Effect_exports.catchDefect(
|
|
1017
|
+
(defect) => Schema_exports.is(MigrationFailed)(defect) || Schema_exports.is(MigrationHistoryChanged)(defect) ? Effect_exports.fail(defect) : Effect_exports.die(defect)
|
|
1018
|
+
),
|
|
1019
|
+
Effect_exports.ensuring(Effect_exports.sync(() => restoreSettings(storage, baseline)))
|
|
1020
|
+
);
|
|
1021
|
+
});
|
|
1022
|
+
|
|
488
1023
|
// src/implementation/cache.ts
|
|
489
1024
|
var unavailableCache = {
|
|
490
1025
|
transport: () => Effect_exports.fail(new CacheError({ reason: "unavailable" })),
|
|
491
1026
|
background: () => Effect_exports.die(new Error("Cache background runner is unavailable"))
|
|
492
1027
|
};
|
|
493
|
-
var authorCache = (host, accounts, signal, deadline) => {
|
|
1028
|
+
var authorCache = (host, accounts, signal, telemetry, deadline) => {
|
|
494
1029
|
const scoped = (scope, callerSignal = signal) => {
|
|
495
1030
|
const cache = makeCache(host.transport, host.background, scope, deadline);
|
|
496
|
-
const load = (
|
|
1031
|
+
const load = (read, options) => cache[read]({
|
|
497
1032
|
key: options.key,
|
|
498
1033
|
schema: decoderOf(options.schema),
|
|
499
1034
|
freshFor: options.freshFor,
|
|
500
1035
|
...options.staleFor === void 0 ? {} : { staleFor: options.staleFor },
|
|
1036
|
+
...options.stale === void 0 ? {} : { stale: options.stale },
|
|
501
1037
|
load: Effect_exports.acquireUseRelease(
|
|
502
1038
|
Effect_exports.sync(() => new AbortController()),
|
|
503
|
-
(controller) =>
|
|
1039
|
+
(controller) => appInvocationFetch(controller.signal).pipe(
|
|
504
1040
|
Effect_exports.flatMap(
|
|
505
|
-
(fetch) => fromPromise(
|
|
1041
|
+
(fetch) => fromPromise(
|
|
1042
|
+
method(options, "load"),
|
|
1043
|
+
"loader"
|
|
1044
|
+
)({
|
|
506
1045
|
fetch,
|
|
507
1046
|
signal: controller.signal,
|
|
508
1047
|
cache: scoped(scope, controller.signal)
|
|
@@ -512,22 +1051,30 @@ var authorCache = (host, accounts, signal, deadline) => {
|
|
|
512
1051
|
(controller) => Effect_exports.sync(() => controller.abort())
|
|
513
1052
|
)
|
|
514
1053
|
});
|
|
1054
|
+
const service = (method2, operation) => toPromise(
|
|
1055
|
+
(...args) => operation(...args).pipe(
|
|
1056
|
+
owned("executor", "app.cache.call", { attributes: { "cache.method": method2 } })
|
|
1057
|
+
),
|
|
1058
|
+
callerSignal,
|
|
1059
|
+
telemetry
|
|
1060
|
+
);
|
|
515
1061
|
return {
|
|
516
|
-
get:
|
|
517
|
-
revalidate:
|
|
518
|
-
|
|
519
|
-
|
|
1062
|
+
get: service("get", (options) => load("get", options)),
|
|
1063
|
+
revalidate: service(
|
|
1064
|
+
"revalidate",
|
|
1065
|
+
(options) => load("revalidate", options)
|
|
520
1066
|
),
|
|
521
|
-
read:
|
|
1067
|
+
read: service(
|
|
1068
|
+
"read",
|
|
522
1069
|
(key, schema) => cache.read([key]).pipe(
|
|
523
1070
|
Effect_exports.flatMap((entries) => {
|
|
524
1071
|
const entry = entries[0];
|
|
525
1072
|
return entry === void 0 || entry === null ? Effect_exports.succeed(void 0) : Schema_exports.decodeUnknownEffect(decoderOf(schema))(entry.value);
|
|
526
1073
|
})
|
|
527
|
-
)
|
|
528
|
-
callerSignal
|
|
1074
|
+
)
|
|
529
1075
|
),
|
|
530
|
-
readMany:
|
|
1076
|
+
readMany: service(
|
|
1077
|
+
"readMany",
|
|
531
1078
|
(keys, schema) => cache.read(keys).pipe(
|
|
532
1079
|
Effect_exports.flatMap(
|
|
533
1080
|
(entries) => Effect_exports.forEach(
|
|
@@ -535,11 +1082,10 @@ var authorCache = (host, accounts, signal, deadline) => {
|
|
|
535
1082
|
(entry) => entry === null ? Effect_exports.succeed(void 0) : Schema_exports.decodeUnknownEffect(decoderOf(schema))(entry.value)
|
|
536
1083
|
)
|
|
537
1084
|
)
|
|
538
|
-
)
|
|
539
|
-
callerSignal
|
|
1085
|
+
)
|
|
540
1086
|
),
|
|
541
|
-
write:
|
|
542
|
-
invalidate:
|
|
1087
|
+
write: service("write", cache.write),
|
|
1088
|
+
invalidate: service("invalidate", cache.invalidate),
|
|
543
1089
|
forAccount: (account) => {
|
|
544
1090
|
const bound = Object.values(accounts).flatMap((value) => Array.isArray(value) ? value : [value]).find((value) => value.id === account.id);
|
|
545
1091
|
if (bound === void 0) throw new CacheError({ reason: "invalid" });
|
|
@@ -571,9 +1117,9 @@ var evaluationSafe = (work, secrets) => work.pipe(
|
|
|
571
1117
|
const error = Cause_exports.squash(cause);
|
|
572
1118
|
const provider = parseProviderError(error);
|
|
573
1119
|
const skills = parseSkillLoadFailed(error);
|
|
574
|
-
const mcp = parseMcpError(error);
|
|
1120
|
+
const mcp = parseMcpError(error, secrets);
|
|
575
1121
|
return Effect_exports.fail(
|
|
576
|
-
Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed(failureDetail(error, secrets))
|
|
1122
|
+
Option_exports.isSome(provider) ? leavingProviderError(provider.value, secrets, "discover") : Option_exports.isSome(skills) ? skills.value : Option_exports.isSome(mcp) ? mcp.value : new HostEvaluationFailed(failureDetail(error, secrets))
|
|
577
1123
|
);
|
|
578
1124
|
})
|
|
579
1125
|
);
|
|
@@ -590,54 +1136,70 @@ var declarationSafe = (work, summary) => Effect_exports.suspend(work).pipe(
|
|
|
590
1136
|
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(declarationInvalid(summary, Cause_exports.squash(cause)))
|
|
591
1137
|
)
|
|
592
1138
|
);
|
|
1139
|
+
function declaredExposure(exposure) {
|
|
1140
|
+
const named = (kind) => Object.entries(exposure ?? {}).filter(([, value]) => value === kind).map(([field]) => field).sort();
|
|
1141
|
+
const plain = named("plain");
|
|
1142
|
+
const raw = named("raw");
|
|
1143
|
+
return { ...plain.length === 0 ? {} : { plain }, ...raw.length === 0 ? {} : { raw } };
|
|
1144
|
+
}
|
|
593
1145
|
function providerDeclaration(provider) {
|
|
594
1146
|
return declarationSafe(
|
|
595
1147
|
() => Effect_exports.gen(function* () {
|
|
596
1148
|
const auth = /* @__PURE__ */ new Map();
|
|
597
|
-
for (const [name,
|
|
598
|
-
switch (
|
|
1149
|
+
for (const [name, method2] of Object.entries(provider.auth)) {
|
|
1150
|
+
switch (method2._tag) {
|
|
599
1151
|
case "secrets":
|
|
600
1152
|
auth.set(name, {
|
|
601
1153
|
type: "secrets",
|
|
602
|
-
label:
|
|
603
|
-
fields: yield* jsonSchemaDocument(
|
|
1154
|
+
label: method2.label,
|
|
1155
|
+
fields: yield* jsonSchemaDocument(method2.fields),
|
|
1156
|
+
...declaredExposure(method2.exposure)
|
|
604
1157
|
});
|
|
605
1158
|
break;
|
|
606
1159
|
case "oauth2":
|
|
607
1160
|
auth.set(name, {
|
|
608
1161
|
type: "oauth2",
|
|
609
|
-
...
|
|
610
|
-
response: yield* jsonSchemaDocument(
|
|
1162
|
+
...method2.config,
|
|
1163
|
+
response: yield* jsonSchemaDocument(method2.response),
|
|
1164
|
+
...declaredExposure(method2.exposure)
|
|
611
1165
|
});
|
|
612
1166
|
break;
|
|
613
1167
|
}
|
|
614
1168
|
}
|
|
615
1169
|
return yield* Schema_exports.decodeUnknownEffect(DeclaredProvider)({
|
|
616
1170
|
name: provider.name,
|
|
617
|
-
auth: Object.fromEntries(auth)
|
|
1171
|
+
auth: Object.fromEntries(auth),
|
|
1172
|
+
// Order and repetition carry no meaning, so neither changes the provider's identity.
|
|
1173
|
+
...provider.hosts === void 0 ? {} : { hosts: [...new Set(provider.hosts)].sort() }
|
|
618
1174
|
});
|
|
619
1175
|
}),
|
|
620
1176
|
`Account provider "${provider.name}" has an invalid declaration`
|
|
621
1177
|
);
|
|
622
1178
|
}
|
|
623
|
-
function requirements(slots,
|
|
1179
|
+
function requirements(slots, sql, events) {
|
|
624
1180
|
return Effect_exports.gen(function* () {
|
|
625
1181
|
const accounts = /* @__PURE__ */ new Map();
|
|
626
1182
|
for (const [slot, selection] of Object.entries(slots)) {
|
|
1183
|
+
const provider = selection instanceof ManyAccounts ? selection.provider : selection;
|
|
627
1184
|
accounts.set(slot, {
|
|
628
1185
|
cardinality: selection instanceof ManyAccounts ? "many" : "one",
|
|
629
|
-
definition: yield* providerDeclaration(
|
|
630
|
-
|
|
631
|
-
)
|
|
1186
|
+
definition: yield* providerDeclaration(provider),
|
|
1187
|
+
...provider.health === void 0 ? {} : { health: true }
|
|
632
1188
|
});
|
|
633
1189
|
}
|
|
634
1190
|
return yield* Schema_exports.decodeUnknownEffect(DeclaredRequirements)({
|
|
635
1191
|
accounts: Object.fromEntries(accounts),
|
|
636
1192
|
capabilities: { skills: true, toolIndex: true, skillSources: true, scheduledTools: true },
|
|
637
|
-
...
|
|
1193
|
+
...sql ? { sql: true } : {},
|
|
1194
|
+
...events === void 0 || Object.keys(events).length === 0 ? {} : {
|
|
1195
|
+
events: yield* declarationSafe(
|
|
1196
|
+
() => declaredEvents(events),
|
|
1197
|
+
"The app's event declarations are invalid"
|
|
1198
|
+
)
|
|
1199
|
+
}
|
|
638
1200
|
}).pipe(
|
|
639
1201
|
Effect_exports.mapError(
|
|
640
|
-
(cause) => declarationInvalid("The app's account
|
|
1202
|
+
(cause) => declarationInvalid("The app's account declarations are invalid", cause)
|
|
641
1203
|
)
|
|
642
1204
|
);
|
|
643
1205
|
});
|
|
@@ -649,6 +1211,9 @@ function canonical(value) {
|
|
|
649
1211
|
}
|
|
650
1212
|
return JSON.stringify(value);
|
|
651
1213
|
}
|
|
1214
|
+
function withoutHosts({ hosts: _hosts, ...provider }) {
|
|
1215
|
+
return provider;
|
|
1216
|
+
}
|
|
652
1217
|
function bindAccounts(slots, declarations, context) {
|
|
653
1218
|
return safe2(
|
|
654
1219
|
() => Effect_exports.gen(function* () {
|
|
@@ -674,12 +1239,12 @@ function bindAccounts(slots, declarations, context) {
|
|
|
674
1239
|
for (const account of accounts) {
|
|
675
1240
|
if (ids.has(account.id)) return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
676
1241
|
ids.add(account.id);
|
|
677
|
-
if (canonical(account.provider) !== canonical(requirement.definition) || !Object.hasOwn(provider.auth, account.method))
|
|
1242
|
+
if (canonical(withoutHosts(account.provider)) !== canonical(withoutHosts(requirement.definition)) || !Object.hasOwn(provider.auth, account.method))
|
|
678
1243
|
return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
679
|
-
const
|
|
680
|
-
if (
|
|
1244
|
+
const method2 = provider.auth[account.method];
|
|
1245
|
+
if (method2 === void 0) return yield* Effect_exports.fail(new HostAccountsInvalid());
|
|
681
1246
|
const fields = yield* Schema_exports.decodeUnknownEffect(
|
|
682
|
-
|
|
1247
|
+
method2._tag === "secrets" ? method2.fields : method2.response
|
|
683
1248
|
)(account.fields);
|
|
684
1249
|
values.push({ id: account.id, method: account.method, fields });
|
|
685
1250
|
}
|
|
@@ -695,7 +1260,42 @@ function bindAccounts(slots, declarations, context) {
|
|
|
695
1260
|
new HostAccountsInvalid()
|
|
696
1261
|
);
|
|
697
1262
|
}
|
|
698
|
-
|
|
1263
|
+
var fetchLifetime = (signal, background) => Effect_exports.acquireRelease(
|
|
1264
|
+
Effect_exports.sync(() => {
|
|
1265
|
+
const controller = new AbortController();
|
|
1266
|
+
let refreshes = 0;
|
|
1267
|
+
let ended = false;
|
|
1268
|
+
const settle = () => {
|
|
1269
|
+
if (ended && refreshes === 0) controller.abort();
|
|
1270
|
+
};
|
|
1271
|
+
const end = () => {
|
|
1272
|
+
ended = true;
|
|
1273
|
+
settle();
|
|
1274
|
+
};
|
|
1275
|
+
signal.addEventListener("abort", end, { once: true });
|
|
1276
|
+
if (signal.aborted) end();
|
|
1277
|
+
const settled = Effect_exports.sync(() => {
|
|
1278
|
+
refreshes -= 1;
|
|
1279
|
+
settle();
|
|
1280
|
+
});
|
|
1281
|
+
return {
|
|
1282
|
+
signal: controller.signal,
|
|
1283
|
+
close: () => {
|
|
1284
|
+
signal.removeEventListener("abort", end);
|
|
1285
|
+
end();
|
|
1286
|
+
},
|
|
1287
|
+
/** Counted from the hand-off, so a refresh that has not started yet keeps the fetch. */
|
|
1288
|
+
background: (task) => Effect_exports.suspend(() => {
|
|
1289
|
+
refreshes += 1;
|
|
1290
|
+
return background(task.pipe(Effect_exports.ensuring(settled))).pipe(
|
|
1291
|
+
Effect_exports.onError(() => settled)
|
|
1292
|
+
);
|
|
1293
|
+
})
|
|
1294
|
+
};
|
|
1295
|
+
}),
|
|
1296
|
+
(lifetime) => Effect_exports.sync(lifetime.close)
|
|
1297
|
+
);
|
|
1298
|
+
function dispatch(app, request, context, signal, emitted) {
|
|
699
1299
|
return Effect_exports.scoped(
|
|
700
1300
|
Effect_exports.gen(function* () {
|
|
701
1301
|
if (!isApp(app))
|
|
@@ -704,28 +1304,52 @@ function dispatch(app, request, context, signal) {
|
|
|
704
1304
|
);
|
|
705
1305
|
const native = toEffectApp(app);
|
|
706
1306
|
const secrets = accountSecrets(context.accounts);
|
|
707
|
-
const
|
|
708
|
-
const declared = yield* requirements(native.accounts, native.
|
|
709
|
-
if (request.operation === "requirements")
|
|
710
|
-
if (native.database !== void 0)
|
|
711
|
-
yield* parseDatabaseSchema(native.database.schema).pipe(
|
|
712
|
-
Effect_exports.catchTag(
|
|
713
|
-
"AppDatabaseError",
|
|
714
|
-
(cause) => Effect_exports.fail(
|
|
715
|
-
declarationInvalid("The app's account or database declarations are invalid", cause)
|
|
716
|
-
)
|
|
717
|
-
)
|
|
718
|
-
);
|
|
1307
|
+
const ownsSql = hasMigrations(context.files ?? []);
|
|
1308
|
+
const declared = yield* requirements(native.accounts, ownsSql, native.events);
|
|
1309
|
+
if (request.operation === "requirements")
|
|
719
1310
|
return yield* safe2(
|
|
720
1311
|
() => Schema_exports.decodeUnknownEffect(JsonValue)(declared),
|
|
721
1312
|
new HostDeclarationInvalid()
|
|
722
1313
|
);
|
|
1314
|
+
if (request.operation === "migrate") {
|
|
1315
|
+
if (!ownsSql) return yield* new HostOperationNotFound();
|
|
1316
|
+
const storage2 = context.storage;
|
|
1317
|
+
if (storage2 === void 0)
|
|
1318
|
+
return yield* new HostOperationFailed(
|
|
1319
|
+
failureDetail(new Error("This host gave the app no SQL storage."), secrets)
|
|
1320
|
+
);
|
|
1321
|
+
const sources = yield* Schema_exports.decodeUnknownEffect(Schema_exports.Array(SkillFile))(
|
|
1322
|
+
context.files ?? []
|
|
1323
|
+
).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
|
|
1324
|
+
const applied = yield* migrate(storage2, sources).pipe(
|
|
1325
|
+
Effect_exports.mapError((error) => new HostOperationFailed(failureDetail(error, secrets))),
|
|
1326
|
+
Effect_exports.withSpan("app.sql.migrate")
|
|
1327
|
+
);
|
|
1328
|
+
return yield* safe2(
|
|
1329
|
+
() => Schema_exports.decodeUnknownEffect(JsonValue)(applied),
|
|
1330
|
+
new HostOutputInvalid()
|
|
1331
|
+
);
|
|
723
1332
|
}
|
|
724
1333
|
const lifetime = yield* Effect_exports.acquireRelease(
|
|
725
1334
|
Effect_exports.sync(() => new AbortController()),
|
|
726
1335
|
(controller) => Effect_exports.sync(() => controller.abort())
|
|
727
1336
|
);
|
|
728
1337
|
const invocationSignal = AbortSignal.any([signal, lifetime.signal]);
|
|
1338
|
+
const storage = context.storage;
|
|
1339
|
+
const sqlSession = (step) => !ownsSql ? Effect_exports.succeed({ reader: noDatabase, writer: noDatabase }) : storage === void 0 ? Effect_exports.fail(
|
|
1340
|
+
new HostOperationFailed(
|
|
1341
|
+
failureDetail(new Error("This host gave the app no SQL storage."), secrets)
|
|
1342
|
+
)
|
|
1343
|
+
) : Effect_exports.acquireRelease(
|
|
1344
|
+
Effect_exports.sync(
|
|
1345
|
+
() => authorSql(storage, {
|
|
1346
|
+
signal: invocationSignal,
|
|
1347
|
+
emitted,
|
|
1348
|
+
...step === void 0 ? {} : { step }
|
|
1349
|
+
})
|
|
1350
|
+
),
|
|
1351
|
+
(session2) => Effect_exports.sync(session2.close)
|
|
1352
|
+
);
|
|
729
1353
|
const deadline = context.deadline === void 0 ? void 0 : yield* safe2(
|
|
730
1354
|
() => Schema_exports.decodeUnknownEffect(InvocationDeadline)(context.deadline),
|
|
731
1355
|
new HostInputInvalid()
|
|
@@ -746,31 +1370,62 @@ function dispatch(app, request, context, signal) {
|
|
|
746
1370
|
return yield* new WorkflowFailure({ reason: "engine", retryable: true });
|
|
747
1371
|
return result;
|
|
748
1372
|
});
|
|
1373
|
+
if (request.operation === "account-check")
|
|
1374
|
+
return yield* checkAccount(
|
|
1375
|
+
native.accounts,
|
|
1376
|
+
declared,
|
|
1377
|
+
request.requirement,
|
|
1378
|
+
context,
|
|
1379
|
+
invocationSignal,
|
|
1380
|
+
deadline
|
|
1381
|
+
).pipe(withinDeadline);
|
|
749
1382
|
let running;
|
|
750
|
-
let transactionOpen = false;
|
|
751
1383
|
const delivery = (request2, signal2) => Effect_exports.suspend(
|
|
752
|
-
() =>
|
|
753
|
-
|
|
1384
|
+
() => running !== void 0 && context.elicitation !== void 0 ? context.elicitation(request2, signal2).pipe(
|
|
1385
|
+
// Delivering the question and waiting for its answer is the person's time.
|
|
1386
|
+
owned("person", "app.tool.elicitation"),
|
|
754
1387
|
Effect_exports.provideContext(running.context)
|
|
755
1388
|
) : Effect_exports.fail(new ElicitationFailed({ reason: "unavailable" }))
|
|
756
1389
|
);
|
|
757
1390
|
const unavailableWorkflow = () => Effect_exports.fail(new WorkflowFailure({ reason: "unavailable", retryable: false }));
|
|
1391
|
+
const telemetry = yield* captureTelemetry;
|
|
1392
|
+
const control = (operation, work) => work.pipe(
|
|
1393
|
+
owned("executor", workflowControlSpan, {
|
|
1394
|
+
attributes: { "executor.workflow.operation": operation }
|
|
1395
|
+
})
|
|
1396
|
+
);
|
|
758
1397
|
const workflowControls = {
|
|
759
1398
|
start: toPromise(
|
|
760
|
-
(input2) =>
|
|
761
|
-
|
|
1399
|
+
(input2) => control(
|
|
1400
|
+
"start",
|
|
1401
|
+
context.workflowControls === void 0 ? unavailableWorkflow() : context.workflowControls.start(input2)
|
|
1402
|
+
),
|
|
1403
|
+
invocationSignal,
|
|
1404
|
+
telemetry.context
|
|
762
1405
|
),
|
|
763
1406
|
get: toPromise(
|
|
764
|
-
(input2) =>
|
|
765
|
-
|
|
1407
|
+
(input2) => control(
|
|
1408
|
+
"get",
|
|
1409
|
+
context.workflowControls === void 0 ? unavailableWorkflow() : context.workflowControls.get(input2)
|
|
1410
|
+
),
|
|
1411
|
+
invocationSignal,
|
|
1412
|
+
telemetry.context
|
|
766
1413
|
),
|
|
767
1414
|
list: toPromise(
|
|
768
|
-
(input2) =>
|
|
769
|
-
|
|
1415
|
+
(input2) => control(
|
|
1416
|
+
"list",
|
|
1417
|
+
context.workflowControls === void 0 ? unavailableWorkflow() : context.workflowControls.list(input2)
|
|
1418
|
+
),
|
|
1419
|
+
invocationSignal,
|
|
1420
|
+
telemetry.context
|
|
770
1421
|
),
|
|
771
1422
|
terminate: toPromise(
|
|
772
|
-
(input2) =>
|
|
773
|
-
|
|
1423
|
+
(input2) => control(
|
|
1424
|
+
"terminate",
|
|
1425
|
+
context.workflowControls === void 0 ? unavailableWorkflow() : context.workflowControls.terminate(input2)
|
|
1426
|
+
),
|
|
1427
|
+
invocationSignal,
|
|
1428
|
+
telemetry.context
|
|
774
1429
|
)
|
|
775
1430
|
};
|
|
776
1431
|
const workflowReads = {
|
|
@@ -782,6 +1437,7 @@ function dispatch(app, request, context, signal) {
|
|
|
782
1437
|
).pipe(Effect_exports.mapError(() => new HostDeclarationInvalid()));
|
|
783
1438
|
let cacheCommands = 0;
|
|
784
1439
|
const hostCache = context.cache ?? unavailableCache;
|
|
1440
|
+
const fetching = yield* fetchLifetime(signal, hostCache.background);
|
|
785
1441
|
const bound = {
|
|
786
1442
|
cache: authorCache(
|
|
787
1443
|
{
|
|
@@ -789,10 +1445,12 @@ function dispatch(app, request, context, signal) {
|
|
|
789
1445
|
transport: (command) => {
|
|
790
1446
|
cacheCommands += 1;
|
|
791
1447
|
return hostCache.transport(command);
|
|
792
|
-
}
|
|
1448
|
+
},
|
|
1449
|
+
background: fetching.background
|
|
793
1450
|
},
|
|
794
1451
|
Redacted_exports.value(context.accounts),
|
|
795
1452
|
invocationSignal,
|
|
1453
|
+
telemetry.context,
|
|
796
1454
|
deadline
|
|
797
1455
|
),
|
|
798
1456
|
files,
|
|
@@ -801,9 +1459,20 @@ function dispatch(app, request, context, signal) {
|
|
|
801
1459
|
),
|
|
802
1460
|
workflows: workflowReads,
|
|
803
1461
|
signal: invocationSignal,
|
|
804
|
-
fetch: yield*
|
|
805
|
-
elicit: makeElicit(delivery, invocationSignal)
|
|
1462
|
+
fetch: yield* appInvocationFetch(fetching.signal),
|
|
1463
|
+
elicit: makeElicit(delivery, invocationSignal, telemetry.context)
|
|
806
1464
|
};
|
|
1465
|
+
const accountIds = Object.values(bound.accounts).flatMap(
|
|
1466
|
+
(selected) => (Array.isArray(selected) ? selected : [selected]).map(
|
|
1467
|
+
(account) => account.id
|
|
1468
|
+
)
|
|
1469
|
+
);
|
|
1470
|
+
const emitter = (sourceAccount) => makeEmitter({
|
|
1471
|
+
events: native.events ?? {},
|
|
1472
|
+
accounts: accountIds,
|
|
1473
|
+
...sourceAccount === void 0 ? {} : { sourceAccount },
|
|
1474
|
+
emitted
|
|
1475
|
+
});
|
|
807
1476
|
const definition = yield* evaluationSafe(native.evaluate(bound), secrets).pipe(
|
|
808
1477
|
Effect_exports.withSpan("app.evaluate")
|
|
809
1478
|
);
|
|
@@ -875,10 +1544,11 @@ function dispatch(app, request, context, signal) {
|
|
|
875
1544
|
cache: authorCache(
|
|
876
1545
|
context.cache ?? unavailableCache,
|
|
877
1546
|
Redacted_exports.value(current.accounts),
|
|
878
|
-
signal2
|
|
1547
|
+
signal2,
|
|
1548
|
+
(yield* captureTelemetry).context
|
|
879
1549
|
),
|
|
880
1550
|
files,
|
|
881
|
-
fetch: yield*
|
|
1551
|
+
fetch: yield* appInvocationFetch(signal2),
|
|
882
1552
|
signal: signal2,
|
|
883
1553
|
runId: execution.runId,
|
|
884
1554
|
stepId,
|
|
@@ -926,7 +1596,8 @@ function dispatch(app, request, context, signal) {
|
|
|
926
1596
|
);
|
|
927
1597
|
}
|
|
928
1598
|
if (request.operation === "webhook-complete" || request.operation === "webhook-validate" || request.operation === "webhooks" || request.operation === "webhook-register" || request.operation === "webhook-handle" || request.operation === "webhook-unregister") {
|
|
929
|
-
const
|
|
1599
|
+
const session2 = yield* sqlSession();
|
|
1600
|
+
return yield* dispatchWebhook(
|
|
930
1601
|
definition,
|
|
931
1602
|
request,
|
|
932
1603
|
{
|
|
@@ -936,27 +1607,17 @@ function dispatch(app, request, context, signal) {
|
|
|
936
1607
|
workflows: workflowControls,
|
|
937
1608
|
signal: bound.signal,
|
|
938
1609
|
fetch: bound.fetch,
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
}
|
|
1610
|
+
sql: session2.writer,
|
|
1611
|
+
events: emitter("sourceAccount" in request ? request.sourceAccount : void 0)
|
|
942
1612
|
},
|
|
943
1613
|
Redacted_exports.value(context.accounts)
|
|
944
1614
|
);
|
|
945
|
-
if (native.database === void 0 || !["webhook-register", "webhook-handle", "webhook-unregister"].includes(request.operation))
|
|
946
|
-
return yield* executeWebhook();
|
|
947
|
-
const storage2 = context.storage ?? unavailableStorage;
|
|
948
|
-
return yield* storage2.mutate(native.database.schema, executeWebhook).pipe(
|
|
949
|
-
Effect_exports.catchTags({
|
|
950
|
-
AppDatabaseError: storageFailure,
|
|
951
|
-
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
952
|
-
AppStorageUnavailable: storageFailure,
|
|
953
|
-
AppStorageError: storageFailure
|
|
954
|
-
})
|
|
955
|
-
);
|
|
956
1615
|
}
|
|
957
1616
|
const toolName = request.operation === "call" ? request.tool : request.name;
|
|
958
1617
|
const location = locate(definition.tools, toolName);
|
|
959
|
-
const tool = location === void 0 ? void 0 : location.kind === "operation" ? location.operation : yield* evaluationSafe(location.source.resolve(location.name), secrets)
|
|
1618
|
+
const tool = location === void 0 ? void 0 : location.kind === "operation" ? location.operation : yield* evaluationSafe(location.source.resolve(location.name), secrets).pipe(
|
|
1619
|
+
Effect_exports.withSpan("app.tool.resolve")
|
|
1620
|
+
);
|
|
960
1621
|
if (tool === void 0)
|
|
961
1622
|
return yield* request.operation === "call" ? new HostToolNotFound() : new HostOperationNotFound();
|
|
962
1623
|
const requested = request.operation === "call" ? request.kind : request.operation === "query" ? "query" : "mutation";
|
|
@@ -967,7 +1628,7 @@ function dispatch(app, request, context, signal) {
|
|
|
967
1628
|
() => Schema_exports.decodeUnknownEffect(tool.input)(request.input)
|
|
968
1629
|
).pipe(
|
|
969
1630
|
Effect_exports.catchCause(
|
|
970
|
-
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(inputInvalid(Cause_exports.squash(cause)))
|
|
1631
|
+
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : Effect_exports.fail(inputInvalid(Cause_exports.squash(cause), request.input))
|
|
971
1632
|
)
|
|
972
1633
|
);
|
|
973
1634
|
if (context.approval !== void 0) {
|
|
@@ -1012,24 +1673,23 @@ function dispatch(app, request, context, signal) {
|
|
|
1012
1673
|
Match_exports.exhaustive
|
|
1013
1674
|
);
|
|
1014
1675
|
}
|
|
1015
|
-
const
|
|
1016
|
-
|
|
1676
|
+
const replay = context.replay === void 0 ? void 0 : yield* safe2(
|
|
1677
|
+
() => Schema_exports.decodeUnknownEffect(WorkflowReplay)(context.replay),
|
|
1678
|
+
new HostInputInvalid()
|
|
1679
|
+
);
|
|
1680
|
+
if (replay !== void 0 && kind !== "mutate") return yield* new HostInputInvalid();
|
|
1681
|
+
const session = yield* sqlSession(replay);
|
|
1682
|
+
const execute = () => Effect_exports.gen(function* () {
|
|
1017
1683
|
const output = yield* Effect_exports.gen(function* () {
|
|
1018
1684
|
running = yield* captureTelemetry;
|
|
1019
|
-
const fetch = yield*
|
|
1685
|
+
const fetch = yield* appInvocationFetch(fetching.signal);
|
|
1020
1686
|
return yield* tool.run(
|
|
1021
1687
|
{
|
|
1022
1688
|
...bound,
|
|
1023
1689
|
fetch,
|
|
1024
1690
|
workflows: kind === "mutate" ? workflowControls : workflowReads,
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
native.database.tables,
|
|
1028
|
-
db,
|
|
1029
|
-
invocationSignal,
|
|
1030
|
-
kind === "mutate"
|
|
1031
|
-
)
|
|
1032
|
-
}
|
|
1691
|
+
sql: kind === "mutate" ? session.writer : session.reader,
|
|
1692
|
+
...kind === "mutate" ? { events: emitter() } : {}
|
|
1033
1693
|
},
|
|
1034
1694
|
input
|
|
1035
1695
|
);
|
|
@@ -1044,14 +1704,15 @@ function dispatch(app, request, context, signal) {
|
|
|
1044
1704
|
const error = Cause_exports.squash(cause);
|
|
1045
1705
|
const provider = parseProviderError(error);
|
|
1046
1706
|
const response = Schema_exports.decodeUnknownOption(OpenapiResponseError)(error);
|
|
1707
|
+
const mcp = parseMcpError(error, secrets);
|
|
1047
1708
|
const failure = Schema_exports.decodeUnknownOption(ElicitationFailed)(error);
|
|
1048
1709
|
return Effect_exports.fail(
|
|
1049
|
-
Option_exports.isSome(provider) ? provider.value : Option_exports.isSome(response) ? new OpenapiResponseError({
|
|
1710
|
+
Option_exports.isSome(provider) ? leavingProviderError(provider.value, secrets, "call") : Option_exports.isSome(response) ? new OpenapiResponseError({
|
|
1050
1711
|
code: response.value.code,
|
|
1051
1712
|
status: response.value.status,
|
|
1052
1713
|
message: response.value.message,
|
|
1053
1714
|
...response.value.recovery === void 0 ? {} : { recovery: response.value.recovery }
|
|
1054
|
-
}) : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed(failureDetail(error, secrets))
|
|
1715
|
+
}) : Option_exports.isSome(mcp) ? mcp.value : Option_exports.isSome(failure) ? failure.value : new HostOperationFailed(failureDetail(error, secrets))
|
|
1055
1716
|
);
|
|
1056
1717
|
}),
|
|
1057
1718
|
Effect_exports.withSpan("app.operation.execute", {
|
|
@@ -1068,43 +1729,56 @@ function dispatch(app, request, context, signal) {
|
|
|
1068
1729
|
new HostOutputInvalid()
|
|
1069
1730
|
);
|
|
1070
1731
|
});
|
|
1071
|
-
|
|
1072
|
-
() => Schema_exports.decodeUnknownEffect(WorkflowReplay)(context.replay),
|
|
1073
|
-
new HostInputInvalid()
|
|
1074
|
-
);
|
|
1075
|
-
if (replay !== void 0 && kind !== "mutate") return yield* new HostInputInvalid();
|
|
1076
|
-
if (native.database === void 0) return yield* withinDeadline(execute());
|
|
1077
|
-
const storage = context.storage ?? unavailableStorage;
|
|
1078
|
-
return yield* storage[kind === "query" ? "read" : "mutate"](
|
|
1079
|
-
native.database.schema,
|
|
1080
|
-
(db) => withinDeadline(
|
|
1081
|
-
replay === void 0 ? execute(db) : db.once(replay.key, replay.fingerprint, () => execute(db))
|
|
1082
|
-
)
|
|
1083
|
-
).pipe(
|
|
1084
|
-
Effect_exports.catchTags({
|
|
1085
|
-
AppDatabaseError: storageFailure,
|
|
1086
|
-
DatabaseLimitExceeded: (error) => Effect_exports.fail(error),
|
|
1087
|
-
AppStorageUnavailable: storageFailure,
|
|
1088
|
-
AppStorageError: storageFailure
|
|
1089
|
-
})
|
|
1090
|
-
);
|
|
1732
|
+
return yield* withinDeadline(execute());
|
|
1091
1733
|
})
|
|
1092
1734
|
);
|
|
1093
1735
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1736
|
+
function checkAccount(slots, declared, requirement, context, signal, deadline) {
|
|
1737
|
+
return Effect_exports.gen(function* () {
|
|
1738
|
+
const selection = Object.hasOwn(slots, requirement) ? slots[requirement] : void 0;
|
|
1739
|
+
const slot = Object.hasOwn(declared.accounts, requirement) ? declared.accounts[requirement] : void 0;
|
|
1740
|
+
if (selection === void 0 || slot === void 0) return yield* new HostAccountsInvalid();
|
|
1741
|
+
const provider = selection instanceof ManyAccounts ? selection.provider : selection;
|
|
1742
|
+
const health = provider.health;
|
|
1743
|
+
if (health === void 0) return yield* new HostOperationNotFound();
|
|
1744
|
+
const { accounts } = yield* bindAccounts(
|
|
1745
|
+
{ [requirement]: provider },
|
|
1746
|
+
{ accounts: { [requirement]: { ...slot, cardinality: "one" } } },
|
|
1747
|
+
context
|
|
1748
|
+
).pipe(Effect_exports.withSpan("app.accounts.bind"));
|
|
1749
|
+
const account = accounts[requirement];
|
|
1750
|
+
if (account === void 0 || !("id" in account)) return yield* new HostAccountsInvalid();
|
|
1751
|
+
const result = yield* Effect_exports.suspend(
|
|
1752
|
+
() => Effect_exports.gen(function* () {
|
|
1753
|
+
return yield* health.run({
|
|
1754
|
+
account,
|
|
1755
|
+
fetch: yield* appInvocationFetch(signal),
|
|
1756
|
+
signal,
|
|
1757
|
+
...deadline === void 0 ? {} : { deadline }
|
|
1758
|
+
});
|
|
1759
|
+
})
|
|
1760
|
+
).pipe(
|
|
1761
|
+
Effect_exports.catchCause((cause) => {
|
|
1762
|
+
if (Cause_exports.hasInterrupts(cause)) return Effect_exports.interrupt;
|
|
1763
|
+
const error = Cause_exports.squash(cause);
|
|
1764
|
+
const status = Schema_exports.decodeUnknownOption(ResponseStatusError)(error);
|
|
1765
|
+
const classified = Option_exports.isSome(status) ? Option_exports.fromNullishOr(httpProviderError(status.value.status)) : parseProviderError(error);
|
|
1766
|
+
const secrets = accountSecrets(context.accounts);
|
|
1767
|
+
return Effect_exports.fail(
|
|
1768
|
+
Option_exports.isSome(classified) ? leavingProviderError(accountProviderError(classified.value, account.id), secrets) : new HostOperationFailed(failureDetail(error, secrets))
|
|
1769
|
+
);
|
|
1770
|
+
}),
|
|
1771
|
+
Effect_exports.withSpan("app.account.check")
|
|
1772
|
+
);
|
|
1773
|
+
return yield* safe2(
|
|
1774
|
+
() => Schema_exports.decodeUnknownEffect(AccountCheckResult)(result ?? {}).pipe(
|
|
1775
|
+
Effect_exports.flatMap(Schema_exports.encodeEffect(AccountCheckResult)),
|
|
1776
|
+
Effect_exports.flatMap(Schema_exports.decodeUnknownEffect(JsonValue))
|
|
1777
|
+
),
|
|
1778
|
+
new HostOutputInvalid()
|
|
1779
|
+
);
|
|
1780
|
+
});
|
|
1781
|
+
}
|
|
1108
1782
|
var errorStatus = Match_exports.type().pipe(
|
|
1109
1783
|
Match_exports.tagsExhaustive({
|
|
1110
1784
|
ProviderError: () => 502,
|
|
@@ -1144,20 +1818,37 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
|
|
|
1144
1818
|
...command.operation === "call" ? { "executor.tool.name": command.tool } : {}
|
|
1145
1819
|
});
|
|
1146
1820
|
let toolError = false;
|
|
1147
|
-
const
|
|
1821
|
+
const emitted = [];
|
|
1822
|
+
const value = yield* dispatch(app, command, context, request.signal, emitted).pipe(
|
|
1148
1823
|
Effect_exports.provideService(ToolResultObservation, {
|
|
1149
1824
|
failed: () => {
|
|
1150
1825
|
toolError = true;
|
|
1151
1826
|
}
|
|
1152
1827
|
}),
|
|
1153
|
-
|
|
1828
|
+
// Name what failed on the span; the bounded message stays in the reply only. The host
|
|
1829
|
+
// records an app's own error names and codes as `unrecognized` (telemetry `app-records`).
|
|
1830
|
+
Effect_exports.tapError(
|
|
1831
|
+
(error) => (error._tag === "HostEvaluationFailed" || error._tag === "HostOperationFailed" || error._tag === "HostDeclarationInvalid") && error.errorName !== void 0 ? Effect_exports.annotateCurrentSpan({
|
|
1832
|
+
"error.type": error.errorName,
|
|
1833
|
+
...error.source === void 0 ? {} : { "executor.failure.source": error.source },
|
|
1834
|
+
...error.code === void 0 ? {} : { "executor.failure.code": error.code }
|
|
1835
|
+
}) : Effect_exports.void
|
|
1836
|
+
),
|
|
1837
|
+
// Tool operations time themselves, dividing their time by who owned the work in progress.
|
|
1838
|
+
// Other operations do not.
|
|
1839
|
+
command.operation === "call" || command.operation === "query" || command.operation === "mutate" ? timedInvocation(command.operation) : Effect_exports.withSpan(`app.${command.operation}`)
|
|
1154
1840
|
);
|
|
1155
1841
|
if (toolError)
|
|
1156
1842
|
yield* Effect_exports.annotateCurrentSpan({
|
|
1157
1843
|
"executor.outcome": "failed",
|
|
1158
1844
|
"error.type": "McpToolError"
|
|
1159
1845
|
});
|
|
1160
|
-
return Response.json({
|
|
1846
|
+
return Response.json({
|
|
1847
|
+
ok: true,
|
|
1848
|
+
value,
|
|
1849
|
+
...toolError ? { toolError: true } : {},
|
|
1850
|
+
...emitted.length === 0 ? {} : { events: emitted }
|
|
1851
|
+
});
|
|
1161
1852
|
}).pipe(
|
|
1162
1853
|
Effect_exports.catch(
|
|
1163
1854
|
(error) => Schema_exports.encodeEffect(HostError)(error).pipe(
|
|
@@ -1168,18 +1859,21 @@ var createAppHandler = (app) => (request, context) => Effect_exports.gen(functio
|
|
|
1168
1859
|
)
|
|
1169
1860
|
),
|
|
1170
1861
|
Effect_exports.catchCause(
|
|
1171
|
-
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt :
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1862
|
+
(cause) => Cause_exports.hasInterrupts(cause) ? Effect_exports.interrupt : (
|
|
1863
|
+
// The cause can carry any text the app threw; its caller receives that, not the log.
|
|
1864
|
+
Effect_exports.logError("The app's request failed unexpectedly").pipe(
|
|
1865
|
+
Effect_exports.andThen(
|
|
1866
|
+
Schema_exports.encodeEffect(HostError)(
|
|
1867
|
+
declarationInvalid(
|
|
1868
|
+
"The app failed while it was loaded",
|
|
1869
|
+
Cause_exports.squash(cause),
|
|
1870
|
+
accountSecrets(context.accounts)
|
|
1871
|
+
)
|
|
1178
1872
|
)
|
|
1179
|
-
)
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1873
|
+
),
|
|
1874
|
+
Effect_exports.map((error) => Response.json({ ok: false, error }, { status: 500 })),
|
|
1875
|
+
Effect_exports.orDie
|
|
1876
|
+
)
|
|
1183
1877
|
)
|
|
1184
1878
|
)
|
|
1185
1879
|
);
|