@xnetjs/data 0.0.2 → 0.1.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.
- package/README.md +112 -0
- package/dist/account-MWNCH4GJ.js +12 -0
- package/dist/account-ledger-R2GAFJL6.js +38 -0
- package/dist/auth/index.d.ts +420 -0
- package/dist/auth/index.js +102 -0
- package/dist/budget-NN7P35XP.js +12 -0
- package/dist/canvas-6WYBNH53.js +10 -0
- package/dist/channel-AT3LQF4A.js +12 -0
- package/dist/chat-message-DSVO72B3.js +10 -0
- package/dist/chunk-2ZNJWIQG.js +84 -0
- package/dist/chunk-3J3HILXO.js +46 -0
- package/dist/chunk-3RUDVTMH.js +5543 -0
- package/dist/chunk-4EYKGTSQ.js +49 -0
- package/dist/chunk-53F4PRNC.js +32 -0
- package/dist/chunk-5EXHNXPL.js +48 -0
- package/dist/{chunk-BQBPA5HS.js → chunk-5HC5NO57.js} +16 -2
- package/dist/chunk-6KLGA6IR.js +47 -0
- package/dist/chunk-6OMG4I7M.js +41 -0
- package/dist/chunk-7PDRDSFH.js +69 -0
- package/dist/chunk-BQLQSWKZ.js +232 -0
- package/dist/chunk-BY5O6LNC.js +380 -0
- package/dist/chunk-DCTRX6II.js +40 -0
- package/dist/{chunk-VYR5GPJP.js → chunk-DWEXKD6E.js} +9 -3
- package/dist/chunk-EBNMV2VO.js +896 -0
- package/dist/chunk-FVEACSKE.js +102 -0
- package/dist/chunk-GU6THOAB.js +45 -0
- package/dist/chunk-H4GA4BBK.js +75 -0
- package/dist/chunk-IJ44LR7N.js +76 -0
- package/dist/chunk-J4ANIXIV.js +402 -0
- package/dist/chunk-JDFNMFOZ.js +45 -0
- package/dist/chunk-K7DOZWWT.js +1811 -0
- package/dist/chunk-KQAT4XBL.js +49 -0
- package/dist/chunk-KQUALW4O.js +183 -0
- package/dist/chunk-LYSWLCOI.js +47 -0
- package/dist/chunk-MBTUO3ZL.js +65 -0
- package/dist/chunk-NI4FHG2K.js +52 -0
- package/dist/chunk-OCMSAKWV.js +78 -0
- package/dist/chunk-OGJCRNGE.js +57 -0
- package/dist/chunk-OPPHF3TF.js +143 -0
- package/dist/{chunk-IDMBCRUC.js → chunk-OSAWNZVM.js} +1 -1
- package/dist/chunk-PMUQACPY.js +33 -0
- package/dist/chunk-PNESGUH5.js +63 -0
- package/dist/chunk-Q3IEGH4B.js +51 -0
- package/dist/chunk-QJW5LDP4.js +52 -0
- package/dist/chunk-QWFTRZQT.js +142 -0
- package/dist/{chunk-SZC345Z2.js → chunk-RL64OJJ5.js} +1025 -1110
- package/dist/chunk-S5RP5RKY.js +416 -0
- package/dist/chunk-S6U6TCMN.js +722 -0
- package/dist/chunk-SVNGSZZA.js +69 -0
- package/dist/chunk-T5AZAOG5.js +54 -0
- package/dist/chunk-TCTZW4A6.js +42 -0
- package/dist/chunk-U64CW73O.js +109 -0
- package/dist/chunk-UDWKWTAX.js +6526 -0
- package/dist/chunk-UQM3G5A2.js +148 -0
- package/dist/chunk-VQ7JHB67.js +57 -0
- package/dist/chunk-W7EBL7ZU.js +73 -0
- package/dist/chunk-WEPK7SZF.js +65 -0
- package/dist/chunk-XHEA5UER.js +75 -0
- package/dist/chunk-XMSKJ5PV.js +66 -0
- package/dist/chunk-XROI44ZP.js +64 -0
- package/dist/chunk-Y3S5SRVM.js +45 -0
- package/dist/chunk-YEFKQYKA.js +43 -0
- package/dist/chunk-YSUIXD2Y.js +105 -0
- package/dist/chunk-ZCOFZY5M.js +70 -0
- package/dist/chunk-ZLU4Y3O2.js +50 -0
- package/dist/chunk-ZPZ7XDA6.js +54 -0
- package/dist/chunk-ZZ6TWKGS.js +40 -0
- package/dist/clone-C0Jhk2UN.d.ts +2205 -0
- package/dist/comment-QSWYAQVS.js +10 -0
- package/dist/crm-L5RYAAF3.js +68 -0
- package/dist/dashboard-JMKTTRA7.js +10 -0
- package/dist/database/index.d.ts +882 -0
- package/dist/database/index.js +523 -0
- package/dist/database-GIXSPZJW.js +10 -0
- package/dist/database-field-3EPAMZUR.js +10 -0
- package/dist/database-row-6Q6TRVE4.js +10 -0
- package/dist/database-select-option-BBBJFLLH.js +10 -0
- package/dist/database-view-5PLSOBI2.js +10 -0
- package/dist/experiment-DOVOZ34Y.js +10 -0
- package/dist/external-item-P2E5X7BZ.js +14 -0
- package/dist/external-reference-7BSFF6SA.js +8 -0
- package/dist/feed-2IXHHP6O.js +12 -0
- package/dist/feed-item-DPE6LN7I.js +12 -0
- package/dist/folder-6KM3KYD5.js +21 -0
- package/dist/game-5AK5XWBR.js +50 -0
- package/dist/grant-WTQSNT5A.js +8 -0
- package/dist/grant-expiration-cleaner-CY6BcmlR.d.ts +249 -0
- package/dist/import-batch-IXBJLQPJ.js +12 -0
- package/dist/inbox-state-E5NSVOGP.js +12 -0
- package/dist/index.d.ts +224 -4548
- package/dist/index.js +2252 -4754
- package/dist/map-RG5Y3CPC.js +10 -0
- package/dist/media-asset-QTCGLIZA.js +8 -0
- package/dist/memory-PNRTMBZO.js +12 -0
- package/dist/metric-65SVOX5C.js +10 -0
- package/dist/milestone-XEO6ZGDG.js +12 -0
- package/dist/moderation-FFHETMRB.js +30 -0
- package/dist/observation-2Y3QKUXM.js +10 -0
- package/dist/page-2V27JGKJ.js +10 -0
- package/dist/posting-GBOSZCMZ.js +12 -0
- package/dist/profile-BLLDWIDK.js +8 -0
- package/dist/project-CQL5LN26.js +10 -0
- package/dist/query-ast-C3m6kZYv.d.ts +226 -0
- package/dist/reaction-T2DTJBBV.js +10 -0
- package/dist/registry-DunPv__d.d.ts +99 -0
- package/dist/saved-view-4R2DBCL3.js +10 -0
- package/dist/schema/index.d.ts +6489 -0
- package/dist/schema/index.js +677 -0
- package/dist/schema-extension-LNRF2YRD.js +18 -0
- package/dist/space-IJU24PBH.js +42 -0
- package/dist/space-membership-DEUMM7NV.js +14 -0
- package/dist/store/index.d.ts +518 -0
- package/dist/store/index.js +135 -0
- package/dist/store-DtIDjk7c.d.ts +355 -0
- package/dist/sync/awareness.d.ts +69 -0
- package/dist/sync/awareness.js +20 -0
- package/dist/system-ILHCZOVO.js +38 -0
- package/dist/tag-SKCHM3U5.js +16 -0
- package/dist/task-7AOBP7WC.js +16 -0
- package/dist/task-view-NUGKELJP.js +10 -0
- package/dist/transaction-ZDSEGDIR.js +12 -0
- package/dist/transcription-PSCLDAGX.js +12 -0
- package/dist/types-S-BJAKyK.d.ts +1576 -0
- package/dist/updates.d.ts +44 -0
- package/dist/updates.js +16 -0
- package/dist/user-widget-RLY2N46A.js +8 -0
- package/dist/view-types-DSde-uT_.d.ts +316 -0
- package/package.json +32 -9
- package/dist/canvas-HSIKIQFK.js +0 -7
- package/dist/chunk-2L5ZUGG5.js +0 -53
- package/dist/chunk-4MTS5KAQ.js +0 -22
- package/dist/chunk-GZHARFKC.js +0 -25
- package/dist/chunk-WKIKJTI2.js +0 -45
- package/dist/comment-277JD7DV.js +0 -7
- package/dist/database-W3KEHLI3.js +0 -7
- package/dist/database-row-3O2QSNZN.js +0 -7
- package/dist/grant-QVZ454YC.js +0 -7
- package/dist/page-O4WTOIEO.js +0 -7
- package/dist/task-SEKAYJH7.js +0 -7
|
@@ -0,0 +1,1811 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACCOUNT_RECORD_SCHEMA_IRI,
|
|
3
|
+
DEVICE_RECORD_SCHEMA_IRI,
|
|
4
|
+
REVOCATION_RECORD_SCHEMA_IRI,
|
|
5
|
+
accountRecordId,
|
|
6
|
+
deviceRecordId,
|
|
7
|
+
resolveActiveDevices,
|
|
8
|
+
revocationRecordId,
|
|
9
|
+
revokedSubjects
|
|
10
|
+
} from "./chunk-KQUALW4O.js";
|
|
11
|
+
import {
|
|
12
|
+
extKey
|
|
13
|
+
} from "./chunk-PMUQACPY.js";
|
|
14
|
+
import {
|
|
15
|
+
EXTENSION_FIELD_SCHEMA_IRI,
|
|
16
|
+
SCHEMA_EXTENSION_SCHEMA_IRI
|
|
17
|
+
} from "./chunk-WEPK7SZF.js";
|
|
18
|
+
import {
|
|
19
|
+
PresenceSummarySchema,
|
|
20
|
+
SchemaDefinitionSchema,
|
|
21
|
+
buildSystemNodeId,
|
|
22
|
+
validateSchemaDefinitionNode
|
|
23
|
+
} from "./chunk-BY5O6LNC.js";
|
|
24
|
+
import {
|
|
25
|
+
checkbox,
|
|
26
|
+
createNodeId,
|
|
27
|
+
created,
|
|
28
|
+
createdBy,
|
|
29
|
+
date,
|
|
30
|
+
dateRange,
|
|
31
|
+
email,
|
|
32
|
+
file,
|
|
33
|
+
getBaseSchemaIRI,
|
|
34
|
+
multiSelect,
|
|
35
|
+
normalizeSchemaIRI,
|
|
36
|
+
number,
|
|
37
|
+
parseSchemaIRI,
|
|
38
|
+
person,
|
|
39
|
+
phone,
|
|
40
|
+
relation,
|
|
41
|
+
select,
|
|
42
|
+
text,
|
|
43
|
+
updated,
|
|
44
|
+
url
|
|
45
|
+
} from "./chunk-EBNMV2VO.js";
|
|
46
|
+
|
|
47
|
+
// src/schema/schemas/task-identifiers.ts
|
|
48
|
+
var TASK_SHORT_ID_PATTERN = /\b([A-Za-z]{1,5})-(\d{1,8})\b/;
|
|
49
|
+
function formatTaskShortId(prefix, number2) {
|
|
50
|
+
return `${prefix.toUpperCase()}-${number2}`;
|
|
51
|
+
}
|
|
52
|
+
function parseTaskShortId(value) {
|
|
53
|
+
const match = TASK_SHORT_ID_PATTERN.exec(value.trim());
|
|
54
|
+
if (!match) return null;
|
|
55
|
+
const number2 = Number(match[2]);
|
|
56
|
+
if (!Number.isSafeInteger(number2) || number2 <= 0) return null;
|
|
57
|
+
return { prefix: match[1].toUpperCase(), number: number2 };
|
|
58
|
+
}
|
|
59
|
+
function taskBranchName(shortId, title, username) {
|
|
60
|
+
const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40).replace(/-+$/g, "");
|
|
61
|
+
const base = `${shortId.toLowerCase()}${slug ? `-${slug}` : ""}`;
|
|
62
|
+
return username ? `${username}/${base}` : base;
|
|
63
|
+
}
|
|
64
|
+
function* shortIdsFromBlock(block) {
|
|
65
|
+
for (let n = block.start; n <= block.end; n += 1) {
|
|
66
|
+
yield formatTaskShortId(block.prefix, n);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/schema/schemas/mentions.ts
|
|
71
|
+
var MAX_MENTION_DIDS = 50;
|
|
72
|
+
var DID_PATTERN = /^did:[a-z]+:[a-zA-Z0-9._:-]+$/;
|
|
73
|
+
function normalizeMentions(value) {
|
|
74
|
+
if (!value || typeof value !== "object") return void 0;
|
|
75
|
+
const raw = value;
|
|
76
|
+
const dids = Array.isArray(raw.dids) ? [
|
|
77
|
+
...new Set(
|
|
78
|
+
raw.dids.filter((d) => typeof d === "string" && DID_PATTERN.test(d))
|
|
79
|
+
)
|
|
80
|
+
].slice(0, MAX_MENTION_DIDS) : [];
|
|
81
|
+
const room = raw.room === true;
|
|
82
|
+
if (dids.length === 0 && !room) return void 0;
|
|
83
|
+
return room ? { dids, room: true } : { dids };
|
|
84
|
+
}
|
|
85
|
+
function mentionsInclude(mentions, did) {
|
|
86
|
+
return Boolean(mentions?.dids?.includes(did));
|
|
87
|
+
}
|
|
88
|
+
function isValidMentions(value) {
|
|
89
|
+
if (value === null || value === void 0) return true;
|
|
90
|
+
if (typeof value !== "object") return false;
|
|
91
|
+
const raw = value;
|
|
92
|
+
if (raw.room !== void 0 && typeof raw.room !== "boolean") return false;
|
|
93
|
+
if (!Array.isArray(raw.dids)) return false;
|
|
94
|
+
if (raw.dids.length > MAX_MENTION_DIDS) return false;
|
|
95
|
+
return raw.dids.every((d) => typeof d === "string" && DID_PATTERN.test(d));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/schema/schemas/account-ledger-ops.ts
|
|
99
|
+
function createAccountRecord(args) {
|
|
100
|
+
return {
|
|
101
|
+
id: accountRecordId(args.accountId),
|
|
102
|
+
schemaId: ACCOUNT_RECORD_SCHEMA_IRI,
|
|
103
|
+
properties: {
|
|
104
|
+
accountId: args.accountId,
|
|
105
|
+
...args.label ? { label: args.label } : {},
|
|
106
|
+
controllers: [...args.controllers],
|
|
107
|
+
epoch: args.epoch ?? 0
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function admitDeviceRecord(args) {
|
|
112
|
+
return {
|
|
113
|
+
id: deviceRecordId(args.accountId, args.deviceDid),
|
|
114
|
+
schemaId: DEVICE_RECORD_SCHEMA_IRI,
|
|
115
|
+
properties: {
|
|
116
|
+
account: args.accountId,
|
|
117
|
+
deviceDid: args.deviceDid,
|
|
118
|
+
status: "active",
|
|
119
|
+
addedBy: args.addedBy,
|
|
120
|
+
addedAt: args.nowMs,
|
|
121
|
+
lastSeenAt: args.nowMs,
|
|
122
|
+
epoch: args.epoch,
|
|
123
|
+
...args.label ? { label: args.label } : {},
|
|
124
|
+
...args.rpId ? { rpId: args.rpId } : {},
|
|
125
|
+
...args.credentialIdHash ? { credentialIdHash: args.credentialIdHash } : {},
|
|
126
|
+
...args.capabilities !== void 0 ? { capabilities: args.capabilities } : {}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function nextEpoch(currentEpoch) {
|
|
131
|
+
return currentEpoch + 1;
|
|
132
|
+
}
|
|
133
|
+
function revokeSubjectRecord(args) {
|
|
134
|
+
const epoch = nextEpoch(args.currentEpoch);
|
|
135
|
+
return {
|
|
136
|
+
nextEpoch: epoch,
|
|
137
|
+
revocation: {
|
|
138
|
+
id: revocationRecordId(args.accountId, args.subject),
|
|
139
|
+
schemaId: REVOCATION_RECORD_SCHEMA_IRI,
|
|
140
|
+
properties: {
|
|
141
|
+
account: args.accountId,
|
|
142
|
+
subjectKind: args.subjectKind,
|
|
143
|
+
subject: args.subject,
|
|
144
|
+
signedBy: args.signedBy,
|
|
145
|
+
effectiveAt: args.nowMs,
|
|
146
|
+
epoch,
|
|
147
|
+
...args.reason ? { reason: args.reason } : {}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function revokeDeviceRecord(args) {
|
|
153
|
+
return revokeSubjectRecord({ ...args, subject: args.deviceDid, subjectKind: "device" });
|
|
154
|
+
}
|
|
155
|
+
function accountState(input) {
|
|
156
|
+
return {
|
|
157
|
+
epoch: input.account?.epoch ?? 0,
|
|
158
|
+
activeDevices: resolveActiveDevices(input.devices, input.revocations),
|
|
159
|
+
revoked: revokedSubjects(input.revocations)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/schema/schemas/commentAnchors.ts
|
|
164
|
+
function encodeAnchor(data) {
|
|
165
|
+
return JSON.stringify(data);
|
|
166
|
+
}
|
|
167
|
+
function decodeAnchor(json2) {
|
|
168
|
+
return JSON.parse(json2);
|
|
169
|
+
}
|
|
170
|
+
function isTextAnchor(data) {
|
|
171
|
+
return "startRelative" in data && "endRelative" in data;
|
|
172
|
+
}
|
|
173
|
+
function isCellAnchor(data) {
|
|
174
|
+
return "rowId" in data && "propertyKey" in data;
|
|
175
|
+
}
|
|
176
|
+
function isRowAnchor(data) {
|
|
177
|
+
return "rowId" in data && !("propertyKey" in data);
|
|
178
|
+
}
|
|
179
|
+
function isColumnAnchor(data) {
|
|
180
|
+
return "propertyKey" in data && !("rowId" in data);
|
|
181
|
+
}
|
|
182
|
+
function isCanvasPositionAnchor(data) {
|
|
183
|
+
return "x" in data && "y" in data && !("objectId" in data);
|
|
184
|
+
}
|
|
185
|
+
function isCanvasObjectAnchor(data) {
|
|
186
|
+
return "objectId" in data;
|
|
187
|
+
}
|
|
188
|
+
function isNodeAnchor(data) {
|
|
189
|
+
return Object.keys(data).length === 0;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/schema/schemas/commentReferences.ts
|
|
193
|
+
var MENTION_REGEX = /@(did:key:z[a-zA-Z0-9]+|[a-zA-Z_][\w]*)/g;
|
|
194
|
+
var COMMENT_REF_REGEX = /#([a-zA-Z0-9_-]{21})(?![a-zA-Z0-9_-])/g;
|
|
195
|
+
var NODE_REF_REGEX = /\[\[([a-zA-Z0-9_-]{21})\]\]/g;
|
|
196
|
+
function extractReferences(content) {
|
|
197
|
+
const refs = [];
|
|
198
|
+
MENTION_REGEX.lastIndex = 0;
|
|
199
|
+
COMMENT_REF_REGEX.lastIndex = 0;
|
|
200
|
+
NODE_REF_REGEX.lastIndex = 0;
|
|
201
|
+
let match;
|
|
202
|
+
while ((match = MENTION_REGEX.exec(content)) !== null) {
|
|
203
|
+
const value = match[1];
|
|
204
|
+
refs.push({
|
|
205
|
+
type: "user",
|
|
206
|
+
raw: match[0],
|
|
207
|
+
did: value.startsWith("did:") ? value : void 0,
|
|
208
|
+
displayName: value.startsWith("did:") ? void 0 : value,
|
|
209
|
+
index: match.index
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
while ((match = COMMENT_REF_REGEX.exec(content)) !== null) {
|
|
213
|
+
refs.push({
|
|
214
|
+
type: "comment",
|
|
215
|
+
raw: match[0],
|
|
216
|
+
commentId: match[1],
|
|
217
|
+
index: match.index
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
while ((match = NODE_REF_REGEX.exec(content)) !== null) {
|
|
221
|
+
refs.push({
|
|
222
|
+
type: "node",
|
|
223
|
+
raw: match[0],
|
|
224
|
+
nodeId: match[1],
|
|
225
|
+
index: match.index
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return refs.sort((a, b) => a.index - b.index);
|
|
229
|
+
}
|
|
230
|
+
function extractMentions(content) {
|
|
231
|
+
return extractReferences(content).filter((r) => r.type === "user");
|
|
232
|
+
}
|
|
233
|
+
function getMentionedUsers(content) {
|
|
234
|
+
return extractMentions(content).map((m) => m.did ?? m.displayName).filter((id) => id !== void 0);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/schema/schemas/commentOrphans.ts
|
|
238
|
+
function checkOrphanStatus(anchorType, anchorData, resolvers) {
|
|
239
|
+
try {
|
|
240
|
+
switch (anchorType) {
|
|
241
|
+
case "text": {
|
|
242
|
+
if (!resolvers.resolveTextAnchor) {
|
|
243
|
+
return { orphaned: false };
|
|
244
|
+
}
|
|
245
|
+
const anchor = decodeAnchor(anchorData);
|
|
246
|
+
const resolved = resolvers.resolveTextAnchor(anchor);
|
|
247
|
+
if (resolved === null) {
|
|
248
|
+
return {
|
|
249
|
+
orphaned: true,
|
|
250
|
+
reason: "text-deleted",
|
|
251
|
+
context: anchor.quotedText
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return { orphaned: false };
|
|
255
|
+
}
|
|
256
|
+
case "cell": {
|
|
257
|
+
const anchor = decodeAnchor(anchorData);
|
|
258
|
+
if (resolvers.rowExists && !resolvers.rowExists(anchor.rowId)) {
|
|
259
|
+
return {
|
|
260
|
+
orphaned: true,
|
|
261
|
+
reason: "row-deleted",
|
|
262
|
+
context: `Row ${anchor.rowId.slice(0, 8)}`
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
if (resolvers.columnExists && !resolvers.columnExists(anchor.propertyKey)) {
|
|
266
|
+
return {
|
|
267
|
+
orphaned: true,
|
|
268
|
+
reason: "column-deleted",
|
|
269
|
+
context: `Column "${anchor.propertyKey}"`
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return { orphaned: false };
|
|
273
|
+
}
|
|
274
|
+
case "row": {
|
|
275
|
+
const anchor = decodeAnchor(anchorData);
|
|
276
|
+
if (resolvers.rowExists && !resolvers.rowExists(anchor.rowId)) {
|
|
277
|
+
return {
|
|
278
|
+
orphaned: true,
|
|
279
|
+
reason: "row-deleted",
|
|
280
|
+
context: `Row ${anchor.rowId.slice(0, 8)}`
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
return { orphaned: false };
|
|
284
|
+
}
|
|
285
|
+
case "column": {
|
|
286
|
+
const anchor = decodeAnchor(anchorData);
|
|
287
|
+
if (resolvers.columnExists && !resolvers.columnExists(anchor.propertyKey)) {
|
|
288
|
+
return {
|
|
289
|
+
orphaned: true,
|
|
290
|
+
reason: "column-deleted",
|
|
291
|
+
context: `Column "${anchor.propertyKey}"`
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
return { orphaned: false };
|
|
295
|
+
}
|
|
296
|
+
case "canvas-object": {
|
|
297
|
+
const anchor = decodeAnchor(anchorData);
|
|
298
|
+
if (resolvers.objectExists && !resolvers.objectExists(anchor.objectId)) {
|
|
299
|
+
return {
|
|
300
|
+
orphaned: true,
|
|
301
|
+
reason: "object-deleted",
|
|
302
|
+
context: `Object ${anchor.objectId.slice(0, 8)}`
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
return { orphaned: false };
|
|
306
|
+
}
|
|
307
|
+
case "canvas-position":
|
|
308
|
+
return { orphaned: false };
|
|
309
|
+
case "node":
|
|
310
|
+
return { orphaned: false };
|
|
311
|
+
default:
|
|
312
|
+
return { orphaned: false };
|
|
313
|
+
}
|
|
314
|
+
} catch {
|
|
315
|
+
return {
|
|
316
|
+
orphaned: true,
|
|
317
|
+
reason: "invalid-anchor",
|
|
318
|
+
context: "Invalid anchor data"
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
function filterOrphanedComments(comments, resolvers) {
|
|
323
|
+
const active = [];
|
|
324
|
+
const orphaned = [];
|
|
325
|
+
for (const comment of comments) {
|
|
326
|
+
const status = checkOrphanStatus(
|
|
327
|
+
comment.properties.anchorType,
|
|
328
|
+
comment.properties.anchorData,
|
|
329
|
+
resolvers
|
|
330
|
+
);
|
|
331
|
+
if (status.orphaned) {
|
|
332
|
+
orphaned.push({ comment, status });
|
|
333
|
+
} else {
|
|
334
|
+
active.push(comment);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return { active, orphaned };
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/schema/schemas/index.ts
|
|
341
|
+
var builtInSchemas = {
|
|
342
|
+
// Versioned IRIs (canonical)
|
|
343
|
+
"xnet://xnet.fyi/Page@1.0.0": () => import("./page-2V27JGKJ.js").then((m) => m.PageSchema),
|
|
344
|
+
"xnet://xnet.fyi/Folder@1.0.0": () => import("./folder-6KM3KYD5.js").then((m) => m.FolderSchema),
|
|
345
|
+
"xnet://xnet.fyi/Tag@1.0.0": () => import("./tag-SKCHM3U5.js").then((m) => m.TagSchema),
|
|
346
|
+
"xnet://xnet.fyi/Database@2.0.0": () => import("./database-GIXSPZJW.js").then((m) => m.DatabaseSchema),
|
|
347
|
+
"xnet://xnet.fyi/DatabaseRow@2.0.0": () => import("./database-row-6Q6TRVE4.js").then((m) => m.DatabaseRowSchema),
|
|
348
|
+
"xnet://xnet.fyi/DatabaseField@1.0.0": () => import("./database-field-3EPAMZUR.js").then((m) => m.DatabaseFieldSchema),
|
|
349
|
+
"xnet://xnet.fyi/DatabaseSelectOption@1.0.0": () => import("./database-select-option-BBBJFLLH.js").then((m) => m.DatabaseSelectOptionSchema),
|
|
350
|
+
"xnet://xnet.fyi/DatabaseView@1.0.0": () => import("./database-view-5PLSOBI2.js").then((m) => m.DatabaseViewSchema),
|
|
351
|
+
"xnet://xnet.fyi/SchemaExtension@1.0.0": () => import("./schema-extension-LNRF2YRD.js").then((m) => m.SchemaExtensionSchema),
|
|
352
|
+
"xnet://xnet.fyi/ExtensionField@1.0.0": () => import("./schema-extension-LNRF2YRD.js").then((m) => m.ExtensionFieldSchema),
|
|
353
|
+
"xnet://xnet.fyi/Task@1.0.0": () => import("./task-7AOBP7WC.js").then((m) => m.TaskSchema),
|
|
354
|
+
"xnet://xnet.fyi/TaskView@1.0.0": () => import("./task-view-NUGKELJP.js").then((m) => m.TaskViewSchema),
|
|
355
|
+
"xnet://xnet.fyi/Project@1.0.0": () => import("./project-CQL5LN26.js").then((m) => m.ProjectSchema),
|
|
356
|
+
"xnet://xnet.fyi/Metric@1.0.0": () => import("./metric-65SVOX5C.js").then((m) => m.MetricSchema),
|
|
357
|
+
"xnet://xnet.fyi/Observation@1.0.0": () => import("./observation-2Y3QKUXM.js").then((m) => m.ObservationSchema),
|
|
358
|
+
"xnet://xnet.fyi/Experiment@1.0.0": () => import("./experiment-DOVOZ34Y.js").then((m) => m.ExperimentSchema),
|
|
359
|
+
"xnet://xnet.fyi/Milestone@1.0.0": () => import("./milestone-XEO6ZGDG.js").then((m) => m.MilestoneSchema),
|
|
360
|
+
// CRM schema pack (exploration 0188)
|
|
361
|
+
"xnet://xnet.fyi/Organization@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.OrganizationSchema),
|
|
362
|
+
"xnet://xnet.fyi/Contact@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.ContactSchema),
|
|
363
|
+
"xnet://xnet.fyi/Relationship@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.RelationshipSchema),
|
|
364
|
+
"xnet://xnet.fyi/Pipeline@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.PipelineSchema),
|
|
365
|
+
"xnet://xnet.fyi/Stage@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.StageSchema),
|
|
366
|
+
"xnet://xnet.fyi/Deal@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.DealSchema),
|
|
367
|
+
"xnet://xnet.fyi/DealContactRole@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.DealContactRoleSchema),
|
|
368
|
+
"xnet://xnet.fyi/Activity@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.ActivitySchema),
|
|
369
|
+
"xnet://xnet.fyi/Product@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.ProductSchema),
|
|
370
|
+
"xnet://xnet.fyi/LineItem@1.0.0": () => import("./crm-L5RYAAF3.js").then((m) => m.LineItemSchema),
|
|
371
|
+
// Double-entry accounting + personal finance (exploration 0187)
|
|
372
|
+
"xnet://xnet.fyi/Account@1.0.0": () => import("./account-MWNCH4GJ.js").then((m) => m.AccountSchema),
|
|
373
|
+
"xnet://xnet.fyi/Transaction@1.0.0": () => import("./transaction-ZDSEGDIR.js").then((m) => m.TransactionSchema),
|
|
374
|
+
"xnet://xnet.fyi/Posting@1.0.0": () => import("./posting-GBOSZCMZ.js").then((m) => m.PostingSchema),
|
|
375
|
+
"xnet://xnet.fyi/Budget@1.0.0": () => import("./budget-NN7P35XP.js").then((m) => m.BudgetSchema),
|
|
376
|
+
"xnet://xnet.fyi/ImportBatch@1.0.0": () => import("./import-batch-IXBJLQPJ.js").then((m) => m.ImportBatchSchema),
|
|
377
|
+
"xnet://xnet.fyi/Space@1.0.0": () => import("./space-IJU24PBH.js").then((m) => m.SpaceSchema),
|
|
378
|
+
"xnet://xnet.fyi/SpaceMembership@1.0.0": () => import("./space-membership-DEUMM7NV.js").then((m) => m.SpaceMembershipSchema),
|
|
379
|
+
"xnet://xnet.fyi/ExternalReference@1.0.0": () => import("./external-reference-7BSFF6SA.js").then((m) => m.ExternalReferenceSchema),
|
|
380
|
+
"xnet://xnet.fyi/MediaAsset@1.0.0": () => import("./media-asset-QTCGLIZA.js").then((m) => m.MediaAssetSchema),
|
|
381
|
+
"xnet://xnet.fyi/Transcription@1.0.0": () => import("./transcription-PSCLDAGX.js").then((m) => m.TranscriptionSchema),
|
|
382
|
+
"xnet://xnet.fyi/Canvas@1.0.0": () => import("./canvas-6WYBNH53.js").then((m) => m.CanvasSchema),
|
|
383
|
+
"xnet://xnet.fyi/Map@1.0.0": () => import("./map-RG5Y3CPC.js").then((m) => m.MapSchema),
|
|
384
|
+
"xnet://xnet.fyi/Comment@1.0.0": () => import("./comment-QSWYAQVS.js").then((m) => m.CommentSchema),
|
|
385
|
+
"xnet://xnet.fyi/Reaction@1.0.0": () => import("./reaction-T2DTJBBV.js").then((m) => m.ReactionSchema),
|
|
386
|
+
"xnet://xnet.fyi/Profile@1.0.0": () => import("./profile-BLLDWIDK.js").then((m) => m.ProfileSchema),
|
|
387
|
+
"xnet://xnet.fyi/Channel@1.0.0": () => import("./channel-AT3LQF4A.js").then((m) => m.ChannelSchema),
|
|
388
|
+
"xnet://xnet.fyi/ChatMessage@1.0.0": () => import("./chat-message-DSVO72B3.js").then((m) => m.ChatMessageSchema),
|
|
389
|
+
// Integration schema pack (exploration 0213)
|
|
390
|
+
"xnet://xnet.fyi/Feed@1.0.0": () => import("./feed-2IXHHP6O.js").then((m) => m.FeedSchema),
|
|
391
|
+
"xnet://xnet.fyi/FeedItem@1.0.0": () => import("./feed-item-DPE6LN7I.js").then((m) => m.FeedItemSchema),
|
|
392
|
+
"xnet://xnet.fyi/ExternalItem@1.0.0": () => import("./external-item-P2E5X7BZ.js").then((m) => m.ExternalItemSchema),
|
|
393
|
+
"xnet://xnet.fyi/InboxState@1.0.0": () => import("./inbox-state-E5NSVOGP.js").then((m) => m.InboxStateSchema),
|
|
394
|
+
"xnet://xnet.fyi/Grant@1.0.0": () => import("./grant-WTQSNT5A.js").then((m) => m.GrantSchema),
|
|
395
|
+
"xnet://xnet.fyi/AccountRecord@1.0.0": () => import("./account-ledger-R2GAFJL6.js").then((m) => m.AccountRecordSchema),
|
|
396
|
+
"xnet://xnet.fyi/DeviceRecord@1.0.0": () => import("./account-ledger-R2GAFJL6.js").then((m) => m.DeviceRecordSchema),
|
|
397
|
+
"xnet://xnet.fyi/RecoveryRecord@1.0.0": () => import("./account-ledger-R2GAFJL6.js").then((m) => m.RecoveryRecordSchema),
|
|
398
|
+
"xnet://xnet.fyi/RevocationRecord@1.0.0": () => import("./account-ledger-R2GAFJL6.js").then((m) => m.RevocationRecordSchema),
|
|
399
|
+
"xnet://xnet.fyi/SavedView@1.0.0": () => import("./saved-view-4R2DBCL3.js").then((m) => m.SavedViewSchema),
|
|
400
|
+
"xnet://xnet.fyi/Dashboard@1.0.0": () => import("./dashboard-JMKTTRA7.js").then((m) => m.DashboardSchema),
|
|
401
|
+
"xnet://xnet.fyi/UserWidget@1.0.0": () => import("./user-widget-RLY2N46A.js").then((m) => m.UserWidgetSchema),
|
|
402
|
+
"xnet://xnet.fyi/SchemaDefinition@1.0.0": () => import("./system-ILHCZOVO.js").then((m) => m.SchemaDefinitionSchema),
|
|
403
|
+
"xnet://xnet.fyi/SchemaCompatibility@1.0.0": () => import("./system-ILHCZOVO.js").then((m) => m.SchemaCompatibilitySchema),
|
|
404
|
+
"xnet://xnet.fyi/SyncPolicy@1.0.0": () => import("./system-ILHCZOVO.js").then((m) => m.SyncPolicySchema),
|
|
405
|
+
"xnet://xnet.fyi/PresenceSummary@1.0.0": () => import("./system-ILHCZOVO.js").then((m) => m.PresenceSummarySchema),
|
|
406
|
+
"xnet://xnet.fyi/AbuseReport@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.AbuseReportSchema),
|
|
407
|
+
"xnet://xnet.fyi/ModerationLabel@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.ModerationLabelSchema),
|
|
408
|
+
"xnet://xnet.fyi/PolicyList@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.PolicyListSchema),
|
|
409
|
+
"xnet://xnet.fyi/PolicySubscription@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.PolicySubscriptionSchema),
|
|
410
|
+
"xnet://xnet.fyi/PublicInteractionPolicy@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.PublicInteractionPolicySchema),
|
|
411
|
+
"xnet://xnet.fyi/MessageRequest@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.MessageRequestSchema),
|
|
412
|
+
"xnet://xnet.fyi/CommunityNote@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.CommunityNoteSchema),
|
|
413
|
+
"xnet://xnet.fyi/NoteRating@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.NoteRatingSchema),
|
|
414
|
+
"xnet://xnet.fyi/QualitySignal@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.QualitySignalSchema),
|
|
415
|
+
"xnet://xnet.fyi/ContentProvenance@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.ContentProvenanceSchema),
|
|
416
|
+
"xnet://xnet.fyi/Appeal@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.AppealSchema),
|
|
417
|
+
"xnet://xnet.fyi/ReviewTask@1.0.0": () => import("./moderation-FFHETMRB.js").then((m) => m.ReviewTaskSchema),
|
|
418
|
+
// Game-interop schema pack (exploration 0200)
|
|
419
|
+
"xnet://xnet.fyi/PlayerIdentity@1.0.0": () => import("./game-5AK5XWBR.js").then((m) => m.PlayerIdentitySchema),
|
|
420
|
+
"xnet://xnet.fyi/Inventory@1.0.0": () => import("./game-5AK5XWBR.js").then((m) => m.InventorySchema),
|
|
421
|
+
"xnet://xnet.fyi/GameItem@1.0.0": () => import("./game-5AK5XWBR.js").then((m) => m.GameItemSchema),
|
|
422
|
+
"xnet://xnet.fyi/Achievement@1.0.0": () => import("./game-5AK5XWBR.js").then((m) => m.AchievementSchema),
|
|
423
|
+
"xnet://xnet.fyi/MatchSession@1.0.0": () => import("./game-5AK5XWBR.js").then((m) => m.MatchSessionSchema),
|
|
424
|
+
"xnet://xnet.fyi/GameEconomyEntry@1.0.0": () => import("./game-5AK5XWBR.js").then((m) => m.GameEconomyEntrySchema),
|
|
425
|
+
"xnet://xnet.fyi/GameAsset@1.0.0": () => import("./game-5AK5XWBR.js").then((m) => m.GameAssetSchema),
|
|
426
|
+
// Memory schema pack (exploration 0211)
|
|
427
|
+
"xnet://xnet.fyi/MemoryItem@1.0.0": () => import("./memory-PNRTMBZO.js").then((m) => m.MemoryItemSchema),
|
|
428
|
+
// Legacy unversioned IRIs (aliases for the current version)
|
|
429
|
+
"xnet://xnet.fyi/Page": () => import("./page-2V27JGKJ.js").then((m) => m.PageSchema),
|
|
430
|
+
"xnet://xnet.fyi/Folder": () => import("./folder-6KM3KYD5.js").then((m) => m.FolderSchema),
|
|
431
|
+
"xnet://xnet.fyi/Tag": () => import("./tag-SKCHM3U5.js").then((m) => m.TagSchema),
|
|
432
|
+
"xnet://xnet.fyi/Database": () => import("./database-GIXSPZJW.js").then((m) => m.DatabaseSchema),
|
|
433
|
+
"xnet://xnet.fyi/DatabaseRow": () => import("./database-row-6Q6TRVE4.js").then((m) => m.DatabaseRowSchema),
|
|
434
|
+
"xnet://xnet.fyi/DatabaseField": () => import("./database-field-3EPAMZUR.js").then((m) => m.DatabaseFieldSchema),
|
|
435
|
+
"xnet://xnet.fyi/DatabaseSelectOption": () => import("./database-select-option-BBBJFLLH.js").then((m) => m.DatabaseSelectOptionSchema),
|
|
436
|
+
"xnet://xnet.fyi/DatabaseView": () => import("./database-view-5PLSOBI2.js").then((m) => m.DatabaseViewSchema),
|
|
437
|
+
"xnet://xnet.fyi/SchemaExtension": () => import("./schema-extension-LNRF2YRD.js").then((m) => m.SchemaExtensionSchema),
|
|
438
|
+
"xnet://xnet.fyi/ExtensionField": () => import("./schema-extension-LNRF2YRD.js").then((m) => m.ExtensionFieldSchema),
|
|
439
|
+
"xnet://xnet.fyi/Task": () => import("./task-7AOBP7WC.js").then((m) => m.TaskSchema),
|
|
440
|
+
"xnet://xnet.fyi/TaskView": () => import("./task-view-NUGKELJP.js").then((m) => m.TaskViewSchema),
|
|
441
|
+
"xnet://xnet.fyi/Project": () => import("./project-CQL5LN26.js").then((m) => m.ProjectSchema),
|
|
442
|
+
"xnet://xnet.fyi/Metric": () => import("./metric-65SVOX5C.js").then((m) => m.MetricSchema),
|
|
443
|
+
"xnet://xnet.fyi/Observation": () => import("./observation-2Y3QKUXM.js").then((m) => m.ObservationSchema),
|
|
444
|
+
"xnet://xnet.fyi/Experiment": () => import("./experiment-DOVOZ34Y.js").then((m) => m.ExperimentSchema),
|
|
445
|
+
"xnet://xnet.fyi/Milestone": () => import("./milestone-XEO6ZGDG.js").then((m) => m.MilestoneSchema),
|
|
446
|
+
"xnet://xnet.fyi/Organization": () => import("./crm-L5RYAAF3.js").then((m) => m.OrganizationSchema),
|
|
447
|
+
"xnet://xnet.fyi/Contact": () => import("./crm-L5RYAAF3.js").then((m) => m.ContactSchema),
|
|
448
|
+
"xnet://xnet.fyi/Relationship": () => import("./crm-L5RYAAF3.js").then((m) => m.RelationshipSchema),
|
|
449
|
+
"xnet://xnet.fyi/Pipeline": () => import("./crm-L5RYAAF3.js").then((m) => m.PipelineSchema),
|
|
450
|
+
"xnet://xnet.fyi/Stage": () => import("./crm-L5RYAAF3.js").then((m) => m.StageSchema),
|
|
451
|
+
"xnet://xnet.fyi/Deal": () => import("./crm-L5RYAAF3.js").then((m) => m.DealSchema),
|
|
452
|
+
"xnet://xnet.fyi/DealContactRole": () => import("./crm-L5RYAAF3.js").then((m) => m.DealContactRoleSchema),
|
|
453
|
+
"xnet://xnet.fyi/Activity": () => import("./crm-L5RYAAF3.js").then((m) => m.ActivitySchema),
|
|
454
|
+
"xnet://xnet.fyi/Product": () => import("./crm-L5RYAAF3.js").then((m) => m.ProductSchema),
|
|
455
|
+
"xnet://xnet.fyi/LineItem": () => import("./crm-L5RYAAF3.js").then((m) => m.LineItemSchema),
|
|
456
|
+
"xnet://xnet.fyi/Account": () => import("./account-MWNCH4GJ.js").then((m) => m.AccountSchema),
|
|
457
|
+
"xnet://xnet.fyi/Transaction": () => import("./transaction-ZDSEGDIR.js").then((m) => m.TransactionSchema),
|
|
458
|
+
"xnet://xnet.fyi/Posting": () => import("./posting-GBOSZCMZ.js").then((m) => m.PostingSchema),
|
|
459
|
+
"xnet://xnet.fyi/Budget": () => import("./budget-NN7P35XP.js").then((m) => m.BudgetSchema),
|
|
460
|
+
"xnet://xnet.fyi/ImportBatch": () => import("./import-batch-IXBJLQPJ.js").then((m) => m.ImportBatchSchema),
|
|
461
|
+
"xnet://xnet.fyi/Space": () => import("./space-IJU24PBH.js").then((m) => m.SpaceSchema),
|
|
462
|
+
"xnet://xnet.fyi/SpaceMembership": () => import("./space-membership-DEUMM7NV.js").then((m) => m.SpaceMembershipSchema),
|
|
463
|
+
"xnet://xnet.fyi/ExternalReference": () => import("./external-reference-7BSFF6SA.js").then((m) => m.ExternalReferenceSchema),
|
|
464
|
+
"xnet://xnet.fyi/MediaAsset": () => import("./media-asset-QTCGLIZA.js").then((m) => m.MediaAssetSchema),
|
|
465
|
+
"xnet://xnet.fyi/Transcription": () => import("./transcription-PSCLDAGX.js").then((m) => m.TranscriptionSchema),
|
|
466
|
+
"xnet://xnet.fyi/Canvas": () => import("./canvas-6WYBNH53.js").then((m) => m.CanvasSchema),
|
|
467
|
+
"xnet://xnet.fyi/Map": () => import("./map-RG5Y3CPC.js").then((m) => m.MapSchema),
|
|
468
|
+
"xnet://xnet.fyi/Comment": () => import("./comment-QSWYAQVS.js").then((m) => m.CommentSchema),
|
|
469
|
+
"xnet://xnet.fyi/Reaction": () => import("./reaction-T2DTJBBV.js").then((m) => m.ReactionSchema),
|
|
470
|
+
"xnet://xnet.fyi/Profile": () => import("./profile-BLLDWIDK.js").then((m) => m.ProfileSchema),
|
|
471
|
+
"xnet://xnet.fyi/Channel": () => import("./channel-AT3LQF4A.js").then((m) => m.ChannelSchema),
|
|
472
|
+
"xnet://xnet.fyi/ChatMessage": () => import("./chat-message-DSVO72B3.js").then((m) => m.ChatMessageSchema),
|
|
473
|
+
"xnet://xnet.fyi/Feed": () => import("./feed-2IXHHP6O.js").then((m) => m.FeedSchema),
|
|
474
|
+
"xnet://xnet.fyi/FeedItem": () => import("./feed-item-DPE6LN7I.js").then((m) => m.FeedItemSchema),
|
|
475
|
+
"xnet://xnet.fyi/ExternalItem": () => import("./external-item-P2E5X7BZ.js").then((m) => m.ExternalItemSchema),
|
|
476
|
+
"xnet://xnet.fyi/InboxState": () => import("./inbox-state-E5NSVOGP.js").then((m) => m.InboxStateSchema),
|
|
477
|
+
"xnet://xnet.fyi/Grant": () => import("./grant-WTQSNT5A.js").then((m) => m.GrantSchema),
|
|
478
|
+
"xnet://xnet.fyi/AccountRecord": () => import("./account-ledger-R2GAFJL6.js").then((m) => m.AccountRecordSchema),
|
|
479
|
+
"xnet://xnet.fyi/DeviceRecord": () => import("./account-ledger-R2GAFJL6.js").then((m) => m.DeviceRecordSchema),
|
|
480
|
+
"xnet://xnet.fyi/RecoveryRecord": () => import("./account-ledger-R2GAFJL6.js").then((m) => m.RecoveryRecordSchema),
|
|
481
|
+
"xnet://xnet.fyi/RevocationRecord": () => import("./account-ledger-R2GAFJL6.js").then((m) => m.RevocationRecordSchema),
|
|
482
|
+
"xnet://xnet.fyi/SavedView": () => import("./saved-view-4R2DBCL3.js").then((m) => m.SavedViewSchema),
|
|
483
|
+
"xnet://xnet.fyi/Dashboard": () => import("./dashboard-JMKTTRA7.js").then((m) => m.DashboardSchema),
|
|
484
|
+
"xnet://xnet.fyi/UserWidget": () => import("./user-widget-RLY2N46A.js").then((m) => m.UserWidgetSchema),
|
|
485
|
+
"xnet://xnet.fyi/SchemaDefinition": () => import("./system-ILHCZOVO.js").then((m) => m.SchemaDefinitionSchema),
|
|
486
|
+
"xnet://xnet.fyi/SchemaCompatibility": () => import("./system-ILHCZOVO.js").then((m) => m.SchemaCompatibilitySchema),
|
|
487
|
+
"xnet://xnet.fyi/SyncPolicy": () => import("./system-ILHCZOVO.js").then((m) => m.SyncPolicySchema),
|
|
488
|
+
"xnet://xnet.fyi/PresenceSummary": () => import("./system-ILHCZOVO.js").then((m) => m.PresenceSummarySchema),
|
|
489
|
+
"xnet://xnet.fyi/AbuseReport": () => import("./moderation-FFHETMRB.js").then((m) => m.AbuseReportSchema),
|
|
490
|
+
"xnet://xnet.fyi/ModerationLabel": () => import("./moderation-FFHETMRB.js").then((m) => m.ModerationLabelSchema),
|
|
491
|
+
"xnet://xnet.fyi/PolicyList": () => import("./moderation-FFHETMRB.js").then((m) => m.PolicyListSchema),
|
|
492
|
+
"xnet://xnet.fyi/PolicySubscription": () => import("./moderation-FFHETMRB.js").then((m) => m.PolicySubscriptionSchema),
|
|
493
|
+
"xnet://xnet.fyi/PublicInteractionPolicy": () => import("./moderation-FFHETMRB.js").then((m) => m.PublicInteractionPolicySchema),
|
|
494
|
+
"xnet://xnet.fyi/MessageRequest": () => import("./moderation-FFHETMRB.js").then((m) => m.MessageRequestSchema),
|
|
495
|
+
"xnet://xnet.fyi/CommunityNote": () => import("./moderation-FFHETMRB.js").then((m) => m.CommunityNoteSchema),
|
|
496
|
+
"xnet://xnet.fyi/NoteRating": () => import("./moderation-FFHETMRB.js").then((m) => m.NoteRatingSchema),
|
|
497
|
+
"xnet://xnet.fyi/QualitySignal": () => import("./moderation-FFHETMRB.js").then((m) => m.QualitySignalSchema),
|
|
498
|
+
"xnet://xnet.fyi/ContentProvenance": () => import("./moderation-FFHETMRB.js").then((m) => m.ContentProvenanceSchema),
|
|
499
|
+
"xnet://xnet.fyi/Appeal": () => import("./moderation-FFHETMRB.js").then((m) => m.AppealSchema),
|
|
500
|
+
"xnet://xnet.fyi/ReviewTask": () => import("./moderation-FFHETMRB.js").then((m) => m.ReviewTaskSchema),
|
|
501
|
+
// Game-interop schema pack (exploration 0200)
|
|
502
|
+
"xnet://xnet.fyi/PlayerIdentity": () => import("./game-5AK5XWBR.js").then((m) => m.PlayerIdentitySchema),
|
|
503
|
+
"xnet://xnet.fyi/Inventory": () => import("./game-5AK5XWBR.js").then((m) => m.InventorySchema),
|
|
504
|
+
"xnet://xnet.fyi/GameItem": () => import("./game-5AK5XWBR.js").then((m) => m.GameItemSchema),
|
|
505
|
+
"xnet://xnet.fyi/Achievement": () => import("./game-5AK5XWBR.js").then((m) => m.AchievementSchema),
|
|
506
|
+
"xnet://xnet.fyi/MatchSession": () => import("./game-5AK5XWBR.js").then((m) => m.MatchSessionSchema),
|
|
507
|
+
"xnet://xnet.fyi/GameEconomyEntry": () => import("./game-5AK5XWBR.js").then((m) => m.GameEconomyEntrySchema),
|
|
508
|
+
"xnet://xnet.fyi/GameAsset": () => import("./game-5AK5XWBR.js").then((m) => m.GameAssetSchema),
|
|
509
|
+
// Memory schema pack (exploration 0211)
|
|
510
|
+
"xnet://xnet.fyi/MemoryItem": () => import("./memory-PNRTMBZO.js").then((m) => m.MemoryItemSchema)
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
// src/schema/effective-schema.ts
|
|
514
|
+
function buildEffectiveSchema(core, extensions) {
|
|
515
|
+
if (extensions.length === 0) return core;
|
|
516
|
+
const lockedCore = core.properties.map((property) => ({
|
|
517
|
+
...property,
|
|
518
|
+
readonly: true
|
|
519
|
+
}));
|
|
520
|
+
const extensionProperties = extensions.map((field) => {
|
|
521
|
+
const key = extKey(field.authority, field.name);
|
|
522
|
+
return {
|
|
523
|
+
"@id": `${core["@id"]}#${key}`,
|
|
524
|
+
name: key,
|
|
525
|
+
type: field.type,
|
|
526
|
+
required: false,
|
|
527
|
+
readonly: false,
|
|
528
|
+
...field.config ? { config: field.config } : {}
|
|
529
|
+
};
|
|
530
|
+
});
|
|
531
|
+
return { ...core, properties: [...lockedCore, ...extensionProperties] };
|
|
532
|
+
}
|
|
533
|
+
function lockedPropertyKeys(schema) {
|
|
534
|
+
return schema.properties.filter((property) => property.readonly).map((property) => property.name);
|
|
535
|
+
}
|
|
536
|
+
function canModifyColumn(schema, propertyName) {
|
|
537
|
+
const property = schema.properties.find((entry) => entry.name === propertyName);
|
|
538
|
+
if (!property) return false;
|
|
539
|
+
return property.readonly !== true;
|
|
540
|
+
}
|
|
541
|
+
function findLockedColumns(schema, propertyNames) {
|
|
542
|
+
const locked = new Set(lockedPropertyKeys(schema));
|
|
543
|
+
const violations = [];
|
|
544
|
+
for (const name of propertyNames) {
|
|
545
|
+
if (locked.has(name)) violations.push(name);
|
|
546
|
+
}
|
|
547
|
+
return violations;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// src/schema/extension-resolver.ts
|
|
551
|
+
function readString(value) {
|
|
552
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
553
|
+
}
|
|
554
|
+
function selectExtensionFields(targetSchema, extensions, fields) {
|
|
555
|
+
const base = getBaseSchemaIRI(targetSchema);
|
|
556
|
+
const authorityByExtensionId = /* @__PURE__ */ new Map();
|
|
557
|
+
for (const ext of extensions) {
|
|
558
|
+
if (ext.deleted) continue;
|
|
559
|
+
const target = readString(ext.targetSchema);
|
|
560
|
+
const authority = readString(ext.authority);
|
|
561
|
+
if (!target || !authority) continue;
|
|
562
|
+
if (target === targetSchema || getBaseSchemaIRI(target) === base) {
|
|
563
|
+
authorityByExtensionId.set(ext.id, authority);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
if (authorityByExtensionId.size === 0) return [];
|
|
567
|
+
const collected = [];
|
|
568
|
+
for (const field of fields) {
|
|
569
|
+
if (field.deleted) continue;
|
|
570
|
+
const extensionId = readString(field.extension);
|
|
571
|
+
if (!extensionId) continue;
|
|
572
|
+
const authority = authorityByExtensionId.get(extensionId);
|
|
573
|
+
if (!authority) continue;
|
|
574
|
+
const name = readString(field.name);
|
|
575
|
+
const type = readString(field.type);
|
|
576
|
+
if (!name || !type) continue;
|
|
577
|
+
const config = field.config && typeof field.config === "object" ? field.config : void 0;
|
|
578
|
+
collected.push({
|
|
579
|
+
sortKey: readString(field.sortKey) ?? "",
|
|
580
|
+
field: { authority, name, type, ...config ? { config } : {} }
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
collected.sort((a, b) => a.sortKey < b.sortKey ? -1 : a.sortKey > b.sortKey ? 1 : 0);
|
|
584
|
+
return collected.map((entry) => entry.field);
|
|
585
|
+
}
|
|
586
|
+
async function loadExtensionFields(store, targetSchema) {
|
|
587
|
+
const [extensionNodes, fieldNodes] = await Promise.all([
|
|
588
|
+
store.list({ schemaId: SCHEMA_EXTENSION_SCHEMA_IRI }),
|
|
589
|
+
store.list({ schemaId: EXTENSION_FIELD_SCHEMA_IRI })
|
|
590
|
+
]);
|
|
591
|
+
return selectExtensionFields(
|
|
592
|
+
targetSchema,
|
|
593
|
+
extensionNodes.map((node) => ({ id: node.id, deleted: node.deleted, ...node.properties })),
|
|
594
|
+
fieldNodes.map((node) => ({ deleted: node.deleted, ...node.properties }))
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
async function resolveEffectiveSchema(options) {
|
|
598
|
+
const { store, registry, schemaId } = options;
|
|
599
|
+
const defined = await registry.get(schemaId);
|
|
600
|
+
if (!defined) return null;
|
|
601
|
+
const extensions = await loadExtensionFields(store, schemaId);
|
|
602
|
+
return buildEffectiveSchema(defined.schema, extensions);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// src/schema/sidecar.ts
|
|
606
|
+
var SIDECAR_PREFIX = "sidecar:";
|
|
607
|
+
function sidecarId(authority, targetId) {
|
|
608
|
+
return `${SIDECAR_PREFIX}${authority}:${targetId}`;
|
|
609
|
+
}
|
|
610
|
+
var RESERVED_SIDECAR_KEYS = /* @__PURE__ */ new Set(["target", "space"]);
|
|
611
|
+
function sidecarOverlayKeys(overlay) {
|
|
612
|
+
const excluded = new Set(RESERVED_SIDECAR_KEYS);
|
|
613
|
+
for (const key of overlay.exclude ?? []) excluded.add(key);
|
|
614
|
+
const out = {};
|
|
615
|
+
for (const [field, value] of Object.entries(overlay.properties)) {
|
|
616
|
+
if (excluded.has(field)) continue;
|
|
617
|
+
try {
|
|
618
|
+
out[extKey(overlay.authority, field)] = value;
|
|
619
|
+
} catch {
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
return out;
|
|
623
|
+
}
|
|
624
|
+
function mergeSidecarsIntoRow(baseProps, sidecars) {
|
|
625
|
+
const merged = {};
|
|
626
|
+
for (const sidecar of sidecars) {
|
|
627
|
+
Object.assign(merged, sidecarOverlayKeys(sidecar));
|
|
628
|
+
}
|
|
629
|
+
return { ...merged, ...baseProps };
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// src/schema/registry.ts
|
|
633
|
+
var SchemaRegistry = class {
|
|
634
|
+
schemas = /* @__PURE__ */ new Map();
|
|
635
|
+
loadingPromises = /* @__PURE__ */ new Map();
|
|
636
|
+
remoteResolver = null;
|
|
637
|
+
/**
|
|
638
|
+
* Register a custom schema.
|
|
639
|
+
*
|
|
640
|
+
* @param schema - The defined schema to register
|
|
641
|
+
* @throws If a schema with this IRI is already registered
|
|
642
|
+
*/
|
|
643
|
+
register(schema) {
|
|
644
|
+
const iri = schema.schema["@id"];
|
|
645
|
+
if (this.schemas.has(iri)) {
|
|
646
|
+
throw new Error(`Schema already registered: ${iri}`);
|
|
647
|
+
}
|
|
648
|
+
this.schemas.set(iri, {
|
|
649
|
+
schema,
|
|
650
|
+
builtIn: false
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Get a schema by IRI.
|
|
655
|
+
* For built-in schemas, this will lazy-load them on first access.
|
|
656
|
+
*
|
|
657
|
+
* @param iri - The schema IRI
|
|
658
|
+
* @returns The schema, or undefined if not found
|
|
659
|
+
*/
|
|
660
|
+
async get(iri) {
|
|
661
|
+
const entry = this.schemas.get(iri);
|
|
662
|
+
if (entry) {
|
|
663
|
+
return entry.schema;
|
|
664
|
+
}
|
|
665
|
+
if (iri in builtInSchemas) {
|
|
666
|
+
const existingPromise = this.loadingPromises.get(iri);
|
|
667
|
+
if (existingPromise) {
|
|
668
|
+
return existingPromise;
|
|
669
|
+
}
|
|
670
|
+
const loadPromise = builtInSchemas[iri]().then((schema) => {
|
|
671
|
+
this.schemas.set(iri, { schema, builtIn: true });
|
|
672
|
+
this.loadingPromises.delete(iri);
|
|
673
|
+
return schema;
|
|
674
|
+
});
|
|
675
|
+
this.loadingPromises.set(iri, loadPromise);
|
|
676
|
+
return loadPromise;
|
|
677
|
+
}
|
|
678
|
+
if (this.remoteResolver) {
|
|
679
|
+
const existingPromise = this.loadingPromises.get(iri);
|
|
680
|
+
if (existingPromise) {
|
|
681
|
+
return existingPromise;
|
|
682
|
+
}
|
|
683
|
+
const loadPromise = this.remoteResolver(iri).then((definition) => {
|
|
684
|
+
if (!definition) return void 0;
|
|
685
|
+
const parsed = parseSchemaDefinition(definition);
|
|
686
|
+
if (!parsed) return void 0;
|
|
687
|
+
this.schemas.set(iri, { schema: parsed, builtIn: false });
|
|
688
|
+
return parsed;
|
|
689
|
+
}).catch(() => void 0).finally(() => {
|
|
690
|
+
this.loadingPromises.delete(iri);
|
|
691
|
+
});
|
|
692
|
+
this.loadingPromises.set(iri, loadPromise);
|
|
693
|
+
return loadPromise;
|
|
694
|
+
}
|
|
695
|
+
return void 0;
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Get a schema synchronously (only works for already-loaded schemas).
|
|
699
|
+
*
|
|
700
|
+
* @param iri - The schema IRI
|
|
701
|
+
* @returns The schema, or undefined if not loaded
|
|
702
|
+
*/
|
|
703
|
+
getSync(iri) {
|
|
704
|
+
return this.schemas.get(iri)?.schema;
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Check if a schema is registered (either loaded or built-in).
|
|
708
|
+
*/
|
|
709
|
+
has(iri) {
|
|
710
|
+
return this.schemas.has(iri) || iri in builtInSchemas;
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Check if a schema is a built-in schema.
|
|
714
|
+
*/
|
|
715
|
+
isBuiltIn(iri) {
|
|
716
|
+
return iri in builtInSchemas;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Get all registered schema IRIs (including built-in).
|
|
720
|
+
*/
|
|
721
|
+
getAllIRIs() {
|
|
722
|
+
const iris = /* @__PURE__ */ new Set([
|
|
723
|
+
...this.schemas.keys(),
|
|
724
|
+
...Object.keys(builtInSchemas)
|
|
725
|
+
]);
|
|
726
|
+
return Array.from(iris);
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Unregister a custom schema.
|
|
730
|
+
* Built-in schemas cannot be unregistered.
|
|
731
|
+
*
|
|
732
|
+
* @param iri - The schema IRI to unregister
|
|
733
|
+
* @returns true if the schema was unregistered
|
|
734
|
+
*/
|
|
735
|
+
unregister(iri) {
|
|
736
|
+
const entry = this.schemas.get(iri);
|
|
737
|
+
if (!entry || entry.builtIn) {
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
740
|
+
this.schemas.delete(iri);
|
|
741
|
+
return true;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Clear all custom schemas (keeps built-in schemas).
|
|
745
|
+
*/
|
|
746
|
+
clear() {
|
|
747
|
+
for (const [iri, entry] of this.schemas) {
|
|
748
|
+
if (!entry.builtIn) {
|
|
749
|
+
this.schemas.delete(iri);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Set a remote resolver for fetching schemas by IRI.
|
|
755
|
+
* When a schema is not found locally, the resolver is queried.
|
|
756
|
+
*/
|
|
757
|
+
setRemoteResolver(resolver) {
|
|
758
|
+
this.remoteResolver = resolver;
|
|
759
|
+
}
|
|
760
|
+
// ─── Version-Aware Methods ───────────────────────────────────────────────
|
|
761
|
+
/**
|
|
762
|
+
* Get the version of a registered schema.
|
|
763
|
+
*
|
|
764
|
+
* @param iri - The schema IRI (versioned or unversioned)
|
|
765
|
+
* @returns The version string, or undefined if not found
|
|
766
|
+
*/
|
|
767
|
+
getVersion(iri) {
|
|
768
|
+
const entry = this.schemas.get(iri) ?? this.schemas.get(normalizeSchemaIRI(iri));
|
|
769
|
+
if (entry) {
|
|
770
|
+
return entry.schema.schema.version;
|
|
771
|
+
}
|
|
772
|
+
const normalizedIRI = normalizeSchemaIRI(iri);
|
|
773
|
+
if (normalizedIRI in builtInSchemas || iri in builtInSchemas) {
|
|
774
|
+
return "1.0.0";
|
|
775
|
+
}
|
|
776
|
+
return void 0;
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Get all versions of a schema by its base name.
|
|
780
|
+
*
|
|
781
|
+
* @param baseIRI - The unversioned base IRI (e.g., 'xnet://xnet.fyi/Task')
|
|
782
|
+
* @returns Array of versioned schemas, sorted by version
|
|
783
|
+
*/
|
|
784
|
+
getAllVersions(baseIRI) {
|
|
785
|
+
const versions = [];
|
|
786
|
+
const normalizedBase = getBaseSchemaIRI(baseIRI);
|
|
787
|
+
for (const [iri, entry] of this.schemas) {
|
|
788
|
+
if (getBaseSchemaIRI(iri) === normalizedBase) {
|
|
789
|
+
versions.push({
|
|
790
|
+
iri,
|
|
791
|
+
version: entry.schema.schema.version,
|
|
792
|
+
schema: entry.schema
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
for (const builtInIRI of Object.keys(builtInSchemas)) {
|
|
797
|
+
if (getBaseSchemaIRI(builtInIRI) === normalizedBase) {
|
|
798
|
+
const parsed = parseSchemaIRI(builtInIRI);
|
|
799
|
+
if (!versions.some((v) => v.iri === parsed.iri)) {
|
|
800
|
+
versions.push({
|
|
801
|
+
iri: parsed.iri,
|
|
802
|
+
version: parsed.version,
|
|
803
|
+
schema: void 0
|
|
804
|
+
// Placeholder
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
return versions.sort((a, b) => {
|
|
810
|
+
const [aMajor, aMinor, aPatch] = a.version.split(".").map(Number);
|
|
811
|
+
const [bMajor, bMinor, bPatch] = b.version.split(".").map(Number);
|
|
812
|
+
if (aMajor !== bMajor) return aMajor - bMajor;
|
|
813
|
+
if (aMinor !== bMinor) return aMinor - bMinor;
|
|
814
|
+
return aPatch - bPatch;
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Parse a schema IRI into its components.
|
|
819
|
+
*/
|
|
820
|
+
parseIRI(iri) {
|
|
821
|
+
return parseSchemaIRI(iri);
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
var isRecord = (value) => Boolean(value && typeof value === "object");
|
|
825
|
+
var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
826
|
+
var toBoolean = (value) => typeof value === "boolean" ? value : void 0;
|
|
827
|
+
var toStringValue = (value) => typeof value === "string" ? value : void 0;
|
|
828
|
+
var toStringArray = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
|
|
829
|
+
var toRegExp = (value) => {
|
|
830
|
+
if (typeof value !== "string" || value.length === 0) return void 0;
|
|
831
|
+
try {
|
|
832
|
+
return new RegExp(value);
|
|
833
|
+
} catch {
|
|
834
|
+
return void 0;
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
var normalizeSelectOptions = (value) => {
|
|
838
|
+
if (!Array.isArray(value)) return [];
|
|
839
|
+
return value.filter((entry) => isRecord(entry)).map((entry) => ({
|
|
840
|
+
id: typeof entry.id === "string" ? entry.id : "",
|
|
841
|
+
name: typeof entry.name === "string" ? entry.name : "",
|
|
842
|
+
...typeof entry.color === "string" ? { color: entry.color } : {}
|
|
843
|
+
})).filter((entry) => entry.id.length > 0 && entry.name.length > 0);
|
|
844
|
+
};
|
|
845
|
+
var normalizePropertyDefinition = (definition, schemaId) => {
|
|
846
|
+
const name = typeof definition.name === "string" ? definition.name : "";
|
|
847
|
+
const type = typeof definition.type === "string" ? definition.type : "";
|
|
848
|
+
if (!name || !type) return null;
|
|
849
|
+
return {
|
|
850
|
+
"@id": typeof definition["@id"] === "string" ? definition["@id"] : `${schemaId}#${name}`,
|
|
851
|
+
name,
|
|
852
|
+
type: definition.type,
|
|
853
|
+
required: typeof definition.required === "boolean" ? definition.required : false,
|
|
854
|
+
...isRecord(definition.config) ? { config: definition.config } : {}
|
|
855
|
+
};
|
|
856
|
+
};
|
|
857
|
+
var buildPropertyBuilder = (definition) => {
|
|
858
|
+
const config = isRecord(definition.config) ? definition.config : {};
|
|
859
|
+
const required = typeof definition.required === "boolean" ? definition.required : false;
|
|
860
|
+
switch (definition.type) {
|
|
861
|
+
case "text":
|
|
862
|
+
return text({
|
|
863
|
+
required,
|
|
864
|
+
minLength: toNumber(config.minLength),
|
|
865
|
+
maxLength: toNumber(config.maxLength),
|
|
866
|
+
pattern: toRegExp(config.pattern),
|
|
867
|
+
placeholder: toStringValue(config.placeholder)
|
|
868
|
+
});
|
|
869
|
+
case "number":
|
|
870
|
+
return number({
|
|
871
|
+
required,
|
|
872
|
+
min: toNumber(config.min),
|
|
873
|
+
max: toNumber(config.max),
|
|
874
|
+
integer: toBoolean(config.integer)
|
|
875
|
+
});
|
|
876
|
+
case "checkbox":
|
|
877
|
+
return checkbox({
|
|
878
|
+
required,
|
|
879
|
+
default: toBoolean(config.default)
|
|
880
|
+
});
|
|
881
|
+
case "date":
|
|
882
|
+
return date({
|
|
883
|
+
required,
|
|
884
|
+
includeTime: toBoolean(config.includeTime)
|
|
885
|
+
});
|
|
886
|
+
case "dateRange":
|
|
887
|
+
return dateRange({
|
|
888
|
+
required,
|
|
889
|
+
includeTime: toBoolean(config.includeTime)
|
|
890
|
+
});
|
|
891
|
+
case "select": {
|
|
892
|
+
const options = normalizeSelectOptions(config.options);
|
|
893
|
+
return select({
|
|
894
|
+
options,
|
|
895
|
+
required,
|
|
896
|
+
default: toStringValue(config.default)
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
case "multiSelect": {
|
|
900
|
+
const options = normalizeSelectOptions(config.options);
|
|
901
|
+
const defaultValue = toStringArray(config.default);
|
|
902
|
+
return multiSelect({
|
|
903
|
+
options,
|
|
904
|
+
required,
|
|
905
|
+
default: defaultValue
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
case "person":
|
|
909
|
+
return person({
|
|
910
|
+
required,
|
|
911
|
+
multiple: toBoolean(config.multiple)
|
|
912
|
+
});
|
|
913
|
+
case "relation":
|
|
914
|
+
return relation({
|
|
915
|
+
required,
|
|
916
|
+
multiple: toBoolean(config.multiple),
|
|
917
|
+
target: toStringValue(config.target)
|
|
918
|
+
});
|
|
919
|
+
case "url":
|
|
920
|
+
return url({
|
|
921
|
+
required,
|
|
922
|
+
placeholder: toStringValue(config.placeholder)
|
|
923
|
+
});
|
|
924
|
+
case "email":
|
|
925
|
+
return email({
|
|
926
|
+
required,
|
|
927
|
+
placeholder: toStringValue(config.placeholder)
|
|
928
|
+
});
|
|
929
|
+
case "phone":
|
|
930
|
+
return phone({
|
|
931
|
+
required,
|
|
932
|
+
placeholder: toStringValue(config.placeholder)
|
|
933
|
+
});
|
|
934
|
+
case "file":
|
|
935
|
+
return file({
|
|
936
|
+
required,
|
|
937
|
+
multiple: toBoolean(config.multiple),
|
|
938
|
+
accept: toStringArray(config.accept),
|
|
939
|
+
maxSize: toNumber(config.maxSize)
|
|
940
|
+
});
|
|
941
|
+
case "created":
|
|
942
|
+
return created({
|
|
943
|
+
label: toStringValue(config.label)
|
|
944
|
+
});
|
|
945
|
+
case "updated":
|
|
946
|
+
return updated({
|
|
947
|
+
label: toStringValue(config.label)
|
|
948
|
+
});
|
|
949
|
+
case "createdBy":
|
|
950
|
+
return createdBy({
|
|
951
|
+
label: toStringValue(config.label)
|
|
952
|
+
});
|
|
953
|
+
default:
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
var createDefinedSchema = (schema, properties) => {
|
|
958
|
+
const schemaId = schema["@id"];
|
|
959
|
+
const validate = (node) => {
|
|
960
|
+
const errors = [];
|
|
961
|
+
if (typeof node !== "object" || node === null) {
|
|
962
|
+
return { valid: false, errors: [{ path: "", message: "Node must be an object" }] };
|
|
963
|
+
}
|
|
964
|
+
const obj = node;
|
|
965
|
+
if (typeof obj.id !== "string") {
|
|
966
|
+
errors.push({ path: "id", message: "id is required and must be a string" });
|
|
967
|
+
}
|
|
968
|
+
if (obj.schemaId !== schemaId) {
|
|
969
|
+
errors.push({
|
|
970
|
+
path: "schemaId",
|
|
971
|
+
message: `schemaId must be '${schemaId}'`,
|
|
972
|
+
value: obj.schemaId
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
if (typeof obj.createdAt !== "number") {
|
|
976
|
+
errors.push({ path: "createdAt", message: "createdAt is required and must be a number" });
|
|
977
|
+
}
|
|
978
|
+
if (typeof obj.createdBy !== "string" || !obj.createdBy.startsWith("did:key:")) {
|
|
979
|
+
errors.push({ path: "createdBy", message: "createdBy must be a valid DID" });
|
|
980
|
+
}
|
|
981
|
+
for (const [name, builder] of Object.entries(properties)) {
|
|
982
|
+
const value = obj[name];
|
|
983
|
+
const isRequired = builder.definition.required;
|
|
984
|
+
if (value === void 0 || value === null) {
|
|
985
|
+
if (isRequired) {
|
|
986
|
+
errors.push({ path: name, message: `${name} is required` });
|
|
987
|
+
}
|
|
988
|
+
} else if (!builder.validate(value)) {
|
|
989
|
+
errors.push({ path: name, message: `${name} has invalid value`, value });
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
return { valid: errors.length === 0, errors };
|
|
993
|
+
};
|
|
994
|
+
const create = (props, createOptions) => {
|
|
995
|
+
const now = createOptions.createdAt ?? Date.now();
|
|
996
|
+
const id = createOptions.id ?? createNodeId();
|
|
997
|
+
const node = {
|
|
998
|
+
id,
|
|
999
|
+
schemaId,
|
|
1000
|
+
createdAt: now,
|
|
1001
|
+
createdBy: createOptions.createdBy
|
|
1002
|
+
};
|
|
1003
|
+
for (const [name, builder] of Object.entries(properties)) {
|
|
1004
|
+
const rawValue = props[name];
|
|
1005
|
+
const coerced = builder.coerce(rawValue);
|
|
1006
|
+
if (coerced !== null) {
|
|
1007
|
+
node[name] = coerced;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
return node;
|
|
1011
|
+
};
|
|
1012
|
+
const is = (node) => node.schemaId === schemaId;
|
|
1013
|
+
return {
|
|
1014
|
+
schema,
|
|
1015
|
+
validate,
|
|
1016
|
+
create,
|
|
1017
|
+
is,
|
|
1018
|
+
_schemaId: schemaId,
|
|
1019
|
+
_properties: properties
|
|
1020
|
+
};
|
|
1021
|
+
};
|
|
1022
|
+
var parseSchemaDefinition = (definition) => {
|
|
1023
|
+
if (!definition || typeof definition !== "object") return void 0;
|
|
1024
|
+
if (typeof definition["@id"] !== "string") return void 0;
|
|
1025
|
+
if (!Array.isArray(definition.properties)) return void 0;
|
|
1026
|
+
const schemaId = definition["@id"];
|
|
1027
|
+
const properties = definition.properties.map((prop) => normalizePropertyDefinition(prop, schemaId)).filter((prop) => prop !== null);
|
|
1028
|
+
if (properties.length === 0) return void 0;
|
|
1029
|
+
const propertyBuilders = {};
|
|
1030
|
+
for (const property of properties) {
|
|
1031
|
+
const builder = buildPropertyBuilder(property);
|
|
1032
|
+
if (!builder) return void 0;
|
|
1033
|
+
propertyBuilders[property.name] = builder;
|
|
1034
|
+
}
|
|
1035
|
+
const normalizedSchema = {
|
|
1036
|
+
...definition,
|
|
1037
|
+
properties
|
|
1038
|
+
};
|
|
1039
|
+
return createDefinedSchema(normalizedSchema, propertyBuilders);
|
|
1040
|
+
};
|
|
1041
|
+
var schemaRegistry = new SchemaRegistry();
|
|
1042
|
+
|
|
1043
|
+
// src/schema/system-index.ts
|
|
1044
|
+
var SystemSchemaIndex = class {
|
|
1045
|
+
constructor(store, options = {}) {
|
|
1046
|
+
this.store = store;
|
|
1047
|
+
this.options = options;
|
|
1048
|
+
}
|
|
1049
|
+
recordsByNodeId = /* @__PURE__ */ new Map();
|
|
1050
|
+
recordsByIri = /* @__PURE__ */ new Map();
|
|
1051
|
+
recordsByBaseIri = /* @__PURE__ */ new Map();
|
|
1052
|
+
diagnosticsByNodeId = /* @__PURE__ */ new Map();
|
|
1053
|
+
unsubscribe = null;
|
|
1054
|
+
async initialize() {
|
|
1055
|
+
await this.rebuild();
|
|
1056
|
+
this.unsubscribe = this.store.subscribe((event) => {
|
|
1057
|
+
this.applyChangeEvent(event);
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
async rebuild() {
|
|
1061
|
+
this.recordsByNodeId.clear();
|
|
1062
|
+
this.recordsByIri.clear();
|
|
1063
|
+
this.recordsByBaseIri.clear();
|
|
1064
|
+
this.diagnosticsByNodeId.clear();
|
|
1065
|
+
const nodes = await this.store.list({ includeDeleted: false });
|
|
1066
|
+
for (const node of nodes) {
|
|
1067
|
+
this.indexNode(node);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
resolve(iri) {
|
|
1071
|
+
const normalized = normalizeSchemaIRI(iri);
|
|
1072
|
+
const exact = this.recordsByIri.get(normalized) ?? this.recordsByIri.get(iri);
|
|
1073
|
+
if (exact) {
|
|
1074
|
+
return exact.definition;
|
|
1075
|
+
}
|
|
1076
|
+
const candidates = this.recordsByBaseIri.get(getBaseSchemaIRI(iri)) ?? [];
|
|
1077
|
+
return candidates.at(-1)?.definition ?? null;
|
|
1078
|
+
}
|
|
1079
|
+
listDefinitions() {
|
|
1080
|
+
return [...this.recordsByNodeId.values()].sort(
|
|
1081
|
+
(left, right) => left.schemaIri.localeCompare(right.schemaIri)
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
getDiagnostics() {
|
|
1085
|
+
return [...this.diagnosticsByNodeId.values()];
|
|
1086
|
+
}
|
|
1087
|
+
dispose() {
|
|
1088
|
+
this.unsubscribe?.();
|
|
1089
|
+
this.unsubscribe = null;
|
|
1090
|
+
this.recordsByNodeId.clear();
|
|
1091
|
+
this.recordsByIri.clear();
|
|
1092
|
+
this.recordsByBaseIri.clear();
|
|
1093
|
+
this.diagnosticsByNodeId.clear();
|
|
1094
|
+
}
|
|
1095
|
+
applyChangeEvent(event) {
|
|
1096
|
+
if (event.previousNode && isSchemaDefinitionNode(event.previousNode)) {
|
|
1097
|
+
this.removeNode(event.previousNode.id);
|
|
1098
|
+
}
|
|
1099
|
+
if (event.node && !event.node.deleted && isSchemaDefinitionNode(event.node)) {
|
|
1100
|
+
this.indexNode(event.node);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
indexNode(node) {
|
|
1104
|
+
if (!isSchemaDefinitionNode(node)) {
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
const validation = validateSchemaDefinitionNode(node, this.options);
|
|
1108
|
+
if (!validation.valid) {
|
|
1109
|
+
this.diagnosticsByNodeId.set(node.id, { nodeId: node.id, result: validation });
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1112
|
+
const record = toSystemSchemaDefinitionRecord(node);
|
|
1113
|
+
if (!record) {
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
if (!this.options.includeDrafts && record.status !== "published") {
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1119
|
+
this.recordsByNodeId.set(node.id, record);
|
|
1120
|
+
this.recordsByIri.set(record.schemaIri, record);
|
|
1121
|
+
this.recordsByIri.set(normalizeSchemaIRI(record.schemaIri), record);
|
|
1122
|
+
const records = this.recordsByBaseIri.get(record.baseIri) ?? [];
|
|
1123
|
+
records.push(record);
|
|
1124
|
+
records.sort((left, right) => compareVersions(left.version, right.version));
|
|
1125
|
+
this.recordsByBaseIri.set(record.baseIri, records);
|
|
1126
|
+
}
|
|
1127
|
+
removeNode(nodeId) {
|
|
1128
|
+
const existing = this.recordsByNodeId.get(nodeId);
|
|
1129
|
+
this.recordsByNodeId.delete(nodeId);
|
|
1130
|
+
this.diagnosticsByNodeId.delete(nodeId);
|
|
1131
|
+
if (!existing) {
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
this.recordsByIri.delete(existing.schemaIri);
|
|
1135
|
+
this.recordsByIri.delete(normalizeSchemaIRI(existing.schemaIri));
|
|
1136
|
+
const remaining = (this.recordsByBaseIri.get(existing.baseIri) ?? []).filter(
|
|
1137
|
+
(record) => record.nodeId !== nodeId
|
|
1138
|
+
);
|
|
1139
|
+
if (remaining.length === 0) {
|
|
1140
|
+
this.recordsByBaseIri.delete(existing.baseIri);
|
|
1141
|
+
} else {
|
|
1142
|
+
this.recordsByBaseIri.set(existing.baseIri, remaining);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
};
|
|
1146
|
+
function createNodeGraphSchemaResolver(index) {
|
|
1147
|
+
return async (iri) => index.resolve(iri);
|
|
1148
|
+
}
|
|
1149
|
+
function isSchemaDefinitionNode(node) {
|
|
1150
|
+
return node.schemaId === SchemaDefinitionSchema.schema["@id"] || node.schemaId === "xnet://xnet.fyi/SchemaDefinition";
|
|
1151
|
+
}
|
|
1152
|
+
function toSystemSchemaDefinitionRecord(node) {
|
|
1153
|
+
const schemaIri = asSchemaIri(node.properties.schemaIri);
|
|
1154
|
+
const version = asString(node.properties.version);
|
|
1155
|
+
const authority = asString(node.properties.authority);
|
|
1156
|
+
const status = asSchemaDefinitionStatus(node.properties.status);
|
|
1157
|
+
const publishedAt = asNumber(node.properties.publishedAt);
|
|
1158
|
+
const definitionBytes = asString(node.properties.definitionBytes);
|
|
1159
|
+
if (!schemaIri || !version || !authority || !status || publishedAt === null || !definitionBytes) {
|
|
1160
|
+
return null;
|
|
1161
|
+
}
|
|
1162
|
+
const definition = parseSchemaDefinition2(definitionBytes);
|
|
1163
|
+
if (!definition) {
|
|
1164
|
+
return null;
|
|
1165
|
+
}
|
|
1166
|
+
return {
|
|
1167
|
+
nodeId: node.id,
|
|
1168
|
+
schemaIri,
|
|
1169
|
+
baseIri: getBaseSchemaIRI(schemaIri),
|
|
1170
|
+
version,
|
|
1171
|
+
authority,
|
|
1172
|
+
status,
|
|
1173
|
+
publishedAt,
|
|
1174
|
+
definition,
|
|
1175
|
+
diagnostics: []
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
function parseSchemaDefinition2(definitionBytes) {
|
|
1179
|
+
try {
|
|
1180
|
+
const parsed = JSON.parse(definitionBytes);
|
|
1181
|
+
if (!isRecord2(parsed)) return null;
|
|
1182
|
+
if (typeof parsed["@id"] !== "string") return null;
|
|
1183
|
+
if (typeof parsed["@type"] !== "string") return null;
|
|
1184
|
+
if (typeof parsed.name !== "string") return null;
|
|
1185
|
+
if (typeof parsed.namespace !== "string") return null;
|
|
1186
|
+
if (typeof parsed.version !== "string") return null;
|
|
1187
|
+
if (!Array.isArray(parsed.properties)) return null;
|
|
1188
|
+
return parsed;
|
|
1189
|
+
} catch {
|
|
1190
|
+
return null;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
function compareVersions(left, right) {
|
|
1194
|
+
const leftParsed = parseSemver(left);
|
|
1195
|
+
const rightParsed = parseSemver(right);
|
|
1196
|
+
for (let index = 0; index < leftParsed.length; index++) {
|
|
1197
|
+
const diff = leftParsed[index] - rightParsed[index];
|
|
1198
|
+
if (diff !== 0) {
|
|
1199
|
+
return diff;
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
return left.localeCompare(right);
|
|
1203
|
+
}
|
|
1204
|
+
function parseSemver(version) {
|
|
1205
|
+
const parsed = version.split(/[+-]/)[0].split(".").map(Number);
|
|
1206
|
+
return [
|
|
1207
|
+
Number.isFinite(parsed[0]) ? parsed[0] : 0,
|
|
1208
|
+
Number.isFinite(parsed[1]) ? parsed[1] : 0,
|
|
1209
|
+
Number.isFinite(parsed[2]) ? parsed[2] : 0
|
|
1210
|
+
];
|
|
1211
|
+
}
|
|
1212
|
+
function asString(value) {
|
|
1213
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1214
|
+
}
|
|
1215
|
+
function asNumber(value) {
|
|
1216
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1217
|
+
}
|
|
1218
|
+
function asSchemaIri(value) {
|
|
1219
|
+
if (typeof value !== "string" || !value.startsWith("xnet://")) {
|
|
1220
|
+
return null;
|
|
1221
|
+
}
|
|
1222
|
+
const parsed = parseSchemaIRI(value);
|
|
1223
|
+
return parsed.iri;
|
|
1224
|
+
}
|
|
1225
|
+
function asSchemaDefinitionStatus(value) {
|
|
1226
|
+
return value === "draft" || value === "published" || value === "deprecated" || value === "revoked" ? value : null;
|
|
1227
|
+
}
|
|
1228
|
+
function isRecord2(value) {
|
|
1229
|
+
return Boolean(value && typeof value === "object");
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// src/schema/presence.ts
|
|
1233
|
+
var PresenceAggregator = class {
|
|
1234
|
+
constructor(store, options = {}) {
|
|
1235
|
+
this.store = store;
|
|
1236
|
+
this.visibilityForNode = options.visibilityForNode ?? (() => "private");
|
|
1237
|
+
this.now = options.now ?? Date.now;
|
|
1238
|
+
}
|
|
1239
|
+
visibilityForNode;
|
|
1240
|
+
now;
|
|
1241
|
+
unsubscribe = null;
|
|
1242
|
+
rebuildQueued = false;
|
|
1243
|
+
async initialize() {
|
|
1244
|
+
await this.rebuild();
|
|
1245
|
+
this.unsubscribe = this.store.subscribe((event) => {
|
|
1246
|
+
if (isPresenceSummaryNode(event.node) || isPresenceSummaryNode(event.previousNode)) {
|
|
1247
|
+
return;
|
|
1248
|
+
}
|
|
1249
|
+
void this.queueRebuild();
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
async rebuild() {
|
|
1253
|
+
const nodes = await this.store.list({ includeDeleted: false });
|
|
1254
|
+
const summaries = summarizePresenceNodes(nodes, {
|
|
1255
|
+
visibilityForNode: this.visibilityForNode,
|
|
1256
|
+
now: this.now
|
|
1257
|
+
});
|
|
1258
|
+
await this.upsertSummaries(summaries);
|
|
1259
|
+
return summaries;
|
|
1260
|
+
}
|
|
1261
|
+
dispose() {
|
|
1262
|
+
this.unsubscribe?.();
|
|
1263
|
+
this.unsubscribe = null;
|
|
1264
|
+
}
|
|
1265
|
+
async queueRebuild() {
|
|
1266
|
+
if (this.rebuildQueued) {
|
|
1267
|
+
return;
|
|
1268
|
+
}
|
|
1269
|
+
this.rebuildQueued = true;
|
|
1270
|
+
await Promise.resolve();
|
|
1271
|
+
this.rebuildQueued = false;
|
|
1272
|
+
await this.rebuild();
|
|
1273
|
+
}
|
|
1274
|
+
async upsertSummaries(summaries) {
|
|
1275
|
+
const existing = await this.store.list({ includeDeleted: false });
|
|
1276
|
+
const existingById = new Map(
|
|
1277
|
+
existing.filter(isPresenceSummaryNode).map((node) => [node.id, node])
|
|
1278
|
+
);
|
|
1279
|
+
const desiredIds = new Set(summaries.map((summary) => summary.id));
|
|
1280
|
+
for (const summary of summaries) {
|
|
1281
|
+
const existingSummary = existingById.get(summary.id);
|
|
1282
|
+
const properties = {
|
|
1283
|
+
subjectDid: summary.subjectDid,
|
|
1284
|
+
schemaIri: summary.schemaIri,
|
|
1285
|
+
namespace: summary.namespace,
|
|
1286
|
+
countBucket: summary.countBucket,
|
|
1287
|
+
visibility: summary.visibility,
|
|
1288
|
+
lastUpdatedAt: summary.lastUpdatedAt,
|
|
1289
|
+
sourcePolicy: summary.sourcePolicy,
|
|
1290
|
+
noise: summary.noise
|
|
1291
|
+
};
|
|
1292
|
+
if (!existingSummary) {
|
|
1293
|
+
await this.store.create({
|
|
1294
|
+
id: summary.id,
|
|
1295
|
+
schemaId: PresenceSummarySchema.schema["@id"],
|
|
1296
|
+
properties
|
|
1297
|
+
});
|
|
1298
|
+
continue;
|
|
1299
|
+
}
|
|
1300
|
+
if (shouldUpdateSummary(existingSummary, properties)) {
|
|
1301
|
+
await this.store.update(summary.id, { properties });
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
for (const existingSummary of existingById.values()) {
|
|
1305
|
+
if (desiredIds.has(existingSummary.id)) {
|
|
1306
|
+
continue;
|
|
1307
|
+
}
|
|
1308
|
+
const properties = createZeroPresenceSummaryProperties(existingSummary, this.now());
|
|
1309
|
+
if (properties && shouldUpdateSummary(existingSummary, properties)) {
|
|
1310
|
+
await this.store.update(existingSummary.id, { properties });
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
};
|
|
1315
|
+
function summarizePresenceNodes(nodes, options = {}) {
|
|
1316
|
+
const visibilityForNode = options.visibilityForNode ?? (() => "private");
|
|
1317
|
+
const now = options.now ?? Date.now;
|
|
1318
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1319
|
+
for (const node of nodes) {
|
|
1320
|
+
if (node.deleted || isPresenceSummaryNode(node)) {
|
|
1321
|
+
continue;
|
|
1322
|
+
}
|
|
1323
|
+
const visibility = visibilityForNode(node);
|
|
1324
|
+
const namespace = getNodeNamespace(node);
|
|
1325
|
+
const key = `${node.createdBy}|${node.schemaId}|${namespace}|${visibility}`;
|
|
1326
|
+
const existing = groups.get(key);
|
|
1327
|
+
const count = (existing?.count ?? 0) + 1;
|
|
1328
|
+
const subjectDid = node.createdBy;
|
|
1329
|
+
const schemaIri = node.schemaId;
|
|
1330
|
+
groups.set(key, {
|
|
1331
|
+
count,
|
|
1332
|
+
descriptor: {
|
|
1333
|
+
id: buildPresenceSummaryId(subjectDid, schemaIri, namespace, visibility),
|
|
1334
|
+
subjectDid,
|
|
1335
|
+
schemaIri,
|
|
1336
|
+
namespace,
|
|
1337
|
+
countBucket: bucketPresenceCount(count, visibility),
|
|
1338
|
+
visibility,
|
|
1339
|
+
lastUpdatedAt: now(),
|
|
1340
|
+
sourcePolicy: "node-derived",
|
|
1341
|
+
noise: getPresenceNoisePolicy(visibility)
|
|
1342
|
+
}
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
return [...groups.values()].map((entry) => ({
|
|
1346
|
+
...entry.descriptor,
|
|
1347
|
+
countBucket: bucketPresenceCount(entry.count, entry.descriptor.visibility)
|
|
1348
|
+
})).sort((left, right) => left.id.localeCompare(right.id));
|
|
1349
|
+
}
|
|
1350
|
+
function bucketPresenceCount(count, visibility = "private") {
|
|
1351
|
+
const adjusted = visibility === "public-metadata" ? applyPublicPresenceNoise(count) : count;
|
|
1352
|
+
if (adjusted <= 0) return "0";
|
|
1353
|
+
if (adjusted === 1) return "1";
|
|
1354
|
+
if (adjusted <= 5) return "2-5";
|
|
1355
|
+
if (adjusted <= 20) return "6-20";
|
|
1356
|
+
if (adjusted <= 100) return "21-100";
|
|
1357
|
+
return "100+";
|
|
1358
|
+
}
|
|
1359
|
+
function getPresenceNoisePolicy(visibility) {
|
|
1360
|
+
if (visibility === "public-metadata") {
|
|
1361
|
+
return "bucketed:+1-threshold-noise";
|
|
1362
|
+
}
|
|
1363
|
+
return "bucketed";
|
|
1364
|
+
}
|
|
1365
|
+
function createZeroPresenceSummaryProperties(node, lastUpdatedAt) {
|
|
1366
|
+
const subjectDid = asString2(node.properties.subjectDid);
|
|
1367
|
+
const schemaIri = asString2(node.properties.schemaIri);
|
|
1368
|
+
const namespace = asString2(node.properties.namespace);
|
|
1369
|
+
const visibility = asPresenceVisibility(node.properties.visibility);
|
|
1370
|
+
if (!subjectDid || !schemaIri || !namespace || !visibility) {
|
|
1371
|
+
return null;
|
|
1372
|
+
}
|
|
1373
|
+
return {
|
|
1374
|
+
subjectDid,
|
|
1375
|
+
schemaIri,
|
|
1376
|
+
namespace,
|
|
1377
|
+
countBucket: "0",
|
|
1378
|
+
visibility,
|
|
1379
|
+
lastUpdatedAt,
|
|
1380
|
+
sourcePolicy: "node-derived",
|
|
1381
|
+
noise: getPresenceNoisePolicy(visibility)
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
function applyPublicPresenceNoise(count) {
|
|
1385
|
+
if (count <= 1) {
|
|
1386
|
+
return count;
|
|
1387
|
+
}
|
|
1388
|
+
return count + 1;
|
|
1389
|
+
}
|
|
1390
|
+
function buildPresenceSummaryId(subjectDid, schemaIri, namespace, visibility) {
|
|
1391
|
+
return buildSystemNodeId(
|
|
1392
|
+
subjectDid,
|
|
1393
|
+
"presence",
|
|
1394
|
+
`${encodeURIComponent(schemaIri)}:${encodeURIComponent(namespace)}:${visibility}`
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1397
|
+
function getNodeNamespace(node) {
|
|
1398
|
+
const parsedSystem = node.id.match(/^(xnet:\/\/did:key:[^/]+\/sys\/[^/]+\/)/);
|
|
1399
|
+
if (parsedSystem) {
|
|
1400
|
+
return parsedSystem[1];
|
|
1401
|
+
}
|
|
1402
|
+
const parsedSchema = parseSchemaIRI(node.schemaId);
|
|
1403
|
+
return parsedSchema.namespace || getBaseSchemaIRI(node.schemaId);
|
|
1404
|
+
}
|
|
1405
|
+
function isPresenceSummaryNode(node) {
|
|
1406
|
+
return node !== null && node !== void 0 && (node.schemaId === PresenceSummarySchema.schema["@id"] || node.schemaId === "xnet://xnet.fyi/PresenceSummary");
|
|
1407
|
+
}
|
|
1408
|
+
function shouldUpdateSummary(existing, properties) {
|
|
1409
|
+
return Object.entries(properties).some(([key, value]) => existing.properties[key] !== value);
|
|
1410
|
+
}
|
|
1411
|
+
function asString2(value) {
|
|
1412
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1413
|
+
}
|
|
1414
|
+
function asPresenceVisibility(value) {
|
|
1415
|
+
return value === "private" || value === "trusted-app" || value === "public-metadata" ? value : null;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
// src/schema/lens.ts
|
|
1419
|
+
var MigrationError = class extends Error {
|
|
1420
|
+
constructor(message, source, target) {
|
|
1421
|
+
super(message);
|
|
1422
|
+
this.source = source;
|
|
1423
|
+
this.target = target;
|
|
1424
|
+
this.name = "MigrationError";
|
|
1425
|
+
}
|
|
1426
|
+
};
|
|
1427
|
+
var LensRegistry = class {
|
|
1428
|
+
lenses = /* @__PURE__ */ new Map();
|
|
1429
|
+
pathCache = /* @__PURE__ */ new Map();
|
|
1430
|
+
/**
|
|
1431
|
+
* Register a lens for transforming between two schema versions.
|
|
1432
|
+
* Also registers the reverse transformation automatically.
|
|
1433
|
+
*/
|
|
1434
|
+
register(lens) {
|
|
1435
|
+
const forwardKey = `${lens.source}\u2192${lens.target}`;
|
|
1436
|
+
this.lenses.set(forwardKey, lens);
|
|
1437
|
+
const reverseLens = {
|
|
1438
|
+
source: lens.target,
|
|
1439
|
+
target: lens.source,
|
|
1440
|
+
forward: lens.backward,
|
|
1441
|
+
backward: lens.forward,
|
|
1442
|
+
lossless: lens.lossless
|
|
1443
|
+
};
|
|
1444
|
+
const backwardKey = `${lens.target}\u2192${lens.source}`;
|
|
1445
|
+
this.lenses.set(backwardKey, reverseLens);
|
|
1446
|
+
this.pathCache.clear();
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* Unregister a lens (and its reverse).
|
|
1450
|
+
*/
|
|
1451
|
+
unregister(source, target) {
|
|
1452
|
+
const forwardKey = `${source}\u2192${target}`;
|
|
1453
|
+
const backwardKey = `${target}\u2192${source}`;
|
|
1454
|
+
const removedForward = this.lenses.delete(forwardKey);
|
|
1455
|
+
const removedBackward = this.lenses.delete(backwardKey);
|
|
1456
|
+
const removed = removedForward || removedBackward;
|
|
1457
|
+
if (removed) {
|
|
1458
|
+
this.pathCache.clear();
|
|
1459
|
+
}
|
|
1460
|
+
return removed;
|
|
1461
|
+
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Get a direct lens between two schemas (if registered).
|
|
1464
|
+
*/
|
|
1465
|
+
get(source, target) {
|
|
1466
|
+
return this.lenses.get(`${source}\u2192${target}`);
|
|
1467
|
+
}
|
|
1468
|
+
/**
|
|
1469
|
+
* Check if a direct lens exists between two schemas.
|
|
1470
|
+
*/
|
|
1471
|
+
has(source, target) {
|
|
1472
|
+
return this.lenses.has(`${source}\u2192${target}`);
|
|
1473
|
+
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Find the shortest path of lenses between two schema versions.
|
|
1476
|
+
* Uses BFS to find the optimal path through intermediate versions.
|
|
1477
|
+
*
|
|
1478
|
+
* @returns Array of lenses to apply in order, or null if no path exists
|
|
1479
|
+
*/
|
|
1480
|
+
findPath(from, to) {
|
|
1481
|
+
if (from === to) return [];
|
|
1482
|
+
const cacheKey = `${from}\u2192${to}`;
|
|
1483
|
+
if (this.pathCache.has(cacheKey)) {
|
|
1484
|
+
return this.pathCache.get(cacheKey) ?? null;
|
|
1485
|
+
}
|
|
1486
|
+
const path = this.bfsPath(from, to);
|
|
1487
|
+
this.pathCache.set(cacheKey, path);
|
|
1488
|
+
return path;
|
|
1489
|
+
}
|
|
1490
|
+
/**
|
|
1491
|
+
* Transform data from one schema version to another.
|
|
1492
|
+
*
|
|
1493
|
+
* @throws MigrationError if no path exists between schemas
|
|
1494
|
+
*/
|
|
1495
|
+
transform(data, from, to) {
|
|
1496
|
+
if (from === to) return data;
|
|
1497
|
+
const path = this.findPath(from, to);
|
|
1498
|
+
if (!path) {
|
|
1499
|
+
throw new MigrationError(`No migration path from ${from} to ${to}`, from, to);
|
|
1500
|
+
}
|
|
1501
|
+
let result = data;
|
|
1502
|
+
for (const lens of path) {
|
|
1503
|
+
result = lens.forward(result);
|
|
1504
|
+
}
|
|
1505
|
+
return result;
|
|
1506
|
+
}
|
|
1507
|
+
/**
|
|
1508
|
+
* Transform data with detailed migration result.
|
|
1509
|
+
*/
|
|
1510
|
+
transformWithDetails(data, from, to) {
|
|
1511
|
+
if (from === to) {
|
|
1512
|
+
return { data, path: [], lossless: true, warnings: [] };
|
|
1513
|
+
}
|
|
1514
|
+
const path = this.findPath(from, to);
|
|
1515
|
+
if (!path) {
|
|
1516
|
+
throw new MigrationError(`No migration path from ${from} to ${to}`, from, to);
|
|
1517
|
+
}
|
|
1518
|
+
const warnings = [];
|
|
1519
|
+
let result = data;
|
|
1520
|
+
let allLossless = true;
|
|
1521
|
+
for (const lens of path) {
|
|
1522
|
+
result = lens.forward(result);
|
|
1523
|
+
if (!lens.lossless) {
|
|
1524
|
+
allLossless = false;
|
|
1525
|
+
warnings.push(`Lossy transformation: ${lens.source} \u2192 ${lens.target}`);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
return { data: result, path, lossless: allLossless, warnings };
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Check if a migration path exists between two schemas.
|
|
1532
|
+
*/
|
|
1533
|
+
canMigrate(from, to) {
|
|
1534
|
+
return this.findPath(from, to) !== null;
|
|
1535
|
+
}
|
|
1536
|
+
/**
|
|
1537
|
+
* Check if a migration path is lossless (all transformations preserve data).
|
|
1538
|
+
*/
|
|
1539
|
+
isLossless(from, to) {
|
|
1540
|
+
const path = this.findPath(from, to);
|
|
1541
|
+
if (!path) return false;
|
|
1542
|
+
return path.every((lens) => lens.lossless);
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* Get all registered schema IRIs.
|
|
1546
|
+
*/
|
|
1547
|
+
getSchemas() {
|
|
1548
|
+
const schemas = /* @__PURE__ */ new Set();
|
|
1549
|
+
for (const lens of this.lenses.values()) {
|
|
1550
|
+
schemas.add(lens.source);
|
|
1551
|
+
schemas.add(lens.target);
|
|
1552
|
+
}
|
|
1553
|
+
return Array.from(schemas);
|
|
1554
|
+
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Clear all registered lenses and cached paths.
|
|
1557
|
+
*/
|
|
1558
|
+
clear() {
|
|
1559
|
+
this.lenses.clear();
|
|
1560
|
+
this.pathCache.clear();
|
|
1561
|
+
}
|
|
1562
|
+
// ─── Private Methods ─────────────────────────────────────────────────────
|
|
1563
|
+
/**
|
|
1564
|
+
* BFS pathfinding to find shortest lens path between schemas.
|
|
1565
|
+
*/
|
|
1566
|
+
bfsPath(from, to) {
|
|
1567
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
1568
|
+
for (const lens of this.lenses.values()) {
|
|
1569
|
+
const neighbors = adjacency.get(lens.source) ?? [];
|
|
1570
|
+
neighbors.push({ target: lens.target, lens });
|
|
1571
|
+
adjacency.set(lens.source, neighbors);
|
|
1572
|
+
}
|
|
1573
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1574
|
+
const queue = [{ schema: from, path: [] }];
|
|
1575
|
+
while (queue.length > 0) {
|
|
1576
|
+
const { schema, path } = queue.shift();
|
|
1577
|
+
if (schema === to) {
|
|
1578
|
+
return path;
|
|
1579
|
+
}
|
|
1580
|
+
if (visited.has(schema)) {
|
|
1581
|
+
continue;
|
|
1582
|
+
}
|
|
1583
|
+
visited.add(schema);
|
|
1584
|
+
const neighbors = adjacency.get(schema) ?? [];
|
|
1585
|
+
for (const { target, lens } of neighbors) {
|
|
1586
|
+
if (!visited.has(target)) {
|
|
1587
|
+
queue.push({ schema: target, path: [...path, lens] });
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
return null;
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1594
|
+
var lensRegistry = new LensRegistry();
|
|
1595
|
+
|
|
1596
|
+
// src/schema/lens-builders.ts
|
|
1597
|
+
function rename(from, to) {
|
|
1598
|
+
return {
|
|
1599
|
+
forward: (data) => {
|
|
1600
|
+
const { [from]: value, ...rest } = data;
|
|
1601
|
+
return value !== void 0 ? { ...rest, [to]: value } : rest;
|
|
1602
|
+
},
|
|
1603
|
+
backward: (data) => {
|
|
1604
|
+
const { [to]: value, ...rest } = data;
|
|
1605
|
+
return value !== void 0 ? { ...rest, [from]: value } : rest;
|
|
1606
|
+
},
|
|
1607
|
+
lossless: true
|
|
1608
|
+
};
|
|
1609
|
+
}
|
|
1610
|
+
function convert(prop, forwardMap, backwardMap) {
|
|
1611
|
+
return {
|
|
1612
|
+
forward: (data) => {
|
|
1613
|
+
const value = data[prop];
|
|
1614
|
+
if (value === void 0) return data;
|
|
1615
|
+
const key = String(value);
|
|
1616
|
+
const mapped = forwardMap[key];
|
|
1617
|
+
return mapped !== void 0 ? { ...data, [prop]: mapped } : data;
|
|
1618
|
+
},
|
|
1619
|
+
backward: (data) => {
|
|
1620
|
+
const value = data[prop];
|
|
1621
|
+
if (value === void 0) return data;
|
|
1622
|
+
const key = String(value);
|
|
1623
|
+
const mapped = backwardMap[key];
|
|
1624
|
+
return mapped !== void 0 ? { ...data, [prop]: mapped } : data;
|
|
1625
|
+
},
|
|
1626
|
+
lossless: true
|
|
1627
|
+
};
|
|
1628
|
+
}
|
|
1629
|
+
function promoteOverlay(authority, field, coreProp) {
|
|
1630
|
+
return rename(extKey(authority, field), coreProp);
|
|
1631
|
+
}
|
|
1632
|
+
function addDefault(prop, defaultValue) {
|
|
1633
|
+
return {
|
|
1634
|
+
forward: (data) => ({
|
|
1635
|
+
...data,
|
|
1636
|
+
[prop]: data[prop] ?? defaultValue
|
|
1637
|
+
}),
|
|
1638
|
+
backward: (data) => {
|
|
1639
|
+
const { [prop]: _, ...rest } = data;
|
|
1640
|
+
return rest;
|
|
1641
|
+
},
|
|
1642
|
+
lossless: false
|
|
1643
|
+
// Data is lost in backward transform
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
function remove(prop) {
|
|
1647
|
+
return {
|
|
1648
|
+
forward: (data) => {
|
|
1649
|
+
const { [prop]: _, ...rest } = data;
|
|
1650
|
+
return rest;
|
|
1651
|
+
},
|
|
1652
|
+
backward: (data) => data,
|
|
1653
|
+
// Cannot restore removed data
|
|
1654
|
+
lossless: false
|
|
1655
|
+
// Data is lost when property is removed
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
function transform(prop, forwardFn, backwardFn, options) {
|
|
1659
|
+
return {
|
|
1660
|
+
forward: (data) => {
|
|
1661
|
+
const value = data[prop];
|
|
1662
|
+
if (value === void 0) return data;
|
|
1663
|
+
return { ...data, [prop]: forwardFn(value) };
|
|
1664
|
+
},
|
|
1665
|
+
backward: (data) => {
|
|
1666
|
+
const value = data[prop];
|
|
1667
|
+
if (value === void 0) return data;
|
|
1668
|
+
return { ...data, [prop]: backwardFn(value) };
|
|
1669
|
+
},
|
|
1670
|
+
lossless: options?.lossless ?? true
|
|
1671
|
+
};
|
|
1672
|
+
}
|
|
1673
|
+
function copy(from, to) {
|
|
1674
|
+
return {
|
|
1675
|
+
forward: (data) => {
|
|
1676
|
+
const value = data[from];
|
|
1677
|
+
return value !== void 0 ? { ...data, [to]: value } : data;
|
|
1678
|
+
},
|
|
1679
|
+
backward: (data) => {
|
|
1680
|
+
const { [to]: _, ...rest } = data;
|
|
1681
|
+
return rest;
|
|
1682
|
+
},
|
|
1683
|
+
lossless: true
|
|
1684
|
+
};
|
|
1685
|
+
}
|
|
1686
|
+
function merge(fromProps, toProp, mergeFn, splitFn) {
|
|
1687
|
+
return {
|
|
1688
|
+
forward: (data) => {
|
|
1689
|
+
const values = fromProps.map((prop) => data[prop]);
|
|
1690
|
+
if (values.every((v) => v === void 0)) return data;
|
|
1691
|
+
return { ...data, [toProp]: mergeFn(...values) };
|
|
1692
|
+
},
|
|
1693
|
+
backward: (data) => {
|
|
1694
|
+
if (!splitFn) {
|
|
1695
|
+
const { [toProp]: _, ...rest } = data;
|
|
1696
|
+
return rest;
|
|
1697
|
+
}
|
|
1698
|
+
const value = data[toProp];
|
|
1699
|
+
if (value === void 0) return data;
|
|
1700
|
+
const values = splitFn(value);
|
|
1701
|
+
const result = { ...data };
|
|
1702
|
+
delete result[toProp];
|
|
1703
|
+
fromProps.forEach((prop, i) => {
|
|
1704
|
+
if (values[i] !== void 0) {
|
|
1705
|
+
result[prop] = values[i];
|
|
1706
|
+
}
|
|
1707
|
+
});
|
|
1708
|
+
return result;
|
|
1709
|
+
},
|
|
1710
|
+
lossless: splitFn !== void 0
|
|
1711
|
+
};
|
|
1712
|
+
}
|
|
1713
|
+
function when(condition, operation) {
|
|
1714
|
+
return {
|
|
1715
|
+
forward: (data) => condition(data) ? operation.forward(data) : data,
|
|
1716
|
+
backward: (data) => condition(data) ? operation.backward(data) : data,
|
|
1717
|
+
lossless: operation.lossless
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1720
|
+
function composeLens(source, target, ...operations) {
|
|
1721
|
+
return {
|
|
1722
|
+
source,
|
|
1723
|
+
target,
|
|
1724
|
+
forward: (data) => operations.reduce((d, op) => op.forward(d), data),
|
|
1725
|
+
backward: (data) => operations.reduceRight((d, op) => op.backward(d), data),
|
|
1726
|
+
lossless: operations.every((op) => op.lossless !== false)
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1729
|
+
function createOperations(...operations) {
|
|
1730
|
+
return {
|
|
1731
|
+
forward: (data) => operations.reduce((d, op) => op.forward(d), data),
|
|
1732
|
+
backward: (data) => operations.reduceRight((d, op) => op.backward(d), data),
|
|
1733
|
+
lossless: operations.every((op) => op.lossless !== false)
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
function identity(source, target) {
|
|
1737
|
+
return {
|
|
1738
|
+
source,
|
|
1739
|
+
target,
|
|
1740
|
+
forward: (data) => data,
|
|
1741
|
+
backward: (data) => data,
|
|
1742
|
+
lossless: true
|
|
1743
|
+
};
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
export {
|
|
1747
|
+
TASK_SHORT_ID_PATTERN,
|
|
1748
|
+
formatTaskShortId,
|
|
1749
|
+
parseTaskShortId,
|
|
1750
|
+
taskBranchName,
|
|
1751
|
+
shortIdsFromBlock,
|
|
1752
|
+
MAX_MENTION_DIDS,
|
|
1753
|
+
normalizeMentions,
|
|
1754
|
+
mentionsInclude,
|
|
1755
|
+
isValidMentions,
|
|
1756
|
+
createAccountRecord,
|
|
1757
|
+
admitDeviceRecord,
|
|
1758
|
+
nextEpoch,
|
|
1759
|
+
revokeSubjectRecord,
|
|
1760
|
+
revokeDeviceRecord,
|
|
1761
|
+
accountState,
|
|
1762
|
+
encodeAnchor,
|
|
1763
|
+
decodeAnchor,
|
|
1764
|
+
isTextAnchor,
|
|
1765
|
+
isCellAnchor,
|
|
1766
|
+
isRowAnchor,
|
|
1767
|
+
isColumnAnchor,
|
|
1768
|
+
isCanvasPositionAnchor,
|
|
1769
|
+
isCanvasObjectAnchor,
|
|
1770
|
+
isNodeAnchor,
|
|
1771
|
+
extractMentions,
|
|
1772
|
+
getMentionedUsers,
|
|
1773
|
+
checkOrphanStatus,
|
|
1774
|
+
filterOrphanedComments,
|
|
1775
|
+
builtInSchemas,
|
|
1776
|
+
buildEffectiveSchema,
|
|
1777
|
+
lockedPropertyKeys,
|
|
1778
|
+
canModifyColumn,
|
|
1779
|
+
findLockedColumns,
|
|
1780
|
+
selectExtensionFields,
|
|
1781
|
+
loadExtensionFields,
|
|
1782
|
+
resolveEffectiveSchema,
|
|
1783
|
+
SIDECAR_PREFIX,
|
|
1784
|
+
sidecarId,
|
|
1785
|
+
sidecarOverlayKeys,
|
|
1786
|
+
mergeSidecarsIntoRow,
|
|
1787
|
+
SchemaRegistry,
|
|
1788
|
+
schemaRegistry,
|
|
1789
|
+
SystemSchemaIndex,
|
|
1790
|
+
createNodeGraphSchemaResolver,
|
|
1791
|
+
isSchemaDefinitionNode,
|
|
1792
|
+
PresenceAggregator,
|
|
1793
|
+
summarizePresenceNodes,
|
|
1794
|
+
bucketPresenceCount,
|
|
1795
|
+
getPresenceNoisePolicy,
|
|
1796
|
+
MigrationError,
|
|
1797
|
+
LensRegistry,
|
|
1798
|
+
lensRegistry,
|
|
1799
|
+
rename,
|
|
1800
|
+
convert,
|
|
1801
|
+
promoteOverlay,
|
|
1802
|
+
addDefault,
|
|
1803
|
+
remove,
|
|
1804
|
+
transform,
|
|
1805
|
+
copy,
|
|
1806
|
+
merge,
|
|
1807
|
+
when,
|
|
1808
|
+
composeLens,
|
|
1809
|
+
createOperations,
|
|
1810
|
+
identity
|
|
1811
|
+
};
|