{"version":3,"sources":["../src/backend/postgres/pglite.ts"],"names":["ConfigurationError","tables","PGlite","generatePostgresMigrationSQL","generateVectorlessPostgresMigrationSQL","drizzle","createPostgresBackend","wrapWithManagedClose","markBundledRootAutocommitEligible","closeAfterFailure"],"mappings":";;;;;;;;;AAsJA,eAAe,4BAAA,GAAmD;AAChE,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAU,MAAM,OAAO,+BAA+B,CAAA;AAC5D,IAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,EACjB,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,2PAAA;AAAA,MAIA,EAAE,OAAA,EAAS,QAAA,EAAU,UAAA,EAAY,+BAAA,EAAgC;AAAA,MACjE,EAAE,OAAO,KAAA;AAAM,KACjB;AAAA,EACF;AACF;AAoBA,eAAsB,wBAAA,CACpB,OAAA,GAAqC,EAAC,EACH;AACnC,EAAA,MAAMC,OAAAA,GAAS,QAAQ,MAAA,IAAUA,wBAAA;AAMjC,EAAA,MAAM,eAAA,GACJ,QAAQ,MAAA,KAAW,KAAA,GACjB,SACC,OAAA,CAAQ,MAAA,IAAW,MAAM,4BAAA,EAA6B;AAC3D,EAAA,MAAM,gBAAgB,eAAA,KAAoB,MAAA;AAO1C,EAAA,MAAM,MAAA,GAAS,MAAMC,aAAA,CAAO,MAAA,CAAO;AAAA,IACjC,GAAI,QAAQ,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAA,EAAQ;AAAA,IACpE,GAAI,eAAA,KAAoB,MAAA,GACtB,EAAC,GACD,EAAE,UAAA,EAAY,EAAE,MAAA,EAAQ,eAAA,EAAgB;AAAE,GAC7C,CAAA;AAED,EAAA,IAAI;AAGF,IAAA,MAAM,YAAA,GACJ,aAAA,GACEC,8CAAA,CAA6BF,OAAAA,EAAQ,OAAA,CAAQ,QAAQ,CAAA,GACrDG,wDAAA,CAAuCH,OAAAA,EAAQ,OAAA,CAAQ,QAAQ,CAAA;AACnE,IAAA,MAAM,MAAA,CAAO,KAAK,YAAY,CAAA;AAE9B,IAAA,MAAM,EAAA,GAAKI,iBAAQ,MAAM,CAAA;AACzB,IAAA,MAAM,OAAA,GAAUC,wCAAsB,EAAA,EAAI;AAAA,MACxC,GAAI,QAAQ,kBAAA,KAAuB,KAAA,CAAA,GACjC,EAAC,GACD,EAAE,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,EAAmB;AAAA,MACnD,MAAA,EAAAL,OAAAA;AAAA,MACA,GAAI,aAAA,GAAgB,EAAC,GAAI,EAAE,QAAQ,KAAA,EAAM;AAAA,MACzC,GAAI,QAAQ,QAAA,KAAa,KAAA,CAAA,GAAY,EAAC,GAAI,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA;AAAS,KACxE,CAAA;AACD,IAAA,MAAM,cAAA,GAAiBM,sCAAA,CAAqB,OAAA,EAAS,YAAY;AAC/D,MAAA,MAAM,OAAO,KAAA,EAAM;AAAA,IACrB,CAAC,CAAA;AAED,IAAA,OAAO;AAAA,MACL,OAAA,EAASC,oDAAkC,cAAc,CAAA;AAAA,MACzD,EAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAOC,mCAAA,CAAkB,QAAQ,KAAK,CAAA;AAAA,EACxC;AACF","file":"chunk-E6XL3KMZ.cjs","sourcesContent":["/**\n * Local PGlite backend — Postgres-in-WASM, running in-process.\n *\n * [PGlite](https://pglite.dev/) is a full Postgres compiled to WebAssembly\n * that runs inside the Node/Bun/Deno/browser process with no server and no\n * native addon. This is the batteries-included Postgres analog of\n * `createLocalSqliteBackend`: it constructs a PGlite instance, loads the\n * pgvector extension, runs the schema DDL, and returns a ready\n * `{ backend, db }` pair whose `close()` disposes the engine.\n *\n * `@electric-sql/pglite` is an optional peer dependency. Vector support\n * additionally needs `@electric-sql/pglite-pgvector` (PGlite ≥ 0.5 ships\n * pgvector as a separate package). Install what you need:\n *\n * ```bash\n * pnpm add @electric-sql/pglite @electric-sql/pglite-pgvector\n * ```\n *\n * @example In-memory database (default, vector enabled)\n * ```typescript\n * import { createLocalPgliteBackend } from \"@nicia-ai/typegraph/adapters/drizzle/postgres/pglite\";\n *\n * const { backend } = await createLocalPgliteBackend();\n * const store = createStore(graph, backend);\n * ```\n *\n * @example Persistent on-disk database\n * ```typescript\n * const { backend, db } = await createLocalPgliteBackend({ dataDir: \"./pgdata\" });\n * ```\n *\n * @example No vector support (skip the pgvector extension)\n * ```typescript\n * const { backend } = await createLocalPgliteBackend({ vector: false });\n * ```\n *\n * PGlite is single-connection and serial: there is no pooling, so concurrent\n * `store.transaction()` calls queue rather than run in parallel.\n */\nimport { type Extension, PGlite } from \"@electric-sql/pglite\";\nimport { drizzle, type PgliteDatabase } from \"drizzle-orm/pglite\";\n\nimport { ConfigurationError } from \"../../errors\";\nimport { type FulltextStrategy } from \"../../query/dialect/fulltext-strategy\";\nimport { markBundledRootAutocommitEligible } from \"../capabilities/autocommit-single-statement\";\nimport { wrapWithManagedClose } from \"../derive-backend\";\nexport type { GraphIdentityConfig } from \"../../core/define-graph\";\nimport {\n  generatePostgresMigrationSQL,\n  generateVectorlessPostgresMigrationSQL,\n} from \"../drizzle/ddl\";\nimport { type AnyPgTransaction } from \"../drizzle/execution\";\nexport type { AnyPgDatabase, AnyPgTransaction } from \"../drizzle/execution\";\nimport {\n  createPostgresBackend,\n  type PostgresTables,\n  tables as defaultTables,\n} from \"../drizzle/postgres\";\nimport {\n  type AdapterBackend,\n  closeAfterFailure,\n  type SchemaProvisioning,\n} from \"../types\";\nexport type {\n  ContributionDiagnostic,\n  ContributionDiagnosticState,\n  ContributionRepairEntry,\n  ContributionRepairResult,\n} from \"../types\";\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Options for creating a local PGlite backend.\n */\nexport type LocalPgliteBackendOptions = Readonly<{\n  /**\n   * PGlite data directory. Omit for an in-memory database (the default).\n   * Accepts any PGlite data-dir spec: a filesystem path (`\"./pgdata\"`),\n   * `\"memory://\"`, or a browser/runtime-specific scheme such as\n   * `\"idb://my-db\"`.\n   */\n  dataDir?: string;\n\n  /**\n   * Custom table definitions. Defaults to standard TypeGraph table names.\n   */\n  tables?: PostgresTables;\n\n  /**\n   * Controls the pgvector stack:\n   *\n   * - **omitted (default)** — load pgvector from `@electric-sql/pglite-pgvector`\n   *   and run `CREATE EXTENSION vector`, so embedding fields work out of the\n   *   box. Throws a {@link ConfigurationError} if the package isn't installed.\n   * - **`false`** — skip the extension entirely; the backend advertises no\n   *   vector capability (mirroring a SQLite connection without sqlite-vec).\n   *   Use when a graph carries no embeddings, or to avoid the extension dep.\n   * - **a PGlite `Extension`** — bring your own pgvector build or custom\n   *   extension packaging. Decouples this helper from a specific pgvector\n   *   package version.\n   */\n  vector?: false | Extension;\n\n  /**\n   * Override the fulltext strategy. Defaults to `tsvectorStrategy`. Pass\n   * `false` to disable fulltext support entirely — the backend then\n   * advertises no `capabilities.fulltext` and omits the fulltext CRUD/search\n   * methods, and the installation DDL never creates the fulltext table,\n   * mirroring `vector: false`.\n   */\n  fulltext?: FulltextStrategy | false;\n  /** Opt in to provisioning within caller-owned schema transactions. */\n  schemaProvisioning?: SchemaProvisioning;\n}>;\n\n/**\n * Result of creating a local PGlite backend.\n */\nexport type LocalPgliteBackendResult = Readonly<{\n  /**\n   * The GraphBackend instance for use with createStore. Its `close()`\n   * disposes the underlying PGlite engine.\n   */\n  backend: AdapterBackend<AnyPgTransaction>;\n\n  /**\n   * The underlying Drizzle database instance. Useful for direct SQL access.\n   */\n  db: PgliteDatabase;\n\n  /**\n   * The raw PGlite instance, for engine-specific operations such as\n   * `dumpDataDir()` / `clone()` not surfaced through Drizzle.\n   */\n  client: PGlite;\n}>;\n\n// ============================================================\n// Vector extension loading\n// ============================================================\n\n/**\n * Dynamically loads the default pgvector extension from\n * `@electric-sql/pglite-pgvector`. Kept as a runtime import so the package\n * stays an optional peer dependency — callers using `vector: false` or\n * supplying their own extension never need it installed.\n */\nasync function loadDefaultPgvectorExtension(): Promise<Extension> {\n  try {\n    const module_ = await import(\"@electric-sql/pglite-pgvector\");\n    return module_.vector;\n  } catch (error) {\n    throw new ConfigurationError(\n      \"createLocalPgliteBackend needs the pgvector extension but \" +\n        \"`@electric-sql/pglite-pgvector` could not be loaded. Install it \" +\n        \"(`pnpm add @electric-sql/pglite-pgvector`), pass your own `vector` \" +\n        \"extension, or set `vector: false` to disable vector support.\",\n      { backend: \"pglite\", dependency: \"@electric-sql/pglite-pgvector\" },\n      { cause: error },\n    );\n  }\n}\n\n// ============================================================\n// Factory Function\n// ============================================================\n\n/**\n * Creates a TypeGraph backend backed by an in-process PGlite database.\n *\n * Constructs the PGlite engine (loading pgvector unless disabled), executes\n * the schema DDL, and wires the standard Postgres backend. The returned\n * backend owns the engine: call `backend.close()` to dispose it.\n *\n * For production Postgres, or a PGlite instance you construct yourself,\n * use `createPostgresBackend` directly with your own Drizzle database — the\n * execution fast path detects PGlite and routes it correctly.\n *\n * @param options - Configuration options\n * @returns Backend, Drizzle database, and raw PGlite client\n */\nexport async function createLocalPgliteBackend(\n  options: LocalPgliteBackendOptions = {},\n): Promise<LocalPgliteBackendResult> {\n  const tables = options.tables ?? defaultTables;\n\n  // pgvector lives in the WASM instance, so the extension must be passed at\n  // construction — `CREATE EXTENSION vector` alone can't pull it in. An\n  // explicitly supplied extension wins; `false` disables; otherwise load the\n  // default package.\n  const vectorExtension =\n    options.vector === false ?\n      undefined\n    : (options.vector ?? (await loadDefaultPgvectorExtension()));\n  const vectorEnabled = vectorExtension !== undefined;\n\n  // Construct via the single options-object form (passing `dataDir` as a\n  // field), not the positional `create(dataDir, options)` overload: with a\n  // leading `undefined` dataDir, that overload silently drops `extensions`\n  // (\"extension vector is not available\"). The options form loads them for\n  // both the in-memory and on-disk cases.\n  const client = await PGlite.create({\n    ...(options.dataDir === undefined ? {} : { dataDir: options.dataDir }),\n    ...(vectorExtension === undefined ?\n      {}\n    : { extensions: { vector: vectorExtension } }),\n  });\n\n  try {\n    // `exec` runs a multi-statement batch (DDL + the pgvector `CREATE\n    // EXTENSION` when enabled) in one round trip.\n    const migrationSql =\n      vectorEnabled ?\n        generatePostgresMigrationSQL(tables, options.fulltext)\n      : generateVectorlessPostgresMigrationSQL(tables, options.fulltext);\n    await client.exec(migrationSql);\n\n    const db = drizzle(client);\n    const backend = createPostgresBackend(db, {\n      ...(options.schemaProvisioning === undefined ?\n        {}\n      : { schemaProvisioning: options.schemaProvisioning }),\n      tables,\n      ...(vectorEnabled ? {} : { vector: false }),\n      ...(options.fulltext === undefined ? {} : { fulltext: options.fulltext }),\n    });\n    const managedBackend = wrapWithManagedClose(backend, async () => {\n      await client.close();\n    });\n\n    return {\n      backend: markBundledRootAutocommitEligible(managedBackend),\n      db,\n      client,\n    };\n  } catch (error) {\n    return closeAfterFailure(client, error);\n  }\n}\n"]}