Skip to content
Merged
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
11 changes: 0 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,6 @@ jobs:

- run: npm ci

# TODO: BEGIN REMOVEME (okTurtles/chel#150)
# chel cannot fetch its own SQLite library, so scripts/chel.ts points it
# at the system one. Usually already present.
- name: Make sure the system SQLite library is there
run: |
if [ ! -f /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 ]; then
sudo apt-get update
sudo apt-get install -y libsqlite3-0
fi
# TODO: END REMOVEME (okTurtles/chel#150)

- run: npx playwright install --with-deps chromium

- run: npm run lint
Expand Down
45 changes: 4 additions & 41 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ src/chelonia/offline.ts the queue for writes made while the server is away
src/types.ts the shapes the app passes around
src/components/ Vue, and nothing else
scripts/build-contracts.ts chel manifest -> chel pin -> manifest CID
scripts/chel.ts runs chel from node_modules, see below
scripts/chel.ts runs chel from node_modules
docs/data.md the todos slot and the writes, with code
docs/login.md signup and login, step by step
docs/sharing.md how sharing works, message by message
Expand Down Expand Up @@ -59,9 +59,9 @@ signal the process group or use the port: `lsof -ti:8000 | xargs kill`.
After a full rebuild, restart `npm run serve`. Vite empties `dist/` and a
server that was already running answers 404 until it is restarted.

The app is built with `LIGHTWEIGHT_CLIENT=true` (see `vite.config.ts`), the
same as Group Income: the browser keeps no message log, and Chelonia reads each
contract's HEAD from the saved state.
Chelonia runs as a lightweight client, which is `@chelonia/lib`'s default since
2.0.0, the same as Group Income: the browser keeps no message log, and Chelonia
reads each contract's HEAD from the saved state.

The contract version comes from `version` in `package.json`. Editing a contract
without bumping it makes the build stop, since the app would then be built
Expand All @@ -72,45 +72,8 @@ against a manifest the accounts already on the server do not have.
Each one is fenced in the source with `TODO: BEGIN REMOVEME (issue)` and
`TODO: END REMOVEME (issue)`, so `grep REMOVEME` finds them all.

Several of these are already fixed upstream but not published. The app pins
`@chelonia/lib` 1.5.0 and `@chelonia/cli` 3.4.0, so a merged fix changes nothing
here until there is a release to bump to.

