reactive_component 0.9.0 → 0.9.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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b5392838b8ed189cab22600b11b26eaa10215f601dd18294a4070febd9d88fbc
|
|
4
|
+
data.tar.gz: ed5fc1b4fb9c8e41ca0e717481323655b04b31bd4c94eb7ae011d4e05452b881
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bc1903d993c6504bccd2235175c131287589437461991084dfd93f6124f806de5589a669581bc9e3a34feac4fd5ad5f251131cabe498e5ad4218ade2db225574
|
|
7
|
+
data.tar.gz: 84a9b85096b7838863837ed0fac03be89394ceef37a24484a1425a9643f707dc120204a8c8b9bf90f2f5645e5d18ce87f04e0d4603a6a6c218f31f16b85d1bc1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.1] - 2026-09-17
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- The renderer logs every render and update only when `ReactiveComponent.debug`
|
|
7
|
+
is on, which it reads from the `data-reactive-debug` attribute already on the
|
|
8
|
+
wrapper. It used to log everywhere, production included, unless a
|
|
9
|
+
`devToolbar:debug` key in `localStorage` was set to the string `"false"`.
|
|
10
|
+
- A client-state change on a notify component that has no data yet asks the
|
|
11
|
+
server to render it instead of doing nothing, and an update request carries
|
|
12
|
+
the state the component is in now rather than the one the page was built
|
|
13
|
+
with.
|
|
14
|
+
- A notify wrapper with client state no longer embeds its initial data payload.
|
|
15
|
+
It asks the server to render it, so the attribute was the page a second time,
|
|
16
|
+
carrying every branch of every extracted expression. A push wrapper keeps it:
|
|
17
|
+
it renders from that payload until the first broadcast arrives.
|
|
18
|
+
|
|
3
19
|
## [0.9.0] - 2026-09-17
|
|
4
20
|
|
|
5
21
|
### Added
|
|
@@ -3,11 +3,6 @@ import { createConsumer } from "@rails/actioncable"
|
|
|
3
3
|
import { compileTemplate, decompress, morphElement, buildActionBody, routeMessage, duplicateIds, strictData } from "reactive_component/lib/reactive_renderer_utils"
|
|
4
4
|
|
|
5
5
|
const consumer = createConsumer()
|
|
6
|
-
const log = (...args) => {
|
|
7
|
-
if (localStorage.getItem("devToolbar:debug") !== "false") {
|
|
8
|
-
console.log("[reactive-renderer]", ...args)
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
6
|
|
|
12
7
|
function findSubscription(streamValue) {
|
|
13
8
|
const identifier = JSON.stringify({ channel: "ReactiveComponent::Channel", signed_stream_name: streamValue })
|
|
@@ -113,6 +108,14 @@ export default class extends Controller {
|
|
|
113
108
|
this.element.removeAttribute("data-reactive-renderer-connected")
|
|
114
109
|
}
|
|
115
110
|
|
|
111
|
+
// ReactiveComponent.debug marks the wrapper, so the gem is quiet unless the
|
|
112
|
+
// app turns debugging on server-side.
|
|
113
|
+
log(...args) {
|
|
114
|
+
if (this.element.hasAttribute("data-reactive-debug")) {
|
|
115
|
+
console.log("[reactive-renderer]", ...args)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
116
119
|
resolveTemplate() {
|
|
117
120
|
if (this.hasTemplateValue) return this.templateValue
|
|
118
121
|
|
|
@@ -129,18 +132,18 @@ export default class extends Controller {
|
|
|
129
132
|
|
|
130
133
|
switch (route.type) {
|
|
131
134
|
case "render":
|
|
132
|
-
log("render", this.element.id, route.data)
|
|
135
|
+
this.log("render", this.element.id, route.data)
|
|
133
136
|
this.lastServerData = route.data
|
|
134
137
|
if (this.renderFn) this.render({ ...route.data, ...this.clientState })
|
|
135
138
|
break
|
|
136
139
|
|
|
137
140
|
case "request_update":
|
|
138
|
-
log("update", this.element.id, { action: message.action, strategy: "notify" })
|
|
141
|
+
this.log("update", this.element.id, { action: message.action, strategy: "notify" })
|
|
139
142
|
this.requestUpdate()
|
|
140
143
|
break
|
|
141
144
|
|
|
142
145
|
case "update":
|
|
143
|
-
log("update", this.element.id, route.data)
|
|
146
|
+
this.log("update", this.element.id, route.data)
|
|
144
147
|
this.lastServerData = route.data
|
|
145
148
|
if (this.renderFn) this.render({ ...route.data, ...this.clientState })
|
|
146
149
|
this.element.dispatchEvent(new CustomEvent("reactive-renderer:updated", {
|
|
@@ -168,7 +171,9 @@ export default class extends Controller {
|
|
|
168
171
|
component: this.componentValue,
|
|
169
172
|
sgid: this.sgidValue,
|
|
170
173
|
dom_id: this.element.id,
|
|
171
|
-
params
|
|
174
|
+
// The channel reads client state off params, so the server renders the
|
|
175
|
+
// state the component is in now, not the one the page was built with.
|
|
176
|
+
params: { ...this.paramsValue, ...this.clientState }
|
|
172
177
|
})
|
|
173
178
|
}, 50)
|
|
174
179
|
}
|
|
@@ -262,16 +267,23 @@ export default class extends Controller {
|
|
|
262
267
|
changed = true
|
|
263
268
|
}
|
|
264
269
|
}
|
|
265
|
-
if (changed
|
|
266
|
-
requestAnimationFrame(() => ctrl.render({ ...ctrl.lastServerData, ...ctrl.clientState }))
|
|
267
|
-
}
|
|
270
|
+
if (changed) ctrl.rerender()
|
|
268
271
|
})
|
|
269
272
|
}
|
|
270
273
|
}
|
|
271
274
|
|
|
272
275
|
Object.assign(this.clientState, updates)
|
|
276
|
+
this.rerender()
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// A push component holds the data it needs. A notify one may not have any
|
|
280
|
+
// yet, its payload arrives on request, so a state change asks for it rather
|
|
281
|
+
// than leaving the click with nothing to show.
|
|
282
|
+
rerender() {
|
|
273
283
|
if (this.lastServerData && this.renderFn) {
|
|
274
284
|
requestAnimationFrame(() => this.render({ ...this.lastServerData, ...this.clientState }))
|
|
285
|
+
} else if (this.strategyValue === "notify") {
|
|
286
|
+
this.requestUpdate()
|
|
275
287
|
}
|
|
276
288
|
}
|
|
277
289
|
|
|
@@ -45,8 +45,15 @@ module ReactiveComponent
|
|
|
45
45
|
|
|
46
46
|
if client_state
|
|
47
47
|
attrs << %(data-reactive-renderer-state-value="#{ERB::Util.html_escape(client_state.to_json)}")
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
|
|
49
|
+
# A push wrapper renders from this payload until the first broadcast
|
|
50
|
+
# arrives. A notify one asks the server for its data instead, so the
|
|
51
|
+
# attribute would be the page a second time, both branches of every
|
|
52
|
+
# extracted expression included.
|
|
53
|
+
unless strategy.to_s == 'notify'
|
|
54
|
+
initial_data = component_class.build_data(record, **client_state.symbolize_keys)
|
|
55
|
+
attrs << %(data-reactive-renderer-data-value="#{ERB::Util.html_escape(initial_data.to_json)}")
|
|
56
|
+
end
|
|
50
57
|
end
|
|
51
58
|
|
|
52
59
|
attrs << %(data-reactive-renderer-strategy-value="#{strategy}") if strategy
|