uniweb 0.31.1 → 0.32.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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
"prompts": "^2.4.2",
|
|
43
43
|
"tar": "^7.0.0",
|
|
44
44
|
"@uniweb/core": "^0.13.0",
|
|
45
|
-
"@uniweb/kit": "^0.13.7",
|
|
46
45
|
"@uniweb/runtime": "^0.13.0",
|
|
46
|
+
"@uniweb/kit": "^0.13.7",
|
|
47
47
|
"@uniweb/semantic-parser": "^1.3.1"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@uniweb/build": "^0.
|
|
51
|
-
"@uniweb/
|
|
52
|
-
"@uniweb/
|
|
50
|
+
"@uniweb/build": "^0.28.0",
|
|
51
|
+
"@uniweb/content-reader": "^1.2.4",
|
|
52
|
+
"@uniweb/semantic-parser": "^1.3.1"
|
|
53
53
|
},
|
|
54
54
|
"peerDependenciesMeta": {
|
|
55
55
|
"@uniweb/build": {
|
package/src/backend/site-sync.js
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
describeSiteDiff,
|
|
27
27
|
computeUnitHashes,
|
|
28
28
|
collectUnitUuids,
|
|
29
|
+
collectFolderItemUuids,
|
|
29
30
|
readAssetMap
|
|
30
31
|
} from '@uniweb/build/uwx'
|
|
31
32
|
|
|
@@ -457,6 +458,20 @@ export function mergeBaseVersions(siteDir, versions) {
|
|
|
457
458
|
export function readItemUuids(siteDir) {
|
|
458
459
|
return readMap(siteDir, 'itemUuids')
|
|
459
460
|
}
|
|
461
|
+
/**
|
|
462
|
+
* Placement identity for the site's `@uniweb/folder` — path chain → `$uuid`.
|
|
463
|
+
*
|
|
464
|
+
* Kept separate from `itemUuids` (which is site-content units) because they key
|
|
465
|
+
* different trees: `pages/…/page.yml` there, `members/alice` here. One map with
|
|
466
|
+
* two key languages is a map nobody can validate.
|
|
467
|
+
*/
|
|
468
|
+
export function readFolderItemUuids(siteDir) {
|
|
469
|
+
return readMap(siteDir, 'folderItemUuids')
|
|
470
|
+
}
|
|
471
|
+
export function writeFolderItemUuids(siteDir, map) {
|
|
472
|
+
if (!map || !Object.keys(map).length) return
|
|
473
|
+
updateSyncCache(siteDir, { folderItemUuids: map })
|
|
474
|
+
}
|
|
460
475
|
export function writeItemUuids(siteDir, map) {
|
|
461
476
|
if (!map || !Object.keys(map).length) return
|
|
462
477
|
updateSyncCache(siteDir, { itemUuids: map })
|
|
@@ -1297,6 +1312,21 @@ export async function pushSyncPackages({
|
|
|
1297
1312
|
for (const d of bf.deferred) note(`↷ ${d.id ?? `#${d.index}`}: ${d.reason}`)
|
|
1298
1313
|
if (bf.updated.length)
|
|
1299
1314
|
wrote.push(`wrote ${bf.updated.length} record file(s)`)
|
|
1315
|
+
// ⭐ BANK THE FOLDER'S PLACEMENT IDENTITY. The records back-fill their own
|
|
1316
|
+
// `$uuid` into their source files (above); the folder's ITEMS have nowhere to
|
|
1317
|
+
// be written, so they are banked here from the document the backend just
|
|
1318
|
+
// returned.
|
|
1319
|
+
//
|
|
1320
|
+
// ⛔ Without this a `publish` after a `push` is refused: send-only-changed
|
|
1321
|
+
// skips the unchanged records and re-sends the folder ALONE, its `contents`
|
|
1322
|
+
// items carry no `$uuid`, and a `multi` item without one reads as new — so
|
|
1323
|
+
// the backend refuses rather than replacing every placement. Reproduced on a
|
|
1324
|
+
// live manor 2026-08-27; the identities were on the wire all along.
|
|
1325
|
+
const folderDoc = finalized.find((f) => f?.document?.contents)?.document
|
|
1326
|
+
if (folderDoc) {
|
|
1327
|
+
const placements = collectFolderItemUuids(folderDoc)
|
|
1328
|
+
if (Object.keys(placements).length) writeFolderItemUuids(siteDir, placements)
|
|
1329
|
+
}
|
|
1300
1330
|
finalizedTotal += finalized.length
|
|
1301
1331
|
}
|
|
1302
1332
|
|
|
@@ -1323,6 +1353,26 @@ export async function pushSyncPackages({
|
|
|
1323
1353
|
// Replaced wholesale: an item that no longer exists must not keep a uuid that
|
|
1324
1354
|
// would re-target something else.
|
|
1325
1355
|
if (theirs) writeItemUuids(siteDir, collectUnitUuids(theirs))
|
|
1356
|
+
else {
|
|
1357
|
+
// ⛔ BANKING IS BEST-EFFORT AND ITS FAILURE USED TO BE SILENT — say it here,
|
|
1358
|
+
// because the cost lands two commands away and names something else.
|
|
1359
|
+
//
|
|
1360
|
+
// Without `finalized[0].document` (carrying `pages`) this push banks NO item
|
|
1361
|
+
// identity. The push still reports success. The next `push`/`publish` then
|
|
1362
|
+
// emits with no `$uuid` per item, and the backend refuses — correctly, since
|
|
1363
|
+
// silently re-identifying every stored row is far worse. But that refusal
|
|
1364
|
+
// reads as a stale-token or a producer bug, with nothing pointing back at the
|
|
1365
|
+
// push that failed to bank.
|
|
1366
|
+
//
|
|
1367
|
+
// ⚠️ We cannot tell WHY it is absent from here — a response shape that
|
|
1368
|
+
// changed, a lane that shipped nothing, a backend that does not echo the
|
|
1369
|
+
// document. Report the observable fact and let the operator carry it.
|
|
1370
|
+
note(
|
|
1371
|
+
'identity not banked: this push returned no post-write document, so no per-item ' +
|
|
1372
|
+
'$uuid was stored. The next push or publish will be identity-blind and the backend ' +
|
|
1373
|
+
'may refuse it. `uniweb pull` re-arms identity if that happens.'
|
|
1374
|
+
)
|
|
1375
|
+
}
|
|
1326
1376
|
}
|
|
1327
1377
|
return { exitCode: 0, boundSiteUuid, finalizedTotal, wrote }
|
|
1328
1378
|
}
|
package/src/commands/publish.js
CHANGED
|
@@ -77,6 +77,7 @@ import {
|
|
|
77
77
|
readBaseVersions,
|
|
78
78
|
readItemBaseVersions,
|
|
79
79
|
ensureItemUuids,
|
|
80
|
+
readFolderItemUuids,
|
|
80
81
|
ensureSiteExists,
|
|
81
82
|
clearRemoteSyncStateIfUnbound,
|
|
82
83
|
pushSyncPackages,
|
|
@@ -440,6 +441,8 @@ export async function publish(args = []) {
|
|
|
440
441
|
let probe
|
|
441
442
|
try {
|
|
442
443
|
probe = await emitSyncPackages(siteDir, {
|
|
444
|
+
// Placement identity for the folder — see writeFolderItemUuids.
|
|
445
|
+
folderItemUuids: readFolderItemUuids(siteDir),
|
|
443
446
|
// Resolves a foundation-relative `@/x` model ref into `@org/x`.
|
|
444
447
|
...(asOrg ? { org: asOrg } : {}),
|
|
445
448
|
...(foundationDir ? { foundationDir } : {}),
|
|
@@ -641,6 +644,8 @@ export async function publish(args = []) {
|
|
|
641
644
|
let pkg
|
|
642
645
|
try {
|
|
643
646
|
pkg = await emitSyncPackages(siteDir, {
|
|
647
|
+
// Placement identity for the folder — see writeFolderItemUuids.
|
|
648
|
+
folderItemUuids: readFolderItemUuids(siteDir),
|
|
644
649
|
// Resolves a foundation-relative `@/x` model ref into `@org/x`.
|
|
645
650
|
...(asOrg ? { org: asOrg } : {}),
|
|
646
651
|
...(foundationDir ? { foundationDir } : {}),
|
package/src/commands/push.js
CHANGED
|
@@ -84,6 +84,7 @@ import {
|
|
|
84
84
|
readBaseVersions,
|
|
85
85
|
readItemBaseVersions,
|
|
86
86
|
readItemUuids,
|
|
87
|
+
readFolderItemUuids,
|
|
87
88
|
ensureItemUuids,
|
|
88
89
|
ensureSiteExists,
|
|
89
90
|
clearRemoteSyncStateIfUnbound,
|
|
@@ -373,6 +374,8 @@ export async function push(args = [], deps = {}) {
|
|
|
373
374
|
let mediaRefs = []
|
|
374
375
|
try {
|
|
375
376
|
const probe = await emitSyncPackages(siteDir, {
|
|
377
|
+
// Placement identity for the folder — see writeFolderItemUuids.
|
|
378
|
+
folderItemUuids: readFolderItemUuids(siteDir),
|
|
376
379
|
// Resolves a foundation-relative `@/x` model ref into `@org/x`.
|
|
377
380
|
...(asOrg ? { org: asOrg } : {}),
|
|
378
381
|
...(foundationDir ? { foundationDir } : {}),
|
|
@@ -469,6 +472,8 @@ export async function push(args = [], deps = {}) {
|
|
|
469
472
|
let pkg
|
|
470
473
|
try {
|
|
471
474
|
pkg = await emitSyncPackages(siteDir, {
|
|
475
|
+
// Placement identity for the folder — see writeFolderItemUuids.
|
|
476
|
+
folderItemUuids: readFolderItemUuids(siteDir),
|
|
472
477
|
// Resolves a foundation-relative `@/x` model ref into `@org/x`.
|
|
473
478
|
...(asOrg ? { org: asOrg } : {}),
|
|
474
479
|
...(foundationDir ? { foundationDir } : {}),
|
package/src/framework-index.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-08-
|
|
3
|
+
"generatedAt": "2026-08-27T21:10:42.589Z",
|
|
4
4
|
"packages": {
|
|
5
5
|
"@uniweb/build": {
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.28.0",
|
|
7
7
|
"path": "framework/build",
|
|
8
8
|
"deps": [
|
|
9
9
|
"@uniweb/content-reader",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"deps": []
|
|
69
69
|
},
|
|
70
70
|
"@uniweb/projections": {
|
|
71
|
-
"version": "0.
|
|
71
|
+
"version": "0.4.1",
|
|
72
72
|
"path": "framework/projections",
|
|
73
73
|
"deps": [
|
|
74
74
|
"@uniweb/content-writer",
|