feat(client): read filter — capability-based view over the reactive set
makeReadFilteredView wraps a DeepSignalSet in a Proxy whose iteration/size/forEach yield only items the current user may read (canRead on the item's emulated grant), while add/delete and the underlying reactivity pass through. filterReadable is the pure core. useShape applies it only when a grantOf resolver is configured (else passthrough, so ungranted apps are unaffected). grantOf/setGrantOf added to the polyfill surface. Mirrors the broker delivering only authorized docs; removed at migration. 4 unit tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
* Wrapped `useShape`: same signature as `@ng-org/orm`. The returned reactive set
|
||||
* is filtered to what the current user may read (emulated caps). At migration
|
||||
* this filtering disappears — the broker only syncs authorized documents.
|
||||
* Wrapped `useShape`: same signature as `@ng-org/orm`. When a grant resolver is
|
||||
* configured, the returned set is a read-filtered VIEW (only items the current
|
||||
* user may read); otherwise it passes the real set through unchanged. At
|
||||
* migration the filtering disappears — the broker only delivers authorized docs.
|
||||
*/
|
||||
|
||||
import { getConfig } from "./polyfill";
|
||||
import { getConfig, getCurrentUser, getGrantOf } from "./polyfill";
|
||||
import { makeReadFilteredView } from "./read-filter";
|
||||
|
||||
export function useShape(shapeType: unknown, scope: unknown): unknown {
|
||||
const { useShape: real } = getConfig();
|
||||
const set = real(shapeType, scope);
|
||||
// TODO(polyfill): wrap `set` so iteration yields only entries whose emulated
|
||||
// grant satisfies access.canRead(grant, getCurrentUser()), while preserving
|
||||
// the reactivity of the underlying DeepSignalSet. This is the trickiest piece.
|
||||
return set;
|
||||
const set = getConfig().useShape(shapeType, scope) as object;
|
||||
const grantOf = getGrantOf();
|
||||
if (!grantOf) return set; // no policy configured → passthrough (filter inert)
|
||||
return makeReadFilteredView(set, grantOf, getCurrentUser);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user