@effect-app/infra 4.0.0-beta.256 → 4.0.0-beta.257

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @effect-app/infra
2
2
 
3
+ ## 4.0.0-beta.257
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [e71eb78]
8
+ - effect-app@4.0.0-beta.257
9
+
3
10
  ## 4.0.0-beta.256
4
11
 
5
12
  ### Patch Changes
@@ -0,0 +1,29 @@
1
+ import * as Layer from "effect-app/Layer";
2
+ import * as Duration from "effect/Duration";
3
+ import * as Redacted from "effect/Redacted";
4
+ import { WorkflowEngine } from "effect/unstable/workflow/WorkflowEngine";
5
+ export interface WorkflowEngineCosmosConfig {
6
+ readonly url: Redacted.Redacted<string>;
7
+ readonly dbName: string;
8
+ readonly prefix?: string;
9
+ /** Lease duration before claim considered stale. Default 30s. */
10
+ readonly leaseTtl?: Duration.Duration;
11
+ /** Renewal cadence — should be < leaseTtl. Default 10s. */
12
+ readonly heartbeatInterval?: Duration.Duration;
13
+ /** Cadence for scanning stale leases. Default 15s. Set to `Duration.zero` to disable. */
14
+ readonly recoveryInterval?: Duration.Duration;
15
+ /** Cadence for scanning due clocks. Default 5s. Set to `Duration.zero` to disable. */
16
+ readonly clockPollInterval?: Duration.Duration;
17
+ /** Stable worker identity; defaults to a random UUID per process. */
18
+ readonly workerId?: string;
19
+ }
20
+ /**
21
+ * Cosmos DB backed `WorkflowEngine` layer.
22
+ *
23
+ * Per-execution writes share a partition key (TransactionalBatch-eligible) and
24
+ * use OCC via `_etag`/IfMatch, giving first-writer-wins semantics for activity
25
+ * results, durable-deferred completions, and exec-state transitions. All
26
+ * persisted payloads/results/exits are round-tripped through schema codecs.
27
+ */
28
+ export declare const layerCosmos: (cfg: WorkflowEngineCosmosConfig) => Layer.Layer<WorkflowEngine>;
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV29ya2Zsb3dFbmdpbmVDb3Ntb3MuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Xb3JrZmxvd0VuZ2luZUNvc21vcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFpQ0EsT0FBTyxLQUFLLEtBQUssTUFBTSxrQkFBa0IsQ0FBQTtBQUd6QyxPQUFPLEtBQUssUUFBUSxNQUFNLGlCQUFpQixDQUFBO0FBSTNDLE9BQU8sS0FBSyxRQUFRLE1BQU0saUJBQWlCLENBQUE7QUFJM0MsT0FBTyxFQUE0QixjQUFjLEVBQW9CLE1BQU0seUNBQXlDLENBQUE7QUFNcEgsTUFBTSxXQUFXLDBCQUEwQjtJQUN6QyxRQUFRLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDdkMsUUFBUSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUE7SUFDdkIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQTtJQUN4QixpRUFBaUU7SUFDakUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUE7SUFDckMsMkRBQTJEO0lBQzNELFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUE7SUFDOUMseUZBQXlGO0lBQ3pGLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUE7SUFDN0Msc0ZBQXNGO0lBQ3RGLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUE7SUFDOUMscUVBQXFFO0lBQ3JFLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLENBQUE7Q0FDM0I7QUFtb0JEOzs7Ozs7O0dBT0c7QUFDSCxlQUFPLE1BQU0sV0FBVyxRQUFTLDBCQUEwQixLQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUdSLENBQUEifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkflowEngineCosmos.d.ts","sourceRoot":"","sources":["../src/WorkflowEngineCosmos.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA;AAGzC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAI3C,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAI3C,OAAO,EAA4B,cAAc,EAAoB,MAAM,yCAAyC,CAAA;AAMpH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;IAC9C,yFAAyF;IACzF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;IAC7C,sFAAsF;IACtF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;IAC9C,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAmoBD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,QAAS,0BAA0B,KAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAGR,CAAA"}
@@ -0,0 +1,521 @@
1
+ /**
2
+ * Cosmos DB backed {@link WorkflowEngine} implementation.
3
+ *
4
+ * Persists workflow state in a single container partitioned by `executionId`
5
+ * so per-execution writes share a partition key (eligible for Cosmos
6
+ * TransactionalBatch). Optimistic concurrency is enforced with `_etag` +
7
+ * `IfMatch` on Replace, and create-only batch ops give first-writer-wins
8
+ * semantics for activity results and durable-deferred completions.
9
+ *
10
+ * Durability — everything that crosses the storage boundary is round-tripped
11
+ * through schema codecs (`S.fromJsonString(S.toCodecJson(...))`), exactly like
12
+ * the cluster engine, instead of dumping live runtime objects as JSON:
13
+ *
14
+ * - The workflow payload and the top-level workflow result are encoded with the
15
+ * workflow's own `payloadSchema` / `successSchema` / `errorSchema`, so typed
16
+ * values (dates, branded ids, schema classes) survive a restart.
17
+ * - Activity results flow through the engine already encoded, so they are
18
+ * persisted with an opaque `Workflow.Result({ success: AnyOrVoid, error:
19
+ * AnyOrVoid })` codec — same trick the cluster `ActivityRpc` uses.
20
+ * - Durable-deferred exits and clock completions use an opaque `Exit` codec.
21
+ *
22
+ * Crash recovery: each driver holds a time-bound lease (`worker` +
23
+ * `leaseExpiresAt`) on the exec doc and renews it via a heartbeat fiber. A
24
+ * scope-bound recovery poller queries for exec docs whose lease has lapsed and
25
+ * re-drives them in the local process, decoding the persisted payload and
26
+ * picking up persisted activity results from where the crashed driver left off.
27
+ *
28
+ * Durable clocks: `scheduleClock` writes a clock doc (`fireAt`, `deferredName`)
29
+ * and arms an in-process timer. A cross-partition clock poller fires any clock
30
+ * whose `fireAt` is due, completing the deferred idempotently (create-only) and
31
+ * deleting the doc. Survives restarts.
32
+ */
33
+ import * as Effect from "effect-app/Effect";
34
+ import * as Layer from "effect-app/Layer";
35
+ import * as Option from "effect-app/Option";
36
+ import * as S from "effect-app/Schema";
37
+ import * as Duration from "effect/Duration";
38
+ import * as Exit from "effect/Exit";
39
+ import * as Fiber from "effect/Fiber";
40
+ import * as FiberMap from "effect/FiberMap";
41
+ import * as Redacted from "effect/Redacted";
42
+ import * as Schedule from "effect/Schedule";
43
+ import * as Workflow from "effect/unstable/workflow/Workflow";
44
+ import { makeUnsafe, WorkflowEngine, WorkflowInstance } from "effect/unstable/workflow/WorkflowEngine";
45
+ import { randomUUID } from "node:crypto";
46
+ import { CosmosClient, CosmosClientLayer } from "./cosmos-client.js";
47
+ import { OptimisticConcurrencyException } from "./errors.js";
48
+ import { annotateCosmosResponse, annotateDb } from "./otel.js";
49
+ const execId = "exec";
50
+ const activityKey = (name, attempt) => `activity::${name}::${attempt}`;
51
+ const deferredKey = (name) => `deferred::${name}`;
52
+ const clockKey = (name) => `clock::${name}`;
53
+ const isOptimisticStatus = (code) => code === 409 || code === 412 || code === 404;
54
+ // --- Storage codecs ----------------------------------------------------------
55
+ // Values flowing through the engine's activity / deferred boundary are already
56
+ // schema-encoded, so the structure is round-tripped while the payload stays
57
+ // opaque (mirrors the cluster engine's `AnyOrVoid` usage).
58
+ const AnyOrVoid = S.Union([S.Any, S.Void]);
59
+ const ActivityResultCodec = S.fromJsonString(S.toCodecJson(Workflow.Result({ success: AnyOrVoid, error: AnyOrVoid })));
60
+ const DeferredExitCodec = S.fromJsonString(S.toCodecJson(S.Exit(AnyOrVoid, AnyOrVoid, S.Defect)));
61
+ const encodeActivityResult = (r) => Effect.orDie(S.encodeEffect(ActivityResultCodec)(r));
62
+ const decodeActivityResult = (s) => Effect.orDie(S.decodeEffect(ActivityResultCodec)(s));
63
+ const encodeDeferredExit = (e) => Effect.orDie(S.encodeEffect(DeferredExitCodec)(e));
64
+ const decodeDeferredExit = (s) => Effect.orDie(S.decodeEffect(DeferredExitCodec)(s));
65
+ const makeCosmosWorkflowEngine = Effect.fnUntraced(function* (cfg) {
66
+ const { db } = yield* CosmosClient;
67
+ const containerId = `${cfg.prefix ?? ""}workflow-engine`;
68
+ yield* Effect.promise(() => db.containers.createIfNotExists({
69
+ id: containerId,
70
+ partitionKey: { paths: ["/_partitionKey"], version: 2 }
71
+ }));
72
+ const container = db.container(containerId);
73
+ const scope = yield* Effect.scope;
74
+ const workerId = cfg.workerId ?? randomUUID();
75
+ const leaseTtl = cfg.leaseTtl ?? Duration.seconds(30);
76
+ const heartbeatInterval = cfg.heartbeatInterval ?? Duration.seconds(10);
77
+ const recoveryInterval = cfg.recoveryInterval ?? Duration.seconds(15);
78
+ const clockPollInterval = cfg.clockPollInterval ?? Duration.seconds(5);
79
+ const annotate = (operation, executionId) => annotateDb({
80
+ operation,
81
+ system: "cosmosdb",
82
+ collection: containerId,
83
+ entity: "workflow",
84
+ extra: executionId !== undefined
85
+ ? { "azure.cosmosdb.operation.partition_key": executionId, "app.entity.id": executionId }
86
+ : undefined
87
+ });
88
+ const workflows = new Map();
89
+ const locals = new Map();
90
+ const clocks = yield* FiberMap.make();
91
+ // Per-workflow codecs for the typed payload + top-level result. Cached by
92
+ // workflow name; derived from the workflow's own schemas so typed values
93
+ // (dates, branded ids, schema classes) survive the storage round-trip.
94
+ const makePayloadCodec = (workflow) => S.fromJsonString(S.toCodecJson(workflow.payloadSchema));
95
+ const payloadCodecCache = new Map();
96
+ const payloadCodecFor = (workflow) => {
97
+ let c = payloadCodecCache.get(workflow.name);
98
+ if (!c) {
99
+ c = makePayloadCodec(workflow);
100
+ payloadCodecCache.set(workflow.name, c);
101
+ }
102
+ return c;
103
+ };
104
+ const makeResultCodec = (workflow) => S.fromJsonString(S.toCodecJson(Workflow.Result({ success: workflow.successSchema, error: workflow.errorSchema })));
105
+ const resultCodecCache = new Map();
106
+ const resultCodecFor = (workflow) => {
107
+ let c = resultCodecCache.get(workflow.name);
108
+ if (!c) {
109
+ c = makeResultCodec(workflow);
110
+ resultCodecCache.set(workflow.name, c);
111
+ }
112
+ return c;
113
+ };
114
+ const encodePayload = (workflow, payload) => Effect.orDie(S.encodeEffect(payloadCodecFor(workflow))(payload));
115
+ const decodePayload = (workflow, s) => Effect.orDie(S.decodeEffect(payloadCodecFor(workflow))(s));
116
+ const encodeResult = (workflow, r) => Effect.orDie(S.encodeEffect(resultCodecFor(workflow))(r));
117
+ const decodeResult = (workflow, s) => Effect.orDie(S.decodeEffect(resultCodecFor(workflow))(s));
118
+ // --- Cosmos primitives -------------------------------------------------
119
+ const readExec = (executionId) => Effect
120
+ .gen(function* () {
121
+ const resp = yield* Effect.promise(() => container.item(execId, executionId).read());
122
+ yield* annotateCosmosResponse({ requestCharge: resp.requestCharge, statusCode: resp.statusCode });
123
+ return Option.fromNullishOr(resp.resource).pipe(Option.map((r) => ({ ...r, _etag: resp.etag })));
124
+ })
125
+ .pipe(annotate("readExec", executionId));
126
+ const replaceExec = (doc) => Effect
127
+ .gen(function* () {
128
+ const resp = yield* Effect.promise(() => container.item(execId, doc._partitionKey).replace(doc, {
129
+ accessCondition: { type: "IfMatch", condition: doc._etag ?? "" }
130
+ }));
131
+ yield* annotateCosmosResponse({ requestCharge: resp.requestCharge, statusCode: resp.statusCode });
132
+ if (isOptimisticStatus(resp.statusCode)) {
133
+ return yield* new OptimisticConcurrencyException({
134
+ type: "workflow.exec",
135
+ id: doc._partitionKey,
136
+ code: resp.statusCode
137
+ });
138
+ }
139
+ return { ...doc, _etag: resp.etag };
140
+ })
141
+ .pipe(annotate("replaceExec", doc._partitionKey));
142
+ // Atomic create-or-noop using a single-op batch — returns true if created.
143
+ const createIfMissing = (body) => Effect.gen(function* () {
144
+ const resp = yield* Effect.promise(() => container.items.batch([{ operationType: "Create", resourceBody: body }], body._partitionKey));
145
+ const r = resp.result?.[0];
146
+ const code = r?.statusCode ?? 0;
147
+ if (code === 201)
148
+ return true;
149
+ if (code === 409)
150
+ return false;
151
+ return yield* Effect.die(new Error(`workflow-engine cosmos createIfMissing for ${body.id} failed: ${code}`));
152
+ });
153
+ // Last-writer-wins upsert — used to overwrite a persisted *suspended* activity
154
+ // result once it finally completes (create-only ops can't transition it).
155
+ const upsert = (body) => Effect.gen(function* () {
156
+ const resp = yield* Effect.promise(() => container.items.upsert(body));
157
+ yield* annotateCosmosResponse({ requestCharge: resp.requestCharge, statusCode: resp.statusCode });
158
+ });
159
+ const readPoint = (id, executionId) => Effect.promise(() => container.item(id, executionId).read()).pipe(Effect.map((r) => Option.fromNullishOr(r.resource)));
160
+ // --- Workflow result helpers ------------------------------------------
161
+ const completeResult = (workflow, state) => state.status === "complete" && state.completedResult
162
+ ? Effect.map(decodeResult(workflow, state.completedResult), Option.some)
163
+ : Effect.succeedNone;
164
+ // --- Lease / claim ----------------------------------------------------
165
+ const leaseActive = (state, now) => state.worker !== undefined
166
+ && state.worker !== workerId
167
+ && state.leaseExpiresAt !== undefined
168
+ && Date.parse(state.leaseExpiresAt) > now;
169
+ /**
170
+ * Try to claim a lease on `state`. Returns the updated doc on success, `None`
171
+ * if another worker holds an active lease, or on OCC conflict (caller may
172
+ * retry by re-reading).
173
+ */
174
+ const tryClaim = (state) => Effect.gen(function* () {
175
+ const now = Date.now();
176
+ if (leaseActive(state, now))
177
+ return Option.none();
178
+ const updated = {
179
+ ...state,
180
+ worker: workerId,
181
+ leaseExpiresAt: new Date(now + Duration.toMillis(leaseTtl)).toISOString()
182
+ };
183
+ return yield* replaceExec(updated).pipe(Effect.map(Option.some), Effect.catchTag("OptimisticConcurrencyException", () => Effect.succeed(Option.none())));
184
+ });
185
+ /**
186
+ * Renew lease until the local fiber stops or another worker takes the claim.
187
+ * Best-effort: failures are swallowed; loop simply retries on next tick.
188
+ */
189
+ const heartbeat = (executionId) => Effect.gen(function* () {
190
+ while (true) {
191
+ yield* Effect.sleep(heartbeatInterval);
192
+ const local = locals.get(executionId);
193
+ const polled = local?.fiber?.pollUnsafe();
194
+ if (!local?.fiber || polled)
195
+ return;
196
+ const cur = yield* readExec(executionId).pipe(Effect.catchCause(() => Effect.succeed(Option.none())));
197
+ if (Option.isNone(cur))
198
+ continue;
199
+ const state = cur.value;
200
+ if (state.status === "complete" || state.worker !== workerId)
201
+ return;
202
+ yield* replaceExec({
203
+ ...state,
204
+ leaseExpiresAt: new Date(Date.now() + Duration.toMillis(leaseTtl)).toISOString()
205
+ })
206
+ .pipe(Effect.catchTag("OptimisticConcurrencyException", () => Effect.void), Effect.catchCause(() => Effect.void));
207
+ }
208
+ });
209
+ // --- Drive logic -------------------------------------------------------
210
+ const drive = (executionId, payload, parent, entry) => Effect.gen(function* () {
211
+ let local = locals.get(executionId);
212
+ if (local?.fiber) {
213
+ const polled = local.fiber.pollUnsafe();
214
+ const stillRunning = !polled;
215
+ const completedNotResume = polled && polled._tag === "Success" && polled.value._tag === "Complete";
216
+ if (stillRunning || completedNotResume)
217
+ return;
218
+ }
219
+ const stateOpt = yield* readExec(executionId);
220
+ if (Option.isNone(stateOpt) || stateOpt.value.status === "complete")
221
+ return;
222
+ // Best-effort claim: takes lease so recovery poller leaves us alone.
223
+ // Failure is tolerated — local fiber still drives; OCC guards persisted
224
+ // state so split-brain stays correct.
225
+ const claimed = yield* tryClaim(stateOpt.value);
226
+ const state = Option.isSome(claimed) ? claimed.value : stateOpt.value;
227
+ const instance = WorkflowInstance.initial(entry.workflow, executionId);
228
+ instance.interrupted = state.interrupted;
229
+ if (!local) {
230
+ local = { instance, fiber: undefined, parent };
231
+ locals.set(executionId, local);
232
+ }
233
+ else {
234
+ local.instance = instance;
235
+ }
236
+ const onComplete = Effect.fnUntraced(function* (result) {
237
+ const current = yield* readExec(executionId);
238
+ if (Option.isNone(current) || current.value.status === "complete")
239
+ return;
240
+ const isComplete = result._tag === "Complete";
241
+ const completedResult = isComplete ? yield* encodeResult(entry.workflow, result) : undefined;
242
+ yield* replaceExec({
243
+ ...current.value,
244
+ status: isComplete ? "complete" : current.value.status,
245
+ suspended: result._tag === "Suspended",
246
+ interrupted: instance.interrupted,
247
+ completedResult,
248
+ // Release lease on completion so the doc isn't seen as orphaned.
249
+ worker: isComplete ? undefined : current.value.worker,
250
+ leaseExpiresAt: isComplete ? undefined : current.value.leaseExpiresAt
251
+ })
252
+ .pipe(Effect.catchTag("OptimisticConcurrencyException", () => Effect.void));
253
+ if (parent && isComplete) {
254
+ yield* Effect.forkIn(driveById(parent), scope);
255
+ }
256
+ });
257
+ local.fiber = yield* entry.execute(payload, executionId).pipe(Effect.onExit(() => {
258
+ if (!instance.interrupted)
259
+ return Effect.void;
260
+ instance.suspended = false;
261
+ return Effect.withFiber((fiber) => Effect.interruptible(Fiber.interrupt(fiber)));
262
+ }), Workflow.intoResult, Effect.provideService(WorkflowInstance, instance), Effect.provideService(WorkflowEngine, engine), Effect.tap(onComplete), Effect.forkIn(entry.scope));
263
+ if (Option.isSome(claimed)) {
264
+ yield* Effect.forkIn(heartbeat(executionId), scope);
265
+ }
266
+ });
267
+ const driveById = (executionId) => Effect.gen(function* () {
268
+ const stateOpt = yield* readExec(executionId);
269
+ if (Option.isNone(stateOpt))
270
+ return;
271
+ const state = stateOpt.value;
272
+ const entry = workflows.get(state.workflowName);
273
+ if (!entry)
274
+ return;
275
+ const payload = yield* decodePayload(entry.workflow, state.payload);
276
+ yield* drive(executionId, payload, state.parent, entry);
277
+ });
278
+ // --- Clock firing -----------------------------------------------------
279
+ // Persist deferred completion (first-writer-wins via createIfMissing),
280
+ // resume the workflow, then clean up the clock doc.
281
+ const fireClock = (doc) => Effect.gen(function* () {
282
+ const created = yield* createIfMissing({
283
+ id: deferredKey(doc.deferredName),
284
+ _partitionKey: doc._partitionKey,
285
+ type: "deferred",
286
+ exit: yield* encodeDeferredExit(Exit.void)
287
+ })
288
+ .pipe(annotate("clockFire", doc._partitionKey));
289
+ if (created)
290
+ yield* driveById(doc._partitionKey);
291
+ yield* Effect.promise(() => container.item(doc.id, doc._partitionKey).delete()).pipe(Effect.catchCause(() => Effect.void));
292
+ });
293
+ // --- Encoded engine ----------------------------------------------------
294
+ const encoded = {
295
+ register: Effect.fnUntraced(function* (workflow, execute) {
296
+ workflows.set(workflow.name, {
297
+ workflow,
298
+ execute,
299
+ scope: yield* Effect.scope
300
+ });
301
+ }),
302
+ execute: Effect.fnUntraced(function* (workflow, options) {
303
+ const entry = workflows.get(workflow.name);
304
+ if (!entry) {
305
+ return yield* Effect.orDie(Effect.fail(`Workflow ${workflow.name} is not registered`));
306
+ }
307
+ const initial = {
308
+ id: execId,
309
+ _partitionKey: options.executionId,
310
+ type: "exec",
311
+ workflowName: workflow.name,
312
+ payload: yield* encodePayload(workflow, options.payload),
313
+ parent: options.parent?.executionId,
314
+ status: "running",
315
+ suspended: false,
316
+ interrupted: false
317
+ };
318
+ const created = yield* createIfMissing(initial).pipe(annotate("execute.claim", options.executionId));
319
+ if (created || !locals.has(options.executionId)) {
320
+ yield* drive(options.executionId, options.payload, options.parent?.executionId, entry);
321
+ }
322
+ if (options.discard)
323
+ return undefined;
324
+ const local = locals.get(options.executionId);
325
+ if (local?.fiber) {
326
+ return (yield* Fiber.join(local.fiber));
327
+ }
328
+ // Foreign-owned execution: poll until exec doc reports complete.
329
+ while (true) {
330
+ const cur = yield* readExec(options.executionId);
331
+ if (Option.isSome(cur)) {
332
+ const c = yield* completeResult(workflow, cur.value);
333
+ if (Option.isSome(c))
334
+ return c.value;
335
+ }
336
+ yield* Effect.sleep(Duration.millis(500));
337
+ }
338
+ }),
339
+ poll: (workflow, executionId) => Effect.gen(function* () {
340
+ const local = locals.get(executionId);
341
+ if (local?.fiber) {
342
+ const exit = local.fiber.pollUnsafe();
343
+ if (!exit)
344
+ return Option.none();
345
+ if (exit._tag !== "Success")
346
+ return yield* Effect.die(exit.cause);
347
+ return Option.some(exit.value);
348
+ }
349
+ const state = yield* readExec(executionId);
350
+ if (Option.isNone(state))
351
+ return Option.none();
352
+ return yield* completeResult(workflow, state.value);
353
+ }),
354
+ interrupt: Effect.fnUntraced(function* (_workflow, executionId) {
355
+ const local = locals.get(executionId);
356
+ if (local)
357
+ local.instance.interrupted = true;
358
+ const current = yield* readExec(executionId);
359
+ if (Option.isNone(current) || current.value.status === "complete")
360
+ return;
361
+ yield* replaceExec({ ...current.value, interrupted: true }).pipe(Effect.catchTag("OptimisticConcurrencyException", () => Effect.void));
362
+ yield* driveById(executionId);
363
+ }),
364
+ interruptUnsafe: Effect.fnUntraced(function* (_workflow, executionId) {
365
+ const local = locals.get(executionId);
366
+ if (local)
367
+ local.instance.interrupted = true;
368
+ const current = yield* readExec(executionId);
369
+ if (Option.isSome(current) && current.value.status !== "complete") {
370
+ yield* replaceExec({ ...current.value, interrupted: true }).pipe(Effect.catchTag("OptimisticConcurrencyException", () => Effect.void));
371
+ }
372
+ if (local?.fiber)
373
+ yield* Fiber.interrupt(local.fiber);
374
+ }),
375
+ resume: (_workflow, executionId) => driveById(executionId),
376
+ activityExecute: Effect.fnUntraced(function* (activity, attempt) {
377
+ const instance = yield* WorkflowInstance;
378
+ const id = activityKey(activity.name, attempt);
379
+ const existing = yield* readPoint(id, instance.executionId).pipe(annotate("activityRead", instance.executionId));
380
+ if (Option.isSome(existing)) {
381
+ const prev = yield* decodeActivityResult(existing.value.result);
382
+ // A completed activity is replayed from its persisted result; a
383
+ // suspended one must re-run (it parked on a clock/deferred).
384
+ if (prev._tag === "Complete")
385
+ return prev;
386
+ }
387
+ const activityInstance = WorkflowInstance.initial(instance.workflow, instance.executionId);
388
+ activityInstance.interrupted = instance.interrupted;
389
+ const result = yield* activity.executeEncoded.pipe(Workflow.intoResult, Effect.provideService(WorkflowInstance, activityInstance));
390
+ const doc = {
391
+ id,
392
+ _partitionKey: instance.executionId,
393
+ type: "activity",
394
+ result: yield* encodeActivityResult(result)
395
+ };
396
+ if (Option.isSome(existing)) {
397
+ // Overwrite the previously persisted *suspended* doc with the new result.
398
+ yield* upsert(doc).pipe(annotate("activityPersist", instance.executionId));
399
+ return result;
400
+ }
401
+ // First-writer-wins: if persistence loses the race, use the persisted result.
402
+ const persisted = yield* createIfMissing(doc).pipe(annotate("activityPersist", instance.executionId));
403
+ if (persisted)
404
+ return result;
405
+ const winner = yield* readPoint(id, instance.executionId);
406
+ if (Option.isSome(winner)) {
407
+ const w = yield* decodeActivityResult(winner.value.result);
408
+ if (w._tag === "Complete")
409
+ return w;
410
+ }
411
+ return result;
412
+ }),
413
+ deferredResult: Effect.fnUntraced(function* (deferred) {
414
+ const instance = yield* WorkflowInstance;
415
+ const got = yield* readPoint(deferredKey(deferred.name), instance.executionId).pipe(annotate("deferredRead", instance.executionId));
416
+ if (Option.isNone(got))
417
+ return Option.none();
418
+ return Option.some(yield* decodeDeferredExit(got.value.exit));
419
+ }),
420
+ deferredDone: Effect.fnUntraced(function* (options) {
421
+ const created = yield* createIfMissing({
422
+ id: deferredKey(options.deferredName),
423
+ _partitionKey: options.executionId,
424
+ type: "deferred",
425
+ exit: yield* encodeDeferredExit(options.exit)
426
+ })
427
+ .pipe(annotate("deferredPersist", options.executionId));
428
+ if (!created)
429
+ return;
430
+ yield* driveById(options.executionId);
431
+ }),
432
+ scheduleClock: (workflow, options) => {
433
+ const fireAt = new Date(Date.now() + Duration.toMillis(options.clock.duration)).toISOString();
434
+ const clockDoc = {
435
+ id: clockKey(options.clock.name),
436
+ _partitionKey: options.executionId,
437
+ type: "clock",
438
+ workflowName: workflow.name,
439
+ deferredName: options.clock.deferred.name,
440
+ fireAt
441
+ };
442
+ return Effect.gen(function* () {
443
+ yield* createIfMissing(clockDoc).pipe(annotate("clockPersist", options.executionId));
444
+ // Fast-path in-process timer. If this process dies, the clock poller
445
+ // picks up the persisted doc and fires the deferred.
446
+ yield* fireClock(clockDoc).pipe(Effect.delay(options.clock.duration), FiberMap.run(clocks, `${options.executionId}/${options.clock.name}`, { onlyIfMissing: true }), Effect.asVoid);
447
+ });
448
+ }
449
+ };
450
+ const engine = makeUnsafe(encoded);
451
+ // --- Recovery poller --------------------------------------------------
452
+ // Scan for executions whose lease has lapsed (or was never set) and
453
+ // re-drive them locally. driveById will go through claim → fork fiber,
454
+ // resuming activities from persisted results.
455
+ if (Duration.toMillis(recoveryInterval) > 0) {
456
+ const recoverStep = Effect
457
+ .gen(function* () {
458
+ const nowIso = new Date().toISOString();
459
+ const stale = yield* Effect.promise(() => container
460
+ .items
461
+ .query({
462
+ query: "SELECT c._partitionKey, c.workflowName FROM c WHERE c.type = 'exec' AND c.status = 'running' AND (NOT IS_DEFINED(c.leaseExpiresAt) OR c.leaseExpiresAt <= @now)",
463
+ parameters: [{ name: "@now", value: nowIso }]
464
+ })
465
+ .fetchAll());
466
+ for (const row of stale.resources) {
467
+ if (!workflows.has(row.workflowName))
468
+ continue;
469
+ const local = locals.get(row._partitionKey);
470
+ if (local?.fiber && !local.fiber.pollUnsafe())
471
+ continue;
472
+ yield* Effect.forkIn(driveById(row._partitionKey), scope);
473
+ }
474
+ })
475
+ .pipe(annotate("recoveryScan"), Effect.catchCause(() => Effect.void));
476
+ yield* recoverStep.pipe(Effect.repeat(Schedule.spaced(recoveryInterval)), Effect.forkIn(scope));
477
+ }
478
+ // --- Clock poller -----------------------------------------------------
479
+ // Cross-partition scan for clocks whose fireAt is due. Fires the deferred
480
+ // via createIfMissing (idempotent) so multiple pollers across processes
481
+ // converge. Also acts as the restart recovery path for clocks scheduled
482
+ // before a crash.
483
+ if (Duration.toMillis(clockPollInterval) > 0) {
484
+ const clockStep = Effect
485
+ .gen(function* () {
486
+ const nowIso = new Date().toISOString();
487
+ const due = yield* Effect.promise(() => container
488
+ .items
489
+ .query({
490
+ query: "SELECT c.id, c._partitionKey, c.workflowName, c.deferredName FROM c WHERE c.type = 'clock' AND c.fireAt <= @now",
491
+ parameters: [{ name: "@now", value: nowIso }]
492
+ })
493
+ .fetchAll());
494
+ for (const row of due.resources) {
495
+ yield* Effect.forkIn(fireClock({
496
+ id: row.id,
497
+ _partitionKey: row._partitionKey,
498
+ type: "clock",
499
+ workflowName: row.workflowName,
500
+ deferredName: row.deferredName,
501
+ fireAt: nowIso
502
+ }), scope);
503
+ }
504
+ })
505
+ .pipe(annotate("clockScan"), Effect.catchCause(() => Effect.void));
506
+ yield* clockStep.pipe(Effect.repeat(Schedule.spaced(clockPollInterval)), Effect.forkIn(scope));
507
+ }
508
+ return engine;
509
+ });
510
+ /**
511
+ * Cosmos DB backed `WorkflowEngine` layer.
512
+ *
513
+ * Per-execution writes share a partition key (TransactionalBatch-eligible) and
514
+ * use OCC via `_etag`/IfMatch, giving first-writer-wins semantics for activity
515
+ * results, durable-deferred completions, and exec-state transitions. All
516
+ * persisted payloads/results/exits are round-tripped through schema codecs.
517
+ */
518
+ export const layerCosmos = (cfg) => Layer
519
+ .effect(WorkflowEngine)(makeCosmosWorkflowEngine(cfg))
520
+ .pipe(Layer.provide(CosmosClientLayer(Redacted.value(cfg.url), cfg.dbName)));
521
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV29ya2Zsb3dFbmdpbmVDb3Ntb3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvV29ya2Zsb3dFbmdpbmVDb3Ntb3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQkc7QUFDSCxPQUFPLEtBQUssTUFBTSxNQUFNLG1CQUFtQixDQUFBO0FBQzNDLE9BQU8sS0FBSyxLQUFLLE1BQU0sa0JBQWtCLENBQUE7QUFDekMsT0FBTyxLQUFLLE1BQU0sTUFBTSxtQkFBbUIsQ0FBQTtBQUMzQyxPQUFPLEtBQUssQ0FBQyxNQUFNLG1CQUFtQixDQUFBO0FBQ3RDLE9BQU8sS0FBSyxRQUFRLE1BQU0saUJBQWlCLENBQUE7QUFDM0MsT0FBTyxLQUFLLElBQUksTUFBTSxhQUFhLENBQUE7QUFDbkMsT0FBTyxLQUFLLEtBQUssTUFBTSxjQUFjLENBQUE7QUFDckMsT0FBTyxLQUFLLFFBQVEsTUFBTSxpQkFBaUIsQ0FBQTtBQUMzQyxPQUFPLEtBQUssUUFBUSxNQUFNLGlCQUFpQixDQUFBO0FBQzNDLE9BQU8sS0FBSyxRQUFRLE1BQU0saUJBQWlCLENBQUE7QUFFM0MsT0FBTyxLQUFLLFFBQVEsTUFBTSxtQ0FBbUMsQ0FBQTtBQUM3RCxPQUFPLEVBQWdCLFVBQVUsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUNwSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQ3hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUNwRSxPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDNUQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLFVBQVUsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQStEOUQsTUFBTSxNQUFNLEdBQUcsTUFBZSxDQUFBO0FBQzlCLE1BQU0sV0FBVyxHQUFHLENBQUMs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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "4.0.0-beta.256",
3
+ "version": "4.0.0-beta.257",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -13,7 +13,7 @@
13
13
  "proper-lockfile": "^4.1.2",
