Skip to content

v0.19.0

Choose a tag to compare

@github-actions github-actions released this 13 Oct 20:35
· 570 commits to main since this release

Every package with a Foldkit peer now asks for Foldkit 0.168, so each of them
takes a minor version, as do foldkit-entity 0.9.0 (and, or, not and
comparisons), foldkit-remote-drizzle 0.12.0 (compiling them),
foldkit-guard 0.2.0, foldkit-durable 0.9.0 and foldkit-react-codegen
0.3.0 (TypeScript 6 as well as 5). Republished to re-pin: foldkit-cms-drizzle
0.6.3 and foldkit-remote-server 0.13.3; foldkit-richtext-markdown 0.2.1
widens a dependency. foldkit-metadata, foldkit-richtext,
foldkit-richtext-code and foldkit-richtext-code-shiki are unchanged.

Three changes can break code written for 0.18:

  • Foldkit 0.168 itself: an application moves with it, renaming what 0.166 and
    0.167 renamed (read for toChildModel, persistentEntry, the Dom
    stream helpers).
  • GuardServer.validate refuses at startup a query body that filters or orders
    by a member with a Read rule.
  • A Behavior whose Mount fails no longer takes the element's other Behaviors
    with it; it is reported and the rest go on.

Added

  • foldkit-mixins: a reader's light or dark, before the first paint.
    Theme.schemeScript(key?) is a head script that applies the scheme kept in
    localStorage; Theme.chooseScheme(scheme, key?) applies and keeps one
    ('system' removes it); Theme.currentScheme() reads it back. The docs site
    has an Auto/Light/Dark choice built on them.

  • foldkit-sync: the browser asks before leaving while an edit is unsaved.
    Sync.mount shows a durable edit before it is stored; a reload in between
    lost it. From the first such edit until the last is stored, beforeunload
    asks the reader first.

  • Public types a dependent's declarations need. A library built on these
    packages could not emit declarations under TypeScript 7 for a value whose
    inferred type reaches a type it cannot name. The package indexes now export
    them: foldkit-mixins AttributeName, EventName, RequirementName,
    HiddenOf and SlotRecipe; foldkit-bundle PlacedBy, CollectionBy,
    WithoutResources and RuntimeResult; foldkit-agent CapabilitiesByName,
    CapabilitiesByTag, their Any forms, DefinitionOf and AnyCompletion;
    foldkit-data-grid EditableId. An interface that shares its namespace's
    name is exported as a shape: CapabilityShape, SlotViewShape,
    BundleShape, JournalShape.

  • foldkit-guard: GuardServer.validate refuses a query body that filters
    or orders by a member with a Read rule.
    The row comes back without the
    member, but which rows match, and in what order, still tells what it holds;
    with comparisons a client could bisect it (cost < $max).

  • foldkit-entity: Expr.and, Expr.or and Expr.not. The connectives,
    with SQL's three-valued meaning: or takes true over unknown, and false,
    and not of an unknown stays unknown, so a null matches neither a
    comparison nor its not. and and or need an operand and flatten one of
    the same kind. Expr.whenGiven(input, given => predicate) is a filter that
    applies only when a nullable input is given. evaluate runs them, and
    decided(predicate, input) is a predicate's truth from the input alone,
    when it reads no field. The conformance suite covers them.

  • foldkit-entity: comparisons, Expr.lt, lte, gt and gte. Numbers
    compare as numbers; text only under Collation.binary or asciiFold
    (declared on the field or passed) and against a field, refused where it is
    written otherwise, since backends order text by different defaults. A value
    compares in its encoded form, so a date stored as an ISO string is text. The
    evaluator compares as orderBy does, and the conformance suite covers them.

  • foldkit-remote-drizzle: comparisons compiled, the column first however
    the body wrote it, and text under its collation as keyset paging applies one
    (collate "C" on Postgres, collate binary or nocase on SQLite).

  • foldkit-remote-drizzle: and, or and not compiled, and an operand
    that reads no field decided per request, so whenGiven compiles to true
    when its input is null and to the predicate alone when it is given, with no
    parameter for the check.

Changed

  • TypeScript 7. The workspace typechecks and builds with TypeScript 7.0.2,
    the native compiler (a forced typecheck takes under a minute). Its DOM
    library declares the Navigation API, so foldkit-primitives no longer
    declares its own. foldkit-react-codegen peers on typescript@>=5.7.2 <7
    rather than exactly 5.9.3: it reads source through the compiler API, which
    TypeScript 7 does not ship.
  • Foldkit 0.168. Each package with a Foldkit peer asks for foldkit@^0.168.0 (and
    foldkit-mixins-ui on @foldkit/ui@^0.168.0), since they use what 0.166 and
    0.167 renamed: a lifted child is read as an Option (read, not
    toChildModel), the entry factories end in Entry
    (Subscription.persistentEntry, Port.subscriptionEntry), and the DOM
    Stream helpers are Dom's (Dom.streamFromEventFilterMap,
    Dom.streamFromKeyBindings; KeyBinding and KeySequence come from
    foldkit/dom). The examples build with Vite 8 and @foldkit/vite-plugin
    0.27.
  • Effect 4.0.4. The workspace builds and tests against effect@4.0.4 and
    its @effect/* packages at the same version. Published packages still peer on
    effect@^4.0.0, and foldkit-durable now depends on
    @effect/sql-sqlite-node@^4.0.0 rather than exactly 4.0.0, so an
    application chooses its 4.x. examples/livestore moves to
    @livestore/livestore 0.5.0-dev.1, which peers on effect@^4.0.3, so the
    workspace holds one Effect.
  • foldkit-mixins: one Behavior's failing Mount no longer stops the others
    on its element.
    The resolver merges an element's Mounts into one, and from
    Effect 4.0.2 a merge ends when any stream in it fails, so a Measure without
    a ResizeObserver took the canvas's Targets with it. Each fails alone now,
    reported as Foldkit reports a Mount ([OnMount Name] unhandled failure).

Fixed

  • foldkit-remote depends on foldkit-metadata, which its declarations
    name (import("foldkit-metadata").MetadataKey). Without the dependency the
    declaration build copied metadata's types into remote's; TypeScript 7
    refuses that, and the copy was a second set of the same types.
  • foldkit-sync: foldkit-remote is an optional peer again. The manifest
    declared peerDependenciesMeta twice, and the second, naming only
    foldkit-durable, replaced the first.
  • foldkit-durable: a database it cannot open fails as a JournalError.
    From @effect/sql-sqlite-node 4.0.1 opening the file can fail with a
    SqlError, which escaped the journal's declared errors.
  • foldkit-mixins: Theme.oklch's doc said a knob overridden on any
    subtree re-derives the palette.
    A custom property resolves where it is
    declared, so tokens on :root reach a subtree already resolved; the knob
    re-derives them only on the element that declares them (:root, a
    Theme.scoped selector, or a subtree that declares the theme itself).