uniweb 0.69.3 → 0.69.5
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/backend/site-sync.js +72 -3
- package/src/framework-index.json +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uniweb",
|
|
3
|
-
"version": "0.69.
|
|
3
|
+
"version": "0.69.5",
|
|
4
4
|
"description": "Create structured Vite + React sites with content/code separation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,16 +41,16 @@
|
|
|
41
41
|
"js-yaml": "^4.1.0",
|
|
42
42
|
"prompts": "^2.4.2",
|
|
43
43
|
"tar": "^7.0.0",
|
|
44
|
-
"@uniweb/core": "^0.29.8",
|
|
45
|
-
"@uniweb/runtime": "^0.27.4",
|
|
46
44
|
"@uniweb/content-writer": "^0.3.4",
|
|
47
|
-
"@uniweb/
|
|
45
|
+
"@uniweb/core": "^0.29.8",
|
|
48
46
|
"@uniweb/kit": "^0.19.4",
|
|
47
|
+
"@uniweb/schemas": "^0.7.0",
|
|
48
|
+
"@uniweb/runtime": "^0.27.4",
|
|
49
49
|
"@uniweb/semantic-parser": "^1.4.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
+
"@uniweb/build": "^0.63.4",
|
|
52
53
|
"@uniweb/content-reader": "^1.2.5",
|
|
53
|
-
"@uniweb/build": "^0.63.2",
|
|
54
54
|
"@uniweb/semantic-parser": "^1.4.1"
|
|
55
55
|
},
|
|
56
56
|
"peerDependenciesMeta": {
|
package/src/backend/site-sync.js
CHANGED
|
@@ -45,7 +45,8 @@ import {
|
|
|
45
45
|
removeYamlScalar,
|
|
46
46
|
harvestRecordItems,
|
|
47
47
|
storedRecordItems,
|
|
48
|
-
reprintRecordItems
|
|
48
|
+
reprintRecordItems,
|
|
49
|
+
matchStoredRecords
|
|
49
50
|
} from '@uniweb/build/uwx'
|
|
50
51
|
|
|
51
52
|
// First entity `$`-document out of a `.uwx` we produced or the backend served.
|
|
@@ -878,6 +879,64 @@ export async function recoverRecordItemUuids({ client, siteDir, uuids, note }) {
|
|
|
878
879
|
}
|
|
879
880
|
}
|
|
880
881
|
|
|
882
|
+
/**
|
|
883
|
+
* Recover the records lane's identity this copy lacks for the site it is bound to — which stored
|
|
884
|
+
* record each of its records is (`records`), each placement's in the folder (`folders`), and the
|
|
885
|
+
* list items of the records it matches (`recordItems`) — from one read of the backend's folder
|
|
886
|
+
* lane. What the copy already holds is kept.
|
|
887
|
+
*
|
|
888
|
+
* ⛔ Until 2026-09-25 nothing recovered these, and a copy whose `sync.json` had lost them — a
|
|
889
|
+
* blog site whose push was refused after its content landed, with an older CLI — was refused on
|
|
890
|
+
* every push after: its folder sent three placements with no `$uuid` while three were stored
|
|
891
|
+
* ("one section carries no item identity (section contents)"). Unrefused, its records would have
|
|
892
|
+
* gone up with none, and the backend would have made a second entity of each.
|
|
893
|
+
*
|
|
894
|
+
* Reads only when the package names a record the map does not, or the folder map is empty; a
|
|
895
|
+
* record new to the backend costs that read and finds nothing (`matchStoredRecords`).
|
|
896
|
+
*
|
|
897
|
+
* @param {object} params
|
|
898
|
+
* @param {object[]} params.index - the records the package sends (`pkg.records.index`)
|
|
899
|
+
* @returns {Promise<number>} how many records and placements were recovered
|
|
900
|
+
*/
|
|
901
|
+
export async function recoverRecordsIdentity({ client, siteDir, index, note }) {
|
|
902
|
+
const state = readBackendState(siteDir, client.origin)
|
|
903
|
+
const siteUuid = state.site?.uuid || null
|
|
904
|
+
const recordMap = state.records || {}
|
|
905
|
+
const records = (index || []).filter((e) => e?.ownId && e.model && e.slug)
|
|
906
|
+
const folders = readFolderItemUuids(siteDir, client.origin)
|
|
907
|
+
const unmapped = records.some((e) => !recordMap[e.ownId])
|
|
908
|
+
if (!siteUuid || !records.length || (!unmapped && Object.keys(folders).length)) return 0
|
|
909
|
+
try {
|
|
910
|
+
const res = await client.pullFolder(siteUuid)
|
|
911
|
+
if (!res?.ok) return 0
|
|
912
|
+
const docs = entityDocsFromUwx(Buffer.from(await res.arrayBuffer()))
|
|
913
|
+
const folderDoc = docs.find((d) => d?.$schema === '@uniweb/folder')
|
|
914
|
+
if (!folderDoc) return 0
|
|
915
|
+
const learned = matchStoredRecords({ index: records, recordMap, folderDoc })
|
|
916
|
+
const matched = Object.keys(learned).length
|
|
917
|
+
if (matched) {
|
|
918
|
+
updateBackendMap(siteDir, client.origin, 'records', learned)
|
|
919
|
+
const stored = new Map(docs.map((d) => [d?.$uuid, d]))
|
|
920
|
+
const items = {}
|
|
921
|
+
for (const theirs of Object.values(learned)) {
|
|
922
|
+
const doc = stored.get(theirs)
|
|
923
|
+
if (doc) items[theirs] = storedRecordItems(doc)
|
|
924
|
+
}
|
|
925
|
+
writeRecordItemUuids(siteDir, client.origin, items)
|
|
926
|
+
}
|
|
927
|
+
const placements = collectFolderItemUuids(folderDoc)
|
|
928
|
+
const missing = Object.fromEntries(Object.entries(placements).filter(([k]) => !folders[k]))
|
|
929
|
+
writeFolderItemUuids(siteDir, client.origin, missing)
|
|
930
|
+
const placed = Object.keys(missing).length
|
|
931
|
+
if (matched || placed) {
|
|
932
|
+
note?.(`Recovered the identity of ${matched} record(s) and ${placed} folder placement(s) from the backend.`)
|
|
933
|
+
}
|
|
934
|
+
return matched + placed
|
|
935
|
+
} catch {
|
|
936
|
+
return 0
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
881
940
|
/**
|
|
882
941
|
* The workspace this site was created in on `backend` — its owner, as the create
|
|
883
942
|
* answered it — in the header's form: `@handle`, a unit's bare uuid when that unit has
|
|
@@ -1263,8 +1322,9 @@ export async function recoverItemUuids({ client, siteDir, note }) {
|
|
|
1263
1322
|
|
|
1264
1323
|
/**
|
|
1265
1324
|
* Recover the identity a package just built went out without, when the backend may hold it —
|
|
1266
|
-
* a page or section (`itemIdentity.unknown`), or a
|
|
1267
|
-
* (`recordItemIdentity.unbanked`) — and say
|
|
1325
|
+
* a page or section (`itemIdentity.unknown`), a record or a folder placement
|
|
1326
|
+
* (`recoverRecordsIdentity`), or a record's list items (`recordItemIdentity.unbanked`) — and say
|
|
1327
|
+
* what to build the package again with.
|
|
1268
1328
|
*
|
|
1269
1329
|
* A page added since the last push is also without identity, and costs one read that finds
|
|
1270
1330
|
* nothing. That is the price of never sending as new an item the backend already holds.
|
|
@@ -1277,6 +1337,15 @@ export async function recoverUnbankedIdentity({ client, siteDir, pkg, note }) {
|
|
|
1277
1337
|
if (pkg?.itemIdentity?.unknown > 0 && (await recoverItemUuids({ client, siteDir, note }))) {
|
|
1278
1338
|
again = { ...again, itemUuids: readItemUuids(siteDir, client.origin) }
|
|
1279
1339
|
}
|
|
1340
|
+
// The records the package sends, and the folder placing them. The emit reads the `records`
|
|
1341
|
+
// map from sync.json itself, so it needs no option — only the build again.
|
|
1342
|
+
if (await recoverRecordsIdentity({ client, siteDir, index: pkg?.records?.index, note })) {
|
|
1343
|
+
again = {
|
|
1344
|
+
...again,
|
|
1345
|
+
folderItemUuids: readFolderItemUuids(siteDir, client.origin),
|
|
1346
|
+
recordItemUuids: readRecordItemUuids(siteDir, client.origin)
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1280
1349
|
const unbanked = pkg?.recordItemIdentity?.unbanked
|
|
1281
1350
|
if (unbanked?.length && (await recoverRecordItemUuids({ client, siteDir, uuids: unbanked, note }))) {
|
|
1282
1351
|
again = { ...again, recordItemUuids: readRecordItemUuids(siteDir, client.origin) }
|
package/src/framework-index.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-09-
|
|
3
|
+
"generatedAt": "2026-09-25T17:28:23.816Z",
|
|
4
4
|
"packages": {
|
|
5
5
|
"@uniweb/api": {
|
|
6
6
|
"version": "0.6.2",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
12
|
"@uniweb/build": {
|
|
13
|
-
"version": "0.63.
|
|
13
|
+
"version": "0.63.4",
|
|
14
14
|
"path": "framework/build",
|
|
15
15
|
"deps": [
|
|
16
16
|
"@uniweb/content-reader",
|