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
4 changes: 2 additions & 2 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ vars:
IMAGE: '{{.IMAGE | default "ghcr.io/configbutler/krm-foyer"}}'
# The krm-stream browser bundle the hello example vendors, and npm's integrity for
# its package. Bump both together, then `task vendor-krm-stream`.
KRM_STREAM_VERSION: 0.7.0
KRM_STREAM_INTEGRITY: sha512-LFXyJIv4UmlBBEJEdx68wzwaqUIVai5HbDe70ACTWIpFZexlJbd/wyhzryoW5uBg55y/f+dZ4bapajybPJ7c0w==
KRM_STREAM_VERSION: 0.10.0
KRM_STREAM_INTEGRITY: sha512-Wjl0sq6he959ximL+0wHU1on+mfVfT+MyrJucp+sfd7idepOdBFjwWSv43L34oVRsY/1+QFZcheaoiubPlmEFQ==
VERSION:
sh: git describe --tags --always --dirty 2>/dev/null || echo dev

Expand Down
322 changes: 322 additions & 0 deletions docs/investigations/adopting-krm-stream-native-watches.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions docs/investigations/krm-stream-native-connector-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

**Draft for the krm-stream team, 2026-10-05. Not submitted upstream.**

**Update 2026-10-06:** krm-stream built Deliverables 1 and 2 (0.8.0, and native resume
in 0.10.0), without pagination or streaming lists. What it takes to adopt
them here: [adopting native watches](adopting-krm-stream-native-watches.md).

Suggested issue title: **feat(client): add a native Kubernetes watch connector with
the shared frontend lifecycle**

Expand Down
250 changes: 250 additions & 0 deletions docs/investigations/stream-investigate.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/watches.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ either way later: only krm-foyer's flags change, never the page.

## Choosing a projection

These views are implemented in the pinned krm-stream **0.7.0** gateway, and krm-foyer
These views are implemented in the pinned krm-stream **0.10.0** gateway, and krm-foyer
accepts all three. Pass `projection` on `/stream/v1`; omitting it selects `krm-full/v1`.

| Projection | Status | Secret values | Use when |
Expand Down
7 changes: 4 additions & 3 deletions examples/hello/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,16 @@ change either way.

```js
import { session, login, k8s } from '/_foyer/foyer.js';
import { LiveResourceStore, connectManagedResourceStream, resourceStreamURL } from './krm-stream.js';
import { LiveResourceStore, applyStreamEvent, connectResourceStream, resourceStreamURL } from './krm-stream.js';

const s = await session(); // {authenticated, email, ...}; never a token
if (!s.authenticated) login(); // to the issuer, and back to this page

// The notes as they are, and as they change, for what RBAC lets this user see.
const store = new LiveResourceStore();
connectManagedResourceStream(resourceStreamURL('/stream/v1',
{ group: 'hello.krm-foyer.example', version: 'v1', resource: 'notes', namespace: 'hello' }), store);
connectResourceStream(resourceStreamURL('/stream/v1',
{ group: 'hello.krm-foyer.example', version: 'v1', resource: 'notes', namespace: 'hello' }),
(event) => applyStreamEvent(store, event));

// A save is the user's edit alone, on the version they last saw.
const { uid, resourceVersion, patch } = store.captureSave(id);
Expand Down
17 changes: 12 additions & 5 deletions examples/hello/web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import { session, login, logout, k8s } from '/_foyer/foyer.js';
// krm-stream's browser library, one file vendored from its npm package (task
// vendor-krm-stream). It keeps what the server sent apart from what the user typed.
import { LiveResourceStore, connectManagedResourceStream, resourceStreamURL } from './krm-stream.js';
import { LiveResourceStore, applyStreamEvent, connectResourceStream, resourceStreamURL } from './krm-stream.js';

const namespace = new URLSearchParams(location.search).get('namespace') || 'hello';
const group = 'hello.krm-foyer.example';
Expand Down Expand Up @@ -94,12 +94,15 @@ function showConnection(state) {
function connect() {
connection?.close();
return new Promise((synced) => {
connection = connectManagedResourceStream(
connection = connectResourceStream(
resourceStreamURL('/stream/v1', { group, version: 'v1', resource: 'notes', namespace }),
store,
(event) => {
applyStreamEvent(store, event);
if (event.type === 'synced') {
synced();
}
},
{
onSynced: synced,
onStateChange: showConnection,
onError: (code, message, terminal) => {
if (!terminal) {
return; // the connection recovers on its own
Expand All @@ -113,6 +116,10 @@ function connect() {
},
},
);
showConnection(connection.state);
connection.subscribe(showConnection);
// A rendering bug stops the stream; say so rather than leave it unhandled.
connection.closed.catch((err) => say(`The live view stopped: ${err.message}`, 'error'));
});
}

Expand Down
Loading
Loading