@elurjs/core 3.6.1 → 3.7.0-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/dist/lib/async.cjs +1 -1
- package/dist/lib/async.js +1 -1
- package/dist/lib/component.cjs +1 -2
- package/dist/lib/component.js +2 -66
- package/dist/lib/context.cjs +1 -1
- package/dist/lib/context.js +35 -23
- package/dist/lib/devtools.cjs +1 -1
- package/dist/lib/devtools.js +1 -1
- package/dist/lib/elur/async.cjs +1 -1
- package/dist/lib/elur/async.cjs.map +1 -1
- package/dist/lib/elur/async.js +1 -1
- package/dist/lib/elur/component.cjs +1 -2
- package/dist/lib/elur/component.d.cts +1 -17
- package/dist/lib/elur/component.d.ts +1 -17
- package/dist/lib/elur/component.js +2 -66
- package/dist/lib/elur/context.cjs +1 -1
- package/dist/lib/elur/context.cjs.map +1 -1
- package/dist/lib/elur/context.d.cts +5 -0
- package/dist/lib/elur/context.d.ts +5 -0
- package/dist/lib/elur/context.js +35 -23
- package/dist/lib/elur/context.js.map +1 -1
- package/dist/lib/elur/devtools.cjs +1 -1
- package/dist/lib/elur/devtools.cjs.map +1 -1
- package/dist/lib/elur/devtools.js +1 -1
- package/dist/lib/elur/form.cjs +1 -1
- package/dist/lib/elur/form.cjs.map +1 -1
- package/dist/lib/elur/form.js +1 -1
- package/dist/lib/elur/hydrate/index.cjs +1 -2
- package/dist/lib/elur/hydrate/index.d.cts +1 -13
- package/dist/lib/elur/hydrate/index.d.ts +1 -13
- package/dist/lib/elur/hydrate/index.js +2 -410
- package/dist/lib/elur/lifecycle.cjs +1 -1
- package/dist/lib/elur/lifecycle.cjs.map +1 -1
- package/dist/lib/elur/lifecycle.d.cts +27 -0
- package/dist/lib/elur/lifecycle.d.ts +27 -0
- package/dist/lib/elur/lifecycle.js +4 -0
- package/dist/lib/elur/lifecycle.js.map +1 -1
- package/dist/lib/elur/next/component.d.cts +281 -0
- package/dist/lib/elur/next/component.d.ts +281 -0
- package/dist/lib/elur/next/dom-write.d.cts +18 -0
- package/dist/lib/elur/next/dom-write.d.ts +18 -0
- package/dist/lib/elur/next/hydrate.d.cts +14 -0
- package/dist/lib/elur/next/hydrate.d.ts +14 -0
- package/dist/lib/elur/next/keyed-diff.d.cts +46 -0
- package/dist/lib/elur/next/keyed-diff.d.ts +46 -0
- package/dist/lib/elur/next/mount-helpers.d.cts +25 -0
- package/dist/lib/elur/next/mount-helpers.d.ts +25 -0
- package/dist/lib/elur/next/mount.d.cts +29 -0
- package/dist/lib/elur/next/mount.d.ts +29 -0
- package/dist/lib/elur/next/node-binding.d.cts +6 -0
- package/dist/lib/elur/next/node-binding.d.ts +6 -0
- package/dist/lib/elur/next/reactivity.d.cts +193 -0
- package/dist/lib/elur/next/reactivity.d.ts +193 -0
- package/dist/lib/elur/next-2/component.cjs +2 -0
- package/dist/lib/elur/next-2/component.cjs.map +1 -0
- package/dist/lib/elur/next-2/component.d.cts +283 -0
- package/dist/lib/elur/next-2/component.d.ts +283 -0
- package/dist/lib/elur/next-2/component.js +340 -0
- package/dist/lib/elur/next-2/component.js.map +1 -0
- package/dist/lib/elur/next-2/dom-write.cjs +2 -0
- package/dist/lib/elur/next-2/dom-write.cjs.map +1 -0
- package/dist/lib/elur/next-2/dom-write.d.cts +18 -0
- package/dist/lib/elur/next-2/dom-write.d.ts +18 -0
- package/dist/lib/elur/next-2/dom-write.js +31 -0
- package/dist/lib/elur/next-2/dom-write.js.map +1 -0
- package/dist/lib/elur/next-2/hydrate.cjs +2 -0
- package/dist/lib/elur/next-2/hydrate.cjs.map +1 -0
- package/dist/lib/elur/next-2/hydrate.d.cts +30 -0
- package/dist/lib/elur/next-2/hydrate.d.ts +30 -0
- package/dist/lib/elur/next-2/hydrate.js +449 -0
- package/dist/lib/elur/next-2/hydrate.js.map +1 -0
- package/dist/lib/elur/next-2/keyed-diff.cjs +2 -0
- package/dist/lib/elur/next-2/keyed-diff.cjs.map +1 -0
- package/dist/lib/elur/next-2/keyed-diff.d.cts +79 -0
- package/dist/lib/elur/next-2/keyed-diff.d.ts +79 -0
- package/dist/lib/elur/next-2/keyed-diff.js +208 -0
- package/dist/lib/elur/next-2/keyed-diff.js.map +1 -0
- package/dist/lib/elur/next-2/mount-helpers.cjs +2 -0
- package/dist/lib/elur/next-2/mount-helpers.cjs.map +1 -0
- package/dist/lib/elur/next-2/mount-helpers.d.cts +25 -0
- package/dist/lib/elur/next-2/mount-helpers.d.ts +25 -0
- package/dist/lib/elur/next-2/mount-helpers.js +87 -0
- package/dist/lib/elur/next-2/mount-helpers.js.map +1 -0
- package/dist/lib/elur/next-2/mount.cjs +2 -0
- package/dist/lib/elur/next-2/mount.cjs.map +1 -0
- package/dist/lib/elur/next-2/mount.d.cts +29 -0
- package/dist/lib/elur/next-2/mount.d.ts +29 -0
- package/dist/lib/elur/next-2/mount.js +34 -0
- package/dist/lib/elur/next-2/mount.js.map +1 -0
- package/dist/lib/elur/next-2/node-binding.cjs +2 -0
- package/dist/lib/elur/next-2/node-binding.cjs.map +1 -0
- package/dist/lib/elur/next-2/node-binding.d.cts +6 -0
- package/dist/lib/elur/next-2/node-binding.d.ts +6 -0
- package/dist/lib/elur/next-2/node-binding.js +130 -0
- package/dist/lib/elur/next-2/node-binding.js.map +1 -0
- package/dist/lib/elur/next-2/reactivity.cjs +2 -0
- package/dist/lib/elur/next-2/reactivity.cjs.map +1 -0
- package/dist/lib/elur/next-2/reactivity.d.cts +220 -0
- package/dist/lib/elur/next-2/reactivity.d.ts +220 -0
- package/dist/lib/elur/next-2/reactivity.js +614 -0
- package/dist/lib/elur/next-2/reactivity.js.map +1 -0
- package/dist/lib/elur/next-2/scheduler.cjs +2 -0
- package/dist/lib/elur/next-2/scheduler.cjs.map +1 -0
- package/dist/lib/elur/next-2/scheduler.d.cts +23 -0
- package/dist/lib/elur/next-2/scheduler.d.ts +23 -0
- package/dist/lib/elur/next-2/scheduler.js +26 -0
- package/dist/lib/elur/next-2/scheduler.js.map +1 -0
- package/dist/lib/elur/plugins.cjs +1 -1
- package/dist/lib/elur/plugins.cjs.map +1 -1
- package/dist/lib/elur/plugins.js +1 -1
- package/dist/lib/elur/reactivity.cjs +1 -2
- package/dist/lib/elur/reactivity.d.cts +1 -67
- package/dist/lib/elur/reactivity.d.ts +1 -67
- package/dist/lib/elur/reactivity.js +2 -218
- package/dist/lib/elur/router.cjs +2 -2
- package/dist/lib/elur/router.cjs.map +1 -1
- package/dist/lib/elur/router.js +2 -2
- package/dist/lib/elur/router.js.map +1 -1
- package/dist/lib/elur/server/index.cjs +1 -1
- package/dist/lib/elur/server/index.cjs.map +1 -1
- package/dist/lib/elur/server/index.js +180 -108
- package/dist/lib/elur/server/index.js.map +1 -1
- package/dist/lib/elur/store.cjs +1 -1
- package/dist/lib/elur/store.cjs.map +1 -1
- package/dist/lib/elur/store.js +10 -4
- package/dist/lib/elur/store.js.map +1 -1
- package/dist/lib/elur/template/bindings.cjs +1 -1
- package/dist/lib/elur/template/bindings.cjs.map +1 -1
- package/dist/lib/elur/template/bindings.js +98 -84
- package/dist/lib/elur/template/bindings.js.map +1 -1
- package/dist/lib/elur/template/dom-write.d.cts +1 -5
- package/dist/lib/elur/template/dom-write.d.ts +1 -5
- package/dist/lib/elur/template/error-boundary.cjs +1 -1
- package/dist/lib/elur/template/error-boundary.cjs.map +1 -1
- package/dist/lib/elur/template/error-boundary.js +56 -50
- package/dist/lib/elur/template/error-boundary.js.map +1 -1
- package/dist/lib/elur/template/html.cjs +1 -1
- package/dist/lib/elur/template/html.cjs.map +1 -1
- package/dist/lib/elur/template/html.js +40 -37
- package/dist/lib/elur/template/html.js.map +1 -1
- package/dist/lib/elur/template/index.cjs +1 -1
- package/dist/lib/elur/template/index.d.cts +2 -1
- package/dist/lib/elur/template/index.d.ts +2 -1
- package/dist/lib/elur/template/index.js +13 -12
- package/dist/lib/elur/template/keyed-diff.d.cts +1 -32
- package/dist/lib/elur/template/keyed-diff.d.ts +1 -32
- package/dist/lib/elur/template/keyed.cjs +1 -1
- package/dist/lib/elur/template/keyed.cjs.map +1 -1
- package/dist/lib/elur/template/keyed.d.cts +10 -2
- package/dist/lib/elur/template/keyed.d.ts +10 -2
- package/dist/lib/elur/template/keyed.js +12 -1
- package/dist/lib/elur/template/keyed.js.map +1 -1
- package/dist/lib/elur/template/mount-helpers.d.cts +1 -29
- package/dist/lib/elur/template/mount-helpers.d.ts +1 -29
- package/dist/lib/elur/template/node-binding.d.cts +1 -6
- package/dist/lib/elur/template/node-binding.d.ts +1 -6
- package/dist/lib/elur/template/portal.cjs +1 -1
- package/dist/lib/elur/template/portal.cjs.map +1 -1
- package/dist/lib/elur/template/portal.js +1 -1
- package/dist/lib/elur/template/transitions.cjs +1 -1
- package/dist/lib/elur/template/transitions.cjs.map +1 -1
- package/dist/lib/elur/template/transitions.js +2 -2
- package/dist/lib/elur/template/types.cjs +1 -1
- package/dist/lib/elur/template/types.cjs.map +1 -1
- package/dist/lib/elur/template/types.d.cts +55 -0
- package/dist/lib/elur/template/types.d.ts +55 -0
- package/dist/lib/elur/template/types.js +5 -1
- package/dist/lib/elur/template/types.js.map +1 -1
- package/dist/lib/elur.cjs +1 -1
- package/dist/lib/elur.js +2 -2
- package/dist/lib/form.cjs +1 -1
- package/dist/lib/form.js +1 -1
- package/dist/lib/hydrate.cjs +1 -2
- package/dist/lib/hydrate.js +2 -410
- package/dist/lib/index.cjs +1 -1
- package/dist/lib/index.js +2 -2
- package/dist/lib/lifecycle.cjs +1 -1
- package/dist/lib/lifecycle.js +4 -0
- package/dist/lib/plugins.cjs +1 -1
- package/dist/lib/plugins.js +1 -1
- package/dist/lib/router.cjs +2 -2
- package/dist/lib/router.js +2 -2
- package/dist/lib/server.cjs +1 -1
- package/dist/lib/server.js +180 -108
- package/dist/lib/signals.cjs +1 -2
- package/dist/lib/signals.js +2 -218
- package/dist/lib/store.cjs +1 -1
- package/dist/lib/store.js +10 -4
- package/dist/lib/template.cjs +1 -1
- package/dist/lib/template.js +13 -12
- package/package.json +7 -9
- package/dist/lib/elur/component.cjs.map +0 -1
- package/dist/lib/elur/component.js.map +0 -1
- package/dist/lib/elur/hydrate/index.cjs.map +0 -1
- package/dist/lib/elur/hydrate/index.js.map +0 -1
- package/dist/lib/elur/reactivity.cjs.map +0 -1
- package/dist/lib/elur/reactivity.js.map +0 -1
- package/dist/lib/elur/template/dom-write.cjs +0 -2
- package/dist/lib/elur/template/dom-write.cjs.map +0 -1
- package/dist/lib/elur/template/dom-write.js +0 -16
- package/dist/lib/elur/template/dom-write.js.map +0 -1
- package/dist/lib/elur/template/keyed-diff.cjs +0 -2
- package/dist/lib/elur/template/keyed-diff.cjs.map +0 -1
- package/dist/lib/elur/template/keyed-diff.js +0 -100
- package/dist/lib/elur/template/keyed-diff.js.map +0 -1
- package/dist/lib/elur/template/mount-helpers.cjs +0 -2
- package/dist/lib/elur/template/mount-helpers.cjs.map +0 -1
- package/dist/lib/elur/template/mount-helpers.js +0 -132
- package/dist/lib/elur/template/mount-helpers.js.map +0 -1
- package/dist/lib/elur/template/node-binding.cjs +0 -2
- package/dist/lib/elur/template/node-binding.cjs.map +0 -1
- package/dist/lib/elur/template/node-binding.js +0 -95
- package/dist/lib/elur/template/node-binding.js.map +0 -1
|
@@ -1,29 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { _captureContextSnapshot } from "../context.js";
|
|
3
|
-
/**
|
|
4
|
-
* Renders a ElurComponent into the DOM and calls onMount immediately.
|
|
5
|
-
* Propagates errors through onError (or re-throws if not present).
|
|
6
|
-
* Returns a full cleanup function (onUnmount + mountCleanup + renderCleanup).
|
|
7
|
-
*/
|
|
8
|
-
export declare function _mountComponent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
9
|
-
/**
|
|
10
|
-
* Same as `_mountComponent` but silently swallows all lifecycle errors.
|
|
11
|
-
* Used for transition content and error boundary fallbacks where errors
|
|
12
|
-
* inside the fallback/transition itself must not propagate.
|
|
13
|
-
*/
|
|
14
|
-
export declare function _mountComponentSilent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
15
|
-
/**
|
|
16
|
-
* Renders a ElurComponent using a captured context snapshot.
|
|
17
|
-
* Used for dynamic/keyed rendering inside reactive effects, where the
|
|
18
|
-
* provide/inject context must be inherited from the point of declaration.
|
|
19
|
-
* Calls onMount immediately. Returns a full cleanup function.
|
|
20
|
-
*/
|
|
21
|
-
export declare function _mountComponentWithCtx(inst: ElurComponent, parent: Node, before: Node | null, ctxSnapshot: ReturnType<typeof _captureContextSnapshot>): () => void;
|
|
22
|
-
/**
|
|
23
|
-
* Renders a ElurComponent with *deferred* onMount — used inside `html` template
|
|
24
|
-
* fragments where the DOM nodes are still in a DocumentFragment and onMount must
|
|
25
|
-
* fire only after the fragment is inserted into the live document.
|
|
26
|
-
*
|
|
27
|
-
* Pushes the full cleanup into `disposes` and the onMount call into `postMountHooks`.
|
|
28
|
-
*/
|
|
29
|
-
export declare function _mountComponentDeferred(inst: ElurComponent, parent: Node, before: Node | null, postMountHooks: Array<() => void>, disposes: Array<() => void>): void;
|
|
1
|
+
export * from "../next-2/mount-helpers.js";
|
|
@@ -1,29 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { _captureContextSnapshot } from "../context.js";
|
|
3
|
-
/**
|
|
4
|
-
* Renders a ElurComponent into the DOM and calls onMount immediately.
|
|
5
|
-
* Propagates errors through onError (or re-throws if not present).
|
|
6
|
-
* Returns a full cleanup function (onUnmount + mountCleanup + renderCleanup).
|
|
7
|
-
*/
|
|
8
|
-
export declare function _mountComponent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
9
|
-
/**
|
|
10
|
-
* Same as `_mountComponent` but silently swallows all lifecycle errors.
|
|
11
|
-
* Used for transition content and error boundary fallbacks where errors
|
|
12
|
-
* inside the fallback/transition itself must not propagate.
|
|
13
|
-
*/
|
|
14
|
-
export declare function _mountComponentSilent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
15
|
-
/**
|
|
16
|
-
* Renders a ElurComponent using a captured context snapshot.
|
|
17
|
-
* Used for dynamic/keyed rendering inside reactive effects, where the
|
|
18
|
-
* provide/inject context must be inherited from the point of declaration.
|
|
19
|
-
* Calls onMount immediately. Returns a full cleanup function.
|
|
20
|
-
*/
|
|
21
|
-
export declare function _mountComponentWithCtx(inst: ElurComponent, parent: Node, before: Node | null, ctxSnapshot: ReturnType<typeof _captureContextSnapshot>): () => void;
|
|
22
|
-
/**
|
|
23
|
-
* Renders a ElurComponent with *deferred* onMount — used inside `html` template
|
|
24
|
-
* fragments where the DOM nodes are still in a DocumentFragment and onMount must
|
|
25
|
-
* fire only after the fragment is inserted into the live document.
|
|
26
|
-
*
|
|
27
|
-
* Pushes the full cleanup into `disposes` and the onMount call into `postMountHooks`.
|
|
28
|
-
*/
|
|
29
|
-
export declare function _mountComponentDeferred(inst: ElurComponent, parent: Node, before: Node | null, postMountHooks: Array<() => void>, disposes: Array<() => void>): void;
|
|
1
|
+
export * from "../next-2/mount-helpers.js";
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Activates a reactive node binding at `anchor`.
|
|
3
|
-
* Handles: text, ElurTemplate, ElurComponent, KeyedList, Array, and static values.
|
|
4
|
-
* Pushes dispose functions into `disposes`.
|
|
5
|
-
*/
|
|
6
|
-
export declare function activateNodeBinding(anchor: Text, value: unknown, disposes: Array<() => void>, postMountHooks: Array<() => void>): void;
|
|
1
|
+
export * from "../next-2/node-binding.js";
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Activates a reactive node binding at `anchor`.
|
|
3
|
-
* Handles: text, ElurTemplate, ElurComponent, KeyedList, Array, and static values.
|
|
4
|
-
* Pushes dispose functions into `disposes`.
|
|
5
|
-
*/
|
|
6
|
-
export declare function activateNodeBinding(anchor: Text, value: unknown, disposes: Array<() => void>, postMountHooks: Array<() => void>): void;
|
|
1
|
+
export * from "../next-2/node-binding.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../../lifecycle.cjs`),t=require(`../../context.cjs`),n=require(
|
|
1
|
+
const e=require(`../../lifecycle.cjs`),t=require(`../../context.cjs`),n=require(`../next-2/mount-helpers.cjs`);function r(){return{__isPortalOutlet:!0,_container:null}}function i(e){return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(t,n){let r=document.createElement(`div`);return r.setAttribute(`data-elur-outlet`,``),e._container=r,t.insertBefore(r,n),()=>{e._container=null,r.remove()}}}}function a(t,r=document.body){return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(i,a){let o;return o=typeof r==`string`?document.querySelector(r)??document.body:r instanceof Element?r:`__isPortalOutlet`in r?r._container??document.body:r.el??document.body,e.isElurComponent(t)?n._mountComponent(t,o,null):t._render(o,null)}}}var o=t.createInjectionKey(`elur:portal-outlet`);function s(e){t.provide(o,e)}function c(){return t.inject(o)}exports.createPortalOutlet=r,exports.injectOutlet=c,exports.portal=a,exports.portalOutlet=i,exports.provideOutlet=s;
|
|
2
2
|
//# sourceMappingURL=portal.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.cjs","names":[],"sources":["../../../../src/elur/template/portal.ts"],"sourcesContent":["import { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport { provide, inject, createInjectionKey } from \"../context.js\";\nimport type { ElurTemplate, ElurMountHandle, ElurRef, PortalOutlet } from \"./types.js\";\nimport { _mountComponent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- PortalOutlet ---\n// =============================================================================\n\n/** Creates a PortalOutlet token for decoupled portal targeting. */\nexport function createPortalOutlet(): PortalOutlet {\n return { __isPortalOutlet: true as const, _container: null };\n}\n\n/** Declares the DOM anchor for a PortalOutlet inside a template. */\nexport function portalOutlet(outlet: PortalOutlet): ElurTemplate {\n return {\n __isElurTemplate: true as const,\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n _render(parent: Node, before: Node | null): () => void {\n const el = document.createElement(\"div\");\n el.setAttribute(\"data-elur-outlet\", \"\");\n outlet._container = el;\n parent.insertBefore(el, before);\n return () => {\n outlet._container = null;\n el.remove();\n };\n },\n };\n}\n\n// =============================================================================\n// --- portal() ---\n// =============================================================================\n\n/**\n * Renders `content` into `target` instead of the current tree position.\n * Useful for modals, tooltips, and overlays that must escape overflow clipping.\n * Returns a ElurTemplate — works inside reactive conditionals.\n *\n * @param content Template or component to render.\n * @param target CSS selector, Element, PortalOutlet, or ElurRef. Defaults to `document.body`.\n */\nexport function portal(\n content: ElurTemplate | ElurComponent,\n target: Element | string | PortalOutlet | ElurRef<Element> = document.body\n): ElurTemplate {\n return {\n __isElurTemplate: true as const,\n\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n\n _render(_parent: Node, _before: Node | null): () => void {\n let targetEl: Element;\n if (typeof target === \"string\") {\n targetEl = document.querySelector(target) ?? document.body;\n } else if (target instanceof Element) {\n targetEl = target;\n } else if (\"__isPortalOutlet\" in target) {\n targetEl = (target as PortalOutlet)._container ?? document.body;\n } else {\n targetEl = (target as ElurRef<Element>).el ?? document.body;\n }\n\n if (isElurComponent(content)) {\n return _mountComponent(content, targetEl, null);\n }\n\n return content._render(targetEl, null);\n },\n };\n}\n\n// =============================================================================\n// --- Portal outlet via provide/inject ---\n// =============================================================================\n\nconst _OUTLET_KEY = createInjectionKey<PortalOutlet>(\"elur:portal-outlet\");\n\n/** Provides a PortalOutlet to descendant components via dependency injection. */\nexport function provideOutlet(outlet: PortalOutlet): void {\n provide(_OUTLET_KEY, outlet);\n}\n\n/** Injects the nearest PortalOutlet provided by an ancestor. */\nexport function injectOutlet(): PortalOutlet | undefined {\n return inject(_OUTLET_KEY);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"portal.cjs","names":[],"sources":["../../../../src/elur/template/portal.ts"],"sourcesContent":["import { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport { provide, inject, createInjectionKey } from \"../context.js\";\nimport type { ElurTemplate, ElurMountHandle, ElurRef, PortalOutlet } from \"./types.js\";\nimport { _mountComponent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- PortalOutlet ---\n// =============================================================================\n\n/** Creates a PortalOutlet token for decoupled portal targeting. */\nexport function createPortalOutlet(): PortalOutlet {\n return { __isPortalOutlet: true as const, _container: null };\n}\n\n/** Declares the DOM anchor for a PortalOutlet inside a template. */\nexport function portalOutlet(outlet: PortalOutlet): ElurTemplate {\n return {\n __isElurTemplate: true as const,\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n _render(parent: Node, before: Node | null): () => void {\n const el = document.createElement(\"div\");\n el.setAttribute(\"data-elur-outlet\", \"\");\n outlet._container = el;\n parent.insertBefore(el, before);\n return () => {\n outlet._container = null;\n el.remove();\n };\n },\n };\n}\n\n// =============================================================================\n// --- portal() ---\n// =============================================================================\n\n/**\n * Renders `content` into `target` instead of the current tree position.\n * Useful for modals, tooltips, and overlays that must escape overflow clipping.\n * Returns a ElurTemplate — works inside reactive conditionals.\n *\n * @param content Template or component to render.\n * @param target CSS selector, Element, PortalOutlet, or ElurRef. Defaults to `document.body`.\n */\nexport function portal(\n content: ElurTemplate | ElurComponent,\n target: Element | string | PortalOutlet | ElurRef<Element> = document.body\n): ElurTemplate {\n return {\n __isElurTemplate: true as const,\n\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n\n _render(_parent: Node, _before: Node | null): () => void {\n let targetEl: Element;\n if (typeof target === \"string\") {\n targetEl = document.querySelector(target) ?? document.body;\n } else if (target instanceof Element) {\n targetEl = target;\n } else if (\"__isPortalOutlet\" in target) {\n targetEl = (target as PortalOutlet)._container ?? document.body;\n } else {\n targetEl = (target as ElurRef<Element>).el ?? document.body;\n }\n\n if (isElurComponent(content)) {\n return _mountComponent(content, targetEl, null);\n }\n\n return content._render(targetEl, null);\n },\n };\n}\n\n// =============================================================================\n// --- Portal outlet via provide/inject ---\n// =============================================================================\n\nconst _OUTLET_KEY = createInjectionKey<PortalOutlet>(\"elur:portal-outlet\");\n\n/** Provides a PortalOutlet to descendant components via dependency injection. */\nexport function provideOutlet(outlet: PortalOutlet): void {\n provide(_OUTLET_KEY, outlet);\n}\n\n/** Injects the nearest PortalOutlet provided by an ancestor. */\nexport function injectOutlet(): PortalOutlet | undefined {\n return inject(_OUTLET_KEY);\n}\n"],"mappings":"+GAWA,SAAgB,GAAmC,CAC/C,MAAO,CAAE,iBAAkB,GAAe,WAAY,KAAM,CAIhE,SAAgB,EAAa,EAAoC,CAC7D,MAAO,CACH,iBAAkB,GAClB,MAAM,EAA8C,CAChD,IAAM,EACF,OAAO,GAAc,SACd,SAAS,cAAc,EAAU,EAAI,SAAS,KAC/C,EAEV,MAAO,CAAE,QADO,KAAK,QAAQ,EAAI,KAAK,CACX,EAE/B,QAAQ,EAAc,EAAiC,CACnD,IAAM,EAAK,SAAS,cAAc,MAAM,CAIxC,OAHA,EAAG,aAAa,mBAAoB,GAAG,CACvC,EAAO,WAAa,EACpB,EAAO,aAAa,EAAI,EAAO,KAClB,CACT,EAAO,WAAa,KACpB,EAAG,QAAQ,GAGtB,CAeL,SAAgB,EACZ,EACA,EAA6D,SAAS,KAC1D,CACZ,MAAO,CACH,iBAAkB,GAElB,MAAM,EAA8C,CAChD,IAAM,EACF,OAAO,GAAc,SACd,SAAS,cAAc,EAAU,EAAI,SAAS,KAC/C,EAEV,MAAO,CAAE,QADO,KAAK,QAAQ,EAAI,KAAK,CACX,EAG/B,QAAQ,EAAe,EAAkC,CACrD,IAAI,EAeJ,MAdA,CAOI,EAPA,OAAO,GAAW,SACP,SAAS,cAAc,EAAO,EAAI,SAAS,KAC/C,aAAkB,QACd,EACJ,qBAAsB,EACjB,EAAwB,YAAc,SAAS,KAE/C,EAA4B,IAAM,SAAS,KAGvD,EAAA,gBAAgB,EAAQ,CACjB,EAAA,gBAAgB,EAAS,EAAU,KAAK,CAG5C,EAAQ,QAAQ,EAAU,KAAK,EAE7C,CAOL,IAAM,EAAc,EAAA,mBAAiC,qBAAqB,CAG1E,SAAgB,EAAc,EAA4B,CACtD,EAAA,QAAQ,EAAa,EAAO,CAIhC,SAAgB,GAAyC,CACrD,OAAO,EAAA,OAAO,EAAY"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isElurComponent as e } from "../../lifecycle.js";
|
|
2
2
|
import { createInjectionKey as t, inject as n, provide as r } from "../../context.js";
|
|
3
|
-
import { _mountComponent as i } from "
|
|
3
|
+
import { _mountComponent as i } from "../next-2/mount-helpers.js";
|
|
4
4
|
//#region src/elur/template/portal.ts
|
|
5
5
|
function a() {
|
|
6
6
|
return {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(
|
|
1
|
+
const e=require(`../next-2/reactivity.cjs`),t=require(`./types.cjs`),n=require(`../../lifecycle.cjs`),r=require(`../next-2/mount-helpers.cjs`);function i(e){let t=e.name??`elur`;return{enterFrom:e.enterFrom??`${t}-enter-from`,enterActive:e.enterActive??`${t}-enter-active`,enterTo:e.enterTo??`${t}-enter-to`,leaveFrom:e.leaveFrom??`${t}-leave-from`,leaveActive:e.leaveActive??`${t}-leave-active`,leaveTo:e.leaveTo??`${t}-leave-to`}}function a(e){return Math.max(0,...e.split(`,`).map(e=>parseFloat(e.trim())||0))}function o(e,t=0){return new Promise(n=>{let r=getComputedStyle(e),i=Math.max(a(r.transitionDuration||`0`),a(r.animationDuration||`0`))*1e3,o=i>0?i+100:t;if(o<=0){n();return}let s,c=t=>{t.target===e&&(clearTimeout(s),e.removeEventListener(`transitionend`,c),e.removeEventListener(`animationend`,c),n())};e.addEventListener(`transitionend`,c),e.addEventListener(`animationend`,c),s=setTimeout(()=>{e.removeEventListener(`transitionend`,c),e.removeEventListener(`animationend`,c),n()},o)})}function s(a,s={}){let c=i(s);return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(i,l){let u=document.createComment(t.COMMENT.TRANSITION);i.insertBefore(u,l);let d=null,f=null,p=0,m=!0,h=()=>{let e=u.nextSibling;for(;e&&e!==l;){if(e.nodeType===Node.ELEMENT_NODE)return e;e=e.nextSibling}return null};function g(e){return n.isElurComponent(e)?r._mountComponentSilent(e,i,l):e._render(i,l)}let _=(e,t=!1)=>{p++,f&&=(f(),null),d=g(e);let n=h();if(n&&(!m||s.appear)&&!t){let e=p;(async()=>{s.onBeforeEnter?.(n),n.classList.add(c.enterFrom,c.enterActive),n.getBoundingClientRect(),await new Promise(e=>requestAnimationFrame(()=>e())),p===e&&(n.classList.remove(c.enterFrom),n.classList.add(c.enterTo),await o(n,s.duration),p===e&&(n.classList.remove(c.enterActive,c.enterTo),s.onAfterEnter?.(n)))})().catch(()=>{})}m=!1},v=()=>{let e=d;d=null;let t=h();if(!t){e?.();return}let n=++p;f=e??null,(async()=>{s.onBeforeLeave?.(t),t.classList.add(c.leaveFrom,c.leaveActive),t.getBoundingClientRect(),await new Promise(e=>requestAnimationFrame(()=>e())),p===n&&(t.classList.remove(c.leaveFrom),t.classList.add(c.leaveTo),await o(t,s.duration),p===n&&(t.classList.remove(c.leaveActive,c.leaveTo),s.onAfterLeave?.(t),f?.(),f=null))})().catch(()=>{})},y=null;if(typeof a==`function`&&!n.isElurComponent(a)){let t=a,n=null;y=e.effect(()=>{let e=t(),r=n===null,i=e===null;r&&!i?_(e):!r&&i?v():!r&&!i&&(p++,f?.(),f=null,d?.(),d=null,_(e,!0)),n=e}),m=!1}else _(a);return()=>{p++,y?.(),d?.(),f?.(),d=null,f=null,u.remove()}}}}exports.transition=s;
|
|
2
2
|
//# sourceMappingURL=transitions.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transitions.cjs","names":[],"sources":["../../../../src/elur/template/transitions.ts"],"sourcesContent":["import { effect } from \"../reactivity.js\";\nimport { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport type { ElurTemplate, ElurMountHandle, TransitionContent } from \"./types.js\";\nimport { COMMENT } from \"./types.js\";\nimport { _mountComponentSilent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- TransitionOptions ---\n// =============================================================================\n\n/**\n * Options for `transition()`. All class-name overrides are optional — by\n * default they are derived from `name` (default `\"elur\"`).\n *\n * | phase | from class | active class | to class |\n * |--------------|-------------------|---------------------|-----------------|\n * | enter | `{n}-enter-from` | `{n}-enter-active` | `{n}-enter-to` |\n * | leave | `{n}-leave-from` | `{n}-leave-active` | `{n}-leave-to` |\n */\nexport interface TransitionOptions {\n /**\n * Prefix for all generated CSS classes. Default `\"elur\"`.\n * e.g. `name: \"fade\"` generates `.fade-enter-from`, `.fade-leave-to`, …\n */\n name?: string;\n enterFrom?: string;\n enterActive?: string;\n enterTo?: string;\n leaveFrom?: string;\n leaveActive?: string;\n leaveTo?: string;\n /**\n * When `true` the enter transition also plays on the very first render\n * (similar to Vue's `appear`). Default `false`.\n */\n appear?: boolean;\n /**\n * Fallback duration in **milliseconds** used when no `transition-duration`\n * or `animation-duration` is found on the element via `getComputedStyle`.\n */\n duration?: number;\n onBeforeEnter?: (el: Element) => void;\n onAfterEnter?: (el: Element) => void;\n onBeforeLeave?: (el: Element) => void;\n onAfterLeave?: (el: Element) => void;\n}\n\n// =============================================================================\n// --- Internal transition helpers ---\n// =============================================================================\n\nfunction _resolveTransitionClasses(opts: TransitionOptions) {\n const n = opts.name ?? \"elur\";\n return {\n enterFrom: opts.enterFrom ?? `${n}-enter-from`,\n enterActive: opts.enterActive ?? `${n}-enter-active`,\n enterTo: opts.enterTo ?? `${n}-enter-to`,\n leaveFrom: opts.leaveFrom ?? `${n}-leave-from`,\n leaveActive: opts.leaveActive ?? `${n}-leave-active`,\n leaveTo: opts.leaveTo ?? `${n}-leave-to`,\n };\n}\n\nfunction _cssMaxDuration(cssValue: string): number {\n return Math.max(0, ...cssValue.split(\",\").map((s) => parseFloat(s.trim()) || 0));\n}\n\nfunction _waitTransitionEnd(el: Element, fallbackMs = 0): Promise<void> {\n return new Promise((resolve) => {\n const st = getComputedStyle(el);\n const ms =\n Math.max(\n _cssMaxDuration(st.transitionDuration || \"0\"),\n _cssMaxDuration(st.animationDuration || \"0\"),\n ) * 1000;\n const wait = ms > 0 ? ms + 100 : fallbackMs;\n\n if (wait <= 0) { resolve(); return; }\n\n let timerId: ReturnType<typeof setTimeout>;\n const done = (e: Event) => {\n if (e.target !== el) return;\n clearTimeout(timerId);\n el.removeEventListener(\"transitionend\", done);\n el.removeEventListener(\"animationend\", done);\n resolve();\n };\n el.addEventListener(\"transitionend\", done);\n el.addEventListener(\"animationend\", done);\n timerId = setTimeout(() => {\n el.removeEventListener(\"transitionend\", done);\n el.removeEventListener(\"animationend\", done);\n resolve();\n }, wait);\n });\n}\n\n// =============================================================================\n// --- transition() ---\n// =============================================================================\n\n/**\n * Wraps content with CSS class-based enter/leave transitions.\n * Static content plays enter on mount (only with `appear: true`).\n * Reactive `() => Template | null` auto-animates enter/leave on toggle.\n */\nexport function transition(\n content: TransitionContent,\n options: TransitionOptions = {},\n): ElurTemplate {\n const cls = _resolveTransitionClasses(options);\n\n return {\n __isElurTemplate: true as const,\n\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n\n _render(parent: Node, before: Node | null): () => void {\n const marker = document.createComment(COMMENT.TRANSITION);\n parent.insertBefore(marker, before);\n\n let contentCleanup: (() => void) | null = null;\n let leaveCleanup: (() => void) | null = null;\n let leaveGen = 0;\n let isFirstRender = true;\n\n /** Find first Element node between `marker` and `before`. */\n const getEl = (): Element | null => {\n let node: Node | null = marker.nextSibling;\n while (node && node !== before) {\n if (node.nodeType === Node.ELEMENT_NODE) return node as Element;\n node = node.nextSibling;\n }\n return null;\n };\n\n function mountContent(tpl: ElurTemplate | ElurComponent): () => void {\n if (isElurComponent(tpl)) {\n return _mountComponentSilent(tpl as ElurComponent, parent, before);\n }\n return (tpl as ElurTemplate)._render(parent, before);\n }\n\n /** Mount content and play enter animation (does NOT block). */\n const doEnter = (tpl: ElurTemplate | ElurComponent, skipAnim = false): void => {\n leaveGen++;\n if (leaveCleanup) {\n leaveCleanup();\n leaveCleanup = null;\n }\n\n contentCleanup = mountContent(tpl);\n\n const el = getEl();\n const shouldAnimate = el && (!isFirstRender || options.appear) && !skipAnim;\n if (shouldAnimate) {\n const gen = leaveGen;\n const doIt = async () => {\n options.onBeforeEnter?.(el);\n el.classList.add(cls.enterFrom, cls.enterActive);\n void el.getBoundingClientRect();\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n if (leaveGen !== gen) return;\n el.classList.remove(cls.enterFrom);\n el.classList.add(cls.enterTo);\n await _waitTransitionEnd(el, options.duration);\n if (leaveGen !== gen) return;\n el.classList.remove(cls.enterActive, cls.enterTo);\n options.onAfterEnter?.(el);\n };\n doIt().catch(() => { /* ignore */ });\n }\n isFirstRender = false;\n };\n\n /** Remove current content after playing leave animation (does NOT block). */\n const doLeave = (): void => {\n const savedCleanup = contentCleanup;\n contentCleanup = null;\n const el = getEl();\n\n if (!el) { savedCleanup?.(); return; }\n\n const gen = ++leaveGen;\n leaveCleanup = savedCleanup ?? null;\n\n const doIt = async () => {\n options.onBeforeLeave?.(el);\n el.classList.add(cls.leaveFrom, cls.leaveActive);\n void el.getBoundingClientRect();\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n if (leaveGen !== gen) return;\n el.classList.remove(cls.leaveFrom);\n el.classList.add(cls.leaveTo);\n await _waitTransitionEnd(el, options.duration);\n if (leaveGen !== gen) return;\n el.classList.remove(cls.leaveActive, cls.leaveTo);\n options.onAfterLeave?.(el);\n leaveCleanup?.();\n leaveCleanup = null;\n };\n doIt().catch(() => { /* ignore */ });\n };\n\n let disposeWatcher: (() => void) | null = null;\n\n if (typeof content === \"function\" && !isElurComponent(content as unknown)) {\n const getter = content as () => ElurTemplate | ElurComponent | null;\n let prevVal: ElurTemplate | ElurComponent | null = null;\n\n disposeWatcher = effect(() => {\n const val = getter();\n const wasNull = prevVal === null;\n const isNull = val === null;\n\n if (wasNull && !isNull) {\n doEnter(val!);\n } else if (!wasNull && isNull) {\n doLeave();\n } else if (!wasNull && !isNull) {\n leaveGen++;\n leaveCleanup?.();\n leaveCleanup = null;\n contentCleanup?.();\n contentCleanup = null;\n doEnter(val!, true);\n }\n prevVal = val;\n });\n isFirstRender = false;\n } else {\n doEnter(content as ElurTemplate | ElurComponent);\n }\n\n return () => {\n leaveGen++;\n disposeWatcher?.();\n contentCleanup?.();\n leaveCleanup?.();\n contentCleanup = null;\n leaveCleanup = null;\n marker.remove();\n };\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transitions.cjs","names":[],"sources":["../../../../src/elur/template/transitions.ts"],"sourcesContent":["import { effect } from \"../reactivity.js\";\nimport { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport type { ElurTemplate, ElurMountHandle, TransitionContent } from \"./types.js\";\nimport { COMMENT } from \"./types.js\";\nimport { _mountComponentSilent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- TransitionOptions ---\n// =============================================================================\n\n/**\n * Options for `transition()`. All class-name overrides are optional — by\n * default they are derived from `name` (default `\"elur\"`).\n *\n * | phase | from class | active class | to class |\n * |--------------|-------------------|---------------------|-----------------|\n * | enter | `{n}-enter-from` | `{n}-enter-active` | `{n}-enter-to` |\n * | leave | `{n}-leave-from` | `{n}-leave-active` | `{n}-leave-to` |\n */\nexport interface TransitionOptions {\n /**\n * Prefix for all generated CSS classes. Default `\"elur\"`.\n * e.g. `name: \"fade\"` generates `.fade-enter-from`, `.fade-leave-to`, …\n */\n name?: string;\n enterFrom?: string;\n enterActive?: string;\n enterTo?: string;\n leaveFrom?: string;\n leaveActive?: string;\n leaveTo?: string;\n /**\n * When `true` the enter transition also plays on the very first render\n * (similar to Vue's `appear`). Default `false`.\n */\n appear?: boolean;\n /**\n * Fallback duration in **milliseconds** used when no `transition-duration`\n * or `animation-duration` is found on the element via `getComputedStyle`.\n */\n duration?: number;\n onBeforeEnter?: (el: Element) => void;\n onAfterEnter?: (el: Element) => void;\n onBeforeLeave?: (el: Element) => void;\n onAfterLeave?: (el: Element) => void;\n}\n\n// =============================================================================\n// --- Internal transition helpers ---\n// =============================================================================\n\nfunction _resolveTransitionClasses(opts: TransitionOptions) {\n const n = opts.name ?? \"elur\";\n return {\n enterFrom: opts.enterFrom ?? `${n}-enter-from`,\n enterActive: opts.enterActive ?? `${n}-enter-active`,\n enterTo: opts.enterTo ?? `${n}-enter-to`,\n leaveFrom: opts.leaveFrom ?? `${n}-leave-from`,\n leaveActive: opts.leaveActive ?? `${n}-leave-active`,\n leaveTo: opts.leaveTo ?? `${n}-leave-to`,\n };\n}\n\nfunction _cssMaxDuration(cssValue: string): number {\n return Math.max(0, ...cssValue.split(\",\").map((s) => parseFloat(s.trim()) || 0));\n}\n\nfunction _waitTransitionEnd(el: Element, fallbackMs = 0): Promise<void> {\n return new Promise((resolve) => {\n const st = getComputedStyle(el);\n const ms =\n Math.max(\n _cssMaxDuration(st.transitionDuration || \"0\"),\n _cssMaxDuration(st.animationDuration || \"0\"),\n ) * 1000;\n const wait = ms > 0 ? ms + 100 : fallbackMs;\n\n if (wait <= 0) { resolve(); return; }\n\n let timerId: ReturnType<typeof setTimeout>;\n const done = (e: Event) => {\n if (e.target !== el) return;\n clearTimeout(timerId);\n el.removeEventListener(\"transitionend\", done);\n el.removeEventListener(\"animationend\", done);\n resolve();\n };\n el.addEventListener(\"transitionend\", done);\n el.addEventListener(\"animationend\", done);\n timerId = setTimeout(() => {\n el.removeEventListener(\"transitionend\", done);\n el.removeEventListener(\"animationend\", done);\n resolve();\n }, wait);\n });\n}\n\n// =============================================================================\n// --- transition() ---\n// =============================================================================\n\n/**\n * Wraps content with CSS class-based enter/leave transitions.\n * Static content plays enter on mount (only with `appear: true`).\n * Reactive `() => Template | null` auto-animates enter/leave on toggle.\n */\nexport function transition(\n content: TransitionContent,\n options: TransitionOptions = {},\n): ElurTemplate {\n const cls = _resolveTransitionClasses(options);\n\n return {\n __isElurTemplate: true as const,\n\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n\n _render(parent: Node, before: Node | null): () => void {\n const marker = document.createComment(COMMENT.TRANSITION);\n parent.insertBefore(marker, before);\n\n let contentCleanup: (() => void) | null = null;\n let leaveCleanup: (() => void) | null = null;\n let leaveGen = 0;\n let isFirstRender = true;\n\n /** Find first Element node between `marker` and `before`. */\n const getEl = (): Element | null => {\n let node: Node | null = marker.nextSibling;\n while (node && node !== before) {\n if (node.nodeType === Node.ELEMENT_NODE) return node as Element;\n node = node.nextSibling;\n }\n return null;\n };\n\n function mountContent(tpl: ElurTemplate | ElurComponent): () => void {\n if (isElurComponent(tpl)) {\n return _mountComponentSilent(tpl as ElurComponent, parent, before);\n }\n return (tpl as ElurTemplate)._render(parent, before);\n }\n\n /** Mount content and play enter animation (does NOT block). */\n const doEnter = (tpl: ElurTemplate | ElurComponent, skipAnim = false): void => {\n leaveGen++;\n if (leaveCleanup) {\n leaveCleanup();\n leaveCleanup = null;\n }\n\n contentCleanup = mountContent(tpl);\n\n const el = getEl();\n const shouldAnimate = el && (!isFirstRender || options.appear) && !skipAnim;\n if (shouldAnimate) {\n const gen = leaveGen;\n const doIt = async () => {\n options.onBeforeEnter?.(el);\n el.classList.add(cls.enterFrom, cls.enterActive);\n void el.getBoundingClientRect();\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n if (leaveGen !== gen) return;\n el.classList.remove(cls.enterFrom);\n el.classList.add(cls.enterTo);\n await _waitTransitionEnd(el, options.duration);\n if (leaveGen !== gen) return;\n el.classList.remove(cls.enterActive, cls.enterTo);\n options.onAfterEnter?.(el);\n };\n doIt().catch(() => { /* ignore */ });\n }\n isFirstRender = false;\n };\n\n /** Remove current content after playing leave animation (does NOT block). */\n const doLeave = (): void => {\n const savedCleanup = contentCleanup;\n contentCleanup = null;\n const el = getEl();\n\n if (!el) { savedCleanup?.(); return; }\n\n const gen = ++leaveGen;\n leaveCleanup = savedCleanup ?? null;\n\n const doIt = async () => {\n options.onBeforeLeave?.(el);\n el.classList.add(cls.leaveFrom, cls.leaveActive);\n void el.getBoundingClientRect();\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n if (leaveGen !== gen) return;\n el.classList.remove(cls.leaveFrom);\n el.classList.add(cls.leaveTo);\n await _waitTransitionEnd(el, options.duration);\n if (leaveGen !== gen) return;\n el.classList.remove(cls.leaveActive, cls.leaveTo);\n options.onAfterLeave?.(el);\n leaveCleanup?.();\n leaveCleanup = null;\n };\n doIt().catch(() => { /* ignore */ });\n };\n\n let disposeWatcher: (() => void) | null = null;\n\n if (typeof content === \"function\" && !isElurComponent(content as unknown)) {\n const getter = content as () => ElurTemplate | ElurComponent | null;\n let prevVal: ElurTemplate | ElurComponent | null = null;\n\n disposeWatcher = effect(() => {\n const val = getter();\n const wasNull = prevVal === null;\n const isNull = val === null;\n\n if (wasNull && !isNull) {\n doEnter(val!);\n } else if (!wasNull && isNull) {\n doLeave();\n } else if (!wasNull && !isNull) {\n leaveGen++;\n leaveCleanup?.();\n leaveCleanup = null;\n contentCleanup?.();\n contentCleanup = null;\n doEnter(val!, true);\n }\n prevVal = val;\n });\n isFirstRender = false;\n } else {\n doEnter(content as ElurTemplate | ElurComponent);\n }\n\n return () => {\n leaveGen++;\n disposeWatcher?.();\n contentCleanup?.();\n leaveCleanup?.();\n contentCleanup = null;\n leaveCleanup = null;\n marker.remove();\n };\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { effect as e } from "
|
|
1
|
+
import { effect as e } from "../next-2/reactivity.js";
|
|
2
2
|
import { COMMENT as t } from "./types.js";
|
|
3
3
|
import { isElurComponent as n } from "../../lifecycle.js";
|
|
4
|
-
import { _mountComponentSilent as r } from "
|
|
4
|
+
import { _mountComponentSilent as r } from "../next-2/mount-helpers.js";
|
|
5
5
|
//#region src/elur/template/transitions.ts
|
|
6
6
|
function i(e) {
|
|
7
7
|
let t = e.name ?? "elur";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=Symbol.for(`@elurjs/core/template-descriptor`),t=Symbol.for(`@elurjs/core/render-protocol`),n={partialAttributeInterpolation:!1};function r(){return{el:null}}var i={SCOPE:`elur-scope`,ERROR_BOUNDARY:`elur-eb`,TRANSITION:`elur-t`,KEYED_START:`elur-ks`,KEYED_END:`elur-ke`,KEYED_ZONE:`elur-kz`};function a(e){return typeof e==`object`&&!!e&&e.__isElurTemplate===!0}function o(e){return typeof e==`object`&&!!e&&e.__isKeyedList===!0}exports.COMMENT=i,exports.ELUR_RENDER_PROTOCOL=t,exports.ELUR_TEMPLATE_DESCRIPTOR=e,exports.isElurTemplate=a,exports.isKeyedList=o,exports.ref=r,exports.templateFeatures=n;
|
|
1
|
+
var e=Symbol.for(`@elurjs/core/template-descriptor`),t=Symbol.for(`@elurjs/core/render-protocol`),n={partialAttributeInterpolation:!1};function r(){return{el:null}}var i={SCOPE:`elur-scope`,ERROR_BOUNDARY:`elur-eb`,TRANSITION:`elur-t`,KEYED_START:`elur-ks`,KEYED_END:`elur-ke`,KEYED_ZONE:`elur-kz`};function a(e){return typeof e==`object`&&!!e&&e.__isElurTemplate===!0}function o(e){return typeof e==`object`&&!!e&&e.__isKeyedList===!0}var s=Symbol.for(`elur.derived`);function c(e){return typeof e==`object`&&!!e&&e[s]===!0}exports.COMMENT=i,exports.ELUR_RENDER_PROTOCOL=t,exports.ELUR_TEMPLATE_DESCRIPTOR=e,exports.isDerivedBinding=c,exports.isElurTemplate=a,exports.isKeyedList=o,exports.ref=r,exports.templateFeatures=n;
|
|
2
2
|
//# sourceMappingURL=types.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs","names":[],"sources":["../../../../src/elur/template/types.ts"],"sourcesContent":["// =============================================================================\n// --- Public types ---\n// =============================================================================\n\nexport type TemplateBindingContext =\n | { type: \"node\" }\n | { type: \"event\"; eventName: string; modifiers: string[]; hadOpenQuote: boolean }\n | { type: \"attr\"; attrName: string; hadOpenQuote: boolean; url?: boolean; executable?: boolean };\n\nexport interface TemplateDescriptor {\n readonly version: 1;\n readonly strings: readonly string[];\n readonly values: readonly unknown[];\n readonly contexts: readonly TemplateBindingContext[];\n}\n\nexport interface ServerRenderProtocolContext {\n readonly markers: boolean;\n readonly signal?: AbortSignal;\n readonly context?: unknown;\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n}\n\n/** Context passed to a custom value's `mountDom` protocol during client-side mount. */\nexport interface DomProtocolContext {\n readonly parent: Node;\n readonly before: Node | null;\n readonly context?: unknown;\n}\n\n/** Context passed to a custom value's `hydrateDom` protocol during hydration. */\nexport interface HydrationProtocolContext {\n readonly parent: Node;\n readonly bounds: { start: Comment; end: Comment } | null;\n readonly context?: unknown;\n /** Remounts a value inside the current bounds (used as fallback). */\n render(value: unknown): unknown;\n}\n\nexport interface ElurRenderProtocol {\n renderServer?(context: ServerRenderProtocolContext): string | Promise<string>;\n mountDom?(context: DomProtocolContext): (() => void) | void;\n hydrateDom?(context: HydrationProtocolContext): (() => void) | void;\n}\n\nexport const ELUR_TEMPLATE_DESCRIPTOR = Symbol.for(\"@elurjs/core/template-descriptor\");\nexport const ELUR_RENDER_PROTOCOL = Symbol.for(\"@elurjs/core/render-protocol\");\n\n/**\n * Runtime feature capabilities, for tooling to detect support without\n * inferring it from version strings.\n *\n * NOTE: Partial attribute interpolation is now handled at compile time by\n * @elurjs/vite-plugin-elur. The core runtime does not support it natively.\n * Use the Vite plugin for partial interpolation support.\n */\nexport const templateFeatures = {\n /** Partial attribute interpolation (`class=\"btn ${size}\"`) is supported. */\n partialAttributeInterpolation: false,\n} as const;\n\nexport interface ElurTemplate {\n readonly __isElurTemplate: true;\n readonly [ELUR_TEMPLATE_DESCRIPTOR]?: TemplateDescriptor;\n readonly [ELUR_RENDER_PROTOCOL]?: ElurRenderProtocol;\n /** Mounts the template into a container element (public / root API). */\n mount(container: Element | string): ElurMountHandle;\n /** @internal Renders before `before` node (or appends to `parent`). Returns cleanup. */\n _render(parent: Node, before: Node | null): () => void;\n}\n\nexport interface ElurMountHandle {\n unmount(): void;\n}\n\n/** Direct reference to a DOM element, assigned on mount and cleared on unmount. */\nexport interface ElurRef<T extends Element = Element> {\n el: T | null;\n}\n\n/** Creates an empty `ElurRef`. Use as `ref` attribute value in templates. */\nexport function ref<T extends Element = Element>(): ElurRef<T> {\n return { el: null };\n}\n\n/** Keyed list result for efficient DOM diffing via `repeat()`. */\nexport interface KeyedList<T = unknown> {\n readonly __isKeyedList: true;\n readonly items: T[];\n readonly keyFn: (item: T, index: number) => string | number;\n readonly renderFn: (item: T, index: number) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent;\n}\n\nexport interface KEntry {\n start: Comment;\n end: Comment;\n cleanup: () => void;\n}\n\n/** Opaque token for a named portal target. */\nexport interface PortalOutlet {\n readonly __isPortalOutlet: true;\n /** @internal */\n _container: Element | null;\n}\n\n/** Fallback: a static template/component, or a factory receiving the error. */\nexport type ErrorFallback =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | ((err: unknown) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent);\n\n/** Content that can be wrapped with `transition()`. */\nexport type TransitionContent =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | (() => ElurTemplate | import(\"../lifecycle.js\").ElurComponent | null);\n\nexport const COMMENT = {\n SCOPE: \"elur-scope\",\n ERROR_BOUNDARY: \"elur-eb\",\n TRANSITION: \"elur-t\",\n KEYED_START: \"elur-ks\",\n KEYED_END: \"elur-ke\",\n KEYED_ZONE: \"elur-kz\",\n} as const;\n\n// =============================================================================\n// --- DOM inspection helpers ---\n// =============================================================================\n\nexport function isElurTemplate(v: unknown): v is ElurTemplate {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isElurTemplate === true\n );\n}\n\nexport function isKeyedList(v: unknown): v is KeyedList {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isKeyedList === true\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.cjs","names":[],"sources":["../../../../src/elur/template/types.ts"],"sourcesContent":["// =============================================================================\n// --- Public types ---\n// =============================================================================\n\nexport type TemplateBindingContext =\n | { type: \"node\" }\n | { type: \"event\"; eventName: string; modifiers: string[]; hadOpenQuote: boolean }\n | { type: \"attr\"; attrName: string; hadOpenQuote: boolean; url?: boolean; executable?: boolean };\n\nexport interface TemplateDescriptor {\n readonly version: 1;\n readonly strings: readonly string[];\n readonly values: readonly unknown[];\n readonly contexts: readonly TemplateBindingContext[];\n /**\n * C.13: hidratación compilada — el codegen emite una función que activa\n * los bindings por posición (access paths) en vez de un scan global de\n * markers. Sólo los boundaries de contenido dinámico (`<!--elur-N-->`)\n * siguen marcados en el HTML; `data-elur-*` no se emiten.\n * `bounds` se pasa cuando el descriptor es anidado dentro de otro\n * binding. Devuelve cleanup.\n */\n readonly hydrate?: (\n root: ParentNode,\n values: readonly unknown[],\n options?: unknown,\n bounds?: { start: Comment; end: Comment } | null,\n ) => (() => void) | void;\n /**\n * C.12 fase 2: renderer SSR especializado — el codegen emite una función\n * generadora que secuencia los chunks con los strings ya cortados\n * (`attr=`/comillas pre-resueltos en build). Toda la semántica\n * (resolución de valores, sanitización, markers, abort) sigue en los\n * helpers `emit.*` del core — el artefacto compilado y el descriptor\n * genérico producen exactamente el mismo HTML.\n */\n readonly ssr?: (\n emit: SsrEmit,\n values: readonly unknown[],\n ) => AsyncGenerator<SsrChunk, void, unknown>;\n}\n\n/** Chunk producido por el renderer SSR especializado (descriptor.ssr). */\nexport interface SsrChunk {\n readonly type: \"markup\" | \"boundary-start\" | \"boundary-end\" | \"error\" | \"done\";\n readonly value: string;\n readonly index: number;\n}\n\n/** Ops que el core expone al renderer SSR especializado. */\nexport interface SsrEmit {\n /** Static markup, ya cortado en build. */\n m(value: string): SsrChunk;\n /** Binding node: boundaries + resolución + renderValueChunks. */\n node(index: number, value: unknown): AsyncGenerator<SsrChunk, void, unknown>;\n /** Binding attr: prefix + `name=\"v\"` serializada + marker opcional. */\n attr(\n prefix: string,\n index: number,\n attrName: string,\n url: boolean,\n executable: boolean,\n value: unknown,\n ): Promise<SsrChunk[]>;\n /** Binding event: marker data-elur-e o prefix recortado. */\n event(index: number, prefix: string, eventName: string): SsrChunk;\n}\n\nexport interface ServerRenderProtocolContext {\n readonly markers: boolean;\n readonly signal?: AbortSignal;\n readonly context?: unknown;\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n}\n\n/** Context passed to a custom value's `mountDom` protocol during client-side mount. */\nexport interface DomProtocolContext {\n readonly parent: Node;\n readonly before: Node | null;\n readonly context?: unknown;\n}\n\n/** Context passed to a custom value's `hydrateDom` protocol during hydration. */\nexport interface HydrationProtocolContext {\n readonly parent: Node;\n readonly bounds: { start: Comment; end: Comment } | null;\n readonly context?: unknown;\n /** Remounts a value inside the current bounds (used as fallback). */\n render(value: unknown): unknown;\n}\n\nexport interface ElurRenderProtocol {\n renderServer?(context: ServerRenderProtocolContext): string | Promise<string>;\n mountDom?(context: DomProtocolContext): (() => void) | void;\n hydrateDom?(context: HydrationProtocolContext): (() => void) | void;\n}\n\nexport const ELUR_TEMPLATE_DESCRIPTOR = Symbol.for(\"@elurjs/core/template-descriptor\");\nexport const ELUR_RENDER_PROTOCOL = Symbol.for(\"@elurjs/core/render-protocol\");\n\n/**\n * Runtime feature capabilities, for tooling to detect support without\n * inferring it from version strings.\n *\n * NOTE: Partial attribute interpolation is now handled at compile time by\n * @elurjs/vite-plugin-elur. The core runtime does not support it natively.\n * Use the Vite plugin for partial interpolation support.\n */\nexport const templateFeatures = {\n /** Partial attribute interpolation (`class=\"btn ${size}\"`) is supported. */\n partialAttributeInterpolation: false,\n} as const;\n\nexport interface ElurTemplate {\n readonly __isElurTemplate: true;\n readonly [ELUR_TEMPLATE_DESCRIPTOR]?: TemplateDescriptor;\n readonly [ELUR_RENDER_PROTOCOL]?: ElurRenderProtocol;\n /** Mounts the template into a container element (public / root API). */\n mount(container: Element | string): ElurMountHandle;\n /** @internal Renders before `before` node (or appends to `parent`). Returns cleanup. */\n _render(parent: Node, before: Node | null): () => void;\n}\n\nexport interface ElurMountHandle {\n unmount(): void;\n}\n\n/** Direct reference to a DOM element, assigned on mount and cleared on unmount. */\nexport interface ElurRef<T extends Element = Element> {\n el: T | null;\n}\n\n/** Creates an empty `ElurRef`. Use as `ref` attribute value in templates. */\nexport function ref<T extends Element = Element>(): ElurRef<T> {\n return { el: null };\n}\n\n/** Keyed list result for efficient DOM diffing via `repeat()`. */\nexport interface KeyedList<T = unknown> {\n readonly __isKeyedList: true;\n readonly items: T[];\n readonly keyFn: (item: T, index: number) => string | number;\n readonly renderFn: (item: T, index: number) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent;\n}\n\nexport interface KEntry {\n start: Comment;\n end: Comment;\n cleanup: () => void;\n /**\n * C.16.4: item que originó la entry — permite detectar\n * \"misma key, objeto nuevo\" y re-montarla in-place. Opcional porque\n * algunos paths (adopción vieja, internals) no lo registran.\n */\n item?: unknown;\n}\n\n/** Opaque token for a named portal target. */\nexport interface PortalOutlet {\n readonly __isPortalOutlet: true;\n /** @internal */\n _container: Element | null;\n}\n\n/** Fallback: a static template/component, or a factory receiving the error. */\nexport type ErrorFallback =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | ((err: unknown) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent);\n\n/** Content that can be wrapped with `transition()`. */\nexport type TransitionContent =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | (() => ElurTemplate | import(\"../lifecycle.js\").ElurComponent | null);\n\nexport const COMMENT = {\n SCOPE: \"elur-scope\",\n ERROR_BOUNDARY: \"elur-eb\",\n TRANSITION: \"elur-t\",\n KEYED_START: \"elur-ks\",\n KEYED_END: \"elur-ke\",\n KEYED_ZONE: \"elur-kz\",\n} as const;\n\n// =============================================================================\n// --- DOM inspection helpers ---\n// =============================================================================\n\nexport function isElurTemplate(v: unknown): v is ElurTemplate {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isElurTemplate === true\n );\n}\n\nexport function isKeyedList(v: unknown): v is KeyedList {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isKeyedList === true\n );\n}\n\n/** Marca del pack de binding derivado T2 emitido por el compilador. */\nexport const ELUR_DERIVED = Symbol.for(\"elur.derived\");\n\nexport interface ElurDerivedBinding {\n deps: unknown[];\n get: () => unknown;\n}\n\n/**\n * Detecta el pack `__elurDerive(dep…, getter)` del compilador. Symbol.for\n * permite detección cross-module (plugin runtime vs core hydrate/SSR).\n */\nexport function isDerivedBinding(v: unknown): v is ElurDerivedBinding {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<symbol, unknown>)[ELUR_DERIVED] === true\n );\n}\n"],"mappings":"AAiGA,IAAa,EAA2B,OAAO,IAAI,mCAAmC,CACzE,EAAuB,OAAO,IAAI,+BAA+B,CAUjE,EAAmB,CAE5B,8BAA+B,GAClC,CAsBD,SAAgB,GAA+C,CAC3D,MAAO,CAAE,GAAI,KAAM,CA0CvB,IAAa,EAAU,CACnB,MAAO,aACP,eAAgB,UAChB,WAAY,SACZ,YAAa,UACb,UAAW,UACX,WAAY,UACf,CAMD,SAAgB,EAAe,EAA+B,CAC1D,OAEI,OAAO,GAAM,YADb,GAEC,EAA8B,mBAAqB,GAI5D,SAAgB,EAAY,EAA4B,CACpD,OAEI,OAAO,GAAM,YADb,GAEC,EAA8B,gBAAkB,GAKzD,IAAa,EAAe,OAAO,IAAI,eAAe,CAWtD,SAAgB,EAAiB,EAAqC,CAClE,OAEI,OAAO,GAAM,YADb,GAEC,EAA8B,KAAkB"}
|
|
@@ -17,6 +17,44 @@ export interface TemplateDescriptor {
|
|
|
17
17
|
readonly strings: readonly string[];
|
|
18
18
|
readonly values: readonly unknown[];
|
|
19
19
|
readonly contexts: readonly TemplateBindingContext[];
|
|
20
|
+
/**
|
|
21
|
+
* C.13: hidratación compilada — el codegen emite una función que activa
|
|
22
|
+
* los bindings por posición (access paths) en vez de un scan global de
|
|
23
|
+
* markers. Sólo los boundaries de contenido dinámico (`<!--elur-N-->`)
|
|
24
|
+
* siguen marcados en el HTML; `data-elur-*` no se emiten.
|
|
25
|
+
* `bounds` se pasa cuando el descriptor es anidado dentro de otro
|
|
26
|
+
* binding. Devuelve cleanup.
|
|
27
|
+
*/
|
|
28
|
+
readonly hydrate?: (root: ParentNode, values: readonly unknown[], options?: unknown, bounds?: {
|
|
29
|
+
start: Comment;
|
|
30
|
+
end: Comment;
|
|
31
|
+
} | null) => (() => void) | void;
|
|
32
|
+
/**
|
|
33
|
+
* C.12 fase 2: renderer SSR especializado — el codegen emite una función
|
|
34
|
+
* generadora que secuencia los chunks con los strings ya cortados
|
|
35
|
+
* (`attr=`/comillas pre-resueltos en build). Toda la semántica
|
|
36
|
+
* (resolución de valores, sanitización, markers, abort) sigue en los
|
|
37
|
+
* helpers `emit.*` del core — el artefacto compilado y el descriptor
|
|
38
|
+
* genérico producen exactamente el mismo HTML.
|
|
39
|
+
*/
|
|
40
|
+
readonly ssr?: (emit: SsrEmit, values: readonly unknown[]) => AsyncGenerator<SsrChunk, void, unknown>;
|
|
41
|
+
}
|
|
42
|
+
/** Chunk producido por el renderer SSR especializado (descriptor.ssr). */
|
|
43
|
+
export interface SsrChunk {
|
|
44
|
+
readonly type: "markup" | "boundary-start" | "boundary-end" | "error" | "done";
|
|
45
|
+
readonly value: string;
|
|
46
|
+
readonly index: number;
|
|
47
|
+
}
|
|
48
|
+
/** Ops que el core expone al renderer SSR especializado. */
|
|
49
|
+
export interface SsrEmit {
|
|
50
|
+
/** Static markup, ya cortado en build. */
|
|
51
|
+
m(value: string): SsrChunk;
|
|
52
|
+
/** Binding node: boundaries + resolución + renderValueChunks. */
|
|
53
|
+
node(index: number, value: unknown): AsyncGenerator<SsrChunk, void, unknown>;
|
|
54
|
+
/** Binding attr: prefix + `name="v"` serializada + marker opcional. */
|
|
55
|
+
attr(prefix: string, index: number, attrName: string, url: boolean, executable: boolean, value: unknown): Promise<SsrChunk[]>;
|
|
56
|
+
/** Binding event: marker data-elur-e o prefix recortado. */
|
|
57
|
+
event(index: number, prefix: string, eventName: string): SsrChunk;
|
|
20
58
|
}
|
|
21
59
|
export interface ServerRenderProtocolContext {
|
|
22
60
|
readonly markers: boolean;
|
|
@@ -91,6 +129,12 @@ export interface KEntry {
|
|
|
91
129
|
start: Comment;
|
|
92
130
|
end: Comment;
|
|
93
131
|
cleanup: () => void;
|
|
132
|
+
/**
|
|
133
|
+
* C.16.4: item que originó la entry — permite detectar
|
|
134
|
+
* "misma key, objeto nuevo" y re-montarla in-place. Opcional porque
|
|
135
|
+
* algunos paths (adopción vieja, internals) no lo registran.
|
|
136
|
+
*/
|
|
137
|
+
item?: unknown;
|
|
94
138
|
}
|
|
95
139
|
/** Opaque token for a named portal target. */
|
|
96
140
|
export interface PortalOutlet {
|
|
@@ -112,3 +156,14 @@ export declare const COMMENT: {
|
|
|
112
156
|
};
|
|
113
157
|
export declare function isElurTemplate(v: unknown): v is ElurTemplate;
|
|
114
158
|
export declare function isKeyedList(v: unknown): v is KeyedList;
|
|
159
|
+
/** Marca del pack de binding derivado T2 emitido por el compilador. */
|
|
160
|
+
export declare const ELUR_DERIVED: unique symbol;
|
|
161
|
+
export interface ElurDerivedBinding {
|
|
162
|
+
deps: unknown[];
|
|
163
|
+
get: () => unknown;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Detecta el pack `__elurDerive(dep…, getter)` del compilador. Symbol.for
|
|
167
|
+
* permite detección cross-module (plugin runtime vs core hydrate/SSR).
|
|
168
|
+
*/
|
|
169
|
+
export declare function isDerivedBinding(v: unknown): v is ElurDerivedBinding;
|
|
@@ -17,6 +17,44 @@ export interface TemplateDescriptor {
|
|
|
17
17
|
readonly strings: readonly string[];
|
|
18
18
|
readonly values: readonly unknown[];
|
|
19
19
|
readonly contexts: readonly TemplateBindingContext[];
|
|
20
|
+
/**
|
|
21
|
+
* C.13: hidratación compilada — el codegen emite una función que activa
|
|
22
|
+
* los bindings por posición (access paths) en vez de un scan global de
|
|
23
|
+
* markers. Sólo los boundaries de contenido dinámico (`<!--elur-N-->`)
|
|
24
|
+
* siguen marcados en el HTML; `data-elur-*` no se emiten.
|
|
25
|
+
* `bounds` se pasa cuando el descriptor es anidado dentro de otro
|
|
26
|
+
* binding. Devuelve cleanup.
|
|
27
|
+
*/
|
|
28
|
+
readonly hydrate?: (root: ParentNode, values: readonly unknown[], options?: unknown, bounds?: {
|
|
29
|
+
start: Comment;
|
|
30
|
+
end: Comment;
|
|
31
|
+
} | null) => (() => void) | void;
|
|
32
|
+
/**
|
|
33
|
+
* C.12 fase 2: renderer SSR especializado — el codegen emite una función
|
|
34
|
+
* generadora que secuencia los chunks con los strings ya cortados
|
|
35
|
+
* (`attr=`/comillas pre-resueltos en build). Toda la semántica
|
|
36
|
+
* (resolución de valores, sanitización, markers, abort) sigue en los
|
|
37
|
+
* helpers `emit.*` del core — el artefacto compilado y el descriptor
|
|
38
|
+
* genérico producen exactamente el mismo HTML.
|
|
39
|
+
*/
|
|
40
|
+
readonly ssr?: (emit: SsrEmit, values: readonly unknown[]) => AsyncGenerator<SsrChunk, void, unknown>;
|
|
41
|
+
}
|
|
42
|
+
/** Chunk producido por el renderer SSR especializado (descriptor.ssr). */
|
|
43
|
+
export interface SsrChunk {
|
|
44
|
+
readonly type: "markup" | "boundary-start" | "boundary-end" | "error" | "done";
|
|
45
|
+
readonly value: string;
|
|
46
|
+
readonly index: number;
|
|
47
|
+
}
|
|
48
|
+
/** Ops que el core expone al renderer SSR especializado. */
|
|
49
|
+
export interface SsrEmit {
|
|
50
|
+
/** Static markup, ya cortado en build. */
|
|
51
|
+
m(value: string): SsrChunk;
|
|
52
|
+
/** Binding node: boundaries + resolución + renderValueChunks. */
|
|
53
|
+
node(index: number, value: unknown): AsyncGenerator<SsrChunk, void, unknown>;
|
|
54
|
+
/** Binding attr: prefix + `name="v"` serializada + marker opcional. */
|
|
55
|
+
attr(prefix: string, index: number, attrName: string, url: boolean, executable: boolean, value: unknown): Promise<SsrChunk[]>;
|
|
56
|
+
/** Binding event: marker data-elur-e o prefix recortado. */
|
|
57
|
+
event(index: number, prefix: string, eventName: string): SsrChunk;
|
|
20
58
|
}
|
|
21
59
|
export interface ServerRenderProtocolContext {
|
|
22
60
|
readonly markers: boolean;
|
|
@@ -91,6 +129,12 @@ export interface KEntry {
|
|
|
91
129
|
start: Comment;
|
|
92
130
|
end: Comment;
|
|
93
131
|
cleanup: () => void;
|
|
132
|
+
/**
|
|
133
|
+
* C.16.4: item que originó la entry — permite detectar
|
|
134
|
+
* "misma key, objeto nuevo" y re-montarla in-place. Opcional porque
|
|
135
|
+
* algunos paths (adopción vieja, internals) no lo registran.
|
|
136
|
+
*/
|
|
137
|
+
item?: unknown;
|
|
94
138
|
}
|
|
95
139
|
/** Opaque token for a named portal target. */
|
|
96
140
|
export interface PortalOutlet {
|
|
@@ -112,3 +156,14 @@ export declare const COMMENT: {
|
|
|
112
156
|
};
|
|
113
157
|
export declare function isElurTemplate(v: unknown): v is ElurTemplate;
|
|
114
158
|
export declare function isKeyedList(v: unknown): v is KeyedList;
|
|
159
|
+
/** Marca del pack de binding derivado T2 emitido por el compilador. */
|
|
160
|
+
export declare const ELUR_DERIVED: unique symbol;
|
|
161
|
+
export interface ElurDerivedBinding {
|
|
162
|
+
deps: unknown[];
|
|
163
|
+
get: () => unknown;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Detecta el pack `__elurDerive(dep…, getter)` del compilador. Symbol.for
|
|
167
|
+
* permite detección cross-module (plugin runtime vs core hydrate/SSR).
|
|
168
|
+
*/
|
|
169
|
+
export declare function isDerivedBinding(v: unknown): v is ElurDerivedBinding;
|
|
@@ -17,7 +17,11 @@ function a(e) {
|
|
|
17
17
|
function o(e) {
|
|
18
18
|
return typeof e == "object" && !!e && e.__isKeyedList === !0;
|
|
19
19
|
}
|
|
20
|
+
var s = Symbol.for("elur.derived");
|
|
21
|
+
function c(e) {
|
|
22
|
+
return typeof e == "object" && !!e && e[s] === !0;
|
|
23
|
+
}
|
|
20
24
|
//#endregion
|
|
21
|
-
export { i as COMMENT, t as ELUR_RENDER_PROTOCOL, e as ELUR_TEMPLATE_DESCRIPTOR, a as isElurTemplate, o as isKeyedList, r as ref, n as templateFeatures };
|
|
25
|
+
export { i as COMMENT, t as ELUR_RENDER_PROTOCOL, e as ELUR_TEMPLATE_DESCRIPTOR, c as isDerivedBinding, a as isElurTemplate, o as isKeyedList, r as ref, n as templateFeatures };
|
|
22
26
|
|
|
23
27
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../../src/elur/template/types.ts"],"sourcesContent":["// =============================================================================\n// --- Public types ---\n// =============================================================================\n\nexport type TemplateBindingContext =\n | { type: \"node\" }\n | { type: \"event\"; eventName: string; modifiers: string[]; hadOpenQuote: boolean }\n | { type: \"attr\"; attrName: string; hadOpenQuote: boolean; url?: boolean; executable?: boolean };\n\nexport interface TemplateDescriptor {\n readonly version: 1;\n readonly strings: readonly string[];\n readonly values: readonly unknown[];\n readonly contexts: readonly TemplateBindingContext[];\n}\n\nexport interface ServerRenderProtocolContext {\n readonly markers: boolean;\n readonly signal?: AbortSignal;\n readonly context?: unknown;\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n}\n\n/** Context passed to a custom value's `mountDom` protocol during client-side mount. */\nexport interface DomProtocolContext {\n readonly parent: Node;\n readonly before: Node | null;\n readonly context?: unknown;\n}\n\n/** Context passed to a custom value's `hydrateDom` protocol during hydration. */\nexport interface HydrationProtocolContext {\n readonly parent: Node;\n readonly bounds: { start: Comment; end: Comment } | null;\n readonly context?: unknown;\n /** Remounts a value inside the current bounds (used as fallback). */\n render(value: unknown): unknown;\n}\n\nexport interface ElurRenderProtocol {\n renderServer?(context: ServerRenderProtocolContext): string | Promise<string>;\n mountDom?(context: DomProtocolContext): (() => void) | void;\n hydrateDom?(context: HydrationProtocolContext): (() => void) | void;\n}\n\nexport const ELUR_TEMPLATE_DESCRIPTOR = Symbol.for(\"@elurjs/core/template-descriptor\");\nexport const ELUR_RENDER_PROTOCOL = Symbol.for(\"@elurjs/core/render-protocol\");\n\n/**\n * Runtime feature capabilities, for tooling to detect support without\n * inferring it from version strings.\n *\n * NOTE: Partial attribute interpolation is now handled at compile time by\n * @elurjs/vite-plugin-elur. The core runtime does not support it natively.\n * Use the Vite plugin for partial interpolation support.\n */\nexport const templateFeatures = {\n /** Partial attribute interpolation (`class=\"btn ${size}\"`) is supported. */\n partialAttributeInterpolation: false,\n} as const;\n\nexport interface ElurTemplate {\n readonly __isElurTemplate: true;\n readonly [ELUR_TEMPLATE_DESCRIPTOR]?: TemplateDescriptor;\n readonly [ELUR_RENDER_PROTOCOL]?: ElurRenderProtocol;\n /** Mounts the template into a container element (public / root API). */\n mount(container: Element | string): ElurMountHandle;\n /** @internal Renders before `before` node (or appends to `parent`). Returns cleanup. */\n _render(parent: Node, before: Node | null): () => void;\n}\n\nexport interface ElurMountHandle {\n unmount(): void;\n}\n\n/** Direct reference to a DOM element, assigned on mount and cleared on unmount. */\nexport interface ElurRef<T extends Element = Element> {\n el: T | null;\n}\n\n/** Creates an empty `ElurRef`. Use as `ref` attribute value in templates. */\nexport function ref<T extends Element = Element>(): ElurRef<T> {\n return { el: null };\n}\n\n/** Keyed list result for efficient DOM diffing via `repeat()`. */\nexport interface KeyedList<T = unknown> {\n readonly __isKeyedList: true;\n readonly items: T[];\n readonly keyFn: (item: T, index: number) => string | number;\n readonly renderFn: (item: T, index: number) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent;\n}\n\nexport interface KEntry {\n start: Comment;\n end: Comment;\n cleanup: () => void;\n}\n\n/** Opaque token for a named portal target. */\nexport interface PortalOutlet {\n readonly __isPortalOutlet: true;\n /** @internal */\n _container: Element | null;\n}\n\n/** Fallback: a static template/component, or a factory receiving the error. */\nexport type ErrorFallback =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | ((err: unknown) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent);\n\n/** Content that can be wrapped with `transition()`. */\nexport type TransitionContent =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | (() => ElurTemplate | import(\"../lifecycle.js\").ElurComponent | null);\n\nexport const COMMENT = {\n SCOPE: \"elur-scope\",\n ERROR_BOUNDARY: \"elur-eb\",\n TRANSITION: \"elur-t\",\n KEYED_START: \"elur-ks\",\n KEYED_END: \"elur-ke\",\n KEYED_ZONE: \"elur-kz\",\n} as const;\n\n// =============================================================================\n// --- DOM inspection helpers ---\n// =============================================================================\n\nexport function isElurTemplate(v: unknown): v is ElurTemplate {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isElurTemplate === true\n );\n}\n\nexport function isKeyedList(v: unknown): v is KeyedList {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isKeyedList === true\n );\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../../src/elur/template/types.ts"],"sourcesContent":["// =============================================================================\n// --- Public types ---\n// =============================================================================\n\nexport type TemplateBindingContext =\n | { type: \"node\" }\n | { type: \"event\"; eventName: string; modifiers: string[]; hadOpenQuote: boolean }\n | { type: \"attr\"; attrName: string; hadOpenQuote: boolean; url?: boolean; executable?: boolean };\n\nexport interface TemplateDescriptor {\n readonly version: 1;\n readonly strings: readonly string[];\n readonly values: readonly unknown[];\n readonly contexts: readonly TemplateBindingContext[];\n /**\n * C.13: hidratación compilada — el codegen emite una función que activa\n * los bindings por posición (access paths) en vez de un scan global de\n * markers. Sólo los boundaries de contenido dinámico (`<!--elur-N-->`)\n * siguen marcados en el HTML; `data-elur-*` no se emiten.\n * `bounds` se pasa cuando el descriptor es anidado dentro de otro\n * binding. Devuelve cleanup.\n */\n readonly hydrate?: (\n root: ParentNode,\n values: readonly unknown[],\n options?: unknown,\n bounds?: { start: Comment; end: Comment } | null,\n ) => (() => void) | void;\n /**\n * C.12 fase 2: renderer SSR especializado — el codegen emite una función\n * generadora que secuencia los chunks con los strings ya cortados\n * (`attr=`/comillas pre-resueltos en build). Toda la semántica\n * (resolución de valores, sanitización, markers, abort) sigue en los\n * helpers `emit.*` del core — el artefacto compilado y el descriptor\n * genérico producen exactamente el mismo HTML.\n */\n readonly ssr?: (\n emit: SsrEmit,\n values: readonly unknown[],\n ) => AsyncGenerator<SsrChunk, void, unknown>;\n}\n\n/** Chunk producido por el renderer SSR especializado (descriptor.ssr). */\nexport interface SsrChunk {\n readonly type: \"markup\" | \"boundary-start\" | \"boundary-end\" | \"error\" | \"done\";\n readonly value: string;\n readonly index: number;\n}\n\n/** Ops que el core expone al renderer SSR especializado. */\nexport interface SsrEmit {\n /** Static markup, ya cortado en build. */\n m(value: string): SsrChunk;\n /** Binding node: boundaries + resolución + renderValueChunks. */\n node(index: number, value: unknown): AsyncGenerator<SsrChunk, void, unknown>;\n /** Binding attr: prefix + `name=\"v\"` serializada + marker opcional. */\n attr(\n prefix: string,\n index: number,\n attrName: string,\n url: boolean,\n executable: boolean,\n value: unknown,\n ): Promise<SsrChunk[]>;\n /** Binding event: marker data-elur-e o prefix recortado. */\n event(index: number, prefix: string, eventName: string): SsrChunk;\n}\n\nexport interface ServerRenderProtocolContext {\n readonly markers: boolean;\n readonly signal?: AbortSignal;\n readonly context?: unknown;\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n}\n\n/** Context passed to a custom value's `mountDom` protocol during client-side mount. */\nexport interface DomProtocolContext {\n readonly parent: Node;\n readonly before: Node | null;\n readonly context?: unknown;\n}\n\n/** Context passed to a custom value's `hydrateDom` protocol during hydration. */\nexport interface HydrationProtocolContext {\n readonly parent: Node;\n readonly bounds: { start: Comment; end: Comment } | null;\n readonly context?: unknown;\n /** Remounts a value inside the current bounds (used as fallback). */\n render(value: unknown): unknown;\n}\n\nexport interface ElurRenderProtocol {\n renderServer?(context: ServerRenderProtocolContext): string | Promise<string>;\n mountDom?(context: DomProtocolContext): (() => void) | void;\n hydrateDom?(context: HydrationProtocolContext): (() => void) | void;\n}\n\nexport const ELUR_TEMPLATE_DESCRIPTOR = Symbol.for(\"@elurjs/core/template-descriptor\");\nexport const ELUR_RENDER_PROTOCOL = Symbol.for(\"@elurjs/core/render-protocol\");\n\n/**\n * Runtime feature capabilities, for tooling to detect support without\n * inferring it from version strings.\n *\n * NOTE: Partial attribute interpolation is now handled at compile time by\n * @elurjs/vite-plugin-elur. The core runtime does not support it natively.\n * Use the Vite plugin for partial interpolation support.\n */\nexport const templateFeatures = {\n /** Partial attribute interpolation (`class=\"btn ${size}\"`) is supported. */\n partialAttributeInterpolation: false,\n} as const;\n\nexport interface ElurTemplate {\n readonly __isElurTemplate: true;\n readonly [ELUR_TEMPLATE_DESCRIPTOR]?: TemplateDescriptor;\n readonly [ELUR_RENDER_PROTOCOL]?: ElurRenderProtocol;\n /** Mounts the template into a container element (public / root API). */\n mount(container: Element | string): ElurMountHandle;\n /** @internal Renders before `before` node (or appends to `parent`). Returns cleanup. */\n _render(parent: Node, before: Node | null): () => void;\n}\n\nexport interface ElurMountHandle {\n unmount(): void;\n}\n\n/** Direct reference to a DOM element, assigned on mount and cleared on unmount. */\nexport interface ElurRef<T extends Element = Element> {\n el: T | null;\n}\n\n/** Creates an empty `ElurRef`. Use as `ref` attribute value in templates. */\nexport function ref<T extends Element = Element>(): ElurRef<T> {\n return { el: null };\n}\n\n/** Keyed list result for efficient DOM diffing via `repeat()`. */\nexport interface KeyedList<T = unknown> {\n readonly __isKeyedList: true;\n readonly items: T[];\n readonly keyFn: (item: T, index: number) => string | number;\n readonly renderFn: (item: T, index: number) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent;\n}\n\nexport interface KEntry {\n start: Comment;\n end: Comment;\n cleanup: () => void;\n /**\n * C.16.4: item que originó la entry — permite detectar\n * \"misma key, objeto nuevo\" y re-montarla in-place. Opcional porque\n * algunos paths (adopción vieja, internals) no lo registran.\n */\n item?: unknown;\n}\n\n/** Opaque token for a named portal target. */\nexport interface PortalOutlet {\n readonly __isPortalOutlet: true;\n /** @internal */\n _container: Element | null;\n}\n\n/** Fallback: a static template/component, or a factory receiving the error. */\nexport type ErrorFallback =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | ((err: unknown) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent);\n\n/** Content that can be wrapped with `transition()`. */\nexport type TransitionContent =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | (() => ElurTemplate | import(\"../lifecycle.js\").ElurComponent | null);\n\nexport const COMMENT = {\n SCOPE: \"elur-scope\",\n ERROR_BOUNDARY: \"elur-eb\",\n TRANSITION: \"elur-t\",\n KEYED_START: \"elur-ks\",\n KEYED_END: \"elur-ke\",\n KEYED_ZONE: \"elur-kz\",\n} as const;\n\n// =============================================================================\n// --- DOM inspection helpers ---\n// =============================================================================\n\nexport function isElurTemplate(v: unknown): v is ElurTemplate {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isElurTemplate === true\n );\n}\n\nexport function isKeyedList(v: unknown): v is KeyedList {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isKeyedList === true\n );\n}\n\n/** Marca del pack de binding derivado T2 emitido por el compilador. */\nexport const ELUR_DERIVED = Symbol.for(\"elur.derived\");\n\nexport interface ElurDerivedBinding {\n deps: unknown[];\n get: () => unknown;\n}\n\n/**\n * Detecta el pack `__elurDerive(dep…, getter)` del compilador. Symbol.for\n * permite detección cross-module (plugin runtime vs core hydrate/SSR).\n */\nexport function isDerivedBinding(v: unknown): v is ElurDerivedBinding {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<symbol, unknown>)[ELUR_DERIVED] === true\n );\n}\n"],"mappings":";AAiGA,IAAa,IAA2B,OAAO,IAAI,mCAAmC,EACzE,IAAuB,OAAO,IAAI,+BAA+B,EAUjE,IAAmB,EAE5B,+BAA+B,IAClC;AAsBD,SAAgB,IAA+C;AAC3D,QAAO,EAAE,IAAI,MAAM;;AA0CvB,IAAa,IAAU;CACnB,OAAO;CACP,gBAAgB;CAChB,YAAY;CACZ,aAAa;CACb,WAAW;CACX,YAAY;CACf;AAMD,SAAgB,EAAe,GAA+B;AAC1D,QAEI,OAAO,KAAM,cADb,KAEC,EAA8B,qBAAqB;;AAI5D,SAAgB,EAAY,GAA4B;AACpD,QAEI,OAAO,KAAM,cADb,KAEC,EAA8B,kBAAkB;;AAKzD,IAAa,IAAe,OAAO,IAAI,eAAe;AAWtD,SAAgB,EAAiB,GAAqC;AAClE,QAEI,OAAO,KAAM,cADb,KAEC,EAA8B,OAAkB"}
|
package/dist/lib/elur.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./elur/next-2/reactivity.cjs`),t=require(`./elur/template/types.cjs`),n=require(`./lifecycle.cjs`),r=require(`./context.cjs`),i=require(`./elur/template/keyed.cjs`),a=require(`./elur/template/bindings.cjs`),o=require(`./elur/template/html.cjs`),s=require(`./elur/template/raw.cjs`),c=require(`./elur/template/transitions.cjs`),l=require(`./elur/template/portal.cjs`),u=require(`./elur/template/error-boundary.cjs`),d=require(`./elur/router-registry.cjs`),f=require(`./elur/next-2/mount.cjs`),p=require(`./store.cjs`),m=require(`./plugins.cjs`),h=require(`./router.cjs`),g=require(`./async.cjs`),_=require(`./form.cjs`);exports.ELUR_RENDER_PROTOCOL=t.ELUR_RENDER_PROTOCOL,exports.ELUR_TEMPLATE_DESCRIPTOR=t.ELUR_TEMPLATE_DESCRIPTOR,exports.ElurComponent=n.ElurComponent,exports.Link=h.Link,exports.RouterKey=d.RouterKey,exports.RouterView=h.RouterView,exports.Signal=e.Signal,exports._hasActiveRouter=h._hasActiveRouter,exports.batch=e.batch,exports.bridgePlugin=m.bridgePlugin,exports.computed=e.computed,exports.createErrorBoundary=u.createErrorBoundary,exports.createForm=_.createForm,exports.createInjectionKey=r.createInjectionKey,exports.createPortalOutlet=l.createPortalOutlet,exports.createRouter=h.createRouter,exports.createStore=p.createStore,exports.createValidator=_.createValidator,exports.effect=e.effect,exports.elurField=_.elurField,exports.elurFieldArray=_.elurFieldArray,exports.elurRouter=h.elurRouter,exports.email=_.email,exports.extendValidators=_.extendValidators,exports.guardPlugin=m.guardPlugin,exports.html=o.html,exports.inject=r.inject,exports.injectOutlet=l.injectOutlet,exports.lazy=g.lazy,exports.loggerPlugin=m.loggerPlugin,exports.max=_.max,exports.maxLength=_.maxLength,exports.min=_.min,exports.minLength=_.minLength,exports.mount=f.mount,exports.nextTick=e.nextTick,exports.pattern=_.pattern,exports.persistPlugin=m.persistPlugin,exports.portal=l.portal,exports.portalOutlet=l.portalOutlet,exports.provide=r.provide,exports.provideOutlet=l.provideOutlet,exports.raw=s.raw,exports.ref=t.ref,exports.repeat=i.repeat,exports.required=_.required,exports.showWhen=a.showWhen,exports.signal=e.signal,exports.suspend=g.suspend,exports.templateFeatures=t.templateFeatures,exports.transition=c.transition,exports.untrack=e.untrack,exports.validators=_.validators,exports.watch=e.watch;
|
package/dist/lib/elur.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Signal as e, batch as t, computed as n, effect as r, nextTick as i, signal as a, untrack as o, watch as s } from "./
|
|
1
|
+
import { Signal as e, batch as t, computed as n, effect as r, nextTick as i, signal as a, untrack as o, watch as s } from "./elur/next-2/reactivity.js";
|
|
2
2
|
import { ELUR_RENDER_PROTOCOL as c, ELUR_TEMPLATE_DESCRIPTOR as l, ref as u, templateFeatures as d } from "./elur/template/types.js";
|
|
3
3
|
import { ElurComponent as f } from "./lifecycle.js";
|
|
4
4
|
import { createInjectionKey as p, inject as m, provide as h } from "./context.js";
|
|
@@ -10,7 +10,7 @@ import { transition as b } from "./elur/template/transitions.js";
|
|
|
10
10
|
import { createPortalOutlet as x, injectOutlet as S, portal as C, portalOutlet as w, provideOutlet as T } from "./elur/template/portal.js";
|
|
11
11
|
import { createErrorBoundary as E } from "./elur/template/error-boundary.js";
|
|
12
12
|
import { RouterKey as D } from "./elur/router-registry.js";
|
|
13
|
-
import { mount as O } from "./
|
|
13
|
+
import { mount as O } from "./elur/next-2/mount.js";
|
|
14
14
|
import { createStore as k } from "./store.js";
|
|
15
15
|
import { bridgePlugin as A, guardPlugin as j, loggerPlugin as M, persistPlugin as N } from "./plugins.js";
|
|
16
16
|
import { Link as P, RouterView as F, _hasActiveRouter as I, createRouter as L, elurRouter as R } from "./router.js";
|
package/dist/lib/form.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./elur/next-2/reactivity.cjs`);function t(e=`Required`){return t=>t==null||t===``||Array.isArray(t)&&t.length===0?e:null}function n(e,t){return n=>typeof n==`string`&&n.length<e?t??`Minimum ${e} characters`:null}function r(e,t){return n=>typeof n==`string`&&n.length>e?t??`Maximum ${e} characters`:null}function i(e,t=`Invalid format`){return n=>typeof n==`string`&&!e.test(n)?t:null}function a(e=`Invalid email`){return i(/^[^\s@]+@[^\s@]+\.[^\s@]+$/,e)}function o(e,t){return n=>typeof n==`number`&&n<e?t??`Minimum value is ${e}`:null}function s(e,t){return n=>typeof n==`number`&&n>e?t??`Maximum value is ${e}`:null}function c(e){return e}var l={required:t,minLength:n,maxLength:r,email:a,pattern:i,min:o,max:s};function u(e,t){return{...e,...t}}function d(t,n=[],r=`blur`,i){let a=e.signal(t),o=e.signal(!1),s=e.signal(!1),c=e.signal(null),l=e.signal(!1),u=t,d=!0,f=e.effect(()=>{if(a.value,d){d=!1;return}c.peek()!==null&&(c.value=null)}),p=e.computed(()=>{if(c.value)return c.value;let e=i?.();for(let t of n){let n=t(a.value,e);if(n)return n}return null}),m=e.computed(()=>(r===`input`?s.value||o.value:r===`submit`?l.value:o.value)?p.value:null);function h(e){return e.type===`checkbox`||e.type===`radio`}function g(e){if(!e||!(`value`in e))return t;let n=e,r=n.value;return typeof t==`boolean`?n.checked===!0?!0:h(n)?!1:r===`true`||r===`1`?!0:r===`false`||r===`0`||r===``?!1:t:typeof t==`number`?r===``?NaN:Number(r):r}let _=e=>{a.value=g(e.target),s.value=!0},v=()=>{o.value=!0};function y(){e.batch(()=>{a.value=u,o.value=!1,s.value=!1,c.value=null,l.value=!1})}function b(t,n={}){let{shouldTouch:r=!1,shouldDirty:i=!0,shouldValidate:c=!0}=n;e.batch(()=>{a.value=t,i&&(s.value=!0),r&&(o.value=!0),c&&(l.value=!0)})}function x(e){c.value=e,e&&(o.value=!0)}function S(){o.value=!0,l.value=!0}function C(e){u=e}function w(){f(),m.dispose(),p.dispose()}return{value:a,error:m,rawError:p,touched:o,dirty:s,onInput:_,onBlur:v,reset:y,setValue:b,_setExternalError:x,_forceVisible:S,_setInitialValue:C,_dispose:w}}function f(t,n={},r=`blur`){function i(e){let t={};for(let i in e){let a=n[i]??[];t[i]=d(e[i],a,r)}return t}let a=e.signal(t.map(i)),o=t,s=e.computed(()=>a.value.length);function c(e){a.value=[...a.value,i(e)]}function l(e){let t=a.value;if(!(e<0||e>=t.length)){for(let n in t[e])t[e][n]._dispose();a.value=t.filter((t,n)=>n!==e)}}function u(e,t){let n=[...a.value];if(e<0||e>=n.length||t<0||t>=n.length||e===t)return;let[r]=n.splice(e,1);n.splice(t,0,r),a.value=n}function f(e,t){let n=[...a.value];if(!(e<0||e>=n.length)){for(let t in n[e])n[e][t]._dispose();n[e]=i(t),a.value=n}}function p(e){for(let e of a.value)for(let t in e)e[t]._dispose();a.value=e.map(i)}function m(e){let t=[...a.value];for(let n=0;n<e.length;n++){let r=e[n];if(n>=t.length){t.push(i(r));continue}let a=t[n];for(let[e,t]of Object.entries(r))a[e]&&a[e].setValue(t,{shouldDirty:!1,shouldTouch:!1,shouldValidate:!1})}a.value=t}function h(e){e&&(o=e);for(let e of a.value)for(let t in e)e[t]._dispose();a.value=o.map(i)}function g(){for(let e of a.value)for(let t in e)e[t]._dispose();s.dispose()}return{fields:a,append:c,remove:l,move:u,replace:f,length:s,setValues:p,patchValues:m,reset:h,_dispose:g}}function p(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function m(e,t=``,n=[]){for(let[r,i]of Object.entries(e)){let e=t?`${t}.${r}`:r;if(p(i)&&Object.keys(i).length>0){m(i,e,n);continue}n.push([e,i])}return n}function h(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e],n=i[t];p(n)||(i[t]={}),i=i[t]}i[r[r.length-1]]=n}function g(t,n={}){let r=n.validateOn??`blur`,i={},a=n.validators;function o(){let e={};for(let t in i)h(e,t,i[t].value.value);return e}for(let[e,n]of m(t))i[e]=d(n,a?.[e]??[],r,o);let s=e.signal(!1),c=e.signal(0),l=e.computed(()=>o()),u=e.computed(()=>{let e={};for(let t in i){let n=i[t].error.value;n&&(e[t]=n)}return e}),f=e.computed(()=>{for(let e in i)if(i[e].rawError.value)return!1;return!0}),p=e.computed(()=>{for(let e in i)if(i[e].error.value)return!1;return!0}),g=e.computed(()=>{for(let e in i)if(i[e].dirty.value)return!0;return!1}),_=e.computed(()=>{for(let e in i)if(i[e].touched.value)return!0;return!1});function v(e){for(let t in e)i[t]?._setExternalError(e[t]??null)}function y(e,t,n={}){let r=i[e];r&&r.setValue(t,n)}function b(t,n={}){let{keepDirty:r=!1,keepTouched:a=!1,keepErrors:o=!0}=n;e.batch(()=>{for(let[e,n]of m(t)){let t=i[e];t&&(t.setValue(n,{shouldDirty:!r,shouldTouch:!1,shouldValidate:!o}),a||(t.touched.value=!1))}})}function x(e){if(e)for(let[t,n]of m(e)){let e=i[t];e&&e._setInitialValue(n)}for(let e in i)i[e].reset();s.value=!1,c.value=0}function S(){l.dispose(),u.dispose(),f.dispose(),p.dispose(),g.dispose(),_.dispose();for(let e in i)i[e]._dispose()}function C(e){return t=>{t.preventDefault(),c.value++;for(let e in i)i[e]._forceVisible();let r=l.value;if(n.validate){let e=n.validate(r);if(e){let t={},n=!1;for(let r in e){let i=e[r],a=Array.isArray(i)?i[0]??null:i??null;a&&(t[r]=a,n=!0)}if(n){v(t);return}}}for(let e in i)if(i[e].rawError.value)return;let a=e(r);a instanceof Promise&&(s.value=!0,a.finally(()=>{s.value=!1}).catch(()=>{}))}}return{fields:i,values:l,errors:u,canSubmit:f,valid:p,dirty:g,touched:_,isSubmitting:s,submitCount:c,handleSubmit:C,reset:x,setValue:y,setValues:b,setErrors:v,dispose:S}}exports.createForm=g,exports.createValidator=c,exports.elurField=d,exports.elurFieldArray=f,exports.email=a,exports.extendValidators=u,exports.max=s,exports.maxLength=r,exports.min=o,exports.minLength=n,exports.pattern=i,exports.required=t,exports.validators=l;
|
|
2
2
|
//# sourceMappingURL=form.cjs.map
|
package/dist/lib/form.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { batch as e, computed as t, effect as n, signal as r } from "./
|
|
1
|
+
import { batch as e, computed as t, effect as n, signal as r } from "./elur/next-2/reactivity.js";
|
|
2
2
|
//#region src/elur/form.ts
|
|
3
3
|
function i(e = "Required") {
|
|
4
4
|
return (t) => t == null || t === "" || Array.isArray(t) && t.length === 0 ? e : null;
|
package/dist/lib/hydrate.cjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./
|
|
2
|
-
//# sourceMappingURL=hydrate.cjs.map
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./elur/next-2/hydrate.cjs`);exports._hydrateNodeRange=e._hydrateNodeRange,exports.hydrate=e.hydrate;
|