clanka 0.7.0 → 0.7.2

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.
Files changed (45) hide show
  1. package/dist/CodeChunker.d.ts.map +1 -1
  2. package/dist/CodeChunker.js +17 -2
  3. package/dist/CodeChunker.js.map +1 -1
  4. package/dist/CodeChunker.test.js +49 -2
  5. package/dist/CodeChunker.test.js.map +1 -1
  6. package/dist/Compaction.d.ts +2 -1
  7. package/dist/Compaction.d.ts.map +1 -1
  8. package/dist/Compaction.js +30 -3
  9. package/dist/Compaction.js.map +1 -1
  10. package/dist/CompactionTokens.test.d.ts +2 -0
  11. package/dist/CompactionTokens.test.d.ts.map +1 -0
  12. package/dist/CompactionTokens.test.js +152 -0
  13. package/dist/CompactionTokens.test.js.map +1 -0
  14. package/dist/ExaSearch.d.ts.map +1 -1
  15. package/dist/ExaSearch.js +13 -5
  16. package/dist/ExaSearch.js.map +1 -1
  17. package/dist/Image.d.ts.map +1 -1
  18. package/dist/Image.js +10 -18
  19. package/dist/Image.js.map +1 -1
  20. package/dist/OutputFormatter.js +1 -1
  21. package/dist/OutputFormatter.js.map +1 -1
  22. package/dist/SemanticSearch.js +2 -2
  23. package/dist/SemanticSearch.js.map +1 -1
  24. package/dist/bin/McpClient-D6vFD-wP.mjs +16337 -0
  25. package/dist/bin/McpClient-D6vFD-wP.mjs.map +1 -0
  26. package/dist/bin/Schema-D6y3R-At.mjs +28728 -0
  27. package/dist/bin/Schema-D6y3R-At.mjs.map +1 -0
  28. package/dist/bin/SemanticSearch-D9iZ_Mi9.mjs +3372 -0
  29. package/dist/bin/SemanticSearch-D9iZ_Mi9.mjs.map +1 -0
  30. package/dist/bin/Undici-ChB4UBDa.mjs +28 -0
  31. package/dist/bin/Undici-ChB4UBDa.mjs.map +1 -0
  32. package/dist/bin/cli.mjs +57559 -0
  33. package/dist/bin/cli.mjs.map +1 -0
  34. package/dist/cli.js +1 -1
  35. package/dist/cli.js.map +1 -1
  36. package/package.json +7 -4
  37. package/src/CodeChunker.test.ts +62 -2
  38. package/src/CodeChunker.ts +30 -2
  39. package/src/Compaction.ts +32 -4
  40. package/src/CompactionTokens.test.ts +214 -0
  41. package/src/ExaSearch.ts +18 -5
  42. package/src/Image.ts +12 -3
  43. package/src/OutputFormatter.ts +1 -1
  44. package/src/SemanticSearch.ts +2 -2
  45. package/src/cli.ts +1 -1
