@radishland/runtime 0.4.0 → 0.4.2

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/client/index.d.ts CHANGED
@@ -62,7 +62,7 @@ declare class HandlerRegistry extends HTMLElement implements AutonomousCustomEle
62
62
  */
63
63
  lookup(identifier: string): any;
64
64
  hydrateElement(element: Element): void;
65
- walkDOM(node: Node): void;
65
+ hydrate(node?: Node): void;
66
66
  connectedCallback(): void;
67
67
  disconnectedCallback(): void;
68
68
  }
@@ -104,4 +104,4 @@ declare const effect: (cb: EffectCallback, options?: EffectOptions) => Destructo
104
104
  */
105
105
  declare const reactive: <T>(thing: T) => T;
106
106
 
107
- export { HandlerRegistry, computed, effect, isState, reactive, signal };
107
+ export { type AutonomousCustomElement, HandlerRegistry, computed, effect, isState, reactive, signal };
package/client/index.js CHANGED
@@ -128,7 +128,7 @@ var object = (init) => {
128
128
  };
129
129
 
130
130
  // src/handler-registry.ts
131
- var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
131
+ var HandlerRegistry = class extends HTMLElement {
132
132
  #cleanup = [];
133
133
  /**
134
134
  * References the handler's `AbortController`.
@@ -165,6 +165,7 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
165
165
  target.setAttribute(attribute, `${ref}`);
166
166
  }
167
167
  });
168
+ target.removeAttribute("attr:" + attribute);
168
169
  e.stopPropagation();
169
170
  }
170
171
  }
@@ -177,6 +178,7 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
177
178
  this.effect(() => {
178
179
  target.toggleAttribute(attribute, ref.valueOf());
179
180
  });
181
+ target.removeAttribute("bool:" + attribute);
180
182
  e.stopPropagation();
181
183
  }
182
184
  }
@@ -184,8 +186,9 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
184
186
  #handleOn(e) {
185
187
  if (e instanceof CustomEvent) {
186
188
  const { identifier, type: type2, target } = e.detail;
187
- if (identifier in this && typeof this.lookup(identifier) === "function") {
189
+ if (identifier in this && target instanceof HTMLElement && typeof this.lookup(identifier) === "function") {
188
190
  target.addEventListener(type2, this.lookup(identifier).bind(this));
191
+ target.removeAttribute("on:" + type2);
189
192
  e.stopPropagation();
190
193
  }
191
194
  }
@@ -193,21 +196,19 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
193
196
  #handleClass(e) {
194
197
  if (e instanceof CustomEvent) {
195
198
  const { identifier, target } = e.detail;
196
- if (identifier in this) {
199
+ if (identifier in this && target instanceof HTMLElement) {
197
200
  this.effect(() => {
198
201
  const classList = this.lookup(identifier)?.valueOf();
199
- if (classList && typeof classList === "object") {
202
+ if (target instanceof HTMLElement && classList && typeof classList === "object") {
200
203
  for (const [k, v] of Object.entries(classList)) {
201
204
  const force = !!v?.valueOf();
202
205
  for (const className of k.split(" ")) {
203
- target.classList.toggle(
204
- className,
205
- force
206
- );
206
+ target.classList.toggle(className, force);
207
207
  }
208
208
  }
209
209
  }
210
210
  });
211
+ target.removeAttribute("classList");
211
212
  e.stopPropagation();
212
213
  }
213
214
  }
@@ -215,11 +216,12 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
215
216
  #handleUse(e) {
216
217
  if (e instanceof CustomEvent) {
217
218
  const { identifier, target } = e.detail;
218
- if (identifier in this && typeof this.lookup(identifier) === "function") {
219
+ if (identifier in this && typeof this.lookup(identifier) === "function" && target instanceof HTMLElement) {
219
220
  const cleanup = this.lookup(identifier).bind(this)(target);
220
221
  if (typeof cleanup === "function") {
221
222
  this.#cleanup.push(cleanup);
222
223
  }
224
+ target.removeAttribute("use:" + identifier);
223
225
  e.stopPropagation();
224
226
  }
225
227
  }
@@ -227,11 +229,16 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
227
229
  #handleProp(e) {
228
230
  if (e instanceof CustomEvent) {
229
231
  const { identifier, property, target } = e.detail;
230
- if (identifier in this && property in target) {
232
+ if (identifier in this && property in target && target instanceof HTMLElement) {
231
233
  const ref = this.lookup(identifier);
232
234
  this.effect(() => {
233
- target[property] = ref.valueOf();
235
+ if (isState(target[property])) {
236
+ target[property].value = ref.valueOf();
237
+ } else {
238
+ target[property] = ref.valueOf();
239
+ }
234
240
  });
241
+ target.removeAttribute("prop:" + property);
235
242
  e.stopPropagation();
236
243
  }
237
244
  }
@@ -244,6 +251,7 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
244
251
  this.effect(() => {
245
252
  target.textContent = `${ref}`;
246
253
  });
254
+ target.removeAttribute("text");
247
255
  e.stopPropagation();
248
256
  }
249
257
  }
@@ -256,6 +264,7 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
256
264
  this.effect(() => {
257
265
  target.innerHTML = `${ref}`;
258
266
  });
267
+ target.removeAttribute("html");
259
268
  e.stopPropagation();
260
269
  }
261
270
  }
@@ -274,6 +283,7 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
274
283
  target[property] = state.value;
275
284
  });
276
285
  }
286
+ target.removeAttribute("bind:" + property);
277
287
  e.stopPropagation();
278
288
  }
279
289
  }
@@ -417,23 +427,20 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
417
427
  element.dispatchEvent(useRequest);
418
428
  }
419
429
  }
420
- walkDOM(node) {
430
+ // TODO: tree aware hydration that filters out HandlerRegistries and parallelize
431
+ hydrate(node = this) {
421
432
  if (node instanceof Element) {
422
433
  this.hydrateElement(node);
423
434
  if (node.shadowRoot && node.shadowRoot.mode === "open") {
424
435
  console.log("entering shadow root");
425
- this.walkDOM(node.shadowRoot);
436
+ this.hydrate(node.shadowRoot);
426
437
  console.log("exiting shadow root");
427
438
  }
428
- let child = node.firstElementChild;
429
- while (child) {
430
- if (!(child instanceof _HandlerRegistry)) {
431
- this.walkDOM(child);
432
- } else {
433
- console.log(`skipping handler registry ${child.tagName}`);
434
- }
435
- child = child.nextElementSibling;
436
- }
439
+ }
440
+ let child = node.firstChild;
441
+ while (child) {
442
+ this.hydrate(child);
443
+ child = child.nextSibling;
437
444
  }
438
445
  }
439
446
  connectedCallback() {
@@ -448,7 +455,6 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
448
455
  this.addEventListener("rad::prop", this.#handleProp, { signal: signal2 });
449
456
  this.addEventListener("rad::text", this.#handleText, { signal: signal2 });
450
457
  this.addEventListener("rad::use", this.#handleUse, { signal: signal2 });
451
- this.walkDOM(this);
452
458
  }
453
459
  disconnectedCallback() {
454
460
  this.abortController.abort();
@@ -460,5 +466,21 @@ var HandlerRegistry = class _HandlerRegistry extends HTMLElement {
460
466
  if (window && !customElements.get("handler-registry")) {
461
467
  customElements?.define("handler-registry", HandlerRegistry);
462
468
  }
469
+ customElements?.whenDefined("handler-registry").then(() => {
470
+ const tw = document.createTreeWalker(
471
+ document,
472
+ NodeFilter.SHOW_ELEMENT,
473
+ (node) => {
474
+ return node instanceof HandlerRegistry ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
475
+ }
476
+ );
477
+ let current = tw.firstChild();
478
+ while (current) {
479
+ if (current instanceof HandlerRegistry) {
480
+ current.hydrate();
481
+ }
482
+ current = tw.nextNode();
483
+ }
484
+ });
463
485
 
464
486
  export { HandlerRegistry, computed, effect, isState, reactive, signal };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radishland/runtime",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "type": "module",
5
5
  "description": "The Radish runtime",
6
6
  "author": "Frédéric Crozatier",