@tempots/client 0.0.1 → 0.0.3

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 (4) hide show
  1. package/index.cjs +1 -1
  2. package/index.d.ts +11 -3
  3. package/index.js +121 -89
  4. package/package.json +3 -3
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("@tempots/core"),a=require("@tempots/dom");function y(r,e,t={}){const{providers:n={},removeMarkers:i=!0}=t,s=N(e),o=new p.DisposalScope,c=new d(e.ownerDocument,e,void 0,n,s,0),h=p.withScope(o,()=>r.render(c));return i&&g(e),(l=!1)=>{o.dispose(),h(l)}}function N(r){const e=new Map;return r.querySelectorAll(`[${a.HYDRATION_ID_ATTR}]`).forEach(n=>{const i=n.getAttribute(a.HYDRATION_ID_ATTR);i&&e.set(i,n)}),e}function g(r){r.querySelectorAll(`[${a.HYDRATION_ID_ATTR}]`).forEach(t=>{t.removeAttribute(a.HYDRATION_ID_ATTR),t.removeAttribute("data-tts-node")})}class d{constructor(e,t,n,i,s,o){this.document=e,this.element=t,this.reference=n,this.providers=i,this.hydrationMap=s,this.childIndex=o}makeChildElement=(e,t)=>{const n=this.element.children;for(let s=this.childIndex;s<n.length;s++){const o=n[s];if(o.tagName.toLowerCase()===e.toLowerCase())return this.childIndex=s+1,new d(this.document,o,void 0,this.providers,this.hydrationMap,0)}console.warn(`Hydration mismatch: could not find element <${e}> in container`);const i=t!==void 0?this.document.createElementNS(t,e):this.document.createElement(e);return this.appendOrInsert(i),new d(this.document,i,void 0,this.providers,this.hydrationMap,0)};makeChildText=e=>{const t=this.element.childNodes;for(let i=this.childIndex;i<t.length;i++){const s=t[i];if(s.nodeType===Node.TEXT_NODE)return this.childIndex=i+1,s.textContent!==e&&(s.textContent=e),new d(this.document,this.element,s,this.providers,this.hydrationMap,this.childIndex)}const n=this.document.createTextNode(e);return this.appendOrInsert(n),new d(this.document,this.element,n,this.providers,this.hydrationMap,this.childIndex)};setText=e=>{this.reference&&(this.reference.nodeValue=e)};getText=()=>this.reference?.nodeValue??this.element.textContent??"";makeRef=()=>{const e=this.element.childNodes;for(let n=this.childIndex;n<e.length;n++){const i=e[n];if(i.nodeType===Node.TEXT_NODE&&(i.textContent===""||i.textContent===null))return this.childIndex=n+1,new d(this.document,this.element,i,this.providers,this.hydrationMap,this.childIndex)}const t=this.document.createTextNode("");return this.appendOrInsert(t),new d(this.document,this.element,t,this.providers,this.hydrationMap,this.childIndex)};makePortal=e=>{const t=typeof e=="string"?this.document.querySelector(e):e;if(t==null)throw new Error(`Cannot find element by selector for portal: ${e}`);return new d(this.document,t,void 0,this.providers,this.hydrationMap,0)};appendOrInsert=e=>{this.reference===void 0?this.element.appendChild(e):this.element.insertBefore(e,this.reference)};setProvider=(e,t,n)=>new d(this.document,this.element,this.reference,{...this.providers,[e]:[t,n]},this.hydrationMap,this.childIndex);getProvider=e=>{if(this.providers[e]===void 0)throw new Error(`Provider not found: ${String(e)}`);const[t,n]=this.providers[e];return{value:t,onUse:n}};clear=e=>{e&&(this.reference!==void 0?this.reference.parentNode?.removeChild(this.reference):this.element.parentNode?.removeChild(this.element))};addClasses=e=>{this.element.classList.add(...e)};removeClasses=e=>{this.element.classList.remove(...e)};getClasses=()=>Array.from(this.element.classList);on=(e,t,n)=>{const i=s=>t(s,this);return this.element.addEventListener(e,i,n),s=>{s&&this.element.removeEventListener(e,i,n)}};isBrowserDOM=()=>!1;isBrowser=()=>!0;isHeadlessDOM=()=>!1;isHeadless=()=>!1;setStyle=(e,t)=>{this.element.style[e]=t};getStyle=e=>this.element.style[e];makeAccessors=e=>{const t=this.element;return{get:()=>t[e],set:n=>{t[e]=n}}}}const u="data-tempo-island",I="data-tempo-hydrate",A="data-tempo-options";function S(r,e,t,n={}){r.innerHTML="";const i=new a.BrowserContext(r.ownerDocument,r,void 0,n.providers??{}),s=new p.DisposalScope,o=p.withScope(s,()=>e(t).render(i));return(c=!1)=>{s.dispose(),o(c)}}function D(r,e,t){if(e==="immediate")return t(),()=>{};if(e==="idle")if("requestIdleCallback"in window){const n=requestIdleCallback(t);return()=>cancelIdleCallback(n)}else{const n=setTimeout(t,1);return()=>clearTimeout(n)}if(e==="visible"){const n=new IntersectionObserver(i=>{for(const s of i)if(s.isIntersecting){n.disconnect(),t();break}},{rootMargin:"50px"});return n.observe(r),()=>n.disconnect()}if(typeof e=="object"&&"media"in e){const n=window.matchMedia(e.media);if(n.matches)return t(),()=>{};const i=s=>{s.matches&&(n.removeEventListener("change",i),t())};return n.addEventListener("change",i),()=>n.removeEventListener("change",i)}return t(),()=>{}}function O(r){return!r||r==="immediate"||r==="load"?"immediate":r==="idle"?"idle":r==="visible"?"visible":r.startsWith("media:")?{media:r.slice(6).trim()}:"immediate"}function v(r,e={}){const t=[];return document.querySelectorAll(`[${u}]`).forEach(i=>{const s=i,o=s.getAttribute(u);if(!o){console.warn("[Tempo Islands] Element missing island name:",s);return}const c=r[o];if(!c){console.warn(`[Tempo Islands] Component "${o}" not found in registry`);return}const h=s.getAttribute(A);let l={};if(h)try{l=JSON.parse(h)}catch(f){console.warn(`[Tempo Islands] Failed to parse options for "${o}":`,f)}const m=s.getAttribute(I),T=O(m),w=D(s,T,()=>{const f=S(s,c,l,e);t.push(f),s.removeAttribute(u),s.removeAttribute(I),s.removeAttribute(A)});t.push(w)}),()=>{t.forEach(i=>i())}}function R(r,e={},t="visible"){const n=typeof t=="object"?`media:${t.media}`:t;return[{name:u,value:r},{name:A,value:JSON.stringify(e)},{name:I,value:n}]}function b(r){const{app:e,islands:t,container:n="#app",providers:i={},debug:s=!1}=r,o=s?m=>console.log(`[Tempo] ${m}`):()=>{},c=typeof n=="string"?document.querySelector(n):n;if(!c)return console.error(`[Tempo] Could not find container: ${typeof n=="string"?n:"(element)"}`),()=>{};const h=c.querySelector(`[${u}]`)!==null;let l;if(h)o("SSR mode: Initializing islands..."),l=v(t,{providers:i}),o("Islands initialized! Static content stays static.");else if(e){o("Client-only mode: Rendering app...");const m=new a.BrowserContext(document,c,void 0,i),T=new p.DisposalScope,w=p.withScope(T,()=>e().render(m)),f=v(t,{providers:i});l=()=>{f(),T.dispose(),w(!0)},o("App rendered and islands initialized!")}else o("No SSR content detected, initializing islands only..."),l=v(t,{providers:i});return l}Object.defineProperty(exports,"HYDRATION_ID_ATTR",{enumerable:!0,get:()=>a.HYDRATION_ID_ATTR});exports.HydrationContext=d;exports.ISLAND_ATTR=u;exports.ISLAND_HYDRATE_ATTR=I;exports.ISLAND_OPTIONS_ATTR=A;exports.hydrate=y;exports.hydrateIsland=S;exports.initIslands=v;exports.islandMarker=R;exports.startClient=b;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("@tempots/core"),h=require("@tempots/dom");function g(o,e,t={}){const{providers:n={},removeMarkers:i=!0}=t,r=N(e),s=new f.DisposalScope,d=new a(e.ownerDocument,e,void 0,n,r,0),c=f.withScope(s,()=>o.render(d));return i&&y(e),(l=!1)=>{s.dispose(),c(l)}}function N(o){const e=new Map;return o.querySelectorAll(`[${h.HYDRATION_ID_ATTR}]`).forEach(n=>{const i=n.getAttribute(h.HYDRATION_ID_ATTR);i&&e.set(i,n)}),e}function y(o){o.querySelectorAll(`[${h.HYDRATION_ID_ATTR}]`).forEach(t=>{t.removeAttribute(h.HYDRATION_ID_ATTR),t.removeAttribute("data-tts-node")})}class a{constructor(e,t,n,i,r,s){this.document=e,this.element=t,this.reference=n,this.providers=i,this.hydrationMap=r,this.childIndex=s}makeChildElement=(e,t)=>{const n=this.element.children;for(let r=this.childIndex;r<n.length;r++){const s=n[r];if(s.tagName.toLowerCase()===e.toLowerCase())return this.childIndex=r+1,new a(this.document,s,void 0,this.providers,this.hydrationMap,0)}console.warn(`Hydration mismatch: could not find element <${e}> in container`);const i=t!==void 0?this.document.createElementNS(t,e):this.document.createElement(e);return this.appendOrInsert(i),new a(this.document,i,void 0,this.providers,this.hydrationMap,0)};makeChildText=e=>{const t=this.element.childNodes;for(let i=this.childIndex;i<t.length;i++){const r=t[i];if(r.nodeType===Node.TEXT_NODE)return this.childIndex=i+1,r.textContent!==e&&(r.textContent=e),new a(this.document,this.element,r,this.providers,this.hydrationMap,this.childIndex)}const n=this.document.createTextNode(e);return this.appendOrInsert(n),new a(this.document,this.element,n,this.providers,this.hydrationMap,this.childIndex)};setText=e=>{this.reference&&(this.reference.nodeValue=e)};getText=()=>this.reference?.nodeValue??this.element.textContent??"";makeRef=()=>{const e=this.element.childNodes;for(let n=this.childIndex;n<e.length;n++){const i=e[n];if(i.nodeType===Node.TEXT_NODE&&(i.textContent===""||i.textContent===null))return this.childIndex=n+1,new a(this.document,this.element,i,this.providers,this.hydrationMap,this.childIndex)}const t=this.document.createTextNode("");return this.appendOrInsert(t),new a(this.document,this.element,t,this.providers,this.hydrationMap,this.childIndex)};makeMarker=()=>this.makeRef();makePortal=e=>{const t=typeof e=="string"?this.document.querySelector(e):e;if(t==null)throw new Error(`Cannot find element by selector for portal: ${e}`);return new a(this.document,t,void 0,this.providers,this.hydrationMap,0)};appendOrInsert=e=>{this.reference===void 0?this.element.appendChild(e):this.element.insertBefore(e,this.reference)};setProvider=(e,t,n)=>new a(this.document,this.element,this.reference,{...this.providers,[e]:[t,n]},this.hydrationMap,this.childIndex);getProvider=e=>{if(this.providers[e]===void 0)throw new Error(`Provider not found: ${String(e)}`);const[t,n]=this.providers[e];return{value:t,onUse:n}};clear=e=>{e&&(this.reference!==void 0?this.reference.parentNode?.removeChild(this.reference):this.element.parentNode?.removeChild(this.element))};addClasses=e=>{this.element.classList.add(...e)};removeClasses=e=>{this.element.classList.remove(...e)};getClasses=()=>Array.from(this.element.classList);on=(e,t,n)=>{const i=r=>t(r,this);return this.element.addEventListener(e,i,n),r=>{r&&this.element.removeEventListener(e,i,n)}};isBrowserDOM=()=>!1;isBrowser=()=>!0;isHeadlessDOM=()=>!1;isHeadless=()=>!1;setStyle=(e,t)=>{this.element.style[e]=t};getStyle=e=>this.element.style[e];makeAccessors=e=>{const t=this.element;return{get:()=>t[e],set:n=>{t[e]=n}}};moveRangeBefore=(e,t,n)=>{const i=e.reference,r=t.reference,s=n.reference,d=this.element;let c=i;for(;c!==null;){const l=c.nextSibling;if(d.insertBefore(c,s),c===r)break;c=l}};removeRange=(e,t)=>{const n=e.reference,i=t.reference,r=this.element;let s=n;for(;s!==null;){const d=s.nextSibling;if(r.removeChild(s),s===i)break;s=d}};removeAllBefore(e){const t=e.reference,n=this.element;if(!n.firstChild||n.firstChild===t)return;const i=this.document.createRange();i.setStartBefore(n.firstChild),i.setEndBefore(t),i.deleteContents()}_detachedParent=null;_detachedNext=null;detach(){const e=this.element;e.parentNode&&(this._detachedParent=e.parentNode,this._detachedNext=e.nextSibling,e.remove())}reattach(){this._detachedParent&&(this._detachedParent.insertBefore(this.element,this._detachedNext),this._detachedParent=null,this._detachedNext=null)}}const u="data-tempo-island",I="data-tempo-hydrate",S="data-tempo-options";function A(o,e,t,n={}){o.innerHTML="";const i=new h.BrowserContext(o.ownerDocument,o,void 0,n.providers??{}),r=new f.DisposalScope,s=f.withScope(r,()=>e(t).render(i));return(d=!1)=>{r.dispose(),s(d)}}function x(o,e,t){if(e==="immediate")return t(),()=>{};if(e==="idle")if("requestIdleCallback"in window){const n=requestIdleCallback(t);return()=>cancelIdleCallback(n)}else{const n=setTimeout(t,1);return()=>clearTimeout(n)}if(e==="visible"){const n=new IntersectionObserver(i=>{for(const r of i)if(r.isIntersecting){n.disconnect(),t();break}},{rootMargin:"50px"});return n.observe(o),()=>n.disconnect()}if(typeof e=="object"&&"media"in e){const n=window.matchMedia(e.media);if(n.matches)return t(),()=>{};const i=r=>{r.matches&&(n.removeEventListener("change",i),t())};return n.addEventListener("change",i),()=>n.removeEventListener("change",i)}return t(),()=>{}}function D(o){return!o||o==="immediate"||o==="load"?"immediate":o==="idle"?"idle":o==="visible"?"visible":o.startsWith("media:")?{media:o.slice(6).trim()}:"immediate"}function T(o,e={}){const t=[];return document.querySelectorAll(`[${u}]`).forEach(i=>{const r=i,s=r.getAttribute(u);if(!s){console.warn("[Tempo Islands] Element missing island name:",r);return}const d=o[s];if(!d){console.warn(`[Tempo Islands] Component "${s}" not found in registry`);return}const c=r.getAttribute(S);let l={};if(c)try{l=JSON.parse(c)}catch(p){console.warn(`[Tempo Islands] Failed to parse options for "${s}":`,p)}const m=r.getAttribute(I),v=D(m),w=x(r,v,()=>{const p=A(r,d,l,e);t.push(p),r.removeAttribute(u),r.removeAttribute(I),r.removeAttribute(S)});t.push(w)}),()=>{t.forEach(i=>i())}}function R(o,e={},t="visible"){const n=typeof t=="object"?`media:${t.media}`:t;return[{name:u,value:o},{name:S,value:JSON.stringify(e)},{name:I,value:n}]}function b(o){const{app:e,islands:t,container:n="#app",providers:i={},debug:r=!1}=o,s=r?m=>console.log(`[Tempo] ${m}`):()=>{},d=typeof n=="string"?document.querySelector(n):n;if(!d)return console.error(`[Tempo] Could not find container: ${typeof n=="string"?n:"(element)"}`),()=>{};const c=d.querySelector(`[${u}]`)!==null;let l;if(c)s("SSR mode: Initializing islands..."),l=T(t,{providers:i}),s("Islands initialized! Static content stays static.");else if(e){s("Client-only mode: Rendering app...");const m=new h.BrowserContext(document,d,void 0,i),v=new f.DisposalScope,w=f.withScope(v,()=>e().render(m)),p=T(t,{providers:i});l=()=>{p(),v.dispose(),w(!0)},s("App rendered and islands initialized!")}else s("No SSR content detected, initializing islands only..."),l=T(t,{providers:i});return l}Object.defineProperty(exports,"HYDRATION_ID_ATTR",{enumerable:!0,get:()=>h.HYDRATION_ID_ATTR});exports.HydrationContext=a;exports.ISLAND_ATTR=u;exports.ISLAND_HYDRATE_ATTR=I;exports.ISLAND_OPTIONS_ATTR=S;exports.hydrate=g;exports.hydrateIsland=A;exports.initIslands=T;exports.islandMarker=R;exports.startClient=b;
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Renderable, Providers, ProviderMark, Clear, BrowserContext, DOMContext, HYDRATION_ID_ATTR, HeadlessContext } from '@tempots/dom';
1
+ import { Renderable, Providers, ProviderMark, Clear, BrowserContext, DOMContext, HYDRATION_ID_ATTR, HeadlessContext, HandlerOptions } from '@tempots/dom';
2
2
  /**
3
3
  * Options for client-side hydration.
4
4
  * @public
@@ -69,6 +69,7 @@ export declare class HydrationContext implements DOMContext {
69
69
  readonly setText: (text: string) => void;
70
70
  readonly getText: () => string;
71
71
  readonly makeRef: () => DOMContext;
72
+ readonly makeMarker: () => DOMContext;
72
73
  readonly makePortal: (selector: string | HTMLElement) => DOMContext;
73
74
  private readonly appendOrInsert;
74
75
  readonly setProvider: <T>(mark: ProviderMark<T>, value: T, onUse: undefined | (() => void)) => DOMContext;
@@ -80,7 +81,7 @@ export declare class HydrationContext implements DOMContext {
80
81
  readonly addClasses: (tokens: string[]) => void;
81
82
  readonly removeClasses: (tokens: string[]) => void;
82
83
  readonly getClasses: () => string[];
83
- readonly on: <E>(event: string, listener: (event: E, ctx: HydrationContext) => void, options?: AddEventListenerOptions) => Clear;
84
+ readonly on: <E>(event: string, listener: (event: E, ctx: DOMContext) => void, options?: HandlerOptions) => Clear;
84
85
  readonly isBrowserDOM: () => this is BrowserContext;
85
86
  readonly isBrowser: () => this is BrowserContext;
86
87
  readonly isHeadlessDOM: () => this is HeadlessContext;
@@ -91,6 +92,13 @@ export declare class HydrationContext implements DOMContext {
91
92
  get(): unknown;
92
93
  set(value: unknown): void;
93
94
  };
95
+ readonly moveRangeBefore: (startRef: DOMContext, endRef: DOMContext, targetRef: DOMContext) => void;
96
+ readonly removeRange: (startRef: DOMContext, endRef: DOMContext) => void;
97
+ removeAllBefore(ref: DOMContext): void;
98
+ private _detachedParent;
99
+ private _detachedNext;
100
+ detach(): void;
101
+ reattach(): void;
94
102
  }
95
103
  /**
96
104
  * Attribute name for island markers.
@@ -117,7 +125,7 @@ export declare const ISLAND_OPTIONS_ATTR = "data-tempo-options";
117
125
  *
118
126
  * @public
119
127
  */