@@ -0,0 +1,3372 @@
1
+ import { $a as done, B as TaggedError, Bi as void_$1, Bo as onExit$1, Bs as isZero, Co as exitHasInterrupts, Cs as sort, Ct as isSchema, Da as effect, Dc as Prototype, Di as sync, Dr as forEach, Ei as suspend, Er as fnUntraced, Fc as assignProperty, Fo as forkUnsafe, Fr as interrupt, Gc as byReferenceUnsafe, Gn as all, Ha as addFinalizer, Hn as acquireRelease, Hs as minutes, I as String$1, Ia as provide$1, Ii as uninterruptibleMask, Ja as provide, Jc as hash, Ji as Class$2, Jn as annotateLogs, Jo as updateContext, Js as add, Ka as make$8, Kc as equals, Ki as withSpan, Ks as Reference, Kt as evolve, L as Struct$2, La as provideMerge, Lr as isEffect, Ls as fromInputUnsafe, Mi as tryPromise, Mo as fiberJoin, Ni as try_, Nr as gen, O as Number$1, Oa as effectContext, Oi as tap, Oo as fiberInterrupt, Or as forever, Ot as mutable, Pc as withFiber$1, Pr as ignore, Q as brand, Qs as getOrUndefined, Rr as logDebug, Rs as infinity, S as Natural, Sc as some, Si as serviceOption, So as endSpan, Sr as flatMap, Tc as make$10, Tr as fn, Ui as withFiber, Un as acquireUseRelease, Uo as succeed$1, Ur as makeSpanScoped, Us as seconds, Va as Scope, Vr as logInfo, Vs as millis, Wa as close, Wi as withLogSpan, Wr as map, Ws as toMillis, Xc as symbol$1, Xr as matchCauseEager, Xs as get$1, Y as Union$2, Yn as as, Yo as void_$2, Za as TracerTimingEnabled, Zc as hasProperty, Zn as asVoid, Zo as ParentSpan, Zs as getOption, _c as map$1, _i as runForkWith, ai as orDie, ao as makeUnsafe$2, bi as scoped, co as failCause, cr as catchTag, d as Defect, da as NoSuchElementError, dl as constUndefined, do as isFailure, ds as flatMapNullishOr, dt as instanceOf, ec as getUnsafe, eo as doneUnsafe, fo as isSuccess, fr as context, fs as fromIterable, gc as isSome, gi as runFork, gl as identity, hc as isNone, hl as flow, ho as ClockRef, hr as die, it as decodeUnknownEffect, jr as forkScoped, ka as effectDiscard, kc as PipeInspectableProto, kt as optional, la as Clock, li as provideContext, lr as catchTags, ml as dual, mo as void_$3, mr as delay, ms as isArrayNonEmpty, n as ArraySchema, ni as onExitPrimitive, no as into, nr as catchDefect, o as Class$1, oi as orElseSucceed, or as catchNoSuchElement, pi as request$1, po as succeed$2, pr as contextWith, qc as symbol, qn as annotateCurrentSpan, qr as mapError, qs as Service, rc as merge, rs as TaggedError$1, rt as decodeTo, so as fail, ss as empty, st as encodeEffect, tc as make$9, ti as onExit, tr as catchCause, uc as fromNullishOr, ui as provideService, ur as catch_, va as filterInterruptors, vc as match, vl as pipe, wc as Number$2, wi as succeed, wn as transform$1, xa as hasInterruptsOnly, xo as contextWith$1, xr as filterOrFail, yc as none, yi as scope, yl as pipeArguments, yr as fail$1, ys as map$2, zi as useSpan, zo as makeSpanUnsafe, zs as isFinite } from "./Schema-D6y3R-At.mjs";
2
+ import { A as isEmpty, B as getCurrent, C as runCollect, D as empty$1, E as unwrap, F as make$14, G as has, H as join$1, I as makeUnsafe$3, K as toPredicate, L as failCauseUnsafe, M as remove, N as set, O as forEach$1, P as size, R as make$11, S as provideService$1, T as tap$1, U as runIn, V as interruptAs, W as compose, _ as die$1, a as makeGrouped, b as fromArrayEffect, c as SemanticSearch, f as make$13, g as FileSystem, h as Path, i as batchN, j as make$12, k as get$2, l as maybeRemoveFile, m as Console, n as EmbeddingModel, o as setDelay, p as ChildProcessSpawner, r as EmbeddingRequest, s as withSpan$1, t as Dimensions, u as maybeUpdateFile, v as flatMap$1, w as runDrain, x as fromQueue, y as fromArray, z as offerUnsafe } from "./cli.mjs";
3
+ import { createHash } from "node:crypto";
4
+ import TreeSitter from "tree-sitter";
5
+ import TreeSitterJavaScript from "tree-sitter-javascript";
6
+ import TreeSitterTypeScript from "tree-sitter-typescript";
7
+ import { DatabaseSync, backup } from "node:sqlite";
8
+ import { getLoadablePath } from "sqlite-vec";
9
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/unstable/reactivity/Reactivity.js
10
+ /**
11
+ * Process-local invalidation for connecting writes to dependent reads.
12
+ *
13
+ * This module does not cache values itself. It lets callers register handlers
14
+ * for keys, invalidate those keys, wrap successful mutations so they invalidate
15
+ * keys, and expose effects as queues or streams that rerun when matching keys
16
+ * change. The service can also batch invalidations so handlers run after the
17
+ * batch completes.
18
+ *
19
+ * @since 4.0.0
20
+ */
21
+ /**
22
+ * Brand for `Reactivity` implementations.
23
+ *
24
+ * @category type IDs
25
+ * @since 4.0.0
26
+ */
27
+ const TypeId$6 = "~effect/reactivity/Reactivity";
28
+ /**
29
+ * Service key for reactive invalidation.
30
+ *
31
+ * @category services
32
+ * @since 4.0.0
33
+ */
34
+ const Reactivity = /*#__PURE__*/ Service("effect/reactivity/Reactivity");
35
+ /**
36
+ * Creates an in-memory `Reactivity` service.
37
+ *
38
+ * **Details**
39
+ *
40
+ * The service tracks handlers by hashed keys and runs the registered handlers when
41
+ * matching keys are invalidated.
42
+ *
43
+ * @category constructors
44
+ * @since 4.0.0
45
+ */
46
+ const make$7 = /*#__PURE__*/ sync(() => {
47
+ const handlers = /* @__PURE__ */ new Map();
48
+ const invalidateUnsafe = (keys) => {
49
+ keysToHashes(keys, (hash) => {
50
+ const set = handlers.get(hash);
51
+ if (set === void 0) return;
52
+ set.forEach((run) => run());
53
+ });
54
+ };
55
+ const invalidate = (keys) => contextWith((services) => {
56
+ const pending = getOrUndefined(services, PendingInvalidation);
57
+ if (pending) keysToHashes(keys, (hash) => {
58
+ pending.add(hash);
59
+ });
60
+ else invalidateUnsafe(keys);
61
+ return void_$1;
62
+ });
63
+ const mutation = (keys, effect) => tap(effect, invalidate(keys));
64
+ const registerUnsafe = (keys, handler) => {
65
+ const resolvedKeys = [];
66
+ keysToHashes(keys, (hash) => {
67
+ resolvedKeys.push(hash);
68
+ let set = handlers.get(hash);
69
+ if (set === void 0) {
70
+ set = /* @__PURE__ */ new Set();
71
+ handlers.set(hash, set);
72
+ }
73
+ set.add(handler);
74
+ });
75
+ return () => {
76
+ for (let i = 0; i < resolvedKeys.length; i++) {
77
+ const set = handlers.get(resolvedKeys[i]);
78
+ if (set === void 0) continue;
79
+ set.delete(handler);
80
+ if (set.size === 0) handlers.delete(resolvedKeys[i]);
81
+ }
82
+ };
83
+ };
84
+ const query = (keys, effect) => gen(function* () {
85
+ const services = yield* context();
86
+ const scope = get$1(services, Scope);
87
+ const results = yield* make$11();
88
+ const runFork = flow(runForkWith(services), runIn(scope));
89
+ let running = false;
90
+ let pending = false;
91
+ const handleExit = (exit) => {
92
+ if (exit._tag === "Failure") failCauseUnsafe(results, exit.cause);
93
+ else offerUnsafe(results, exit.value);
94
+ if (pending) {
95
+ pending = false;
96
+ runFork(effect).addObserver(handleExit);
97
+ } else running = false;
98
+ };
99
+ function run() {
100
+ if (running) {
101
+ pending = true;
102
+ return;
103
+ }
104
+ running = true;
105
+ runFork(effect).addObserver(handleExit);
106
+ }
107
+ const cancel = registerUnsafe(keys, run);
108
+ yield* addFinalizer(scope, sync(cancel));
109
+ run();
110
+ return results;
111
+ });
112
+ const stream = (tables, effect) => query(tables, effect).pipe(map(fromQueue), unwrap);
113
+ const withBatch = (effect) => suspend(() => {
114
+ const pending = /* @__PURE__ */ new Set();
115
+ return effect.pipe(provideService(PendingInvalidation, pending), onExit((_) => sync(() => {
116
+ pending.forEach((hash) => {
117
+ const set = handlers.get(hash);
118
+ if (set === void 0) return;
119
+ set.forEach((run) => run());
120
+ });
121
+ })));
122
+ });
123
+ return Reactivity.of({
124
+ [TypeId$6]: TypeId$6,
125
+ mutation,
126
+ query,
127
+ stream,
128
+ invalidateUnsafe,
129
+ invalidate,
130
+ registerUnsafe,
131
+ withBatch
132
+ });
133
+ });
134
+ var PendingInvalidation = class extends (/*#__PURE__*/ Service()("effect/reactivity/Reactivity/PendingInvalidation")) {};
135
+ /**
136
+ * The default layer that provides an in-memory `Reactivity` service.
137
+ *
138
+ * @category layers
139
+ * @since 4.0.0
140
+ */
141
+ const layer$5 = /*#__PURE__*/ effect(Reactivity)(make$7);
142
+ function stringOrHash(u) {
143
+ switch (typeof u) {
144
+ case "string":
145
+ case "number":
146
+ case "bigint":
147
+ case "boolean": return String(u);
148
+ default: return hash(u);
149
+ }
150
+ }
151
+ const keysToHashes = (keys, f) => {
152
+ if (Array.isArray(keys)) {
153
+ for (let i = 0; i < keys.length; i++) f(stringOrHash(keys[i]));
154
+ return;
155
+ }
156
+ for (const key in keys) {
157
+ f(key);
158
+ const ids = keys[key];
159
+ for (let i = 0; i < ids.length; i++) f(`${key}:${stringOrHash(ids[i])}`);
160
+ }
161
+ };
162
+ //#endregion
163
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/unstable/sql/Statement.js
164
+ /**
165
+ * Low-level SQL statement and fragment primitives.
166
+ *
167
+ * `SqlClient` uses this module to build executable, parameterized SQL from
168
+ * reusable fragments. A statement can be executed, streamed, run without row
169
+ * transformation, or compiled to SQL text and parameters for a specific
170
+ * dialect. The module also contains helpers for identifiers, parameters,
171
+ * inserts, updates, custom dialect fragments, statement compilation, and row
172
+ * transformation.
173
+ *
174
+ * @since 4.0.0
175
+ */
176
+ const FragmentTypeId = "~effect/sql/Statement/Fragment";
177
+ /**
178
+ * Constructs a SQL `Fragment` from low-level statement segments.
179
+ *
180
+ * @category constructors
181
+ * @since 4.0.0
182
+ */
183
+ const fragment = (segments) => ({
184
+ [FragmentTypeId]: FragmentTypeId,
185
+ segments
186
+ });
187
+ /**
188
+ * Context reference for an optional current SQL statement transformer applied
189
+ * before statement execution.
190
+ *
191
+ * @category services
192
+ * @since 4.0.0
193
+ */
194
+ const CurrentTransformer = /*#__PURE__*/ Reference("effect/sql/CurrentTransformer", { defaultValue: constUndefined });
195
+ /**
196
+ * Parents driver spans under `sql.execute` for every client in the current scope,
197
+ * including acquisition and stream pulls. Defaults to `false`; ignored when tracing is disabled.
198
+ *
199
+ * @category services
200
+ * @since 4.0.0
201
+ */
202
+ const SpanPropagationEnabled = /*#__PURE__*/ Reference("effect/sql/SpanPropagationEnabled", { defaultValue: () => false });
203
+ /**
204
+ * Returns `true` when a value is a SQL `Fragment`.
205
+ *
206
+ * @category guards
207
+ * @since 4.0.0
208
+ */
209
+ const isFragment = (u) => hasProperty(u, FragmentTypeId);
210
+ /**
211
+ * Constructs a raw SQL literal segment. The literal text is not escaped, so use
212
+ * bound parameters for untrusted values.
213
+ *
214
+ * @category constructors
215
+ * @since 4.0.0
216
+ */
217
+ const literal = (value, params) => ({
218
+ _tag: "Literal",
219
+ value,
220
+ params
221
+ });
222
+ /**
223
+ * Constructs a SQL identifier segment that will be escaped by the active
224
+ * compiler.
225
+ *
226
+ * @category constructors
227
+ * @since 4.0.0
228
+ */
229
+ const identifier = (value) => ({
230
+ _tag: "Identifier",
231
+ value
232
+ });
233
+ /**
234
+ * Constructs a bound parameter segment for a statement value.
235
+ *
236
+ * @category constructors
237
+ * @since 4.0.0
238
+ */
239
+ const parameter = (value) => ({
240
+ _tag: "Parameter",
241
+ value
242
+ });
243
+ /**
244
+ * Constructs an `ArrayHelper` segment for an array of values or fragments.
245
+ *
246
+ * @category constructors
247
+ * @since 4.0.0
248
+ */
249
+ const arrayHelper = (value) => ({
250
+ _tag: "ArrayHelper",
251
+ value
252
+ });
253
+ const RecordInsertHelperProto = {
254
+ _tag: "RecordInsertHelper",
255
+ returning(sql) {
256
+ const self = Object.create(Object.getPrototypeOf(this));
257
+ Object.assign(self, this, { returningIdentifier: typeof sql === "string" || isFragment(sql) ? sql : fragment([sql]) });
258
+ return self;
259
+ }
260
+ };
261
+ /**
262
+ * Constructs a `RecordInsertHelper` from one or more row objects.
263
+ *
264
+ * @category constructors
265
+ * @since 4.0.0
266
+ */
267
+ const recordInsertHelper = (value) => Object.assign(Object.create(RecordInsertHelperProto), {
268
+ value,
269
+ returningIdentifier: void 0
270
+ });
271
+ const RecordUpdateHelperProto = {
272
+ ...RecordInsertHelperProto,
273
+ _tag: "RecordUpdateHelper"
274
+ };
275
+ /**
276
+ * Constructs a `RecordUpdateHelper` for multi-row update compilation using the
277
+ * provided alias.
278
+ *
279
+ * @category constructors
280
+ * @since 4.0.0
281
+ */
282
+ const recordUpdateHelper = (value, alias) => Object.assign(Object.create(RecordUpdateHelperProto), {
283
+ value,
284
+ alias,
285
+ returningIdentifier: void 0
286
+ });
287
+ const RecordUpdateHelperSingleProto = {
288
+ ...RecordInsertHelperProto,
289
+ _tag: "RecordUpdateHelperSingle"
290
+ };
291
+ /**
292
+ * Constructs a `RecordUpdateHelperSingle` from a record and a list of columns
293
+ * to omit from the update.
294
+ *
295
+ * @category constructors
296
+ * @since 4.0.0
297
+ */
298
+ const recordUpdateHelperSingle = (value, omit) => Object.assign(Object.create(RecordUpdateHelperSingleProto), {
299
+ value,
300
+ omit,
301
+ returningIdentifier: void 0
302
+ });
303
+ /**
304
+ * Creates a cached SQL statement constructor from a connection acquirer,
305
+ * compiler, tracing attributes, and optional row transformation function.
306
+ *
307
+ * @category constructors
308
+ * @since 4.0.0
309
+ */
310
+ const make$6 = (acquirer, compiler, spanAttributes, transformRows, borrower) => {
311
+ const cache = transformRows === void 0 ? constructorCache.noTransforms : constructorCache.transforms;
312
+ if (cache.has(acquirer)) return cache.get(acquirer);
313
+ const self = Object.assign(function sql(strings, ...args) {
314
+ if (typeof strings === "string") return identifier(strings);
315
+ else if (Array.isArray(strings) && "raw" in strings) return statement(acquirer, compiler, strings, args, spanAttributes, transformRows, borrower);
316
+ throw "absurd";
317
+ }, {
318
+ unsafe(sql, params) {
319
+ return makeUnsafe$1([literal(sql, params)], acquirer, compiler, spanAttributes, transformRows, borrower);
320
+ },
321
+ literal(sql) {
322
+ return fragment([literal(sql)]);
323
+ },
324
+ in: in_,
325
+ insert(value) {
326
+ return recordInsertHelper(Array.isArray(value) ? value : [value]);
327
+ },
328
+ update(value, omit) {
329
+ return recordUpdateHelperSingle(value, omit ?? []);
330
+ },
331
+ updateValues(value, alias) {
332
+ return recordUpdateHelper(value, alias);
333
+ },
334
+ and,
335
+ or,
336
+ csv,
337
+ join,
338
+ onDialect(options) {
339
+ return options[compiler.dialect]();
340
+ },
341
+ onDialectOrElse(options) {
342
+ return options[compiler.dialect] !== void 0 ? options[compiler.dialect]() : options.orElse();
343
+ }
344
+ });
345
+ cache.set(acquirer, self);
346
+ return self;
347
+ };
348
+ const constructorCache = {
349
+ transforms: /*#__PURE__*/ new WeakMap(),
350
+ noTransforms: /*#__PURE__*/ new WeakMap()
351
+ };
352
+ /**
353
+ * Builds a `Statement` from template strings and arguments, preserving
354
+ * fragments and helper segments while converting ordinary interpolated values
355
+ * into bound parameters.
356
+ *
357
+ * @category constructors
358
+ * @since 4.0.0
359
+ */
360
+ const statement = (acquirer, compiler, strings, args, spanAttributes, transformRows, borrower) => {
361
+ const segments = strings[0].length > 0 ? [literal(strings[0])] : [];
362
+ for (let i = 0; i < args.length; i++) {
363
+ const arg = args[i];
364
+ if (isFragment(arg)) segments.push(...arg.segments);
365
+ else if (isSegment(arg)) segments.push(arg);
366
+ else segments.push(parameter(arg));
367
+ if (strings[i + 1].length > 0) segments.push(literal(strings[i + 1]));
368
+ }
369
+ return makeUnsafe$1(segments, acquirer, compiler, spanAttributes, transformRows, borrower);
370
+ };
371
+ /**
372
+ * Creates a helper that joins SQL clauses with a literal separator, optionally
373
+ * wrapping multiple clauses in parentheses and using a fallback for an empty
374
+ * list.
375
+ *
376
+ * @category constructors
377
+ * @since 4.0.0
378
+ */
379
+ function join(lit, addParens = true, fallback = "") {
380
+ const literalStatement = literal(lit);
381
+ const fallbackFragment = fragment([literal(fallback)]);
382
+ return (clauses) => {
383
+ if (clauses.length === 0) return fallbackFragment;
384
+ else if (clauses.length === 1) return fragment(convertLiteralOrFragment(clauses[0]));
385
+ const segments = [];
386
+ if (addParens) segments.push(literal("("));
387
+ segments.push.apply(segments, convertLiteralOrFragment(clauses[0]));
388
+ for (let i = 1; i < clauses.length; i++) {
389
+ segments.push(literalStatement);
390
+ segments.push.apply(segments, convertLiteralOrFragment(clauses[i]));
391
+ }
392
+ if (addParens) segments.push(literal(")"));
393
+ return fragment(segments);
394
+ };
395
+ }
396
+ /**
397
+ * Combines clauses with `AND`, parenthesizing multiple clauses and returning
398
+ * `1=1` when the list is empty.
399
+ *
400
+ * @category constructors
401
+ * @since 4.0.0
402
+ */
403
+ const and = /*#__PURE__*/ join(" AND ", true, "1=1");
404
+ /**
405
+ * Combines clauses with `OR`, parenthesizing multiple clauses and returning
406
+ * `1=1` when the list is empty.
407
+ *
408
+ * @category constructors
409
+ * @since 4.0.0
410
+ */
411
+ const or = /*#__PURE__*/ join(" OR ", true, "1=1");
412
+ /**
413
+ * Creates a comma-separated SQL fragment from values, optionally adding a
414
+ * prefix, and returns an empty fragment when no values are provided.
415
+ *
416
+ * @category constructors
417
+ * @since 4.0.0
418
+ */
419
+ const csv = function(...args) {
420
+ if (args[args.length - 1].length === 0) return emptyFragment;
421
+ if (args.length === 1) return csvRaw(args[0]);
422
+ return fragment([literal(`${args[0]} `), ...csvRaw(args[1]).segments]);
423
+ };
424
+ const csvRaw = /*#__PURE__*/ join(",", false);
425
+ const emptyFragment = /*#__PURE__*/ fragment([/*#__PURE__*/ literal("")]);
426
+ /**
427
+ * Creates a dialect-specific SQL `Compiler` from rendering callbacks.
428
+ *
429
+ * @category constructors
430
+ * @since 4.0.0
431
+ */
432
+ const makeCompiler = (options) => {
433
+ const self = Object.create(CompilerProto);
434
+ self.options = options;
435
+ self.dialect = options.dialect;
436
+ self.disableTransforms = false;
437
+ self.statementCache = /* @__PURE__ */ new WeakMap();
438
+ self.statementCacheNoTransform = /* @__PURE__ */ new WeakMap();
439
+ return self;
440
+ };
441
+ const CompilerProto = {
442
+ compile(statement, withoutTransform = false, placeholderOverride) {
443
+ const opts = this.options;
444
+ withoutTransform = withoutTransform || this.disableTransforms;
445
+ const cache = withoutTransform ? this.statementCacheNoTransform : this.statementCache;
446
+ const cached = cache.get(statement);
447
+ if (cached !== void 0 && placeholderOverride === void 0) return cached;
448
+ const segments = statement.segments;
449
+ const len = segments.length;
450
+ let sql = "";
451
+ const binds = [];
452
+ let placeholderCount = 0;
453
+ const placeholder = placeholderOverride ?? ((u) => opts.placeholder(++placeholderCount, u));
454
+ const placeholderNoIncrement = (u) => opts.placeholder(placeholderCount, u);
455
+ const placeholders = makePlaceholdersArray(placeholder);
456
+ for (let i = 0; i < len; i++) {
457
+ const segment = segments[i];
458
+ switch (segment._tag) {
459
+ case "Literal":
460
+ sql += segment.value;
461
+ if (segment.params) binds.push.apply(binds, segment.params);
462
+ break;
463
+ case "Identifier":
464
+ sql += opts.onIdentifier(segment.value, withoutTransform);
465
+ break;
466
+ case "Parameter":
467
+ sql += placeholder(segment.value);
468
+ binds.push(segment.value);
469
+ break;
470
+ case "ArrayHelper":
471
+ sql += `(${placeholders(segment.value)})`;
472
+ binds.push.apply(binds, segment.value);
473
+ break;
474
+ case "RecordInsertHelper": {
475
+ const keys = Object.keys(segment.value[0]);
476
+ if (opts.onInsert) {
477
+ const values = new Array(segment.value.length);
478
+ let placeholders = "";
479
+ for (let i = 0; i < segment.value.length; i++) {
480
+ const row = new Array(keys.length);
481
+ values[i] = row;
482
+ placeholders += i === 0 ? "(" : ",(";
483
+ for (let j = 0; j < keys.length; j++) {
484
+ const key = keys[j];
485
+ const value = segment.value[i][key];
486
+ const primitive = extractPrimitive(value, opts.onCustom, placeholderNoIncrement, withoutTransform);
487
+ row[j] = primitive;
488
+ placeholders += j === 0 ? placeholder(value) : `,${placeholder(value)}`;
489
+ }
490
+ placeholders += ")";
491
+ }
492
+ 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);
493
+ sql += s;
494
+ binds.push.apply(binds, b);
495
+ } else {
496
+ let placeholders = "";
497
+ for (let i = 0; i < segment.value.length; i++) {
498
+ placeholders += i === 0 ? "(" : ",(";
499
+ for (let j = 0; j < keys.length; j++) {
500
+ const value = segment.value[i][keys[j]];
501
+ const primitive = extractPrimitive(value, opts.onCustom, placeholderNoIncrement, withoutTransform);
502
+ binds.push(primitive);
503
+ placeholders += j === 0 ? placeholder(value) : `,${placeholder(value)}`;
504
+ }
505
+ placeholders += ")";
506
+ }
507
+ sql += `${generateColumns(keys, opts.onIdentifier, withoutTransform)} VALUES ${placeholders}`;
508
+ if (typeof segment.returningIdentifier === "string") sql += ` RETURNING ${segment.returningIdentifier}`;
509
+ else if (segment.returningIdentifier) {
510
+ sql += " RETURNING ";
511
+ const [s, b] = this.compile(segment.returningIdentifier, withoutTransform, placeholder);
512
+ sql += s;
513
+ binds.push.apply(binds, b);
514
+ }
515
+ }
516
+ break;
517
+ }
518
+ case "RecordUpdateHelperSingle": {
519
+ let keys = Object.keys(segment.value);
520
+ if (segment.omit.length > 0) keys = keys.filter((key) => !segment.omit.includes(key));
521
+ if (opts.onRecordUpdateSingle) {
522
+ 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);
523
+ sql += s;
524
+ binds.push.apply(binds, b);
525
+ } else {
526
+ for (let i = 0, len = keys.length; i < len; i++) {
527
+ const column = opts.onIdentifier(keys[i], withoutTransform);
528
+ if (i === 0) sql += `${column} = ${placeholder(segment.value[keys[i]])}`;
529
+ else sql += `, ${column} = ${placeholder(segment.value[keys[i]])}`;
530
+ binds.push(extractPrimitive(segment.value[keys[i]], opts.onCustom, placeholderNoIncrement, withoutTransform));
531
+ }
532
+ if (typeof segment.returningIdentifier === "string") {
533
+ if (this.dialect === "mssql") sql += ` OUTPUT ${segment.returningIdentifier === "*" ? "INSERTED.*" : segment.returningIdentifier}`;
534
+ else sql += ` RETURNING ${segment.returningIdentifier}`;
535
+ } else if (segment.returningIdentifier) {
536
+ sql += this.dialect === "mssql" ? " OUTPUT " : " RETURNING ";
537
+ const [s, b] = this.compile(segment.returningIdentifier, withoutTransform, placeholder);
538
+ sql += s;
539
+ binds.push.apply(binds, b);
540
+ }
541
+ }
542
+ break;
543
+ }
544
+ case "RecordUpdateHelper": {
545
+ const keys = Object.keys(segment.value[0]);
546
+ const values = new Array(segment.value.length);
547
+ let placeholders = "";
548
+ for (let i = 0; i < segment.value.length; i++) {
549
+ const row = new Array(keys.length);
550
+ values[i] = row;
551
+ placeholders += i === 0 ? "(" : ",(";
552
+ for (let j = 0; j < keys.length; j++) {
553
+ const key = keys[j];
554
+ const value = segment.value[i][key];
555
+ row[j] = extractPrimitive(value, opts.onCustom, placeholderNoIncrement, withoutTransform);
556
+ placeholders += j === 0 ? placeholder(value) : `,${placeholder(value)}`;
557
+ }
558
+ placeholders += ")";
559
+ }
560
+ 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);
561
+ sql += s;
562
+ binds.push.apply(binds, b);
563
+ break;
564
+ }
565
+ case "Custom": {
566
+ const [s, b] = opts.onCustom(segment, placeholder, withoutTransform);
567
+ sql += s;
568
+ binds.push.apply(binds, b);
569
+ break;
570
+ }
571
+ }
572
+ }
573
+ const result = [sql, binds];
574
+ if (placeholderOverride !== void 0) return result;
575
+ cache.set(statement, result);
576
+ return result;
577
+ },
578
+ get withoutTransform() {
579
+ const self = Object.create(CompilerProto);
580
+ Object.assign(self, this, { disableTransforms: true });
581
+ return self;
582
+ }
583
+ };
584
+ /**
585
+ * Creates a SQLite compiler that uses `?` placeholders and quoted identifiers,
586
+ * optionally transforming identifier names before escaping.
587
+ *
588
+ * @category constructors
589
+ * @since 4.0.0
590
+ */
591
+ const makeCompilerSqlite = (transform) => makeCompiler({
592
+ dialect: "sqlite",
593
+ placeholder(_) {
594
+ return "?";
595
+ },
596
+ onIdentifier: transform ? function(value, withoutTransform) {
597
+ return withoutTransform ? escapeSqlite(value) : escapeSqlite(transform(value));
598
+ } : escapeSqlite,
599
+ onRecordUpdate() {
600
+ return ["", []];
601
+ },
602
+ onCustom() {
603
+ return ["", []];
604
+ }
605
+ });
606
+ /**
607
+ * Creates an identifier escaping function that wraps names in the given
608
+ * delimiter, doubles delimiter characters, and escapes dots between identifier
609
+ * parts.
610
+ *
611
+ * @category constructors
612
+ * @since 4.0.0
613
+ */
614
+ function defaultEscape(c) {
615
+ const re = new RegExp(c, "g");
616
+ const double = c + c;
617
+ const dot = c + "." + c;
618
+ return function(str) {
619
+ return c + str.replace(re, double).replace(/\./g, dot) + c;
620
+ };
621
+ }
622
+ /**
623
+ * Builds value, object, and row-array transformers that rename object keys with
624
+ * the supplied function and optionally recurse into nested object arrays.
625
+ *
626
+ * @category transforming
627
+ * @since 4.0.0
628
+ */
629
+ const defaultTransforms = (transformer, nested = true) => {
630
+ const transformValue = (value) => {
631
+ if (Array.isArray(value)) {
632
+ if (value.length === 0 || value[0].constructor !== Object) return value;
633
+ return array(value);
634
+ } else if (value?.constructor === Object) return transformObject(value);
635
+ return value;
636
+ };
637
+ const transformObject = (obj) => {
638
+ const newObj = {};
639
+ for (const key of Object.keys(obj)) assignProperty(newObj, transformer(key), transformValue(obj[key]));
640
+ return newObj;
641
+ };
642
+ const transformArrayNested = (rows) => {
643
+ const newRows = new Array(rows.length);
644
+ for (let i = 0, len = rows.length; i < len; i++) {
645
+ const row = rows[i];
646
+ if (Array.isArray(row)) newRows[i] = transformArrayNested(row);
647
+ else {
648
+ const obj = {};
649
+ for (const [key, value] of Object.entries(row)) assignProperty(obj, transformer(key), transformValue(value));
650
+ newRows[i] = obj;
651
+ }
652
+ }
653
+ return newRows;
654
+ };
655
+ const transformArray = (rows) => {
656
+ const newRows = new Array(rows.length);
657
+ for (let i = 0, len = rows.length; i < len; i++) {
658
+ const row = rows[i];
659
+ if (Array.isArray(row)) newRows[i] = transformArray(row);
660
+ else {
661
+ const obj = {};
662
+ for (const [key, value] of Object.entries(row)) assignProperty(obj, transformer(key), value);
663
+ newRows[i] = obj;
664
+ }
665
+ }
666
+ return newRows;
667
+ };
668
+ const array = nested ? transformArrayNested : transformArray;
669
+ return {
670
+ value: transformValue,
671
+ object: transformObject,
672
+ array
673
+ };
674
+ };
675
+ const ATTR_DB_OPERATION_NAME = "db.operation.name";
676
+ const ATTR_DB_QUERY_TEXT = "db.query.text";
677
+ const makeUnsafe$1 = (segments, acquirer, compiler, spanAttributes, transformRows, borrower) => {
678
+ const self = Object.create(StatementProto);
679
+ self.segments = segments;
680
+ self.acquirer = acquirer;
681
+ self.compiler = compiler;
682
+ self.spanAttributes = spanAttributes;
683
+ self.transformRows = transformRows;
684
+ self.borrower = borrower;
685
+ return self;
686
+ };
687
+ const StatementProto = {
688
+ [FragmentTypeId]: FragmentTypeId,
689
+ withConnection(operation, f, withoutTransform = false) {
690
+ return useSpan("sql.execute", { kind: "client" }, (span) => this.withConnectionSpan(operation, f, withoutTransform, span));
691
+ },
692
+ withConnectionSpan(operation, f, withoutTransform, span) {
693
+ return withStatement(this, span, (statement, fiber) => {
694
+ const [sql, params] = statement.compile(withoutTransform);
695
+ for (const [key, value] of this.spanAttributes) span.attribute(key, value);
696
+ span.attribute(ATTR_DB_OPERATION_NAME, operation);
697
+ span.attribute(ATTR_DB_QUERY_TEXT, sql);
698
+ const execute = this.borrower === void 0 ? scoped(flatMap(this.acquirer, (_) => f(_, sql, params))) : this.borrower((connection) => f(connection, sql, params));
699
+ return fiber.cache.tracerEnabled && fiber.getRef(SpanPropagationEnabled) ? provideService(execute, ParentSpan, span) : execute;
700
+ });
701
+ },
702
+ get withoutTransform() {
703
+ return this.withConnection("executeWithoutTransform", (connection, sql, params) => connection.execute(sql, params, void 0), true);
704
+ },
705
+ get raw() {
706
+ return this.withConnection("executeRaw", (connection, sql, params) => connection.executeRaw(sql, params), true);
707
+ },
708
+ get stream() {
709
+ const self = this;
710
+ return unwrap(flatMap(makeSpanScoped("sql.execute", { kind: "client" }), (span) => withStatement(self, span, (statement, fiber) => {
711
+ const [sql, params] = statement.compile();
712
+ for (const [key, value] of self.spanAttributes) span.attribute(key, value);
713
+ span.attribute(ATTR_DB_OPERATION_NAME, "executeStream");
714
+ span.attribute(ATTR_DB_QUERY_TEXT, sql);
715
+ const acquire = map(self.acquirer, (_) => _.executeStream(sql, params, self.transformRows));
716
+ return fiber.cache.tracerEnabled && fiber.getRef(SpanPropagationEnabled) ? succeed(provideService$1(unwrap(acquire), ParentSpan, span)) : acquire;
717
+ })));
718
+ },
719
+ get values() {
720
+ return this.withConnection("executeValues", (connection, sql, params) => connection.executeValues(sql, params));
721
+ },
722
+ get valuesUnprepared() {
723
+ return this.withConnection("executeValuesUnprepared", (connection, sql, params) => connection.executeValuesUnprepared(sql, params));
724
+ },
725
+ get unprepared() {
726
+ const self = this;
727
+ return self.withConnection("executeUnprepared", (connection, sql, params) => connection.executeUnprepared(sql, params, self.transformRows));
728
+ },
729
+ .../*#__PURE__*/ Prototype({
730
+ label: "Statement",
731
+ evaluate(fiber) {
732
+ const span = makeSpanUnsafe(fiber, "sql.execute", { kind: "client" });
733
+ const clock = fiber.getRef(Clock);
734
+ const timingEnabled = fiber.getRef(TracerTimingEnabled);
735
+ return onExit(this.withConnectionSpan("execute", (connection, sql, params) => connection.execute(sql, params, this.transformRows), false, span), (exit) => endSpan(span, exit, clock, timingEnabled));
736
+ }
737
+ }),
738
+ compile(withoutTransform) {
739
+ return this.compiler.compile(this, withoutTransform ?? false);
740
+ },
741
+ toJSON() {
742
+ const [sql, params] = this.compile();
743
+ return {
744
+ _id: "Statement",
745
+ segments: this.segments,
746
+ sql,
747
+ params
748
+ };
749
+ }
750
+ };
751
+ const withStatement = (self, span, f) => withFiber((fiber) => {
752
+ const transform = fiber.getRef(CurrentTransformer);
753
+ if (transform === void 0) return f(self, fiber);
754
+ return flatMap(transform(self, make$6(self.acquirer, self.compiler, self.spanAttributes, self.transformRows, self.borrower), fiber, span), (statement) => f(statement, fiber));
755
+ });
756
+ const isSegment = (u) => {
757
+ if (!hasProperty(u, "_tag")) return false;
758
+ switch (u._tag) {
759
+ case "Literal":
760
+ case "Parameter":
761
+ case "ArrayHelper":
762
+ case "RecordInsertHelper":
763
+ case "RecordUpdateHelper":
764
+ case "RecordUpdateHelperSingle":
765
+ case "Identifier":
766
+ case "Custom": return true;
767
+ default: return false;
768
+ }
769
+ };
770
+ function convertLiteralOrFragment(clause) {
771
+ if (typeof clause === "string") return [literal(clause)];
772
+ return clause.segments;
773
+ }
774
+ const makePlaceholdersArray = (evaluate) => (values) => {
775
+ if (values.length === 0) return "";
776
+ let result = evaluate(values[0]);
777
+ for (let i = 1; i < values.length; i++) result += `,${evaluate(values[i])}`;
778
+ return result;
779
+ };
780
+ const generateColumns = (keys, escape, withoutTransform) => {
781
+ if (keys.length === 0) return "()";
782
+ let str = `(${escape(keys[0], withoutTransform)}`;
783
+ for (let i = 1; i < keys.length; i++) str += `,${escape(keys[i], withoutTransform)}`;
784
+ return str + ")";
785
+ };
786
+ const extractPrimitive = (value, onCustom, placeholder, withoutTransform) => {
787
+ if (value === void 0) return null;
788
+ else if (isFragment(value)) {
789
+ const head = value.segments[0];
790
+ if (head._tag === "Custom") return onCustom(head, placeholder, withoutTransform)[1][0] ?? null;
791
+ else if (head._tag === "Parameter") return head.value;
792
+ return null;
793
+ }
794
+ return value;
795
+ };
796
+ const escapeSqlite = /*#__PURE__*/ defaultEscape("\"");
797
+ function in_() {
798
+ if (arguments.length === 1) return arrayHelper(arguments[0]);
799
+ const column = arguments[0];
800
+ const values = arguments[1];
801
+ return values.length === 0 ? neverFragment : fragment([
802
+ identifier(column),
803
+ literal(" IN "),
804
+ arrayHelper(values)
805
+ ]);
806
+ }
807
+ const neverFragment = /*#__PURE__*/ fragment([/*#__PURE__*/ literal("1=0")]);
808
+ //#endregion
809
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/unstable/sql/SqlClient.js
810
+ /**
811
+ * Main SQL client service for tagged-template queries.
812
+ *
813
+ * `SqlClient` combines the tagged-template statement constructor with
814
+ * connection acquisition, dialect compilation, transactions, row transforms,
815
+ * tracing, and reactive query helpers. Driver integrations build this service
816
+ * from their connection and compiler pieces.
817
+ *
818
+ * @since 4.0.0
819
+ */
820
+ const TypeId$5 = "~effect/sql/SqlClient";
821
+ /**
822
+ * Service tag for the active SQL client service.
823
+ *
824
+ * **When to use**
825
+ *
826
+ * Use to access or provide the SQL client used to build statements, stream
827
+ * rows, reserve connections, and run transactions.
828
+ *
829
+ * @category services
830
+ * @since 4.0.0
831
+ */
832
+ const SqlClient = /*#__PURE__*/ Service("effect/sql/SqlClient");
833
+ let clientIdCounter = 0;
834
+ let transactionSemaphoreIdCounter = 0;
835
+ /**
836
+ * Constructs a `SqlClient` from connection acquirers, a compiler, transaction
837
+ * commands, tracing attributes, optional row transforms, and reactive query
838
+ * integration.
839
+ *
840
+ * @category constructors
841
+ * @since 4.0.0
842
+ */
843
+ const make$5 = /*#__PURE__*/ fnUntraced(function* (options) {
844
+ const transactionService = options.transactionService ?? TransactionConnection(clientIdCounter++);
845
+ const getConnection = flatMap(serviceOption(transactionService), match({
846
+ onNone: () => options.acquirer,
847
+ onSome: ([conn]) => succeed(conn)
848
+ }));
849
+ const beginTransaction = options.beginTransaction ?? "BEGIN";
850
+ const commit = options.commit ?? "COMMIT";
851
+ const savepoint = options.savepoint ?? ((name) => `SAVEPOINT ${name}`);
852
+ const rollback = options.rollback ?? "ROLLBACK";
853
+ const rollbackSavepoint = options.rollbackSavepoint ?? ((name) => `ROLLBACK TO SAVEPOINT ${name}`);
854
+ const transactionAcquirer = options.transactionAcquirer ?? options.acquirer;
855
+ const control = options.prepareTransactionControls === true ? (conn, sql) => conn.execute(sql, [], void 0) : (conn, sql) => conn.executeUnprepared(sql, [], void 0);
856
+ const withTransaction = makeWithTransaction({
857
+ transactionService,
858
+ spanAttributes: options.spanAttributes,
859
+ acquireConnection: flatMap(make$8(), (scope) => map(provide(transactionAcquirer, scope), (conn) => [scope, conn])),
860
+ begin: (conn) => control(conn, beginTransaction),
861
+ savepoint: (conn, id) => control(conn, savepoint(`effect_sql_${id}`)),
862
+ commit: (conn) => control(conn, commit),
863
+ rollback: (conn) => control(conn, rollback),
864
+ rollbackSavepoint: (conn, id) => control(conn, rollbackSavepoint(`effect_sql_${id}`))
865
+ });
866
+ const reactivity = yield* Reactivity;
867
+ const borrower = options.borrower === void 0 ? void 0 : (f) => flatMap(serviceOption(transactionService), match({
868
+ onNone: () => options.borrower(f),
869
+ onSome: ([conn]) => f(conn)
870
+ }));
871
+ const client = Object.assign(make$6(getConnection, options.compiler, options.spanAttributes, options.transformRows, borrower), {
872
+ [TypeId$5]: TypeId$5,
873
+ safe: void 0,
874
+ withTransaction,
875
+ transactionService,
876
+ reserve: transactionAcquirer,
877
+ withoutTransforms() {
878
+ if (options.transformRows === void 0) return this;
879
+ const statement = make$6(getConnection, options.compiler.withoutTransform, options.spanAttributes, void 0, borrower);
880
+ const client = Object.assign(statement, {
881
+ ...this,
882
+ ...statement
883
+ });
884
+ client.safe = client;
885
+ client.withoutTransforms = () => client;
886
+ return client;
887
+ },
888
+ reactive: options.reactiveQueue ? (keys, effect) => options.reactiveQueue(keys, effect).pipe(map(fromQueue), unwrap) : reactivity.stream,
889
+ reactiveMailbox: options.reactiveQueue ?? reactivity.query
890
+ });
891
+ client.safe = client;
892
+ return client;
893
+ });
894
+ /**
895
+ * Builds a transaction wrapper that begins top-level transactions, uses
896
+ * savepoints for nested transactions, commits on success, and rolls back on
897
+ * failure or interruption.
898
+ *
899
+ * @category transactions
900
+ * @since 4.0.0
901
+ */
902
+ const makeWithTransaction = (options) => {
903
+ const transactionSemaphore = Service(`effect/sql/SqlClient/TransactionSemaphore/${transactionSemaphoreIdCounter++}`);
904
+ return (effect) => uninterruptibleMask((restore) => useSpan("sql.transaction", { kind: "client" }, (span) => withFiber((fiber) => {
905
+ for (const [key, value] of options.spanAttributes) span.attribute(key, value);
906
+ const services = fiber.context;
907
+ const clock = fiber.getRef(Clock);
908
+ const connOption = getOption(services, options.transactionService);
909
+ const conn = connOption._tag === "Some" ? succeed([void 0, connOption.value[0]]) : options.acquireConnection;
910
+ const id = connOption._tag === "Some" ? connOption.value[1] + 1 : 0;
911
+ const transaction = flatMap(conn, ([scope, conn]) => (id === 0 ? options.begin(conn) : options.savepoint(conn, id)).pipe(flatMap(() => onExitPrimitive(provideContext(restore(effect), services.pipe(add(options.transactionService, [conn, id]), add(transactionSemaphore, makeUnsafe$3(1)), add(ParentSpan, span))), (exit) => {
912
+ let effect;
913
+ if (isSuccess(exit)) {
914
+ if (id === 0) {
915
+ span.event("db.transaction.commit", clock.currentTimeNanosUnsafe());
916
+ effect = orDie(options.commit(conn));
917
+ } else {
918
+ span.event("db.transaction.savepoint", clock.currentTimeNanosUnsafe());
919
+ effect = void_$1;
920
+ }
921
+ } else {
922
+ span.event("db.transaction.rollback", clock.currentTimeNanosUnsafe());
923
+ effect = orDie(id > 0 ? options.rollbackSavepoint(conn, id) : options.rollback(conn));
924
+ }
925
+ return flatMap(effect, () => exit);
926
+ }, true)), scope ? (eff) => onExitPrimitive(eff, (exit) => close(scope, exit), true) : identity));
927
+ return id === 0 ? transaction : getUnsafe(services, transactionSemaphore).withPermit(transaction);
928
+ })));
929
+ };
930
+ /**
931
+ * Creates a unique context service tag for the active transaction connection of
932
+ * a specific SQL client.
933
+ *
934
+ * @category services
935
+ * @since 4.0.0
936
+ */
937
+ const TransactionConnection = (clientId) => Service(`effect/sql/SqlClient/TransactionConnection/${clientId}`);
938
+ /**
939
+ * Context reference used by SQL integrations to opt in to safe integer
940
+ * handling; defaults to `false`.
941
+ *
942
+ * @category services
943
+ * @since 4.0.0
944
+ */
945
+ const SafeIntegers = /*#__PURE__*/ Reference("effect/sql/SqlClient/SafeIntegers", { defaultValue: () => false });
946
+ //#endregion
947
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/Cache.js
948
+ /**
949
+ * Caches values loaded by an Effect lookup function.
950
+ *
951
+ * A cache stores successful and failed lookup results, shares an in-progress
952
+ * lookup when multiple callers request the same missing key, and limits entries
953
+ * by capacity and optional time-to-live rules. This module includes helpers for
954
+ * reading, setting, refreshing, invalidating, and inspecting cache contents.
955
+ *
956
+ * @since 4.0.0
957
+ */
958
+ const TypeId$4 = "~effect/Cache";
959
+ /**
960
+ * Creates a cache with dynamic time-to-live based on the result and key.
961
+ *
962
+ * **When to use**
963
+ *
964
+ * Use when you need different cache entry lifetimes based on the lookup result
965
+ * or key characteristics.
966
+ *
967
+ * **Details**
968
+ *
969
+ * The timeToLive function receives both the exit result and the key, allowing
970
+ * for flexible TTL policies based on success/failure state and key characteristics.
971
+ *
972
+ * **Example** (Configuring dynamic time to live)
973
+ *
974
+ * ```ts import.meta.vitest
975
+ * import { Cache, Effect, Exit } from "effect"
976
+ *
977
+ * // Cache with TTL based on computed value
978
+ * const program = Effect.gen(function*() {
979
+ * const cache = yield* Cache.makeWith(
980
+ * (id: number) => Effect.succeed({ id, active: id % 2 === 0 }),
981
+ * {
982
+ * capacity: 1000,
983
+ * timeToLive(exit) {
984
+ * if (Exit.isSuccess(exit)) {
985
+ * const user = exit.value
986
+ * return user.active ? "1 hour" : "5 minutes"
987
+ * }
988
+ * return "30 seconds"
989
+ * }
990
+ * }
991
+ * )
992
+ *
993
+ * return cache.capacity
994
+ * })
995
+ *
996
+ * const actual = await Effect.runPromise(program)
997
+ * actual // => 1000
998
+ * ```
999
+ *
1000
+ * @see {@link make} for a simpler cache constructor with a fixed time-to-live for all entries
1001
+ * @category constructors
1002
+ * @since 2.0.0
1003
+ */
1004
+ const makeWith = (lookup, options) => contextWith$1((context) => {
1005
+ const self = Object.create(Proto$1);
1006
+ self.lookup = (key) => updateContext(lookup(key), (input) => merge(context, input));
1007
+ self.map = make$12();
1008
+ self.capacity = options.capacity;
1009
+ self.timeToLive = options.timeToLive ? (exit, key) => fromInputUnsafe(options.timeToLive(exit, key)) : defaultTimeToLive;
1010
+ return succeed$1(self);
1011
+ });
1012
+ /**
1013
+ * Creates a cache with a fixed time-to-live for all entries.
1014
+ *
1015
+ * **Details**
1016
+ *
1017
+ * This is the basic cache constructor where all entries share the same TTL.
1018
+ * The lookup function will be called when a key is not found or has expired.
1019
+ *
1020
+ * **Example** (Creating a basic cache)
1021
+ *
1022
+ * ```ts import.meta.vitest
1023
+ * import { Cache, Effect } from "effect"
1024
+ *
1025
+ * // Basic cache with string keys
1026
+ * const program = Effect.gen(function*() {
1027
+ * const cache = yield* Cache.make<string, number>({
1028
+ * capacity: 100,
1029
+ * lookup: (key) => Effect.succeed(key.length)
1030
+ * })
1031
+ *
1032
+ * const result1 = yield* Cache.get(cache, "hello")
1033
+ * const result2 = yield* Cache.get(cache, "world")
1034
+ * return { result1, result2 }
1035
+ * })
1036
+ *
1037
+ * const actual = await Effect.runPromise(program)
1038
+ * actual // => { result1: 5, result2: 5 }
1039
+ * ```
1040
+ *
1041
+ * **Example** (Creating a cache with TTL)
1042
+ *
1043
+ * ```ts import.meta.vitest
1044
+ * import { Cache, Effect } from "effect"
1045
+ *
1046
+ * const program = Effect.gen(function*() {
1047
+ * const users = new Map([
1048
+ * [123, { name: "Ada", email: "ada@example.com" }],
1049
+ * [456, { name: "Grace", email: "grace@example.com" }]
1050
+ * ])
1051
+ *
1052
+ * const cache = yield* Cache.make<
1053
+ * number,
1054
+ * { name: string; email: string },
1055
+ * string
1056
+ * >({
1057
+ * capacity: 500,
1058
+ * lookup: (userId) =>
1059
+ * Effect.suspend(() => {
1060
+ * const user = users.get(userId)
1061
+ * return user === undefined
1062
+ * ? Effect.fail(`User ${userId} not found`)
1063
+ * : Effect.succeed(user)
1064
+ * }),
1065
+ * timeToLive: "15 minutes"
1066
+ * })
1067
+ *
1068
+ * const user1 = yield* Cache.get(cache, 123)
1069
+ * const user2 = yield* Cache.get(cache, 123)
1070
+ * return [user1, user2, user1 === user2] as const
1071
+ * })
1072
+ *
1073
+ * const actual = await Effect.runPromise(program)
1074
+ * actual // => [{ name: "Ada", email: "ada@example.com" }, { name: "Ada", email: "ada@example.com" }, true]
1075
+ * ```
1076
+ *
1077
+ * @category constructors
1078
+ * @since 2.0.0
1079
+ */
1080
+ const make$4 = (options) => makeWith(options.lookup, {
1081
+ ...options,
1082
+ timeToLive: options.timeToLive !== void 0 ? () => options.timeToLive : defaultTimeToLive
1083
+ });
1084
+ const Proto$1 = {
1085
+ ...PipeInspectableProto,
1086
+ [TypeId$4]: TypeId$4,
1087
+ toJSON() {
1088
+ return {
1089
+ _id: "Cache",
1090
+ capacity: this.capacity,
1091
+ map: this.map
1092
+ };
1093
+ }
1094
+ };
1095
+ const defaultTimeToLive = (_, _key) => infinity;
1096
+ /**
1097
+ * Retrieves the value for a key, invoking the lookup function on a cache miss
1098
+ * or expired entry.
1099
+ *
1100
+ * **Details**
1101
+ *
1102
+ * Concurrent `get` calls for the same missing key share the same pending
1103
+ * lookup. The cache stores the lookup `Exit`, so failed lookups are cached and
1104
+ * will fail again until the entry expires, is invalidated, or is refreshed.
1105
+ *
1106
+ * **Example** (Getting cached values)
1107
+ *
1108
+ * ```ts import.meta.vitest
1109
+ * import { Cache, Effect } from "effect"
1110
+ *
1111
+ * const program = Effect.gen(function*() {
1112
+ * const cache = yield* Cache.make({
1113
+ * capacity: 10,
1114
+ * lookup: (key: string) => Effect.succeed(key.length)
1115
+ * })
1116
+ *
1117
+ * // Cache miss - triggers lookup function
1118
+ * const result1 = yield* Cache.get(cache, "hello")
1119
+ *
1120
+ * // Cache hit - returns cached value without lookup
1121
+ * const result2 = yield* Cache.get(cache, "hello")
1122
+ *
1123
+ * return { result1, result2 }
1124
+ * })
1125
+ *
1126
+ * const actual = await Effect.runPromise(program)
1127
+ * actual // => { result1: 5, result2: 5 }
1128
+ * ```
1129
+ *
1130
+ * **Example** (Handling lookup failures)
1131
+ *
1132
+ * ```ts import.meta.vitest
1133
+ * import { Cache, Effect, Exit } from "effect"
1134
+ *
1135
+ * // Error handling when lookup fails
1136
+ * const program = Effect.gen(function*() {
1137
+ * const cache = yield* Cache.make<string, number, string>({
1138
+ * capacity: 10,
1139
+ * lookup: (key: string) =>
1140
+ * key === "error"
1141
+ * ? Effect.fail("Lookup failed")
1142
+ * : Effect.succeed(key.length)
1143
+ * })
1144
+ *
1145
+ * // Successful lookup
1146
+ * const success = yield* Cache.get(cache, "hello")
1147
+ *
1148
+ * // Failed lookup - returns error
1149
+ * const failure = yield* Effect.exit(Cache.get(cache, "error"))
1150
+ * return [success, failure] as const
1151
+ * })
1152
+ *
1153
+ * const actual = await Effect.runPromise(program)
1154
+ * actual // => [5, Exit.fail("Lookup failed")]
1155
+ * ```
1156
+ *
1157
+ * **Example** (Sharing concurrent lookups)
1158
+ *
1159
+ * ```ts import.meta.vitest
1160
+ * import { Cache, Effect } from "effect"
1161
+ *
1162
+ * // Concurrent access - multiple gets of same key only invoke lookup once
1163
+ * const program = Effect.gen(function*() {
1164
+ * let lookupCount = 0
1165
+ * const cache = yield* Cache.make({
1166
+ * capacity: 10,
1167
+ * lookup: (key: string) =>
1168
+ * Effect.sync(() => {
1169
+ * lookupCount++
1170
+ * return key.length
1171
+ * })
1172
+ * })
1173
+ *
1174
+ * // Multiple concurrent gets
1175
+ * const results = yield* Effect.all([
1176
+ * Cache.get(cache, "hello"),
1177
+ * Cache.get(cache, "hello"),
1178
+ * Cache.get(cache, "hello")
1179
+ * ], { concurrency: "unbounded" })
1180
+ *
1181
+ * return { results, lookupCount }
1182
+ * })
1183
+ *
1184
+ * const actual = await Effect.runPromise(program)
1185
+ * actual // => { results: [5, 5, 5], lookupCount: 1 }
1186
+ * ```
1187
+ *
1188
+ * @category combinators
1189
+ * @since 4.0.0
1190
+ */
1191
+ const get = /*#__PURE__*/ dual(2, (self, key) => withFiber$1((fiber) => {
1192
+ const oentry = get$2(self.map, key);
1193
+ if (isSome(oentry) && !hasExpired(oentry.value, fiber)) {
1194
+ remove(self.map, key);
1195
+ set(self.map, key, oentry.value);
1196
+ return oentry.value.await();
1197
+ }
1198
+ const entry = new EntryImpl(fiber, self.lookup(key));
1199
+ entry.fiber.addObserver((exit) => {
1200
+ if (exitHasInterrupts(exit)) {
1201
+ const current = get$2(self.map, key);
1202
+ if (isSome(current) && current.value === entry) remove(self.map, key);
1203
+ return;
1204
+ }
1205
+ const ttl = self.timeToLive(exit, key);
1206
+ if (isFinite(ttl)) entry.expiresAt = fiber.getRef(ClockRef).currentTimeMillisUnsafe() + toMillis(ttl);
1207
+ else if (isZero(ttl)) remove(self.map, key);
1208
+ });
1209
+ const exit = entry.fiber.pollUnsafe();
1210
+ if (exit === void 0 || !exitHasInterrupts(exit)) set(self.map, key, entry);
1211
+ if (Number.isFinite(self.capacity)) checkCapacity(self);
1212
+ return entry.await();
1213
+ }));
1214
+ var EntryImpl = class {
1215
+ expiresAt;
1216
+ awaiters;
1217
+ fiber;
1218
+ constructor(parent, valueEffect) {
1219
+ this.fiber = forkUnsafe(parent, valueEffect, true, true);
1220
+ this.awaiters = 0;
1221
+ this.expiresAt = void 0;
1222
+ }
1223
+ await() {
1224
+ const exit = this.fiber.pollUnsafe();
1225
+ if (exit) return exit;
1226
+ this.awaiters++;
1227
+ return onExit$1(fiberJoin(this.fiber), () => {
1228
+ this.awaiters--;
1229
+ if (this.awaiters > 0 || this.fiber.pollUnsafe()) return void_$2;
1230
+ return fiberInterrupt(this.fiber);
1231
+ });
1232
+ }
1233
+ };
1234
+ const hasExpired = (entry, fiber) => {
1235
+ if (entry.expiresAt === void 0) return false;
1236
+ return fiber.getRef(ClockRef).currentTimeMillisUnsafe() >= entry.expiresAt;
1237
+ };
1238
+ const checkCapacity = (self) => {
1239
+ let diff = size(self.map) - self.capacity;
1240
+ if (diff <= 0) return;
1241
+ for (const [key] of self.map) {
1242
+ remove(self.map, key);
1243
+ diff--;
1244
+ if (diff === 0) return;
1245
+ }
1246
+ };
1247
+ //#endregion
1248
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/unstable/schema/VariantSchema.js
1249
+ /**
1250
+ * Runtime type identifier attached to variant schema structs.
1251
+ *
1252
+ * @category type IDs
1253
+ * @since 4.0.0
1254
+ */
1255
+ const TypeId$3 = "~effect/schema/VariantSchema";
1256
+ const cacheSymbol = /*#__PURE__*/ Symbol.for(`${TypeId$3}/cache`);
1257
+ const defaultCacheSymbol = /*#__PURE__*/ Symbol.for(`${TypeId$3}/defaultCache`);
1258
+ /**
1259
+ * Returns `true` when a value is a variant schema struct.
1260
+ *
1261
+ * @category guards
1262
+ * @since 4.0.0
1263
+ */
1264
+ const isStruct = (u) => hasProperty(u, TypeId$3);
1265
+ const FieldTypeId = "~effect/schema/VariantSchema/Field";
1266
+ /**
1267
+ * Returns `true` when a value is a variant schema field.
1268
+ *
1269
+ * @category guards
1270
+ * @since 4.0.0
1271
+ */
1272
+ const isField = (u) => hasProperty(u, FieldTypeId);
1273
+ const extract$1 = /*#__PURE__*/ dual((args) => isStruct(args[0]), (self, variant, options) => {
1274
+ if (options?.isDefault === true && isSchema(self)) return self;
1275
+ const cache = options?.isDefault === true ? self[defaultCacheSymbol] ?? (self[defaultCacheSymbol] = Object.create(null)) : self[cacheSymbol] ?? (self[cacheSymbol] = Object.create(null));
1276
+ if (Object.hasOwn(cache, variant)) return cache[variant];
1277
+ const fields = {};
1278
+ for (const key of Object.keys(self[TypeId$3])) {
1279
+ const value = self[TypeId$3][key];
1280
+ if (value === void 0) continue;
1281
+ if ("~effect/schema/VariantSchema" in value) {
1282
+ if (options?.isDefault === true && isSchema(value)) assignProperty(fields, key, value);
1283
+ else assignProperty(fields, key, extract$1(value, variant));
1284
+ } else if (FieldTypeId in value) {
1285
+ if (Object.hasOwn(value.schemas, variant)) {
1286
+ const schema = value.schemas[variant];
1287
+ if (schema !== void 0) assignProperty(fields, key, schema);
1288
+ }
1289
+ } else assignProperty(fields, key, value);
1290
+ }
1291
+ const schema = Struct$2(fields);
1292
+ cache[variant] = schema;
1293
+ return schema;
1294
+ });
1295
+ /**
1296
+ * Creates a variant schema toolkit for a fixed set of variant names and a default
1297
+ * variant.
1298
+ *
1299
+ * @category constructors
1300
+ * @since 4.0.0
1301
+ */
1302
+ const make$3 = (options) => {
1303
+ function Class(identifier) {
1304
+ return function(fields, annotations) {
1305
+ const variantStruct = Struct$1(fields);
1306
+ const schema = extract$1(variantStruct, options.defaultVariant, { isDefault: true });
1307
+ const SClass = Class$1;
1308
+ class Base extends SClass(identifier)(schema.fields, annotations) {
1309
+ static [TypeId$3] = fields;
1310
+ }
1311
+ for (const variant of options.variants) Object.defineProperty(Base, variant, { value: extract$1(variantStruct, variant).annotate({
1312
+ id: `${identifier}.${variant}`,
1313
+ title: `${identifier}.${variant}`
1314
+ }) });
1315
+ return Base;
1316
+ };
1317
+ }
1318
+ function FieldOnly(keys) {
1319
+ return function(schema) {
1320
+ const obj = {};
1321
+ for (const key of keys) assignProperty(obj, key, schema);
1322
+ return Field$1(obj);
1323
+ };
1324
+ }
1325
+ function FieldExcept(keys) {
1326
+ return function(schema) {
1327
+ const obj = {};
1328
+ for (const variant of options.variants) if (!keys.includes(variant)) assignProperty(obj, variant, schema);
1329
+ return Field$1(obj);
1330
+ };
1331
+ }
1332
+ function UnionVariants(members) {
1333
+ return Union$1(members, options.defaultVariant, options.variants);
1334
+ }
1335
+ const fieldEvolve = dual(2, (self, f) => {
1336
+ const field = isField(self) ? self : Field$1(Object.fromEntries(options.variants.map((variant) => [variant, self])));
1337
+ return Field$1(evolve(field.schemas, f));
1338
+ });
1339
+ const extractVariants = dual(2, (self, variant) => extract$1(self, variant, { isDefault: variant === options.defaultVariant }));
1340
+ return {
1341
+ Struct: Struct$1,
1342
+ Field: Field$1,
1343
+ FieldOnly,
1344
+ FieldExcept,
1345
+ Class,
1346
+ Union: UnionVariants,
1347
+ fieldEvolve,
1348
+ extract: extractVariants
1349
+ };
1350
+ };
1351
+ const StructProto = { pipe() {
1352
+ return pipeArguments(this, arguments);
1353
+ } };
1354
+ const Struct$1 = (fields) => {
1355
+ const self = Object.create(StructProto);
1356
+ self[TypeId$3] = fields;
1357
+ return self;
1358
+ };
1359
+ const FieldProto = {
1360
+ [FieldTypeId]: FieldTypeId,
1361
+ pipe() {
1362
+ return pipeArguments(this, arguments);
1363
+ }
1364
+ };
1365
+ const Field$1 = (schemas) => {
1366
+ const self = Object.create(FieldProto);
1367
+ self.schemas = schemas;
1368
+ return self;
1369
+ };
1370
+ const Union$1 = (members, defaultVariant, variants) => {
1371
+ const VariantUnion = Union$2(members.map((member) => isSchema(member) ? member : extract$1(member, defaultVariant, { isDefault: true })));
1372
+ for (const variant of variants) Object.defineProperty(VariantUnion, variant, { value: Union$2(members.map((member) => extract$1(member, variant))) });
1373
+ return VariantUnion;
1374
+ };
1375
+ //#endregion
1376
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/unstable/schema/Model.js
1377
+ const { Class, Field, FieldExcept, FieldOnly, Struct, Union, extract, fieldEvolve } = /*#__PURE__*/ make$3({
1378
+ variants: [
1379
+ "select",
1380
+ "insert",
1381
+ "update",
1382
+ "json",
1383
+ "jsonCreate",
1384
+ "jsonUpdate"
1385
+ ],
1386
+ defaultVariant: "select"
1387
+ });
1388
+ //#endregion
1389
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/unstable/sql/SqlError.js
1390
+ /**
1391
+ * Defines structured failures for SQL clients and driver integrations.
1392
+ *
1393
+ * `SqlError` wraps the different reasons a SQL operation can fail, such as
1394
+ * connection, authentication, authorization, syntax, constraint, or transaction
1395
+ * problems. Each reason keeps the original cause, optional message and
1396
+ * operation metadata, and whether retrying may succeed. This module also
1397
+ * includes schemas, guards, a SQLite error classifier, and the
1398
+ * `ResultLengthMismatch` error used by ordered batched SQL resolvers.
1399
+ *
1400
+ * @since 4.0.0
1401
+ */
1402
+ const TypeId$2 = "~effect/sql/SqlError";
1403
+ const ReasonTypeId = "~effect/sql/SqlError/Reason";
1404
+ const ReasonFields = {
1405
+ cause: /*#__PURE__*/ Defect(),
1406
+ message: /*#__PURE__*/ optional(String$1),
1407
+ operation: /*#__PURE__*/ optional(String$1)
1408
+ };
1409
+ /**
1410
+ * SQL error reason for connection or open failures; marked retryable.
1411
+ *
1412
+ * @category errors
1413
+ * @since 4.0.0
1414
+ */
1415
+ var ConnectionError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/ConnectionError")("ConnectionError", ReasonFields)) {
1416
+ /**
1417
+ * Marks this value as a structured SQL error reason for runtime guards.
1418
+ *
1419
+ * @since 4.0.0
1420
+ */
1421
+ [ReasonTypeId] = ReasonTypeId;
1422
+ /**
1423
+ * Indicates whether retrying the failed SQL operation may succeed.
1424
+ *
1425
+ * @since 4.0.0
1426
+ */
1427
+ get isRetryable() {
1428
+ return true;
1429
+ }
1430
+ };
1431
+ /**
1432
+ * SQL error reason for authentication failures such as invalid credentials; not
1433
+ * marked retryable.
1434
+ *
1435
+ * @category errors
1436
+ * @since 4.0.0
1437
+ */
1438
+ var AuthenticationError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/AuthenticationError")("AuthenticationError", ReasonFields)) {
1439
+ /**
1440
+ * Marks this value as a structured SQL error reason for runtime guards.
1441
+ *
1442
+ * @since 4.0.0
1443
+ */
1444
+ [ReasonTypeId] = ReasonTypeId;
1445
+ /**
1446
+ * Indicates whether retrying the failed SQL operation may succeed.
1447
+ *
1448
+ * @since 4.0.0
1449
+ */
1450
+ get isRetryable() {
1451
+ return false;
1452
+ }
1453
+ };
1454
+ /**
1455
+ * SQL error reason for authorization or permission failures; not marked
1456
+ * retryable.
1457
+ *
1458
+ * @category errors
1459
+ * @since 4.0.0
1460
+ */
1461
+ var AuthorizationError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/AuthorizationError")("AuthorizationError", ReasonFields)) {
1462
+ /**
1463
+ * Marks this value as a structured SQL error reason for runtime guards.
1464
+ *
1465
+ * @since 4.0.0
1466
+ */
1467
+ [ReasonTypeId] = ReasonTypeId;
1468
+ /**
1469
+ * Indicates whether retrying the failed SQL operation may succeed.
1470
+ *
1471
+ * @since 4.0.0
1472
+ */
1473
+ get isRetryable() {
1474
+ return false;
1475
+ }
1476
+ };
1477
+ /**
1478
+ * SQL error reason for invalid SQL syntax; not marked retryable.
1479
+ *
1480
+ * @category errors
1481
+ * @since 4.0.0
1482
+ */
1483
+ var SqlSyntaxError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/SqlSyntaxError")("SqlSyntaxError", ReasonFields)) {
1484
+ /**
1485
+ * Marks this value as a structured SQL error reason for runtime guards.
1486
+ *
1487
+ * @since 4.0.0
1488
+ */
1489
+ [ReasonTypeId] = ReasonTypeId;
1490
+ /**
1491
+ * Indicates whether retrying the failed SQL operation may succeed.
1492
+ *
1493
+ * @since 4.0.0
1494
+ */
1495
+ get isRetryable() {
1496
+ return false;
1497
+ }
1498
+ };
1499
+ const UniqueViolationFields = {
1500
+ ...ReasonFields,
1501
+ constraint: String$1
1502
+ };
1503
+ /**
1504
+ * SQL error reason for a unique constraint violation, including the violated
1505
+ * constraint identifier; not marked retryable.
1506
+ *
1507
+ * @category errors
1508
+ * @since 4.0.0
1509
+ */
1510
+ var UniqueViolation = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/UniqueViolation")("UniqueViolation", UniqueViolationFields)) {
1511
+ /**
1512
+ * Marks this value as a structured SQL error reason for runtime guards.
1513
+ *
1514
+ * @since 4.0.0
1515
+ */
1516
+ [ReasonTypeId] = ReasonTypeId;
1517
+ /**
1518
+ * Indicates whether retrying the failed SQL operation may succeed.
1519
+ *
1520
+ * @since 4.0.0
1521
+ */
1522
+ get isRetryable() {
1523
+ return false;
1524
+ }
1525
+ };
1526
+ /**
1527
+ * SQL error reason for a non-unique constraint violation; not marked retryable.
1528
+ *
1529
+ * @category errors
1530
+ * @since 4.0.0
1531
+ */
1532
+ var ConstraintError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/ConstraintError")("ConstraintError", ReasonFields)) {
1533
+ /**
1534
+ * Marks this value as a structured SQL error reason for runtime guards.
1535
+ *
1536
+ * @since 4.0.0
1537
+ */
1538
+ [ReasonTypeId] = ReasonTypeId;
1539
+ /**
1540
+ * Indicates whether retrying the failed SQL operation may succeed.
1541
+ *
1542
+ * @since 4.0.0
1543
+ */
1544
+ get isRetryable() {
1545
+ return false;
1546
+ }
1547
+ };
1548
+ /**
1549
+ * SQL error reason for a database deadlock; marked retryable.
1550
+ *
1551
+ * @category errors
1552
+ * @since 4.0.0
1553
+ */
1554
+ var DeadlockError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/DeadlockError")("DeadlockError", ReasonFields)) {
1555
+ /**
1556
+ * Marks this value as a structured SQL error reason for runtime guards.
1557
+ *
1558
+ * @since 4.0.0
1559
+ */
1560
+ [ReasonTypeId] = ReasonTypeId;
1561
+ /**
1562
+ * Indicates whether retrying the failed SQL operation may succeed.
1563
+ *
1564
+ * @since 4.0.0
1565
+ */
1566
+ get isRetryable() {
1567
+ return true;
1568
+ }
1569
+ };
1570
+ /**
1571
+ * SQL error reason for a transaction serialization or isolation conflict;
1572
+ * marked retryable.
1573
+ *
1574
+ * @category errors
1575
+ * @since 4.0.0
1576
+ */
1577
+ var SerializationError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/SerializationError")("SerializationError", ReasonFields)) {
1578
+ /**
1579
+ * Marks this value as a structured SQL error reason for runtime guards.
1580
+ *
1581
+ * @since 4.0.0
1582
+ */
1583
+ [ReasonTypeId] = ReasonTypeId;
1584
+ /**
1585
+ * Indicates whether retrying the failed SQL operation may succeed.
1586
+ *
1587
+ * @since 4.0.0
1588
+ */
1589
+ get isRetryable() {
1590
+ return true;
1591
+ }
1592
+ };
1593
+ /**
1594
+ * SQL error reason for timing out while waiting on a database lock; marked
1595
+ * retryable.
1596
+ *
1597
+ * @category errors
1598
+ * @since 4.0.0
1599
+ */
1600
+ var LockTimeoutError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/LockTimeoutError")("LockTimeoutError", ReasonFields)) {
1601
+ /**
1602
+ * Marks this value as a structured SQL error reason for runtime guards.
1603
+ *
1604
+ * @since 4.0.0
1605
+ */
1606
+ [ReasonTypeId] = ReasonTypeId;
1607
+ /**
1608
+ * Indicates whether retrying the failed SQL operation may succeed.
1609
+ *
1610
+ * @since 4.0.0
1611
+ */
1612
+ get isRetryable() {
1613
+ return true;
1614
+ }
1615
+ };
1616
+ /**
1617
+ * SQL error reason for a statement or query timeout; marked retryable.
1618
+ *
1619
+ * @category errors
1620
+ * @since 4.0.0
1621
+ */
1622
+ var StatementTimeoutError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/StatementTimeoutError")("StatementTimeoutError", ReasonFields)) {
1623
+ /**
1624
+ * Marks this value as a structured SQL error reason for runtime guards.
1625
+ *
1626
+ * @since 4.0.0
1627
+ */
1628
+ [ReasonTypeId] = ReasonTypeId;
1629
+ /**
1630
+ * Indicates whether retrying the failed SQL operation may succeed.
1631
+ *
1632
+ * @since 4.0.0
1633
+ */
1634
+ get isRetryable() {
1635
+ return true;
1636
+ }
1637
+ };
1638
+ /**
1639
+ * SQL error reason for an unclassified database failure; not marked retryable.
1640
+ *
1641
+ * @category errors
1642
+ * @since 4.0.0
1643
+ */
1644
+ var UnknownError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError/UnknownError")("UnknownError", ReasonFields)) {
1645
+ /**
1646
+ * Marks this value as a structured SQL error reason for runtime guards.
1647
+ *
1648
+ * @since 4.0.0
1649
+ */
1650
+ [ReasonTypeId] = ReasonTypeId;
1651
+ /**
1652
+ * Indicates whether retrying the failed SQL operation may succeed.
1653
+ *
1654
+ * @since 4.0.0
1655
+ */
1656
+ get isRetryable() {
1657
+ return false;
1658
+ }
1659
+ };
1660
+ /**
1661
+ * Schema for encoding and decoding SQL error reasons.
1662
+ *
1663
+ * @category schemas
1664
+ * @since 4.0.0
1665
+ */
1666
+ const SqlErrorReason = /*#__PURE__*/ Union$2([
1667
+ ConnectionError,
1668
+ AuthenticationError,
1669
+ AuthorizationError,
1670
+ SqlSyntaxError,
1671
+ UniqueViolation,
1672
+ ConstraintError,
1673
+ DeadlockError,
1674
+ SerializationError,
1675
+ LockTimeoutError,
1676
+ StatementTimeoutError,
1677
+ UnknownError
1678
+ ]);
1679
+ /**
1680
+ * Error wrapper for SQL failures whose `message`, `cause`, and `isRetryable`
1681
+ * values are derived from its `SqlErrorReason`.
1682
+ *
1683
+ * @category errors
1684
+ * @since 4.0.0
1685
+ */
1686
+ var SqlError = class extends (/*#__PURE__*/ TaggedError("effect/sql/SqlError")("SqlError", { reason: SqlErrorReason })) {
1687
+ /**
1688
+ * Marks this value as the top-level SQL error wrapper for runtime guards.
1689
+ *
1690
+ * @since 4.0.0
1691
+ */
1692
+ [TypeId$2] = TypeId$2;
1693
+ /**
1694
+ * Exposes the structured SQL reason as the JavaScript error cause.
1695
+ *
1696
+ * @since 4.0.0
1697
+ */
1698
+ cause = this.reason;
1699
+ /**
1700
+ * Uses the reason message when present, otherwise falls back to the reason tag.
1701
+ *
1702
+ * @since 4.0.0
1703
+ */
1704
+ get message() {
1705
+ return this.reason.message || this.reason._tag;
1706
+ }
1707
+ /**
1708
+ * Delegates retryability to the underlying SQL error reason.
1709
+ *
1710
+ * @since 4.0.0
1711
+ */
1712
+ get isRetryable() {
1713
+ return this.reason.isRetryable;
1714
+ }
1715
+ };
1716
+ const sqliteCodeFromCause = (cause) => {
1717
+ if (!hasProperty(cause, "code")) return;
1718
+ const code = cause.code;
1719
+ return typeof code === "string" || typeof code === "number" ? code : void 0;
1720
+ };
1721
+ const sqliteNumericCodeFromCause = (cause) => {
1722
+ const code = sqliteCodeFromCause(cause);
1723
+ if (typeof code === "number") return code;
1724
+ if (!hasProperty(cause, "errno")) return;
1725
+ const errno = cause.errno;
1726
+ return typeof errno === "number" ? errno : void 0;
1727
+ };
1728
+ const matchesSqliteNumericCode = (cause, expected) => {
1729
+ if (sqliteCodeFromCause(cause) === expected) return true;
1730
+ if (!hasProperty(cause, "errno")) return false;
1731
+ return cause.errno === expected;
1732
+ };
1733
+ const matchesSqliteCode = (code, expected) => code === expected || code.startsWith(expected + "_");
1734
+ const UNKNOWN_CONSTRAINT = "unknown";
1735
+ const SQLITE_CONSTRAINT_UNIQUE = "SQLITE_CONSTRAINT_UNIQUE";
1736
+ const SQLITE_CONSTRAINT_UNIQUE_CODE = 2067;
1737
+ const normalizeConstraintIdentifier = (identifier) => {
1738
+ if (typeof identifier !== "string") return UNKNOWN_CONSTRAINT;
1739
+ const trimmed = identifier.trim();
1740
+ return trimmed.length === 0 ? UNKNOWN_CONSTRAINT : trimmed;
1741
+ };
1742
+ const sqliteUniqueConstraintFromCause = (cause) => {
1743
+ if (hasProperty(cause, "constraint")) return normalizeConstraintIdentifier(cause.constraint);
1744
+ if (!hasProperty(cause, "message")) return UNKNOWN_CONSTRAINT;
1745
+ const message = cause.message;
1746
+ if (typeof message !== "string") return UNKNOWN_CONSTRAINT;
1747
+ const index = message.indexOf("UNIQUE constraint failed:");
1748
+ return index === -1 ? UNKNOWN_CONSTRAINT : normalizeConstraintIdentifier(message.slice(index + 25));
1749
+ };
1750
+ /**
1751
+ * Classifies a native SQLite error cause into a `SqlErrorReason` using its
1752
+ * `code` or `errno`, with optional message and operation metadata.
1753
+ *
1754
+ * @category converting
1755
+ * @since 4.0.0
1756
+ */
1757
+ const classifySqliteError = (cause, { message, operation } = {}) => {
1758
+ const props = {
1759
+ cause,
1760
+ message,
1761
+ operation
1762
+ };
1763
+ const code = sqliteCodeFromCause(cause);
1764
+ const numericCode = sqliteNumericCodeFromCause(cause);
1765
+ if (code === SQLITE_CONSTRAINT_UNIQUE || matchesSqliteNumericCode(cause, SQLITE_CONSTRAINT_UNIQUE_CODE)) return new UniqueViolation({
1766
+ ...props,
1767
+ constraint: sqliteUniqueConstraintFromCause(cause)
1768
+ });
1769
+ if (typeof code === "string") {
1770
+ if (matchesSqliteCode(code, "SQLITE_AUTH")) return new AuthenticationError(props);
1771
+ if (matchesSqliteCode(code, "SQLITE_PERM")) return new AuthorizationError(props);
1772
+ if (matchesSqliteCode(code, "SQLITE_CONSTRAINT")) return new ConstraintError(props);
1773
+ if (matchesSqliteCode(code, "SQLITE_BUSY") || matchesSqliteCode(code, "SQLITE_LOCKED")) return new LockTimeoutError(props);
1774
+ if (matchesSqliteCode(code, "SQLITE_CANTOPEN")) return new ConnectionError(props);
1775
+ }
1776
+ if (typeof numericCode === "number") switch (numericCode & 255) {
1777
+ case 23: return new AuthenticationError(props);
1778
+ case 3: return new AuthorizationError(props);
1779
+ case 19: return new ConstraintError(props);
1780
+ case 5:
1781
+ case 6: return new LockTimeoutError(props);
1782
+ case 14: return new ConnectionError(props);
1783
+ default: return new UnknownError(props);
1784
+ }
1785
+ return new UnknownError(props);
1786
+ };
1787
+ /**
1788
+ * Error raised when an ordered batched SQL resolver receives a different number
1789
+ * of result rows than requests.
1790
+ *
1791
+ * @category errors
1792
+ * @since 4.0.0
1793
+ */
1794
+ var ResultLengthMismatch = class extends (/*#__PURE__*/ TaggedError("effect/sql/ResultLengthMismatch")("ResultLengthMismatch", {
1795
+ expected: Natural,
1796
+ actual: Natural
1797
+ })) {
1798
+ /**
1799
+ * Explains the mismatch between expected and actual batched SQL result counts.
1800
+ *
1801
+ * @since 4.0.0
1802
+ */
1803
+ get message() {
1804
+ return `Expected ${this.expected} results but got ${this.actual}`;
1805
+ }
1806
+ };
1807
+ //#endregion
1808
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/unstable/sql/SqlResolver.js
1809
+ /**
1810
+ * Schema-aware `RequestResolver` helpers for SQL-backed data loading.
1811
+ *
1812
+ * This module represents each lookup or mutation as a `SqlRequest` and batches
1813
+ * concurrent requests into SQL operations. Request payloads are encoded with the
1814
+ * request schema before `execute` is called, and returned rows are decoded with
1815
+ * the result schema before requests are completed. It provides ordered,
1816
+ * grouped, id-based, and side-effect-only resolver constructors, and keeps
1817
+ * batches separated by the active SQL transaction connection.
1818
+ *
1819
+ * @since 4.0.0
1820
+ */
1821
+ const SqlRequestProto = {
1822
+ ...Class$2.prototype,
1823
+ [symbol](that) {
1824
+ return equals(this.payload, that.payload);
1825
+ },
1826
+ [symbol$1]() {
1827
+ return hash(this.payload);
1828
+ }
1829
+ };
1830
+ /**
1831
+ * Runs a payload as a `SqlRequest` through a request resolver, either directly
1832
+ * with a payload and resolver or curried by resolver.
1833
+ *
1834
+ * @category running
1835
+ * @since 4.0.0
1836
+ */
1837
+ const request = function() {
1838
+ if (arguments.length === 1) {
1839
+ const resolver = arguments[0];
1840
+ return (payload) => request$1(SqlRequest(payload), resolver);
1841
+ }
1842
+ return request$1(SqlRequest(arguments[0]), arguments[1]);
1843
+ };
1844
+ /**
1845
+ * Constructs a `SqlRequest` from a payload. Equality and hashing are based on
1846
+ * the payload so equal requests can be batched and deduplicated.
1847
+ *
1848
+ * @category constructors
1849
+ * @since 4.0.0
1850
+ */
1851
+ const SqlRequest = (payload) => {
1852
+ const self = Object.create(SqlRequestProto);
1853
+ self.payload = payload;
1854
+ return self;
1855
+ };
1856
+ /**
1857
+ * Creates a resolver for a SQL query with a request schema and a result schema.
1858
+ *
1859
+ * **Details**
1860
+ *
1861
+ * The request schema is used to validate the input of the query, and the result
1862
+ * schema is used to validate the output of the query. Results are mapped to the
1863
+ * requests in order, so the length of the results must match the length of the
1864
+ * requests.
1865
+ *
1866
+ * @category resolvers
1867
+ * @since 4.0.0
1868
+ */
1869
+ const ordered = (options) => {
1870
+ const decodeArray = decodeUnknownEffect(ArraySchema(options.Result));
1871
+ return makeGrouped({
1872
+ key: transactionKey,
1873
+ resolver: fnUntraced(function* (entries) {
1874
+ const [inputs, encodedEntries] = yield* partitionRequests(entries, options.Request);
1875
+ if (!isArrayNonEmpty(inputs)) return;
1876
+ const results = yield* options.execute(inputs).pipe(provideContext(entries[0].context));
1877
+ if (results.length !== inputs.length) return yield* new ResultLengthMismatch({
1878
+ expected: inputs.length,
1879
+ actual: results.length
1880
+ });
1881
+ const decodedResults = yield* decodeArray(results).pipe(provideContext(entries[0].context));
1882
+ for (let i = 0; i < encodedEntries.length; i++) encodedEntries[i].completeUnsafe(succeed$2(decodedResults[i]));
1883
+ })
1884
+ });
1885
+ };
1886
+ /**
1887
+ * Creates a batched resolver that fetches rows for encoded ids, decodes
1888
+ * results, completes each matching request using `ResultId`, and fails missing
1889
+ * ids with `NoSuchElementError`.
1890
+ *
1891
+ * @category resolvers
1892
+ * @since 4.0.0
1893
+ */
1894
+ const findById = (options) => {
1895
+ const decodeResults = decodeUnknownEffect(ArraySchema(options.Result));
1896
+ return makeGrouped({
1897
+ key: transactionKey,
1898
+ resolver: fnUntraced(function* (entries) {
1899
+ const [inputs, idMap] = yield* partitionRequestsById(entries, options.Id);
1900
+ if (!isArrayNonEmpty(inputs)) return;
1901
+ const results = yield* options.execute(inputs).pipe(provideContext(entries[0].context));
1902
+ const decodedResults = yield* decodeResults(results).pipe(provideContext(entries[0].context));
1903
+ for (let i = 0; i < decodedResults.length; i++) {
1904
+ const result = decodedResults[i];
1905
+ const id = options.ResultId(result, results[i]);
1906
+ const request = get$2(idMap, id);
1907
+ if (request._tag === "None") continue;
1908
+ remove(idMap, id);
1909
+ request.value.completeUnsafe(succeed$2(result));
1910
+ }
1911
+ if (isEmpty(idMap)) return;
1912
+ forEach$1(idMap, (request) => {
1913
+ request.completeUnsafe(constNoSuchElement);
1914
+ });
1915
+ })
1916
+ });
1917
+ };
1918
+ const void_ = (options) => makeGrouped({
1919
+ key: transactionKey,
1920
+ resolver: fnUntraced(function* (entries) {
1921
+ const [inputs] = yield* partitionRequests(entries, options.Request);
1922
+ if (!isArrayNonEmpty(inputs)) return;
1923
+ yield* options.execute(inputs).pipe(provideContext(entries[0].context));
1924
+ for (let i = 0; i < entries.length; i++) entries[i].completeUnsafe(void_$3);
1925
+ })
1926
+ });
1927
+ const constNoSuchElement = /*#__PURE__*/ fail(/*#__PURE__*/ new NoSuchElementError());
1928
+ const partitionRequests = function* (requests, schema) {
1929
+ const len = requests.length;
1930
+ const inputs = empty();
1931
+ const encodedEntries = empty();
1932
+ let entry;
1933
+ const encode = encodeEffect(schema);
1934
+ const handle = matchCauseEager({
1935
+ onFailure(cause) {
1936
+ entry.completeUnsafe(failCause(cause));
1937
+ },
1938
+ onSuccess(value) {
1939
+ inputs.push(value);
1940
+ encodedEntries.push(entry);
1941
+ }
1942
+ });
1943
+ for (let i = 0; i < len; i++) {
1944
+ entry = requests[i];
1945
+ yield provideContext(handle(encode(entry.request.payload)), entry.context);
1946
+ }
1947
+ return [inputs, encodedEntries];
1948
+ };
1949
+ const partitionRequestsById = function* (requests, schema) {
1950
+ const len = requests.length;
1951
+ const inputs = empty();
1952
+ const byIdMap = empty$1();
1953
+ for (let i = 0; i < len; i++) {
1954
+ const entry = requests[i];
1955
+ const existing = get$2(byIdMap, entry.request.payload);
1956
+ if (isSome(existing)) {
1957
+ const previous = existing.value;
1958
+ set(byIdMap, entry.request.payload, {
1959
+ ...previous,
1960
+ completeUnsafe(exit) {
1961
+ previous.completeUnsafe(exit);
1962
+ entry.completeUnsafe(exit);
1963
+ }
1964
+ });
1965
+ } else set(byIdMap, entry.request.payload, entry);
1966
+ }
1967
+ const encode = encodeEffect(schema);
1968
+ for (const [, entry] of byIdMap) yield* provideContext(matchCauseEager(encode(entry.request.payload), {
1969
+ onFailure(cause) {
1970
+ entry.completeUnsafe(failCause(cause));
1971
+ },
1972
+ onSuccess(value) {
1973
+ inputs.push(value);
1974
+ }
1975
+ }), entry.context);
1976
+ return [inputs, byIdMap];
1977
+ };
1978
+ function transactionKey(entry) {
1979
+ const client = getOrUndefined(entry.context, SqlClient);
1980
+ if (!client) return void 0;
1981
+ const conn = getOrUndefined(entry.context, client.transactionService);
1982
+ if (!conn) return void 0;
1983
+ return byReferenceUnsafe(conn);
1984
+ }
1985
+ //#endregion
1986
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/unstable/sql/SqlSchema.js
1987
+ /**
1988
+ * Builds a query function that encodes the request and decodes all result rows,
1989
+ * allowing an empty result set.
1990
+ *
1991
+ * **When to use**
1992
+ *
1993
+ * Use when you need to run a query that may return zero or more rows and
1994
+ * represent an empty result as an empty array.
1995
+ *
1996
+ * @see {@link findNonEmpty} for queries where an empty result is a failure
1997
+ *
1998
+ * @category constructors
1999
+ * @since 4.0.0
2000
+ */
2001
+ const findAll = (options) => {
2002
+ const encodeRequest = encodeEffect(options.Request);
2003
+ const decode = decodeUnknownEffect(mutable(ArraySchema(options.Result)));
2004
+ return (request) => flatMap(flatMap(encodeRequest(request), options.execute), decode);
2005
+ };
2006
+ //#endregion
2007
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/unstable/sql/SqlModel.js
2008
+ /**
2009
+ * Creates batched request resolvers for a schema model's insert, insert-void,
2010
+ * find-by-id, and delete operations, honoring the optional soft-delete column.
2011
+ *
2012
+ * @category constructors
2013
+ * @since 4.0.0
2014
+ */
2015
+ const makeResolvers = (Model, options) => gen(function* () {
2016
+ const sql = yield* SqlClient;
2017
+ const idSchema = Model.fields[options.idColumn];
2018
+ const idColumn = options.idColumn;
2019
+ const softDeleteColumn = options.softDeleteColumn;
2020
+ const withSoftDeleteFilter = (where) => softDeleteColumn === void 0 ? where : sql.and([where, sql`${sql(softDeleteColumn)} is null`]);
2021
+ const setSoftDeleted = softDeleteColumn === void 0 ? void 0 : sql`${sql(softDeleteColumn)} = CURRENT_TIMESTAMP`;
2022
+ return {
2023
+ insert: ordered({
2024
+ Request: Model.insert,
2025
+ Result: Model,
2026
+ execute: (request) => sql.onDialectOrElse({
2027
+ mysql: () => forEach(request, (request) => sql`insert into ${sql(options.tableName)} ${sql.insert(request)};
2028
+ select * from ${sql(options.tableName)} where ${withSoftDeleteFilter(sql`${sql(idColumn)} = LAST_INSERT_ID()`)};`.unprepared.pipe(map(([, results]) => results[0])), { concurrency: 10 }),
2029
+ orElse: () => sql`insert into ${sql(options.tableName)} ${sql.insert(request).returning("*")}`
2030
+ })
2031
+ }).pipe(withSpan$1(`${options.spanPrefix}.insertResolver`)),
2032
+ insertVoid: void_({
2033
+ Request: Model.insert,
2034
+ execute: (request) => sql`insert into ${sql(options.tableName)} ${sql.insert(request)}`
2035
+ }).pipe(withSpan$1(`${options.spanPrefix}.insertVoidResolver`)),
2036
+ findById: findById({
2037
+ Id: idSchema,
2038
+ Result: Model,
2039
+ ResultId(request) {
2040
+ return request[idColumn];
2041
+ },
2042
+ execute: (ids) => sql`select * from ${sql(options.tableName)} where ${withSoftDeleteFilter(sql.in(idColumn, ids))}`
2043
+ }).pipe(withSpan$1(`${options.spanPrefix}.findByIdResolver`)),
2044
+ delete: void_({
2045
+ Request: idSchema,
2046
+ execute: (ids) => softDeleteColumn === void 0 ? sql`delete from ${sql(options.tableName)} where ${sql.in(idColumn, ids)}` : sql`update ${sql(options.tableName)} set ${setSoftDeleted} where ${withSoftDeleteFilter(sql.in(idColumn, ids))}`
2047
+ }).pipe(withSpan$1(`${options.spanPrefix}.deleteResolver`))
2048
+ };
2049
+ });
2050
+ //#endregion
2051
+ //#region src/ChunkRepo.ts
2052
+ /** @effect-diagnostics schemaNumber:off */
2053
+ /**
2054
+ * @since 1.0.0
2055
+ * @category Models
2056
+ */
2057
+ const ChunkId = Number$1.pipe(brand("ChunkRepo/ChunkId"));
2058
+ /**
2059
+ * @since 1.0.0
2060
+ * @category Models
2061
+ */
2062
+ const SyncId = String$1.pipe(brand("ChunkRepo/SyncId"));
2063
+ /**
2064
+ * @since 1.0.0
2065
+ * @category Models
2066
+ */
2067
+ const Float32ArraySchema = instanceOf(Float32Array);
2068
+ /**
2069
+ * @since 1.0.0
2070
+ * @category Models
2071
+ */
2072
+ const Float32ArrayFromArray = ArraySchema(Number$1).pipe(decodeTo(Float32ArraySchema, transform$1({
2073
+ decode: (arr) => new Float32Array(arr),
2074
+ encode: (array) => Array.from(array)
2075
+ })));
2076
+ /**
2077
+ * @since 1.0.0
2078
+ * @category Models
2079
+ */
2080
+ const Float32ArrayField = Field({
2081
+ insert: Float32ArraySchema,
2082
+ update: Float32ArraySchema,
2083
+ jsonCreate: Float32ArrayFromArray,
2084
+ jsonUpdate: Float32ArrayFromArray
2085
+ });
2086
+ /**
2087
+ * @since 1.0.0
2088
+ * @category Models
2089
+ */
2090
+ var Chunk = class extends Class("Chunk")({
2091
+ id: ChunkId.pipe(FieldExcept(["insert", "jsonCreate"])),
2092
+ path: String$1,
2093
+ content: String$1,
2094
+ hash: String$1,
2095
+ vector: Float32ArrayField,
2096
+ syncId: SyncId
2097
+ }) {};
2098
+ /**
2099
+ * @since 1.0.0
2100
+ * @category Services
2101
+ */
2102
+ var ChunkRepo = class extends Service()("clanka/ChunkRepo") {};
2103
+ /**
2104
+ * @since 1.0.0
2105
+ * @category Errors
2106
+ */
2107
+ var ChunkRepoError = class extends TaggedError()("ChunkRepoError", { reason: Union$2([SqlError]) }) {
2108
+ cause = this.reason;
2109
+ message = this.reason.message;
2110
+ };
2111
+ /**
2112
+ * @since 1.0.0
2113
+ * @category Layers
2114
+ */
2115
+ const layer$4 = effect(ChunkRepo, gen(function* () {
2116
+ const sql = yield* SqlClient;
2117
+ const dimensions = yield* Dimensions;
2118
+ yield* gen(function* () {
2119
+ yield* sql`CREATE VIRTUAL TABLE IF NOT EXISTS chunk_vectors USING vec0(
2120
+ vector float[${sql.literal(String(dimensions))}]
2121
+ )`;
2122
+ yield* sql`CREATE TRIGGER IF NOT EXISTS chunks_vector_insert
2123
+ AFTER INSERT ON chunks
2124
+ BEGIN
2125
+ INSERT INTO chunk_vectors(rowid, vector) VALUES (new.id, new.vector);
2126
+ END`;
2127
+ yield* sql`CREATE TRIGGER IF NOT EXISTS chunks_vector_update
2128
+ AFTER UPDATE OF vector ON chunks
2129
+ BEGIN
2130
+ DELETE FROM chunk_vectors WHERE rowid = old.id;
2131
+ INSERT INTO chunk_vectors(rowid, vector) VALUES (new.id, new.vector);
2132
+ END`;
2133
+ yield* sql`CREATE TRIGGER IF NOT EXISTS chunks_vector_delete
2134
+ AFTER DELETE ON chunks
2135
+ BEGIN
2136
+ DELETE FROM chunk_vectors WHERE rowid = old.id;
2137
+ END`;
2138
+ yield* sql`DELETE FROM chunk_vectors
2139
+ WHERE rowid NOT IN (SELECT id FROM chunks)`;
2140
+ yield* sql`INSERT INTO chunk_vectors(rowid, vector)
2141
+ SELECT id, vector FROM chunks
2142
+ WHERE id NOT IN (SELECT rowid FROM chunk_vectors)`;
2143
+ }).pipe(sql.withTransaction);
2144
+ const loaders = yield* makeResolvers(Chunk, {
2145
+ tableName: "chunks",
2146
+ idColumn: "id",
2147
+ spanPrefix: "ChunkRepo"
2148
+ });
2149
+ const search = findAll({
2150
+ Request: Struct$2({
2151
+ vector: Float32ArraySchema,
2152
+ limit: Number$1
2153
+ }),
2154
+ Result: Chunk,
2155
+ execute: ({ vector, limit }) => sql`
2156
+ select chunks.id, chunks.path, chunks.content, chunks.hash, chunks.syncId
2157
+ from chunk_vectors
2158
+ JOIN chunks ON chunks.id = chunk_vectors.rowid
2159
+ WHERE chunk_vectors.vector MATCH ${vector}
2160
+ AND k = CAST(${limit} AS INTEGER)
2161
+ ORDER BY chunk_vectors.distance
2162
+ `
2163
+ });
2164
+ const exists = findById({
2165
+ Id: String$1,
2166
+ Result: Struct$2({
2167
+ id: ChunkId,
2168
+ hash: String$1
2169
+ }),
2170
+ ResultId(result) {
2171
+ return result.hash;
2172
+ },
2173
+ execute: (hashes) => sql`select id, hash from chunks where ${sql.in("hash", hashes)}`
2174
+ }).pipe(setDelay(5));
2175
+ const insertResolver = loaders.insert.pipe(setDelay(5));
2176
+ const findByIdResolver = loaders.findById.pipe(setDelay(5));
2177
+ return ChunkRepo.of({
2178
+ insert: (insert) => request(insert, insertResolver).pipe(catchTags({
2179
+ SchemaError: die,
2180
+ ResultLengthMismatch: die
2181
+ }, (reason) => fail$1(new ChunkRepoError({ reason })))),
2182
+ findById: (id) => request(id, findByIdResolver).pipe(catchTags({
2183
+ SchemaError: die,
2184
+ SqlError: (reason) => fail$1(new ChunkRepoError({ reason }))
2185
+ })),
2186
+ exists: (hash) => request(hash, exists).pipe(map((result) => result.id), catchNoSuchElement, catchTags({
2187
+ SqlError: (reason) => fail$1(new ChunkRepoError({ reason })),
2188
+ SchemaError: die
2189
+ })),
2190
+ search: fn("ChunkRepo.search")(function* (options) {
2191
+ return yield* search(options).pipe(catchTags({
2192
+ SqlError: (reason) => fail$1(new ChunkRepoError({ reason })),
2193
+ SchemaError: die
2194
+ }));
2195
+ }),
2196
+ quantize: void_$1,
2197
+ setSyncId: (chunkId, syncId) => sql`update chunks set syncId = ${syncId} where id = ${chunkId}`.pipe(mapError((reason) => new ChunkRepoError({ reason }))),
2198
+ deleteByPath: (path) => sql`delete from chunks where path = ${path}`.pipe(mapError((reason) => new ChunkRepoError({ reason }))),
2199
+ deleteForSyncId: (syncId) => sql`delete from chunks where syncId != ${syncId}`.pipe(mapError((reason) => new ChunkRepoError({ reason })))
2200
+ });
2201
+ }));
2202
+ //#endregion
2203
+ //#region src/CodeChunker.ts
2204
+ /**
2205
+ * @since 1.0.0
2206
+ */
2207
+ /**
2208
+ * @since 1.0.0
2209
+ * @category Services
2210
+ */
2211
+ var CodeChunker = class extends Service()("clanka/CodeChunker") {};
2212
+ const sourceExtensions = /* @__PURE__ */ new Set([
2213
+ "c",
2214
+ "cc",
2215
+ "cpp",
2216
+ "cs",
2217
+ "css",
2218
+ "cts",
2219
+ "cxx",
2220
+ "go",
2221
+ "gql",
2222
+ "graphql",
2223
+ "h",
2224
+ "hpp",
2225
+ "html",
2226
+ "ini",
2227
+ "java",
2228
+ "js",
2229
+ "jsx",
2230
+ "kt",
2231
+ "kts",
2232
+ "less",
2233
+ "lua",
2234
+ "mjs",
2235
+ "mts",
2236
+ "php",
2237
+ "py",
2238
+ "rb",
2239
+ "rs",
2240
+ "sass",
2241
+ "scala",
2242
+ "scss",
2243
+ "sh",
2244
+ "sql",
2245
+ "svelte",
2246
+ "swift",
2247
+ "ts",
2248
+ "tsx",
2249
+ "vue",
2250
+ "xml",
2251
+ "zsh"
2252
+ ]);
2253
+ const documentationExtensions = /* @__PURE__ */ new Set([
2254
+ "adoc",
2255
+ "asciidoc",
2256
+ "md",
2257
+ "mdx",
2258
+ "rst",
2259
+ "txt"
2260
+ ]);
2261
+ const ignoredDirectories = /* @__PURE__ */ new Set([
2262
+ ".git",
2263
+ ".next",
2264
+ ".nuxt",
2265
+ ".svelte-kit",
2266
+ ".turbo",
2267
+ "build",
2268
+ "coverage",
2269
+ "dist",
2270
+ "node_modules",
2271
+ "target"
2272
+ ]);
2273
+ const normalizePath$1 = (path) => path.replace(/\\/g, "/");
2274
+ const normalizeText = (content) => content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
2275
+ const meaningfulLinePattern = /[^\s\p{P}]/u;
2276
+ const isMeaningfulLine = (line) => meaningfulLinePattern.test(line);
2277
+ const languageByExtension = /* @__PURE__ */ new Map([
2278
+ ["js", TreeSitterJavaScript],
2279
+ ["jsx", TreeSitterJavaScript],
2280
+ ["ts", TreeSitterTypeScript.typescript],
2281
+ ["tsx", TreeSitterTypeScript.tsx]
2282
+ ]);
2283
+ /**
2284
+ * @since 1.0.0
2285
+ * @category Predicates
2286
+ */
2287
+ const isProbablyMinified = (content) => {
2288
+ const normalized = normalizeText(content);
2289
+ if (normalized.length < 2e3) return false;
2290
+ const lines = normalized.split("\n");
2291
+ if (lines.length <= 2) return true;
2292
+ let longLines = 0;
2293
+ for (const line of lines) if (line.length >= 300) longLines++;
2294
+ return lines.length <= 20 && longLines / lines.length >= .8;
2295
+ };
2296
+ /**
2297
+ * @since 1.0.0
2298
+ * @category Predicates
2299
+ */
2300
+ const isMeaningfulFile = (path) => {
2301
+ const parts = normalizePath$1(path).toLowerCase().split("/");
2302
+ const fileName = parts.at(-1);
2303
+ if (fileName === void 0 || fileName.length === 0) return false;
2304
+ if (parts.some((part) => ignoredDirectories.has(part))) return false;
2305
+ if (/\.min\.(?:css|js)$/i.test(fileName)) return false;
2306
+ const extensionIndex = fileName.lastIndexOf(".");
2307
+ if (extensionIndex === -1) return false;
2308
+ const extension = fileName.slice(extensionIndex + 1);
2309
+ return sourceExtensions.has(extension) || documentationExtensions.has(extension);
2310
+ };
2311
+ const resolveChunkSettings = (options) => {
2312
+ const chunkSize = Math.max(1, options.chunkSize);
2313
+ return {
2314
+ chunkSize,
2315
+ chunkOverlap: Math.max(0, Math.min(chunkSize - 1, options.chunkOverlap)),
2316
+ chunkMaxCharacters: options.chunkMaxCharacters !== void 0 && Number.isFinite(options.chunkMaxCharacters) ? Math.max(1, Math.floor(options.chunkMaxCharacters)) : Number.POSITIVE_INFINITY
2317
+ };
2318
+ };
2319
+ const getPathExtension = (path) => {
2320
+ const fileName = path.split("/").at(-1);
2321
+ if (fileName === void 0) return;
2322
+ const extensionIndex = fileName.lastIndexOf(".");
2323
+ if (extensionIndex === -1) return;
2324
+ return fileName.slice(extensionIndex + 1).toLowerCase();
2325
+ };
2326
+ const resolveAstLanguage = (path) => {
2327
+ const extension = getPathExtension(path);
2328
+ if (extension === void 0) return;
2329
+ return languageByExtension.get(extension);
2330
+ };
2331
+ const lineRangeFromNode = (node) => {
2332
+ const startLine = node.startPosition.row + 1;
2333
+ return {
2334
+ startLine,
2335
+ endLine: Math.max(startLine, node.endPosition.row + 1)
2336
+ };
2337
+ };
2338
+ const hasOnlyWhitespaceLines = (lines, startLine, endLine) => {
2339
+ if (startLine > endLine) return true;
2340
+ for (let lineIndex = startLine; lineIndex <= endLine; lineIndex++) if ((lines[lineIndex - 1] ?? "").trim().length > 0) return false;
2341
+ return true;
2342
+ };
2343
+ const lineRangeWithLeadingComments = (node, siblings, nodeIndex, lines) => {
2344
+ const baseRange = lineRangeFromNode(node);
2345
+ let startLine = baseRange.startLine;
2346
+ for (let index = nodeIndex - 1; index >= 0; index--) {
2347
+ const sibling = siblings[index];
2348
+ if (sibling.type !== "comment") break;
2349
+ const commentRange = lineRangeFromNode(sibling);
2350
+ if (!hasOnlyWhitespaceLines(lines, commentRange.endLine + 1, startLine - 1)) break;
2351
+ startLine = commentRange.startLine;
2352
+ }
2353
+ return {
2354
+ startLine,
2355
+ endLine: baseRange.endLine
2356
+ };
2357
+ };
2358
+ const normalizeLineRange = (range, lineCount) => {
2359
+ const startLine = Math.max(1, Math.min(lineCount, range.startLine));
2360
+ const endLine = Math.max(1, Math.min(lineCount, range.endLine));
2361
+ if (endLine < startLine) return;
2362
+ return {
2363
+ startLine,
2364
+ endLine
2365
+ };
2366
+ };
2367
+ const lineLengthPrefixSums = (lines) => {
2368
+ const sums = [0];
2369
+ for (let index = 0; index < lines.length; index++) sums.push(sums[index] + lines[index].length);
2370
+ return sums;
2371
+ };
2372
+ const lineRangeCharacterLength = (prefixSums, range) => prefixSums[range.endLine] - prefixSums[range.startLine - 1] + (range.endLine - range.startLine);
2373
+ const resolveSegmentEndLine = (options) => {
2374
+ if (options.settings.chunkMaxCharacters === Number.POSITIVE_INFINITY) return options.maxEndLine;
2375
+ let endLine = options.maxEndLine;
2376
+ while (endLine > options.startLine && lineRangeCharacterLength(options.prefixSums, {
2377
+ startLine: options.startLine,
2378
+ endLine
2379
+ }) > options.settings.chunkMaxCharacters) endLine--;
2380
+ return endLine;
2381
+ };
2382
+ const splitRange = (range, settings, prefixSums) => {
2383
+ if (range.endLine - range.startLine + 1 <= settings.chunkSize && lineRangeCharacterLength(prefixSums, range) <= settings.chunkMaxCharacters) return [range];
2384
+ const out = [];
2385
+ for (let startLine = range.startLine; startLine <= range.endLine;) {
2386
+ const maxEndLine = Math.min(range.endLine, startLine + settings.chunkSize - 1);
2387
+ const endLine = resolveSegmentEndLine({
2388
+ startLine,
2389
+ maxEndLine,
2390
+ settings,
2391
+ prefixSums
2392
+ });
2393
+ out.push({
2394
+ startLine,
2395
+ endLine
2396
+ });
2397
+ if (endLine >= range.endLine) break;
2398
+ startLine = Math.max(startLine + 1, endLine - settings.chunkOverlap + 1);
2399
+ }
2400
+ return out;
2401
+ };
2402
+ const nodeText = (node) => {
2403
+ if (node === null) return;
2404
+ const value = node.text.trim().replace(/\s+/g, " ");
2405
+ return value.length === 0 ? void 0 : value;
2406
+ };
2407
+ const nodeFieldText = (node, fieldName) => nodeText(node.childForFieldName(fieldName));
2408
+ const isNamespaceNode = (node) => node.type === "internal_module" || node.type === "module";
2409
+ const unwrapDeclarationNode = (node) => {
2410
+ let current = node;
2411
+ while (true) {
2412
+ if (current.type === "export_statement") {
2413
+ const declaration = current.childForFieldName("declaration") ?? current.namedChildren[0];
2414
+ if (declaration === void 0) return current;
2415
+ current = declaration;
2416
+ continue;
2417
+ }
2418
+ if (current.type === "ambient_declaration") {
2419
+ const declaration = current.namedChildren.find((child) => child.type.endsWith("_declaration") || isNamespaceNode(child));
2420
+ if (declaration === void 0) return current;
2421
+ current = declaration;
2422
+ continue;
2423
+ }
2424
+ return current;
2425
+ }
2426
+ };
2427
+ const variableDeclarators = (node) => node.namedChildren.filter((child) => child.type === "variable_declarator");
2428
+ const variableTypeFromDeclarator = (node) => {
2429
+ const value = node.childForFieldName("value");
2430
+ if (value !== null && value.type.includes("function")) return "function";
2431
+ return "variable";
2432
+ };
2433
+ const variableTypeFromDeclaration = (node) => {
2434
+ if (variableDeclarators(node).some((declarator) => variableTypeFromDeclarator(declarator) === "function")) return "function";
2435
+ return "variable";
2436
+ };
2437
+ const chunkTypeFromNode = (node) => {
2438
+ switch (node.type) {
2439
+ case "class_declaration": return "class";
2440
+ case "enum_declaration": return "enum";
2441
+ case "function_declaration":
2442
+ case "generator_function_declaration": return "function";
2443
+ case "internal_module":
2444
+ case "module": return "namespace";
2445
+ case "interface_declaration": return "interface";
2446
+ case "generator_method_definition":
2447
+ case "method_definition": return "method";
2448
+ case "type_alias_declaration": return "type-alias";
2449
+ case "lexical_declaration":
2450
+ case "variable_declaration": return variableTypeFromDeclaration(node);
2451
+ case "variable_declarator": return variableTypeFromDeclarator(node);
2452
+ default: return;
2453
+ }
2454
+ };
2455
+ const variableNamesFromDeclaration = (node) => {
2456
+ const names = variableDeclarators(node).map((declarator) => nodeFieldText(declarator, "name")).filter((name) => name !== void 0);
2457
+ if (names.length === 0) return;
2458
+ return names.join(", ");
2459
+ };
2460
+ const nameFromNode = (node) => {
2461
+ switch (node.type) {
2462
+ case "class_declaration":
2463
+ case "enum_declaration":
2464
+ case "function_declaration":
2465
+ case "generator_function_declaration":
2466
+ case "internal_module":
2467
+ case "interface_declaration":
2468
+ case "module":
2469
+ case "generator_method_definition":
2470
+ case "method_definition":
2471
+ case "type_alias_declaration":
2472
+ case "variable_declarator": return nodeFieldText(node, "name");
2473
+ case "lexical_declaration":
2474
+ case "variable_declaration": return variableNamesFromDeclaration(node);
2475
+ default: return;
2476
+ }
2477
+ };
2478
+ const formatParent = (type, name) => {
2479
+ if (type === void 0 && name === void 0) return;
2480
+ if (type === void 0) return name;
2481
+ if (name === void 0) return type;
2482
+ return type + " " + name;
2483
+ };
2484
+ const collectClassMethodRanges = (classNode, parent, lines) => {
2485
+ const body = classNode.childForFieldName("body");
2486
+ if (body === null) return [];
2487
+ const out = [];
2488
+ for (let index = 0; index < body.namedChildren.length; index++) {
2489
+ const child = body.namedChildren[index];
2490
+ if (!child.type.includes("method")) continue;
2491
+ out.push({
2492
+ ...lineRangeWithLeadingComments(child, body.namedChildren, index, lines),
2493
+ name: nameFromNode(child),
2494
+ type: chunkTypeFromNode(child),
2495
+ parent
2496
+ });
2497
+ }
2498
+ return out;
2499
+ };
2500
+ const collectAstRanges = (path, content, lines) => {
2501
+ const language = resolveAstLanguage(path);
2502
+ if (language === void 0) return [];
2503
+ try {
2504
+ const parser = new TreeSitter();
2505
+ parser.setLanguage(language);
2506
+ const tree = parser.parse(content, void 0, { bufferSize: 1048576 });
2507
+ const collectDeclarationRanges = (siblings, parent) => {
2508
+ const out = [];
2509
+ for (let index = 0; index < siblings.length; index++) {
2510
+ const sibling = siblings[index];
2511
+ if (sibling.type === "comment" || sibling.type.includes("import")) continue;
2512
+ const declarationNode = unwrapDeclarationNode(sibling);
2513
+ const type = chunkTypeFromNode(declarationNode);
2514
+ const name = nameFromNode(declarationNode);
2515
+ if (type === void 0 && name === void 0) continue;
2516
+ out.push({
2517
+ ...lineRangeWithLeadingComments(sibling, siblings, index, lines),
2518
+ name,
2519
+ type,
2520
+ parent
2521
+ });
2522
+ if (declarationNode.type === "class_declaration") out.push(...collectClassMethodRanges(declarationNode, formatParent(type, name), lines));
2523
+ if (isNamespaceNode(declarationNode)) {
2524
+ const body = declarationNode.childForFieldName("body");
2525
+ if (body !== null) out.push(...collectDeclarationRanges(body.namedChildren, formatParent(type, name)));
2526
+ }
2527
+ }
2528
+ return out;
2529
+ };
2530
+ return collectDeclarationRanges(tree.rootNode.namedChildren, void 0);
2531
+ } catch {
2532
+ return [];
2533
+ }
2534
+ };
2535
+ const chunksFromRanges = (path, lines, ranges, settings) => {
2536
+ const hasMethodChildRange = (classRange) => {
2537
+ const parent = formatParent("class", classRange.name);
2538
+ return ranges.some((range) => range.type === "method" && range.parent === parent && range.startLine >= classRange.startLine && range.endLine <= classRange.endLine);
2539
+ };
2540
+ const out = [];
2541
+ const seen = /* @__PURE__ */ new Set();
2542
+ const prefixSums = lineLengthPrefixSums(lines);
2543
+ for (const range of ranges) {
2544
+ const normalizedRange = normalizeLineRange(range, lines.length);
2545
+ if (normalizedRange === void 0) continue;
2546
+ const allSegments = splitRange(normalizedRange, settings, prefixSums);
2547
+ const segments = range.type === "class" && allSegments.length > 1 && hasMethodChildRange({
2548
+ ...normalizedRange,
2549
+ name: range.name
2550
+ }) ? [allSegments[0]] : allSegments;
2551
+ for (const segment of segments) {
2552
+ const key = String(segment.startLine) + ":" + String(segment.endLine) + ":" + (range.name ?? "") + ":" + (range.type ?? "") + ":" + (range.parent ?? "");
2553
+ if (seen.has(key)) continue;
2554
+ seen.add(key);
2555
+ const chunkLines = lines.slice(segment.startLine - 1, segment.endLine);
2556
+ if (!chunkLines.some(isMeaningfulLine)) continue;
2557
+ out.push({
2558
+ path,
2559
+ startLine: segment.startLine,
2560
+ endLine: segment.endLine,
2561
+ name: range.name,
2562
+ type: range.type,
2563
+ parent: range.parent,
2564
+ content: chunkLines.join("\n")
2565
+ });
2566
+ }
2567
+ }
2568
+ return out.toSorted((left, right) => left.startLine - right.startLine || left.endLine - right.endLine || (left.name ?? "").localeCompare(right.name ?? ""));
2569
+ };
2570
+ const chunkWithLineWindows = (path, lines, settings) => {
2571
+ const out = [];
2572
+ const prefixSums = lineLengthPrefixSums(lines);
2573
+ for (let index = 0; index < lines.length;) {
2574
+ if (!isMeaningfulLine(lines[index])) {
2575
+ index++;
2576
+ continue;
2577
+ }
2578
+ const startLine = index + 1;
2579
+ const maxEndLine = Math.min(lines.length, startLine + settings.chunkSize - 1);
2580
+ const endLine = resolveSegmentEndLine({
2581
+ startLine,
2582
+ maxEndLine,
2583
+ settings,
2584
+ prefixSums
2585
+ });
2586
+ const chunkLines = lines.slice(startLine - 1, endLine);
2587
+ out.push({
2588
+ path,
2589
+ startLine,
2590
+ endLine,
2591
+ name: void 0,
2592
+ type: void 0,
2593
+ parent: void 0,
2594
+ content: chunkLines.join("\n")
2595
+ });
2596
+ if (endLine >= lines.length) break;
2597
+ index = Math.max(startLine + 1, endLine - settings.chunkOverlap + 1) - 1;
2598
+ }
2599
+ return out;
2600
+ };
2601
+ const splitOversizedChunks = (chunks, maxCharacters) => chunks.flatMap((chunk) => {
2602
+ if (chunk.content.length <= maxCharacters) return [chunk];
2603
+ const pieces = [];
2604
+ for (let offset = 0; offset < chunk.content.length; offset += maxCharacters) pieces.push({
2605
+ ...chunk,
2606
+ content: chunk.content.slice(offset, offset + maxCharacters)
2607
+ });
2608
+ return pieces;
2609
+ });
2610
+ /**
2611
+ * @since 1.0.0
2612
+ * @category Constructors
2613
+ */
2614
+ const chunkFileContent = (path, content, options) => {
2615
+ if (content.trim().length === 0 || isProbablyMinified(content)) return [];
2616
+ const normalizedPath = normalizePath$1(path);
2617
+ const normalizedContent = normalizeText(content);
2618
+ const lines = normalizedContent.split("\n");
2619
+ if (lines.at(-1) === "") lines.pop();
2620
+ if (lines.length === 0) return [];
2621
+ const settings = resolveChunkSettings(options);
2622
+ const astRanges = collectAstRanges(normalizedPath, normalizedContent, lines);
2623
+ if (astRanges.length > 0) {
2624
+ const astChunks = chunksFromRanges(normalizedPath, lines, astRanges, settings);
2625
+ if (astChunks.length > 0) return splitOversizedChunks(astChunks, settings.chunkMaxCharacters);
2626
+ }
2627
+ return splitOversizedChunks(chunkWithLineWindows(normalizedPath, lines, settings), settings.chunkMaxCharacters);
2628
+ };
2629
+ /**
2630
+ * @since 1.0.0
2631
+ * @category Layers
2632
+ */
2633
+ const layer$3 = effect(CodeChunker, gen(function* () {
2634
+ const spawner = yield* ChildProcessSpawner;
2635
+ const fs = yield* FileSystem;
2636
+ const pathService = yield* Path;
2637
+ const listFiles = fn("CodeChunker.listFiles")(function* (options) {
2638
+ const root = pathService.resolve(options.root);
2639
+ const maxFileSize = options.maxFileSize ?? "1M";
2640
+ return yield* pipe(spawner.streamLines(make$13("rg", [
2641
+ "--files",
2642
+ "--hidden",
2643
+ "--max-filesize",
2644
+ maxFileSize,
2645
+ "--glob",
2646
+ "!.git"
2647
+ ], {
2648
+ cwd: root,
2649
+ stdin: "ignore"
2650
+ })), runCollect, map(fromIterable), map((entries) => entries.map((entry) => normalizePath$1(entry.trim())).filter((entry) => entry.length > 0 && isMeaningfulFile(entry)).toSorted((left, right) => left.localeCompare(right))), orDie);
2651
+ });
2652
+ const chunkFile = fn("CodeChunker.chunkFile")(function* (options) {
2653
+ const root = pathService.resolve(options.root);
2654
+ const absolutePath = pathService.resolve(root, options.path);
2655
+ const path = normalizePath$1(pathService.relative(root, absolutePath));
2656
+ if (path.length === 0 || path === ".." || path.startsWith("../") || !isMeaningfulFile(path)) return [];
2657
+ return yield* pipe(fs.readFileString(absolutePath), map((content) => chunkFileContent(path, content, options)), orElseSucceed(() => []));
2658
+ });
2659
+ const chunkFiles = (options) => fromArray(options.paths).pipe(flatMap$1((path) => pipe(chunkFile({
2660
+ root: options.root,
2661
+ path,
2662
+ chunkSize: options.chunkSize,
2663
+ chunkOverlap: options.chunkOverlap,
2664
+ ...options.chunkMaxCharacters === void 0 ? {} : { chunkMaxCharacters: options.chunkMaxCharacters }
2665
+ }), fromArrayEffect), { concurrency: 5 }));
2666
+ const chunkCodebase = fnUntraced(function* (options) {
2667
+ const root = pathService.resolve(options.root);
2668
+ const files = yield* listFiles({
2669
+ root,
2670
+ ...options.maxFileSize === void 0 ? {} : { maxFileSize: options.maxFileSize }
2671
+ });
2672
+ return chunkFiles({
2673
+ root,
2674
+ paths: files,
2675
+ chunkSize: options.chunkSize,
2676
+ chunkOverlap: options.chunkOverlap,
2677
+ ...options.chunkMaxCharacters === void 0 ? {} : { chunkMaxCharacters: options.chunkMaxCharacters }
2678
+ });
2679
+ }, unwrap);
2680
+ return CodeChunker.of({
2681
+ listFiles,
2682
+ chunkFile,
2683
+ chunkFiles,
2684
+ chunkCodebase
2685
+ });
2686
+ }));
2687
+ //#endregion
2688
+ //#region node_modules/.pnpm/effect@4.0.0-rc.115/node_modules/effect/dist/FiberHandle.js
2689
+ /**
2690
+ * Manages at most one fiber inside a scope.
2691
+ *
2692
+ * A `FiberHandle<A, E>` can hold one `Fiber<A, E>`. Installing a new fiber
2693
+ * interrupts the previous one unless the operation is configured with
2694
+ * `onlyIfMissing`, and closing the owning scope interrupts the current fiber.
2695
+ * This module includes constructors for handles and scoped runtimes, helpers
2696
+ * for setting, reading, clearing, and running fibers, and operations for joining
2697
+ * the current fiber or waiting until the handle is empty.
2698
+ *
2699
+ * @since 2.0.0
2700
+ */
2701
+ const TypeId$1 = "~effect/FiberHandle";
2702
+ /**
2703
+ * Returns `true` if a value is a `FiberHandle` by checking for the
2704
+ * `FiberHandle` runtime marker.
2705
+ *
2706
+ * **Example** (Checking fiber handles)
2707
+ *
2708
+ * ```ts import.meta.vitest
2709
+ * import { Effect, FiberHandle } from "effect"
2710
+ *
2711
+ * const program = Effect.gen(function*() {
2712
+ * const handle = yield* FiberHandle.make()
2713
+ *
2714
+ * return [FiberHandle.isFiberHandle(handle), FiberHandle.isFiberHandle("not a handle")]
2715
+ * })
2716
+ *
2717
+ * const actual = await Effect.runPromise(Effect.scoped(program))
2718
+ * actual // => [true, false]
2719
+ * ```
2720
+ *
2721
+ * @category guards
2722
+ * @since 2.0.0
2723
+ */
2724
+ const isFiberHandle = (u) => hasProperty(u, TypeId$1);
2725
+ const Proto = {
2726
+ [TypeId$1]: TypeId$1,
2727
+ ...PipeInspectableProto,
2728
+ toJSON() {
2729
+ return {
2730
+ _id: "FiberHandle",
2731
+ state: this.state
2732
+ };
2733
+ }
2734
+ };
2735
+ const makeUnsafe = () => {
2736
+ const self = Object.create(Proto);
2737
+ self.state = {
2738
+ _tag: "Open",
2739
+ fiber: void 0
2740
+ };
2741
+ self.deferred = makeUnsafe$2();
2742
+ return self;
2743
+ };
2744
+ /**
2745
+ * Creates a scoped `FiberHandle` that can store a single fiber.
2746
+ *
2747
+ * **Details**
2748
+ *
2749
+ * When the associated `Scope` is closed, the contained fiber will be
2750
+ * interrupted. You can add a fiber to the handle using `FiberHandle.run`, and
2751
+ * the fiber will be automatically removed from the `FiberHandle` when it
2752
+ * completes.
2753
+ *
2754
+ * **Example** (Creating a scoped fiber handle)
2755
+ *
2756
+ * ```ts import.meta.vitest
2757
+ * import { Effect, FiberHandle } from "effect"
2758
+ *
2759
+ * const program = Effect.gen(function*() {
2760
+ * const handle = yield* FiberHandle.make()
2761
+ *
2762
+ * // run some effects
2763
+ * yield* FiberHandle.run(handle, Effect.never)
2764
+ * // this will interrupt the previous fiber
2765
+ * yield* FiberHandle.run(handle, Effect.never)
2766
+ *
2767
+ * yield* Effect.yieldNow
2768
+ * return handle.state._tag === "Open" && handle.state.fiber !== undefined
2769
+ * }).pipe(
2770
+ * Effect.scoped // The fiber will be interrupted when the scope is closed
2771
+ * )
2772
+ *
2773
+ * const actual = await Effect.runPromise(program)
2774
+ * actual // => true
2775
+ * ```
2776
+ *
2777
+ * @category constructors
2778
+ * @since 2.0.0
2779
+ */
2780
+ const make$2 = () => acquireRelease(sync(() => makeUnsafe()), (handle) => {
2781
+ const state = handle.state;
2782
+ if (state._tag === "Closed") return void_$1;
2783
+ handle.state = { _tag: "Closed" };
2784
+ return state.fiber ? into(asVoid(interruptAs(state.fiber, internalFiberId)), handle.deferred) : done(handle.deferred, void_$3);
2785
+ });
2786
+ const internalFiberId = -1;
2787
+ const isInternalInterruption = /*#__PURE__*/ toPredicate(/*#__PURE__*/ compose(filterInterruptors, /*#__PURE__*/ has(internalFiberId)));
2788
+ /**
2789
+ * Sets the fiber in a FiberHandle. When the fiber completes, it will be removed from the FiberHandle.
2790
+ * If a fiber is already running, it will be interrupted unless `options.onlyIfMissing` is set.
2791
+ *
2792
+ * **When to use**
2793
+ *
2794
+ * Use when an existing forked fiber must be installed synchronously into a
2795
+ * handle and immediate interruption of replaced or closed fibers is acceptable.
2796
+ *
2797
+ * **Example** (Setting a fiber unsafely)
2798
+ *
2799
+ * ```ts import.meta.vitest
2800
+ * import { Effect, Fiber, FiberHandle } from "effect"
2801
+ *
2802
+ * const program = Effect.gen(function*() {
2803
+ * const handle = yield* FiberHandle.make()
2804
+ * const fiber = Effect.runFork(Effect.succeed("hello"))
2805
+ *
2806
+ * // Set the fiber directly (unsafe)
2807
+ * FiberHandle.setUnsafe(handle, fiber)
2808
+ *
2809
+ * // The fiber is now managed by the handle
2810
+ * return yield* Fiber.join(fiber)
2811
+ * })
2812
+ *
2813
+ * const actual = await Effect.runPromise(Effect.scoped(program))
2814
+ * actual // => "hello"
2815
+ * ```
2816
+ *
2817
+ * @category combinators
2818
+ * @since 4.0.0
2819
+ */
2820
+ const setUnsafe = /*#__PURE__*/ dual((args) => isFiberHandle(args[0]), (self, fiber, options) => {
2821
+ if (self.state._tag === "Closed") {
2822
+ fiber.interruptUnsafe(internalFiberId);
2823
+ return;
2824
+ } else if (self.state.fiber !== void 0) {
2825
+ if (self.state.fiber === fiber) return;
2826
+ else if (options?.onlyIfMissing === true) {
2827
+ fiber.interruptUnsafe(internalFiberId);
2828
+ return;
2829
+ }
2830
+ self.state.fiber.interruptUnsafe(internalFiberId);
2831
+ self.state.fiber = void 0;
2832
+ }
2833
+ self.state.fiber = fiber;
2834
+ fiber.addObserver((exit) => {
2835
+ if (self.state._tag === "Open" && fiber === self.state.fiber) self.state.fiber = void 0;
2836
+ if (isFailure(exit) && (options?.propagateInterruption === true ? !isInternalInterruption(exit.cause) : !hasInterruptsOnly(exit.cause))) doneUnsafe(self.deferred, exit);
2837
+ });
2838
+ });
2839
+ const constInterruptedFiber = /*#__PURE__*/ function() {
2840
+ let fiber = void 0;
2841
+ return () => {
2842
+ if (fiber === void 0) fiber = runFork(interrupt);
2843
+ return fiber;
2844
+ };
2845
+ }();
2846
+ /**
2847
+ * Forks an Effect and stores the resulting fiber in the `FiberHandle`.
2848
+ *
2849
+ * **Details**
2850
+ *
2851
+ * The handle manages only one fiber: running a new effect interrupts the
2852
+ * previous fiber unless `onlyIfMissing` is set. When the managed fiber
2853
+ * completes, it is removed from the handle.
2854
+ *
2855
+ * **Example** (Running an effect in a fiber handle)
2856
+ *
2857
+ * ```ts import.meta.vitest
2858
+ * import { Effect, Fiber, FiberHandle } from "effect"
2859
+ *
2860
+ * const program = Effect.gen(function*() {
2861
+ * const handle = yield* FiberHandle.make()
2862
+ *
2863
+ * // Run an effect and get the fiber
2864
+ * const fiber = yield* FiberHandle.run(handle, Effect.succeed("hello"))
2865
+ * const result = yield* Fiber.join(fiber)
2866
+ *
2867
+ * // Running another effect will interrupt the previous one
2868
+ * const fiber2 = yield* FiberHandle.run(handle, Effect.succeed("world"))
2869
+ * const result2 = yield* Fiber.join(fiber2)
2870
+ * return [result, result2]
2871
+ * })
2872
+ *
2873
+ * const actual = await Effect.runPromise(Effect.scoped(program))
2874
+ * actual // => ["hello", "world"]
2875
+ * ```
2876
+ *
2877
+ * @category combinators
2878
+ * @since 2.0.0
2879
+ */
2880
+ const run$1 = function() {
2881
+ const self = arguments[0];
2882
+ if (isEffect(arguments[1])) return runImpl(self, arguments[1], arguments[2]);
2883
+ const options = arguments[1];
2884
+ return (effect) => runImpl(self, effect, options);
2885
+ };
2886
+ const runImpl = (self, effect, options) => withFiber((parent) => {
2887
+ if (self.state._tag === "Closed") return interrupt;
2888
+ else if (self.state.fiber !== void 0 && options?.onlyIfMissing === true) return sync(constInterruptedFiber);
2889
+ const fiber = runForkWith(parent.context)(effect);
2890
+ setUnsafe(self, fiber, options);
2891
+ return succeed(fiber);
2892
+ });
2893
+ //#endregion
2894
+ //#region node_modules/.pnpm/@effect+sql-sqlite-node@4.0.0-rc.115_effect@4.0.0-rc.115/node_modules/@effect/sql-sqlite-node/dist/SqliteClient.js
2895
+ /**
2896
+ * Connects Effect SQL to SQLite on Node.js using `node:sqlite`.
2897
+ *
2898
+ * This module opens a SQLite database and exposes it as both `SqliteClient` and
2899
+ * the generic Effect SQL client. It serializes access through one connection,
2900
+ * caches prepared statements, enables WAL mode unless disabled, and waits up
2901
+ * to five seconds for busy databases by default. Explicit transactions on
2902
+ * writable connections use `BEGIN IMMEDIATE` to avoid read-to-write lock
2903
+ * upgrades, which serializes them behind other writers even when they only
2904
+ * read. Clients opened with `readonly: true` are unaffected. Busy waits block
2905
+ * the Node.js event loop because `node:sqlite` is synchronous. Database backup
2906
+ * and extension loading are supported; streaming queries and `updateValues`
2907
+ * are not.
2908
+ *
2909
+ * @since 4.0.0
2910
+ */
2911
+ const ATTR_DB_SYSTEM_NAME = "db.system.name";
2912
+ const MAX_BUSY_TIMEOUT = 2147483647;
2913
+ /**
2914
+ * Runtime type identifier used to mark Node `SqliteClient` values.
2915
+ *
2916
+ * @category type IDs
2917
+ * @since 4.0.0
2918
+ */
2919
+ const TypeId = "~@effect/sql-sqlite-node/SqliteClient";
2920
+ /**
2921
+ * Service tag for the node SQLite client implementation.
2922
+ *
2923
+ * @category services
2924
+ * @since 4.0.0
2925
+ */
2926
+ const SqliteClient = /*#__PURE__*/ Service("@effect/sql-sqlite-node/SqliteClient");
2927
+ /**
2928
+ * Creates a scoped node SQLite client from the supplied configuration, using a single serialized connection with WAL and a 5-second busy timeout enabled by default. Explicit transactions on writable connections take the write lock for their duration, even when they only read; clients opened with `readonly: true` are unaffected.
2929
+ *
2930
+ * @category constructors
2931
+ * @since 4.0.0
2932
+ */
2933
+ const make$1 = (options) => gen(function* () {
2934
+ const compiler = makeCompilerSqlite(options.transformQueryNames);
2935
+ const transformRows = options.transformResultNames ? defaultTransforms(options.transformResultNames).array : void 0;
2936
+ const makeConnection = gen(function* () {
2937
+ const scope$1 = yield* scope;
2938
+ const db = new DatabaseSync(options.filename, {
2939
+ readOnly: options.readonly ?? false,
2940
+ allowExtension: true
2941
+ });
2942
+ yield* addFinalizer(scope$1, sync(() => db.close()));
2943
+ db.enableLoadExtension(false);
2944
+ const busyTimeout = Math.min(MAX_BUSY_TIMEOUT, Math.max(0, Math.round(toMillis(options.busyTimeout ?? seconds(5)))));
2945
+ db.exec(`PRAGMA busy_timeout = ${busyTimeout}`);
2946
+ if (options.disableWAL !== true) db.exec("PRAGMA journal_mode = WAL");
2947
+ const prepare = (sql) => try_({
2948
+ try: () => db.prepare(sql),
2949
+ catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to prepare statement", "prepare") })
2950
+ });
2951
+ const prepareCache = yield* make$4({
2952
+ capacity: options.prepareCacheSize ?? 200,
2953
+ timeToLive: options.prepareCacheTTL ?? minutes(10),
2954
+ lookup: prepare
2955
+ });
2956
+ const runStatement = (statement, params, raw) => withFiber((fiber) => {
2957
+ const useSafeIntegers = get$1(fiber.context, SafeIntegers);
2958
+ return try_({
2959
+ try: () => {
2960
+ statement.setReadBigInts(useSafeIntegers);
2961
+ if (statement.columns().length > 0) return statement.all(...params);
2962
+ const result = statement.run(...params);
2963
+ return raw ? {
2964
+ changes: result.changes,
2965
+ lastInsertRowid: result.lastInsertRowid
2966
+ } : [];
2967
+ },
2968
+ catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to execute statement", "execute") })
2969
+ });
2970
+ });
2971
+ const runStatementValues = (statement, params) => withFiber((fiber) => {
2972
+ const useSafeIntegers = get$1(fiber.context, SafeIntegers);
2973
+ return try_({
2974
+ try: () => {
2975
+ statement.setReadBigInts(useSafeIntegers);
2976
+ if (statement.columns().length > 0) return statement.all(...params);
2977
+ statement.run(...params);
2978
+ return [];
2979
+ },
2980
+ catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to execute statement", "execute") })
2981
+ });
2982
+ });
2983
+ const runStatementValuesUnprepared = (statement, params) => withFiber((fiber) => {
2984
+ const useSafeIntegers = get$1(fiber.context, SafeIntegers);
2985
+ return try_({
2986
+ try: () => {
2987
+ statement.setReadBigInts(useSafeIntegers);
2988
+ statement.setReturnArrays(true);
2989
+ if (statement.columns().length > 0) return statement.all(...params);
2990
+ statement.run(...params);
2991
+ return [];
2992
+ },
2993
+ catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to execute statement", "execute") })
2994
+ });
2995
+ });
2996
+ const run = (sql, params, raw = false) => flatMap(get(prepareCache, sql), (s) => runStatement(s, params, raw));
2997
+ const runValues = (sql, params) => acquireUseRelease(get(prepareCache, sql), (statement) => {
2998
+ statement.setReturnArrays(true);
2999
+ return runStatementValues(statement, params);
3000
+ }, (statement) => sync(() => statement.setReturnArrays(false)));
3001
+ const runValuesUnprepared = (sql, params) => flatMap(prepare(sql), (statement) => runStatementValuesUnprepared(statement, params));
3002
+ return identity({
3003
+ execute(sql, params, transformRows) {
3004
+ return transformRows ? map(run(sql, params), transformRows) : run(sql, params);
3005
+ },
3006
+ executeRaw(sql, params) {
3007
+ return run(sql, params, true);
3008
+ },
3009
+ executeValues(sql, params) {
3010
+ return runValues(sql, params);
3011
+ },
3012
+ executeValuesUnprepared(sql, params) {
3013
+ return runValuesUnprepared(sql, params);
3014
+ },
3015
+ executeUnprepared(sql, params, transformRows) {
3016
+ const effect = flatMap(prepare(sql), (statement) => runStatement(statement, params ?? [], false));
3017
+ return transformRows ? map(effect, transformRows) : effect;
3018
+ },
3019
+ executeStream(_sql, _params) {
3020
+ return die$1("executeStream not implemented");
3021
+ },
3022
+ backup(destination) {
3023
+ return suspend(() => {
3024
+ let totalPages = 0;
3025
+ return tryPromise({
3026
+ try: () => backup(db, destination, { progress: (progress) => {
3027
+ totalPages = progress.totalPages;
3028
+ } }).then((pages) => ({
3029
+ totalPages: totalPages || pages,
3030
+ remainingPages: 0
3031
+ })),
3032
+ catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to backup database", "backup") })
3033
+ });
3034
+ });
3035
+ },
3036
+ loadExtension(path) {
3037
+ return acquireUseRelease(sync(() => db.enableLoadExtension(true)), () => try_({
3038
+ try: () => db.loadExtension(path),
3039
+ catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to load extension", "loadExtension") })
3040
+ }), () => sync(() => db.enableLoadExtension(false)));
3041
+ }
3042
+ });
3043
+ });
3044
+ const semaphore = yield* make$14(1);
3045
+ const connection = yield* makeConnection;
3046
+ const acquirer = semaphore.withPermits(1)(succeed(connection));
3047
+ const transactionAcquirer = uninterruptibleMask((restore) => {
3048
+ const fiber = getCurrent();
3049
+ const scope = getUnsafe(fiber.context, Scope);
3050
+ return as(tap(restore(semaphore.take(1)), () => addFinalizer(scope, semaphore.release(1))), connection);
3051
+ });
3052
+ return Object.assign(yield* make$5({
3053
+ acquirer,
3054
+ compiler,
3055
+ transactionAcquirer,
3056
+ beginTransaction: options.readonly === true ? "BEGIN" : "BEGIN IMMEDIATE",
3057
+ spanAttributes: [...options.spanAttributes ? Object.entries(options.spanAttributes) : [], [ATTR_DB_SYSTEM_NAME, "sqlite"]],
3058
+ transformRows
3059
+ }), {
3060
+ [TypeId]: TypeId,
3061
+ config: options,
3062
+ backup: (destination) => flatMap(acquirer, (_) => _.backup(destination)),
3063
+ loadExtension: (path) => flatMap(acquirer, (_) => _.loadExtension(path))
3064
+ });
3065
+ });
3066
+ /**
3067
+ * Builds a layer from a node SQLite client configuration, providing both `SqliteClient` and the generic `SqlClient` service.
3068
+ *
3069
+ * @category layers
3070
+ * @since 4.0.0
3071
+ */
3072
+ const layer$2 = (config) => effectContext(map(make$1(config), (client) => make$9(SqliteClient, client).pipe(add(SqlClient, client)))).pipe(provide$1(layer$5));
3073
+ const classifyError = (cause, message, operation) => classifySqliteError(sqliteCauseWithErrno(cause), {
3074
+ message,
3075
+ operation
3076
+ });
3077
+ const sqliteCauseWithErrno = (cause) => {
3078
+ if (typeof cause !== "object" || cause === null || !("errcode" in cause) || "errno" in cause) return cause;
3079
+ const errcode = cause.errcode;
3080
+ if (typeof errcode !== "number") return cause;
3081
+ return Object.assign(cause, { errno: errcode });
3082
+ };
3083
+ /**
3084
+ * Error raised while loading, validating, locking, or running SQL migrations.
3085
+ *
3086
+ * @category errors
3087
+ * @since 4.0.0
3088
+ */
3089
+ var MigrationError = class extends (/*#__PURE__*/ TaggedError$1("MigrationError")) {};
3090
+ /**
3091
+ * Creates a migrator that ensures the migrations table exists, runs pending
3092
+ * migrations in a transaction, and optionally dumps the schema after successful
3093
+ * migrations.
3094
+ *
3095
+ * @category constructors
3096
+ * @since 4.0.0
3097
+ */
3098
+ const make = ({ dumpSchema = () => void_$1 }) => ({ loader, schemaDirectory, table = "effect_sql_migrations" }) => gen(function* () {
3099
+ const sql = yield* SqlClient;
3100
+ const ensureMigrationsTable = sql.onDialectOrElse({
3101
+ mssql: () => sql`IF OBJECT_ID(N'${sql.literal(table)}', N'U') IS NULL
3102
+ CREATE TABLE ${sql(table)} (
3103
+ migration_id INT NOT NULL PRIMARY KEY,
3104
+ name VARCHAR(255) NOT NULL,
3105
+ created_at DATETIME NOT NULL DEFAULT GETDATE()
3106
+ )`,
3107
+ mysql: () => sql`CREATE TABLE IF NOT EXISTS ${sql(table)} (
3108
+ migration_id INTEGER UNSIGNED NOT NULL,
3109
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
3110
+ name VARCHAR(255) NOT NULL,
3111
+ PRIMARY KEY (migration_id)
3112
+ )`,
3113
+ pg: () => catch_(sql`select ${table}::regclass`, () => sql`CREATE TABLE ${sql(table)} (
3114
+ migration_id integer primary key,
3115
+ created_at timestamp with time zone not null default now(),
3116
+ name text not null
3117
+ )`),
3118
+ orElse: () => sql`CREATE TABLE IF NOT EXISTS ${sql(table)} (
3119
+ migration_id integer PRIMARY KEY NOT NULL,
3120
+ created_at datetime NOT NULL DEFAULT current_timestamp,
3121
+ name VARCHAR(255) NOT NULL
3122
+ )`
3123
+ });
3124
+ const insertMigrations = (rows) => sql`INSERT INTO ${sql(table)} ${sql.insert(rows.map(([migration_id, name]) => ({
3125
+ migration_id,
3126
+ name
3127
+ })))}`.withoutTransform;
3128
+ const latestMigration = map(sql`SELECT migration_id, name, created_at FROM ${sql(table)} ORDER BY migration_id DESC`.withoutTransform, (_) => map$1(fromNullishOr(_[0]), ({ created_at, migration_id, name }) => ({
3129
+ id: migration_id,
3130
+ name,
3131
+ createdAt: created_at
3132
+ })));
3133
+ const loadMigration = ([id, name, load]) => catchDefect(load, (_) => fail$1(new MigrationError({
3134
+ kind: "ImportError",
3135
+ message: `Could not import migration "${id}_${name}"\n\n${_}`
3136
+ }))).pipe(flatMap((_) => isEffect(_) ? succeed(_) : _.default ? succeed(_.default?.default ?? _.default) : fail$1(new MigrationError({
3137
+ kind: "ImportError",
3138
+ message: `Default export not found for migration "${id}_${name}"`
3139
+ }))), filterOrFail(isEffect, () => new MigrationError({
3140
+ kind: "ImportError",
3141
+ message: `Default export was not an Effect for migration "${id}_${name}"`
3142
+ })));
3143
+ const runMigration = (id, name, effect) => catch_(effect, (error) => die(new MigrationError({
3144
+ cause: error,
3145
+ kind: "Failed",
3146
+ message: `Migration "${id}_${name}" failed`
3147
+ })));
3148
+ const run = gen(function* () {
3149
+ yield* sql.onDialectOrElse({
3150
+ pg: () => sql`LOCK TABLE ${sql(table)} IN ACCESS EXCLUSIVE MODE`,
3151
+ orElse: () => void_$1
3152
+ });
3153
+ const [latestMigrationId, current] = yield* all([map(latestMigration, match({
3154
+ onNone: () => 0,
3155
+ onSome: (_) => _.id
3156
+ })), loader]);
3157
+ if (new Set(current.map(([id]) => id)).size !== current.length) return yield* new MigrationError({
3158
+ kind: "Duplicates",
3159
+ message: "Found duplicate migration id's"
3160
+ });
3161
+ const required = [];
3162
+ for (const resolved of current) {
3163
+ const [currentId, currentName] = resolved;
3164
+ if (currentId <= latestMigrationId) continue;
3165
+ required.push([
3166
+ currentId,
3167
+ currentName,
3168
+ yield* loadMigration(resolved)
3169
+ ]);
3170
+ }
3171
+ if (required.length > 0) yield* pipe(insertMigrations(required.map(([id, name]) => [id, name])), mapError((error) => isConstraintConflict(error) ? new MigrationError({
3172
+ kind: "Locked",
3173
+ message: "Migrations already running"
3174
+ }) : error));
3175
+ yield* forEach(required, ([id, name, effect]) => logDebug(`Running migration`).pipe(flatMap(() => runMigration(id, name, effect)), annotateLogs("migration_id", String(id)), annotateLogs("migration_name", name), withSpan(`Migrator ${id}_${name}`)), { discard: true });
3176
+ yield* pipe(latestMigration, flatMap(match({
3177
+ onNone: () => logDebug(`Migrations complete`),
3178
+ onSome: (_) => logDebug(`Migrations complete`).pipe(annotateLogs("latest_migration_id", _.id.toString()), annotateLogs("latest_migration_name", _.name))
3179
+ })));
3180
+ return required.map(([id, name]) => [id, name]);
3181
+ });
3182
+ yield* ensureMigrationsTable;
3183
+ const completed = yield* pipe(sql.withTransaction(run), catchTag("MigrationError", (_) => _.kind === "Locked" ? as(logDebug(_.message), []) : fail$1(_)));
3184
+ if (schemaDirectory && completed.length > 0) yield* dumpSchema(`${schemaDirectory}/_schema.sql`, table).pipe(catchCause((cause) => logInfo("Could not dump schema", cause)));
3185
+ return completed;
3186
+ });
3187
+ const migrationOrder = /*#__PURE__*/ make$10(([a], [b]) => Number$2(a, b));
3188
+ const isConstraintConflict = (error) => error.reason._tag === "ConstraintError" || error.reason._tag === "UniqueViolation";
3189
+ /**
3190
+ * Creates a migration loader from a record of migration effects keyed by
3191
+ * `<id>_<name>`, sorted by migration id.
3192
+ *
3193
+ * @category loaders
3194
+ * @since 4.0.0
3195
+ */
3196
+ const fromRecord = (migrations) => pipe(Object.keys(migrations), flatMapNullishOr((_) => _.match(/^(\d+)_(.+)$/)), map$2(([key, id, name]) => [
3197
+ Number(id),
3198
+ name,
3199
+ succeed(migrations[key])
3200
+ ]), sort(migrationOrder), succeed);
3201
+ //#endregion
3202
+ //#region node_modules/.pnpm/@effect+sql-sqlite-node@4.0.0-rc.115_effect@4.0.0-rc.115/node_modules/@effect/sql-sqlite-node/dist/SqliteMigrator.js
3203
+ /**
3204
+ * Runs SQL migrations for a SQLite database using the shared `Migrator` implementation and the current `SqlClient`.
3205
+ *
3206
+ * @category running
3207
+ * @since 4.0.0
3208
+ */
3209
+ const run = /*#__PURE__*/ make({});
3210
+ /**
3211
+ * Creates a layer that runs the configured SQLite migrations during layer construction and provides no services.
3212
+ *
3213
+ * @category layers
3214
+ * @since 4.0.0
3215
+ */
3216
+ const layer$1 = (options) => effectDiscard(run(options));
3217
+ //#endregion
3218
+ //#region src/Sqlite.ts
3219
+ /**
3220
+ * @since 1.0.0
3221
+ */
3222
+ /**
3223
+ * @since 1.0.0
3224
+ * @category Layers
3225
+ */
3226
+ const SqliteLayer = (database) => layer$1({ loader: fromRecord({ "0001_create_chunks": gen(function* () {
3227
+ const sql = yield* SqlClient;
3228
+ yield* sql`CREATE TABLE IF NOT EXISTS chunks (
3229
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
3230
+ path TEXT NOT NULL,
3231
+ content TEXT NOT NULL,
3232
+ hash TEXT NOT NULL,
3233
+ vector BLOB NOT NULL,
3234
+ syncId TEXT NOT NULL
3235
+ )`;
3236
+ yield* sql`CREATE INDEX IF NOT EXISTS idx_chunks_hash ON chunks (hash)`;
3237
+ }) }) }).pipe(provide$1(effectDiscard(gen(function* () {
3238
+ yield* (yield* SqliteClient).loadExtension(getLoadablePath());
3239
+ }))), provideMerge(layer$2({ filename: database })), provide$1(effectDiscard(gen(function* () {
3240
+ const fs = yield* FileSystem;
3241
+ const directory = (yield* Path).dirname(database);
3242
+ if (directory === ".") return;
3243
+ yield* fs.makeDirectory(directory, { recursive: true });
3244
+ }))));
3245
+ //#endregion
3246
+ //#region src/SemanticSearch.ts
3247
+ /**
3248
+ * @since 1.0.0
3249
+ */
3250
+ const normalizePath = (path) => path.replace(/\\/g, "/");
3251
+ const resolveChunkConfig = (options) => ({
3252
+ chunkSize: 30,
3253
+ chunkOverlap: 0,
3254
+ chunkMaxCharacters: options.chunkMaxCharacters ?? 15e3
3255
+ });
3256
+ const makeEmbeddingResolver = (resolver, options) => resolver.pipe(setDelay(options.embeddingRequestDelay ?? millis(50)), batchN(options.embeddingBatchSize ?? 32));
3257
+ const chunkEmbeddingInput = (chunk) => {
3258
+ const headerLines = ["---", "file: " + chunk.path];
3259
+ if (chunk.name !== void 0) headerLines.push("name: " + chunk.name);
3260
+ if (chunk.type !== void 0) headerLines.push("type: " + chunk.type);
3261
+ if (chunk.parent !== void 0) headerLines.push("parent: " + chunk.parent);
3262
+ headerLines.push("---");
3263
+ const contentLines = chunk.content.split("\n");
3264
+ let contentWithLines = "";
3265
+ for (let i = 0; i < contentLines.length; i++) {
3266
+ if (i > 0) contentWithLines += "\n";
3267
+ contentWithLines += `${chunk.startLine + i}: ${contentLines[i]}`;
3268
+ }
3269
+ return headerLines.join("\n") + "\n\n" + contentWithLines;
3270
+ };
3271
+ const hashChunkInput = (input) => createHash("sha256").update(input).digest("hex");
3272
+ /**
3273
+ * @since 1.0.0
3274
+ * @category Layers
3275
+ */
3276
+ const layer = (options) => effect(SemanticSearch, gen(function* () {
3277
+ const chunker = yield* CodeChunker;
3278
+ const repo = yield* ChunkRepo;
3279
+ const embeddings = yield* EmbeddingModel;
3280
+ const pathService = yield* Path;
3281
+ const root = pathService.resolve(options.directory);
3282
+ const resolver = makeEmbeddingResolver(embeddings.resolver, options);
3283
+ const concurrency = options.concurrency ?? 2e3;
3284
+ const chunkConfig = resolveChunkConfig(options);
3285
+ const indexHandle = yield* make$2();
3286
+ const console = yield* Console;
3287
+ const resolveIndexedPath = (path) => {
3288
+ const absolutePath = pathService.resolve(root, path);
3289
+ const relativePath = normalizePath(pathService.relative(root, absolutePath));
3290
+ if (relativePath.length === 0 || relativePath === ".." || relativePath.startsWith("../")) return none();
3291
+ return some(relativePath);
3292
+ };
3293
+ const processChunk = fnUntraced(function* (options) {
3294
+ const input = chunkEmbeddingInput(options.chunk);
3295
+ const hash = hashChunkInput(input);
3296
+ if (options.checkExisting) {
3297
+ const id = yield* repo.exists(hash);
3298
+ if (isSome(id)) {
3299
+ yield* repo.setSyncId(id.value, options.syncId);
3300
+ return;
3301
+ }
3302
+ }
3303
+ const result = yield* request$1(new EmbeddingRequest({ input }), resolver);
3304
+ const vector = new Float32Array(result.vector);
3305
+ yield* repo.insert(Chunk.insert.make({
3306
+ path: options.chunk.path,
3307
+ hash,
3308
+ content: input,
3309
+ vector,
3310
+ syncId: options.syncId
3311
+ }));
3312
+ }, ignore({
3313
+ log: "Warn",
3314
+ message: "Failed to process chunk for embedding"
3315
+ }), (effect, options) => annotateLogs(effect, { chunk: `${options.chunk.path}/${options.chunk.startLine}` }));
3316
+ const index = gen(function* () {
3317
+ const syncId = SyncId.make(crypto.randomUUID());
3318
+ yield* logInfo("Starting SemanticSearch index");
3319
+ yield* pipe(chunker.chunkCodebase({
3320
+ root,
3321
+ ...chunkConfig
3322
+ }), tap$1((chunk) => processChunk({
3323
+ chunk,
3324
+ syncId,
3325
+ checkExisting: true
3326
+ }), { concurrency }), runDrain);
3327
+ yield* repo.deleteForSyncId(syncId);
3328
+ yield* logInfo("Finished SemanticSearch index");
3329
+ }).pipe(withSpan("SemanticSearch.index"), withLogSpan("SemanticSearch.index"), provideService(Console, console));
3330
+ const runIndex = run$1(indexHandle, index, { onlyIfMissing: true });
3331
+ const initialIndex = yield* runIndex;
3332
+ yield* runIndex.pipe(delay(minutes(3)), forever, forkScoped);
3333
+ return SemanticSearch.of({
3334
+ search: fn("SemanticSearch.search")(function* (options) {
3335
+ yield* join$1(initialIndex);
3336
+ yield* annotateCurrentSpan(options);
3337
+ const { vector } = yield* embeddings.embed(options.query);
3338
+ return (yield* repo.search({
3339
+ vector: new Float32Array(vector),
3340
+ limit: options.limit
3341
+ })).map((r) => r.content).join("\n\n");
3342
+ }, orDie),
3343
+ updateFile: fn("SemanticSearch.updateFile")(function* (path) {
3344
+ yield* join$1(initialIndex);
3345
+ const indexedPath = resolveIndexedPath(path);
3346
+ if (isNone(indexedPath)) return;
3347
+ yield* repo.deleteByPath(indexedPath.value);
3348
+ const chunks = yield* chunker.chunkFile({
3349
+ root,
3350
+ path: indexedPath.value,
3351
+ ...chunkConfig
3352
+ });
3353
+ if (chunks.length === 0) return;
3354
+ const syncId = SyncId.make(crypto.randomUUID());
3355
+ yield* pipe(fromArray(chunks), tap$1((chunk) => processChunk({
3356
+ chunk,
3357
+ syncId,
3358
+ checkExisting: false
3359
+ }), { concurrency }), runDrain);
3360
+ }, orDie),
3361
+ removeFile: fn("SemanticSearch.removeFile")(function* (path) {
3362
+ yield* join$1(initialIndex);
3363
+ const indexedPath = resolveIndexedPath(path);
3364
+ if (isNone(indexedPath)) return;
3365
+ yield* repo.deleteByPath(indexedPath.value);
3366
+ }, orDie)
3367
+ });
3368
+ })).pipe(provide$1([layer$3, layer$4.pipe(provide$1(SqliteLayer(options.database ?? ".clanka/search.sqlite")))]));
3369
+ //#endregion
3370
+ export { SemanticSearch, chunkEmbeddingInput, layer, makeEmbeddingResolver, maybeRemoveFile, maybeUpdateFile };
3371
+
3372
+ //# sourceMappingURL=SemanticSearch-D9iZ_Mi9.mjs.map