@cms0/cms0 0.2.11 → 0.2.12
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/dist/cjs/custom-types/registry.cjs +12 -0
- package/dist/cjs/index.cjs +114 -9
- package/dist/cjs/libs/cli/descriptor-builder-alt.cjs +65 -10
- package/dist/cjs/libs/cli/publisher.cjs +23 -3
- package/dist/cjs/provenance.cjs +517 -0
- package/dist/esm/custom-types/registry.js +12 -0
- package/dist/esm/index.js +101 -8
- package/dist/esm/libs/cli/descriptor-builder-alt.js +65 -10
- package/dist/esm/libs/cli/publisher.js +23 -4
- package/dist/esm/provenance.js +501 -0
- package/dist/types/custom-types/registry.d.ts.map +1 -1
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/libs/cli/descriptor-builder-alt.d.ts.map +1 -1
- package/dist/types/libs/cli/publisher.d.ts +2 -1
- package/dist/types/libs/cli/publisher.d.ts.map +1 -1
- package/dist/types/provenance.d.ts +55 -0
- package/dist/types/provenance.d.ts.map +1 -0
- package/package.json +11 -2
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isCms0CanvasTransportEnabled = isCms0CanvasTransportEnabled;
|
|
4
|
+
exports.registerCms0LiveRoot = registerCms0LiveRoot;
|
|
5
|
+
exports.registerCms0CollectionItemIdentity = registerCms0CollectionItemIdentity;
|
|
6
|
+
exports.readCms0CollectionItemIdentity = readCms0CollectionItemIdentity;
|
|
7
|
+
exports.enableCms0ProvenanceTracking = enableCms0ProvenanceTracking;
|
|
8
|
+
exports.activateCms0CanvasTransport = activateCms0CanvasTransport;
|
|
9
|
+
exports.isCms0ProvenanceTrackingEnabled = isCms0ProvenanceTrackingEnabled;
|
|
10
|
+
exports.attachCms0ProvenanceRoot = attachCms0ProvenanceRoot;
|
|
11
|
+
exports.readCms0ProvenanceValueMeta = readCms0ProvenanceValueMeta;
|
|
12
|
+
exports.unwrapCms0CanvasTransportValue = unwrapCms0CanvasTransportValue;
|
|
13
|
+
exports.readCms0CanvasTransportCollectionItemId = readCms0CanvasTransportCollectionItemId;
|
|
14
|
+
exports.restoreCms0CanvasTransportMetadata = restoreCms0CanvasTransportMetadata;
|
|
15
|
+
exports.readCms0LiveRoots = readCms0LiveRoots;
|
|
16
|
+
exports.captureCms0Provenance = captureCms0Provenance;
|
|
17
|
+
const schema_descriptors_js_1 = require("./schema-descriptors.cjs");
|
|
18
|
+
globalThis.__CMS0_SCHEMA_DESCRIPTOR__ = schema_descriptors_js_1.schemaDescriptor;
|
|
19
|
+
globalThis.__CMS0_CANVAS_SCHEMA_DESCRIPTOR__ = schema_descriptors_js_1.schemaDescriptor;
|
|
20
|
+
const CAPTURE_STACK = [];
|
|
21
|
+
const ARRAY_METHOD_NAMES = new Set(Object.getOwnPropertyNames(Array.prototype));
|
|
22
|
+
const TRACK_IGNORED_OBJECT_KEYS = new Set([
|
|
23
|
+
"__proto__",
|
|
24
|
+
"prototype",
|
|
25
|
+
"constructor",
|
|
26
|
+
"toJSON",
|
|
27
|
+
]);
|
|
28
|
+
const CMS0_CANVAS_TRANSPORT_KEY = "__cms0CanvasTransport";
|
|
29
|
+
const CMS0_CANVAS_TRANSPORT_DATA_KEY = "data";
|
|
30
|
+
const CMS0_CANVAS_COLLECTION_ITEM_ID_KEY = "__cms0CanvasCollectionItemId";
|
|
31
|
+
let provenanceEnabled = false;
|
|
32
|
+
const proxyCache = new WeakMap();
|
|
33
|
+
const proxyMeta = new WeakMap();
|
|
34
|
+
const collectionItemIdentity = new WeakMap();
|
|
35
|
+
function isCanvasTransportEnabled() {
|
|
36
|
+
return globalThis.__CMS0_CANVAS_TRANSPORT_ENABLED__ === true;
|
|
37
|
+
}
|
|
38
|
+
function isCms0CanvasTransportEnabled() {
|
|
39
|
+
return isCanvasTransportEnabled();
|
|
40
|
+
}
|
|
41
|
+
function isRootRawPath(rawPath) {
|
|
42
|
+
return rawPath.length > 0 && !rawPath.includes(".") && !rawPath.includes("[#");
|
|
43
|
+
}
|
|
44
|
+
function cloneCanvasTransportValue(value, seen = new WeakMap()) {
|
|
45
|
+
if (!value || typeof value !== "object")
|
|
46
|
+
return value;
|
|
47
|
+
const cached = seen.get(value);
|
|
48
|
+
if (cached)
|
|
49
|
+
return cached;
|
|
50
|
+
if (Array.isArray(value)) {
|
|
51
|
+
const clone = [];
|
|
52
|
+
seen.set(value, clone);
|
|
53
|
+
value.forEach((item, index) => {
|
|
54
|
+
clone[index] = cloneCanvasTransportValue(item, seen);
|
|
55
|
+
});
|
|
56
|
+
return clone;
|
|
57
|
+
}
|
|
58
|
+
const clone = {};
|
|
59
|
+
seen.set(value, clone);
|
|
60
|
+
Object.entries(value).forEach(([key, nested]) => {
|
|
61
|
+
clone[key] = cloneCanvasTransportValue(nested, seen);
|
|
62
|
+
});
|
|
63
|
+
const collectionItemId = readCms0CollectionItemIdentity(value);
|
|
64
|
+
if (collectionItemId) {
|
|
65
|
+
clone[CMS0_CANVAS_COLLECTION_ITEM_ID_KEY] = collectionItemId;
|
|
66
|
+
}
|
|
67
|
+
return clone;
|
|
68
|
+
}
|
|
69
|
+
function wrapCanvasTransportRoot(value, rootId) {
|
|
70
|
+
return {
|
|
71
|
+
[CMS0_CANVAS_TRANSPORT_KEY]: {
|
|
72
|
+
version: 1,
|
|
73
|
+
rootId,
|
|
74
|
+
},
|
|
75
|
+
[CMS0_CANVAS_TRANSPORT_DATA_KEY]: cloneCanvasTransportValue(value),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function supportsWeakRef() {
|
|
79
|
+
return typeof WeakRef !== "undefined";
|
|
80
|
+
}
|
|
81
|
+
function getLiveRootStore() {
|
|
82
|
+
const existing = globalThis.__CMS0_LIVE_ROOTS__;
|
|
83
|
+
if (existing)
|
|
84
|
+
return existing;
|
|
85
|
+
const created = new Map();
|
|
86
|
+
globalThis.__CMS0_LIVE_ROOTS__ = created;
|
|
87
|
+
return created;
|
|
88
|
+
}
|
|
89
|
+
function derefLiveRoot(entry) {
|
|
90
|
+
if (supportsWeakRef() && entry instanceof WeakRef) {
|
|
91
|
+
return entry.deref() ?? null;
|
|
92
|
+
}
|
|
93
|
+
return entry;
|
|
94
|
+
}
|
|
95
|
+
function pruneDeadLiveRoots(entries) {
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
if (!derefLiveRoot(entry)) {
|
|
98
|
+
entries.delete(entry);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function registerLiveRoot(rootId, value) {
|
|
103
|
+
const store = getLiveRootStore();
|
|
104
|
+
const entries = store.get(rootId) ?? new Set();
|
|
105
|
+
pruneDeadLiveRoots(entries);
|
|
106
|
+
for (const entry of entries) {
|
|
107
|
+
if (derefLiveRoot(entry) === value) {
|
|
108
|
+
store.set(rootId, entries);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
entries.add(supportsWeakRef() ? new WeakRef(value) : value);
|
|
113
|
+
store.set(rootId, entries);
|
|
114
|
+
}
|
|
115
|
+
function registerCms0LiveRoot(rootId, value) {
|
|
116
|
+
const normalizedRoot = typeof rootId === "string" ? rootId.trim() : "";
|
|
117
|
+
if (!normalizedRoot)
|
|
118
|
+
return;
|
|
119
|
+
registerLiveRoot(normalizedRoot, value);
|
|
120
|
+
}
|
|
121
|
+
function registerCms0CollectionItemIdentity(value, collectionItemId) {
|
|
122
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
123
|
+
return;
|
|
124
|
+
const normalizedId = typeof collectionItemId === "string" ? collectionItemId.trim() : "";
|
|
125
|
+
if (!normalizedId)
|
|
126
|
+
return;
|
|
127
|
+
collectionItemIdentity.set(value, normalizedId);
|
|
128
|
+
}
|
|
129
|
+
function readCms0CollectionItemIdentity(value) {
|
|
130
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
131
|
+
return null;
|
|
132
|
+
return collectionItemIdentity.get(value) ?? null;
|
|
133
|
+
}
|
|
134
|
+
function isNumericToken(value) {
|
|
135
|
+
return /^\d+$/.test(value);
|
|
136
|
+
}
|
|
137
|
+
function isItemMarkerToken(value) {
|
|
138
|
+
return /^\[#.+\]$/.test(value);
|
|
139
|
+
}
|
|
140
|
+
function readTrackedEntityId(value) {
|
|
141
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
142
|
+
return null;
|
|
143
|
+
const rawId = value.id;
|
|
144
|
+
return typeof rawId === "string" && rawId.trim().length > 0 ? rawId : null;
|
|
145
|
+
}
|
|
146
|
+
function readTrackedCollectionItemId(value) {
|
|
147
|
+
return readCms0CollectionItemIdentity(value) ?? readTrackedEntityId(value);
|
|
148
|
+
}
|
|
149
|
+
function normalizeTrackedToken(target, property, value) {
|
|
150
|
+
const token = property.trim();
|
|
151
|
+
if (!token)
|
|
152
|
+
return null;
|
|
153
|
+
if (Array.isArray(target)) {
|
|
154
|
+
if (isNumericToken(token)) {
|
|
155
|
+
const entityId = readTrackedCollectionItemId(value);
|
|
156
|
+
return entityId ? `[#${entityId}]` : token;
|
|
157
|
+
}
|
|
158
|
+
if (token === "length")
|
|
159
|
+
return null;
|
|
160
|
+
if (ARRAY_METHOD_NAMES.has(token))
|
|
161
|
+
return null;
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
if (TRACK_IGNORED_OBJECT_KEYS.has(token))
|
|
165
|
+
return null;
|
|
166
|
+
return token;
|
|
167
|
+
}
|
|
168
|
+
function recordPath(pathTokens) {
|
|
169
|
+
const activeCapture = CAPTURE_STACK[CAPTURE_STACK.length - 1];
|
|
170
|
+
if (!activeCapture)
|
|
171
|
+
return;
|
|
172
|
+
const normalizedTokens = pathTokens.filter((token) => token.length > 0);
|
|
173
|
+
if (normalizedTokens.length === 0)
|
|
174
|
+
return;
|
|
175
|
+
activeCapture.paths.add(normalizedTokens.join("."));
|
|
176
|
+
}
|
|
177
|
+
function recordCapture(pathTokens, value) {
|
|
178
|
+
const activeCapture = CAPTURE_STACK[CAPTURE_STACK.length - 1];
|
|
179
|
+
if (!activeCapture)
|
|
180
|
+
return;
|
|
181
|
+
const normalizedTokens = pathTokens.filter((token) => token.length > 0);
|
|
182
|
+
if (normalizedTokens.length === 0)
|
|
183
|
+
return;
|
|
184
|
+
const rawPath = normalizedTokens.join(".");
|
|
185
|
+
const path = canonicalizePath(rawPath);
|
|
186
|
+
if (!path)
|
|
187
|
+
return;
|
|
188
|
+
if (!activeCapture.captures.has(rawPath)) {
|
|
189
|
+
activeCapture.captures.set(rawPath, {
|
|
190
|
+
path,
|
|
191
|
+
rawPath,
|
|
192
|
+
value,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function canonicalizePath(path) {
|
|
197
|
+
return path
|
|
198
|
+
.split(".")
|
|
199
|
+
.map((token) => token.trim())
|
|
200
|
+
.filter((token) => token.length > 0 &&
|
|
201
|
+
!isNumericToken(token) &&
|
|
202
|
+
!isItemMarkerToken(token))
|
|
203
|
+
.join(".");
|
|
204
|
+
}
|
|
205
|
+
function collectCanonicalLeaves(paths) {
|
|
206
|
+
const leaves = new Set();
|
|
207
|
+
for (const rawPath of paths) {
|
|
208
|
+
const canonicalPath = canonicalizePath(rawPath);
|
|
209
|
+
if (!canonicalPath)
|
|
210
|
+
continue;
|
|
211
|
+
leaves.add(canonicalPath);
|
|
212
|
+
}
|
|
213
|
+
const ordered = Array.from(leaves).sort((a, b) => {
|
|
214
|
+
const depthA = a.split(".").length;
|
|
215
|
+
const depthB = b.split(".").length;
|
|
216
|
+
if (depthA !== depthB)
|
|
217
|
+
return depthB - depthA;
|
|
218
|
+
return a.localeCompare(b);
|
|
219
|
+
});
|
|
220
|
+
const filtered = [];
|
|
221
|
+
for (const path of ordered) {
|
|
222
|
+
const isAncestorOfKnownLeaf = filtered.some((known) => known === path || known.startsWith(`${path}.`));
|
|
223
|
+
if (isAncestorOfKnownLeaf)
|
|
224
|
+
continue;
|
|
225
|
+
filtered.push(path);
|
|
226
|
+
}
|
|
227
|
+
return filtered.sort((a, b) => a.localeCompare(b));
|
|
228
|
+
}
|
|
229
|
+
function expandCandidates(paths) {
|
|
230
|
+
const candidates = new Set();
|
|
231
|
+
for (const rawPath of paths) {
|
|
232
|
+
const canonicalPath = canonicalizePath(rawPath);
|
|
233
|
+
if (!canonicalPath)
|
|
234
|
+
continue;
|
|
235
|
+
const tokens = canonicalPath.split(".");
|
|
236
|
+
for (let index = 1; index <= tokens.length; index += 1) {
|
|
237
|
+
candidates.add(tokens.slice(0, index).join("."));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return Array.from(candidates).sort((a, b) => {
|
|
241
|
+
const depthA = a.split(".").length;
|
|
242
|
+
const depthB = b.split(".").length;
|
|
243
|
+
if (depthA !== depthB)
|
|
244
|
+
return depthA - depthB;
|
|
245
|
+
return a.localeCompare(b);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
function longestCommonPrefix(paths) {
|
|
249
|
+
if (paths.length === 0)
|
|
250
|
+
return undefined;
|
|
251
|
+
const tokensList = paths.map((path) => path.split("."));
|
|
252
|
+
const first = tokensList[0];
|
|
253
|
+
if (!first)
|
|
254
|
+
return undefined;
|
|
255
|
+
const prefix = [];
|
|
256
|
+
for (let index = 0; index < first.length; index += 1) {
|
|
257
|
+
const token = first[index];
|
|
258
|
+
if (!token)
|
|
259
|
+
break;
|
|
260
|
+
const matchesAll = tokensList.every((tokens) => tokens[index] === token);
|
|
261
|
+
if (!matchesAll)
|
|
262
|
+
break;
|
|
263
|
+
prefix.push(token);
|
|
264
|
+
}
|
|
265
|
+
return prefix.length ? prefix.join(".") : undefined;
|
|
266
|
+
}
|
|
267
|
+
function buildMapping(paths) {
|
|
268
|
+
const leaves = collectCanonicalLeaves(paths);
|
|
269
|
+
const expanded = expandCandidates(leaves);
|
|
270
|
+
if (expanded.length === 0)
|
|
271
|
+
return null;
|
|
272
|
+
const rootCandidates = new Set();
|
|
273
|
+
expanded.forEach((candidate) => {
|
|
274
|
+
const [root] = candidate.split(".");
|
|
275
|
+
if (root)
|
|
276
|
+
rootCandidates.add(root);
|
|
277
|
+
});
|
|
278
|
+
const rootId = rootCandidates.size === 1 ? Array.from(rootCandidates)[0] : undefined;
|
|
279
|
+
const fieldId = leaves.length === 1 ? leaves[0] : undefined;
|
|
280
|
+
let scopeId;
|
|
281
|
+
if (!fieldId && leaves.length > 1) {
|
|
282
|
+
const prefix = longestCommonPrefix(leaves);
|
|
283
|
+
if (prefix && prefix.includes(".")) {
|
|
284
|
+
scopeId = prefix;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const candidates = expanded.length > 1 ? expanded : undefined;
|
|
288
|
+
if (fieldId) {
|
|
289
|
+
return {
|
|
290
|
+
paths: leaves,
|
|
291
|
+
fieldId,
|
|
292
|
+
scopeId,
|
|
293
|
+
rootId,
|
|
294
|
+
candidates,
|
|
295
|
+
confidence: "exact",
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
if (scopeId) {
|
|
299
|
+
return { paths: leaves, fieldId, scopeId, rootId, candidates, confidence: "scope" };
|
|
300
|
+
}
|
|
301
|
+
if (rootId) {
|
|
302
|
+
return { paths: leaves, fieldId, scopeId, rootId, candidates, confidence: "root" };
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
paths: leaves,
|
|
306
|
+
fieldId,
|
|
307
|
+
scopeId,
|
|
308
|
+
rootId,
|
|
309
|
+
candidates: expanded,
|
|
310
|
+
confidence: "multi",
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function attachCaptures(mapping, captures) {
|
|
314
|
+
if (!mapping || captures.size === 0)
|
|
315
|
+
return mapping;
|
|
316
|
+
const entityIds = {};
|
|
317
|
+
for (const capture of captures.values()) {
|
|
318
|
+
const meta = readCms0ProvenanceValueMeta(capture.value);
|
|
319
|
+
if (!meta?.entityIds)
|
|
320
|
+
continue;
|
|
321
|
+
for (const [rawPath, entityId] of Object.entries(meta.entityIds)) {
|
|
322
|
+
if (typeof entityId !== "string" || entityId.trim().length === 0)
|
|
323
|
+
continue;
|
|
324
|
+
entityIds[rawPath] = entityId;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
...mapping,
|
|
329
|
+
captures: Array.from(captures.values()).sort((left, right) => {
|
|
330
|
+
const depthDelta = left.rawPath.split(".").length - right.rawPath.split(".").length;
|
|
331
|
+
if (depthDelta !== 0)
|
|
332
|
+
return depthDelta;
|
|
333
|
+
return left.rawPath.localeCompare(right.rawPath);
|
|
334
|
+
}),
|
|
335
|
+
entityIds: Object.keys(entityIds).length > 0 ? entityIds : undefined,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function buildEntityLineage(inheritedEntityIds, rawPath, value) {
|
|
339
|
+
const entityId = readTrackedEntityId(value);
|
|
340
|
+
if (!entityId) {
|
|
341
|
+
return inheritedEntityIds;
|
|
342
|
+
}
|
|
343
|
+
return {
|
|
344
|
+
...inheritedEntityIds,
|
|
345
|
+
[rawPath]: entityId,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
function wrapWithProvenance(value, pathTokens, inheritedEntityIds = {}) {
|
|
349
|
+
if (!provenanceEnabled)
|
|
350
|
+
return value;
|
|
351
|
+
if (!value || typeof value !== "object")
|
|
352
|
+
return value;
|
|
353
|
+
const objectValue = value;
|
|
354
|
+
const pathKey = pathTokens.join(".");
|
|
355
|
+
const currentEntityIds = buildEntityLineage(inheritedEntityIds, pathKey, objectValue);
|
|
356
|
+
const cachedByPath = proxyCache.get(objectValue);
|
|
357
|
+
if (cachedByPath?.has(pathKey)) {
|
|
358
|
+
return cachedByPath.get(pathKey);
|
|
359
|
+
}
|
|
360
|
+
const proxy = new Proxy(objectValue, {
|
|
361
|
+
get(target, property, receiver) {
|
|
362
|
+
if (property === "toJSON" &&
|
|
363
|
+
isCanvasTransportEnabled() &&
|
|
364
|
+
isRootRawPath(pathKey)) {
|
|
365
|
+
return () => wrapCanvasTransportRoot(target, pathKey);
|
|
366
|
+
}
|
|
367
|
+
const result = Reflect.get(target, property, receiver);
|
|
368
|
+
if (typeof property !== "string")
|
|
369
|
+
return result;
|
|
370
|
+
const trackedToken = normalizeTrackedToken(target, property, result);
|
|
371
|
+
if (!trackedToken)
|
|
372
|
+
return result;
|
|
373
|
+
const nextPath = [...pathTokens, trackedToken];
|
|
374
|
+
const wrappedResult = wrapWithProvenance(result, nextPath, buildEntityLineage(currentEntityIds, nextPath.join("."), result));
|
|
375
|
+
recordPath(nextPath);
|
|
376
|
+
recordCapture(nextPath, wrappedResult);
|
|
377
|
+
return wrappedResult;
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
const map = cachedByPath ?? new Map();
|
|
381
|
+
map.set(pathKey, proxy);
|
|
382
|
+
if (!cachedByPath) {
|
|
383
|
+
proxyCache.set(objectValue, map);
|
|
384
|
+
}
|
|
385
|
+
const collectionItemId = readCms0CollectionItemIdentity(objectValue);
|
|
386
|
+
if (collectionItemId) {
|
|
387
|
+
collectionItemIdentity.set(proxy, collectionItemId);
|
|
388
|
+
}
|
|
389
|
+
const rawPath = pathKey;
|
|
390
|
+
proxyMeta.set(proxy, {
|
|
391
|
+
path: canonicalizePath(rawPath),
|
|
392
|
+
rawPath,
|
|
393
|
+
entityIds: currentEntityIds,
|
|
394
|
+
});
|
|
395
|
+
return proxy;
|
|
396
|
+
}
|
|
397
|
+
function enableCms0ProvenanceTracking(enabled = true) {
|
|
398
|
+
provenanceEnabled = enabled;
|
|
399
|
+
}
|
|
400
|
+
function activateCms0CanvasTransport(enabled = true) {
|
|
401
|
+
globalThis.__CMS0_CANVAS_TRANSPORT_ENABLED__ = enabled;
|
|
402
|
+
}
|
|
403
|
+
function isCms0ProvenanceTrackingEnabled() {
|
|
404
|
+
return provenanceEnabled;
|
|
405
|
+
}
|
|
406
|
+
function attachCms0ProvenanceRoot(value, rootId, options) {
|
|
407
|
+
if (!provenanceEnabled)
|
|
408
|
+
return value;
|
|
409
|
+
const normalizedRoot = typeof rootId === "string" ? rootId.trim() : "";
|
|
410
|
+
if (!normalizedRoot)
|
|
411
|
+
return value;
|
|
412
|
+
const wrapped = wrapWithProvenance(value, [normalizedRoot]);
|
|
413
|
+
if (options?.registerLiveRoot !== false &&
|
|
414
|
+
wrapped &&
|
|
415
|
+
typeof wrapped === "object") {
|
|
416
|
+
registerLiveRoot(normalizedRoot, wrapped);
|
|
417
|
+
}
|
|
418
|
+
return wrapped;
|
|
419
|
+
}
|
|
420
|
+
function readCms0ProvenanceValueMeta(value) {
|
|
421
|
+
if (!value || typeof value !== "object")
|
|
422
|
+
return null;
|
|
423
|
+
return proxyMeta.get(value) ?? null;
|
|
424
|
+
}
|
|
425
|
+
function unwrapCms0CanvasTransportValue(value) {
|
|
426
|
+
if (!value || typeof value !== "object")
|
|
427
|
+
return null;
|
|
428
|
+
const marker = value[CMS0_CANVAS_TRANSPORT_KEY];
|
|
429
|
+
const payload = value[CMS0_CANVAS_TRANSPORT_DATA_KEY];
|
|
430
|
+
if (!marker || typeof marker !== "object")
|
|
431
|
+
return null;
|
|
432
|
+
const rootId = marker.rootId;
|
|
433
|
+
const version = marker.version;
|
|
434
|
+
if (version !== 1 || typeof rootId !== "string" || rootId.trim().length === 0) {
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
return {
|
|
438
|
+
rootId: rootId.trim(),
|
|
439
|
+
value: payload,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
function readCms0CanvasTransportCollectionItemId(value) {
|
|
443
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
444
|
+
return null;
|
|
445
|
+
const candidate = value[CMS0_CANVAS_COLLECTION_ITEM_ID_KEY];
|
|
446
|
+
return typeof candidate === "string" && candidate.trim().length > 0
|
|
447
|
+
? candidate.trim()
|
|
448
|
+
: null;
|
|
449
|
+
}
|
|
450
|
+
function restoreCanvasTransportMetadataInternal(value, visited) {
|
|
451
|
+
if (!value || typeof value !== "object")
|
|
452
|
+
return;
|
|
453
|
+
if (visited.has(value))
|
|
454
|
+
return;
|
|
455
|
+
visited.add(value);
|
|
456
|
+
if (Array.isArray(value)) {
|
|
457
|
+
value.forEach((entry) => restoreCanvasTransportMetadataInternal(entry, visited));
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const record = value;
|
|
461
|
+
const collectionItemId = record[CMS0_CANVAS_COLLECTION_ITEM_ID_KEY];
|
|
462
|
+
if (typeof collectionItemId === "string" && collectionItemId.trim().length > 0) {
|
|
463
|
+
registerCms0CollectionItemIdentity(record, collectionItemId);
|
|
464
|
+
}
|
|
465
|
+
delete record[CMS0_CANVAS_COLLECTION_ITEM_ID_KEY];
|
|
466
|
+
Object.values(record).forEach((entry) => restoreCanvasTransportMetadataInternal(entry, visited));
|
|
467
|
+
}
|
|
468
|
+
function restoreCms0CanvasTransportMetadata(value) {
|
|
469
|
+
restoreCanvasTransportMetadataInternal(value, new WeakSet());
|
|
470
|
+
return value;
|
|
471
|
+
}
|
|
472
|
+
function readCms0LiveRoots(rootId) {
|
|
473
|
+
const store = globalThis.__CMS0_LIVE_ROOTS__;
|
|
474
|
+
if (!store)
|
|
475
|
+
return [];
|
|
476
|
+
const rootIds = typeof rootId === "string" && rootId.trim().length > 0
|
|
477
|
+
? [rootId.trim()]
|
|
478
|
+
: Array.from(store.keys());
|
|
479
|
+
const results = [];
|
|
480
|
+
for (const id of rootIds) {
|
|
481
|
+
const entries = store.get(id);
|
|
482
|
+
if (!entries)
|
|
483
|
+
continue;
|
|
484
|
+
pruneDeadLiveRoots(entries);
|
|
485
|
+
for (const entry of entries) {
|
|
486
|
+
const value = derefLiveRoot(entry);
|
|
487
|
+
if (!value)
|
|
488
|
+
continue;
|
|
489
|
+
results.push({ rootId: id, value });
|
|
490
|
+
}
|
|
491
|
+
if (entries.size === 0) {
|
|
492
|
+
store.delete(id);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return results;
|
|
496
|
+
}
|
|
497
|
+
globalThis.__CMS0_READ_PROVENANCE_VALUE_META__ = readCms0ProvenanceValueMeta;
|
|
498
|
+
function captureCms0Provenance(evaluate) {
|
|
499
|
+
if (!provenanceEnabled) {
|
|
500
|
+
return { value: evaluate(), mapping: null };
|
|
501
|
+
}
|
|
502
|
+
const capture = {
|
|
503
|
+
paths: new Set(),
|
|
504
|
+
captures: new Map(),
|
|
505
|
+
};
|
|
506
|
+
CAPTURE_STACK.push(capture);
|
|
507
|
+
try {
|
|
508
|
+
const value = evaluate();
|
|
509
|
+
return {
|
|
510
|
+
value,
|
|
511
|
+
mapping: attachCaptures(buildMapping(capture.paths), capture.captures),
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
finally {
|
|
515
|
+
CAPTURE_STACK.pop();
|
|
516
|
+
}
|
|
517
|
+
}
|
|
@@ -15,6 +15,10 @@ const fileFieldDescriptors = {
|
|
|
15
15
|
const fileDescriptor = {
|
|
16
16
|
kind: "model",
|
|
17
17
|
properties: fileFieldDescriptors,
|
|
18
|
+
presentation: {
|
|
19
|
+
kind: "asset",
|
|
20
|
+
assetKind: "file",
|
|
21
|
+
},
|
|
18
22
|
};
|
|
19
23
|
const imageDescriptor = {
|
|
20
24
|
kind: "model",
|
|
@@ -24,6 +28,10 @@ const imageDescriptor = {
|
|
|
24
28
|
height: primitive("number"),
|
|
25
29
|
alt: { kind: "primitive", type: "string", optional: true, nullable: false },
|
|
26
30
|
},
|
|
31
|
+
presentation: {
|
|
32
|
+
kind: "asset",
|
|
33
|
+
assetKind: "image",
|
|
34
|
+
},
|
|
27
35
|
};
|
|
28
36
|
const videoDescriptor = {
|
|
29
37
|
kind: "model",
|
|
@@ -34,6 +42,10 @@ const videoDescriptor = {
|
|
|
34
42
|
length: primitive("number"),
|
|
35
43
|
alt: { kind: "primitive", type: "string", optional: true, nullable: false },
|
|
36
44
|
},
|
|
45
|
+
presentation: {
|
|
46
|
+
kind: "asset",
|
|
47
|
+
assetKind: "video",
|
|
48
|
+
},
|
|
37
49
|
};
|
|
38
50
|
const richTextDescriptor = {
|
|
39
51
|
kind: "primitive",
|