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
4 changes: 4 additions & 0 deletions packages/coln-repo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dist/
playwright-report/
test-results/
tests/browser/dist/
77 changes: 77 additions & 0 deletions packages/coln-repo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# `@coln-project/repo`

Coln Repo exposes Coln stores as [Automerge Repo](https://github.com/automerge/automerge-repo) document handles. Use them to create or find stores, read the current typed view, make atomic changes, and subscribe to changes to update application state or UI. Automerge Repo provides persistence and synchronization.

Coln Repo currently requires the experimental [doctypes](https://github.com/automerge/automerge-repo/tree/doctypes) branch.

## Create

Create a Coln store using generated bindings.

```ts
import * as Bindings from "./ExampleRealm.js";
import { create } from "@coln-project/repo";

const handle = create(repo, Bindings);
```

## Find

Find a Coln store by Automerge URL. Bindings are optional and must match the document schema when supplied.

```ts
import * as Bindings from "./ExampleRealm.js";
import { find } from "@coln-project/repo";

const handle = await find(repo, url, Bindings);
```

Apply bindings to a raw handle later if needed:

```ts
import * as Bindings from "./ExampleRealm.js";
import { applyBindings, find } from "@coln-project/repo";

const rawHandle = await find(repo, url);
const handle = applyBindings(rawHandle, Bindings);
```

> [!IMPORTANT]
> Once bindings are applied, later raw lookups in the same Repo may return that bound handle. It retains the raw Coln operations and adds `root` to documents and change transactions.

## Read

Read the current document synchronously or subscribe to changes.

```ts
const doc = handle.doc();
doc.scanTable("Example.Items");
doc.root.Items.values();

handle.on("change", ({ doc }) => {
doc?.scanTable("Example.Items");
doc?.root.Items.values();
});
```

Documents expose `heads()`, `jsonIR()`, `rowById()`, and `scanTable()`.

## Write

Changes are synchronous and atomic. A thrown error aborts the transaction.

```ts
handle.change((tx) => {
tx.root.Items.add();
});
```

Transactions expose `add(path, values)`; bound transactions also expose `root`.

The underlying `StoreHandle` is available through `handle.fullDoc().store` for advanced use. Its lifecycle operations bypass Coln Repo changes, events, and synchronization; prefer `doc()` and `change()`.

## Current Limitations

Values returned by `handle.doc()` are current documents, not durable snapshots.

Generated read methods such as `has()` and `values()` are not supported inside `handle.change()`. Typed transactions currently support writes only.
40 changes: 40 additions & 0 deletions packages/coln-repo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "@coln-project/repo",
"version": "0.0.1-alpha.0",
"private": true,
"license": "(Apache-2.0 OR MIT)",
"files": [
"dist"
],
"type": "module",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"scripts": {
"build": "tsc -p tsconfig.build.json",
"typecheck": "tsc --noEmit",
"test": "pnpm run typecheck && pnpm run test:unit && pnpm run test:e2e",
"test:unit": "tsx --test \"tests/**/*.test.ts\"",
"test:package": "pnpm run build && tsc -p tsconfig.package.json && node --input-type=module --eval \"const pkg = await import('@coln-project/repo'); if (typeof pkg.find !== 'function') throw new Error('missing find export')\"",
"test:e2e": "pnpm run test:package && playwright test"
},
"dependencies": {
"@automerge/automerge-repo": "github:automerge/automerge-repo#doctypes&path:packages/automerge-repo",
"@coln-project/runtime": "link:../coln-js-runtime"
},
"devDependencies": {
"@automerge/automerge-subduction": "0.16.1",
"@playwright/test": "^1.62.1",
"@types/node": "^25.9.5",
"@types/ws": "^8.18.1",
"tsx": "^4.23.13",
"typescript": "^6.0.3",
"vite": "^8.2.2",
"vite-plugin-wasm": "^3.6.0",
"ws": "^8.21.3"
}
}
42 changes: 42 additions & 0 deletions packages/coln-repo/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-FileCopyrightText: 2026 Coln contributors
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

import { defineConfig, devices } from "@playwright/test"

const webPort = Number(process.env.COLN_REPO_TEST_WEB_PORT ?? 5174)

export default defineConfig({
testDir: "./tests",
testMatch: "**/*.spec.ts",
timeout: 30_000,
expect: { timeout: 10_000 },
fullyParallel: false,
retries: 0,
use: {
baseURL: `http://127.0.0.1:${webPort}`,
trace: "retain-on-failure",
},
webServer: [
{
command: "node tests/server.mjs",
port: 3031,
reuseExistingServer: false,
stdout: "pipe",
stderr: "pipe",
},
{
command: `./node_modules/.bin/vite --host 127.0.0.1 --port ${webPort}`,
url: `http://127.0.0.1:${webPort}`,
reuseExistingServer: false,
stdout: "pipe",
stderr: "pipe",
},
],
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
],
})
Loading