@jasonshimmy/custom-elements-runtime 0.0.2 → 0.0.3-beta.0

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/README.md CHANGED
@@ -1,9 +1,39 @@
1
- # Custom Elements Runtime
1
+ # 🧩 Custom Elements Runtime
2
2
 
3
3
  > **Ultra-lightweight, type-safe runtime for fast, reactive, and maintainable web components.**
4
4
 
5
5
  Build modern web components with strict TypeScript, zero dependencies, and a functional API. Designed for performance, standards compliance, and developer productivity.
6
6
 
7
+ ## 🚀 Getting Started
8
+
9
+ ### Install
10
+
11
+ ```bash
12
+ npm install @jasonshimmy/custom-elements-runtime
13
+ ```
14
+
15
+ ### Import and use in your project
16
+
17
+ ```typescript
18
+ import { component, html } from '@jasonshimmy/custom-elements-runtime';
19
+
20
+ component('my-counter', {
21
+ state: { count: 0 },
22
+ template: ({ count }) => html`
23
+ <button data-on-click="increment">Count: ${count}</button>
24
+ `({ count }),
25
+ increment: (_e, state) => state.count++
26
+ });
27
+ ```
28
+
29
+ ### TypeScript support
30
+
31
+ All types and interfaces are available for auto-completion and strict typing in code editors. No extra configuration is needed.
32
+
33
+ ### Advanced usage
34
+
35
+ See the [API Reference](docs/api-reference.md) for advanced configuration, SSR, plugin system, global store, event bus, and more.
36
+
7
37
  ## ✨ Features
8
38
 
9
39
  - **Reactive State:** Automatic re-renders using ES6 Proxy; direct assignment supported. State changes trigger batched updates for performance.
@@ -40,36 +70,6 @@ Build modern web components with strict TypeScript, zero dependencies, and a fun
40
70
  - Only features documented here and in [`src/lib/runtime.ts`](src/lib/runtime.ts) are supported. Undocumented features may not work as expected.
41
71
  - VDOM patching for controlled inputs (checkboxes, radios, etc.) is regression-tested to ensure event listeners are always attached and state updates are reliable.
42
72
 
43
- ## 🚀 Getting Started
44
-
45
- ### Install
46
-
47
- ```bash
48
- npm install @jasonshimmy/custom-elements-runtime
49
- ```
50
-
51
- ### Import and use in your project
52
-
53
- ```typescript
54
- import { component, html } from '@jasonshimmy/custom-elements-runtime';
55
-
56
- component('my-counter', {
57
- state: { count: 0 },
58
- template: ({ count }) => html`
59
- <button data-on-click="increment">Count: ${count}</button>
60
- `({ count }),
61
- increment(_e, state) { state.count++; }
62
- });
63
- ```
64
-
65
- ### TypeScript support
66
-
67
- All types and interfaces are available for auto-completion and strict typing in code editors. No extra configuration is needed.
68
-
69
- ### Advanced usage
70
-
71
- See the [API Reference](docs/api-reference.md) for advanced configuration, SSR, plugin system, global store, event bus, and more.
72
-
73
73
  ## 🎯 Use Cases
74
74
 
75
75
  - **Micro-frontends**: Lightweight, isolated components
@@ -79,11 +79,14 @@ See the [API Reference](docs/api-reference.md) for advanced configuration, SSR,
79
79
  - **Performance-Critical Apps**: When bundle size matters
80
80
  - **Web Standards**: Future-proof, standards-based development
81
81
 
82
- ## ⚠️ SSR Caveats
82
+ ## 🖥️ SSR Highlights
83
83
 
84
- - SSR only generates HTML and styles; DOM APIs, refs, and event listeners are not available during server rendering.
85
- - Lifecycle hooks (`onMounted`, `onUnmounted`) and refs are ignored during SSR.
86
- - Hydration requires the client bundle to match the server-rendered markup and state exactly.
84
+ - **Universal Rendering:** Generate fast, standards-compliant HTML and CSS on the server for instant page loads and SEO.
85
+ - **Opt-in Hydration:** Hydrate only the regions you need with `hydrate` for efficient client-side interactivity.
86
+ - **Template Matching:** Hydration requires the client bundle to match the server-rendered markup and state for seamless transitions.
87
+ - **Fragment & Keyed Templates:** Supports fragments and keyed nodes for robust SSR reconciliation.
88
+ - **Error Boundaries:** SSR supports error boundaries for graceful fallback UI and diagnostics.
89
+ - **Strict SSR Compliance:** Lifecycle hooks and refs are excluded during SSR for predictable, side-effect-free rendering.
87
90
 
88
91
  ## 🛡️ Production-Readiness
89
92
 
@@ -102,7 +105,7 @@ See the [API Reference](docs/api-reference.md) for advanced configuration, SSR,
102
105
  - **Async rendering**: Supports Promises in templates for async data and UI
103
106
  - **Selective hydration**: Hydrate only regions marked with `data-hydrate` for efficient SSR
104
107
 
105
- ## Documentation
108
+ ## 📚 Documentation
106
109
 
107
110
  - [API Reference](docs/api-reference.md): All runtime exports, configuration options, and advanced patterns.
108
111
  - [Core Concepts](docs/core-concepts.md): State, attribute sync, event binding, input binding, global store, event bus, lifecycle, error boundaries, SSR, plugin system.
@@ -42,5 +42,5 @@
42
42
  <h3>Error Boundary</h3>
