@xnetjs/data 0.0.2
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/LICENSE +21 -0
- package/README.md +229 -0
- package/dist/canvas-HSIKIQFK.js +7 -0
- package/dist/chunk-2L5ZUGG5.js +53 -0
- package/dist/chunk-4MTS5KAQ.js +22 -0
- package/dist/chunk-BQBPA5HS.js +76 -0
- package/dist/chunk-GZHARFKC.js +25 -0
- package/dist/chunk-IDMBCRUC.js +29 -0
- package/dist/chunk-SZC345Z2.js +2347 -0
- package/dist/chunk-VYR5GPJP.js +39 -0
- package/dist/chunk-WKIKJTI2.js +45 -0
- package/dist/comment-277JD7DV.js +7 -0
- package/dist/database-W3KEHLI3.js +7 -0
- package/dist/database-row-3O2QSNZN.js +7 -0
- package/dist/grant-QVZ454YC.js +7 -0
- package/dist/index.d.ts +4598 -0
- package/dist/index.js +5103 -0
- package/dist/page-O4WTOIEO.js +7 -0
- package/dist/task-SEKAYJH7.js +7 -0
- package/dist/ts-plugin/index.cjs +240 -0
- package/dist/ts-plugin/index.d.cts +46 -0
- package/dist/ts-plugin/index.d.ts +46 -0
- package/dist/ts-plugin/index.js +213 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Chris Smothers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# @xnetjs/data
|
|
2
|
+
|
|
3
|
+
Schema system, NodeStore, and Yjs CRDT engine for xNet. This is the central data package -- it defines how structured data and rich text documents are created, stored, and synced.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @xnetjs/data
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Schema system** -- `defineSchema()` with 16 typed property helpers
|
|
14
|
+
- **NodeStore** -- Event-sourced LWW (Last-Writer-Wins) storage engine
|
|
15
|
+
- **Built-in schemas** -- Page, Database, Task, Canvas, Comment
|
|
16
|
+
- **Yjs CRDT** -- Y.Doc helpers for signed updates and merge/state-vector workflows
|
|
17
|
+
- **Awareness/presence** -- Real-time user presence
|
|
18
|
+
- **Blob service** -- File upload/download with content addressing
|
|
19
|
+
- **Storage adapters** -- SQLite and in-memory NodeStore adapters
|
|
20
|
+
- **Temp ID mapping** -- Optimistic creates with server-assigned IDs
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
### Define a Schema
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { defineSchema, text, number, select, date, checkbox, relation } from '@xnetjs/data'
|
|
28
|
+
|
|
29
|
+
const TaskSchema = defineSchema({
|
|
30
|
+
name: 'Task',
|
|
31
|
+
namespace: 'myapp://',
|
|
32
|
+
document: 'yjs', // Enable rich text body
|
|
33
|
+
properties: {
|
|
34
|
+
title: text({ required: true }),
|
|
35
|
+
priority: number(),
|
|
36
|
+
done: checkbox(),
|
|
37
|
+
dueDate: date(),
|
|
38
|
+
status: select({
|
|
39
|
+
options: [
|
|
40
|
+
{ id: 'todo', name: 'To Do' },
|
|
41
|
+
{ id: 'in-progress', name: 'In Progress' },
|
|
42
|
+
{ id: 'done', name: 'Done' }
|
|
43
|
+
] as const
|
|
44
|
+
}),
|
|
45
|
+
assignee: relation({ schema: 'myapp://Person' })
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Property Helpers
|
|
51
|
+
|
|
52
|
+
| Type | Import | Description |
|
|
53
|
+
| ------------- | --------------- | --------------------------- |
|
|
54
|
+
| `text` | `text()` | String values |
|
|
55
|
+
| `number` | `number()` | Numeric values |
|
|
56
|
+
| `checkbox` | `checkbox()` | Boolean toggle |
|
|
57
|
+
| `date` | `date()` | Single date |
|
|
58
|
+
| `dateRange` | `dateRange()` | Start + end date |
|
|
59
|
+
| `select` | `select()` | Single choice |
|
|
60
|
+
| `multiSelect` | `multiSelect()` | Multiple choices |
|
|
61
|
+
| `person` | `person()` | DID reference |
|
|
62
|
+
| `relation` | `relation()` | Link to another node |
|
|
63
|
+
| `url` | `url()` | URL string |
|
|
64
|
+
| `email` | `email()` | Email address |
|
|
65
|
+
| `phone` | `phone()` | Phone number |
|
|
66
|
+
| `file` | `file()` | File attachment |
|
|
67
|
+
| `created` | `created()` | Auto-set creation timestamp |
|
|
68
|
+
| `updated` | `updated()` | Auto-set update timestamp |
|
|
69
|
+
| `createdBy` | `createdBy()` | Auto-set author DID |
|
|
70
|
+
|
|
71
|
+
### NodeStore
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { NodeStore, MemoryNodeStorageAdapter } from '@xnetjs/data'
|
|
75
|
+
|
|
76
|
+
const store = new NodeStore({
|
|
77
|
+
storage: new MemoryNodeStorageAdapter(),
|
|
78
|
+
authorDID: identity.did,
|
|
79
|
+
signingKey: privateKey
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
// Create
|
|
83
|
+
const task = await store.create(TaskSchema, { title: 'Buy milk', status: 'todo' })
|
|
84
|
+
|
|
85
|
+
// Read
|
|
86
|
+
const loaded = await store.get(TaskSchema, task.id)
|
|
87
|
+
|
|
88
|
+
// Update
|
|
89
|
+
await store.update(TaskSchema, task.id, { status: 'done' })
|
|
90
|
+
|
|
91
|
+
// List
|
|
92
|
+
const tasks = await store.list(TaskSchema)
|
|
93
|
+
|
|
94
|
+
// Delete (soft)
|
|
95
|
+
await store.remove(task.id)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Yjs Documents
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { YDoc, captureUpdate, applySignedUpdate, signUpdate, mergeDocuments } from '@xnetjs/data'
|
|
102
|
+
|
|
103
|
+
const authorDID = identity.did
|
|
104
|
+
const signingKey = keyBundle.signingKey
|
|
105
|
+
|
|
106
|
+
const docA = new YDoc()
|
|
107
|
+
const docB = new YDoc()
|
|
108
|
+
|
|
109
|
+
// Edit rich text content
|
|
110
|
+
docA.getText('content').insert(0, 'Hello world')
|
|
111
|
+
|
|
112
|
+
// Capture and sign update bytes
|
|
113
|
+
const update = captureUpdate(docA)
|
|
114
|
+
const signed = signUpdate(update, { authorDID, signingKey })
|
|
115
|
+
|
|
116
|
+
// Verify/apply to another replica
|
|
117
|
+
applySignedUpdate(docB, signed)
|
|
118
|
+
|
|
119
|
+
// Merge full state from one doc into another
|
|
120
|
+
mergeDocuments(docA, docB)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Architecture
|
|
124
|
+
|
|
125
|
+
```mermaid
|
|
126
|
+
flowchart TD
|
|
127
|
+
Schema["defineSchema()<br/><small>16 property helpers</small>"]
|
|
128
|
+
Store["NodeStore<br/><small>Event-sourced LWW</small>"]
|
|
129
|
+
Doc["Yjs Documents<br/><small>CRDT rich text</small>"]
|
|
130
|
+
Blob["BlobService<br/><small>File attachments</small>"]
|
|
131
|
+
Builtin["Built-in Schemas<br/><small>Page, Database, Task,<br/>Canvas, Comment</small>"]
|
|
132
|
+
|
|
133
|
+
Schema --> Store
|
|
134
|
+
Schema --> Builtin
|
|
135
|
+
Store --> Doc
|
|
136
|
+
Store --> Blob
|
|
137
|
+
Builtin --> Store
|
|
138
|
+
|
|
139
|
+
subgraph Adapters["Storage Adapters"]
|
|
140
|
+
SQLite["SQLite<br/>Adapter"]
|
|
141
|
+
Mem["Memory<br/>Adapter"]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
Store --> Adapters
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Storage Adapters
|
|
148
|
+
|
|
149
|
+
| Adapter | Platform | Description |
|
|
150
|
+
| -------------------------- | -------- | -------------------------------------- |
|
|
151
|
+
| `SQLiteNodeStorageAdapter` | All | Primary adapter using `@xnetjs/sqlite` |
|
|
152
|
+
| `MemoryNodeStorageAdapter` | All | In-memory storage for testing |
|
|
153
|
+
|
|
154
|
+
**Recommended:** Use `SQLiteNodeStorageAdapter` with the appropriate `@xnetjs/sqlite` adapter for your platform:
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { NodeStore, SQLiteNodeStorageAdapter } from '@xnetjs/data'
|
|
158
|
+
import { ElectronSQLiteAdapter } from '@xnetjs/sqlite/electron' // or /web, /expo
|
|
159
|
+
|
|
160
|
+
const sqliteAdapter = new ElectronSQLiteAdapter()
|
|
161
|
+
await sqliteAdapter.open({ path: 'xnet.db' })
|
|
162
|
+
|
|
163
|
+
const storage = new SQLiteNodeStorageAdapter(sqliteAdapter)
|
|
164
|
+
await storage.open()
|
|
165
|
+
|
|
166
|
+
const store = new NodeStore({
|
|
167
|
+
storage,
|
|
168
|
+
authorDID: identity.did,
|
|
169
|
+
signingKey: privateKey
|
|
170
|
+
})
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Telemetry Integration
|
|
174
|
+
|
|
175
|
+
NodeStore supports optional telemetry for tracking CRUD operations, performance, and errors:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
import { NodeStore } from '@xnetjs/data'
|
|
179
|
+
import { TelemetryCollector, ConsentManager } from '@xnetjs/telemetry'
|
|
180
|
+
|
|
181
|
+
const consent = new ConsentManager()
|
|
182
|
+
const telemetry = new TelemetryCollector({ consent })
|
|
183
|
+
|
|
184
|
+
const store = new NodeStore({
|
|
185
|
+
storage,
|
|
186
|
+
authorDID: identity.did,
|
|
187
|
+
signingKey: privateKey,
|
|
188
|
+
telemetry // <-- Add telemetry collector
|
|
189
|
+
})
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
When telemetry is enabled, NodeStore automatically reports:
|
|
193
|
+
|
|
194
|
+
- **Performance metrics**: `data.create`, `data.update`, `data.delete`, `data.list`, `data.applyRemoteChange`
|
|
195
|
+
- **Usage metrics**: Operation counts
|
|
196
|
+
- **Security events**: Hash/signature verification failures, unauthorized remote changes
|
|
197
|
+
- **Crash reports**: Errors with context
|
|
198
|
+
|
|
199
|
+
All telemetry respects user consent settings and privacy buckets (no exact values, no PII).
|
|
200
|
+
|
|
201
|
+
## Modules
|
|
202
|
+
|
|
203
|
+
| Module | Description |
|
|
204
|
+
| ------------------------- | -------------------------------------- |
|
|
205
|
+
| `schema/define.ts` | `defineSchema()` factory |
|
|
206
|
+
| `schema/node.ts` | FlatNode type (flattened properties) |
|
|
207
|
+
| `schema/registry.ts` | Schema registry |
|
|
208
|
+
| `store/store.ts` | NodeStore engine |
|
|
209
|
+
| `store/sqlite-adapter.ts` | SQLite NodeStore adapter (recommended) |
|
|
210
|
+
| `store/memory-adapter.ts` | In-memory NodeStore adapter |
|
|
211
|
+
| `store/tempids.ts` | Temp ID mapping for optimistic creates |
|
|
212
|
+
| `updates.ts` | Signed update and merge utilities |
|
|
213
|
+
| `blob/blob-service.ts` | File blob storage |
|
|
214
|
+
| `sync/awareness.ts` | Presence awareness |
|
|
215
|
+
| `blocks/registry.ts` | Block type registry |
|
|
216
|
+
|
|
217
|
+
## Dependencies
|
|
218
|
+
|
|
219
|
+
- `@xnetjs/core`, `@xnetjs/crypto`, `@xnetjs/identity`, `@xnetjs/storage`, `@xnetjs/sync`, `@xnetjs/sqlite`
|
|
220
|
+
- `yjs`, `y-protocols` -- CRDT engine
|
|
221
|
+
- `nanoid` -- ID generation
|
|
222
|
+
|
|
223
|
+
## Testing
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
pnpm --filter @xnetjs/data test
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
10 test files covering schema system, NodeStore, comments, and blob service.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkbox,
|
|
3
|
+
date,
|
|
4
|
+
defineSchema,
|
|
5
|
+
person,
|
|
6
|
+
relation,
|
|
7
|
+
select,
|
|
8
|
+
text
|
|
9
|
+
} from "./chunk-SZC345Z2.js";
|
|
10
|
+
|
|
11
|
+
// src/schema/schemas/task.ts
|
|
12
|
+
var TaskSchema = defineSchema({
|
|
13
|
+
name: "Task",
|
|
14
|
+
namespace: "xnet://xnet.fyi/",
|
|
15
|
+
properties: {
|
|
16
|
+
/** Task title */
|
|
17
|
+
title: text({ required: true, maxLength: 500 }),
|
|
18
|
+
/** Whether the task is completed */
|
|
19
|
+
completed: checkbox({ default: false }),
|
|
20
|
+
/** Task status */
|
|
21
|
+
status: select({
|
|
22
|
+
options: [
|
|
23
|
+
{ id: "todo", name: "To Do", color: "gray" },
|
|
24
|
+
{ id: "in-progress", name: "In Progress", color: "blue" },
|
|
25
|
+
{ id: "done", name: "Done", color: "green" },
|
|
26
|
+
{ id: "cancelled", name: "Cancelled", color: "red" }
|
|
27
|
+
],
|
|
28
|
+
default: "todo"
|
|
29
|
+
}),
|
|
30
|
+
/** Task priority */
|
|
31
|
+
priority: select({
|
|
32
|
+
options: [
|
|
33
|
+
{ id: "low", name: "Low", color: "gray" },
|
|
34
|
+
{ id: "medium", name: "Medium", color: "yellow" },
|
|
35
|
+
{ id: "high", name: "High", color: "orange" },
|
|
36
|
+
{ id: "urgent", name: "Urgent", color: "red" }
|
|
37
|
+
],
|
|
38
|
+
default: "medium"
|
|
39
|
+
}),
|
|
40
|
+
/** Due date */
|
|
41
|
+
dueDate: date({}),
|
|
42
|
+
/** Assigned person */
|
|
43
|
+
assignee: person({}),
|
|
44
|
+
/** Parent task (for subtasks) */
|
|
45
|
+
parent: relation({ target: "xnet://xnet.fyi/Task" })
|
|
46
|
+
},
|
|
47
|
+
document: "yjs"
|
|
48
|
+
// Collaborative Y.Doc for description
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
TaskSchema
|
|
53
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineSchema,
|
|
3
|
+
text
|
|
4
|
+
} from "./chunk-SZC345Z2.js";
|
|
5
|
+
|
|
6
|
+
// src/schema/schemas/canvas.ts
|
|
7
|
+
var CanvasSchema = defineSchema({
|
|
8
|
+
name: "Canvas",
|
|
9
|
+
namespace: "xnet://xnet.fyi/",
|
|
10
|
+
properties: {
|
|
11
|
+
/** Canvas title */
|
|
12
|
+
title: text({ required: true, maxLength: 500 }),
|
|
13
|
+
/** Emoji or icon URL */
|
|
14
|
+
icon: text({})
|
|
15
|
+
},
|
|
16
|
+
document: "yjs"
|
|
17
|
+
// Collaborative Y.Doc for canvas data (nodes, edges)
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
CanvasSchema
|
|
22
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkbox,
|
|
3
|
+
created,
|
|
4
|
+
createdBy,
|
|
5
|
+
date,
|
|
6
|
+
defineSchema,
|
|
7
|
+
file,
|
|
8
|
+
person,
|
|
9
|
+
relation,
|
|
10
|
+
select,
|
|
11
|
+
text
|
|
12
|
+
} from "./chunk-SZC345Z2.js";
|
|
13
|
+
|
|
14
|
+
// src/schema/schemas/comment.ts
|
|
15
|
+
var CommentSchema = defineSchema({
|
|
16
|
+
name: "Comment",
|
|
17
|
+
namespace: "xnet://xnet.fyi/",
|
|
18
|
+
properties: {
|
|
19
|
+
// ─── Universal Targeting (schema-agnostic relation) ────────────────────────
|
|
20
|
+
/** The Node this comment is on (any schema - Page, Task, Database, Canvas, etc.) */
|
|
21
|
+
target: relation({ required: true }),
|
|
22
|
+
/** Schema IRI of the target Node (optimization hint, not enforced) */
|
|
23
|
+
targetSchema: text({}),
|
|
24
|
+
// ─── Threading (flat - all replies point to root) ──────────────────────────
|
|
25
|
+
/** Root comment ID for threading (null = this IS the root) */
|
|
26
|
+
inReplyTo: relation({}),
|
|
27
|
+
// ─── Anchor Data (polymorphic positioning) ─────────────────────────────────
|
|
28
|
+
/** Type of anchor point */
|
|
29
|
+
anchorType: select({
|
|
30
|
+
options: [
|
|
31
|
+
{ id: "text", name: "Text Selection", color: "blue" },
|
|
32
|
+
{ id: "cell", name: "Database Cell", color: "green" },
|
|
33
|
+
{ id: "row", name: "Database Row", color: "green" },
|
|
34
|
+
{ id: "column", name: "Database Column", color: "green" },
|
|
35
|
+
{ id: "canvas-position", name: "Canvas Position", color: "purple" },
|
|
36
|
+
{ id: "canvas-object", name: "Canvas Object", color: "purple" },
|
|
37
|
+
{ id: "node", name: "Whole Node", color: "gray" }
|
|
38
|
+
],
|
|
39
|
+
required: true,
|
|
40
|
+
default: "node"
|
|
41
|
+
}),
|
|
42
|
+
/** JSON-encoded anchor position data */
|
|
43
|
+
anchorData: text({ required: true }),
|
|
44
|
+
// ─── Content ───────────────────────────────────────────────────────────────
|
|
45
|
+
/** Comment body in GitHub-flavored markdown (stored as plain text) */
|
|
46
|
+
content: text({ required: true, maxLength: 1e4 }),
|
|
47
|
+
/** Optional file attachments */
|
|
48
|
+
attachments: file({ multiple: true }),
|
|
49
|
+
// ─── Pseudo Reply-To (for UI, not structural threading) ────────────────────
|
|
50
|
+
/** DID of user being replied to (UI hint) */
|
|
51
|
+
replyToUser: person({}),
|
|
52
|
+
/** Comment ID being referenced (for "in reply to" display) */
|
|
53
|
+
replyToCommentId: relation({}),
|
|
54
|
+
// ─── Thread State (on root comment only) ───────────────────────────────────
|
|
55
|
+
/** Whether the thread has been resolved */
|
|
56
|
+
resolved: checkbox({ default: false }),
|
|
57
|
+
/** Who resolved the thread */
|
|
58
|
+
resolvedBy: person({}),
|
|
59
|
+
/** When the thread was resolved */
|
|
60
|
+
resolvedAt: date({}),
|
|
61
|
+
// ─── Edit State ────────────────────────────────────────────────────────────
|
|
62
|
+
/** Whether the comment has been edited */
|
|
63
|
+
edited: checkbox({ default: false }),
|
|
64
|
+
/** When the comment was last edited */
|
|
65
|
+
editedAt: date({}),
|
|
66
|
+
// ─── Auto-populated Metadata ───────────────────────────────────────────────
|
|
67
|
+
createdAt: created(),
|
|
68
|
+
createdBy: createdBy()
|
|
69
|
+
},
|
|
70
|
+
// Comments are plain text + markdown, no collaborative Y.Doc needed
|
|
71
|
+
document: void 0
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export {
|
|
75
|
+
CommentSchema
|
|
76
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineSchema,
|
|
3
|
+
file,
|
|
4
|
+
text
|
|
5
|
+
} from "./chunk-SZC345Z2.js";
|
|
6
|
+
|
|
7
|
+
// src/schema/schemas/page.ts
|
|
8
|
+
var PageSchema = defineSchema({
|
|
9
|
+
name: "Page",
|
|
10
|
+
namespace: "xnet://xnet.fyi/",
|
|
11
|
+
properties: {
|
|
12
|
+
/** Page title */
|
|
13
|
+
title: text({ required: true, maxLength: 500 }),
|
|
14
|
+
/** Emoji or icon URL */
|
|
15
|
+
icon: text({}),
|
|
16
|
+
/** Cover image */
|
|
17
|
+
cover: file({ accept: ["image/*"] })
|
|
18
|
+
},
|
|
19
|
+
document: "yjs"
|
|
20
|
+
// Collaborative Y.Doc for rich text
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
PageSchema
|
|
25
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineSchema,
|
|
3
|
+
number,
|
|
4
|
+
person,
|
|
5
|
+
text
|
|
6
|
+
} from "./chunk-SZC345Z2.js";
|
|
7
|
+
|
|
8
|
+
// src/schema/schemas/grant.ts
|
|
9
|
+
var GrantSchema = defineSchema({
|
|
10
|
+
name: "Grant",
|
|
11
|
+
namespace: "xnet://xnet.fyi/",
|
|
12
|
+
properties: {
|
|
13
|
+
issuer: person({ required: true }),
|
|
14
|
+
grantee: person({ required: true }),
|
|
15
|
+
resource: text({ required: true }),
|
|
16
|
+
resourceSchema: text({ required: true }),
|
|
17
|
+
actions: text({ required: true }),
|
|
18
|
+
expiresAt: number({}),
|
|
19
|
+
revokedAt: number({}),
|
|
20
|
+
revokedBy: person({}),
|
|
21
|
+
ucanToken: text({}),
|
|
22
|
+
proofDepth: number({}),
|
|
23
|
+
parentGrantId: text({})
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
GrantSchema
|
|
29
|
+
};
|