Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Latest commit

 

History

117 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

@kernhq/module-quire

Kern's wiki: spaces, a nested page tree, collaborative documents, versions and comments — and databases, which are pages with typed columns.

This is a first-party Kern module. It ships its own contract, server, screens, strings and manifest in one package; a host service imports quireModule and the app shell registers quireClientModule. Deleting the package removes the feature completely.

pnpm install
pnpm typecheck && pnpm lint && pnpm test && pnpm build

The integration tests need a Postgres to talk to: DATABASE_URL=postgres://kern:kern@localhost:5432/kern pnpm test. They create a scratch database per run and drop it afterwards, so they never touch development data.

What is in here

File What it is
src/contract/ Zod models, the oRPC contract, events, permission keys, capabilities. Imported by both halves, so no Node code.
src/server/schema.ts Drizzle tables in mod_quire.
src/server/services/ Spaces, pages, versions, comments, databases, and the SQL that filters and sorts a view.
src/server/_impl.ts The router. Separate from index.ts so module.test.ts can walk it without a kernel.
src/client/ The typed API client, the Svelte screens and the message bundles. Ships as source.
src/client/database/ The database interface: the views, the cells, the property and view editors.
migrations/ Generated by pnpm db:generate, except the row-level-security one, which is written by hand.

Prose is Yjs; everything else is Postgres rows

The two realtime paths stay separate, and that is the decision the rest of the module hangs off. A page's prose lives in a Y.Doc synchronised through the collab service; its title, position, properties and comments are ordinary rows. page_versions is the backbone of both halves of the draft model: a page serves published_version_id to a reader while a live doc serves the document — one mechanism, two behaviours.

Restoring a version uses collab.document.replace, never .apply. applyUpdate merges, so applying an older state produces the union of old and new rather than the old one.

See docs/adr/0006-collaborative-documents.md in the umbrella repository.

Databases

A database is not a second kind of object beside a page: it is a page whose body draws a view instead of prose, and each of its rows is a page too. That is what makes a row openable, commentable, versioned and searchable without any of it being built twice.

  • A row's cells live in pages.props, keyed by the property's key rather than its id, so renaming a column keeps its data.
  • What the server works out from those cells — formulas and rollups — lives in pages.computed, so a view can sort by a formula in SQL like any other column.
  • Formulas are evaluated by walking a typed AST. Never eval, never new Function: an expression is text a workspace member types and the server runs.
  • Filtering and sorting happen in SQL. A page of fifty rows filtered down to three is not a page of three, and the caller has no way to ask for the rest.

The interface

A page whose kind is database renders view tabs, a toolbar and the chosen view.

View What it does
Table Columns in position order, inline editing per type, resize and reorder, row hover actions, paged 50 at a time
Board Lanes from a select, status or tick column; drag between lanes, and a Move to menu on every card
Gallery Cards of the title and the columns the view shows
List One row each, with the first three columns as trailing values
Calendar A month plotted on a date column; drag between days, and a Move to a date menu on every card

Every property type has an editor, and the six the server writes — formula, rollup, created_time, created_by, edited_time, edited_by — render read-only and say why on hover.

Three things are deliberately not built, and the interface says so rather than pretending:

  • Attachments. Quire has no file handling at all, so an attachment column renders read-only, is not offered when adding a column, and a gallery's cover picker is disabled with that reason.
  • Timeline. ViewKind declares it; it needs a start and an end date per row, a scale and a horizontal virtualiser, none of which exists. It is left out of the kinds the view editor offers, and a view already saved as timeline falls back to the table.
  • A manual row order. Rows are ordered by the view's sorts and then by id; there is no per-row rank. A board drop inside its own lane therefore snaps back, because there is nothing to persist.

Two rules worth knowing before you edit this

updateView replaces config wholesale. It is one jsonb column and the service writes what it is given, so { config: { sorts: [...] } } destroys the filters, the grouping, the column widths and the visible columns in the same request. Every write goes through mergeConfig in src/client/database/view-config.ts.

A property's value is not always in props. Formulas and rollups are in computed, and the four audit stamps are real columns on the page. valueExpr in src/server/services/query.ts is the one place that knows which; reading props for those six matches nothing and sorts nothing, silently, because an absent key is a valid absent value.

Before you call a change done

pnpm typecheck && pnpm lint && pnpm test && pnpm build

lint runs three checks beyond Biome, and each of them exists because the mistake it catches is invisible otherwise: an icon name that is not in @kernhq/ui's registry renders a blank square, a --kern-* token that does not exist is a declaration the browser drops, and a message key missing from one of the five locale bundles type-checks perfectly and falls back to English at runtime.

Then use it through the interface, signed in, with the module enabled for a workspace — in both themes, and in Persian. A module that has never served a request is not finished, whatever the type-checker says.

About

Spaces, pages and collaborative documents for Kern — a first-party module, written the way yours would be

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages