1# Direct sharing example23Define the raw resource and the conventional grant table:45```ts6import { s } from "@nzip/lofi/schema";7import { sharedGrantTable } from "@nzip/lofi/access";89export const app = s.defineApp({10 notes: s.table({ title: s.string(), body: s.string() }),11 noteGrants: sharedGrantTable("notes"),12});13```1415Apply the narrow policy:1617```ts18import { defineAccessPolicies, sharedAccess } from "@nzip/lofi/access";19import { app } from "./schema.ts";2021export default defineAccessPolicies(app, [22 sharedAccess({ resource: app.notes, grants: app.noteGrants }),23]);24```2526Create typed operations and pass the recipient's non-secret, app-scoped sharing identity:2728```ts29import { createSharingOperations } from "@nzip/lofi/access";30import { app } from "./schema.ts";3132const notes = createSharingOperations({ resource: app.notes, grants: app.noteGrants });33await notes.share(note.id, recipientIdentity, "read");34await notes.share(note.id, recipientIdentity, "edit");35await notes.revoke(note.id, recipientIdentity);36```3738Managed sync is required. A read grant permits reads, an edit grant permits reads and updates, and39only the owner can delete or manage grants. Invitation delivery and user discovery remain app40concerns.