druxt 0.24.1-dev.20260920213131 → 0.24.1-dev.20260921024946
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/dist/components/DruxtModule.vue +98 -1
- package/dist/druxt.esm.js +1 -1
- package/dist/druxt.ssr.js +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,66 @@ import Vue from 'vue'
|
|
|
5
5
|
|
|
6
6
|
import DruxtWrapper from './DruxtWrapper.vue'
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Whether JSON holds a value well enough to compare two of them.
|
|
10
|
+
*
|
|
11
|
+
* A function or a symbol writes as `undefined`, a Map or a Set as `{}`, and
|
|
12
|
+
* NaN as `null`, so two different values can write the same text. Anything
|
|
13
|
+
* JSON does not hold exactly is compared by identity instead.
|
|
14
|
+
*
|
|
15
|
+
* @private
|
|
16
|
+
*
|
|
17
|
+
* @param {*} value - The value to check.
|
|
18
|
+
* @param {WeakSet} [seen] - Objects already visited, so a cycle ends the walk.
|
|
19
|
+
*
|
|
20
|
+
* @returns {boolean} Whether JSON.stringify represents the value exactly.
|
|
21
|
+
*/
|
|
22
|
+
const isComparable = (value, seen = new WeakSet()) => {
|
|
23
|
+
if (value === null) return true
|
|
24
|
+
|
|
25
|
+
const type = typeof value
|
|
26
|
+
if (type === 'string' || type === 'boolean') return true
|
|
27
|
+
if (type === 'number') return Number.isFinite(value)
|
|
28
|
+
if (type !== 'object') return false
|
|
29
|
+
|
|
30
|
+
if (seen.has(value)) return false
|
|
31
|
+
seen.add(value)
|
|
32
|
+
|
|
33
|
+
if (Array.isArray(value)) return value.every((item) => isComparable(item, seen))
|
|
34
|
+
|
|
35
|
+
// A Map, a Set, a Date or any class instance writes as something other than itself.
|
|
36
|
+
const prototype = Object.getPrototypeOf(value)
|
|
37
|
+
if (prototype !== Object.prototype && prototype !== null) return false
|
|
38
|
+
|
|
39
|
+
return Object.values(value).every((item) => isComparable(item, seen))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Whether rebuilt propsData differs from what the wrapper already has.
|
|
44
|
+
*
|
|
45
|
+
* Values that cannot be compared count as changed, so a rebuild is skipped
|
|
46
|
+
* only when the two are known to match.
|
|
47
|
+
*
|
|
48
|
+
* @private
|
|
49
|
+
*
|
|
50
|
+
* @param {object} current - The propsData the wrapper holds.
|
|
51
|
+
* @param {object} next - The propsData the module's callback just produced.
|
|
52
|
+
*
|
|
53
|
+
* @returns {boolean} Whether the wrapper needs the new propsData.
|
|
54
|
+
*/
|
|
55
|
+
const hasChanged = (current = {}, next = {}) => {
|
|
56
|
+
const keys = [...new Set([...Object.keys(current), ...Object.keys(next)])]
|
|
57
|
+
return keys.some((key) => {
|
|
58
|
+
if (current[key] === next[key]) return false
|
|
59
|
+
if (!isComparable(current[key]) || !isComparable(next[key])) return true
|
|
60
|
+
try {
|
|
61
|
+
return JSON.stringify(current[key]) !== JSON.stringify(next[key])
|
|
62
|
+
} catch (err) {
|
|
63
|
+
return true
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
8
68
|
/**
|
|
9
69
|
* The DruxtModule component renders a Druxt module; import and extend the
|
|
10
70
|
* component to build your own module.
|
|
@@ -168,6 +228,9 @@ export default {
|
|
|
168
228
|
|
|
169
229
|
// Get wrapper data.
|
|
170
230
|
const wrapperData = await this.getWrapperData(component.is)
|
|
231
|
+
// On the instance rather than in data(), so it is not copied into the
|
|
232
|
+
// server rendered payload once per module.
|
|
233
|
+
this.wrapperProps = wrapperData.props || {}
|
|
171
234
|
|
|
172
235
|
// Build module settings.
|
|
173
236
|
component.settings = wrapperData.druxt || {}
|
|
@@ -206,7 +269,20 @@ export default {
|
|
|
206
269
|
* @param {object} vm.$route - The current route.
|
|
207
270
|
* @return {string} The current language code.
|
|
208
271
|
*/
|
|
209
|
-
lang: ({ langcode, $route }) => langcode || ($route.meta || {}).langcode
|
|
272
|
+
lang: ({ langcode, $route }) => langcode || ($route.meta || {}).langcode,
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* The module's own propsData, tracked so a prop change rebuilds it.
|
|
276
|
+
*
|
|
277
|
+
* Reading it here registers whatever the module's `propsData()` callback
|
|
278
|
+
* reads, so each module declares its own dependencies by using them.
|
|
279
|
+
*
|
|
280
|
+
* @type {object}
|
|
281
|
+
*/
|
|
282
|
+
modulePropsData() {
|
|
283
|
+
if (!(this.$options.druxt || {}).propsData) return null
|
|
284
|
+
return { langcode: this.lang, ...this.$options.druxt.propsData.call(this, this) }
|
|
285
|
+
}
|
|
210
286
|
},
|
|
211
287
|
|
|
212
288
|
watch: {
|
|
@@ -216,6 +292,27 @@ export default {
|
|
|
216
292
|
}
|
|
217
293
|
},
|
|
218
294
|
|
|
295
|
+
// Nuxt 2 doesn't re-run fetch() when a component's own props change, so a
|
|
296
|
+
// reused instance would keep the propsData its first fetch() built. Rebuild
|
|
297
|
+
// it in place instead of refetching: the data is unchanged, the props are not.
|
|
298
|
+
modulePropsData: {
|
|
299
|
+
deep: true,
|
|
300
|
+
handler(to) {
|
|
301
|
+
// An errored module renders DruxtDebug with its own props; leave them.
|
|
302
|
+
if (!to || this.component.is === 'DruxtDebug' || !Object.keys(this.component.propsData || {}).length) {
|
|
303
|
+
return
|
|
304
|
+
}
|
|
305
|
+
if (!hasChanged(this.component.propsData, to)) {
|
|
306
|
+
return
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// After hydration this instance never ran fetch(), so read the resolved
|
|
310
|
+
// wrapper's props instead of the ones that fetch() put on the instance.
|
|
311
|
+
const resolved = ((this.$options.components || {})[this.component.is] || {}).options || {}
|
|
312
|
+
this.component = { ...this.component, ...this.getModulePropsData(this.wrapperProps || resolved.props || {}) }
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
|
|
219
316
|
model() {
|
|
220
317
|
if (this.component.props && this.component.props.value !== this.model) {
|
|
221
318
|
this.component.props.value = this.model
|
package/dist/druxt.esm.js
CHANGED
|
@@ -263,7 +263,7 @@ class DruxtClient {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
var name = "druxt";
|
|
266
|
-
var version = "0.24.1-dev.
|
|
266
|
+
var version = "0.24.1-dev.20260921024946";
|
|
267
267
|
var description = "The Fully Decoupled Drupal Framework for Nuxt.js.";
|
|
268
268
|
var keywords = [
|
|
269
269
|
"cms",
|
package/dist/druxt.ssr.js
CHANGED
|
@@ -276,7 +276,7 @@ class DruxtClient {
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
var name = "druxt";
|
|
279
|
-
var version = "0.24.1-dev.
|
|
279
|
+
var version = "0.24.1-dev.20260921024946";
|
|
280
280
|
var description = "The Fully Decoupled Drupal Framework for Nuxt.js.";
|
|
281
281
|
var keywords = [
|
|
282
282
|
"cms",
|