43
43
  <div>Error: ${e.message}</div>
44
44
  </div>
45
- `}});function dt(e,t){if(t=E(t),t.debug&&console.log(`[runtime] Debugging component: ${e}`,t),!e||!t.template||!t.state){t&&typeof t.onError=="function"&&t.onError(new Error("Component requires tag, template, and state"),t.state,{state:t.state,emit:()=>{},onGlobal:()=>()=>{},offGlobal:()=>{},emitGlobal:()=>{}}),t&&t.debug&&console.error("[runtime] Malformed config:",{tag:e,config:t});return}b.forEach(l=>{try{l.onInit?.(t)}catch(d){t&&typeof t.onError=="function"&&t.onError(d instanceof Error?d:new Error(String(d)),t.state,{state:t.state,emit:()=>{},onGlobal:()=>()=>{},offGlobal:()=>{},emitGlobal:()=>{}}),t&&t.debug&&console.error("[runtime] Plugin onInit error:",d)}});const r=typeof window<"u"&&window.VITE_DEV_HMR,i=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:O&&O.tagName.toUpperCase()==="SCRIPT"&&O.src||new URL("custom-elements-runtime.cjs.js",document.baseURI).href}<"u"&&void 0;if((r||i)&&customElements.get(e))try{document.querySelectorAll(e).forEach(l=>l.remove()),window.customElements._definitions&&delete window.customElements._definitions[e]}catch{}if(customElements.get(e)){t.debug&&console.warn(`[runtime] Component "${e}" already registered`);return}const s=$(t.state,t.computed);t.state=s,t._subscribe=s.subscribe;const o=Object.keys(t.state).filter(l=>["string","number","boolean"].includes(typeof t.state[l]));class a extends K{static get observedAttributes(){return o}constructor(){super()}}const c=a;typeof customElements<"u"&&!customElements.get(e)&&(window.__componentRegistry=window.__componentRegistry||{},window.__componentRegistry[e]=t,customElements.define(e,c))}exports.Store=G;exports.classes=nt;exports.compile=tt;exports.compileTemplate=st;exports.component=dt;exports.createVNodeFromElement=T;exports.css=et;exports.deepSanitizeObject=E;exports.eventBus=A;exports.generateHydrationScript=X;exports.getVNodeKey=H;exports.html=Q;exports.isPromise=C;exports.mountVNode=y;exports.parseVNodeFromHTML=F;exports.patchVNode=S;exports.renderCompiledTemplate=R;exports.renderComponentsToString=V;exports.renderToString=I;exports.runtimePlugins=b;exports.safeReplaceChild=j;exports.styles=rt;exports.updateCompiledTemplate=z;exports.useDataModel=P;exports.useRuntimePlugin=lt;
45
+ `}});function dt(e,t){if(t=E(t),t.debug&&console.log(`[runtime] Debugging component: ${e}`,t),!e||!t.template){t&&typeof t.onError=="function"&&t.onError(new Error("Component requires tag and template"),t.state??{},{state:t.state??{},emit:()=>{},onGlobal:()=>()=>{},offGlobal:()=>{},emitGlobal:()=>{}}),t&&t.debug&&console.error("[runtime] Malformed config:",{tag:e,config:t});return}b.forEach(d=>{try{d.onInit?.(t)}catch(u){t&&typeof t.onError=="function"&&t.onError(u instanceof Error?u:new Error(String(u)),t.state,{state:t.state,emit:()=>{},onGlobal:()=>()=>{},offGlobal:()=>{},emitGlobal:()=>{}}),t&&t.debug&&console.error("[runtime] Plugin onInit error:",u)}});const r=typeof window<"u"&&window.VITE_DEV_HMR,i=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:O&&O.tagName.toUpperCase()==="SCRIPT"&&O.src||new URL("custom-elements-runtime.cjs.js",document.baseURI).href}<"u"&&void 0;if((r||i)&&customElements.get(e))try{document.querySelectorAll(e).forEach(d=>d.remove()),window.customElements._definitions&&delete window.customElements._definitions[e]}catch{}if(customElements.get(e)){t.debug&&console.warn(`[runtime] Component "${e}" already registered`);return}const s=$(t.state??{},t.computed);t.state=s,t._subscribe=s.subscribe;const o=t.state??{},a=Object.keys(o).filter(d=>["string","number","boolean"].includes(typeof o[d]));class c extends K{static get observedAttributes(){return a}constructor(){super()}}const l=c;typeof customElements<"u"&&!customElements.get(e)&&(window.__componentRegistry=window.__componentRegistry||{},window.__componentRegistry[e]=t,customElements.define(e,l))}exports.Store=G;exports.classes=nt;exports.compile=tt;exports.compileTemplate=st;exports.component=dt;exports.createVNodeFromElement=T;exports.css=et;exports.deepSanitizeObject=E;exports.eventBus=A;exports.generateHydrationScript=X;exports.getVNodeKey=H;exports.html=Q;exports.isPromise=C;exports.mountVNode=y;exports.parseVNodeFromHTML=F;exports.patchVNode=S;exports.renderCompiledTemplate=R;exports.renderComponentsToString=V;exports.renderToString=I;exports.runtimePlugins=b;exports.safeReplaceChild=j;exports.styles=rt;exports.updateCompiledTemplate=z;exports.useDataModel=P;exports.useRuntimePlugin=lt;
46
46
  //# sourceMappingURL=custom-elements-runtime.cjs.js.map