- `scripts/chel.ts` and `.github/workflows/ci.yml`: the published
`@chelonia/cli` 3.4.0 cannot load SQLite on its own, so chel is run with
`DENO_SQLITE_PATH` pointing at the system library. Fixed by
[chel#162](https://github.com/okTurtles/chel/pull/162), tracked as
[chel#150](https://github.com/okTurtles/chel/issues/150). Until a release
ships, run chel as `node scripts/chel.ts <args>`.
- `src/contracts/identity.js`, `src/chelonia/config.ts`,
`scripts/build-contracts.ts`: the account contract has to be named
`gi.contracts/identity`, Group Income's name, because chel only accepts a
contract created without an account to bill it to under that exact name.
[chel#160](https://github.com/okTurtles/chel/issues/160).
- `src/chelonia/auth.ts`, `lookupUsername`: replaced by
`chelonia/out/nameToContractID`. Merged as
[libcheloniajs#95](https://github.com/okTurtles/libcheloniajs/pull/95),
tracked as
[libcheloniajs#90](https://github.com/okTurtles/libcheloniajs/issues/90).
- `src/chelonia/auth.ts`, signup error message: the publish error carries the
HTTP status, so signup can say why it failed. Merged as
[libcheloniajs#97](https://github.com/okTurtles/libcheloniajs/pull/97),
tracked as
[libcheloniajs#94](https://github.com/okTurtles/libcheloniajs/issues/94).
- `src/chelonia/auth.ts`, `USERNAME_REGEX`: a copy of chel's private
`NAME_REGEX`. Goes once chel exports the rule.
- `src/chelonia/offline.ts`, `ensureRandomUUID`: `@chelonia/lib` builds
persistent action ids with `crypto.randomUUID`, which browsers only provide
on https and localhost, so the demo breaks over the LAN. Merged as
[libcheloniajs#101](https://github.com/okTurtles/libcheloniajs/pull/101),
tracked as
[libcheloniajs#100](https://github.com/okTurtles/libcheloniajs/issues/100).
- `src/chelonia/auth.ts`, the key list in `signup`: gets shorter once
[libcheloniajs#91](https://github.com/okTurtles/libcheloniajs/issues/91)
lands. Not a removal, so it is a plain TODO.

## Accounts from before lists existed

Their todos were a slot on the identity contract and this version does not look
there. The account, the username and the password still work; the old todos do
not appear. There is no migration, since nothing has shipped.
97 changes: 34 additions & 63 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chelonia-todomvc",
"version": "0.2.0",
"version": "0.3.0",
"private": true,
"type": "module",
"engines": {
Expand All @@ -22,13 +22,13 @@
},
"dependencies": {
"@chelonia/crypto": "1.0.1",
"@chelonia/lib": "1.5.0",
"@chelonia/lib": "2.0.0",
"@sbp/sbp": "2.4.1",
"buffer": "6.0.3",
"vue": "3.5.13"
},
"devDependencies": {
"@chelonia/cli": "3.4.0",
"@chelonia/cli": "3.4.1",
"@eslint/js": "9.17.0",
"@playwright/test": "1.49.1",
"@types/node": "22.10.5",
Expand Down
9 changes: 2 additions & 7 deletions scripts/build-contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ import process from 'node:process'
import { chel } from './chel.ts'

const CONTRACTS = [
// TODO: BEGIN REMOVEME (okTurtles/chel#160)
// Until the fix is released, chel only accepts a contract created without an
// account to bill it to when the manifest name is exactly this. Rename then.
// TODO: END REMOVEME (okTurtles/chel#160)
{ name: 'gi.contracts/identity', file: 'identity.js' },
// A list is created by an identity, so it is attributed and its name is free.
{ name: 'todomvc/identity', file: 'identity.js' },
{ name: 'todomvc/list', file: 'list.js' }
]

Expand Down Expand Up @@ -82,7 +77,7 @@ for (const { name, file } of CONTRACTS) {
if (existsSync(pinnedSource) && !source.equals(await readFile(pinnedSource))) {
console.error(
`src/contracts/${file} changed but the version is still ${VERSION}.\n` +
'Bump "version" in package.json, or delete data/ and contracts/ to start fresh.'
'Bump "version" in package.json, or delete data/, contracts/ and chelonia.json to start fresh.'
)
process.exit(1)
}
Expand Down
40 changes: 4 additions & 36 deletions scripts/chel.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,24 @@
import { spawnSync } from 'node:child_process'
import { existsSync } from 'node:fs'
import { createRequire } from 'node:module'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'

const require = createRequire(import.meta.url)

// Take the entry point from the package's own `bin` field instead of assuming
// where the file lives. Running it cannot be left to PATH or npx: npm creates
// no node_modules/.bin/chel shim for @chelonia/cli 3.4.0, even though the
// package declares one.
// The entry point comes from the package's own `bin` field rather than PATH,
// so this also works when a script is run with plain `node`, where
// node_modules/.bin is not on PATH.
const manifestPath = require.resolve('@chelonia/cli/package.json')
const { bin } = require(manifestPath)
const CHEL_BIN = path.join(
path.dirname(manifestPath),
typeof bin === 'string' ? bin : bin.chel
)

// TODO: BEGIN REMOVEME (okTurtles/chel#150)
// The @chelonia/cli 3.4.0 binary is compiled with `--allow-write=./`, so it
// cannot write Deno's plug cache to fetch the SQLite3 library and every command
// fails with "Failed to load SQLite3 Dynamic Library". Pointing
// DENO_SQLITE_PATH at the system library skips the download. Fixed by
// okTurtles/chel#162, so this block goes once a release with it is out.
//
// These paths are conventional, not guaranteed, so on Linux take the first one
// that is actually there. On macOS the system libraries live in the dyld shared
// cache and there is no file to stat, so the path is used as given.
// DENO_SQLITE_PATH from the environment always wins.
const SYSTEM_SQLITE: Record<string, string[] | undefined> = {
darwin: ['/usr/lib/libsqlite3.dylib'],
linux: [
`/usr/lib/${process.arch === 'arm64' ? 'aarch64' : 'x86_64'}-linux-gnu/libsqlite3.so.0`,
'/usr/lib64/libsqlite3.so.0',
'/usr/lib/libsqlite3.so.0'
]
}

const candidates = SYSTEM_SQLITE[process.platform] ?? []
const found = process.platform === 'darwin'
? candidates[0]
: candidates.find((p: string) => existsSync(p))
const DENO_SQLITE_PATH = process.env.DENO_SQLITE_PATH ?? found ?? ''
// TODO: END REMOVEME (okTurtles/chel#150)

export function chel (args: string[]): void {
const { status, signal } = spawnSync(process.execPath, [CHEL_BIN, ...args], {
stdio: 'inherit',
// TODO: BEGIN REMOVEME (okTurtles/chel#150)
env: { ...process.env, DENO_SQLITE_PATH }
// TODO: END REMOVEME (okTurtles/chel#150)
stdio: 'inherit'
})
if (status !== 0) {
throw new Error(`chel ${args.join(' ')} exited with ${status ?? signal}`)
Expand Down
Loading