commits
- Add core synchronous validation with custom JS validators
- Support async validation for more complex use cases
- Allow logging from validation scripts for debugging
- Apply validation to mutations
- Use more efficient Node.js worker for validation execution
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The build_cursor_where_clause function was using literal '?' placeholders,
which works for SQLite but fails on PostgreSQL (which needs $1, $2, etc.).
Now accepts a start_index parameter and uses executor.placeholder() to
generate the correct format for each database dialect.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Covers the notifications query and notificationCreated subscription,
including collection filtering, pagination, and response examples.
Links like ./authentication.md#using-the-client-sdk now correctly
transform to /guides/authentication#using-the-client-sdk on the
rendered site while still working on GitHub.
Labels:
- Label definitions with severity levels (takedown, alert, inform)
- Apply/negate labels on records and accounts
- Automatic takedown filtering from all queries
- Self-labels support (author-applied labels merged with moderator labels)
- Labels field exposed on all record types
Reports:
- User-submitted reports with reason types
- Admin review and resolution workflow
- Connection pagination for admin queries
Label Preferences:
- Per-user visibility settings (ignore, show, warn, hide)
- Query and mutation via public /graphql endpoint
- System labels enforced, cannot be overridden
Admin API:
- Connection types with cursor pagination for labels and reports
- Label definition management
- Report resolution with label application
Also includes:
- Union input type support for GraphQL mutations
- Moderation documentation guide
Remove viewerDid argument from notifications query. Now uses viewer_did
from auth token context, matching the pattern used by viewer state fields.
Unauthenticated requests return 'notifications query requires authentication'.
- Remove viewerDid from build_notification_query_args
- Update resolver to use get_viewer_did_from_context
- Update tests to use OAuth authentication with test tokens
Viewer state fields show the authenticated user's relationship to records:
- `viewer{Collection}Via{Field}` for AT-URI refs (favorites, likes)
- `viewer{Collection}Via{Field}` for DID refs (follows)
Server extracts viewer DID from auth token automatically. Clients no
longer need to pass viewer_did as a variable.
Includes documentation, tests, and WebSocket subscription support.
Add cross-collection notifications query that finds records mentioning a DID:
- notifications(viewerDid, collections, first, after) GraphQL query
- NotificationRecord union type for type-safe results
- RecordCollection enum for collection filtering
- Real-time notificationCreated subscription with event filtering
Sort notifications by rkey (TID) for chronological ordering:
- Add rkey generated column to record table (VIRTUAL for SQLite, STORED for PostgreSQL)
- Update pagination to support rkey field extraction
- Cursor pagination uses rkey|uri format
Includes comprehensive test coverage for repository, e2e, and subscription handlers.
Add centralized http_client module that wraps httpc and hackney send
functions to automatically include 'user-agent: quickslice' header.
Updated all HTTP call sites to use the new module.
Derive unique namespace from clientId hash to prevent storage collisions
when multiple apps use quickslice-client-js on the same domain.
Changes:
- Storage keys prefixed with 8-char SHA-256 hash of clientId
- IndexedDB database name includes namespace
- Lock keys include namespace
- Breaking: existing users will need to re-login once
Bumps version to 0.3.0
lustre_dev_tools hash verification fails on ARM64 when downloading bun.
Install bun via npm and configure lustre to use the system binary.
Adds pubsub.publish() calls after create, update, and delete mutation
resolvers so WebSocket subscriptions receive updates immediately
without waiting for Jetstream round-trip.
- Create timestamp utility module for ISO8601 formatting
- Rename event_handler_ffi to timestamp_ffi
- Add pubsub events after records.insert/update/delete in mutations
Replace custom tangled link with bigmoves/elements qs-tangled-stars
component for displaying repo star count in sidebar.
Update ATP sessions in place instead of creating new iteration rows.
This fixes "Invalid refresh token" errors that occurred when client
tokens drifted from the current ATP session iteration.
Changes:
- Add update_tokens function to oauth_atp_sessions repository
- Replace increment_iteration with update_session_tokens in bridge
- Remove session_iteration update from atproto_auth refresh flow
- Make oauth_atp_sessions.get ignore iteration parameter
- Set session_iteration to constant Some(0) in new tokens
- Add scope to LoginOptions interface and authorize URL params
- Add scope to QuicksliceClientOptions with per-login override
- Update README with scope documentation
- Bump version to 0.2.0
Add Built-in Fields section documenting uri, cid, did, collection,
actorHandle, and indexedAt fields available on all record nodes.
Add isNull filter operator to the table and explain that ref fields
only support isNull for presence/absence checks.
Align main README with docs intro: focus on what Quickslice does
(spin up an AppView quickly) rather than listing technical features.
Add license section.
- Add Quick Start section to README with Docker and native dev instructions
- Simplify docker-compose.yml for SQLite (default)
- Add docker-compose.postgres.yml for PostgreSQL deployments
- Update .env.example with sslmode param for PostgreSQL
- Add NavItem union type supporting both grouped and standalone pages
- Add CHANGELOG.md as first item in sidebar navigation
- Update loader to handle standalone pages with special path for changelog
- Update layout to render standalone items without group header
- Disable minimap for changelog (duplicate heading IDs)
- Move tangled link below search, match link styles
- Add bottom padding to sidebar for scroll breathing room
- Clarify that only the secret key value should be copied from goat output
- Add example lexicons link to tangled.org
- Add backfill duration and storage cost warnings
- Update statusphere example security notes for DPoP and localStorage
The token endpoint now returns the user's DID as a 'sub' claim
in the token response. This is required by AT Protocol OAuth
clients to identify the authenticated user.
- Add sub parameter to token_response function
- Pass user_id from authorization code grant
- Pass user_id from refresh token grant
- Add tests for both grant types
Fixes: missing sub claim causing client SDK getUser() to return null
When querying through forward join *Resolved fields, reverse joins like
socialGrainPhotoExifViaPhoto are now available on the resolved types.
The fix in swell 2.1.2 makes the executor use a canonical type registry
(built from introspection's deduplicated types) when resolving union types,
ensuring the most complete version of each type is used.
Adds test verifying Record union members have reverse join fields.
These files were already added to .gitignore but needed to be
removed from the Git index.
feat(www): add documentation website with static site generator
- Build static docs site using Gleam with Mork markdown rendering
- Add search functionality using Fuse.js for fuzzy matching
- Generate OG images for social sharing
- Add Bunny CDN deployment script
- Reorganize docs into guides/ and reference/ structure
- Add tutorial, authentication, queries, mutations, joins guides
feat: add multi-database support with PostgreSQL
Add PostgreSQL as an alternative to SQLite, with automatic database selection
based on DATABASE_URL. Includes Docker auto-migrations on container startup.
Database abstraction:
- Add Executor type for multi-database abstraction (SQLite + PostgreSQL)
- Add unified connection module with URL-based database detection
- Migrate all repositories to Executor pattern
- Update where_clause to support database dialects
Migrations:
- Add dbmate schema migrations for both SQLite and PostgreSQL
- Add Makefile for database operations
- Docker containers now auto-run migrations on startup via dbmate
Infrastructure:
- Add pog PostgreSQL driver dependency
- Add GIN index on record.json for efficient JSONB queries
- CI caching for Gleam build to speed up native dependency compilation
- Fix OTP/jose compatibility issues
The build_cursor_where_clause function was using literal '?' placeholders,
which works for SQLite but fails on PostgreSQL (which needs $1, $2, etc.).
Now accepts a start_index parameter and uses executor.placeholder() to
generate the correct format for each database dialect.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Labels:
- Label definitions with severity levels (takedown, alert, inform)
- Apply/negate labels on records and accounts
- Automatic takedown filtering from all queries
- Self-labels support (author-applied labels merged with moderator labels)
- Labels field exposed on all record types
Reports:
- User-submitted reports with reason types
- Admin review and resolution workflow
- Connection pagination for admin queries
Label Preferences:
- Per-user visibility settings (ignore, show, warn, hide)
- Query and mutation via public /graphql endpoint
- System labels enforced, cannot be overridden
Admin API:
- Connection types with cursor pagination for labels and reports
- Label definition management
- Report resolution with label application
Also includes:
- Union input type support for GraphQL mutations
- Moderation documentation guide
Remove viewerDid argument from notifications query. Now uses viewer_did
from auth token context, matching the pattern used by viewer state fields.
Unauthenticated requests return 'notifications query requires authentication'.
- Remove viewerDid from build_notification_query_args
- Update resolver to use get_viewer_did_from_context
- Update tests to use OAuth authentication with test tokens
Viewer state fields show the authenticated user's relationship to records:
- `viewer{Collection}Via{Field}` for AT-URI refs (favorites, likes)
- `viewer{Collection}Via{Field}` for DID refs (follows)
Server extracts viewer DID from auth token automatically. Clients no
longer need to pass viewer_did as a variable.
Includes documentation, tests, and WebSocket subscription support.
Add cross-collection notifications query that finds records mentioning a DID:
- notifications(viewerDid, collections, first, after) GraphQL query
- NotificationRecord union type for type-safe results
- RecordCollection enum for collection filtering
- Real-time notificationCreated subscription with event filtering
Sort notifications by rkey (TID) for chronological ordering:
- Add rkey generated column to record table (VIRTUAL for SQLite, STORED for PostgreSQL)
- Update pagination to support rkey field extraction
- Cursor pagination uses rkey|uri format
Includes comprehensive test coverage for repository, e2e, and subscription handlers.
Derive unique namespace from clientId hash to prevent storage collisions
when multiple apps use quickslice-client-js on the same domain.
Changes:
- Storage keys prefixed with 8-char SHA-256 hash of clientId
- IndexedDB database name includes namespace
- Lock keys include namespace
- Breaking: existing users will need to re-login once
Bumps version to 0.3.0
Adds pubsub.publish() calls after create, update, and delete mutation
resolvers so WebSocket subscriptions receive updates immediately
without waiting for Jetstream round-trip.
- Create timestamp utility module for ISO8601 formatting
- Rename event_handler_ffi to timestamp_ffi
- Add pubsub events after records.insert/update/delete in mutations
Update ATP sessions in place instead of creating new iteration rows.
This fixes "Invalid refresh token" errors that occurred when client
tokens drifted from the current ATP session iteration.
Changes:
- Add update_tokens function to oauth_atp_sessions repository
- Replace increment_iteration with update_session_tokens in bridge
- Remove session_iteration update from atproto_auth refresh flow
- Make oauth_atp_sessions.get ignore iteration parameter
- Set session_iteration to constant Some(0) in new tokens
- Add NavItem union type supporting both grouped and standalone pages
- Add CHANGELOG.md as first item in sidebar navigation
- Update loader to handle standalone pages with special path for changelog
- Update layout to render standalone items without group header
- Disable minimap for changelog (duplicate heading IDs)
- Move tangled link below search, match link styles
- Add bottom padding to sidebar for scroll breathing room
The token endpoint now returns the user's DID as a 'sub' claim
in the token response. This is required by AT Protocol OAuth
clients to identify the authenticated user.
- Add sub parameter to token_response function
- Pass user_id from authorization code grant
- Pass user_id from refresh token grant
- Add tests for both grant types
Fixes: missing sub claim causing client SDK getUser() to return null
When querying through forward join *Resolved fields, reverse joins like
socialGrainPhotoExifViaPhoto are now available on the resolved types.
The fix in swell 2.1.2 makes the executor use a canonical type registry
(built from introspection's deduplicated types) when resolving union types,
ensuring the most complete version of each type is used.
Adds test verifying Record union members have reverse join fields.
feat(www): add documentation website with static site generator
- Build static docs site using Gleam with Mork markdown rendering
- Add search functionality using Fuse.js for fuzzy matching
- Generate OG images for social sharing
- Add Bunny CDN deployment script
- Reorganize docs into guides/ and reference/ structure
- Add tutorial, authentication, queries, mutations, joins guides
feat: add multi-database support with PostgreSQL
Add PostgreSQL as an alternative to SQLite, with automatic database selection
based on DATABASE_URL. Includes Docker auto-migrations on container startup.
Database abstraction:
- Add Executor type for multi-database abstraction (SQLite + PostgreSQL)
- Add unified connection module with URL-based database detection
- Migrate all repositories to Executor pattern
- Update where_clause to support database dialects
Migrations:
- Add dbmate schema migrations for both SQLite and PostgreSQL
- Add Makefile for database operations
- Docker containers now auto-run migrations on startup via dbmate
Infrastructure:
- Add pog PostgreSQL driver dependency
- Add GIN index on record.json for efficient JSONB queries
- CI caching for Gleam build to speed up native dependency compilation
- Fix OTP/jose compatibility issues