@xnetjs/data 2.5.0 → 3.0.0

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.
Files changed (41) hide show
  1. package/README.md +5 -0
  2. package/dist/auth/index.d.ts +4 -4
  3. package/dist/chunk-GJAOMEQO.js +114 -0
  4. package/dist/chunk-KY62NUOI.js +67 -0
  5. package/dist/chunk-N37U6ZPI.js +789 -0
  6. package/dist/chunk-NFPEFD2I.js +42 -0
  7. package/dist/{chunk-ODOPVGUX.js → chunk-QKVIKVAL.js} +65 -26
  8. package/dist/{chunk-CY6EJUNV.js → chunk-S7SEN4LH.js} +5 -1
  9. package/dist/{chunk-4HJZJMPI.js → chunk-TN7LGV66.js} +1 -1
  10. package/dist/{chunk-YRFCXKJC.js → chunk-UQ2VFHU3.js} +2 -2
  11. package/dist/chunk-VZSEZNYA.js +83 -0
  12. package/dist/{chunk-JF4VCZER.js → chunk-WSINZHSR.js} +27 -1
  13. package/dist/{chunk-MAB662PR.js → chunk-YCBJDT23.js} +62 -48
  14. package/dist/{clone-VRVODkBn.d.ts → clone-ywzFVkID.d.ts} +4 -4
  15. package/dist/course-C5DXOIVO.js +24 -0
  16. package/dist/database/index.d.ts +5 -5
  17. package/dist/database/index.js +8 -8
  18. package/dist/event-VW3FBN4F.js +20 -0
  19. package/dist/{form-types-Dkqm9UO2.d.ts → form-types-BrHYdpi0.d.ts} +1 -1
  20. package/dist/{game-NEQP7OFX.js → game-7AXW7XKS.js} +1 -1
  21. package/dist/{grant-expiration-cleaner-CTsW0hvU.d.ts → grant-expiration-cleaner-CRS9OyhV.d.ts} +3 -3
  22. package/dist/index.d.ts +10 -320
  23. package/dist/index.js +292 -867
  24. package/dist/{moderation-HRMMBFVH.js → moderation-5Z4LKOKN.js} +5 -3
  25. package/dist/{page-MADZ5OHM.js → page-W4G6433H.js} +1 -1
  26. package/dist/portability/index.d.ts +330 -0
  27. package/dist/portability/index.js +34 -0
  28. package/dist/post-7IOO64MD.js +14 -0
  29. package/dist/{profile-5H6XWCK4.js → profile-KLHCAQY2.js} +1 -1
  30. package/dist/publication-3MN3WWKP.js +10 -0
  31. package/dist/{query-ast-h31svZnG.d.ts → query-ast-DQJO7yRV.d.ts} +1 -1
  32. package/dist/{registry-Dh4Kr3fo.d.ts → registry-C9IRLLeR.d.ts} +1 -1
  33. package/dist/schema/index.d.ts +366 -26
  34. package/dist/schema/index.js +195 -149
  35. package/dist/space-GBTEHZOK.js +1 -1
  36. package/dist/store/index.d.ts +4 -4
  37. package/dist/store/index.js +2 -2
  38. package/dist/{store-jukJYsvr.d.ts → store-D1oiFQuF.d.ts} +19 -2
  39. package/dist/{types-Z9dUzbDF.d.ts → types-gws1tSf-.d.ts} +1 -1
  40. package/package.json +27 -25
  41. package/dist/{chunk-TW5XJHNF.js → chunk-ANMAR3KY.js} +14 -14
package/README.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
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
4
 