120
- export type HydrationStrategy = "immediate" | "idle" | "visible" | {
128
+ export type HydrationStrategy = 'immediate' | 'idle' | 'visible' | {
121
129
  media: string;
122
130
  };
123
131
  /**
package/index.js CHANGED
@@ -1,34 +1,34 @@
1
- import { DisposalScope as S, withScope as y } from "@tempots/core";
2
- import { HYDRATION_ID_ATTR as f, BrowserContext as g } from "@tempots/dom";
3
- import { HYDRATION_ID_ATTR as q } from "@tempots/dom";
4
- function D(r, e, t = {}) {
5
- const { providers: n = {}, removeMarkers: i = !0 } = t, s = A(e), o = new S(), d = new c(
1
+ import { DisposalScope as S, withScope as T } from "@tempots/core";
2
+ import { HYDRATION_ID_ATTR as p, BrowserContext as x } from "@tempots/dom";
3
+ import { HYDRATION_ID_ATTR as $ } from "@tempots/dom";
4
+ function O(o, e, t = {}) {
5
+ const { providers: n = {}, removeMarkers: i = !0 } = t, r = y(e), s = new S(), d = new a(
6
6
  e.ownerDocument,
7
7
  e,
8
8
  void 0,
9
9
  n,
10
- s,
10
+ r,
11
11
  0
12
- ), h = y(o, () => r.render(d));
12
+ ), c = T(s, () => o.render(d));
13
13
  return i && N(e), (l = !1) => {
14
- o.dispose(), h(l);
14
+ s.dispose(), c(l);
15
15
  };
16
16
  }
17
- function A(r) {
17
+ function y(o) {
18
18
  const e = /* @__PURE__ */ new Map();
19
- return r.querySelectorAll(`[${f}]`).forEach((n) => {
20
- const i = n.getAttribute(f);
19
+ return o.querySelectorAll(`[${p}]`).forEach((n) => {
20
+ const i = n.getAttribute(p);
21
21
  i && e.set(i, n);
22
22
  }), e;
23
23
  }
24
- function N(r) {
25
- r.querySelectorAll(`[${f}]`).forEach((t) => {
26
- t.removeAttribute(f), t.removeAttribute("data-tts-node");
24
+ function N(o) {
25
+ o.querySelectorAll(`[${p}]`).forEach((t) => {
26
+ t.removeAttribute(p), t.removeAttribute("data-tts-node");
27
27
  });
28
28
  }
29
- class c {
30
- constructor(e, t, n, i, s, o) {
31
- this.document = e, this.element = t, this.reference = n, this.providers = i, this.hydrationMap = s, this.childIndex = o;
29
+ class a {
30
+ constructor(e, t, n, i, r, s) {
31
+ this.document = e, this.element = t, this.reference = n, this.providers = i, this.hydrationMap = r, this.childIndex = s;
32
32
  }
33
33
  /**
34
34
  * Finds the next child element instead of creating a new one.
@@ -36,12 +36,12 @@ class c {
36
36
  */
37
37
  makeChildElement = (e, t) => {
38
38
  const n = this.element.children;
39
- for (let s = this.childIndex; s < n.length; s++) {
40
- const o = n[s];
41
- if (o.tagName.toLowerCase() === e.toLowerCase())
42
- return this.childIndex = s + 1, new c(
39
+ for (let r = this.childIndex; r < n.length; r++) {
40
+ const s = n[r];
41
+ if (s.tagName.toLowerCase() === e.toLowerCase())
42
+ return this.childIndex = r + 1, new a(
43
43
  this.document,
44
- o,
44
+ s,
45
45
  void 0,
46
46
  this.providers,
47
47
  this.hydrationMap,
@@ -52,7 +52,7 @@ class c {
52
52
  `Hydration mismatch: could not find element <${e}> in container`
53
53
  );
54
54
  const i = t !== void 0 ? this.document.createElementNS(t, e) : this.document.createElement(e);
55
- return this.appendOrInsert(i), new c(
55
+ return this.appendOrInsert(i), new a(
56
56
  this.document,
57
57
  i,
58
58
  void 0,
@@ -67,19 +67,19 @@ class c {
67
67
  makeChildText = (e) => {
68
68
  const t = this.element.childNodes;
69
69
  for (let i = this.childIndex; i < t.length; i++) {
70
- const s = t[i];
71
- if (s.nodeType === Node.TEXT_NODE)
72
- return this.childIndex = i + 1, s.textContent !== e && (s.textContent = e), new c(
70
+ const r = t[i];
71
+ if (r.nodeType === Node.TEXT_NODE)
72
+ return this.childIndex = i + 1, r.textContent !== e && (r.textContent = e), new a(
73
73
  this.document,
74
74
  this.element,
75
- s,
75
+ r,
76
76
  this.providers,
77
77
  this.hydrationMap,
78
78
  this.childIndex
79
79
  );
80
80
  }
81
81
  const n = this.document.createTextNode(e);
82
- return this.appendOrInsert(n), new c(
82
+ return this.appendOrInsert(n), new a(
83
83
  this.document,
84
84
  this.element,
85
85
  n,
@@ -97,7 +97,7 @@ class c {
97
97
  for (let n = this.childIndex; n < e.length; n++) {
98
98
  const i = e[n];
99
99
  if (i.nodeType === Node.TEXT_NODE && (i.textContent === "" || i.textContent === null))
100
- return this.childIndex = n + 1, new c(
100
+ return this.childIndex = n + 1, new a(
101
101
  this.document,
102
102
  this.element,
103
103
  i,
@@ -107,7 +107,7 @@ class c {
107
107
  );
108
108
  }
109
109
  const t = this.document.createTextNode("");
110
- return this.appendOrInsert(t), new c(
110
+ return this.appendOrInsert(t), new a(
111
111
  this.document,
112
112
  this.element,
113
113
  t,
@@ -116,13 +116,12 @@ class c {
116
116
  this.childIndex
117
117
  );
118
118
  };
119
+ makeMarker = () => this.makeRef();
119
120
  makePortal = (e) => {
120
121
  const t = typeof e == "string" ? this.document.querySelector(e) : e;
121
122
  if (t == null)
122
- throw new Error(
123
- `Cannot find element by selector for portal: ${e}`
124
- );
125
- return new c(
123
+ throw new Error(`Cannot find element by selector for portal: ${e}`);
124
+ return new a(
126
125
  this.document,
127
126
  t,
128
127
  void 0,
@@ -134,7 +133,7 @@ class c {
134
133
  appendOrInsert = (e) => {
135
134
  this.reference === void 0 ? this.element.appendChild(e) : this.element.insertBefore(e, this.reference);
136
135
  };
137
- setProvider = (e, t, n) => new c(
136
+ setProvider = (e, t, n) => new a(
138
137
  this.document,
139
138
  this.element,
140
139
  this.reference,
@@ -159,9 +158,9 @@ class c {
159
158
  };
160
159
  getClasses = () => Array.from(this.element.classList);
161
160
  on = (e, t, n) => {
162
- const i = (s) => t(s, this);
163
- return this.element.addEventListener(e, i, n), (s) => {
164
- s && this.element.removeEventListener(e, i, n);
161
+ const i = (r) => t(r, this);
162
+ return this.element.addEventListener(e, i, n), (r) => {
163
+ r && this.element.removeEventListener(e, i, n);
165
164
  };
166
165
  };
167
166
  // HydrationContext runs in a browser environment, so isBrowser() returns true
@@ -184,21 +183,54 @@ class c {
184
183
  }
185
184
  };
186
185
  };
186
+ moveRangeBefore = (e, t, n) => {
187
+ const i = e.reference, r = t.reference, s = n.reference, d = this.element;
188
+ let c = i;
189
+ for (; c !== null; ) {
190
+ const l = c.nextSibling;
191
+ if (d.insertBefore(c, s), c === r) break;
192
+ c = l;
193
+ }
194
+ };
195
+ removeRange = (e, t) => {
196
+ const n = e.reference, i = t.reference, r = this.element;
197
+ let s = n;
198
+ for (; s !== null; ) {
199
+ const d = s.nextSibling;
200
+ if (r.removeChild(s), s === i) break;
201
+ s = d;
202
+ }
203
+ };
204
+ removeAllBefore(e) {
205
+ const t = e.reference, n = this.element;
206
+ if (!n.firstChild || n.firstChild === t) return;
207
+ const i = this.document.createRange();
208
+ i.setStartBefore(n.firstChild), i.setEndBefore(t), i.deleteContents();
209
+ }
210
+ _detachedParent = null;
211
+ _detachedNext = null;
212
+ detach() {
213
+ const e = this.element;
214
+ e.parentNode && (this._detachedParent = e.parentNode, this._detachedNext = e.nextSibling, e.remove());
215
+ }
216
+ reattach() {
217
+ this._detachedParent && (this._detachedParent.insertBefore(this.element, this._detachedNext), this._detachedParent = null, this._detachedNext = null);
218
+ }
187
219
  }
188
- const u = "data-tempo-island", I = "data-tempo-hydrate", T = "data-tempo-options";
189
- function x(r, e, t, n = {}) {
190
- r.innerHTML = "";
191
- const i = new g(
192
- r.ownerDocument,
193
- r,
220
+ const u = "data-tempo-island", I = "data-tempo-hydrate", g = "data-tempo-options";
221
+ function A(o, e, t, n = {}) {
222
+ o.innerHTML = "";
223
+ const i = new x(
224
+ o.ownerDocument,
225
+ o,
194
226
  void 0,
195
227
  n.providers ?? {}
196
- ), s = new S(), o = y(s, () => e(t).render(i));
228
+ ), r = new S(), s = T(r, () => e(t).render(i));
197
229
  return (d = !1) => {
198
- s.dispose(), o(d);
230
+ r.dispose(), s(d);
199
231
  };
200
232
  }
201
- function E(r, e, t) {
233
+ function b(o, e, t) {
202
234
  if (e === "immediate")
203
235
  return t(), () => {
204
236
  };
@@ -213,115 +245,115 @@ function E(r, e, t) {
213
245
  if (e === "visible") {
214
246
  const n = new IntersectionObserver(
215
247
  (i) => {
216
- for (const s of i)
217
- if (s.isIntersecting) {
248
+ for (const r of i)
249
+ if (r.isIntersecting) {
218
250
  n.disconnect(), t();
219
251
  break;
220
252
  }
221
253
  },
222
254
  { rootMargin: "50px" }
223
255
  );
224
- return n.observe(r), () => n.disconnect();
256
+ return n.observe(o), () => n.disconnect();
225
257
  }
226
258
  if (typeof e == "object" && "media" in e) {
227
259
  const n = window.matchMedia(e.media);
228
260
  if (n.matches)
229
261
  return t(), () => {
230
262
  };
231
- const i = (s) => {
232
- s.matches && (n.removeEventListener("change", i), t());
263
+ const i = (r) => {
264
+ r.matches && (n.removeEventListener("change", i), t());
233
265
  };
234
266
  return n.addEventListener("change", i), () => n.removeEventListener("change", i);
235
267
  }
236
268
  return t(), () => {
237
269
  };
238
270
  }
239
- function M(r) {
240
- return !r || r === "immediate" || r === "load" ? "immediate" : r === "idle" ? "idle" : r === "visible" ? "visible" : r.startsWith("media:") ? { media: r.slice(6).trim() } : "immediate";
271
+ function E(o) {
272
+ return !o || o === "immediate" || o === "load" ? "immediate" : o === "idle" ? "idle" : o === "visible" ? "visible" : o.startsWith("media:") ? { media: o.slice(6).trim() } : "immediate";
241
273
  }
242
- function w(r, e = {}) {
274
+ function w(o, e = {}) {
243
275
  const t = [];
244
276
  return document.querySelectorAll(`[${u}]`).forEach((i) => {
245
- const s = i, o = s.getAttribute(u);
246
- if (!o) {
247
- console.warn("[Tempo Islands] Element missing island name:", s);
277
+ const r = i, s = r.getAttribute(u);
278
+ if (!s) {
279
+ console.warn("[Tempo Islands] Element missing island name:", r);
248
280
  return;
249
281
  }
250
- const d = r[o];
282
+ const d = o[s];
251
283
  if (!d) {
252
284
  console.warn(
253
- `[Tempo Islands] Component "${o}" not found in registry`
285
+ `[Tempo Islands] Component "${s}" not found in registry`
254
286
  );
255
287
  return;
256
288
  }
257
- const h = s.getAttribute(T);
289
+ const c = r.getAttribute(g);
258
290
  let l = {};
259
- if (h)
291
+ if (c)
260
292
  try {
261
- l = JSON.parse(h);
293
+ l = JSON.parse(c);
262
294
  } catch (m) {
263
295
  console.warn(
264
- `[Tempo Islands] Failed to parse options for "${o}":`,
296
+ `[Tempo Islands] Failed to parse options for "${s}":`,
265
297
  m
266
298
  );
267
299
  }
268
- const a = s.getAttribute(I), p = M(a), v = E(s, p, () => {
269
- const m = x(
270
- s,
300
+ const h = r.getAttribute(I), f = E(h), v = b(r, f, () => {
301
+ const m = A(
302
+ r,
271
303
  d,
272
304
  l,
273
305
  e
274
306
  );
275
- t.push(m), s.removeAttribute(u), s.removeAttribute(I), s.removeAttribute(T);
307
+ t.push(m), r.removeAttribute(u), r.removeAttribute(I), r.removeAttribute(g);
276
308
  });
277
309
  t.push(v);
278
310
  }), () => {
279
311
  t.forEach((i) => i());
280
312
  };
281
313
  }
282
- function L(r, e = {}, t = "visible") {
314
+ function R(o, e = {}, t = "visible") {
283
315
  const n = typeof t == "object" ? `media:${t.media}` : t;
284
316
  return [
285
- { name: u, value: r },
286
- { name: T, value: JSON.stringify(e) },
317
+ { name: u, value: o },
318
+ { name: g, value: JSON.stringify(e) },
287
319
  { name: I, value: n }
288
320
  ];
289
321
  }
290
- function C(r) {
322
+ function D(o) {
291
323
  const {
292
324
  app: e,
293
325
  islands: t,
294
326
  container: n = "#app",
295
327
  providers: i = {},
296
- debug: s = !1
297
- } = r, o = s ? (a) => console.log(`[Tempo] ${a}`) : () => {
328
+ debug: r = !1
329
+ } = o, s = r ? (h) => console.log(`[Tempo] ${h}`) : () => {
298
330
  }, d = typeof n == "string" ? document.querySelector(n) : n;
299
331
  if (!d)
300
332
  return console.error(`[Tempo] Could not find container: ${typeof n == "string" ? n : "(element)"}`), () => {
301
333
  };
302
- const h = d.querySelector(`[${u}]`) !== null;
334
+ const c = d.querySelector(`[${u}]`) !== null;
303
335
  let l;
304
- if (h)
305
- o("SSR mode: Initializing islands..."), l = w(t, { providers: i }), o("Islands initialized! Static content stays static.");
336
+ if (c)
337
+ s("SSR mode: Initializing islands..."), l = w(t, { providers: i }), s("Islands initialized! Static content stays static.");
306
338
  else if (e) {
307
- o("Client-only mode: Rendering app...");
308
- const a = new g(document, d, void 0, i), p = new S(), v = y(p, () => e().render(a)), m = w(t, { providers: i });
339
+ s("Client-only mode: Rendering app...");
340
+ const h = new x(document, d, void 0, i), f = new S(), v = T(f, () => e().render(h)), m = w(t, { providers: i });
309
341
  l = () => {
310
- m(), p.dispose(), v(!0);
311
- }, o("App rendered and islands initialized!");
342
+ m(), f.dispose(), v(!0);
343
+ }, s("App rendered and islands initialized!");
312
344
  } else
313
- o("No SSR content detected, initializing islands only..."), l = w(t, { providers: i });
345
+ s("No SSR content detected, initializing islands only..."), l = w(t, { providers: i });
314
346
  return l;
315
347
  }
316
348
  export {
317
- q as HYDRATION_ID_ATTR,
318
- c as HydrationContext,
349
+ $ as HYDRATION_ID_ATTR,
350
+ a as HydrationContext,
319
351
  u as ISLAND_ATTR,
320
352
  I as ISLAND_HYDRATE_ATTR,
321
- T as ISLAND_OPTIONS_ATTR,
322
- D as hydrate,
323
- x as hydrateIsland,
353
+ g as ISLAND_OPTIONS_ATTR,
354
+ O as hydrate,
355
+ A as hydrateIsland,
324
356
  w as initIslands,
325
- L as islandMarker,
326
- C as startClient
357
+ R as islandMarker,
358
+ D as startClient
327
359
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tempots/client",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "main": "./index.cjs",
6
6
  "module": "./index.js",
@@ -34,7 +34,7 @@
34
34
  "url": "git+https://github.com/fponticelli/tempots.git"
35
35
  },
36
36
  "peerDependencies": {
37
- "@tempots/core": "^2.1.0",
38
- "@tempots/dom": "^36.0.0"
37
+ "@tempots/core": "^3.0.0",
38
+ "@tempots/dom": "^37.0.0"
39
39
  }
40
40
  }