diff --git a/.changeset/dynamic-idle-ttl-rcmap.md b/.changeset/dynamic-idle-ttl-rcmap.md new file mode 100644 index 00000000000..b4deb3b59cc --- /dev/null +++ b/.changeset/dynamic-idle-ttl-rcmap.md @@ -0,0 +1,17 @@ +--- +"effect": minor +--- + +RcMap: support dynamic `idleTimeToLive` values per key + +The `idleTimeToLive` option can now be a function that receives the key and returns a duration, allowing different TTL values for different resources. + +```ts +const map = yield* RcMap.make({ + lookup: (key: string) => acquireResource(key), + idleTimeToLive: (key: string) => { + if (key.startsWith("premium:")) return Duration.minutes(10) + return Duration.minutes(1) + } +}) +``` diff --git a/.changeset/fast-shoes-appear.md b/.changeset/fast-shoes-appear.md new file mode 100644 index 00000000000..80a4adda4f8 --- /dev/null +++ b/.changeset/fast-shoes-appear.md @@ -0,0 +1,17 @@ +--- +"@effect/opentelemetry": patch +"effect": patch +--- + +Add logs to first propagated span, in the following case before this fix the log would not be added to the `p` span because `Effect.fn` adds a fake span for the purpose of adding a stack frame. + +```ts +import { Effect } from "effect" + +const f = Effect.fn(function* () { + yield* Effect.logWarning("FooBar") + return yield* Effect.fail("Oops") +}) + +const p = f().pipe(Effect.withSpan("p")) +``` diff --git a/.changeset/many-maps-lie.md b/.changeset/many-maps-lie.md new file mode 100644 index 00000000000..4a83381f9fe --- /dev/null +++ b/.changeset/many-maps-lie.md @@ -0,0 +1,5 @@ +--- +"@effect/sql-pglite": minor +--- + +add @effect/sql-pglite package diff --git a/.changeset/violet-years-stare.md b/.changeset/violet-years-stare.md new file mode 100644 index 00000000000..1e320c0ca62 --- /dev/null +++ b/.changeset/violet-years-stare.md @@ -0,0 +1,5 @@ +--- +"effect": minor +--- + +Fix annotateCurrentSpan, add Effect.currentPropagatedSpan diff --git a/docs/index.md b/docs/index.md index 5d05d3901cf..1ea7d34e112 100644 --- a/docs/index.md +++ b/docs/index.md @@ -50,6 +50,7 @@ The Effect monorepo is organized into multiple packages, each extending the core | `@effect/sql-mssql` | An `@effect/sql` implementation using the mssql `tedious` library. | [README](https://github.com/Effect-TS/effect/blob/main/packages/sql-mssql/README.md) | | `@effect/sql-mysql2` | An `@effect/sql` implementation using the `mysql2` library. | [README](https://github.com/Effect-TS/effect/blob/main/packages/sql-mysql2/README.md) | | `@effect/sql-pg` | An `@effect/sql` implementation using the `postgres.js` library. | [README](https://github.com/Effect-TS/effect/blob/main/packages/sql-pg/README.md) | +| `@effect/sql-pglite` | An `@effect/sql` implementation using `PGlite`, Postgres in the browser. | [README](https://github.com/Effect-TS/effect/blob/main/packages/sql-pglite/README.md) | | `@effect/sql-sqlite-bun` | An `@effect/sql` implementation using the `bun:sqlite` library. | [README](https://github.com/Effect-TS/effect/blob/main/packages/sql-sqlite-bun/README.md) | | `@effect/sql-sqlite-do` | An `@effect/sql` implementation for Cloudflare Durable Objects sqlite storage. | [README](https://github.com/Effect-TS/effect/blob/main/packages/sql-sqlite-do/README.md) | | `@effect/sql-sqlite-node` | An `@effect/sql` implementation using the `better-sqlite3` library. | [README](https://github.com/Effect-TS/effect/blob/main/packages/sql-sqlite-node/README.md) | diff --git a/packages/effect/src/Effect.ts b/packages/effect/src/Effect.ts index b1e897d82b1..d9143c239b6 100644 --- a/packages/effect/src/Effect.ts +++ b/packages/effect/src/Effect.ts @@ -12998,6 +12998,12 @@ export const annotateCurrentSpan: { */ export const currentSpan: Effect = effect.currentSpan +/** + * @since 3.20.0 + * @category Tracing + */ +export const currentPropagatedSpan: Effect = effect.currentPropagatedSpan + /** * @since 2.0.0 * @category Tracing diff --git a/packages/effect/src/RcMap.ts b/packages/effect/src/RcMap.ts index efd93797083..9e78cdce1f9 100644 --- a/packages/effect/src/RcMap.ts +++ b/packages/effect/src/RcMap.ts @@ -56,6 +56,7 @@ export declare namespace RcMap { * * - `capacity`: The maximum number of resources that can be held in the map. * - `idleTimeToLive`: When the reference count reaches zero, the resource will be released after this duration. + * Can be a static duration or a function that returns a duration based on the key. * * @since 3.5.0 * @category models @@ -85,14 +86,14 @@ export const make: { ( options: { readonly lookup: (key: K) => Effect.Effect - readonly idleTimeToLive?: Duration.DurationInput | undefined + readonly idleTimeToLive?: Duration.DurationInput | ((key: K) => Duration.DurationInput) | undefined readonly capacity?: undefined } ): Effect.Effect, never, Scope.Scope | R> ( options: { readonly lookup: (key: K) => Effect.Effect - readonly idleTimeToLive?: Duration.DurationInput | undefined + readonly idleTimeToLive?: Duration.DurationInput | ((key: K) => Duration.DurationInput) | undefined readonly capacity: number } ): Effect.Effect, never, Scope.Scope | R> diff --git a/packages/effect/src/internal/core-effect.ts b/packages/effect/src/internal/core-effect.ts index 2b90e1d0068..0ef68fb67b6 100644 --- a/packages/effect/src/internal/core-effect.ts +++ b/packages/effect/src/internal/core-effect.ts @@ -1966,7 +1966,7 @@ export const annotateCurrentSpan: { } = function(): Effect.Effect { const args = arguments return ignore(core.flatMap( - currentSpan, + currentPropagatedSpan, (span) => core.sync(() => { if (typeof args[0] === "string") { @@ -2041,6 +2041,16 @@ export const currentSpan: Effect.Effect = core.flatMap( + core.context(), + (context) => { + const span = filterDisablePropagation(Context.getOption(context, internalTracer.spanTag)) + return span._tag === "Some" && span.value._tag === "Span" + ? core.succeed(span.value) + : core.fail(new core.NoSuchElementException()) + } +) + /* @internal */ export const linkSpans = dual< ( @@ -2070,12 +2080,13 @@ export const linkSpans = dual< const bigint0 = BigInt(0) -const filterDisablePropagation: (self: Option.Option) => Option.Option = Option.flatMap( - (span) => - Context.get(span.context, internalTracer.DisablePropagation) - ? span._tag === "Span" ? filterDisablePropagation(span.parent) : Option.none() - : Option.some(span) -) +export const filterDisablePropagation: (self: Option.Option) => Option.Option = Option + .flatMap( + (span) => + Context.get(span.context, internalTracer.DisablePropagation) + ? span._tag === "Span" ? filterDisablePropagation(span.parent) : Option.none() + : Option.some(span) + ) /** @internal */ export const unsafeMakeSpan = ( diff --git a/packages/effect/src/internal/fiberRuntime.ts b/packages/effect/src/internal/fiberRuntime.ts index 8362eb2b34a..52ffccf95d2 100644 --- a/packages/effect/src/internal/fiberRuntime.ts +++ b/packages/effect/src/internal/fiberRuntime.ts @@ -1517,13 +1517,15 @@ export const tracerLogger = globalValue( logLevel, message }) => { - const span = Context.getOption( + const span = internalEffect.filterDisablePropagation(Context.getOption( fiberRefs.getOrDefault(context, core.currentContext), tracer.spanTag - ) + )) + if (span._tag === "None" || span.value._tag === "ExternalSpan") { return } + const clockService = Context.unsafeGet( fiberRefs.getOrDefault(context, defaultServices.currentServices), clock.clockTag diff --git a/packages/effect/src/internal/rcMap.ts b/packages/effect/src/internal/rcMap.ts index 12c84ef44f2..b5980220b3a 100644 --- a/packages/effect/src/internal/rcMap.ts +++ b/packages/effect/src/internal/rcMap.ts @@ -4,7 +4,7 @@ import type * as Deferred from "../Deferred.js" import * as Duration from "../Duration.js" import type { Effect } from "../Effect.js" import type { RuntimeFiber } from "../Fiber.js" -import { dual, identity } from "../Function.js" +import { constant, dual, flow, identity } from "../Function.js" import * as MutableHashMap from "../MutableHashMap.js" import { pipeArguments } from "../Pipeable.js" import type * as RcMap from "../RcMap.js" @@ -33,6 +33,7 @@ declare namespace State { readonly deferred: Deferred.Deferred readonly scope: Scope.CloseableScope readonly finalizer: Effect + readonly idleTimeToLive: Duration.Duration fiber: RuntimeFiber | undefined expiresAt: number refCount: number @@ -58,7 +59,7 @@ class RcMapImpl implements RcMap.RcMap { readonly lookup: (key: K) => Effect, readonly context: Context.Context, readonly scope: Scope.Scope, - readonly idleTimeToLive: Duration.Duration | undefined, + readonly idleTimeToLive: ((key: K) => Duration.Duration) | undefined, readonly capacity: number ) { this[TypeId] = variance @@ -73,27 +74,32 @@ class RcMapImpl implements RcMap.RcMap { export const make: { (options: { readonly lookup: (key: K) => Effect - readonly idleTimeToLive?: Duration.DurationInput | undefined + readonly idleTimeToLive?: Duration.DurationInput | ((key: K) => Duration.DurationInput) | undefined readonly capacity?: undefined }): Effect, never, Scope.Scope | R> (options: { readonly lookup: (key: K) => Effect - readonly idleTimeToLive?: Duration.DurationInput | undefined + readonly idleTimeToLive?: Duration.DurationInput | ((key: K) => Duration.DurationInput) | undefined readonly capacity: number }): Effect, never, Scope.Scope | R> } = (options: { readonly lookup: (key: K) => Effect - readonly idleTimeToLive?: Duration.DurationInput | undefined + readonly idleTimeToLive?: Duration.DurationInput | ((key: K) => Duration.DurationInput) | undefined readonly capacity?: number | undefined }) => core.withFiberRuntime, never, R | Scope.Scope>((fiber) => { const context = fiber.getFiberRef(core.currentContext) as Context.Context const scope = Context.get(context, fiberRuntime.scopeTag) + const idleTimeToLive = options.idleTimeToLive === undefined + ? undefined + : typeof options.idleTimeToLive === "function" + ? flow(options.idleTimeToLive, Duration.decode) + : constant(Duration.decode(options.idleTimeToLive)) const self = new RcMapImpl( options.lookup as any, context, scope, - options.idleTimeToLive ? Duration.decode(options.idleTimeToLive) : undefined, + idleTimeToLive, Math.max(options.capacity ?? Number.POSITIVE_INFINITY, 0) ) return core.as( @@ -169,10 +175,12 @@ const acquire = core.fnUntraced(function*(self: RcMapImpl, key core.flatMap((exit) => core.deferredDone(deferred, exit)), circular.forkIn(scope) ) + const idleTimeToLive = self.idleTimeToLive ? self.idleTimeToLive(key) : Duration.zero const entry: State.Entry = { deferred, scope, finalizer: undefined as any, + idleTimeToLive, fiber: undefined, expiresAt: 0, refCount: 1 @@ -192,7 +200,7 @@ const release = (self: RcMapImpl, key: K, entry: State.Entry(self: RcMapImpl, key: K, entry: State.Entry { @@ -276,10 +284,12 @@ export const touch: { (self_: RcMap.RcMap, key: K) => coreEffect.clockWith((clock) => { const self = self_ as RcMapImpl - if (!self.idleTimeToLive || self.state._tag === "Closed") return core.void + if (self.state._tag === "Closed") return core.void const o = MutableHashMap.get(self.state.map, key) if (o._tag === "None") return core.void - o.value.expiresAt = clock.unsafeCurrentTimeMillis() + Duration.toMillis(self.idleTimeToLive) + const entry = o.value + if (Duration.isZero(entry.idleTimeToLive)) return core.void + entry.expiresAt = clock.unsafeCurrentTimeMillis() + Duration.toMillis(entry.idleTimeToLive) return core.void }) ) diff --git a/packages/effect/test/RcMap.test.ts b/packages/effect/test/RcMap.test.ts index e661149a5c0..5d5ec2b1fb3 100644 --- a/packages/effect/test/RcMap.test.ts +++ b/packages/effect/test/RcMap.test.ts @@ -175,4 +175,63 @@ describe("RcMap", () => { deepStrictEqual(yield* RcMap.keys(map), ["foo", "bar", "baz"]) })) + + it.scoped("dynamic idleTimeToLive", () => + Effect.gen(function*() { + const acquired: Array = [] + const released: Array = [] + const map = yield* RcMap.make({ + lookup: (key: string) => + Effect.acquireRelease( + Effect.sync(() => { + acquired.push(key) + return key + }), + () => Effect.sync(() => released.push(key)) + ), + idleTimeToLive: (key: string) => key.startsWith("short:") ? 500 : 2000 + }) + + deepStrictEqual(acquired, []) + + yield* Effect.scoped(RcMap.get(map, "short:a")) + yield* Effect.scoped(RcMap.get(map, "long:b")) + deepStrictEqual(acquired, ["short:a", "long:b"]) + deepStrictEqual(released, []) + + yield* TestClock.adjust(500) + deepStrictEqual(released, ["short:a"]) + + yield* TestClock.adjust(1500) + deepStrictEqual(released, ["short:a", "long:b"]) + })) + + it.scoped("dynamic idleTimeToLive with touch", () => + Effect.gen(function*() { + const acquired: Array = [] + const released: Array = [] + const map = yield* RcMap.make({ + lookup: (key: string) => + Effect.acquireRelease( + Effect.sync(() => { + acquired.push(key) + return key + }), + () => Effect.sync(() => released.push(key)) + ), + idleTimeToLive: (key: string) => key.startsWith("short:") ? 500 : 2000 + }) + + yield* Effect.scoped(RcMap.get(map, "short:a")) + deepStrictEqual(acquired, ["short:a"]) + deepStrictEqual(released, []) + + yield* TestClock.adjust(250) + yield* RcMap.touch(map, "short:a") + yield* TestClock.adjust(250) + deepStrictEqual(released, []) + + yield* TestClock.adjust(250) + deepStrictEqual(released, ["short:a"]) + })) }) diff --git a/packages/opentelemetry/test/Tracer.test.ts b/packages/opentelemetry/test/Tracer.test.ts index 0a2f6fa422e..7eefc8f4ded 100644 --- a/packages/opentelemetry/test/Tracer.test.ts +++ b/packages/opentelemetry/test/Tracer.test.ts @@ -4,16 +4,27 @@ import { assert, describe, expect, it } from "@effect/vitest" import * as OtelApi from "@opentelemetry/api" import { AsyncHooksContextManager } from "@opentelemetry/context-async-hooks" import { InMemorySpanExporter, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base" +import * as Console from "effect/Console" import * as Effect from "effect/Effect" +import * as FiberRef from "effect/FiberRef" +import * as Layer from "effect/Layer" import * as Runtime from "effect/Runtime" import { OtelSpan } from "../src/internal/tracer.js" -const TracingLive = NodeSdk.layer(Effect.sync(() => ({ - resource: { - serviceName: "test" - }, - spanProcessor: [new SimpleSpanProcessor(new InMemorySpanExporter())] -}))) +class Exporter extends Effect.Service()("Exporter", { + effect: Effect.sync(() => ({ exporter: new InMemorySpanExporter() })) +}) {} + +const TracingLive = Layer.unwrapEffect(Effect.gen(function*() { + const { exporter } = yield* Exporter + + return NodeSdk.layer(Effect.sync(() => ({ + resource: { + serviceName: "test" + }, + spanProcessor: [new SimpleSpanProcessor(exporter)] + }))) +})).pipe(Layer.provideMerge(Exporter.Default)) // needed to test context propagation const contextManager = new AsyncHooksContextManager() @@ -123,4 +134,59 @@ describe("Tracer", () => { }) )) }) + + describe("Log Attributes", () => { + it.effect("propagates attributes with Effect.fnUntraced", () => + Effect.gen(function*() { + const f = Effect.fnUntraced(function*() { + yield* Effect.logWarning("FooBar") + return yield* Effect.fail("Oops") + }) + + const p = f().pipe(Effect.withSpan("p")) + + yield* Effect.ignore(p) + + const { exporter } = yield* Exporter + + assert.isNotEmpty(exporter.getFinishedSpans()[0].events.filter((_) => _.name === "FooBar")) + assert.isNotEmpty(exporter.getFinishedSpans()[0].events.filter((_) => _.name === "exception")) + }).pipe(Effect.provide(TracingLive))) + + it.effect("propagates attributes with Effect.fn(name)", () => + Effect.gen(function*() { + const f = Effect.fn("f")(function*() { + yield* Effect.logWarning("FooBar") + return yield* Effect.fail("Oops") + }) + + const p = f().pipe(Effect.withSpan("p")) + + yield* Effect.ignore(p) + + const { exporter } = yield* Exporter + + assert.isNotEmpty(exporter.getFinishedSpans()[0].events.filter((_) => _.name === "FooBar")) + assert.isNotEmpty(exporter.getFinishedSpans()[0].events.filter((_) => _.name === "exception")) + }).pipe(Effect.provide(TracingLive))) + + it.effect("propagates attributes with Effect.fn", () => + Effect.gen(function*() { + const f = Effect.fn(function*() { + yield* Effect.logWarning("FooBar") + return yield* Effect.fail("Oops") + }) + + const p = f().pipe(Effect.withSpan("p")) + + yield* Effect.ignore(p) + + const { exporter } = yield* Exporter + + yield* Console.log(Array.from(yield* FiberRef.get(FiberRef.currentLoggers))) + + assert.isNotEmpty(exporter.getFinishedSpans()[0].events.filter((_) => _.name === "FooBar")) + assert.isNotEmpty(exporter.getFinishedSpans()[0].events.filter((_) => _.name === "exception")) + }).pipe(Effect.provide(TracingLive))) + }) }) diff --git a/packages/sql-pglite/CHANGELOG.md b/packages/sql-pglite/CHANGELOG.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/sql-pglite/LICENSE b/packages/sql-pglite/LICENSE new file mode 100644 index 00000000000..7f6fe480f77 --- /dev/null +++ b/packages/sql-pglite/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023-present The Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/sql-pglite/README.md b/packages/sql-pglite/README.md new file mode 100644 index 00000000000..ef2c920d27e --- /dev/null +++ b/packages/sql-pglite/README.md @@ -0,0 +1,7 @@ +# `@effect/sql-pglite` + +An `@effect/sql` implementation using the `@electric-sql/pglite` library. + +## Documentation + +- **API Reference**: [View the full documentation](https://effect-ts.github.io/effect/docs/sql-pglite). diff --git a/packages/sql-pglite/docgen.json b/packages/sql-pglite/docgen.json new file mode 100644 index 00000000000..7a5bad17ee8 --- /dev/null +++ b/packages/sql-pglite/docgen.json @@ -0,0 +1,24 @@ +{ + "$schema": "../../node_modules/@effect/docgen/schema.json", + "srcLink": "https://github.com/Effect-TS/effect/tree/main/packages/sql-pglite/src/", + "exclude": ["src/internal/**/*.ts"], + "examplesCompilerOptions": { + "noEmit": true, + "strict": true, + "skipLibCheck": true, + "moduleResolution": "Bundler", + "module": "ES2022", + "target": "ES2022", + "lib": ["ES2022", "DOM"], + "paths": { + "@effect/experimental": ["../../../experimental/src/index.js"], + "@effect/experimental/*": ["../../../experimental/src/*.js"], + "@effect/platform": ["../../../platform/src/index.js"], + "@effect/platform/*": ["../../../platform/src/*.js"], + "@effect/sql": ["../../../sql/src/index.js"], + "@effect/sql/*": ["../../../sql/src/*.js"], + "effect": ["../../../effect/src/index.js"], + "effect/*": ["../../../effect/src/*.js"] + } + } +} diff --git a/packages/sql-pglite/package.json b/packages/sql-pglite/package.json new file mode 100644 index 00000000000..1c3a45c3172 --- /dev/null +++ b/packages/sql-pglite/package.json @@ -0,0 +1,62 @@ +{ + "name": "@effect/sql-pglite", + "version": "0.0.0", + "type": "module", + "license": "MIT", + "description": "A PGlite driver for Effect Sql", + "homepage": "https://effect.website", + "repository": { + "type": "git", + "url": "https://github.com/Effect-TS/effect.git", + "directory": "packages/sql-pglite" + }, + "bugs": { + "url": "https://github.com/Effect-TS/effect/issues" + }, + "tags": [ + "typescript", + "sql", + "database" + ], + "keywords": [ + "typescript", + "sql", + "database" + ], + "publishConfig": { + "access": "public", + "directory": "dist", + "provenance": true + }, + "exports": { + ".": "./src/index.ts", + "./*": "./src/*.ts" + }, + "scripts": { + "codegen": "build-utils prepare-v3", + "build": "pnpm build-esm && pnpm build-annotate && pnpm build-cjs && build-utils pack-v3", + "build-esm": "tsc -b tsconfig.build.json", + "build-cjs": "babel build/esm --plugins @babel/transform-export-namespace-from --plugins @babel/transform-modules-commonjs --out-dir build/cjs --source-maps", + "build-annotate": "babel build/esm --plugins annotate-pure-calls --out-dir build/esm --source-maps", + "check": "tsc -b tsconfig.json", + "test": "vitest", + "coverage": "vitest --coverage" + }, + "devDependencies": { + "@effect/experimental": "workspace:^", + "@effect/platform": "workspace:^", + "@effect/sql": "workspace:^", + "effect": "workspace:^" + }, + "peerDependencies": { + "@effect/experimental": "workspace:^", + "@effect/platform": "workspace:^", + "@effect/sql": "workspace:^", + "effect": "workspace:^" + }, + "dependencies": { + "@electric-sql/pglite": "^0.3.2", + "@electric-sql/pglite-tools": "^0.2.7", + "@opentelemetry/semantic-conventions": "^1.33.0" + } +} diff --git a/packages/sql-pglite/src/PgliteClient.ts b/packages/sql-pglite/src/PgliteClient.ts new file mode 100644 index 00000000000..03e7d1a4111 --- /dev/null +++ b/packages/sql-pglite/src/PgliteClient.ts @@ -0,0 +1,333 @@ +/** + * @since 1.0.0 + */ +import * as Reactivity from "@effect/experimental/Reactivity" +import * as Client from "@effect/sql/SqlClient" +import type { Connection } from "@effect/sql/SqlConnection" +import { SqlError } from "@effect/sql/SqlError" +import type { Custom, Fragment } from "@effect/sql/Statement" +import * as Statement from "@effect/sql/Statement" +import type { Extensions, InitializedExtensions, PGliteOptions } from "@electric-sql/pglite" +import { PGlite } from "@electric-sql/pglite" +import * as OtelSemConv from "@opentelemetry/semantic-conventions" +import * as Config from "effect/Config" +import type { ConfigError } from "effect/ConfigError" +import * as Context from "effect/Context" +import * as Effect from "effect/Effect" +import * as Layer from "effect/Layer" +import type * as Scope from "effect/Scope" +import * as Stream from "effect/Stream" + +/** + * @category type ids + * @since 1.0.0 + */ +export const TypeId: unique symbol = Symbol.for("@effect/sql-pglite/PgliteClient") + +/** + * @category type ids + * @since 1.0.0 + */ +export type TypeId = typeof TypeId + +/** + * @category models + * @since 1.0.0 + */ +export interface PgliteClient extends Client.SqlClient { + readonly [TypeId]: TypeId + readonly config: PgliteClientConfig + readonly client: PGlite + readonly json: (_: unknown) => Fragment + readonly array: (_: ReadonlyArray) => Fragment + readonly listen: (channel: string) => Stream.Stream + readonly notify: (channel: string, payload: string) => Effect.Effect + readonly extensions: InitializedExtensions +} + +/** + * @category tags + * @since 1.0.0 + */ +export const PgliteClient = Context.GenericTag>("@effect/sql-pglite/PgliteClient") + +/** + * Returns the tag for PgliteClient with types added for extensions. + * Use this when you need to preserve extension types when retrieving the client from context. + * + * @example + * ```ts + * import { PgliteClient } from "@effect/sql-pglite" + * import { Effect } from "effect" + * + * // Create a tag for your client with extensions + * export const MyClient = PgliteClient.tag<{ + * // vector: typeof vector + * }>() + * + * // Use the tag to retrieve the client with correct extension types + * const program = Effect.gen(function*() { + * const client = yield* MyClient + * // client.extensions.vector is properly typed + * }) + * ``` + * + * @category tags + * @since 1.0.0 + */ +export const tag = () => + PgliteClient as Context.Tag, PgliteClient> + +/** + * @category constructors + * @since 1.0.0 + */ +export interface PgliteClientConfig extends PGliteOptions { + readonly transformResultNames?: ((str: string) => string) | undefined + readonly transformQueryNames?: ((str: string) => string) | undefined + readonly transformJson?: boolean | undefined + readonly applicationName?: string | undefined + readonly spanAttributes?: Record | undefined +} + +/** + * @category constructors + * @since 1.0.0 + */ +export const make = ( + options: PgliteClientConfig +): Effect.Effect, SqlError, Scope.Scope | Reactivity.Reactivity> => + Effect.gen(function*() { + const compiler = makeCompiler(options.transformQueryNames, options.transformJson) + const transformRows = options.transformResultNames + ? Statement.defaultTransforms(options.transformResultNames, options.transformJson).array + : undefined + + const client: PGlite = yield* Effect.tryPromise({ + try: () => + PGlite.create( + options.dataDir || "", + options + ), + catch: (cause) => new SqlError({ cause, message: "PgliteClient: Failed to connect" }) + }) + + yield* Effect.tryPromise({ + try: () => client.query("SELECT 1"), + catch: (cause) => new SqlError({ cause, message: "PgliteClient: Failed to query" }) + }) + + class ConnectionImpl implements Connection { + constructor(private readonly pg: PGlite) {} + + private run(query: Promise) { + return Effect.tryPromise, SqlError>({ + try: async () => (await query).rows, + catch: (cause) => new SqlError({ cause, message: "Failed to execute statement" }) + }) + } + + execute( + sql: string, + params: ReadonlyArray, + transformRows?: ((row: ReadonlyArray) => ReadonlyArray) | undefined, + unprepared?: boolean + ) { + return transformRows + ? Effect.map( + this.run( + unprepared ? this.pg.exec(sql, params as any) : this.pg.query(sql, params as any) + ), + transformRows + ) + : unprepared + ? this.run(this.pg.exec(sql, params as any)) + : this.run(this.pg.query(sql, params as any)) + } + executeRaw(sql: string, params: ReadonlyArray) { + return this.run(this.pg.exec(sql, params as any)) + } + executeWithoutTransform(sql: string, params: ReadonlyArray) { + return this.run(this.pg.query(sql, params as any)) + } + executeValues(sql: string, params: ReadonlyArray) { + return this.execute(sql, params, (r) => r.map((v) => Object.values(v) as any)) + } + executeUnprepared( + sql: string, + params: ReadonlyArray, + transformRows: ((row: ReadonlyArray) => ReadonlyArray) | undefined + ) { + return this.execute(sql, params, transformRows, true) + } + executeStream( + sql: string, + params: ReadonlyArray, + transformRows: ((row: ReadonlyArray) => ReadonlyArray) | undefined + ) { + // PGlite doesn't have a cursor method like postgres.js + // We'll fetch all results at once and convert to a stream + return Stream.fromIterableEffect( + Effect.map(this.run(this.pg.query(sql, params as any)), (rows) => { + const result = transformRows ? transformRows(rows) : rows + return result + }) + ) + } + } + + return Object.assign( + yield* Client.make({ + acquirer: Effect.succeed(new ConnectionImpl(client)), + compiler, + spanAttributes: [ + ...(options.spanAttributes ? Object.entries(options.spanAttributes) : []), + [OtelSemConv.ATTR_DB_SYSTEM_NAME, OtelSemConv.DB_SYSTEM_NAME_VALUE_POSTGRESQL], + [OtelSemConv.ATTR_DB_NAMESPACE, options.database ?? options.username ?? "postgres"] + ], + transformRows + }), + { + [TypeId]: TypeId as TypeId, + config: { + ...options + }, + client, + json: (_: unknown) => PgliteJson([_]), + array: (_: ReadonlyArray) => PgliteArray([_]), + extensions: options.extensions ? (client as any) : ({} as any), + listen: (channel: string) => + Stream.asyncPush((emit) => + Effect.acquireRelease( + Effect.tryPromise({ + try: async () => { + return await client.listen(channel, (payload) => emit.single(payload)) + }, + catch: (cause) => new SqlError({ cause, message: `Failed to listen on channel "${channel}"` }) + }), + (unsub) => + Effect.tryPromise({ + try: () => unsub(), + catch: (cause) => new SqlError({ cause, message: `Failed to unlisten on channel "${channel}"` }) + }).pipe(Effect.catchTag("SqlError", Effect.logError)) + ) + ), + + notify: (channel: string, payload: string) => + Effect.tryPromise({ + try: () => client.query(`NOTIFY ${channel}, '${payload}'`), + catch: (cause) => new SqlError({ cause, message: `Failed to notify on channel "${channel}"` }) + }).pipe(Effect.asVoid) + } + ) + }) + +/** + * @category layers + * @since 1.0.0 + */ +export const layerConfig = ( + config: Config.Config.Wrap> +): Layer.Layer | Client.SqlClient, ConfigError | SqlError> => + Layer.scopedContext( + Config.unwrap(config).pipe( + Effect.flatMap(make), + Effect.map((client) => + Context.make(PgliteClient, client as PgliteClient).pipe( + Context.add(Client.SqlClient, client) + ) + ) + ) + ).pipe(Layer.provide(Reactivity.layer)) + +/** + * @category layers + * @since 1.0.0 + */ +export const layer = = {}>( + config: PgliteClientConfig & { extensions?: Extensions } +): Layer.Layer | Client.SqlClient, ConfigError | SqlError> => + Layer.scopedContext( + Effect.map(make(config), (client) => + Context.make(PgliteClient, client as PgliteClient).pipe( + Context.add(Client.SqlClient, client) + )) + ).pipe(Layer.provide(Reactivity.layer)) + +/** + * @category constructor + * @since 1.0.0 + */ +export const makeCompiler = ( + transform?: (_: string) => string, + transformJson = true +): Statement.Compiler => { + const transformValue = transformJson && transform ? Statement.defaultTransforms(transform).value : undefined + + return Statement.makeCompiler({ + dialect: "pg", + placeholder(_) { + return `$${_}` + }, + onIdentifier: transform + ? function(value, withoutTransform) { + return withoutTransform ? escape(value) : escape(transform(value)) + } + : escape, + onRecordUpdate(placeholders, valueAlias, valueColumns, values, returning) { + return [ + `(values ${placeholders}) AS ${valueAlias}${valueColumns}${returning ? ` RETURNING ${returning[0]}` : ""}`, + returning ? values.flat().concat(returning[1]) : values.flat() + ] + }, + onCustom(type: PgliteCustom, placeholder, withoutTransform) { + switch (type.kind) { + case "PgliteJson": { + const value = withoutTransform || transformValue === undefined + ? type.i0[0] + : transformValue(type.i0[0]) + return [placeholder(undefined), [value]] + } + case "PgliteArray": { + const arrayValue = type.i0[0] + return [placeholder(undefined), [arrayValue]] + } + default: { + throw new Error(`Unknown custom type: ${type}`) + } + } + } + }) +} + +const escape = Statement.defaultEscape("\"") + +/** + * @category custom types + * @since 1.0.0 + */ +export type PgliteCustom = PgliteJson | PgliteArray + +/** + * @category custom types + * @since 1.0.0 + */ +export interface PgliteJson extends Custom<"PgliteJson", [unknown]> {} + +/** + * @category custom types + * @since 1.0.0 + */ +export const PgliteJson = Statement.custom("PgliteJson") + +/** + * @category custom types + * @since 1.0.0 + */ +export interface PgliteArray extends Custom<"PgliteArray", [ReadonlyArray]> {} + +/** + * @category custom types + * @since 1.0.0 + */ +export const PgliteArray = Statement.custom("PgliteArray") diff --git a/packages/sql-pglite/src/PgliteMigrator.ts b/packages/sql-pglite/src/PgliteMigrator.ts new file mode 100644 index 00000000000..8e44de2d5d4 --- /dev/null +++ b/packages/sql-pglite/src/PgliteMigrator.ts @@ -0,0 +1,92 @@ +/** + * @since 1.0.0 + */ +import { FileSystem } from "@effect/platform/FileSystem" +import { Path } from "@effect/platform/Path" +import * as Migrator from "@effect/sql/Migrator" +import type * as Client from "@effect/sql/SqlClient" +import type { SqlError } from "@effect/sql/SqlError" +import { pgDump } from "@electric-sql/pglite-tools/pg_dump" +import * as Effect from "effect/Effect" +import * as Layer from "effect/Layer" +import { PgliteClient } from "./PgliteClient.js" + +/** + * @since 1.0.0 + */ +export * from "@effect/sql/Migrator" + +/** + * @since 1.0.0 + */ +export * from "@effect/sql/Migrator/FileSystem" + +/** + * @category constructor + * @since 1.0.0 + */ +export const run: ( + options: Migrator.MigratorOptions +) => Effect.Effect< + ReadonlyArray, + Migrator.MigrationError | SqlError, + FileSystem | Path | PgliteClient | Client.SqlClient | R2 +> = Migrator.make({ + dumpSchema(path, table) { + const runPgDump = (args: Array) => + Effect.gen(function*() { + const pg = yield* PgliteClient + return Effect.tryPromise({ + try: async () => { + const file = await pgDump({ pg: pg.client, args }) + return (await file.text()) + .replace(/^--.*$/gm, "") + .replace(/^SET .*$/gm, "") + .replace(/^SELECT pg_catalog\..*$/gm, "") + .replace(/\n{2,}/gm, "\n\n") + .trim() + }, + catch: (error) => + new Migrator.MigrationError({ + reason: "failed", + message: error instanceof Error ? error.message : String(error) + }) + }) + }) + + const pgDumpSchema = runPgDump(["--schema-only"]) + + const pgDumpMigrations = runPgDump(["--column-inserts", "--data-only", `--table=${table}`]) + + const pgDumpAll = Effect.map( + Effect.all([pgDumpSchema, pgDumpMigrations], { concurrency: 2 }), + ([schema, migrations]) => schema + "\n\n" + migrations + ) + + const pgDumpFile = (path: string) => + Effect.gen(function*() { + const fs = yield* FileSystem + const { dirname } = yield* Path + const dump = yield* pgDumpAll + yield* fs.makeDirectory(dirname(path), { recursive: true }) + yield* fs.writeFileString(path, dump) + }).pipe( + Effect.mapError( + (error) => new Migrator.MigrationError({ reason: "failed", message: error.message }) + ) + ) + + return pgDumpFile(path) + } +}) +/** + * @category layers + * @since 1.0.0 + */ +export const layer = ( + options: Migrator.MigratorOptions +): Layer.Layer< + never, + Migrator.MigrationError | SqlError, + PgliteClient | Client.SqlClient | FileSystem | Path | R +> => Layer.effectDiscard(run(options)) diff --git a/packages/sql-pglite/src/index.ts b/packages/sql-pglite/src/index.ts new file mode 100644 index 00000000000..e545d427ee4 --- /dev/null +++ b/packages/sql-pglite/src/index.ts @@ -0,0 +1,9 @@ +/** + * @since 1.0.0 + */ +export * as PgliteClient from "./PgliteClient.js" + +/** + * @since 1.0.0 + */ +export * as PgliteMigrator from "./PgliteMigrator.js" diff --git a/packages/sql-pglite/test/Client.test.ts b/packages/sql-pglite/test/Client.test.ts new file mode 100644 index 00000000000..aedcf60cf60 --- /dev/null +++ b/packages/sql-pglite/test/Client.test.ts @@ -0,0 +1,292 @@ +import { PgliteClient } from "@effect/sql-pglite" +import * as Statement from "@effect/sql/Statement" +import { assert, describe, expect, it } from "@effect/vitest" +import { Effect, String } from "effect" + +const compilerTransform = PgliteClient.makeCompiler(String.camelToSnake) +const transformsNested = Statement.defaultTransforms(String.snakeToCamel) +const transforms = Statement.defaultTransforms(String.snakeToCamel, false) + +const ClientLive = PgliteClient.layer({ dataDir: "memory://" }) +const ClientTransformLive = PgliteClient.layer({ + transformResultNames: String.snakeToCamel, + transformQueryNames: String.camelToSnake, + dataDir: "memory://" +}) + +describe("PgliteClient", () => { + it.layer(ClientLive, { timeout: "30 seconds" })("PgliteClient", (it) => { + it.effect("insert helper", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query, params] = sql`INSERT INTO people ${sql.insert({ name: "Tim", age: 10 })}`.compile() + expect(query).toEqual(`INSERT INTO people ("name","age") VALUES ($1,$2)`) + expect(params).toEqual(["Tim", 10]) + })) + + it.effect("updateValues helper", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query, params] = sql`UPDATE people SET name = data.name FROM ${ + sql.updateValues( + [{ name: "Tim" }, { name: "John" }], + "data" + ) + }`.compile() + expect(query).toEqual( + `UPDATE people SET name = data.name FROM (values ($1),($2)) AS data("name")` + ) + expect(params).toEqual(["Tim", "John"]) + })) + + it.effect("updateValues helper returning", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query, params] = sql`UPDATE people SET name = data.name FROM ${ + sql + .updateValues([{ name: "Tim" }, { name: "John" }], "data") + .returning("*") + }`.compile() + expect(query).toEqual( + `UPDATE people SET name = data.name FROM (values ($1),($2)) AS data("name") RETURNING *` + ) + expect(params).toEqual(["Tim", "John"]) + })) + + it.effect("update helper", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + let result = sql`UPDATE people SET ${sql.update({ name: "Tim" })}`.compile() + expect(result[0]).toEqual(`UPDATE people SET "name" = $1`) + expect(result[1]).toEqual(["Tim"]) + + result = sql`UPDATE people SET ${sql.update({ name: "Tim", age: 10 }, ["age"])}`.compile() + expect(result[0]).toEqual(`UPDATE people SET "name" = $1`) + expect(result[1]).toEqual(["Tim"]) + })) + + it.effect("update helper returning", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const result = sql`UPDATE people SET ${sql.update({ name: "Tim" }).returning("*")}`.compile() + expect(result[0]).toEqual(`UPDATE people SET "name" = $1 RETURNING *`) + expect(result[1]).toEqual(["Tim"]) + })) + + it.effect("array helper", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query, params] = sql`SELECT * FROM ${sql("people")} WHERE id IN ${sql.in([1, 2, "string"])}`.compile() + expect(query).toEqual(`SELECT * FROM "people" WHERE id IN ($1,$2,$3)`) + expect(params).toEqual([1, 2, "string"]) + })) + + it.effect("array helper with column", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + let result = sql`SELECT * FROM ${sql("people")} WHERE ${sql.in("id", [1, 2, "string"])}`.compile() + expect(result[0]).toEqual(`SELECT * FROM "people" WHERE "id" IN ($1,$2,$3)`) + expect(result[1]).toEqual([1, 2, "string"]) + + result = sql`SELECT * FROM ${sql("people")} WHERE ${sql.in("id", [])}`.compile() + expect(result[0]).toEqual(`SELECT * FROM "people" WHERE 1=0`) + expect(result[1]).toEqual([]) + })) + + it.effect("and", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const now = new Date() + const result = sql`SELECT * FROM ${sql("people")} WHERE ${ + sql.and([ + sql.in("name", ["Tim", "John"]), + sql`created_at < ${now}` + ]) + }`.compile() + expect(result[0]).toEqual( + `SELECT * FROM "people" WHERE ("name" IN ($1,$2) AND created_at < $3)` + ) + expect(result[1]).toEqual(["Tim", "John", now]) + })) + + it.effect("json", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query] = sql`SELECT ${sql.json({ a: 1 })}`.compile() + expect(query).toEqual(`SELECT $1`) + })) + + it.effect("json transform", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query, params] = compilerTransform.compile( + sql`SELECT ${sql.json({ aKey: 1 })}`, + false + ) + expect(query).toEqual(`SELECT $1`) + assert.deepEqual(params[0] as any, { a_key: 1 }) + })) + + it.effect("array", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query, params] = sql`SELECT ${sql.array([1, 2, 3])}`.compile() + expect(query).toEqual(`SELECT $1`) + expect(params[0] as any).toEqual([1, 2, 3]) + })) + + it("transform nested", () => { + assert.deepEqual( + transformsNested.array([ + { + a_key: 1, + nested: [{ b_key: 2 }], + arr_primitive: [1, "2", true] + } + ]) as any, + [ + { + aKey: 1, + nested: [{ bKey: 2 }], + arrPrimitive: [1, "2", true] + } + ] + ) + }) + + it("transform non nested", () => { + assert.deepEqual( + transforms.array([ + { + a_key: 1, + nested: [{ b_key: 2 }], + arr_primitive: [1, "2", true] + } + ]) as any, + [ + { + aKey: 1, + nested: [{ b_key: 2 }], + arrPrimitive: [1, "2", true] + } + ] + ) + + assert.deepEqual( + transforms.array([ + { + json_field: { + test_value: [1, true, null, "text"], + test_nested: { + test_value: [1, true, null, "text"] + } + } + } + ]) as any, + [ + { + jsonField: { + test_value: [1, true, null, "text"], + test_nested: { + test_value: [1, true, null, "text"] + } + } + } + ] + ) + }) + + it.effect("insert fragments", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query, params] = sql`INSERT INTO people ${ + sql.insert({ + name: "Tim", + age: 10, + json: sql.json({ a: 1 }) + }) + }`.compile() + assert.strictEqual(query, "INSERT INTO people (\"name\",\"age\",\"json\") VALUES ($1,$2,$3)") + assert.lengthOf(params, 3) + // expect((params[2] as any).type).toEqual(3802) + })) + + it.effect("insert array", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query, params] = sql`INSERT INTO people ${ + sql.insert({ + name: "Tim", + age: 10, + array: sql.array([1, 2, 3]) + }) + }`.compile() + assert.strictEqual(query, "INSERT INTO people (\"name\",\"age\",\"array\") VALUES ($1,$2,$3)") + assert.lengthOf(params, 3) + })) + + it.effect("update fragments", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const now = new Date() + const [query, params] = sql`UPDATE people SET json = data.json FROM ${ + sql.updateValues( + [{ json: sql.json({ a: 1 }) }, { json: sql.json({ b: 1 }) }], + "data" + ) + } WHERE created_at > ${now}`.compile() + assert.strictEqual( + query, + `UPDATE people SET json = data.json FROM (values ($1),($2)) AS data("json") WHERE created_at > $3` + ) + assert.lengthOf(params, 3) + })) + + it.effect("onDialect", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + assert.strictEqual( + sql.onDialect({ + sqlite: () => "A", + pg: () => "B", + mysql: () => "C", + mssql: () => "D", + clickhouse: () => "E" + }), + "B" + ) + assert.strictEqual( + sql.onDialectOrElse({ + orElse: () => "A", + pg: () => "B" + }), + "B" + ) + })) + + it.effect("identifier transform", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query] = compilerTransform.compile(sql`SELECT * from ${sql("peopleTest")}`, false) + expect(query).toEqual(`SELECT * from "people_test"`) + })) + }) + + it.layer(ClientTransformLive, { timeout: "30 seconds" })("PgliteClient transforms", (it) => { + it.effect("insert helper", () => + Effect.gen(function*() { + const sql = yield* PgliteClient.PgliteClient + const [query, params] = sql`INSERT INTO people ${sql.insert({ firstName: "Tim", age: 10 })}`.compile() + expect(query).toEqual(`INSERT INTO people ("first_name","age") VALUES ($1,$2)`) + expect(params).toEqual(["Tim", 10]) + })) + + it.effect("insert helper withoutTransforms", () => + Effect.gen(function*() { + const sql = (yield* PgliteClient.PgliteClient).withoutTransforms() + const [query, params] = sql`INSERT INTO people ${sql.insert({ first_name: "Tim", age: 10 })}`.compile() + expect(query).toEqual(`INSERT INTO people ("first_name","age") VALUES ($1,$2)`) + expect(params).toEqual(["Tim", 10]) + })) + }) +}) diff --git a/packages/sql-pglite/tsconfig.build.json b/packages/sql-pglite/tsconfig.build.json new file mode 100644 index 00000000000..8a5c6b4d6ee --- /dev/null +++ b/packages/sql-pglite/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.src.json", + "references": [ + { "path": "../effect/tsconfig.build.json" }, + { "path": "../sql/tsconfig.build.json" } + ], + "compilerOptions": { + "tsBuildInfoFile": ".tsbuildinfo/build.tsbuildinfo", + "outDir": "build/esm", + "declarationDir": "build/dts", + "stripInternal": true + } +} diff --git a/packages/sql-pglite/tsconfig.json b/packages/sql-pglite/tsconfig.json new file mode 100644 index 00000000000..2c291d2192d --- /dev/null +++ b/packages/sql-pglite/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": [], + "references": [ + { "path": "tsconfig.src.json" }, + { "path": "tsconfig.test.json" } + ] +} diff --git a/packages/sql-pglite/tsconfig.src.json b/packages/sql-pglite/tsconfig.src.json new file mode 100644 index 00000000000..13590c3e70a --- /dev/null +++ b/packages/sql-pglite/tsconfig.src.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src"], + "references": [ + { "path": "../effect/tsconfig.src.json" }, + { "path": "../sql/tsconfig.src.json" } + ], + "compilerOptions": { + "tsBuildInfoFile": ".tsbuildinfo/src.tsbuildinfo", + "rootDir": "src", + "outDir": "build/src", + "types": ["node"] + } +} diff --git a/packages/sql-pglite/tsconfig.test.json b/packages/sql-pglite/tsconfig.test.json new file mode 100644 index 00000000000..88df34fca95 --- /dev/null +++ b/packages/sql-pglite/tsconfig.test.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["test"], + "references": [ + { "path": "tsconfig.src.json" }, + { "path": "../vitest/tsconfig.src.json" } + ], + "compilerOptions": { + "tsBuildInfoFile": ".tsbuildinfo/test.tsbuildinfo", + "rootDir": "test", + "outDir": "build/test" + } +} diff --git a/packages/sql-pglite/vitest.config.ts b/packages/sql-pglite/vitest.config.ts new file mode 100644 index 00000000000..578d0667249 --- /dev/null +++ b/packages/sql-pglite/vitest.config.ts @@ -0,0 +1,6 @@ +import { mergeConfig, type ViteUserConfig } from "vitest/config" +import shared from "../../vitest.shared.js" + +const config: ViteUserConfig = {} + +export default mergeConfig(shared, config) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9066efb7e13..c10d4884452 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -770,7 +770,7 @@ importers: version: 10.28.0 drizzle-orm: specifier: ^0.43.1 - version: 0.43.1(@cloudflare/workers-types@4.20250715.0)(@libsql/client@0.12.0)(@op-engineering/op-sqlite@7.1.0(react-native@0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@11.10.0)(bun-types@1.2.18(@types/react@19.1.8))(kysely@0.28.2)(mysql2@3.14.2)(pg@8.16.3)(postgres@3.4.7) + version: 0.43.1(@cloudflare/workers-types@4.20250715.0)(@electric-sql/pglite@0.3.2)(@libsql/client@0.12.0)(@op-engineering/op-sqlite@7.1.0(react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@11.10.0)(bun-types@1.2.18(@types/react@19.1.8))(kysely@0.28.2)(mysql2@3.14.2)(pg@8.16.3)(postgres@3.4.7) effect: specifier: workspace:^ version: link:../effect @@ -926,6 +926,32 @@ importers: version: link:../effect publishDirectory: dist + packages/sql-pglite: + dependencies: + '@electric-sql/pglite': + specifier: ^0.3.2 + version: 0.3.2 + '@electric-sql/pglite-tools': + specifier: ^0.2.7 + version: 0.2.7(@electric-sql/pglite@0.3.2) + '@opentelemetry/semantic-conventions': + specifier: ^1.33.0 + version: 1.36.0 + devDependencies: + '@effect/experimental': + specifier: workspace:^ + version: link:../experimental + '@effect/platform': + specifier: workspace:^ + version: link:../platform + '@effect/sql': + specifier: workspace:^ + version: link:../sql + effect: + specifier: workspace:^ + version: link:../effect + publishDirectory: dist + packages/sql-sqlite-bun: devDependencies: '@effect/experimental': @@ -1000,7 +1026,7 @@ importers: version: link:../sql '@op-engineering/op-sqlite': specifier: 7.1.0 - version: 7.1.0(react-native@0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) + version: 7.1.0(react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) effect: specifier: workspace:^ version: link:../effect @@ -1036,7 +1062,7 @@ importers: version: link:../effect vitest: specifier: ^3.2.4 - version: 3.2.4(@edge-runtime/vm@5.0.0)(@types/node@24.10.1)(@vitest/browser@3.2.4)(happy-dom@17.6.3)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@edge-runtime/vm@5.0.0)(@types/node@24.0.14)(@vitest/browser@3.2.4)(happy-dom@17.6.3)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) publishDirectory: dist packages/workflow: @@ -1273,10 +1299,6 @@ packages: resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.5': - resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} - engines: {node: '>=6.9.0'} - '@babel/generator@7.12.17': resolution: {integrity: sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg==} @@ -1284,10 +1306,6 @@ packages: resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.28.5': - resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} - engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} @@ -1320,12 +1338,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@7.28.3': - resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.27.1': resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} @@ -1352,10 +1364,6 @@ packages: resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} @@ -1364,20 +1372,11 @@ packages: resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.4': - resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} - engines: {node: '>=6.9.0'} - '@babel/parser@7.28.0': resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/plugin-syntax-async-generators@7.8.4': resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -1545,10 +1544,6 @@ packages: resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} - engines: {node: '>=6.9.0'} - '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} @@ -1557,18 +1552,10 @@ packages: resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.5': - resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} - engines: {node: '>=6.9.0'} - '@babel/types@7.28.1': resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} - engines: {node: '>=6.9.0'} - '@balena/dockerignore@1.0.2': resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==} @@ -1727,6 +1714,14 @@ packages: '@effect/wa-sqlite@0.1.2': resolution: {integrity: sha512-2JvJ9BDkBOwfeY/gXsC0XwEKC0AwisP2W5ABJ6mx14QyXTK12MGDIybDlHieuZt1TEFSMiKfpg7yyqyRWRooJQ==} + '@electric-sql/pglite-tools@0.2.7': + resolution: {integrity: sha512-9dAccClqxx4cZB+Ar9B+FZ5WgxDc/Xvl9DPrTWv+dYTf0YNubLzi4wHHRGRGhrJv15XwnyKcGOZAP1VXSneSUg==} + peerDependencies: + '@electric-sql/pglite': 0.3.2 + + '@electric-sql/pglite@0.3.2': + resolution: {integrity: sha512-zfWWa+V2ViDCY/cmUfRqeWY1yLto+EpxjXnZzenB1TyxsTiXaTWeZFIZw6mac52BsuQm0RjCnisjBtdBaXOI6w==} + '@emnapi/core@1.4.4': resolution: {integrity: sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g==} @@ -2135,31 +2130,19 @@ packages: '@jridgewell/gen-mapping@0.3.12': resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/source-map@0.3.11': - resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + '@jridgewell/source-map@0.3.10': + resolution: {integrity: sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==} '@jridgewell/sourcemap-codec@1.5.4': resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.29': resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -2404,6 +2387,10 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/semantic-conventions@1.36.0': + resolution: {integrity: sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ==} + engines: {node: '>=14'} + '@opentelemetry/semantic-conventions@1.38.0': resolution: {integrity: sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==} engines: {node: '>=14'} @@ -2808,8 +2795,8 @@ packages: '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} '@types/better-sqlite3@7.6.13': resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} @@ -2896,8 +2883,8 @@ packages: '@types/node@22.16.4': resolution: {integrity: sha512-PYRhNtZdm2wH/NT2k/oAJ6/f2VD2N2Dag0lGlx2vWgMSJXGNmlce5MiTQzoWAiIJtso30mjnfQCOKVH+kAQC/g==} - '@types/node@24.10.1': - resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + '@types/node@24.0.14': + resolution: {integrity: sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -6800,8 +6787,8 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} undici@5.29.0: resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} @@ -7351,26 +7338,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/core@7.28.5': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) - '@babel/helpers': 7.28.4 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/generator@7.12.17': dependencies: '@babel/types': 7.28.1 @@ -7385,14 +7352,6 @@ snapshots: '@jridgewell/trace-mapping': 0.3.29 jsesc: 3.1.0 - '@babel/generator@7.28.5': - dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.27.3': dependencies: '@babel/types': 7.28.1 @@ -7443,15 +7402,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': - dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.5 - transitivePeerDependencies: - - supports-color - '@babel/helper-optimise-call-expression@7.27.1': dependencies: '@babel/types': 7.28.1 @@ -7478,8 +7428,6 @@ snapshots: '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helper-validator-option@7.27.1': {} '@babel/helpers@7.27.6': @@ -7487,37 +7435,28 @@ snapshots: '@babel/template': 7.27.2 '@babel/types': 7.28.1 - '@babel/helpers@7.28.4': - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 - '@babel/parser@7.28.0': dependencies: '@babel/types': 7.28.1 - '@babel/parser@7.28.5': - dependencies: - '@babel/types': 7.28.5 - - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.5)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.5)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.5)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.0)': @@ -7525,19 +7464,19 @@ snapshots: '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': @@ -7545,44 +7484,44 @@ snapshots: '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.5)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.5)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.5)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.5)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': @@ -7678,8 +7617,6 @@ snapshots: '@babel/runtime@7.27.6': {} - '@babel/runtime@7.28.4': {} - '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -7698,28 +7635,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/traverse@7.28.5': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.5 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.5 - '@babel/template': 7.27.2 - '@babel/types': 7.28.5 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - '@babel/types@7.28.1': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/types@7.28.5': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - '@balena/dockerignore@1.0.2': {} '@bcoe/v8-coverage@1.0.2': {} @@ -7963,6 +7883,12 @@ snapshots: '@effect/wa-sqlite@0.1.2': {} + '@electric-sql/pglite-tools@0.2.7(@electric-sql/pglite@0.3.2)': + dependencies: + '@electric-sql/pglite': 0.3.2 + + '@electric-sql/pglite@0.3.2': {} + '@emnapi/core@1.4.4': dependencies: '@emnapi/wasi-threads': 1.0.3 @@ -8244,7 +8170,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 24.10.1 + '@types/node': 22.16.4 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -8255,7 +8181,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 24.10.1 + '@types/node': 22.16.4 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -8266,9 +8192,9 @@ snapshots: '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/trace-mapping': 0.3.29 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 @@ -8298,37 +8224,20 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.4 '@jridgewell/trace-mapping': 0.3.29 - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/source-map@0.3.11': + '@jridgewell/source-map@0.3.10': dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 '@jridgewell/sourcemap-codec@1.5.4': {} - '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.29': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.4 - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -8473,10 +8382,10 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@op-engineering/op-sqlite@7.1.0(react-native@0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0)': + '@op-engineering/op-sqlite@7.1.0(react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0)': dependencies: react: 19.1.0 - react-native: 0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0) + react-native: 0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0) '@opentelemetry/api-logs@0.208.0': dependencies: @@ -8574,6 +8483,8 @@ snapshots: '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions@1.36.0': {} + '@opentelemetry/semantic-conventions@1.38.0': {} '@parcel/watcher-android-arm64@2.5.1': @@ -8680,9 +8591,9 @@ snapshots: '@react-native/assets-registry@0.80.1': {} - '@react-native/codegen@0.80.1(@babel/core@7.28.5)': + '@react-native/codegen@0.80.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 glob: 7.2.3 hermes-parser: 0.28.1 invariant: 2.2.4 @@ -8730,12 +8641,12 @@ snapshots: '@react-native/normalize-colors@0.80.1': {} - '@react-native/virtualized-lists@0.80.1(@types/react@19.1.8)(react-native@0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0)': + '@react-native/virtualized-lists@0.80.1(@types/react@19.1.8)(react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0)': dependencies: invariant: 2.2.4 nullthrows: 1.1.1 react: 19.1.0 - react-native: 0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0) + react-native: 0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0) optionalDependencies: '@types/react': 19.1.8 @@ -8935,24 +8846,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.1 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 + '@types/babel__traverse': 7.20.7 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.28.1 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.1 - '@types/babel__traverse@7.28.0': + '@types/babel__traverse@7.20.7': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.28.1 '@types/better-sqlite3@7.6.13': dependencies: @@ -9003,7 +8914,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 24.10.1 + '@types/node': 22.16.4 '@types/ini@4.1.1': {} @@ -9054,9 +8965,10 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.10.1': + '@types/node@24.0.14': dependencies: - undici-types: 7.16.0 + undici-types: 7.8.0 + optional: true '@types/normalize-package-data@2.4.4': {} @@ -9311,16 +9223,16 @@ snapshots: - utf-8-validate - vite - '@vitest/browser@3.2.4(playwright@1.54.1)(vite@6.3.5(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4)': + '@vitest/browser@3.2.4(playwright@1.54.1)(vite@6.3.5(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4)': dependencies: '@testing-library/dom': 10.4.0 '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0) - '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0)) + '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0)) '@vitest/utils': 3.2.4 magic-string: 0.30.17 sirv: 3.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@edge-runtime/vm@5.0.0)(@types/node@24.10.1)(@vitest/browser@3.2.4)(happy-dom@17.6.3)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) + vitest: 3.2.4(@edge-runtime/vm@5.0.0)(@types/node@24.0.14)(@vitest/browser@3.2.4)(happy-dom@17.6.3)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) ws: 8.18.3 optionalDependencies: playwright: 1.54.1 @@ -9368,13 +9280,13 @@ snapshots: optionalDependencies: vite: 6.3.5(@types/node@22.16.4)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) - '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0))': + '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) '@vitest/pretty-format@3.2.4': dependencies: @@ -9597,13 +9509,13 @@ snapshots: b4a@1.6.7: {} - babel-jest@29.7.0(@babel/core@7.28.5): + babel-jest@29.7.0(@babel/core@7.28.0): dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 '@jest/transform': 29.7.0 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.28.5) + babel-preset-jest: 29.6.3(@babel/core@7.28.0) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -9627,38 +9539,38 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.5 + '@babel/types': 7.28.1 '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.28.0 + '@types/babel__traverse': 7.20.7 babel-plugin-syntax-hermes-parser@0.28.1: dependencies: hermes-parser: 0.28.1 - babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.5): - dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.5) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.5) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.5) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.5) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.5) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.5) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.5) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.5) - - babel-preset-jest@29.6.3(@babel/core@7.28.5): - dependencies: - '@babel/core': 7.28.5 + babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.0): + dependencies: + '@babel/core': 7.28.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.0) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.0) + + babel-preset-jest@29.6.3(@babel/core@7.28.0): + dependencies: + '@babel/core': 7.28.0 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.0) balanced-match@1.0.2: {} @@ -9880,7 +9792,7 @@ snapshots: chrome-launcher@0.15.2: dependencies: - '@types/node': 24.10.1 + '@types/node': 22.16.4 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -9889,7 +9801,7 @@ snapshots: chromium-edge-launcher@0.2.0: dependencies: - '@types/node': 24.10.1 + '@types/node': 22.16.4 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -10248,11 +10160,12 @@ snapshots: dotenv@8.6.0: {} - drizzle-orm@0.43.1(@cloudflare/workers-types@4.20250715.0)(@libsql/client@0.12.0)(@op-engineering/op-sqlite@7.1.0(react-native@0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@11.10.0)(bun-types@1.2.18(@types/react@19.1.8))(kysely@0.28.2)(mysql2@3.14.2)(pg@8.16.3)(postgres@3.4.7): + drizzle-orm@0.43.1(@cloudflare/workers-types@4.20250715.0)(@electric-sql/pglite@0.3.2)(@libsql/client@0.12.0)(@op-engineering/op-sqlite@7.1.0(react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@11.10.0)(bun-types@1.2.18(@types/react@19.1.8))(kysely@0.28.2)(mysql2@3.14.2)(pg@8.16.3)(postgres@3.4.7): optionalDependencies: '@cloudflare/workers-types': 4.20250715.0 + '@electric-sql/pglite': 0.3.2 '@libsql/client': 0.12.0 - '@op-engineering/op-sqlite': 7.1.0(react-native@0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) + '@op-engineering/op-sqlite': 7.1.0(react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) '@opentelemetry/api': 1.9.0 '@types/better-sqlite3': 7.6.13 '@types/pg': 8.15.6 @@ -11345,8 +11258,8 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.28.5 - '@babel/parser': 7.28.5 + '@babel/core': 7.28.0 + '@babel/parser': 7.28.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -11394,7 +11307,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 24.10.1 + '@types/node': 22.16.4 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -11404,7 +11317,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 24.10.1 + '@types/node': 22.16.4 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -11438,7 +11351,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 24.10.1 + '@types/node': 22.16.4 jest-util: 29.7.0 jest-regex-util@29.6.3: {} @@ -11463,7 +11376,7 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 24.10.1 + '@types/node': 22.16.4 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -11792,7 +11705,7 @@ snapshots: metro-babel-transformer@0.82.5: dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.0 flow-enums-runtime: 0.0.6 hermes-parser: 0.29.1 nullthrows: 1.1.1 @@ -11858,14 +11771,14 @@ snapshots: metro-runtime@0.82.5: dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.27.6 flow-enums-runtime: 0.0.6 metro-source-map@0.82.5: dependencies: - '@babel/traverse': 7.28.5 - '@babel/traverse--for-generate-function-map': '@babel/traverse@7.28.5' - '@babel/types': 7.28.5 + '@babel/traverse': 7.28.0 + '@babel/traverse--for-generate-function-map': '@babel/traverse@7.28.0' + '@babel/types': 7.28.1 flow-enums-runtime: 0.0.6 invariant: 2.2.4 metro-symbolicate: 0.82.5 @@ -11889,10 +11802,10 @@ snapshots: metro-transform-plugins@0.82.5: dependencies: - '@babel/core': 7.28.5 - '@babel/generator': 7.28.5 + '@babel/core': 7.28.0 + '@babel/generator': 7.28.0 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.28.0 flow-enums-runtime: 0.0.6 nullthrows: 1.1.1 transitivePeerDependencies: @@ -11900,10 +11813,10 @@ snapshots: metro-transform-worker@0.82.5: dependencies: - '@babel/core': 7.28.5 - '@babel/generator': 7.28.5 - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/core': 7.28.0 + '@babel/generator': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.1 flow-enums-runtime: 0.0.6 metro: 0.82.5 metro-babel-transformer: 0.82.5 @@ -11921,12 +11834,12 @@ snapshots: metro@0.82.5: dependencies: '@babel/code-frame': 7.27.1 - '@babel/core': 7.28.5 - '@babel/generator': 7.28.5 - '@babel/parser': 7.28.5 + '@babel/core': 7.28.0 + '@babel/generator': 7.28.0 + '@babel/parser': 7.28.0 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 - '@babel/types': 7.28.5 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.1 accepts: 1.3.8 chalk: 4.1.2 ci-info: 2.0.0 @@ -12603,7 +12516,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 24.10.1 + '@types/node': 22.16.4 long: 5.3.2 pump@3.0.3: @@ -12652,20 +12565,20 @@ snapshots: react-is@18.3.1: {} - react-native@0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0): + react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0): dependencies: '@jest/create-cache-key-function': 29.7.0 '@react-native/assets-registry': 0.80.1 - '@react-native/codegen': 0.80.1(@babel/core@7.28.5) + '@react-native/codegen': 0.80.1(@babel/core@7.28.0) '@react-native/community-cli-plugin': 0.80.1 '@react-native/gradle-plugin': 0.80.1 '@react-native/js-polyfills': 0.80.1 '@react-native/normalize-colors': 0.80.1 - '@react-native/virtualized-lists': 0.80.1(@types/react@19.1.8)(react-native@0.80.1(@babel/core@7.28.5)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) + '@react-native/virtualized-lists': 0.80.1(@types/react@19.1.8)(react-native@0.80.1(@babel/core@7.28.0)(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) abort-controller: 3.0.0 anser: 1.4.10 ansi-regex: 5.0.1 - babel-jest: 29.7.0(@babel/core@7.28.5) + babel-jest: 29.7.0(@babel/core@7.28.0) babel-plugin-syntax-hermes-parser: 0.28.1 base64-js: 1.5.1 chalk: 4.1.2 @@ -13330,7 +13243,7 @@ snapshots: terser@5.44.1: dependencies: - '@jridgewell/source-map': 0.3.11 + '@jridgewell/source-map': 0.3.10 acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -13557,7 +13470,8 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.16.0: {} + undici-types@7.8.0: + optional: true undici@5.29.0: dependencies: @@ -13645,13 +13559,13 @@ snapshots: - tsx - yaml - vite-node@3.2.4(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0): + vite-node@3.2.4(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0): dependencies: cac: 6.7.14 debug: 4.4.1 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -13681,7 +13595,7 @@ snapshots: tsx: 4.20.3 yaml: 2.8.0 - vite@6.3.5(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0): + vite@6.3.5(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0): dependencies: esbuild: 0.25.6 fdir: 6.4.6(picomatch@4.0.3) @@ -13690,7 +13604,7 @@ snapshots: rollup: 4.45.1 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 24.10.1 + '@types/node': 24.0.14 fsevents: 2.3.3 terser: 5.44.1 tsx: 4.20.3 @@ -13700,7 +13614,7 @@ snapshots: dependencies: '@vitest/utils': 3.2.4 mock-socket: 9.3.1 - vitest: 3.2.4(@edge-runtime/vm@5.0.0)(@types/node@24.10.1)(@vitest/browser@3.2.4)(happy-dom@17.6.3)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) + vitest: 3.2.4(@edge-runtime/vm@5.0.0)(@types/node@24.0.14)(@vitest/browser@3.2.4)(happy-dom@17.6.3)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) vitest@3.2.4(@edge-runtime/vm@5.0.0)(@types/node@22.16.4)(@vitest/browser@3.2.4)(happy-dom@17.6.3)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0): dependencies: @@ -13746,11 +13660,11 @@ snapshots: - tsx - yaml - vitest@3.2.4(@edge-runtime/vm@5.0.0)(@types/node@24.10.1)(@vitest/browser@3.2.4)(happy-dom@17.6.3)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0): + vitest@3.2.4(@edge-runtime/vm@5.0.0)(@types/node@24.0.14)(@vitest/browser@3.2.4)(happy-dom@17.6.3)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0)) + '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -13768,13 +13682,13 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) - vite-node: 3.2.4(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: '@edge-runtime/vm': 5.0.0 - '@types/node': 24.10.1 - '@vitest/browser': 3.2.4(playwright@1.54.1)(vite@6.3.5(@types/node@24.10.1)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4) + '@types/node': 24.0.14 + '@vitest/browser': 3.2.4(playwright@1.54.1)(vite@6.3.5(@types/node@24.0.14)(terser@5.44.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4) happy-dom: 17.6.3 transitivePeerDependencies: - jiti diff --git a/tsconfig.base.json b/tsconfig.base.json index 7cc6f2eb2da..0c4f8ba5c98 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -75,4 +75,4 @@ } ] } -} +} \ No newline at end of file diff --git a/tsconfig.build.json b/tsconfig.build.json index 9ea6632c8c6..2c5e4bbfa89 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -29,6 +29,7 @@ { "path": "packages/sql-mysql2/tsconfig.build.json" }, { "path": "packages/sql-mssql/tsconfig.build.json" }, { "path": "packages/sql-pg/tsconfig.build.json" }, + { "path": "packages/sql-pglite/tsconfig.build.json" }, { "path": "packages/sql-sqlite-bun/tsconfig.build.json" }, { "path": "packages/sql-sqlite-do/tsconfig.build.json" }, { "path": "packages/sql-sqlite-node/tsconfig.build.json" }, diff --git a/tsconfig.json b/tsconfig.json index a2560eb9b8d..5fcea161bc9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,6 +29,7 @@ { "path": "packages/sql-mssql" }, { "path": "packages/sql-mysql2" }, { "path": "packages/sql-pg" }, + { "path": "packages/sql-pglite" }, { "path": "packages/sql-sqlite-bun" }, { "path": "packages/sql-sqlite-do" }, { "path": "packages/sql-sqlite-node" }, @@ -38,4 +39,4 @@ { "path": "packages/vitest" }, { "path": "packages/workflow" } ] -} +} \ No newline at end of file