@uniweb/build 0.77.0 → 0.78.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/package.json +5 -5
- package/src/content/index.js +0 -1
- package/src/dev/api-mount.js +27 -19
- package/src/site/content-collector.js +20 -6
- package/src/site/data-fetcher.js +19 -0
- package/src/site/index.js +1 -2
- package/src/site/plugin.js +18 -5
- package/src/site/queries-config.js +2 -1
- package/src/site/query-processor.js +4 -40
- package/src/uwx/emit-surface.json +1 -13
- package/src/uwx/index.js +8 -4
- package/src/uwx/services-request.js +350 -198
- package/src/uwx/shown-records.js +52 -0
- package/src/uwx/site-diff.js +47 -0
- package/src/uwx/site-project.js +39 -53
- package/src/uwx/site.js +58 -161
- package/src/uwx/sync-package.js +30 -21
package/src/uwx/sync-package.js
CHANGED
|
@@ -28,6 +28,7 @@ import { siteProjectToDocument } from './site.js'
|
|
|
28
28
|
import { siteSelfScope, refuseOrgOption } from './self-scope.js'
|
|
29
29
|
import { stampUnitUuids, collectUnitUuids } from './site-diff.js'
|
|
30
30
|
import { emitEntitySyncPackage } from './entity-document.js'
|
|
31
|
+
import { recordQueriesShown } from './shown-records.js'
|
|
31
32
|
import { isLocalAssetPath } from '../site/assets.js'
|
|
32
33
|
|
|
33
34
|
const SITE_MODEL_NAME = '@uniweb/site-content'
|
|
@@ -42,17 +43,28 @@ const cacheKey = (entity) => `${entity.model} ${entity.id}`
|
|
|
42
43
|
// uuid→version map (the sync-cache); an entity the map doesn't know is left
|
|
43
44
|
// unconditional rather than guessed at. See entity-document.js for what the
|
|
44
45
|
// token means on the wire.
|
|
45
|
-
const withBaseVersion = (baseVersions, itemBaseVersions) => (entity) => {
|
|
46
|
+
const withBaseVersion = (baseVersions, itemBaseVersions, { every = false } = {}) => (entity) => {
|
|
46
47
|
const uuid = entity?.document?.$uuid
|
|
47
48
|
const v = uuid ? baseVersions[uuid] : null
|
|
48
|
-
// Per-item preconditions
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
// items
|
|
49
|
+
// Per-item preconditions.
|
|
50
|
+
//
|
|
51
|
+
// ⭐ THE SITE-CONTENT ENTITY SENDS EVERY VERSION THIS COPY HOLDS (`every`), for items
|
|
52
|
+
// present AND for items the files dropped. A push deletes only the items it holds a
|
|
53
|
+
// version for, and only while the site left them unchanged — so a dropped item's
|
|
54
|
+
// version is what makes leaving it out a deletion, and without it the item is kept
|
|
55
|
+
// [Diego, 2026-10-07; backend's gate, kb/framework/plans/services-exchange.md]. The
|
|
56
|
+
// caller holds a version only for an item it has seen (`heldTokens`, cli), so none is
|
|
57
|
+
// ever sent for an item the backend holds and this copy does not.
|
|
58
|
+
// ⛔ Until then this narrowed to the units the document carried: a dropped page was
|
|
59
|
+
// deleted by today's rule anyway, and nothing else was sent a version.
|
|
60
|
+
//
|
|
61
|
+
// Any other entity: narrowed to the units it carries, as before — the records lane
|
|
62
|
+
// is gated by its entity version, and sends none.
|
|
52
63
|
let items = null
|
|
53
64
|
if (itemBaseVersions && Object.keys(itemBaseVersions).length) {
|
|
54
65
|
items = {}
|
|
55
|
-
|
|
66
|
+
const uuids = every ? Object.keys(itemBaseVersions) : Object.values(collectUnitUuids(entity.document))
|
|
67
|
+
for (const itemUuid of uuids) {
|
|
56
68
|
const t = itemBaseVersions[itemUuid]
|
|
57
69
|
if (t) items[itemUuid] = t
|
|
58
70
|
}
|
|
@@ -215,8 +227,6 @@ function rewriteEntityAssets(node, map, ids, noStamp = null) {
|
|
|
215
227
|
* @param {string} [opts.sourceLocale] - localized-field wrap locale
|
|
216
228
|
* @param {Object<string,string>} [opts.priorHashes] - sync-cache (send-only-changed)
|
|
217
229
|
* @param {boolean} [opts.sendAll] - bypass the prior-hash filter
|
|
218
|
-
* @param {object[]} [opts.serviceRows] - the `services` Section to send, as the
|
|
219
|
-
* caller decided it (site.js `requestedServices`)
|
|
220
230
|
* @param {Object<string,string>} [opts.itemUuids] - unit path → backend `$uuid`,
|
|
221
231
|
* stamped onto the site-content document so the backend matches our items
|
|
222
232
|
* instead of re-minting them (which deletes and recreates every page and
|
|
@@ -225,11 +235,12 @@ function rewriteEntityAssets(node, map, ids, noStamp = null) {
|
|
|
225
235
|
* identity of its list items, as a previous push or pull banked it
|
|
226
236
|
* (`record-items.js`); stamped onto each record the backend holds, so a re-sent
|
|
227
237
|
* record updates its items instead of replacing them.
|
|
228
|
-
* @param {Object<string,string>} [opts.itemBaseVersions] -
|
|
229
|
-
* per-ITEM `version
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
238
|
+
* @param {Object<string,string>} [opts.itemBaseVersions] - item `$uuid` → opaque
|
|
239
|
+
* per-ITEM `version`, for every site-content item this copy has seen. Sent
|
|
240
|
+
* whole on the site-content entity as `entries[].item_base_versions` — items
|
|
241
|
+
* present and items the files dropped — so the backend refuses only the items
|
|
242
|
+
* that genuinely moved, and deletes only what this copy saw (`withBaseVersion`).
|
|
243
|
+
* Omit to push unconditionally.
|
|
233
244
|
* @param {Object<string,string>} [opts.baseVersions] - backend-uuid → opaque
|
|
234
245
|
* `version` token, the push gate's optimistic-concurrency precondition.
|
|
235
246
|
* Each sent entity whose `$uuid` the map knows carries it as a top-level
|
|
@@ -292,6 +303,7 @@ export async function emitSyncPackages(siteRoot, opts = {}) {
|
|
|
292
303
|
const priorHashes = opts.priorHashes || {}
|
|
293
304
|
const sendAll = !!opts.sendAll
|
|
294
305
|
const stamp = withBaseVersion(opts.baseVersions || {}, opts.itemBaseVersions || {})
|
|
306
|
+
const stampSite = withBaseVersion(opts.baseVersions || {}, opts.itemBaseVersions || {}, { every: true })
|
|
295
307
|
const exporter = opts.exporter
|
|
296
308
|
const exportedAt = opts.exportedAt
|
|
297
309
|
refuseOrgOption(opts, 'emitSyncPackages')
|
|
@@ -376,13 +388,7 @@ export async function emitSyncPackages(siteRoot, opts = {}) {
|
|
|
376
388
|
// and the page and `settings` keys that carry Open Graph texts per language.
|
|
377
389
|
...(Array.isArray(opts.queryFields) ? { queryFields: opts.queryFields } : {}),
|
|
378
390
|
...(Array.isArray(opts.pageFields) ? { pageFields: opts.pageFields } : {}),
|
|
379
|
-
...(Array.isArray(opts.settingsFields) ? { settingsFields: opts.settingsFields } : {})
|
|
380
|
-
// The `services` Section as the caller decided it — the site's rows with the
|
|
381
|
-
// owner's changed asks applied — or the Sections withheld. Passed through
|
|
382
|
-
// rather than decided here: the site's rows and the last agreement are what
|
|
383
|
-
// the CLI reads. See site.js at `requestedServices`.
|
|
384
|
-
...(Array.isArray(opts.serviceRows) ? { serviceRows: opts.serviceRows } : {}),
|
|
385
|
-
...(opts.declareServices === false ? { declareServices: false } : {})
|
|
391
|
+
...(Array.isArray(opts.settingsFields) ? { settingsFields: opts.settingsFields } : {})
|
|
386
392
|
})
|
|
387
393
|
: null
|
|
388
394
|
// Deploy-derived `info` fields are stamped here — NOT authored in site.yml, so they
|
|
@@ -584,7 +590,7 @@ export async function emitSyncPackages(siteRoot, opts = {}) {
|
|
|
584
590
|
// --- site-content lane -------------------------------------------------------
|
|
585
591
|
let siteContent = null
|
|
586
592
|
if (siteEntity && changed(siteEntity)) {
|
|
587
|
-
siteContent = { ...emitLane([
|
|
593
|
+
siteContent = { ...emitLane([stampSite(siteEntity)], exporter, exportedAt), index: [{ kind: 'site' }] }
|
|
588
594
|
}
|
|
589
595
|
|
|
590
596
|
// The site's current uuid (from site.yml): the verb keys the folder push route on
|
|
@@ -636,5 +642,8 @@ export async function emitSyncPackages(siteRoot, opts = {}) {
|
|
|
636
642
|
// records this package SENDS that the backend holds with list items and no bank entry
|
|
637
643
|
// (their uuids) — sent as they are, the backend refuses each one (`identity_required`).
|
|
638
644
|
recordItemIdentity,
|
|
645
|
+
// The queries whose records the site's pages show live — what the `records` service
|
|
646
|
+
// delivers on a published site (`shown-records.js`). Whether it changed or not.
|
|
647
|
+
recordsShown: siteDoc ? recordQueriesShown(siteDoc) : [],
|
|
639
648
|
}
|
|
640
649
|
}
|