14
14
  "pure-rand": "8.4.0",
15
15
  "query-string": "^9.3.1",
16
- "effect-app": "4.0.0-beta.256"
16
+ "effect-app": "4.0.0-beta.257"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@azure/cosmos": "^4.9.3",
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NoZWNrLWFnZy1pbmZlci50ZXN0LWQuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL19jaGVjay1hZ2ctaW5mZXIudGVzdC1kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_check-agg-infer.test-d.d.ts","sourceRoot":"","sources":["../_check-agg-infer.test-d.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import * as S from "effect-app/Schema";
2
+ import { aggregate, make, where } from "effect-app/Model/query";
3
+ const baseSchema = S.Struct({
4
+ id: S.String,
5
+ address: S.Struct({ city: S.String }),
6
+ active: S.Boolean,
7
+ qty: S.Number
8
+ });
9
+ // Should compile — Row inferred from pipe
10
+ const _ok = make().pipe(aggregate(S.Struct({ city: S.String, count: S.NonNegativeInt, total: S.Number }), ($) => ({
11
+ city: $.field("address.city"),
12
+ count: $.countWhen((q) => q.pipe(where("active", true))),
13
+ total: $.sum("qty")
14
+ })));
15
+ // Should ERROR — bad path
16
+ const _bad = make().pipe(aggregate(S.Struct({ a: S.String }), ($) => ({
17
+ a: $.field("nonexistent")
18
+ })));
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NoZWNrLWFnZy1pbmZlci50ZXN0LWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9fY2hlY2stYWdnLWluZmVyLnRlc3QtZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssQ0FBQyxNQUFNLG1CQUFtQixDQUFBO0FBQ3RDLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLHdCQUF3QixDQUFBO0FBRS9ELE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDMUIsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNO0lBQ1osT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3JDLE1BQU0sRUFBRSxDQUFDLENBQUMsT0FBTztJQUNqQixHQUFHLEVBQUUsQ0FBQyxDQUFDLE1BQU07Q0FDZCxDQUFDLENBQUE7QUFHRiwwQ0FBMEM7QUFDMUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxFQUFPLENBQUMsSUFBSSxDQUMxQixTQUFTLENBQ1AsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsY0FBYyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFDdEUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDTixJQUFJLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7SUFDN0IsS0FBSyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3hELEtBQUssRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztDQUNwQixDQUFDLENBQ0gsQ0FDRixDQUFBO0FBRUQsMEJBQTBCO0FBQzFCLE1BQU0sSUFBSSxHQUFHLElBQUksRUFBTyxDQUFDLElBQUksQ0FDM0IsU0FBUyxDQUNQLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQ3pCLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ04sQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDO0NBQzFCLENBQUMsQ0FDSCxDQUNGLENBQUEifQ==
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NoZWNrLXByb2otaW5mZXIudGVzdC1kLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9fY2hlY2stcHJvai1pbmZlci50ZXN0LWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_check-proj-infer.test-d.d.ts","sourceRoot":"","sources":["../_check-proj-infer.test-d.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import * as S from "effect-app/Schema";
2
+ import { make, projectComputed, where } from "effect-app/Model/query";
3
+ const baseSchema = S.Struct({
4
+ id: S.String,
5
+ items: S.Array(S.Struct({ articleId: S.String, qty: S.Number, note: S.String }))
6
+ });
7
+ // Should compile — Row inferred from pipe
8
+ const _ok = make().pipe(projectComputed(S.Struct({ id: S.String, total: S.Number, distinctArticles: S.NonNegativeInt }), ({ relation }) => ({
9
+ total: relation("items").sum("qty"),
10
+ distinctArticles: relation("items").distinctCount("articleId", where("qty", "gte", 0))
11
+ })));
12
+ // Should ERROR — bad path on relation element
13
+ const _bad = make().pipe(projectComputed(S.Struct({ a: S.Number }), ({ relation }) => ({
14
+ a: relation("items").sum("nonexistent")
15
+ })));
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NoZWNrLXByb2otaW5mZXIudGVzdC1kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vX2NoZWNrLXByb2otaW5mZXIudGVzdC1kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxDQUFDLE1BQU0sbUJBQW1CLENBQUE7QUFDdEMsT0FBTyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFFckUsTUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMxQixFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU07SUFDWixLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0NBQ2pGLENBQUMsQ0FBQTtBQUdGLDBDQUEwQztBQUMxQyxNQUFNLEdBQUcsR0FBRyxJQUFJLEVBQU8sQ0FBQyxJQUFJLENBQzFCLGVBQWUsQ0FDYixDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLEVBQy9FLENBQUMsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNqQixLQUFLLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUM7SUFDbkMsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7Q0FDdkYsQ0FBQyxDQUNILENBQ0YsQ0FBQTtBQUVELDhDQUE4QztBQUM5QyxNQUFNLElBQUksR0FBRyxJQUFJLEVBQU8sQ0FBQyxJQUFJLENBQzNCLGVBQWUsQ0FDYixDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUN6QixDQUFDLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDakIsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDO0NBQ3hDLENBQUMsQ0FDSCxDQUNGLENBQUEifQ==
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NoZWNrLXRpZ2h0ZW4udGVzdC1kLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9fY2hlY2stdGlnaHRlbi50ZXN0LWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_check-tighten.test-d.d.ts","sourceRoot":"","sources":["../_check-tighten.test-d.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import * as S from "effect-app/Schema";
2
+ import { computed, relation } from "effect-app/Model/query";
3
+ const baseSchema = S.Struct({
4
+ id: S.String,
5
+ items: S.Array(S.Struct({ articleId: S.String, qty: S.Number }))
6
+ });
7
+ // Should compile:
8
+ const _ok = computed({
9
+ a: relation("items").sum("qty"),
10
+ b: relation("items").distinctCount("articleId"),
11
+ c: relation("items").collect("articleId"),
12
+ d: relation("items").collectFields(["articleId", "qty"])
13
+ });
14
+ // Should ERROR — invalid field paths
15
+ const _bad = computed({
16
+ a: relation("items").sum("nonexistent"),
17
+ b: relation("items").distinctCount("not_a_field"),
18
+ c: relation("items").collect("zzz"),
19
+ d: relation("items").collectFields(["zzz"])
20
+ });
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NoZWNrLXRpZ2h0ZW4udGVzdC1kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vX2NoZWNrLXRpZ2h0ZW4udGVzdC1kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxDQUFDLE1BQU0sbUJBQW1CLENBQUE7QUFDdEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQUUzRCxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzFCLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTTtJQUNaLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7Q0FDakUsQ0FBQyxDQUFBO0FBR0Ysa0JBQWtCO0FBQ2xCLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQztJQUNuQixDQUFDLEVBQUUsUUFBUSxDQUFNLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUM7SUFDcEMsQ0FBQyxFQUFFLFFBQVEsQ0FBTSxPQUFPLENBQUMsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO0lBQ3BELENBQUMsRUFBRSxRQUFRLENBQU0sT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQztJQUM5QyxDQUFDLEVBQUUsUUFBUSxDQUFNLE9BQU8sQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsQ0FBQztDQUM5RCxDQUFDLENBQUE7QUFFRixxQ0FBcUM7QUFDckMsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDO0lBQ3BCLENBQUMsRUFBRSxRQUFRLENBQU0sT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQztJQUM1QyxDQUFDLEVBQUUsUUFBUSxDQUFNLE9BQU8sQ0FBQyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUM7SUFDdEQsQ0FBQyxFQUFFLFFBQVEsQ0FBTSxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO0lBQ3hDLENBQUMsRUFBRSxRQUFRLENBQU0sT0FBTyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7Q0FDakQsQ0FBQyxDQUFBIn0=