alink-cli 0.7.2 → 0.7.4

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.
@@ -0,0 +1,1554 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Bl as void_, Bo as provideContext, Cc as make$6, Cd as match, Cl as asSome, Cs as void_$1, Dl as exitHasInterrupts, El as endSpan, Es as withFiber$1, Fi as failCauseUnsafe, Fl as succeed, Gc as isSuccess, Ha as context, Hu as failVoid, Id as withFiber, Ii as make$5, Il as succeedNone, Io as orDie, Ja as exit, Jd as hash, Ju as succeed$1, Ld as assignProperty, Ll as sync, Md as Prototype, Ml as makeSpanUnsafe, Mo as onExit$1, Nd as PipeInspectableProto, Nl as onExit, Oc as TracerTimingEnabled, Ol as fiberInterrupt, Pd as exitSucceed, Qa as flatMap, Qd as hasProperty, Qu as add, Ru as filterMap, So as map, Ss as useSpan, Tc as provide, Tl as contextWith, Ua as contextWith$1, Vo as provideService, Wl as ParentSpan, Xu as Reference, Zo as scoped, Zu as Service, _c as Scope, aa as runIn, as as suspend, bc as close, bd as isNone, bl as ClockRef, bs as uninterruptibleMask, df as constUndefined, di as make$4, ed as get$2, es as serviceOption, eu as fromInputUnsafe, fi as remove, hf as flow, iu as isZero, jl as forkUnsafe, kl as fiberJoin, lo as gen, mf as dual, mi as size, ni as unwrap, no as fnUntraced, ns as succeed$2, nu as infinity, os as sync$1, pi as set$1, qa as ensuring, qo as runForkWith, qs as Clock, rc as effect, ru as isFinite, sd as merge, ss as tap, td as getOption$1, ui as get$1, uu as toMillis, vc as addFinalizer, xd as isSome, xo as makeSpanScoped, xr as fromQueue, zi as offerUnsafe, zl as updateContext } from "./Schema-B3i-HrZQ.mjs";
4
+ //#region ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=a18f963109656ddbeb2a99ca45f942ecf54830986259eb01ce6a970421c9c6a9/node_modules/effect/dist/Cache.js
5
+ /**
6
+ * Caches values loaded by an Effect lookup function.
7
+ *
8
+ * A cache stores successful and failed lookup results, shares an in-progress
9
+ * lookup when multiple callers request the same missing key, and limits entries
10
+ * by capacity and optional time-to-live rules. This module includes helpers for
11
+ * reading, setting, refreshing, invalidating, and inspecting cache contents.
12
+ *
13
+ * @since 4.0.0
14
+ */
15
+ const TypeId$1 = "~effect/Cache";
16
+ /**
17
+ * Creates a cache with dynamic time-to-live based on the result and key.
18
+ *
19
+ * **When to use**
20
+ *
21
+ * Use when you need different cache entry lifetimes based on the lookup result
22
+ * or key characteristics.
23
+ *
24
+ * **Details**
25
+ *
26
+ * The timeToLive function receives both the exit result and the key, allowing
27
+ * for flexible TTL policies based on success/failure state and key characteristics.
28
+ *
29
+ * **Example** (Configuring dynamic time to live)
30
+ *
31
+ * ```ts import.meta.vitest
32
+ * import { Cache, Effect, Exit } from "effect"
33
+ *
34
+ * // Cache with TTL based on computed value
35
+ * const program = Effect.gen(function*() {
36
+ * const cache = yield* Cache.makeWith(
37
+ * (id: number) => Effect.succeed({ id, active: id % 2 === 0 }),
38
+ * {
39
+ * capacity: 1000,
40
+ * timeToLive(exit) {
41
+ * if (Exit.isSuccess(exit)) {
42
+ * const user = exit.value
43
+ * return user.active ? "1 hour" : "5 minutes"
44
+ * }
45
+ * return "30 seconds"
46
+ * }
47
+ * }
48
+ * )
49
+ *
50
+ * return cache.capacity
51
+ * })
52
+ *
53
+ * const actual = await Effect.runPromise(program)
54
+ * actual // => 1000
55
+ * ```
56
+ *
57
+ * @see {@link make} for a simpler cache constructor with a fixed time-to-live for all entries
58
+ * @category constructors
59
+ * @since 2.0.0
60
+ */
61
+ const makeWith = (lookup, options) => contextWith((context) => {
62
+ const self = Object.create(Proto);
63
+ self.lookup = (key) => updateContext(lookup(key), (input) => merge(context, input));
64
+ self.map = make$4();
65
+ self.capacity = options.capacity;
66
+ self.timeToLive = options.timeToLive ? (exit, key) => fromInputUnsafe(options.timeToLive(exit, key)) : defaultTimeToLive;
67
+ return succeed(self);
68
+ });
69
+ /**
70
+ * Creates a cache with a fixed time-to-live for all entries.
71
+ *
72
+ * **Details**
73
+ *
74
+ * This is the basic cache constructor where all entries share the same TTL.
75
+ * The lookup function will be called when a key is not found or has expired.
76
+ *
77
+ * **Example** (Creating a basic cache)
78
+ *
79
+ * ```ts import.meta.vitest
80
+ * import { Cache, Effect } from "effect"
81
+ *
82
+ * // Basic cache with string keys
83
+ * const program = Effect.gen(function*() {
84
+ * const cache = yield* Cache.make<string, number>({
85
+ * capacity: 100,
86
+ * lookup: (key) => Effect.succeed(key.length)
87
+ * })
88
+ *
89
+ * const result1 = yield* Cache.get(cache, "hello")
90
+ * const result2 = yield* Cache.get(cache, "world")
91
+ * return { result1, result2 }
92
+ * })
93
+ *
94
+ * const actual = await Effect.runPromise(program)
95
+ * actual // => { result1: 5, result2: 5 }
96
+ * ```
97
+ *
98
+ * **Example** (Creating a cache with TTL)
99
+ *
100
+ * ```ts import.meta.vitest
101
+ * import { Cache, Effect } from "effect"
102
+ *
103
+ * const program = Effect.gen(function*() {
104
+ * const users = new Map([
105
+ * [123, { name: "Ada", email: "ada@example.com" }],
106
+ * [456, { name: "Grace", email: "grace@example.com" }]
107
+ * ])
108
+ *
109
+ * const cache = yield* Cache.make<
110
+ * number,
111
+ * { name: string; email: string },
112
+ * string
113
+ * >({
114
+ * capacity: 500,
115
+ * lookup: (userId) =>
116
+ * Effect.suspend(() => {
117
+ * const user = users.get(userId)
118
+ * return user === undefined
119
+ * ? Effect.fail(`User ${userId} not found`)
120
+ * : Effect.succeed(user)
121
+ * }),
122
+ * timeToLive: "15 minutes"
123
+ * })
124
+ *
125
+ * const user1 = yield* Cache.get(cache, 123)
126
+ * const user2 = yield* Cache.get(cache, 123)
127
+ * return [user1, user2, user1 === user2] as const
128
+ * })
129
+ *
130
+ * const actual = await Effect.runPromise(program)
131
+ * actual // => [{ name: "Ada", email: "ada@example.com" }, { name: "Ada", email: "ada@example.com" }, true]
132
+ * ```
133
+ *
134
+ * @category constructors
135
+ * @since 2.0.0
136
+ */
137
+ const make$3 = (options) => makeWith(options.lookup, {
138
+ ...options,
139
+ timeToLive: options.timeToLive ? () => options.timeToLive : defaultTimeToLive
140
+ });
141
+ const Proto = {
142
+ ...PipeInspectableProto,
143
+ [TypeId$1]: TypeId$1,
144
+ toJSON() {
145
+ return {
146
+ _id: "Cache",
147
+ capacity: this.capacity,
148
+ map: this.map
149
+ };
150
+ }
151
+ };
152
+ const defaultTimeToLive = (_, _key) => infinity;
153
+ /**
154
+ * Retrieves the value for a key, invoking the lookup function on a cache miss
155
+ * or expired entry.
156
+ *
157
+ * **Details**
158
+ *
159
+ * Concurrent `get` calls for the same missing key share the same pending
160
+ * lookup. The cache stores the lookup `Exit`, so failed lookups are cached and
161
+ * will fail again until the entry expires, is invalidated, or is refreshed.
162
+ *
163
+ * **Example** (Getting cached values)
164
+ *
165
+ * ```ts import.meta.vitest
166
+ * import { Cache, Effect } from "effect"
167
+ *
168
+ * const program = Effect.gen(function*() {
169
+ * const cache = yield* Cache.make({
170
+ * capacity: 10,
171
+ * lookup: (key: string) => Effect.succeed(key.length)
172
+ * })
173
+ *
174
+ * // Cache miss - triggers lookup function
175
+ * const result1 = yield* Cache.get(cache, "hello")
176
+ *
177
+ * // Cache hit - returns cached value without lookup
178
+ * const result2 = yield* Cache.get(cache, "hello")
179
+ *
180
+ * return { result1, result2 }
181
+ * })
182
+ *
183
+ * const actual = await Effect.runPromise(program)
184
+ * actual // => { result1: 5, result2: 5 }
185
+ * ```
186
+ *
187
+ * **Example** (Handling lookup failures)
188
+ *
189
+ * ```ts import.meta.vitest
190
+ * import { Cache, Effect, Exit } from "effect"
191
+ *
192
+ * // Error handling when lookup fails
193
+ * const program = Effect.gen(function*() {
194
+ * const cache = yield* Cache.make<string, number, string>({
195
+ * capacity: 10,
196
+ * lookup: (key: string) =>
197
+ * key === "error"
198
+ * ? Effect.fail("Lookup failed")
199
+ * : Effect.succeed(key.length)
200
+ * })
201
+ *
202
+ * // Successful lookup
203
+ * const success = yield* Cache.get(cache, "hello")
204
+ *
205
+ * // Failed lookup - returns error
206
+ * const failure = yield* Effect.exit(Cache.get(cache, "error"))
207
+ * return [success, failure] as const
208
+ * })
209
+ *
210
+ * const actual = await Effect.runPromise(program)
211
+ * actual // => [5, Exit.fail("Lookup failed")]
212
+ * ```
213
+ *
214
+ * **Example** (Sharing concurrent lookups)
215
+ *
216
+ * ```ts import.meta.vitest
217
+ * import { Cache, Effect } from "effect"
218
+ *
219
+ * // Concurrent access - multiple gets of same key only invoke lookup once
220
+ * const program = Effect.gen(function*() {
221
+ * let lookupCount = 0
222
+ * const cache = yield* Cache.make({
223
+ * capacity: 10,
224
+ * lookup: (key: string) =>
225
+ * Effect.sync(() => {
226
+ * lookupCount++
227
+ * return key.length
228
+ * })
229
+ * })
230
+ *
231
+ * // Multiple concurrent gets
232
+ * const results = yield* Effect.all([
233
+ * Cache.get(cache, "hello"),
234
+ * Cache.get(cache, "hello"),
235
+ * Cache.get(cache, "hello")
236
+ * ], { concurrency: "unbounded" })
237
+ *
238
+ * return { results, lookupCount }
239
+ * })
240
+ *
241
+ * const actual = await Effect.runPromise(program)
242
+ * actual // => { results: [5, 5, 5], lookupCount: 1 }
243
+ * ```
244
+ *
245
+ * @category combinators
246
+ * @since 4.0.0
247
+ */
248
+ const get = /*#__PURE__*/ dual(2, (self, key) => withFiber((fiber) => {
249
+ const oentry = get$1(self.map, key);
250
+ if (isSome(oentry) && !hasExpired(oentry.value, fiber)) {
251
+ remove(self.map, key);
252
+ set$1(self.map, key, oentry.value);
253
+ return oentry.value.await();
254
+ }
255
+ const entry = new EntryImpl(fiber, self.lookup(key));
256
+ entry.fiber.addObserver((exit) => {
257
+ if (exitHasInterrupts(exit)) {
258
+ const current = get$1(self.map, key);
259
+ if (isSome(current) && current.value === entry) remove(self.map, key);
260
+ return;
261
+ }
262
+ const ttl = self.timeToLive(exit, key);
263
+ if (isFinite(ttl)) entry.expiresAt = fiber.getRef(ClockRef).currentTimeMillisUnsafe() + toMillis(ttl);
264
+ else if (isZero(ttl)) remove(self.map, key);
265
+ });
266
+ set$1(self.map, key, entry);
267
+ if (Number.isFinite(self.capacity)) checkCapacity(self);
268
+ return entry.await();
269
+ }));
270
+ var EntryImpl = class {
271
+ expiresAt;
272
+ awaiters;
273
+ fiber;
274
+ constructor(parent, valueEffect) {
275
+ this.fiber = forkUnsafe(parent, valueEffect, true, true);
276
+ this.awaiters = 0;
277
+ this.expiresAt = void 0;
278
+ }
279
+ await() {
280
+ const exit = this.fiber.pollUnsafe();
281
+ if (exit) return exit;
282
+ this.awaiters++;
283
+ return onExit(fiberJoin(this.fiber), () => {
284
+ this.awaiters--;
285
+ if (this.awaiters > 0 || this.fiber.pollUnsafe()) return void_;
286
+ return fiberInterrupt(this.fiber);
287
+ });
288
+ }
289
+ };
290
+ const hasExpired = (entry, fiber) => {
291
+ if (entry.expiresAt === void 0) return false;
292
+ return fiber.getRef(ClockRef).currentTimeMillisUnsafe() >= entry.expiresAt;
293
+ };
294
+ const checkCapacity = (self) => {
295
+ let diff = size(self.map) - self.capacity;
296
+ if (diff <= 0) return;
297
+ for (const [key] of self.map) {
298
+ remove(self.map, key);
299
+ diff--;
300
+ if (diff === 0) return;
301
+ }
302
+ };
303
+ /**
304
+ * Reads an existing cache entry without invoking the lookup function.
305
+ *
306
+ * **Details**
307
+ *
308
+ * Returns `Option.none()` when the key is missing or expired, and `Option.some`
309
+ * when a cached lookup has succeeded. If the entry is still pending, waits for
310
+ * it to complete. If the cached or pending lookup fails, this effect fails with
311
+ * the same error.
312
+ *
313
+ * **Example** (Reading cached values without lookup)
314
+ *
315
+ * ```ts import.meta.vitest
316
+ * import { Cache, Effect, Option } from "effect"
317
+ *
318
+ * const program = Effect.gen(function*() {
319
+ * const cache = yield* Cache.make({
320
+ * capacity: 10,
321
+ * lookup: (key: string) => Effect.succeed(key.length)
322
+ * })
323
+ *
324
+ * // No value in cache yet - returns None without lookup
325
+ * const empty = yield* Cache.getOption(cache, "hello")
326
+ *
327
+ * // Populate cache using get
328
+ * yield* Cache.get(cache, "hello")
329
+ *
330
+ * // Now getOption returns the cached value
331
+ * const cached = yield* Cache.getOption(cache, "hello")
332
+ * return [empty, cached] as const
333
+ * })
334
+ *
335
+ * const actual = await Effect.runPromise(program)
336
+ * actual // => [Option.none(), Option.some(5)]
337
+ * ```
338
+ *
339
+ * **Example** (Skipping expired entries)
340
+ *
341
+ * ```ts import.meta.vitest
342
+ * import { Cache, Effect, Option } from "effect"
343
+ * import { TestClock } from "effect/testing"
344
+ *
345
+ * // Expired entries return None
346
+ * const program = Effect.gen(function*() {
347
+ * const cache = yield* Cache.make({
348
+ * capacity: 10,
349
+ * lookup: (key: string) => Effect.succeed(key.length),
350
+ * timeToLive: "1 hour"
351
+ * })
352
+ *
353
+ * // Add value to cache
354
+ * yield* Cache.get(cache, "hello")
355
+ *
356
+ * // Value exists before expiration
357
+ * const beforeExpiry = yield* Cache.getOption(cache, "hello")
358
+ *
359
+ * // Simulate time passing
360
+ * yield* TestClock.adjust("2 hours")
361
+ *
362
+ * // Value expired - returns None
363
+ * const afterExpiry = yield* Cache.getOption(cache, "hello")
364
+ * return [beforeExpiry, afterExpiry] as const
365
+ * })
366
+ *
367
+ * const actual = await Effect.runPromise(Effect.provide(program, TestClock.layer()))
368
+ * actual // => [Option.some(5), Option.none()]
369
+ * ```
370
+ *
371
+ * **Example** (Waiting for pending lookups)
372
+ *
373
+ * ```ts import.meta.vitest
374
+ * import { Cache, Deferred, Effect, Fiber, Option } from "effect"
375
+ *
376
+ * // Waits for ongoing computation to complete
377
+ * const program = Effect.gen(function*() {
378
+ * const deferred = yield* Deferred.make<void>()
379
+ * const cache = yield* Cache.make({
380
+ * capacity: 10,
381
+ * lookup: (_key: string) => Deferred.await(deferred).pipe(Effect.as(42))
382
+ * })
383
+ *
384
+ * // Start lookup in background
385
+ * const getFiber = yield* Effect.forkChild(Cache.get(cache, "key"))
386
+ *
387
+ * // getOption waits for ongoing computation
388
+ * const optionFiber = yield* Effect.forkChild(Cache.getOption(cache, "key"))
389
+ *
390
+ * // Complete the computation
391
+ * yield* Deferred.succeed(deferred, void 0)
392
+ *
393
+ * const result = yield* Fiber.join(optionFiber)
394
+ * const value = yield* Fiber.join(getFiber)
395
+ * return [result, value] as const
396
+ * })
397
+ *
398
+ * const actual = await Effect.runPromise(program)
399
+ * actual // => [Option.some(42), 42]
400
+ * ```
401
+ *
402
+ * @category combinators
403
+ * @since 4.0.0
404
+ */
405
+ const getOption = /*#__PURE__*/ dual(2, (self, key) => withFiber((fiber) => {
406
+ const entry = getImpl(self, key, fiber);
407
+ return entry ? asSome(entry.await()) : succeedNone;
408
+ }));
409
+ const getImpl = (self, key, fiber, isRead = true) => {
410
+ const oentry = get$1(self.map, key);
411
+ if (isNone(oentry)) return;
412
+ else if (hasExpired(oentry.value, fiber)) {
413
+ remove(self.map, key);
414
+ return;
415
+ } else if (isRead) {
416
+ remove(self.map, key);
417
+ set$1(self.map, key, oentry.value);
418
+ }
419
+ return oentry.value;
420
+ };
421
+ /**
422
+ * Sets the value associated with the specified key in the cache. This will
423
+ * overwrite any existing value for that key, skipping the lookup function.
424
+ *
425
+ * **Example** (Setting values directly)
426
+ *
427
+ * ```ts import.meta.vitest
428
+ * import { Cache, Effect } from "effect"
429
+ *
430
+ * const program = Effect.gen(function*() {
431
+ * const cache = yield* Cache.make({
432
+ * capacity: 100,
433
+ * lookup: (key: string) => Effect.succeed(key.length)
434
+ * })
435
+ *
436
+ * // Set a value directly without invoking lookup
437
+ * yield* Cache.set(cache, "hello", 42)
438
+ * return yield* Cache.get(cache, "hello")
439
+ * })
440
+ *
441
+ * const actual = await Effect.runPromise(program)
442
+ * actual // => 42
443
+ * ```
444
+ *
445
+ * **Example** (Overwriting cached values)
446
+ *
447
+ * ```ts import.meta.vitest
448
+ * import { Cache, Effect } from "effect"
449
+ *
450
+ * // Overwriting existing cached values
451
+ * const program = Effect.gen(function*() {
452
+ * const cache = yield* Cache.make({
453
+ * capacity: 100,
454
+ * lookup: (key: string) => Effect.succeed(key.length)
455
+ * })
456
+ *
457
+ * // First get populates via lookup
458
+ * const original = yield* Cache.get(cache, "test") // 4
459
+ *
460
+ * // Set overwrites the cached value
461
+ * yield* Cache.set(cache, "test", 999)
462
+ * const updated = yield* Cache.get(cache, "test") // 999
463
+ *
464
+ * return { original, updated }
465
+ * })
466
+ *
467
+ * const actual = await Effect.runPromise(program)
468
+ * actual // => { original: 4, updated: 999 }
469
+ * ```
470
+ *
471
+ * **Example** (Applying TTL to set values)
472
+ *
473
+ * ```ts import.meta.vitest
474
+ * import { Cache, Effect } from "effect"
475
+ * import { TestClock } from "effect/testing"
476
+ *
477
+ * // TTL behavior with set operations
478
+ * const program = Effect.gen(function*() {
479
+ * const cache = yield* Cache.make({
480
+ * capacity: 100,
481
+ * lookup: (key: string) => Effect.succeed(key.length),
482
+ * timeToLive: "1 hour"
483
+ * })
484
+ *
485
+ * // Set value with TTL applied
486
+ * yield* Cache.set(cache, "temporary", 123)
487
+ * const beforeExpiry = yield* Cache.has(cache, "temporary")
488
+ *
489
+ * // Advance time past TTL
490
+ * yield* TestClock.adjust("2 hours")
491
+ * const afterExpiry = yield* Cache.has(cache, "temporary")
492
+ * return [beforeExpiry, afterExpiry]
493
+ * })
494
+ *
495
+ * const actual = await Effect.runPromise(Effect.provide(program, TestClock.layer()))
496
+ * actual // => [true, false]
497
+ * ```
498
+ *
499
+ * **Example** (Enforcing capacity when setting values)
500
+ *
501
+ * ```ts import.meta.vitest
502
+ * import { Cache, Effect } from "effect"
503
+ *
504
+ * // Capacity enforcement with set operations
505
+ * const program = Effect.gen(function*() {
506
+ * const cache = yield* Cache.make({
507
+ * capacity: 2,
508
+ * lookup: (key: string) => Effect.succeed(key.length)
509
+ * })
510
+ *
511
+ * // Fill cache to capacity
512
+ * yield* Cache.set(cache, "a", 1)
513
+ * yield* Cache.set(cache, "b", 2)
514
+ * const sizeBeforeEviction = yield* Cache.size(cache)
515
+ *
516
+ * // Adding another entry evicts oldest
517
+ * yield* Cache.set(cache, "c", 3)
518
+ * const sizeAfterEviction = yield* Cache.size(cache)
519
+ * const hasOldest = yield* Cache.has(cache, "a")
520
+ * const hasNewest = yield* Cache.has(cache, "c")
521
+ * return [sizeBeforeEviction, sizeAfterEviction, hasOldest, hasNewest]
522
+ * })
523
+ *
524
+ * const actual = await Effect.runPromise(program)
525
+ * actual // => [2, 2, false, true]
526
+ * ```
527
+ *
528
+ * @category combinators
529
+ * @since 4.0.0
530
+ */
531
+ const set = /*#__PURE__*/ dual(3, (self, key, value) => withFiber((fiber) => {
532
+ const exit = exitSucceed(value);
533
+ const entry = new EntryImpl(fiber, exit);
534
+ const ttl = self.timeToLive(exit, key);
535
+ if (isZero(ttl)) {
536
+ remove(self.map, key);
537
+ return void_;
538
+ }
539
+ entry.expiresAt = isFinite(ttl) ? fiber.getRef(ClockRef).currentTimeMillisUnsafe() + toMillis(ttl) : void 0;
540
+ set$1(self.map, key, entry);
541
+ checkCapacity(self);
542
+ return void_;
543
+ }));
544
+ /**
545
+ * Invalidates the entry associated with the specified key in the cache.
546
+ *
547
+ * **Example** (Invalidating cached entries)
548
+ *
549
+ * ```ts import.meta.vitest
550
+ * import { Cache, Effect } from "effect"
551
+ *
552
+ * const program = Effect.gen(function*() {
553
+ * const cache = yield* Cache.make({
554
+ * capacity: 10,
555
+ * lookup: (key: string) => Effect.succeed(key.length)
556
+ * })
557
+ *
558
+ * // Add a value to the cache
559
+ * yield* Cache.get(cache, "hello")
560
+ * const beforeInvalidation = yield* Cache.has(cache, "hello")
561
+ *
562
+ * // Invalidate the entry
563
+ * yield* Cache.invalidate(cache, "hello")
564
+ * const afterInvalidation = yield* Cache.has(cache, "hello")
565
+ *
566
+ * // Invalidating non-existent keys doesn't error
567
+ * yield* Cache.invalidate(cache, "nonexistent")
568
+ *
569
+ * // Get after invalidation will invoke lookup again
570
+ * let lookupCount = 0
571
+ * const cache2 = yield* Cache.make({
572
+ * capacity: 10,
573
+ * lookup: (key: string) =>
574
+ * Effect.sync(() => {
575
+ * lookupCount++
576
+ * return key.length
577
+ * })
578
+ * })
579
+ *
580
+ * yield* Cache.get(cache2, "test") // lookupCount = 1
581
+ * yield* Cache.invalidate(cache2, "test")
582
+ * yield* Cache.get(cache2, "test") // lookupCount = 2 (lookup called again)
583
+ * return { beforeInvalidation, afterInvalidation, lookupCount }
584
+ * })
585
+ *
586
+ * const actual = await Effect.runPromise(program)
587
+ * actual // => { beforeInvalidation: true, afterInvalidation: false, lookupCount: 2 }
588
+ * ```
589
+ *
590
+ * @category combinators
591
+ * @since 4.0.0
592
+ */
593
+ const invalidate = /*#__PURE__*/ dual(2, (self, key) => sync(() => {
594
+ remove(self.map, key);
595
+ }));
596
+ /**
597
+ * Retrieves all active keys from the cache, automatically filtering out expired entries.
598
+ *
599
+ * **Example** (Reading active keys)
600
+ *
601
+ * ```ts import.meta.vitest
602
+ * import { Cache, Effect } from "effect"
603
+ *
604
+ * // Basic key enumeration
605
+ * const program = Effect.gen(function*() {
606
+ * const cache = yield* Cache.make({
607
+ * capacity: 10,
608
+ * lookup: (key: string) => Effect.succeed(key.length)
609
+ * })
610
+ *
611
+ * // Add some entries to the cache
612
+ * yield* Cache.get(cache, "hello")
613
+ * yield* Cache.get(cache, "world")
614
+ * yield* Cache.get(cache, "cache")
615
+ *
616
+ * // Retrieve all active keys
617
+ * const keys = yield* Cache.keys(cache)
618
+ * return Array.from(keys).sort()
619
+ * })
620
+ *
621
+ * const actual = await Effect.runPromise(program)
622
+ * actual // => ["cache", "hello", "world"]
623
+ * ```
624
+ *
625
+ * @category combinators
626
+ * @since 4.0.0
627
+ */
628
+ const keys = (self) => withFiber((fiber) => {
629
+ const now = fiber.getRef(ClockRef).currentTimeMillisUnsafe();
630
+ return succeed(filterMap(self.map, ([key, entry]) => {
631
+ if (entry.expiresAt === void 0 || entry.expiresAt > now) return succeed$1(key);
632
+ remove(self.map, key);
633
+ return failVoid;
634
+ }));
635
+ });
636
+ //#endregion
637
+ //#region ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=a18f963109656ddbeb2a99ca45f942ecf54830986259eb01ce6a970421c9c6a9/node_modules/effect/dist/unstable/reactivity/Reactivity.js
638
+ /**
639
+ * Process-local invalidation for connecting writes to dependent reads.
640
+ *
641
+ * This module does not cache values itself. It lets callers register handlers
642
+ * for keys, invalidate those keys, wrap successful mutations so they invalidate
643
+ * keys, and expose effects as queues or streams that rerun when matching keys
644
+ * change. The service can also batch invalidations so handlers run after the
645
+ * batch completes.
646
+ *
647
+ * @since 4.0.0
648
+ */
649
+ /**
650
+ * Service for key-based reactive invalidation.
651
+ *
652
+ * **When to use**
653
+ *
654
+ * Use to provide the invalidation service that refreshes queries, streams, and
655
+ * atoms when application keys change.
656
+ *
657
+ * **Details**
658
+ *
659
+ * The service can register handlers for keys, invalidate those keys, wrap
660
+ * mutations so successful effects invalidate keys, and turn query effects into
661
+ * queues or streams that rerun when keys are invalidated.
662
+ *
663
+ * @category services
664
+ * @since 4.0.0
665
+ */
666
+ var Reactivity = class extends Service()("effect/reactivity/Reactivity") {};
667
+ /**
668
+ * Creates an in-memory `Reactivity` service.
669
+ *
670
+ * **Details**
671
+ *
672
+ * The service tracks handlers by hashed keys and runs the registered handlers when
673
+ * matching keys are invalidated.
674
+ *
675
+ * @category constructors
676
+ * @since 4.0.0
677
+ */
678
+ const make$2 = /*#__PURE__*/ sync$1(() => {
679
+ const handlers = /* @__PURE__ */ new Map();
680
+ const invalidateUnsafe = (keys) => {
681
+ keysToHashes(keys, (hash) => {
682
+ const set = handlers.get(hash);
683
+ if (set === void 0) return;
684
+ set.forEach((run) => run());
685
+ });
686
+ };
687
+ const invalidate = (keys) => contextWith$1((services) => {
688
+ const pending = services.mapUnsafe.get(PendingInvalidation.key);
689
+ if (pending) keysToHashes(keys, (hash) => {
690
+ pending.add(hash);
691
+ });
692
+ else invalidateUnsafe(keys);
693
+ return void_$1;
694
+ });
695
+ const mutation = (keys, effect) => tap(effect, invalidate(keys));
696
+ const registerUnsafe = (keys, handler) => {
697
+ const resolvedKeys = [];
698
+ keysToHashes(keys, (hash) => {
699
+ resolvedKeys.push(hash);
700
+ let set = handlers.get(hash);
701
+ if (set === void 0) {
702
+ set = /* @__PURE__ */ new Set();
703
+ handlers.set(hash, set);
704
+ }
705
+ set.add(handler);
706
+ });
707
+ return () => {
708
+ for (let i = 0; i < resolvedKeys.length; i++) {
709
+ const set = handlers.get(resolvedKeys[i]);
710
+ set.delete(handler);
711
+ if (set.size === 0) handlers.delete(resolvedKeys[i]);
712
+ }
713
+ };
714
+ };
715
+ const query = (keys, effect) => gen(function* () {
716
+ const services = yield* context();
717
+ const scope = get$2(services, Scope);
718
+ const results = yield* make$5();
719
+ const runFork = flow(runForkWith(services), runIn(scope));
720
+ let running = false;
721
+ let pending = false;
722
+ const handleExit = (exit) => {
723
+ if (exit._tag === "Failure") failCauseUnsafe(results, exit.cause);
724
+ else offerUnsafe(results, exit.value);
725
+ if (pending) {
726
+ pending = false;
727
+ runFork(effect).addObserver(handleExit);
728
+ } else running = false;
729
+ };
730
+ function run() {
731
+ if (running) {
732
+ pending = true;
733
+ return;
734
+ }
735
+ running = true;
736
+ runFork(effect).addObserver(handleExit);
737
+ }
738
+ yield* addFinalizer(scope, sync$1(registerUnsafe(keys, run)));
739
+ run();
740
+ return results;
741
+ });
742
+ const stream = (tables, effect) => query(tables, effect).pipe(map(fromQueue), unwrap);
743
+ const withBatch = (effect) => suspend(() => {
744
+ const pending = /* @__PURE__ */ new Set();
745
+ return effect.pipe(provideService(PendingInvalidation, pending), onExit$1((_) => sync$1(() => {
746
+ pending.forEach((hash) => {
747
+ const set = handlers.get(hash);
748
+ if (set === void 0) return;
749
+ set.forEach((run) => run());
750
+ });
751
+ })));
752
+ });
753
+ return Reactivity.of({
754
+ mutation,
755
+ query,
756
+ stream,
757
+ invalidateUnsafe,
758
+ invalidate,
759
+ registerUnsafe,
760
+ withBatch
761
+ });
762
+ });
763
+ var PendingInvalidation = class extends Service()("effect/reactivity/Reactivity/PendingInvalidation") {};
764
+ /**
765
+ * The default layer that provides an in-memory `Reactivity` service.
766
+ *
767
+ * @category layers
768
+ * @since 4.0.0
769
+ */
770
+ const layer = /*#__PURE__*/ effect(Reactivity)(make$2);
771
+ function stringOrHash(u) {
772
+ switch (typeof u) {
773
+ case "string":
774
+ case "number":
775
+ case "bigint":
776
+ case "boolean": return String(u);
777
+ default: return hash(u);
778
+ }
779
+ }
780
+ const keysToHashes = (keys, f) => {
781
+ if (Array.isArray(keys)) {
782
+ for (let i = 0; i < keys.length; i++) f(stringOrHash(keys[i]));
783
+ return;
784
+ }
785
+ for (const key in keys) {
786
+ f(key);
787
+ const ids = keys[key];
788
+ for (let i = 0; i < ids.length; i++) f(`${key}:${stringOrHash(ids[i])}`);
789
+ }
790
+ };
791
+ //#endregion
792
+ //#region ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=a18f963109656ddbeb2a99ca45f942ecf54830986259eb01ce6a970421c9c6a9/node_modules/effect/dist/unstable/sql/Statement.js
793
+ /**
794
+ * Low-level SQL statement and fragment primitives.
795
+ *
796
+ * `SqlClient` uses this module to build executable, parameterized SQL from
797
+ * reusable fragments. A statement can be executed, streamed, run without row
798
+ * transformation, or compiled to SQL text and parameters for a specific
799
+ * dialect. The module also contains helpers for identifiers, parameters,
800
+ * inserts, updates, custom dialect fragments, statement compilation, and row
801
+ * transformation.
802
+ *
803
+ * @since 4.0.0
804
+ */
805
+ const FragmentTypeId = "~effect/sql/Fragment";
806
+ /**
807
+ * Constructs a SQL `Fragment` from low-level statement segments.
808
+ *
809
+ * @category constructors
810
+ * @since 4.0.0
811
+ */
812
+ const fragment = (segments) => ({
813
+ [FragmentTypeId]: FragmentTypeId,
814
+ segments
815
+ });
816
+ /**
817
+ * Context reference for an optional current SQL statement transformer applied
818
+ * before statement execution.
819
+ *
820
+ * @category services
821
+ * @since 4.0.0
822
+ */
823
+ const CurrentTransformer = /*#__PURE__*/ Reference("effect/sql/CurrentTransformer", { defaultValue: constUndefined });
824
+ /**
825
+ * Returns `true` when a value is a SQL `Fragment`.
826
+ *
827
+ * @category guards
828
+ * @since 4.0.0
829
+ */
830
+ const isFragment = (u) => hasProperty(u, FragmentTypeId);
831
+ /**
832
+ * Constructs a raw SQL literal segment. The literal text is not escaped, so use
833
+ * bound parameters for untrusted values.
834
+ *
835
+ * @category constructors
836
+ * @since 4.0.0
837
+ */
838
+ const literal = (value, params) => ({
839
+ _tag: "Literal",
840
+ value,
841
+ params
842
+ });
843
+ /**
844
+ * Constructs a SQL identifier segment that will be escaped by the active
845
+ * compiler.
846
+ *
847
+ * @category constructors
848
+ * @since 4.0.0
849
+ */
850
+ const identifier = (value) => ({
851
+ _tag: "Identifier",
852
+ value
853
+ });
854
+ /**
855
+ * Constructs a bound parameter segment for a statement value.
856
+ *
857
+ * @category constructors
858
+ * @since 4.0.0
859
+ */
860
+ const parameter = (value) => ({
861
+ _tag: "Parameter",
862
+ value
863
+ });
864
+ /**
865
+ * Constructs an `ArrayHelper` segment for an array of values or fragments.
866
+ *
867
+ * @category constructors
868
+ * @since 4.0.0
869
+ */
870
+ const arrayHelper = (value) => ({
871
+ _tag: "ArrayHelper",
872
+ value
873
+ });
874
+ const RecordInsertHelperProto = {
875
+ _tag: "RecordInsertHelper",
876
+ returning(sql) {
877
+ const self = Object.create(Object.getPrototypeOf(this));
878
+ Object.assign(self, this, { returningIdentifier: sql });
879
+ return self;
880
+ }
881
+ };
882
+ /**
883
+ * Constructs a `RecordInsertHelper` from one or more row objects.
884
+ *
885
+ * @category constructors
886
+ * @since 4.0.0
887
+ */
888
+ const recordInsertHelper = (value) => Object.assign(Object.create(RecordInsertHelperProto), {
889
+ value,
890
+ returningIdentifier: void 0
891
+ });
892
+ const RecordUpdateHelperProto = {
893
+ ...RecordInsertHelperProto,
894
+ _tag: "RecordUpdateHelper"
895
+ };
896
+ /**
897
+ * Constructs a `RecordUpdateHelper` for multi-row update compilation using the
898
+ * provided alias.
899
+ *
900
+ * @category constructors
901
+ * @since 4.0.0
902
+ */
903
+ const recordUpdateHelper = (value, alias) => Object.assign(Object.create(RecordUpdateHelperProto), {
904
+ value,
905
+ alias,
906
+ returningIdentifier: void 0
907
+ });
908
+ const RecordUpdateHelperSingleProto = {
909
+ ...RecordInsertHelperProto,
910
+ _tag: "RecordUpdateHelperSingle"
911
+ };
912
+ /**
913
+ * Constructs a `RecordUpdateHelperSingle` from a record and a list of columns
914
+ * to omit from the update.
915
+ *
916
+ * @category constructors
917
+ * @since 4.0.0
918
+ */
919
+ const recordUpdateHelperSingle = (value, omit) => Object.assign(Object.create(RecordUpdateHelperSingleProto), {
920
+ value,
921
+ omit,
922
+ returningIdentifier: void 0
923
+ });
924
+ /**
925
+ * Creates a cached SQL statement constructor from a connection acquirer,
926
+ * compiler, tracing attributes, and optional row transformation function.
927
+ *
928
+ * @category constructors
929
+ * @since 4.0.0
930
+ */
931
+ const make$1 = (acquirer, compiler, spanAttributes, transformRows) => {
932
+ const cache = transformRows === void 0 ? constructorCache.noTransforms : constructorCache.transforms;
933
+ if (cache.has(acquirer)) return cache.get(acquirer);
934
+ const self = Object.assign(function sql(strings, ...args) {
935
+ if (typeof strings === "string") return identifier(strings);
936
+ else if (Array.isArray(strings) && "raw" in strings) return statement(acquirer, compiler, strings, args, spanAttributes, transformRows);
937
+ throw "absurd";
938
+ }, {
939
+ unsafe(sql, params) {
940
+ return makeUnsafe([literal(sql, params)], acquirer, compiler, spanAttributes, transformRows);
941
+ },
942
+ literal(sql) {
943
+ return fragment([literal(sql)]);
944
+ },
945
+ in: in_,
946
+ insert(value) {
947
+ return recordInsertHelper(Array.isArray(value) ? value : [value]);
948
+ },
949
+ update(value, omit) {
950
+ return recordUpdateHelperSingle(value, omit ?? []);
951
+ },
952
+ updateValues(value, alias) {
953
+ return recordUpdateHelper(value, alias);
954
+ },
955
+ and,
956
+ or,
957
+ csv,
958
+ join,
959
+ onDialect(options) {
960
+ return options[compiler.dialect]();
961
+ },
962
+ onDialectOrElse(options) {
963
+ return options[compiler.dialect] !== void 0 ? options[compiler.dialect]() : options.orElse();
964
+ }
965
+ });
966
+ cache.set(acquirer, self);
967
+ return self;
968
+ };
969
+ const constructorCache = {
970
+ transforms: /*#__PURE__*/ new WeakMap(),
971
+ noTransforms: /*#__PURE__*/ new WeakMap()
972
+ };
973
+ /**
974
+ * Builds a `Statement` from template strings and arguments, preserving
975
+ * fragments and helper segments while converting ordinary interpolated values
976
+ * into bound parameters.
977
+ *
978
+ * @category constructors
979
+ * @since 4.0.0
980
+ */
981
+ const statement = (acquirer, compiler, strings, args, spanAttributes, transformRows) => {
982
+ const segments = strings[0].length > 0 ? [literal(strings[0])] : [];
983
+ for (let i = 0; i < args.length; i++) {
984
+ const arg = args[i];
985
+ if (isFragment(arg)) segments.push(...arg.segments);
986
+ else if (isSegment(arg)) segments.push(arg);
987
+ else segments.push(parameter(arg));
988
+ if (strings[i + 1].length > 0) segments.push(literal(strings[i + 1]));
989
+ }
990
+ return makeUnsafe(segments, acquirer, compiler, spanAttributes, transformRows);
991
+ };
992
+ /**
993
+ * Creates a helper that joins SQL clauses with a literal separator, optionally
994
+ * wrapping multiple clauses in parentheses and using a fallback for an empty
995
+ * list.
996
+ *
997
+ * @category constructors
998
+ * @since 4.0.0
999
+ */
1000
+ function join(lit, addParens = true, fallback = "") {
1001
+ const literalStatement = literal(lit);
1002
+ const fallbackFragment = fragment([literal(fallback)]);
1003
+ return (clauses) => {
1004
+ if (clauses.length === 0) return fallbackFragment;
1005
+ else if (clauses.length === 1) return fragment(convertLiteralOrFragment(clauses[0]));
1006
+ const segments = [];
1007
+ if (addParens) segments.push(literal("("));
1008
+ segments.push.apply(segments, convertLiteralOrFragment(clauses[0]));
1009
+ for (let i = 1; i < clauses.length; i++) {
1010
+ segments.push(literalStatement);
1011
+ segments.push.apply(segments, convertLiteralOrFragment(clauses[i]));
1012
+ }
1013
+ if (addParens) segments.push(literal(")"));
1014
+ return fragment(segments);
1015
+ };
1016
+ }
1017
+ /**
1018
+ * Combines clauses with `AND`, parenthesizing multiple clauses and returning
1019
+ * `1=1` when the list is empty.
1020
+ *
1021
+ * @category constructors
1022
+ * @since 4.0.0
1023
+ */
1024
+ const and = /*#__PURE__*/ join(" AND ", true, "1=1");
1025
+ /**
1026
+ * Combines clauses with `OR`, parenthesizing multiple clauses and returning
1027
+ * `1=1` when the list is empty.
1028
+ *
1029
+ * @category constructors
1030
+ * @since 4.0.0
1031
+ */
1032
+ const or = /*#__PURE__*/ join(" OR ", true, "1=1");
1033
+ /**
1034
+ * Creates a comma-separated SQL fragment from values, optionally adding a
1035
+ * prefix, and returns an empty fragment when no values are provided.
1036
+ *
1037
+ * @category constructors
1038
+ * @since 4.0.0
1039
+ */
1040
+ const csv = function(...args) {
1041
+ if (args[args.length - 1].length === 0) return emptyFragment;
1042
+ if (args.length === 1) return csvRaw(args[0]);
1043
+ return fragment([literal(`${args[0]} `), ...csvRaw(args[1]).segments]);
1044
+ };
1045
+ const csvRaw = /*#__PURE__*/ join(",", false);
1046
+ const emptyFragment = /*#__PURE__*/ fragment([/*#__PURE__*/ literal("")]);
1047
+ /**
1048
+ * Creates a dialect-specific SQL `Compiler` from rendering callbacks.
1049
+ *
1050
+ * @category constructors
1051
+ * @since 4.0.0
1052
+ */
1053
+ const makeCompiler = (options) => {
1054
+ const self = Object.create(CompilerProto);
1055
+ self.options = options;
1056
+ self.dialect = options.dialect;
1057
+ self.disableTransforms = false;
1058
+ return self;
1059
+ };
1060
+ const statementCacheSymbol = /*#__PURE__*/ Symbol.for("effect/unstable/sql/Statement/statementCache");
1061
+ const statementCacheNoTransformSymbol = /*#__PURE__*/ Symbol.for("effect/unstable/sql/Statement/statementCacheNoTransform");
1062
+ const CompilerProto = {
1063
+ compile(statement, withoutTransform = false, placeholderOverride) {
1064
+ const opts = this.options;
1065
+ withoutTransform = withoutTransform || this.disableTransforms;
1066
+ const cacheSymbol = withoutTransform ? statementCacheNoTransformSymbol : statementCacheSymbol;
1067
+ if (cacheSymbol in statement) return statement[cacheSymbol];
1068
+ const segments = statement.segments;
1069
+ const len = segments.length;
1070
+ let sql = "";
1071
+ const binds = [];
1072
+ let placeholderCount = 0;
1073
+ const placeholder = placeholderOverride ?? ((u) => opts.placeholder(++placeholderCount, u));
1074
+ const placeholderNoIncrement = (u) => opts.placeholder(placeholderCount, u);
1075
+ const placeholders = makePlaceholdersArray(placeholder);
1076
+ for (let i = 0; i < len; i++) {
1077
+ const segment = segments[i];
1078
+ switch (segment._tag) {
1079
+ case "Literal":
1080
+ sql += segment.value;
1081
+ if (segment.params) binds.push.apply(binds, segment.params);
1082
+ break;
1083
+ case "Identifier":
1084
+ sql += opts.onIdentifier(segment.value, withoutTransform);
1085
+ break;
1086
+ case "Parameter":
1087
+ sql += placeholder(segment.value);
1088
+ binds.push(segment.value);
1089
+ break;
1090
+ case "ArrayHelper":
1091
+ sql += `(${placeholders(segment.value)})`;
1092
+ binds.push.apply(binds, segment.value);
1093
+ break;
1094
+ case "RecordInsertHelper": {
1095
+ const keys = Object.keys(segment.value[0]);
1096
+ if (opts.onInsert) {
1097
+ const values = new Array(segment.value.length);
1098
+ let placeholders = "";
1099
+ for (let i = 0; i < segment.value.length; i++) {
1100
+ const row = new Array(keys.length);
1101
+ values[i] = row;
1102
+ placeholders += i === 0 ? "(" : ",(";
1103
+ for (let j = 0; j < keys.length; j++) {
1104
+ const key = keys[j];
1105
+ const value = segment.value[i][key];
1106
+ row[j] = extractPrimitive(value, opts.onCustom, placeholderNoIncrement, withoutTransform);
1107
+ placeholders += j === 0 ? placeholder(value) : `,${placeholder(value)}`;
1108
+ }
1109
+ placeholders += ")";
1110
+ }
1111
+ const [s, b] = opts.onInsert(keys.map((_) => opts.onIdentifier(_, withoutTransform)), placeholders, values, typeof segment.returningIdentifier === "string" ? [segment.returningIdentifier, []] : segment.returningIdentifier ? this.compile(segment.returningIdentifier, withoutTransform, placeholder) : void 0);
1112
+ sql += s;
1113
+ binds.push.apply(binds, b);
1114
+ } else {
1115
+ let placeholders = "";
1116
+ for (let i = 0; i < segment.value.length; i++) {
1117
+ placeholders += i === 0 ? "(" : ",(";
1118
+ for (let j = 0; j < keys.length; j++) {
1119
+ const value = segment.value[i][keys[j]];
1120
+ const primitive = extractPrimitive(value, opts.onCustom, placeholderNoIncrement, withoutTransform);
1121
+ binds.push(primitive);
1122
+ placeholders += j === 0 ? placeholder(value) : `,${placeholder(value)}`;
1123
+ }
1124
+ placeholders += ")";
1125
+ }
1126
+ sql += `${generateColumns(keys, opts.onIdentifier, withoutTransform)} VALUES ${placeholders}`;
1127
+ if (typeof segment.returningIdentifier === "string") sql += ` RETURNING ${segment.returningIdentifier}`;
1128
+ else if (segment.returningIdentifier) {
1129
+ sql += " RETURNING ";
1130
+ const [s, b] = this.compile(segment.returningIdentifier, withoutTransform, placeholder);
1131
+ sql += s;
1132
+ binds.push.apply(binds, b);
1133
+ }
1134
+ }
1135
+ break;
1136
+ }
1137
+ case "RecordUpdateHelperSingle": {
1138
+ let keys = Object.keys(segment.value);
1139
+ if (segment.omit.length > 0) keys = keys.filter((key) => !segment.omit.includes(key));
1140
+ if (opts.onRecordUpdateSingle) {
1141
+ const [s, b] = opts.onRecordUpdateSingle(keys.map((_) => opts.onIdentifier(_, withoutTransform)), keys.map((key) => extractPrimitive(segment.value[key], opts.onCustom, placeholderNoIncrement, withoutTransform)), typeof segment.returningIdentifier === "string" ? [segment.returningIdentifier, []] : segment.returningIdentifier ? this.compile(segment.returningIdentifier, withoutTransform, placeholder) : void 0);
1142
+ sql += s;
1143
+ binds.push.apply(binds, b);
1144
+ } else {
1145
+ for (let i = 0, len = keys.length; i < len; i++) {
1146
+ const column = opts.onIdentifier(keys[i], withoutTransform);
1147
+ if (i === 0) sql += `${column} = ${placeholder(segment.value[keys[i]])}`;
1148
+ else sql += `, ${column} = ${placeholder(segment.value[keys[i]])}`;
1149
+ binds.push(extractPrimitive(segment.value[keys[i]], opts.onCustom, placeholderNoIncrement, withoutTransform));
1150
+ }
1151
+ if (typeof segment.returningIdentifier === "string") if (this.dialect === "mssql") sql += ` OUTPUT ${segment.returningIdentifier === "*" ? "INSERTED.*" : segment.returningIdentifier}`;
1152
+ else sql += ` RETURNING ${segment.returningIdentifier}`;
1153
+ else if (segment.returningIdentifier) {
1154
+ sql += this.dialect === "mssql" ? " OUTPUT " : " RETURNING ";
1155
+ const [s, b] = this.compile(segment.returningIdentifier, withoutTransform, placeholder);
1156
+ sql += s;
1157
+ binds.push.apply(binds, b);
1158
+ }
1159
+ }
1160
+ break;
1161
+ }
1162
+ case "RecordUpdateHelper": {
1163
+ const keys = Object.keys(segment.value[0]);
1164
+ const values = new Array(segment.value.length);
1165
+ let placeholders = "";
1166
+ for (let i = 0; i < segment.value.length; i++) {
1167
+ const row = new Array(keys.length);
1168
+ values[i] = row;
1169
+ placeholders += i === 0 ? "(" : ",(";
1170
+ for (let j = 0; j < keys.length; j++) {
1171
+ const key = keys[j];
1172
+ const value = segment.value[i][key];
1173
+ row[j] = extractPrimitive(value, opts.onCustom, placeholderNoIncrement, withoutTransform);
1174
+ placeholders += j === 0 ? placeholder(value) : `,${placeholder(value)}`;
1175
+ }
1176
+ placeholders += ")";
1177
+ }
1178
+ const [s, b] = opts.onRecordUpdate(placeholders, segment.alias, generateColumns(keys, opts.onIdentifier, withoutTransform), values, typeof segment.returningIdentifier === "string" ? [segment.returningIdentifier, []] : segment.returningIdentifier ? this.compile(segment.returningIdentifier, withoutTransform, placeholder) : void 0);
1179
+ sql += s;
1180
+ binds.push.apply(binds, b);
1181
+ break;
1182
+ }
1183
+ case "Custom": {
1184
+ const [s, b] = opts.onCustom(segment, placeholder, withoutTransform);
1185
+ sql += s;
1186
+ binds.push.apply(binds, b);
1187
+ break;
1188
+ }
1189
+ }
1190
+ }
1191
+ const result = [sql, binds];
1192
+ if (placeholderOverride !== void 0) return result;
1193
+ return statement[cacheSymbol] = result;
1194
+ },
1195
+ get withoutTransform() {
1196
+ const self = Object.create(CompilerProto);
1197
+ Object.assign(self, this, { disableTransforms: true });
1198
+ return self;
1199
+ }
1200
+ };
1201
+ /**
1202
+ * Creates a SQLite compiler that uses `?` placeholders and quoted identifiers,
1203
+ * optionally transforming identifier names before escaping.
1204
+ *
1205
+ * @category constructors
1206
+ * @since 4.0.0
1207
+ */
1208
+ const makeCompilerSqlite = (transform) => makeCompiler({
1209
+ dialect: "sqlite",
1210
+ placeholder(_) {
1211
+ return "?";
1212
+ },
1213
+ onIdentifier: transform ? function(value, withoutTransform) {
1214
+ return withoutTransform ? escapeSqlite(value) : escapeSqlite(transform(value));
1215
+ } : escapeSqlite,
1216
+ onRecordUpdate() {
1217
+ return ["", []];
1218
+ },
1219
+ onCustom() {
1220
+ return ["", []];
1221
+ }
1222
+ });
1223
+ /**
1224
+ * Creates an identifier escaping function that wraps names in the given
1225
+ * delimiter, doubles delimiter characters, and escapes dots between identifier
1226
+ * parts.
1227
+ *
1228
+ * @category constructors
1229
+ * @since 4.0.0
1230
+ */
1231
+ function defaultEscape(c) {
1232
+ const re = new RegExp(c, "g");
1233
+ const double = c + c;
1234
+ const dot = c + "." + c;
1235
+ return function(str) {
1236
+ return c + str.replace(re, double).replace(/\./g, dot) + c;
1237
+ };
1238
+ }
1239
+ /**
1240
+ * Builds value, object, and row-array transformers that rename object keys with
1241
+ * the supplied function and optionally recurse into nested object arrays.
1242
+ *
1243
+ * @category transforming
1244
+ * @since 4.0.0
1245
+ */
1246
+ const defaultTransforms = (transformer, nested = true) => {
1247
+ const transformValue = (value) => {
1248
+ if (Array.isArray(value)) {
1249
+ if (value.length === 0 || value[0].constructor !== Object) return value;
1250
+ return array(value);
1251
+ } else if (value?.constructor === Object) return transformObject(value);
1252
+ return value;
1253
+ };
1254
+ const transformObject = (obj) => {
1255
+ const newObj = {};
1256
+ for (const key of Object.keys(obj)) assignProperty(newObj, transformer(key), transformValue(obj[key]));
1257
+ return newObj;
1258
+ };
1259
+ const transformArrayNested = (rows) => {
1260
+ const newRows = new Array(rows.length);
1261
+ for (let i = 0, len = rows.length; i < len; i++) {
1262
+ const row = rows[i];
1263
+ if (Array.isArray(row)) newRows[i] = transformArrayNested(row);
1264
+ else {
1265
+ const obj = {};
1266
+ for (const [key, value] of Object.entries(row)) assignProperty(obj, transformer(key), transformValue(value));
1267
+ newRows[i] = obj;
1268
+ }
1269
+ }
1270
+ return newRows;
1271
+ };
1272
+ const transformArray = (rows) => {
1273
+ const newRows = new Array(rows.length);
1274
+ for (let i = 0, len = rows.length; i < len; i++) {
1275
+ const row = rows[i];
1276
+ if (Array.isArray(row)) newRows[i] = transformArray(row);
1277
+ else {
1278
+ const obj = {};
1279
+ for (const [key, value] of Object.entries(row)) assignProperty(obj, transformer(key), value);
1280
+ newRows[i] = obj;
1281
+ }
1282
+ }
1283
+ return newRows;
1284
+ };
1285
+ const array = nested ? transformArrayNested : transformArray;
1286
+ return {
1287
+ value: transformValue,
1288
+ object: transformObject,
1289
+ array
1290
+ };
1291
+ };
1292
+ const ATTR_DB_OPERATION_NAME = "db.operation.name";
1293
+ const ATTR_DB_QUERY_TEXT = "db.query.text";
1294
+ const makeUnsafe = (segments, acquirer, compiler, spanAttributes, transformRows) => {
1295
+ const self = Object.create(StatementProto);
1296
+ self.segments = segments;
1297
+ self.acquirer = acquirer;
1298
+ self.compiler = compiler;
1299
+ self.spanAttributes = spanAttributes;
1300
+ self.transformRows = transformRows;
1301
+ return self;
1302
+ };
1303
+ const StatementProto = {
1304
+ [FragmentTypeId]: FragmentTypeId,
1305
+ withConnection(operation, f, withoutTransform = false) {
1306
+ return useSpan("sql.execute", { kind: "client" }, (span) => this.withConnectionSpan(operation, f, withoutTransform, span));
1307
+ },
1308
+ withConnectionSpan(operation, f, withoutTransform, span) {
1309
+ return withStatement(this, span, (statement) => {
1310
+ const [sql, params] = statement.compile(withoutTransform);
1311
+ for (const [key, value] of this.spanAttributes) span.attribute(key, value);
1312
+ span.attribute(ATTR_DB_OPERATION_NAME, operation);
1313
+ span.attribute(ATTR_DB_QUERY_TEXT, sql);
1314
+ return scoped(flatMap(this.acquirer, (_) => f(_, sql, params)));
1315
+ });
1316
+ },
1317
+ get withoutTransform() {
1318
+ return this.withConnection("executeWithoutTransform", (connection, sql, params) => connection.execute(sql, params, void 0), true);
1319
+ },
1320
+ get raw() {
1321
+ return this.withConnection("executeRaw", (connection, sql, params) => connection.executeRaw(sql, params), true);
1322
+ },
1323
+ get stream() {
1324
+ const self = this;
1325
+ return unwrap(flatMap(makeSpanScoped("sql.execute", { kind: "client" }), (span) => withStatement(self, span, (statement) => {
1326
+ const [sql, params] = statement.compile();
1327
+ for (const [key, value] of self.spanAttributes) span.attribute(key, value);
1328
+ span.attribute(ATTR_DB_OPERATION_NAME, "executeStream");
1329
+ span.attribute(ATTR_DB_QUERY_TEXT, sql);
1330
+ return map(self.acquirer, (_) => _.executeStream(sql, params, self.transformRows));
1331
+ })));
1332
+ },
1333
+ get values() {
1334
+ return this.withConnection("executeValues", (connection, sql, params) => connection.executeValues(sql, params));
1335
+ },
1336
+ get valuesUnprepared() {
1337
+ return this.withConnection("executeValuesUnprepared", (connection, sql, params) => connection.executeValuesUnprepared(sql, params));
1338
+ },
1339
+ get unprepared() {
1340
+ const self = this;
1341
+ return self.withConnection("executeUnprepared", (connection, sql, params) => connection.executeUnprepared(sql, params, self.transformRows));
1342
+ },
1343
+ .../*#__PURE__*/ Prototype({
1344
+ label: "Statement",
1345
+ evaluate(fiber) {
1346
+ const span = makeSpanUnsafe(fiber, "sql.execute", { kind: "client" });
1347
+ const clock = fiber.getRef(Clock);
1348
+ const timingEnabled = fiber.getRef(TracerTimingEnabled);
1349
+ return onExit$1(this.withConnectionSpan("execute", (connection, sql, params) => connection.execute(sql, params, this.transformRows), false, span), (exit) => endSpan(span, exit, clock, timingEnabled));
1350
+ }
1351
+ }),
1352
+ compile(withoutTransform) {
1353
+ return this.compiler.compile(this, withoutTransform ?? false);
1354
+ },
1355
+ toJSON() {
1356
+ const [sql, params] = this.compile();
1357
+ return {
1358
+ _id: "Statement",
1359
+ segments: this.segments,
1360
+ sql,
1361
+ params
1362
+ };
1363
+ }
1364
+ };
1365
+ const withStatement = (self, span, f) => withFiber$1((fiber) => {
1366
+ const transform = fiber.getRef(CurrentTransformer);
1367
+ if (transform === void 0) return f(self);
1368
+ return flatMap(transform(self, make$1(self.acquirer, self.compiler, self.spanAttributes, self.transformRows), fiber, span), f);
1369
+ });
1370
+ const isSegment = (u) => {
1371
+ if (!hasProperty(u, "_tag")) return false;
1372
+ switch (u._tag) {
1373
+ case "Literal":
1374
+ case "Parameter":
1375
+ case "ArrayHelper":
1376
+ case "RecordInsertHelper":
1377
+ case "RecordUpdateHelper":
1378
+ case "RecordUpdateHelperSingle":
1379
+ case "Identifier":
1380
+ case "Custom": return true;
1381
+ default: return false;
1382
+ }
1383
+ };
1384
+ function convertLiteralOrFragment(clause) {
1385
+ if (typeof clause === "string") return [literal(clause)];
1386
+ return clause.segments;
1387
+ }
1388
+ const makePlaceholdersArray = (evaluate) => (values) => {
1389
+ if (values.length === 0) return "";
1390
+ let result = evaluate(values[0]);
1391
+ for (let i = 1; i < values.length; i++) result += `,${evaluate(values[i])}`;
1392
+ return result;
1393
+ };
1394
+ const generateColumns = (keys, escape, withoutTransform) => {
1395
+ if (keys.length === 0) return "()";
1396
+ let str = `(${escape(keys[0], withoutTransform)}`;
1397
+ for (let i = 1; i < keys.length; i++) str += `,${escape(keys[i], withoutTransform)}`;
1398
+ return str + ")";
1399
+ };
1400
+ const extractPrimitive = (value, onCustom, placeholder, withoutTransform) => {
1401
+ if (value === void 0) return null;
1402
+ else if (isFragment(value)) {
1403
+ const head = value.segments[0];
1404
+ if (head._tag === "Custom") return onCustom(head, placeholder, withoutTransform)[1][0] ?? null;
1405
+ else if (head._tag === "Parameter") return head.value;
1406
+ return null;
1407
+ }
1408
+ return value;
1409
+ };
1410
+ const escapeSqlite = /*#__PURE__*/ defaultEscape("\"");
1411
+ function in_() {
1412
+ if (arguments.length === 1) return arrayHelper(arguments[0]);
1413
+ const column = arguments[0];
1414
+ const values = arguments[1];
1415
+ return values.length === 0 ? neverFragment : fragment([
1416
+ identifier(column),
1417
+ literal(" IN "),
1418
+ arrayHelper(values)
1419
+ ]);
1420
+ }
1421
+ const neverFragment = /*#__PURE__*/ fragment([/*#__PURE__*/ literal("1=0")]);
1422
+ //#endregion
1423
+ //#region ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=a18f963109656ddbeb2a99ca45f942ecf54830986259eb01ce6a970421c9c6a9/node_modules/effect/dist/unstable/sql/SqlClient.js
1424
+ /**
1425
+ * Main SQL client service for tagged-template queries.
1426
+ *
1427
+ * `SqlClient` combines the tagged-template statement constructor with
1428
+ * connection acquisition, dialect compilation, transactions, row transforms,
1429
+ * tracing, and reactive query helpers. Driver integrations build this service
1430
+ * from their connection and compiler pieces.
1431
+ *
1432
+ * @since 4.0.0
1433
+ */
1434
+ const TypeId = "~effect/sql/SqlClient";
1435
+ /**
1436
+ * Service tag for the active SQL client service.
1437
+ *
1438
+ * **When to use**
1439
+ *
1440
+ * Use to access or provide the SQL client used to build statements, stream
1441
+ * rows, reserve connections, and run transactions.
1442
+ *
1443
+ * @category services
1444
+ * @since 4.0.0
1445
+ */
1446
+ const SqlClient = /*#__PURE__*/ Service("effect/sql/SqlClient");
1447
+ let clientIdCounter = 0;
1448
+ /**
1449
+ * Constructs a `SqlClient` from connection acquirers, a compiler, transaction
1450
+ * commands, tracing attributes, optional row transforms, and reactive query
1451
+ * integration.
1452
+ *
1453
+ * @category constructors
1454
+ * @since 4.0.0
1455
+ */
1456
+ const make = /*#__PURE__*/ fnUntraced(function* (options) {
1457
+ const transactionService = options.transactionService ?? TransactionConnection(clientIdCounter++);
1458
+ const getConnection = flatMap(serviceOption(transactionService), match({
1459
+ onNone: () => options.acquirer,
1460
+ onSome: ([conn]) => succeed$2(conn)
1461
+ }));
1462
+ const beginTransaction = options.beginTransaction ?? "BEGIN";
1463
+ const commit = options.commit ?? "COMMIT";
1464
+ const savepoint = options.savepoint ?? ((name) => `SAVEPOINT ${name}`);
1465
+ const rollback = options.rollback ?? "ROLLBACK";
1466
+ const rollbackSavepoint = options.rollbackSavepoint ?? ((name) => `ROLLBACK TO SAVEPOINT ${name}`);
1467
+ const transactionAcquirer = options.transactionAcquirer ?? options.acquirer;
1468
+ const withTransaction = makeWithTransaction({
1469
+ transactionService,
1470
+ spanAttributes: options.spanAttributes,
1471
+ acquireConnection: flatMap(make$6(), (scope) => map(provide(transactionAcquirer, scope), (conn) => [scope, conn])),
1472
+ begin: (conn) => conn.executeUnprepared(beginTransaction, [], void 0),
1473
+ savepoint: (conn, id) => conn.executeUnprepared(savepoint(`effect_sql_${id}`), [], void 0),
1474
+ commit: (conn) => conn.executeUnprepared(commit, [], void 0),
1475
+ rollback: (conn) => conn.executeUnprepared(rollback, [], void 0),
1476
+ rollbackSavepoint: (conn, id) => conn.executeUnprepared(rollbackSavepoint(`effect_sql_${id}`), [], void 0)
1477
+ });
1478
+ const reactivity = yield* Reactivity;
1479
+ const client = Object.assign(make$1(getConnection, options.compiler, options.spanAttributes, options.transformRows), {
1480
+ [TypeId]: TypeId,
1481
+ safe: void 0,
1482
+ withTransaction,
1483
+ transactionService,
1484
+ reserve: transactionAcquirer,
1485
+ withoutTransforms() {
1486
+ if (options.transformRows === void 0) return this;
1487
+ const statement = make$1(getConnection, options.compiler.withoutTransform, options.spanAttributes, void 0);
1488
+ const client = Object.assign(statement, {
1489
+ ...this,
1490
+ ...statement
1491
+ });
1492
+ client.safe = client;
1493
+ client.withoutTransforms = () => client;
1494
+ return client;
1495
+ },
1496
+ reactive: options.reactiveQueue ? (keys, effect) => options.reactiveQueue(keys, effect).pipe(map(fromQueue), unwrap) : reactivity.stream,
1497
+ reactiveMailbox: options.reactiveQueue ?? reactivity.query
1498
+ });
1499
+ client.safe = client;
1500
+ return client;
1501
+ });
1502
+ /**
1503
+ * Builds a transaction wrapper that begins top-level transactions, uses
1504
+ * savepoints for nested transactions, commits on success, and rolls back on
1505
+ * failure or interruption.
1506
+ *
1507
+ * @category transactions
1508
+ * @since 4.0.0
1509
+ */
1510
+ const makeWithTransaction = (options) => (effect) => {
1511
+ return uninterruptibleMask((restore) => useSpan("sql.transaction", { kind: "client" }, (span) => withFiber$1((fiber) => {
1512
+ for (const [key, value] of options.spanAttributes) span.attribute(key, value);
1513
+ const services = fiber.context;
1514
+ const clock = fiber.getRef(Clock);
1515
+ const connOption = getOption$1(services, options.transactionService);
1516
+ const conn = connOption._tag === "Some" ? succeed$2([void 0, connOption.value[0]]) : options.acquireConnection;
1517
+ const id = connOption._tag === "Some" ? connOption.value[1] + 1 : 0;
1518
+ return flatMap(conn, ([scope, conn]) => (id === 0 ? options.begin(conn) : options.savepoint(conn, id)).pipe(flatMap(() => provideContext(restore(effect), services.pipe(add(options.transactionService, [conn, id]), add(ParentSpan, span)))), exit, flatMap((exit) => {
1519
+ let effect;
1520
+ if (isSuccess(exit)) if (id === 0) {
1521
+ span.event("db.transaction.commit", clock.currentTimeNanosUnsafe());
1522
+ effect = orDie(options.commit(conn));
1523
+ } else {
1524
+ span.event("db.transaction.savepoint", clock.currentTimeNanosUnsafe());
1525
+ effect = void_$1;
1526
+ }
1527
+ else {
1528
+ span.event("db.transaction.rollback", clock.currentTimeNanosUnsafe());
1529
+ effect = orDie(id > 0 ? options.rollbackSavepoint(conn, id) : options.rollback(conn));
1530
+ }
1531
+ return flatMap(scope !== void 0 ? ensuring(effect, close(scope, exit)) : effect, () => exit);
1532
+ })));
1533
+ })));
1534
+ };
1535
+ /**
1536
+ * Creates a unique context service tag for the active transaction connection of
1537
+ * a specific SQL client.
1538
+ *
1539
+ * @category services
1540
+ * @since 4.0.0
1541
+ */
1542
+ const TransactionConnection = (clientId) => Service(`effect/sql/SqlClient/TransactionConnection/${clientId}`);
1543
+ /**
1544
+ * Context reference used by SQL integrations to opt in to safe integer
1545
+ * handling; defaults to `false`.
1546
+ *
1547
+ * @category services
1548
+ * @since 4.0.0
1549
+ */
1550
+ const SafeIntegers = /*#__PURE__*/ Reference("effect/sql/SqlClient/SafeIntegers", { defaultValue: () => false });
1551
+ //#endregion
1552
+ export { makeCompilerSqlite as a, getOption as c, make$3 as d, makeWith as f, defaultTransforms as i, invalidate as l, SqlClient as n, layer as o, set as p, make as r, get as s, SafeIntegers as t, keys as u };
1553
+
1554
+ //# sourceMappingURL=SqlClient-DcM69ZvI.mjs.map