@zanzojs/react 0.1.0-beta.0 → 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# @zanzojs/react
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@zanzojs/react)
|
|
4
|
+
[](https://react.dev/)
|
|
5
|
+
|
|
6
|
+
React bindings for ZanzoJS.
|
|
7
|
+
|
|
8
|
+
Checking permissions on the frontend needs to be instant. You don't want to make an HTTP request every time a button renders, and you shouldn't ship heavy graph traversal logic to the browser.
|
|
9
|
+
|
|
10
|
+
`@zanzojs/react` solves this by consuming a "Flat Snapshot" generated by your backend. It evaluates permissions strictly synchronously in `O(1)` time limits.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
This package requires `@zanzojs/core` and `react` as peer dependencies.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @zanzojs/core @zanzojs/react
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Step-by-Step Guide
|
|
21
|
+
|
|
22
|
+
### 1. Generate the Snapshot (Backend)
|
|
23
|
+
|
|
24
|
+
When a user logs into your app, or loads a Server Component in Next.js, you calculate their entire permission graph once by providing their tuples to the `ZanzoEngine` and generating a snapshot.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { createZanzoSnapshot } from '@zanzojs/core';
|
|
28
|
+
import { engine } from './zanzo.config';
|
|
29
|
+
import { db, zanzoTuples } from './db';
|
|
30
|
+
import { like } from 'drizzle-orm';
|
|
31
|
+
|
|
32
|
+
export async function getUserSnapshot(userId: string) {
|
|
33
|
+
// Fetch all tuples related to this user from the DB
|
|
34
|
+
const userTuples = await db.select().from(zanzoTuples).where(like(zanzoTuples.subject, `User:${userId}%`));
|
|
35
|
+
|
|
36
|
+
// Temporarily load them into the engine
|
|
37
|
+
engine.addTuples(userTuples);
|
|
38
|
+
|
|
39
|
+
// Extract a flattened JSON dictionary
|
|
40
|
+
return createZanzoSnapshot(engine, `User:${userId}`);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. The Context Provider (Frontend)
|
|
45
|
+
|
|
46
|
+
Wrap your application (or the authenticated portion of it) with `<ZanzoProvider>`. It expects the `snapshot` object you just generated.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
'use client';
|
|
50
|
+
|
|
51
|
+
import { ZanzoProvider } from '@zanzojs/react';
|
|
52
|
+
import type { CompiledPermissions } from '@zanzojs/core';
|
|
53
|
+
|
|
54
|
+
interface AppLayoutProps {
|
|
55
|
+
children: React.ReactNode;
|
|
56
|
+
snapshot: CompiledPermissions;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default function AppLayout({ children, snapshot }: AppLayoutProps) {
|
|
60
|
+
return (
|
|
61
|
+
<ZanzoProvider snapshot={snapshot}>
|
|
62
|
+
{children}
|
|
63
|
+
</ZanzoProvider>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. The `useZanzo` Hook (Client Components)
|
|
69
|
+
|
|
70
|
+
Any child component within the provider can now instantly check access using the custom hook.
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
'use client';
|
|
74
|
+
|
|
75
|
+
import { useZanzo } from '@zanzojs/react';
|
|
76
|
+
|
|
77
|
+
export function EditDocumentButton({ documentId }: { documentId: string }) {
|
|
78
|
+
const { can } = useZanzo();
|
|
79
|
+
|
|
80
|
+
// Instant dictionary lookup!
|
|
81
|
+
// No lag, no re-renders, no network requests.
|
|
82
|
+
if (!can('write', `Document:${documentId}`)) {
|
|
83
|
+
return <span className="text-gray-500">Read Only View</span>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return <button className="bg-blue-500 text-white">Edit Document</button>;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Behavior Notes
|
|
91
|
+
|
|
92
|
+
By intentionally offloading the graph logic to the server, these React tools rely on point-in-time snapshots. If a user's permissions change deeply in the backend, the React app won't know until you fetch and provide a new snapshot to the `ZanzoProvider`. We recommend re-fetching snapshots on critical path navigations.
|
|
93
|
+
|
|
94
|
+
## Documentation
|
|
95
|
+
|
|
96
|
+
For backend compilation instructions, refer to the [ZanzoJS Monorepo](https://github.com/GonzaloJeria/zanzo).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zanzojs/react",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
4
|
"description": "React bindings for Zanzo ReBAC. O(1) permission checks via ZanzoProvider and useZanzo hook.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"@zanzojs/core",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"tsup": "latest",
|
|
53
53
|
"typescript": "^5.7.2",
|
|
54
54
|
"vitest": "latest",
|
|
55
|
-
"@zanzojs/core": "0.1.0-beta.
|
|
55
|
+
"@zanzojs/core": "0.1.0-beta.1"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "tsup",
|