5
+ > **Alpha software.** xNet is released but early: this package is on npm and
6
+ > usable today, but its API can change between releases, sometimes without a
7
+ > migration path. Pin your version. See the
8
+ > [project README](https://github.com/crs48/xNet#readme) for what alpha means here.
9
+
5
10
  > **Status:** Mixed
6
11
  > Stable entrypoints: `@xnetjs/data/schema`, `@xnetjs/data/store`, `@xnetjs/data/updates`, `@xnetjs/data/awareness`
7
12
  > Experimental entrypoints: `@xnetjs/data/database`, `@xnetjs/data/auth`
@@ -1,12 +1,12 @@
1
1
  import { AllowExpr, DenyExpr, AuthExpression, AndExpr, OrExpr, NotExpr, PublicExpr, AuthenticatedExpr, CreatorRoleResolver, PropertyRoleResolver, RelationRoleResolver, MembershipRoleResolver, AuthorizationDefinition, SerializedAuthorization, SerializedAuthExpression, DID } from '@xnetjs/core';
2
2
  export { AUTH_ACTIONS, AllowExpr, AndExpr, AuthAction, AuthCheckInput, AuthDecision, AuthDenyReason, AuthExpression, AuthTrace, AuthTraceStep, AuthenticatedExpr, AuthorizationDefinition, CreatorRoleResolver, DenyExpr, MembershipRoleResolver, NotExpr, OrExpr, PolicyEvaluator, PropertyRoleResolver, PublicExpr, RelationRoleResolver, RoleRefExpr, RoleResolver, SerializedAuthExpression, SerializedAuthorization, SerializedRoleResolver } from '@xnetjs/core';
3
- import { y as PropertyDefinition, a as Schema, h as NodeState, S as SchemaIRI } from '../types-Z9dUzbDF.js';
4
- export { H as DEFAULT_OFFLINE_POLICY, z as GRANT_SCHEMA_IRI, $ as Grant, x as GrantIndex, F as GrantIndexOptions, E as GrantIndexStore, _ as GrantInput, B as GrantNode, Q as GrantRateLimiter, V as GrantRateLimiterOptions, O as OfflineAuthPolicy, K as RevocationConfig, R as RevocationConsistency, W as StoreAuth, e as StoreAuthAPI, a0 as StoreAuthError, a1 as StoreAuthErrorCode, Z as StoreAuthKeyManager, X as StoreAuthOptions, Y as StoreAuthStore, A as isGrantActive, J as mergeOfflinePolicy } from '../types-Z9dUzbDF.js';
5
- export { A as ActionPermission, m as AuthDecisionEvent, D as DecisionCache, g as DecisionCacheOptions, c as DefaultPolicyEvaluator, j as DefaultPolicyEvaluatorOptions, a as DefaultRoleResolver, i as DefaultRoleResolverOptions, k as DefinedSchemaLike, G as GrantExpirationCleaner, o as GrantExpirationCleanerOptions, n as GrantExpirationStore, H as HubPolicy, N as NodeStoreReader, P as PermissionMatrix, l as RevalidationEvent, R as RoleSummary, S as SchemaRegistryReader, b as buildPermissionMatrix, f as createPolicyEvaluator, d as describeRoleResolver, e as evaluateExpression, h as hubActionsForSpaceRole, s as schemaToHubPolicy } from '../grant-expiration-cleaner-CTsW0hvU.js';
3
+ import { F as PropertyDefinition, a as Schema, h as NodeState, S as SchemaIRI } from '../types-gws1tSf-.js';
4
+ export { a_ as DEFAULT_OFFLINE_POLICY, aY as GRANT_SCHEMA_IRI, b4 as Grant, x as GrantIndex, b9 as GrantIndexOptions, b8 as GrantIndexStore, b3 as GrantInput, b7 as GrantNode, aX as GrantRateLimiter, bc as GrantRateLimiterOptions, O as OfflineAuthPolicy, bb as RevocationConfig, ba as RevocationConsistency, aW as StoreAuth, e as StoreAuthAPI, b5 as StoreAuthError, b6 as StoreAuthErrorCode, b2 as StoreAuthKeyManager, b0 as StoreAuthOptions, b1 as StoreAuthStore, aZ as isGrantActive, a$ as mergeOfflinePolicy } from '../types-gws1tSf-.js';
5
+ export { A as ActionPermission, m as AuthDecisionEvent, b as DecisionCache, g as DecisionCacheOptions, D as DefaultPolicyEvaluator, j as DefaultPolicyEvaluatorOptions, a as DefaultRoleResolver, i as DefaultRoleResolverOptions, k as DefinedSchemaLike, G as GrantExpirationCleaner, o as GrantExpirationCleanerOptions, n as GrantExpirationStore, H as HubPolicy, N as NodeStoreReader, P as PermissionMatrix, l as RevalidationEvent, R as RoleSummary, S as SchemaRegistryReader, c as buildPermissionMatrix, f as createPolicyEvaluator, d as describeRoleResolver, e as evaluateExpression, h as hubActionsForSpaceRole, s as schemaToHubPolicy } from '../grant-expiration-cleaner-CRS9OyhV.js';
6
6
  import { PublicKeyResolver } from '@xnetjs/crypto';
7
7
  import '@xnetjs/sqlite';
8
8
  import '@xnetjs/sync';
9
- import '../registry-Dh4Kr3fo.js';
9
+ import '../registry-C9IRLLeR.js';
10
10
 
11
11
  /**
12
12
  * Authorization expression builders for schema definitions.
@@ -0,0 +1,114 @@
1
+ import {
2
+ spaceCascadeAuthorization
3
+ } from "./chunk-RLRAWZJE.js";
4
+ import {
5
+ checkbox,
6
+ created,
7
+ createdBy,
8
+ defineSchema,
9
+ number,
10
+ relation,
11
+ text
12
+ } from "./chunk-NH6OLO3X.js";
13
+ import {
14
+ allow,
15
+ role
16
+ } from "./chunk-D4LUUZYD.js";
17
+
18
+ // src/schema/schemas/course.ts
19
+ var COURSE_SCHEMA_IRI = "xnet://xnet.fyi/Course@1.0.0";
20
+ var LESSON_SCHEMA_IRI = "xnet://xnet.fyi/Lesson@1.0.0";
21
+ var LESSON_PROGRESS_SCHEMA_IRI = "xnet://xnet.fyi/LessonProgress@1.0.0";
22
+ var CourseSchema = defineSchema({
23
+ name: "Course",
24
+ namespace: "xnet://xnet.fyi/",
25
+ properties: {
26
+ title: text({ required: true, maxLength: 300 }),
27
+ description: text({ maxLength: 2e3 }),
28
+ space: relation({ target: "xnet://xnet.fyi/Space@1.0.0" }),
29
+ icon: text({ maxLength: 500 }),
30
+ /** Order among sibling courses — fractional index, code-unit compare. */
31
+ sortKey: text({ maxLength: 500 }),
32
+ /** Unpublished courses are visible to space admins only. */
33
+ published: checkbox({ default: false }),
34
+ createdAt: created(),
35
+ createdBy: createdBy()
36
+ },
37
+ document: void 0,
38
+ authorization: spaceCascadeAuthorization()
39
+ });
40
+ var LessonSchema = defineSchema({
41
+ name: "Lesson",
42
+ namespace: "xnet://xnet.fyi/",
43
+ properties: {
44
+ title: text({ required: true, maxLength: 300 }),
45
+ course: relation({ target: "xnet://xnet.fyi/Course@1.0.0", required: true }),
46
+ space: relation({ target: "xnet://xnet.fyi/Space@1.0.0" }),
47
+ /** Order within the course — fractional index. */
48
+ sortKey: text({ maxLength: 500 }),
49
+ /** Optional estimated minutes, shown as guidance, never as a timer. */
50
+ estimatedMinutes: number({ min: 0 }),
51
+ createdAt: created(),
52
+ createdBy: createdBy()
53
+ },
54
+ // Lesson bodies are documents, same editor surface as Page/Post.
55
+ document: "yjs",
56
+ authorization: spaceCascadeAuthorization()
57
+ });
58
+ var LessonProgressSchema = defineSchema({
59
+ name: "LessonProgress",
60
+ namespace: "xnet://xnet.fyi/",
61
+ properties: {
62
+ lesson: relation({ target: "xnet://xnet.fyi/Lesson@1.0.0", required: true }),
63
+ course: relation({ target: "xnet://xnet.fyi/Course@1.0.0" }),
64
+ space: relation({ target: "xnet://xnet.fyi/Space@1.0.0" }),
65
+ /** ms since epoch; absent = started but not finished. */
66
+ completedAt: number({}),
67
+ createdAt: created(),
68
+ createdBy: createdBy()
69
+ },
70
+ document: void 0,
71
+ // Written out rather than derived from the space cascade, because the whole
72
+ // point is that it does NOT cascade read to the membership.
73
+ authorization: {
74
+ roles: {
75
+ owner: role.creator(),
76
+ spaceOwner: role.relation("space", "spaceOwner"),
77
+ spaceAdmin: role.relation("space", "spaceAdmin"),
78
+ spaceMember: role.relation("space", "spaceMember")
79
+ },
80
+ actions: {
81
+ // Private by construction: the learner and the space's stewards, and
82
+ // nobody else. There is no membership-wide read of someone's progress.
83
+ read: allow("owner", "spaceOwner", "spaceAdmin"),
84
+ create: allow("spaceOwner", "spaceAdmin", "spaceMember"),
85
+ update: allow("owner"),
86
+ delete: allow("owner", "spaceOwner", "spaceAdmin"),
87
+ write: allow("owner"),
88
+ share: allow("owner")
89
+ }
90
+ }
91
+ });
92
+ function lessonProgressId(lessonId, learnerDid) {
93
+ return `lessonprogress:${lessonId}:${learnerDid}`;
94
+ }
95
+ var courseCompletion = (lessons, ownProgress) => {
96
+ const done = new Set(
97
+ ownProgress.filter((p) => typeof p.completedAt === "number" && p.completedAt > 0).map((p) => p.lesson)
98
+ );
99
+ return {
100
+ completed: lessons.filter((l) => done.has(l.id)).length,
101
+ total: lessons.length
102
+ };
103
+ };
104
+
105
+ export {
106
+ COURSE_SCHEMA_IRI,
107
+ LESSON_SCHEMA_IRI,
108
+ LESSON_PROGRESS_SCHEMA_IRI,
109
+ CourseSchema,
110
+ LessonSchema,
111
+ LessonProgressSchema,
112
+ lessonProgressId,
113
+ courseCompletion
114
+ };
@@ -0,0 +1,67 @@
1
+ import {
2
+ spaceContributorAuthorization
3
+ } from "./chunk-RLRAWZJE.js";
4
+ import {
5
+ checkbox,
6
+ created,
7
+ createdBy,
8
+ defineSchema,
9
+ relation,
10
+ select,
11
+ text
12
+ } from "./chunk-NH6OLO3X.js";
13
+
14
+ // src/schema/schemas/post.ts
15
+ var POST_SCHEMA_IRI = "xnet://xnet.fyi/Post@1.0.0";
16
+ var PostSchema = defineSchema({
17
+ name: "Post",
18
+ namespace: "xnet://xnet.fyi/",
19
+ properties: {
20
+ /** Topic title — what the discussion is about. */
21
+ title: text({ required: true, maxLength: 300 }),
22
+ /** Canonical SECURITY home. A Post without a Space is a personal draft. */
23
+ space: relation({ target: "xnet://xnet.fyi/Space@1.0.0" }),
24
+ /**
25
+ * Optional grouping within a community — "Announcements", "Wins",
26
+ * "Questions". A plain label rather than a relation: communities rename
27
+ * and merge these constantly, and a Tag relation would make the common
28
+ * case (one host, five categories) a two-node write.
29
+ */
30
+ category: text({ maxLength: 80 }),
31
+ /**
32
+ * Pinned topics sort above the rest. This is the ONE ordering lever, and
33
+ * it is an explicit editorial act by a space admin — not an engagement
34
+ * score, and not computed from any behavioural signal.
35
+ */
36
+ pinned: checkbox({ default: false }),
37
+ /** Locked topics accept no new replies; existing ones stay readable. */
38
+ locked: checkbox({ default: false }),
39
+ /** Per-node visibility; `inherit` defers to the Space (exploration 0179). */
40
+ visibility: select({
41
+ options: [
42
+ { id: "inherit", name: "Inherit", color: "gray" },
43
+ { id: "private", name: "Private", color: "gray" },
44
+ { id: "unlisted", name: "Unlisted", color: "yellow" },
45
+ { id: "public", name: "Public", color: "green" }
46
+ ],
47
+ default: "inherit"
48
+ }),
49
+ createdAt: created(),
50
+ createdBy: createdBy()
51
+ },
52
+ // Rich body, same editor surface as Page (BlockNote over a Y.Doc).
53
+ document: "yjs",
54
+ authorization: spaceContributorAuthorization()
55
+ });
56
+ var comparePostsForFeed = (a, b) => {
57
+ const aPinned = a.pinned === true;
58
+ const bPinned = b.pinned === true;
59
+ if (aPinned !== bPinned) return aPinned ? -1 : 1;
60
+ return (b.createdAt ?? 0) - (a.createdAt ?? 0);
61
+ };
62
+
63
+ export {
64
+ POST_SCHEMA_IRI,
65
+ PostSchema,
66
+ comparePostsForFeed
67
+ };