Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions .changeset/coalesce-replay-scope-docs.md

This file was deleted.

59 changes: 0 additions & 59 deletions .changeset/marker-gated-vector-storage.md

This file was deleted.

13 changes: 0 additions & 13 deletions .changeset/set-based-graph-traversal.md

This file was deleted.

13 changes: 0 additions & 13 deletions .changeset/trusted-initial-import.md

This file was deleted.

92 changes: 92 additions & 0 deletions packages/typegraph/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,97 @@
# @nicia-ai/typegraph

## 0.37.0

### Minor Changes

- [#269](https://github.com/nicia-ai/typegraph/pull/269) [`92479d4`](https://github.com/nicia-ai/typegraph/commit/92479d44ba7f0fc76985d51174cb9801c055fd4d) Thanks [@pdlug](https://github.com/pdlug)! - Vector storage now rides the [#135](https://github.com/nicia-ai/typegraph/issues/135) durable-contribution machinery, so the
runtime never issues DDL on the embedding hot path.

Previously every vector op (`upsertEmbedding` / `deleteEmbedding` /
`vectorSearch` / `createVectorIndex`) lazily ran `CREATE TABLE IF NOT EXISTS`
for its per-`(kind, field)` table on whatever connection it executed on. On a
least-privilege Postgres role (USAGE on `public`, full DML, but no `CREATE`)
this failed with `permission denied for schema public` (SQLSTATE 42501) — even
when the table already existed, because Postgres runs the schema aclcheck before
the `IF NOT EXISTS` short-circuit. The fulltext path already avoided this via
durable markers; vectors now do too.

What changed:

- **Boot (privileged):** `createStoreWithSchema` provisions every embedding
`(kind, field)` table + a durable contribution marker, enumerated from the
graph. `evolve()` provisions any embedding fields it introduces. A slot
already provisioned at a _different_ shape (the declared dimension changed)
is warned about and left untouched — boot stays reachable so
`store.reembedVectorField()` can recreate it; until then, writes to that
field fail with a `stale` `StoreNotInitializedError` that points at
`reembedVectorField`.
- **Runtime writes (DML-only):** `upsertEmbedding` (single and batch) and
`deleteEmbedding` assert the durable marker with a cached, signature-checked
SELECT and run DML — never DDL. `createVerifiedStore` verifies vector markers
at attach, alongside fulltext.
- **Vector reads are not marker-gated:** `store.search.vector`,
`store.search.hybrid`, and query-builder `.similarTo()` predicates compile to
SQL against the per-field table directly (searches may override the metric at
query time, so their slot legitimately differs from the provisioned shape);
against an un-provisioned database they surface the engine's missing-relation
error, which `createVerifiedStore` catches at attach.
- `reembedVectorField` re-stamps the marker after recreating storage at a new
dimension; vector-field reclaim (`materializeRemovals`) clears the marker when
it drops a table.

**Breaking:** vector ops now require a prior privileged `createStoreWithSchema`
(exactly as fulltext already does). A plain `createStore` + embedding write with
no provisioning step throws `StoreNotInitializedError` instead of lazily
creating the table.

**Migration:** after upgrading, run `createStoreWithSchema(graph, adminBackend)`
once under the schema-owner role. It creates the per-field vector tables +
markers; least-privilege runtimes then assert markers (SELECT) and run vector
DML with zero DDL — no `GRANT CREATE` required.

Consumers that boot manually (raw DDL + the sync `createStore` attach +
`backend.ensureRuntimeContributions`) provision vectors the same way: the new
`resolveGraphVectorSlots(graph)` export enumerates every embedding
`(kind, field)` slot, and `backend.ensureVectorSlotContribution(slot)`
materializes each — the exact step `createStoreWithSchema` performs. Batch
counterparts (`backend.ensureVectorSlotContributions(slots)` /
`backend.assertVectorSlotsInitialized(slots)`) resolve every slot's markers
with one graph-scoped query — what boot and verified attach use, and the
right choice for many embedding fields over a remote connection.

- [#273](https://github.com/nicia-ai/typegraph/pull/273) [`42f6941`](https://github.com/nicia-ai/typegraph/commit/42f6941fdb601629c0f45ec54fa9f3e50bd028ae) Thanks [@pdlug](https://github.com/pdlug)! - Add `trustedImportGraph` and `trustedImportGraphStream` for atomic initial loads
into a fresh, dedicated database. The distinct trusted surface bypasses schema,
reference, cardinality, and conflict validation; uses prepared SQLite writes or
PostgreSQL `UNNEST` ingestion; defers rebuildable secondary indexes; refreshes
planner statistics; and rolls the complete stream back on any failure.

The first version rejects non-empty TypeGraph data tables, recorded history,
revision tracking, uniqueness constraints, searchable fields, vector fields,
and backends without the required native transactional path.

### Patch Changes

- [#265](https://github.com/nicia-ai/typegraph/pull/265) [`35ab2a0`](https://github.com/nicia-ai/typegraph/commit/35ab2a02af728df9059750518ddbdd12e489450e) Thanks [@pdlug](https://github.com/pdlug)! - Docs: scope the `coalesceUnchangedUpserts` benefit correctly. Coalescing
eliminates _re-delivery_ churn (an already-applied change delivered again,
value-identical to the live row). It does not make a full replay-from-zero
free when the stream supersedes values in place: re-applying an older value
over the live row is a genuine change, and restoring the current value
afterwards is another, so such a replay still writes — and leaves a spurious
back-and-forth band in the live store's recorded history. Churn-free rebuilds
replay into a fresh store instead. Clarified in the option's TSDoc and in the
"Materializing external event logs" guide; no behavior change.

- [#274](https://github.com/nicia-ai/typegraph/pull/274) [`2a889aa`](https://github.com/nicia-ai/typegraph/commit/2a889aaea095a842fdd6f1b4a97feba5e6026d82) Thanks [@pdlug](https://github.com/pdlug)! - Replace path-enumerating recursive CTEs in `reachable`, `neighbors`,
`shortestPath`, and `canReach` with set-based breadth-first search.

Transactional SQLite and PostgreSQL backends now execute graph iterations
against a connection-local temporary working table, de-duplicated by node kind
and ID on every round. Non-transactional backends retain parity through a
bind-limit-aware inline frontier. Traversals run in one snapshot where the
backend supports transactions, preserve temporal filtering, and clean up
temporary state on success or failure.

## 0.36.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/typegraph/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nicia-ai/typegraph",
"version": "0.36.0",
"version": "0.37.0",
"description": "TypeScript-first embedded knowledge graph library with ontological reasoning",
"type": "module",
"main": "./dist/index.cjs",
Expand Down