@uniweb/build 1.8.4 → 1.8.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.
Files changed (2) hide show
  1. package/package.json +6 -6
  2. package/src/i18n/sync.js +14 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/build",
3
- "version": "1.8.4",
3
+ "version": "1.8.5",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -57,14 +57,14 @@
57
57
  "sharp": "^0.35.3",
58
58
  "yaml": "^2.5.0",
59
59
  "@uniweb/content-reader": "~1.5.6",
60
- "@uniweb/semantic-parser": "~1.13.0",
61
- "@uniweb/schemas": "~1.6.5",
62
60
  "@uniweb/content-writer": "~1.3.0",
61
+ "@uniweb/schemas": "~1.6.5",
62
+ "@uniweb/semantic-parser": "~1.13.0",
63
63
  "@uniweb/projections": "~1.1.7",
64
64
  "@uniweb/theming": "~1.2.1"
65
65
  },
66
66
  "optionalDependencies": {
67
- "@uniweb/runtime": "~1.1.18"
67
+ "@uniweb/runtime": "~1.1.19"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
@@ -73,8 +73,8 @@
73
73
  "@tailwindcss/vite": "^4.0.0",
74
74
  "@vitejs/plugin-react": "^4.0.0 || ^5.0.0",
75
75
  "vite-plugin-svgr": "^4.0.0",
76
- "@uniweb/runtime": "~1.1.18",
77
- "@uniweb/core": "~1.4.3"
76
+ "@uniweb/core": "~1.4.4",
77
+ "@uniweb/runtime": "~1.1.19"
78
78
  },
79
79
  "peerDependenciesMeta": {
80
80
  "vite": {
package/src/i18n/sync.js CHANGED
@@ -26,6 +26,8 @@ export function syncManifests(previous, current) {
26
26
 
27
27
  const previousHashes = new Set(Object.keys(previousUnits))
28
28
  const currentHashes = new Set(Object.keys(currentUnits))
29
+ // Previous units a new one replaced, so that no two new units claim the same one.
30
+ const replaced = new Set()
29
31
 
30
32
  // Check each current unit
31
33
  for (const hash of currentHashes) {
@@ -66,10 +68,11 @@ export function syncManifests(previous, current) {
66
68
  } else {
67
69
  // New hash - could be new content or changed content
68
70
  // Check if any previous context now has this new hash
69
- const matchingContext = findMatchingContext(currentUnit.contexts, previousUnits)
71
+ const matchingContext = findMatchingContext(currentUnit.contexts, previousUnits, currentHashes, replaced)
70
72
 
71
73
  if (matchingContext) {
72
74
  // Same context, different hash = content changed
75
+ replaced.add(matchingContext.hash)
73
76
  report.changed.push({
74
77
  hash,
75
78
  previousHash: matchingContext.hash,
@@ -94,8 +97,7 @@ export function syncManifests(previous, current) {
94
97
  if (!currentHashes.has(hash)) {
95
98
  const prevUnit = previousUnits[hash]
96
99
  // Only mark as removed if not detected as changed above
97
- const wasChanged = report.changed.some(c => c.previousHash === hash)
98
- if (!wasChanged) {
100
+ if (!replaced.has(hash)) {
99
101
  report.removed.push({
100
102
  hash,
101
103
  source: prevUnit.source,
@@ -128,16 +130,22 @@ function contextsEqual(contexts1, contexts2) {
128
130
  }
129
131
 
130
132
  /**
131
- * Find if any context in the current unit matches a context in previous units
132
- * Returns the previous unit info if found
133
+ * The previous unit a new one replaced: one in a context of the new unit that is gone from the
134
+ * current manifest and not yet replaced. Returns its info, or null.
135
+ *
136
+ * ⛔ Until 2026-10-24 it was the first previous unit in such a context, gone or not. Removing a
137
+ * hero's second button then reported the hero's unchanged title as changed into the remaining
138
+ * button, and the button paragraph it did replace as removed (measured that day on a site's
139
+ * `uniweb i18n extract`).
133
140
  */
134
- function findMatchingContext(currentContexts, previousUnits) {
141
+ function findMatchingContext(currentContexts, previousUnits, currentHashes, replaced) {
135
142
  // One key shape for both lanes: a page/section pair, or a record's identity.
136
143
  const key = (c) => (c.record ? `record:${c.record}` : `${c.page}:${c.section}`)
137
144
  for (const context of currentContexts) {
138
145
  const contextKey = key(context)
139
146
 
140
147
  for (const [hash, unit] of Object.entries(previousUnits)) {
148
+ if (currentHashes.has(hash) || replaced.has(hash)) continue
141
149
  const unitContexts = unit.contexts || []
142
150
  const hasContext = unitContexts.some((c) => key(c) === contextKey)
143
151
  if (hasContext) {