uniweb 0.26.0 → 0.26.1

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.26.0",
3
+ "version": "0.26.1",
4
4
  "description": "Create structured Vite + React sites with content/code separation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -43,13 +43,13 @@
43
43
  "tar": "^7.0.0",
44
44
  "@uniweb/core": "^0.10.1",
45
45
  "@uniweb/kit": "^0.12.3",
46
- "@uniweb/runtime": "^0.12.2",
47
- "@uniweb/semantic-parser": "^1.2.3"
46
+ "@uniweb/semantic-parser": "^1.2.3",
47
+ "@uniweb/runtime": "^0.12.2"
48
48
  },
49
49
  "peerDependencies": {
50
+ "@uniweb/build": "^0.24.5",
50
51
  "@uniweb/content-reader": "^1.2.3",
51
- "@uniweb/semantic-parser": "^1.2.3",
52
- "@uniweb/build": "^0.24.5"
52
+ "@uniweb/semantic-parser": "^1.2.3"
53
53
  },
54
54
  "peerDependenciesMeta": {
55
55
  "@uniweb/build": {
@@ -241,6 +241,33 @@ export async function push(args = [], deps = {}) {
241
241
  // `index` — the per-entity source-file map for back-fill, correlated by submission
242
242
  // position. Non-local Models are fetched from the registry on demand. `priorHashes`
243
243
  // (the .uniweb push-cache) drives "send only changed" across both lanes; --all bypasses.
244
+ // ⛔ DROP STALE REMOTE STATE FIRST — this must precede the hash read below, and it
245
+ // did not until 2026-08-19.
246
+ //
247
+ // The guard itself is right and its docblock names this exact outcome: on a clone
248
+ // whose `$uuid` was cleared to re-publish as a new site — WHICH IS OUR OWN
249
+ // DOCUMENTED RECOVERY — send-only-changed would "skip every entity whose content
250
+ // had not changed since the OLD site's last push, so the NEW site would come up
251
+ // missing exactly the content that did not change." It was defeated twice over:
252
+ //
253
+ // · it ran AFTER `readSyncCache`, so the emit still diffed against the old
254
+ // site's hashes even though the file on disk had just been emptied;
255
+ // · it sat inside `if (mediaRefs.length)`, so a site with no local images never
256
+ // reached it at all.
257
+ //
258
+ // Measured 2026-08-19 against a live uniwebd: clearing `$uuid` and pushing created
259
+ // the new site and pulled back **0 pages, 0 sections**. Successful exit, empty site,
260
+ // nothing to indicate it — the failure the guard was written to prevent.
261
+ //
262
+ // Still skipped for an offline emit: `-o` / `--dry-run` must not mutate project state.
263
+ if (!output && !dryRun) {
264
+ const dropped = clearRemoteSyncStateIfUnbound(siteDir)
265
+ if (dropped.length) {
266
+ note(
267
+ `Cleared stale sync state from a previous site (${dropped.join(', ')}).`
268
+ )
269
+ }
270
+ }
244
271
  const priorHashes = readSyncCache(siteDir)
245
272
  // Per-item identity, without which the backend reads every record as new and
246
273
  // recreates every page and section row.
@@ -324,13 +351,23 @@ export async function push(args = [], deps = {}) {
324
351
  // The site has to exist before its bytes do — an upload with no owning
325
352
  // entity is charged and cannot be freed, because freeing means deleting the
326
353
  // owner. A no-op once `$uuid` is set, so only a never-synced site pays.
327
- const dropped = clearRemoteSyncStateIfUnbound(siteDir)
328
- if (dropped.length) {
329
- note(
330
- `Cleared stale sync state from a previous site (${dropped.join(', ')}).`
331
- )
332
- }
333
- const site = await ensureSiteExists({ client, siteDir, asOrg, note })
354
+ // The PINNED ref, not site.yml's. The create is a THIRD writer of this
355
+ // value — the emit below stamps it via `injectInfo`, publish passes it here,
356
+ // and push did neither until 2026-08-19: it sent the authored alias (`src`),
357
+ // which names a foundation no deployment can resolve. A site created that way
358
+ // keeps the bad ref, and the backend's create guard now refuses it outright
359
+ // (channel backend-framework-787e, their measurement).
360
+ //
361
+ // ⭐ Same shape as the send-only-changed defect fixed this morning, and missed
362
+ // for the same reason: the rule was applied at the writers under discussion and
363
+ // a third caller of the same value was never enumerated.
364
+ const site = await ensureSiteExists({
365
+ client,
366
+ siteDir,
367
+ asOrg,
368
+ note,
369
+ ...(fnd.ref ? { foundation: fnd.ref } : {})
370
+ })
334
371
  if (!site.uuid) {
335
372
  error(`Could not create the site on the backend: ${site.reason}`)
336
373
  note('Nothing was uploaded and nothing was charged.')