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
35 changes: 0 additions & 35 deletions .changeset/unlisted-records.md

This file was deleted.

35 changes: 35 additions & 0 deletions packages/adapter-api/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
# @haverstack/adapter-api

## 0.14.0

### Minor Changes

- [#209](https://github.com/haverstack/core/pull/209) [`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f) Thanks [@cuibonobo](https://github.com/cuibonobo)! - Add an `unlisted` state for records — reachable by ID, absent from enumeration by default.

`StackRecord.unlistedAt` is a native field, orthogonal to `permissions`: it says nothing
about who may read a record, only whether it is enumerable. A record with `unlistedAt` set
is reachable by `get()` for anyone who may already read it, and excluded from an unfiltered
`query()` and the change feed by default — the same posture soft delete already has.
- `stack.create(typeId, content, { unlisted: true })` creates a record already unlisted, so
there is no window where it exists and is briefly enumerable.
- `stack.setUnlisted(id, unlisted)` toggles it on an existing record, gated exactly like
`setPermissions()` under `ScopedStack` — both decide who can discover a record, not merely
read one already found.
- `RecordFilter.includeUnlisted` and `SubscribeOptions.includeUnlisted` opt a query or
subscription back in. Unlike `includeDeleted`, `includeUnlisted` is refused to everyone but
the stack owner acting alone under `ScopedStack` — enumeration standing rests on nothing but
ownership, so no grant or delegation carries it.
- The change feed matches `query()`'s exclusion, with one exception: marking a record unlisted
emits a dedicated `unlist` op (kind `deleted`) so a subscriber that already knows the record
is told to drop it; relisting emits `list` (kind `changed`), an ordinary upsert like
`undelete`. Every other transition — created unlisted, an edit while already unlisted, a
purge of a record that was never listed — needs no special-casing, since it falls out of
checking the record's current state.

See docs/spec/access-control.md § Unlisted records and docs/spec/events.md § The unlisted
transition.

### Patch Changes

- Updated dependencies [[`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f)]:
- @haverstack/core@0.15.0
- @haverstack/wire-types@0.14.0

## 0.13.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@haverstack/adapter-api",
"version": "0.13.0",
"version": "0.14.0",
"description": "Remote server adapter for Haverstack",
"type": "module",
"exports": {
Expand Down
36 changes: 36 additions & 0 deletions packages/adapter-local/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
# @haverstack/adapter-local

## 0.14.0

### Minor Changes

- [#209](https://github.com/haverstack/core/pull/209) [`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f) Thanks [@cuibonobo](https://github.com/cuibonobo)! - Add an `unlisted` state for records — reachable by ID, absent from enumeration by default.

`StackRecord.unlistedAt` is a native field, orthogonal to `permissions`: it says nothing
about who may read a record, only whether it is enumerable. A record with `unlistedAt` set
is reachable by `get()` for anyone who may already read it, and excluded from an unfiltered
`query()` and the change feed by default — the same posture soft delete already has.
- `stack.create(typeId, content, { unlisted: true })` creates a record already unlisted, so
there is no window where it exists and is briefly enumerable.
- `stack.setUnlisted(id, unlisted)` toggles it on an existing record, gated exactly like
`setPermissions()` under `ScopedStack` — both decide who can discover a record, not merely
read one already found.
- `RecordFilter.includeUnlisted` and `SubscribeOptions.includeUnlisted` opt a query or
subscription back in. Unlike `includeDeleted`, `includeUnlisted` is refused to everyone but
the stack owner acting alone under `ScopedStack` — enumeration standing rests on nothing but
ownership, so no grant or delegation carries it.
- The change feed matches `query()`'s exclusion, with one exception: marking a record unlisted
emits a dedicated `unlist` op (kind `deleted`) so a subscriber that already knows the record
is told to drop it; relisting emits `list` (kind `changed`), an ordinary upsert like
`undelete`. Every other transition — created unlisted, an edit while already unlisted, a
purge of a record that was never listed — needs no special-casing, since it falls out of
checking the record's current state.

See docs/spec/access-control.md § Unlisted records and docs/spec/events.md § The unlisted
transition.

### Patch Changes

- Updated dependencies [[`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f)]:
- @haverstack/blob-adapter-disk@0.13.0
- @haverstack/core@0.15.0
- @haverstack/record-adapter-sqlite@0.7.0

## 0.13.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-local/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@haverstack/adapter-local",
"version": "0.13.0",
"version": "0.14.0",
"description": "Local (SQLite + disk) stack adapter for Haverstack",
"type": "module",
"engines": {
Expand Down
11 changes: 11 additions & 0 deletions packages/blob-adapter-disk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# @haverstack/blob-adapter-disk

## 0.13.0

### Minor Changes

- Released for a breaking change in `@haverstack/core`.

### Patch Changes

- Updated dependencies [[`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f)]:
- @haverstack/core@0.15.0

## 0.12.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/blob-adapter-disk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@haverstack/blob-adapter-disk",
"version": "0.12.0",
"version": "0.13.0",
"description": "Disk blob adapter for Haverstack",
"type": "module",
"exports": {
Expand Down
11 changes: 11 additions & 0 deletions packages/commons/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# @haverstack/commons

## 0.7.0

### Minor Changes

- Released for a breaking change in `@haverstack/core`.

### Patch Changes

- Updated dependencies [[`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f)]:
- @haverstack/core@0.15.0

## 0.6.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/commons/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@haverstack/commons",
"version": "0.6.0",
"version": "0.7.0",
"description": "Canonical Schema Commons type definitions for Haverstack — register commons types exactly as written",
"type": "module",
"exports": {
Expand Down
34 changes: 34 additions & 0 deletions packages/conformance-fixtures/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
# @haverstack/conformance-fixtures

## 0.8.0

### Minor Changes

- [#209](https://github.com/haverstack/core/pull/209) [`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f) Thanks [@cuibonobo](https://github.com/cuibonobo)! - Add an `unlisted` state for records — reachable by ID, absent from enumeration by default.

`StackRecord.unlistedAt` is a native field, orthogonal to `permissions`: it says nothing
about who may read a record, only whether it is enumerable. A record with `unlistedAt` set
is reachable by `get()` for anyone who may already read it, and excluded from an unfiltered
`query()` and the change feed by default — the same posture soft delete already has.
- `stack.create(typeId, content, { unlisted: true })` creates a record already unlisted, so
there is no window where it exists and is briefly enumerable.
- `stack.setUnlisted(id, unlisted)` toggles it on an existing record, gated exactly like
`setPermissions()` under `ScopedStack` — both decide who can discover a record, not merely
read one already found.
- `RecordFilter.includeUnlisted` and `SubscribeOptions.includeUnlisted` opt a query or
subscription back in. Unlike `includeDeleted`, `includeUnlisted` is refused to everyone but
the stack owner acting alone under `ScopedStack` — enumeration standing rests on nothing but
ownership, so no grant or delegation carries it.
- The change feed matches `query()`'s exclusion, with one exception: marking a record unlisted
emits a dedicated `unlist` op (kind `deleted`) so a subscriber that already knows the record
is told to drop it; relisting emits `list` (kind `changed`), an ordinary upsert like
`undelete`. Every other transition — created unlisted, an edit while already unlisted, a
purge of a record that was never listed — needs no special-casing, since it falls out of
checking the record's current state.

See docs/spec/access-control.md § Unlisted records and docs/spec/events.md § The unlisted
transition.

### Patch Changes

- Updated dependencies [[`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f)]:
- @haverstack/wire-types@0.14.0

## 0.7.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/conformance-fixtures/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@haverstack/conformance-fixtures",
"version": "0.7.0",
"version": "0.8.0",
"description": "Request/response fixtures for the Stack API wire protocol, shared between adapter-api and server implementations",
"type": "module",
"exports": {
Expand Down
29 changes: 29 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# @haverstack/core

## 0.15.0

### Minor Changes

- [#209](https://github.com/haverstack/core/pull/209) [`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f) Thanks [@cuibonobo](https://github.com/cuibonobo)! - Add an `unlisted` state for records — reachable by ID, absent from enumeration by default.

`StackRecord.unlistedAt` is a native field, orthogonal to `permissions`: it says nothing
about who may read a record, only whether it is enumerable. A record with `unlistedAt` set
is reachable by `get()` for anyone who may already read it, and excluded from an unfiltered
`query()` and the change feed by default — the same posture soft delete already has.
- `stack.create(typeId, content, { unlisted: true })` creates a record already unlisted, so
there is no window where it exists and is briefly enumerable.
- `stack.setUnlisted(id, unlisted)` toggles it on an existing record, gated exactly like
`setPermissions()` under `ScopedStack` — both decide who can discover a record, not merely
read one already found.
- `RecordFilter.includeUnlisted` and `SubscribeOptions.includeUnlisted` opt a query or
subscription back in. Unlike `includeDeleted`, `includeUnlisted` is refused to everyone but
the stack owner acting alone under `ScopedStack` — enumeration standing rests on nothing but
ownership, so no grant or delegation carries it.
- The change feed matches `query()`'s exclusion, with one exception: marking a record unlisted
emits a dedicated `unlist` op (kind `deleted`) so a subscriber that already knows the record
is told to drop it; relisting emits `list` (kind `changed`), an ordinary upsert like
`undelete`. Every other transition — created unlisted, an edit while already unlisted, a
purge of a record that was never listed — needs no special-casing, since it falls out of
checking the record's current state.

See docs/spec/access-control.md § Unlisted records and docs/spec/events.md § The unlisted
transition.

## 0.14.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@haverstack/core",
"version": "0.14.0",
"version": "0.15.0",
"description": "Core library for Haverstack — portable personal data stack",
"type": "module",
"exports": {
Expand Down
34 changes: 34 additions & 0 deletions packages/record-adapter-sqlite/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
# @haverstack/record-adapter-sqlite

## 0.7.0

### Minor Changes

- [#209](https://github.com/haverstack/core/pull/209) [`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f) Thanks [@cuibonobo](https://github.com/cuibonobo)! - Add an `unlisted` state for records — reachable by ID, absent from enumeration by default.

`StackRecord.unlistedAt` is a native field, orthogonal to `permissions`: it says nothing
about who may read a record, only whether it is enumerable. A record with `unlistedAt` set
is reachable by `get()` for anyone who may already read it, and excluded from an unfiltered
`query()` and the change feed by default — the same posture soft delete already has.
- `stack.create(typeId, content, { unlisted: true })` creates a record already unlisted, so
there is no window where it exists and is briefly enumerable.
- `stack.setUnlisted(id, unlisted)` toggles it on an existing record, gated exactly like
`setPermissions()` under `ScopedStack` — both decide who can discover a record, not merely
read one already found.
- `RecordFilter.includeUnlisted` and `SubscribeOptions.includeUnlisted` opt a query or
subscription back in. Unlike `includeDeleted`, `includeUnlisted` is refused to everyone but
the stack owner acting alone under `ScopedStack` — enumeration standing rests on nothing but
ownership, so no grant or delegation carries it.
- The change feed matches `query()`'s exclusion, with one exception: marking a record unlisted
emits a dedicated `unlist` op (kind `deleted`) so a subscriber that already knows the record
is told to drop it; relisting emits `list` (kind `changed`), an ordinary upsert like
`undelete`. Every other transition — created unlisted, an edit while already unlisted, a
purge of a record that was never listed — needs no special-casing, since it falls out of
checking the record's current state.

See docs/spec/access-control.md § Unlisted records and docs/spec/events.md § The unlisted
transition.

### Patch Changes

- Updated dependencies [[`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f)]:
- @haverstack/core@0.15.0

## 0.6.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/record-adapter-sqlite/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@haverstack/record-adapter-sqlite",
"version": "0.6.0",
"version": "0.7.0",
"description": "Native SQLite (node:sqlite) record adapter for Haverstack — Node's built-in engine, no native compilation",
"type": "module",
"engines": {
Expand Down
34 changes: 34 additions & 0 deletions packages/wire-types/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
# @haverstack/wire-types

## 0.14.0

### Minor Changes

- [#209](https://github.com/haverstack/core/pull/209) [`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f) Thanks [@cuibonobo](https://github.com/cuibonobo)! - Add an `unlisted` state for records — reachable by ID, absent from enumeration by default.

`StackRecord.unlistedAt` is a native field, orthogonal to `permissions`: it says nothing
about who may read a record, only whether it is enumerable. A record with `unlistedAt` set
is reachable by `get()` for anyone who may already read it, and excluded from an unfiltered
`query()` and the change feed by default — the same posture soft delete already has.
- `stack.create(typeId, content, { unlisted: true })` creates a record already unlisted, so
there is no window where it exists and is briefly enumerable.
- `stack.setUnlisted(id, unlisted)` toggles it on an existing record, gated exactly like
`setPermissions()` under `ScopedStack` — both decide who can discover a record, not merely
read one already found.
- `RecordFilter.includeUnlisted` and `SubscribeOptions.includeUnlisted` opt a query or
subscription back in. Unlike `includeDeleted`, `includeUnlisted` is refused to everyone but
the stack owner acting alone under `ScopedStack` — enumeration standing rests on nothing but
ownership, so no grant or delegation carries it.
- The change feed matches `query()`'s exclusion, with one exception: marking a record unlisted
emits a dedicated `unlist` op (kind `deleted`) so a subscriber that already knows the record
is told to drop it; relisting emits `list` (kind `changed`), an ordinary upsert like
`undelete`. Every other transition — created unlisted, an edit while already unlisted, a
purge of a record that was never listed — needs no special-casing, since it falls out of
checking the record's current state.

See docs/spec/access-control.md § Unlisted records and docs/spec/events.md § The unlisted
transition.

### Patch Changes

- Updated dependencies [[`9edf5d0`](https://github.com/haverstack/core/commit/9edf5d02925fc6db3d829c21e23150abf15d8a8f)]:
- @haverstack/core@0.15.0

## 0.13.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/wire-types/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@haverstack/wire-types",
"version": "0.13.0",
"version": "0.14.0",
"description": "HTTP wire types and serialization for Haverstack",
"type": "module",
"exports": {
Expand Down
Loading