diff --git a/README.md b/README.md
index 13a5c1a..55a1f73 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ function EmojiCounter({ initial }) {
el("p", {
className: "output",
textContent: S(() =>
- `Hello World ${emoji.get().repeat(clicks.get())}`),
+ `Hello World ${emoji.get().repeat(count.get())}`),
}),
// 🎮 Controls - Update state on events
@@ -39,12 +39,12 @@ function EmojiCounter({ initial }) {
on("click", () => count.set(count.get() + 1))
),
- el("select", null,
+ el("select", null, on.host(el=> el.value= initial),
on("change", e => emoji.set(e.target.value))
).append(
- el(Option, "🎉", isSelected),
- el(Option, "🚀", isSelected),
- el(Option, "💖", isSelected),
+ el(Option, "🎉"),
+ el(Option, "🚀"),
+ el(Option, "💖"),
)
);
}
@@ -93,18 +93,30 @@ into existing projects.
# npm install deka-dom-el
```
-#### Direct Script
+#### CDN / Direct Script
+
+For CDN links and various build formats (ESM/IIFE, with/without signals, minified/unminified), see the [interactive
+format selector](https://jaandrle.github.io/deka-dom-el/) on the documentation site.
+
```html
+
-
+
+
+
```
### Documentation
-- [**Interactive Guide**](https://jaandrle.github.io/deka-dom-el): WIP
-- [Examples](./examples/): TBD/WIP
+- [**Interactive Guide**](https://jaandrle.github.io/deka-dom-el)
+- [**Examples**](https://jaandrle.github.io/deka-dom-el/p15-examples.html)
## Understanding Signals
@@ -117,10 +129,17 @@ Signals are the reactive backbone of Deka DOM Elements:
## Inspiration and Alternatives
-- [vanjs-org/van](https://github.com/vanjs-org/van) - World's smallest reactive UI framework
-- [adamhaile/S](https://github.com/adamhaile/S) - Simple, clean, fast reactive programming
-- [hyperhype/hyperscript](https://github.com/hyperhype/hyperscript) - Create HyperText with JavaScript
-- [potch/signals](https://github.com/potch/signals) - A small reactive signals library
-- [jaandrle/dollar_dom_component](https://github.com/jaandrle/dollar_dom_component) -
+- [vanjs-org/van](https://github.com/vanjs-org/van) — World's smallest reactive UI framework
+- [adamhaile/S](https://github.com/adamhaile/S) — Simple, clean, fast reactive programming
+- [hyperhype/hyperscript](https://github.com/hyperhype/hyperscript) — Create HyperText with JavaScript
+- [potch/signals](https://github.com/potch/signals) — A small reactive signals library
+- [AseasRoa/paintor](https://github.com/AseasRoa/paintor) - JavaScript library for building reactive client-side user
+ interfaces or HTML code.
+- [pota](https://pota.quack.uy/) — small and pluggable Reactive Web Renderer. It's compiler-less, includes an html
+ function, and a optimized babel preset in case you fancy JSX.
+- [jaandrle/dollar_dom_component](https://github.com/jaandrle/dollar_dom_component) —
Functional DOM components without JSX/virtual DOM
-- [mxjp/rvx: A signal based frontend framework](https://github.com/mxjp/rvx)
+- [TarekRaafat/eleva](https://github.com/TarekRaafat/eleva) — A minimalist, lightweight, pure vanilla JavaScript
+ frontend runtime framework.
+- [didi/mpx](https://github.com/didi/mpx) — Mpx,一款具有优秀开发体验和深度性能优化的增强型跨端小程序框架
+- [mxjp/rvx](https://github.com/mxjp/rvx) — A signal based frontend framework
diff --git a/bs/build.js b/bs/build.js
index 477a301..f45cdc8 100755
--- a/bs/build.js
+++ b/bs/build.js
@@ -5,18 +5,18 @@ const files= [ "index", "index-with-signals" ];
$.api("")
.command("main", "Build main files", { default: true })
.option("--no-types", "Also generate d.ts files", false)
-.action(async function main({ types }){
- const regular = await build({
+.action(function main({ types }){
+ const regular = build({
files,
filesOut,
minify: "no",
types,
});
- const min = await build({
+ const min = build({
files,
filesOut(file, mark= "esm"){
const out= filesOut(file, mark);
- const idx= out.lastIndexOf(".");
+ const idx= out.indexOf(".");
return out.slice(0, idx)+".min"+out.slice(idx);
},
minify: "full",
@@ -25,8 +25,8 @@ $.api("")
return $.exit(regular + min);
})
.command("signals", "Build only signals (for example for analysis)")
-.action(async function signals(){
- const regular = await build({
+.action(function signals(){
+ const regular = build({
files: [ "signals" ],
filesOut(file){ return "dist/."+file; },
minify: "no",
diff --git a/bs/dev/.build.js b/bs/dev/.build.js
index ac2f13d..8e7a251 100644
--- a/bs/dev/.build.js
+++ b/bs/dev/.build.js
@@ -1,4 +1,5 @@
#!/usr/bin/env -S npx nodejsscript
+import { buildSync as esbuildSync } from "esbuild";
const css= echo.css`
.info{ color: gray; }
`;
@@ -8,8 +9,7 @@ export function build({ files, filesOut, minify= "partial", iife= true, types= t
const file= file_root+".js";
echo(`Processing ${file} (minified: ${minify})`);
const out= filesOut(file);
- const esbuild_output= buildEsbuild({ file, out, minify });
- echoVariant(esbuild_output.stderr.split("\n")[1].trim());
+ esbuild({ file, out, minify });
if(types){
const file_dts= file_root+".d.ts";
@@ -31,14 +31,13 @@ export function build({ files, filesOut, minify= "partial", iife= true, types= t
const name= "DDE";
const out= filesOut(file_root+".js", fileMark);
- const params= [
- "--format=iife",
- "--global-name="+name,
- ];
- const dde_output= buildEsbuild({ file, out, minify, params });
- echoVariant(`${out} (${name})`)
+ const params= {
+ format: "iife",
+ globalName: name
+ };
+ esbuild({ file, out, minify, params });
- if(!types) return dde_output;
+ if(!types) return;
const file_dts= file_root+".d.ts";
const file_dts_out= filesOut(file_dts, fileMark);
echoVariant(file_dts_out, true);
@@ -48,8 +47,6 @@ export function build({ files, filesOut, minify= "partial", iife= true, types= t
entry: file_dts,
})
echoVariant(file_dts_out);
-
- return dde_output;
}
}
export function buildDts({ bundle, entry, name }){
@@ -64,46 +61,39 @@ export function buildDts({ bundle, entry, name }){
].filter(Boolean).join(" "), { out, entry });
return dts_b_g_output;
}
-class ErrorEsbuild extends Error{
- constructor({ code, stderr }){
- super(stderr);
- this.code= code;
- this.stderr= stderr;
- }
-}
-function buildEsbuild({ file, out, minify= "partial", params= [] }){
- try {
- return esbuild({ file, out, minify, params });
- } catch(e){
- if(e instanceof ErrorEsbuild)
- return $.exit(e.code, echo(e.stderr));
- throw e;
- }
-}
-export function esbuild({ file, out, minify= "partial", params= [] }){
- const esbuild_output= s.$().run([
- "npx esbuild '::file::'",
- "--platform=neutral",
- "--bundle",
- minifyOption(minify),
- "--legal-comments=inline",
- "--packages=external",
- ...params,
- "--outfile='::out::'"
- ].filter(Boolean).join(" "), { file, out });
- if(esbuild_output.code)
- throw new ErrorEsbuild(esbuild_output);
+export function esbuild({ file, out, minify= "partial", params= {} }){
+ const esbuild_output= esbuildSync({
+ entryPoints: [file],
+ outfile: out,
+ platform: "neutral",
+ bundle: true,
+ legalComments: "inline",
+ packages: "external",
+ metafile: true,
+ ...minifyOption(minify),
+ ...params
+ });
pipe(
f=> f.replace(/^ +/gm, m=> "\t".repeat(m.length/2)),
f=> s.echo(f).to(out)
)(s.cat(out));
+
+ echoVariant(metaToLineStatus(esbuild_output.metafile, out));
return esbuild_output;
}
/** @param {"no"|"full"|"partial"} level */
function minifyOption(level= "partial"){
- if("no"===level) return undefined;
- if("full"===level) return "--minify";
- return "--minify-syntax --minify-identifiers";
+ if("no"===level) return { minify: false };
+ if("full"===level) return { minify: true };
+ return { minifySyntax: true, minifyIdentifiers: true };
+}
+function metaToLineStatus(meta, file){
+ const status= meta.outputs[file];
+ if(!status) return `? ${file}: unknown`;
+ const { bytes }= status;
+ const kbytes= bytes/1024;
+ const kbytesR= kbytes.toFixed(2);
+ return `${file}: ${kbytesR} kB`;
}
function echoVariant(name, todo= false){
if(todo) return echo.use("-R", "~ "+name);
diff --git a/dist/esm-with-signals.d.min.ts b/dist/esm-with-signals.d.min.ts
deleted file mode 100644
index 49490b4..0000000
--- a/dist/esm-with-signals.d.min.ts
+++ /dev/null
@@ -1,641 +0,0 @@
-declare global{ /* ddeSignal */ }
-type CustomElementTagNameMap= { '#text': Text, '#comment': Comment }
-type SupportedElement=
- HTMLElementTagNameMap[keyof HTMLElementTagNameMap]
- | SVGElementTagNameMap[keyof SVGElementTagNameMap]
- | MathMLElementTagNameMap[keyof MathMLElementTagNameMap]
- | CustomElementTagNameMap[keyof CustomElementTagNameMap]
-declare global {
- type ddeComponentAttributes= Record | undefined;
- type ddeElementAddon= (element: El)=> any;
- type ddeString= string | ddeSignal
- type ddeStringable= ddeString | number | ddeSignal
-}
-type PascalCase=
-`${Capitalize}${string}`;
-type AttrsModified= {
- /**
- * Use string like in HTML (internally uses `*.setAttribute("style", *)`), or object representation (like DOM API).
- */
- style: Partial | ddeString
- | Partial<{ [K in keyof CSSStyleDeclaration]: ddeSignal }>
- /**
- * Provide option to add/remove/toggle CSS clasess (index of object) using 1/0/-1.
- * In fact `el.classList.toggle(class_name)` for `-1` and `el.classList.toggle(class_name, Boolean(...))`
- * for others.
- */
- classList: Record>,
- /**
- * Used by the dataset HTML attribute to represent data for custom attributes added to elements.
- * Values are converted to string (see {@link DOMStringMap}).
- *
- * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringMap)
- * */
- dataset: Record,
- /**
- * Sets `aria-*` simiraly to `dataset`
- * */
- ariaset: Record,
-} & Record<`=${string}` | `data${PascalCase}` | `aria${PascalCase}`, ddeString>
- & Record<`.${string}`, any>
-type _fromElsInterfaces= Omit;
-type IsReadonly =
- T extends { readonly [P in K]: T[K] } ? true : false;
-/**
- * Just element attributtes
- *
- * In most cases, you can use native propertie such as
- * [MDN WEB/API/Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) and so on
- * (e.g. [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text)).
- *
- * There is added support for `data[A-Z].*`/`aria[A-Z].*` to be converted to the kebab-case alternatives.
- * @private
- */
-type ElementAttributes= Partial<{
- [K in keyof _fromElsInterfaces]:
- _fromElsInterfaces[K] extends ((...p: any[])=> any)
- ? _fromElsInterfaces[K] | ((...p: Parameters<_fromElsInterfaces[K]>)=>
- ddeSignal[K]>>)
- : (IsReadonly<_fromElsInterfaces, K> extends false
- ? _fromElsInterfaces[K] | ddeSignal<_fromElsInterfaces[K]>
- : ddeStringable)
-} & AttrsModified> & Record;
-export function classListDeclarative(
- element: El,
- classList: AttrsModified["classList"]
-): El
-export function assign(element: El, ...attrs_array: ElementAttributes[]): El
-export function assignAttribute>(
- element: El,
- attr: ATT,
- value: ElementAttributes[ATT]
-): ElementAttributes[ATT]
-
-type ExtendedHTMLElementTagNameMap= HTMLElementTagNameMap & CustomElementTagNameMap;
-export namespace el {
- /**
- * Creates a marker comment for elements
- *
- * @param attrs - Marker attributes
- * @param [is_open=false] - Whether the marker is open-ended
- * @returns Comment node marker
- */
- export function mark(
- attrs: { type: "component"|"reactive"|"later", name?: string, host?: "this"|"parentElement" },
- is_open?: boolean
- ): Comment;
-}
-
-export function el<
- A extends ddeComponentAttributes,
- EL extends SupportedElement | ddeDocumentFragment
->(
- component: (attr: A, ...rest: any[])=> EL,
- attrs?: NoInfer,
- ...addons: ddeElementAddon[]
-): EL extends ddeHTMLElementTagNameMap[keyof ddeHTMLElementTagNameMap]
- ? EL
- : ( EL extends ddeDocumentFragment ? EL : ddeHTMLElement )
-export function el<
- A extends { textContent: ddeStringable },
- EL extends SupportedElement | ddeDocumentFragment
->(
- component: (attr: A, ...rest: any[])=> EL,
- attrs?: NoInfer["textContent"],
- ...addons: ddeElementAddon[]
-): EL extends ddeHTMLElementTagNameMap[keyof ddeHTMLElementTagNameMap]
- ? EL
- : ( EL extends ddeDocumentFragment ? EL : ddeHTMLElement )
-export function el<
- TAG extends keyof ExtendedHTMLElementTagNameMap,
->(
- tag_name: TAG,
- attrs?: ElementAttributes]> | ddeStringable,
- ...addons: ddeElementAddon<
- ExtendedHTMLElementTagNameMap[NoInfer]
- >[], // TODO: for now addons must have the same element
-): TAG extends keyof ddeHTMLElementTagNameMap ? ddeHTMLElementTagNameMap[TAG] : ddeHTMLElement
-export function el(
- tag_name?: "<>",
-): ddeDocumentFragment
-export function el(
- tag_name: string,
- attrs?: ElementAttributes | ddeStringable,
- ...addons: ddeElementAddon[]
-): ddeHTMLElement
-export { el as createElement }
-
-export function elNS(
- namespace: "http://www.w3.org/2000/svg"
-): <
- TAG extends keyof SVGElementTagNameMap & string,
- EL extends ( TAG extends keyof SVGElementTagNameMap ? SVGElementTagNameMap[TAG] : SVGElement ),
->(
- tag_name: TAG,
- attrs?: ElementAttributes> | ddeStringable,
- ...addons: ddeElementAddon>[]
-)=> TAG extends keyof ddeSVGElementTagNameMap ? ddeSVGElementTagNameMap[TAG] : ddeSVGElement
-export function elNS(
- namespace: "http://www.w3.org/1998/Math/MathML"
-): <
- TAG extends keyof MathMLElementTagNameMap & string,
- EL extends ( TAG extends keyof MathMLElementTagNameMap ? MathMLElementTagNameMap[TAG] : MathMLElement ),
->(
- tag_name: TAG,
- attrs?: ddeStringable | Partial<{
- [key in keyof EL]: EL[key] | ddeSignal | string | number | boolean
- }>,
- ...addons: ddeElementAddon>[]
-)=> ddeMathMLElement
-export function elNS(
- namespace: string
-): (
- tag_name: string,
- attrs?: string | ddeStringable | Record,
- ...addons: ddeElementAddon[]
-)=> SupportedElement
-export { elNS as createElementNS }
-
-export function chainableAppend(el: EL): EL;
-/** Simulate slots for ddeComponents */
-export function simulateSlots(
- root: EL,
-): EL
-/**
- * Simulate slots in Custom Elements without using `shadowRoot`.
- * @param el Custom Element root element
- * @param body Body of the custom element
- * */
-export function simulateSlots(
- el: HTMLElement,
- body: EL,
-): EL
-
-export function dispatchEvent(name: keyof DocumentEventMap | string, element: SupportedElement):
- (data?: any)=> void;
-export function dispatchEvent(name: keyof DocumentEventMap | string, options?: EventInit):
- (element: SupportedElement, data?: any)=> void;
-export function dispatchEvent(
- name: keyof DocumentEventMap | string,
- options: EventInit | null,
- element: SupportedElement | (()=> SupportedElement)
-): (data?: any)=> void;
-interface On{
- /** Listens to the DOM event. See {@link Document.addEventListener} */
- <
- Event extends keyof DocumentEventMap,
- EE extends ddeElementAddon= ddeElementAddon,
- >(
- type: Event,
- listener: (this: EE extends ddeElementAddon ? El : never, ev: DocumentEventMap[Event]) => any,
- options?: AddEventListenerOptions
- ) : EE;
- <
- EE extends ddeElementAddon= ddeElementAddon,
- >(
- type: string,
- listener: (this: EE extends ddeElementAddon ? El : never, ev: Event | CustomEvent ) => any,
- options?: AddEventListenerOptions
- ) : EE;
- /** Listens to the element is connected to the live DOM. In case of custom elements uses [`connectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
- connected<
- EE extends ddeElementAddon,
- El extends ( EE extends ddeElementAddon ? El : never )
- >(
- listener: (this: El, event: CustomEvent) => any,
- options?: AddEventListenerOptions
- ) : EE;
- /** Listens to the element is disconnected from the live DOM. In case of custom elements uses [`disconnectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
- disconnected<
- EE extends ddeElementAddon,
- El extends ( EE extends ddeElementAddon ? El : never )
- >(
- listener: (this: El, event: CustomEvent) => any,
- options?: AddEventListenerOptions
- ) : EE;
- /** Listens to the element attribute changes. In case of custom elements uses [`attributeChangedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */// editorconfig-checker-disable-line
- attributeChanged<
- EE extends ddeElementAddon,
- El extends ( EE extends ddeElementAddon ? El : never )
- >(
- listener: (this: El, event: CustomEvent<[ string, string ]>) => any,
- options?: AddEventListenerOptions
- ) : EE;
-}
-export const on: On;
-
-type Scope= {
- scope: Node | Function | Object,
- host: ddeElementAddon,
- custom_element: false | HTMLElement,
- prevent: boolean
-};
-/** Current scope created last time the `el(Function)` was invoke. (Or {@link scope.push}) */
-export const scope: {
- current: Scope,
- /** Stops all automatizations. E. g. signals used as attributes in current scope
- * registers removing these listeners (and clean signal if no other listeners are detected)
- * on `disconnected` event. */
- preventDefault(prevent: T): T,
- /**
- * This represents reference to the current host element — `scope.host()`.
- * It can be also used to register Addon(s) (functions to be called when component is initized)
- * — `scope.host(on.connected(console.log))`.
- * */
- host: (...addons: ddeElementAddon[])=> HTMLElement,
-
- state: Scope[],
- /** Adds new child scope. All attributes are inherited by default. */
- push(scope?: Partial): ReturnType["push"]>,
- /** Adds root scope as a child of the current scope. */
- pushRoot(): ReturnType["push"]>,
- /** Removes last/current child scope. */
- pop(): ReturnType["pop"]>,
-};
-
-export function customElementRender<
- EL extends HTMLElement,
- P extends any = Record>
->(
- target: ShadowRoot | EL,
- render: (props: P)=> SupportedElement | DocumentFragment,
- props?: P | ((el: EL)=> P)
-): EL
-export function customElementWithDDE HTMLElement)>(custom_element: EL): EL
-export function lifecyclesToEvents HTMLElement)>(custom_element: EL): EL
-export function observedAttributes(custom_element: HTMLElement): Record
-
-/**
- * This is used primarly for server side rendering. To be sure that all async operations
- * are finished before the page is sent to the client.
- * ```
- * // on component
- * function component(){
- * …
- * queue(fetch(...).then(...));
- * }
- *
- * // building the page
- * async function build(){
- * const { component }= await import("./component.js");
- * document.body.append(el(component));
- * await queue();
- * retutn document.body.innerHTML;
- * }
- * ```
- * */
-export function queue(promise?: Promise): Promise;
-
-/* TypeScript MEH */
-declare global{
- type ddeAppend= (...nodes: (Node | string)[])=> el;
-
- interface ddeDocumentFragment extends DocumentFragment{ append: ddeAppend; }
- interface ddeHTMLElement extends HTMLElement{ append: ddeAppend; }
- interface ddeSVGElement extends SVGElement{ append: ddeAppend; }
- interface ddeMathMLElement extends MathMLElement{ append: ddeAppend; }
-
- interface ddeHTMLElementTagNameMap {
- "a": ddeHTMLAnchorElement;
- "area": ddeHTMLAreaElement;
- "audio": ddeHTMLAudioElement;
- "base": ddeHTMLBaseElement;
- "blockquote": ddeHTMLQuoteElement;
- "body": ddeHTMLBodyElement;
- "br": ddeHTMLBRElement;
- "button": ddeHTMLButtonElement;
- "canvas": ddeHTMLCanvasElement;
- "caption": ddeHTMLTableCaptionElement;
- "col": ddeHTMLTableColElement;
- "colgroup": ddeHTMLTableColElement;
- "data": ddeHTMLDataElement;
- "datalist": ddeHTMLDataListElement;
- "del": ddeHTMLModElement;
- "details": ddeHTMLDetailsElement;
- "dialog": ddeHTMLDialogElement;
- "div": ddeHTMLDivElement;
- "dl": ddeHTMLDListElement;
- "embed": ddeHTMLEmbedElement;
- "fieldset": ddeHTMLFieldSetElement;
- "form": ddeHTMLFormElement;
- "h1": ddeHTMLHeadingElement;
- "h2": ddeHTMLHeadingElement;
- "h3": ddeHTMLHeadingElement;
- "h4": ddeHTMLHeadingElement;
- "h5": ddeHTMLHeadingElement;
- "h6": ddeHTMLHeadingElement;
- "head": ddeHTMLHeadElement;
- "hr": ddeHTMLHRElement;
- "html": ddeHTMLHtmlElement;
- "iframe": ddeHTMLIFrameElement;
- "img": ddeHTMLImageElement;
- "input": ddeHTMLInputElement;
- "ins": ddeHTMLModElement;
- "label": ddeHTMLLabelElement;
- "legend": ddeHTMLLegendElement;
- "li": ddeHTMLLIElement;
- "link": ddeHTMLLinkElement;
- "map": ddeHTMLMapElement;
- "menu": ddeHTMLMenuElement;
- "meta": ddeHTMLMetaElement;
- "meter": ddeHTMLMeterElement;
- "object": ddeHTMLObjectElement;
- "ol": ddeHTMLOListElement;
- "optgroup": ddeHTMLOptGroupElement;
- "option": ddeHTMLOptionElement;
- "output": ddeHTMLOutputElement;
- "p": ddeHTMLParagraphElement;
- "picture": ddeHTMLPictureElement;
- "pre": ddeHTMLPreElement;
- "progress": ddeHTMLProgressElement;
- "q": ddeHTMLQuoteElement;
- "script": ddeHTMLScriptElement;
- "select": ddeHTMLSelectElement;
- "slot": ddeHTMLSlotElement;
- "source": ddeHTMLSourceElement;
- "span": ddeHTMLSpanElement;
- "style": ddeHTMLStyleElement;
- "table": ddeHTMLTableElement;
- "tbody": ddeHTMLTableSectionElement;
- "td": ddeHTMLTableCellElement;
- "template": ddeHTMLTemplateElement;
- "textarea": ddeHTMLTextAreaElement;
- "tfoot": ddeHTMLTableSectionElement;
- "th": ddeHTMLTableCellElement;
- "thead": ddeHTMLTableSectionElement;
- "time": ddeHTMLTimeElement;
- "title": ddeHTMLTitleElement;
- "tr": ddeHTMLTableRowElement;
- "track": ddeHTMLTrackElement;
- "ul": ddeHTMLUListElement;
- "video": ddeHTMLVideoElement;
- }
- interface ddeSVGElementTagNameMap {
- "a": ddeSVGAElement;
- "animate": ddeSVGAnimateElement;
- "animateMotion": ddeSVGAnimateMotionElement;
- "animateTransform": ddeSVGAnimateTransformElement;
- "circle": ddeSVGCircleElement;
- "clipPath": ddeSVGClipPathElement;
- "defs": ddeSVGDefsElement;
- "desc": ddeSVGDescElement;
- "ellipse": ddeSVGEllipseElement;
- "feBlend": ddeSVGFEBlendElement;
- "feColorMatrix": ddeSVGFEColorMatrixElement;
- "feComponentTransfer": ddeSVGFEComponentTransferElement;
- "feComposite": ddeSVGFECompositeElement;
- "feConvolveMatrix": ddeSVGFEConvolveMatrixElement;
- "feDiffuseLighting": ddeSVGFEDiffuseLightingElement;
- "feDisplacementMap": ddeSVGFEDisplacementMapElement;
- "feDistantLight": ddeSVGFEDistantLightElement;
- "feDropShadow": ddeSVGFEDropShadowElement;
- "feFlood": ddeSVGFEFloodElement;
- "feFuncA": ddeSVGFEFuncAElement;
- "feFuncB": ddeSVGFEFuncBElement;
- "feFuncG": ddeSVGFEFuncGElement;
- "feFuncR": ddeSVGFEFuncRElement;
- "feGaussianBlur": ddeSVGFEGaussianBlurElement;
- "feImage": ddeSVGFEImageElement;
- "feMerge": ddeSVGFEMergeElement;
- "feMergeNode": ddeSVGFEMergeNodeElement;
- "feMorphology": ddeSVGFEMorphologyElement;
- "feOffset": ddeSVGFEOffsetElement;
- "fePointLight": ddeSVGFEPointLightElement;
- "feSpecularLighting": ddeSVGFESpecularLightingElement;
- "feSpotLight": ddeSVGFESpotLightElement;
- "feTile": ddeSVGFETileElement;
- "feTurbulence": ddeSVGFETurbulenceElement;
- "filter": ddeSVGFilterElement;
- "foreignObject": ddeSVGForeignObjectElement;
- "g": ddeSVGGElement;
- "image": ddeSVGImageElement;
- "line": ddeSVGLineElement;
- "linearGradient": ddeSVGLinearGradientElement;
- "marker": ddeSVGMarkerElement;
- "mask": ddeSVGMaskElement;
- "metadata": ddeSVGMetadataElement;
- "mpath": ddeSVGMPathElement;
- "path": ddeSVGPathElement;
- "pattern": ddeSVGPatternElement;
- "polygon": ddeSVGPolygonElement;
- "polyline": ddeSVGPolylineElement;
- "radialGradient": ddeSVGRadialGradientElement;
- "rect": ddeSVGRectElement;
- "script": ddeSVGScriptElement;
- "set": ddeSVGSetElement;
- "stop": ddeSVGStopElement;
- "style": ddeSVGStyleElement;
- "svg": ddeSVGSVGElement;
- "switch": ddeSVGSwitchElement;
- "symbol": ddeSVGSymbolElement;
- "text": ddeSVGTextElement;
- "textPath": ddeSVGTextPathElement;
- "title": ddeSVGTitleElement;
- "tspan": ddeSVGTSpanElement;
- "use": ddeSVGUseElement;
- "view": ddeSVGViewElement;
- }
-}
-
-// editorconfig-checker-disable
-interface ddeHTMLAnchorElement extends HTMLAnchorElement{ append: ddeAppend; }
-interface ddeHTMLAreaElement extends HTMLAreaElement{ append: ddeAppend; }
-interface ddeHTMLAudioElement extends HTMLAudioElement{ append: ddeAppend; }
-interface ddeHTMLBaseElement extends HTMLBaseElement{ append: ddeAppend; }
-interface ddeHTMLQuoteElement extends HTMLQuoteElement{ append: ddeAppend; }
-interface ddeHTMLBodyElement extends HTMLBodyElement{ append: ddeAppend; }
-interface ddeHTMLBRElement extends HTMLBRElement{ append: ddeAppend; }
-interface ddeHTMLButtonElement extends HTMLButtonElement{ append: ddeAppend; }
-interface ddeHTMLCanvasElement extends HTMLCanvasElement{ append: ddeAppend; }
-interface ddeHTMLTableCaptionElement extends HTMLTableCaptionElement{ append: ddeAppend; }
-interface ddeHTMLTableColElement extends HTMLTableColElement{ append: ddeAppend; }
-interface ddeHTMLTableColElement extends HTMLTableColElement{ append: ddeAppend; }
-interface ddeHTMLDataElement extends HTMLDataElement{ append: ddeAppend; }
-interface ddeHTMLDataListElement extends HTMLDataListElement{ append: ddeAppend; }
-interface ddeHTMLModElement extends HTMLModElement{ append: ddeAppend; }
-interface ddeHTMLDetailsElement extends HTMLDetailsElement{ append: ddeAppend; }
-interface ddeHTMLDialogElement extends HTMLDialogElement{ append: ddeAppend; }
-interface ddeHTMLDivElement extends HTMLDivElement{ append: ddeAppend; }
-interface ddeHTMLDListElement extends HTMLDListElement{ append: ddeAppend; }
-interface ddeHTMLEmbedElement extends HTMLEmbedElement{ append: ddeAppend; }
-interface ddeHTMLFieldSetElement extends HTMLFieldSetElement{ append: ddeAppend; }
-interface ddeHTMLFormElement extends HTMLFormElement{ append: ddeAppend; }
-interface ddeHTMLHeadingElement extends HTMLHeadingElement{ append: ddeAppend; }
-interface ddeHTMLHeadElement extends HTMLHeadElement{ append: ddeAppend; }
-interface ddeHTMLHRElement extends HTMLHRElement{ append: ddeAppend; }
-interface ddeHTMLHtmlElement extends HTMLHtmlElement{ append: ddeAppend; }
-interface ddeHTMLIFrameElement extends HTMLIFrameElement{ append: ddeAppend; }
-interface ddeHTMLImageElement extends HTMLImageElement{ append: ddeAppend; }
-interface ddeHTMLInputElement extends HTMLInputElement{ append: ddeAppend; }
-interface ddeHTMLLabelElement extends HTMLLabelElement{ append: ddeAppend; }
-interface ddeHTMLLegendElement extends HTMLLegendElement{ append: ddeAppend; }
-interface ddeHTMLLIElement extends HTMLLIElement{ append: ddeAppend; }
-interface ddeHTMLLinkElement extends HTMLLinkElement{ append: ddeAppend; }
-interface ddeHTMLMapElement extends HTMLMapElement{ append: ddeAppend; }
-interface ddeHTMLMenuElement extends HTMLMenuElement{ append: ddeAppend; }
-interface ddeHTMLMetaElement extends HTMLMetaElement{ append: ddeAppend; }
-interface ddeHTMLMeterElement extends HTMLMeterElement{ append: ddeAppend; }
-interface ddeHTMLObjectElement extends HTMLObjectElement{ append: ddeAppend; }
-interface ddeHTMLOListElement extends HTMLOListElement{ append: ddeAppend; }
-interface ddeHTMLOptGroupElement extends HTMLOptGroupElement{ append: ddeAppend; }
-interface ddeHTMLOptionElement extends HTMLOptionElement{ append: ddeAppend; }
-interface ddeHTMLOutputElement extends HTMLOutputElement{ append: ddeAppend; }
-interface ddeHTMLParagraphElement extends HTMLParagraphElement{ append: ddeAppend; }
-interface ddeHTMLPictureElement extends HTMLPictureElement{ append: ddeAppend; }
-interface ddeHTMLPreElement extends HTMLPreElement{ append: ddeAppend; }
-interface ddeHTMLProgressElement extends HTMLProgressElement{ append: ddeAppend; }
-interface ddeHTMLScriptElement extends HTMLScriptElement{ append: ddeAppend; }
-interface ddeHTMLSelectElement extends HTMLSelectElement{ append: ddeAppend; }
-interface ddeHTMLSlotElement extends HTMLSlotElement{ append: ddeAppend; }
-interface ddeHTMLSourceElement extends HTMLSourceElement{ append: ddeAppend; }
-interface ddeHTMLSpanElement extends HTMLSpanElement{ append: ddeAppend; }
-interface ddeHTMLStyleElement extends HTMLStyleElement{ append: ddeAppend; }
-interface ddeHTMLTableElement extends HTMLTableElement{ append: ddeAppend; }
-interface ddeHTMLTableSectionElement extends HTMLTableSectionElement{ append: ddeAppend; }
-interface ddeHTMLTableCellElement extends HTMLTableCellElement{ append: ddeAppend; }
-interface ddeHTMLTemplateElement extends HTMLTemplateElement{ append: ddeAppend; }
-interface ddeHTMLTextAreaElement extends HTMLTextAreaElement{ append: ddeAppend; }
-interface ddeHTMLTableCellElement extends HTMLTableCellElement{ append: ddeAppend; }
-interface ddeHTMLTimeElement extends HTMLTimeElement{ append: ddeAppend; }
-interface ddeHTMLTitleElement extends HTMLTitleElement{ append: ddeAppend; }
-interface ddeHTMLTableRowElement extends HTMLTableRowElement{ append: ddeAppend; }
-interface ddeHTMLTrackElement extends HTMLTrackElement{ append: ddeAppend; }
-interface ddeHTMLUListElement extends HTMLUListElement{ append: ddeAppend; }
-interface ddeHTMLVideoElement extends HTMLVideoElement{ append: ddeAppend; }
-interface ddeSVGAElement extends SVGAElement{ append: ddeAppend; }
-interface ddeSVGAnimateElement extends SVGAnimateElement{ append: ddeAppend; }
-interface ddeSVGAnimateMotionElement extends SVGAnimateMotionElement{ append: ddeAppend; }
-interface ddeSVGAnimateTransformElement extends SVGAnimateTransformElement{ append: ddeAppend; }
-interface ddeSVGCircleElement extends SVGCircleElement{ append: ddeAppend; }
-interface ddeSVGClipPathElement extends SVGClipPathElement{ append: ddeAppend; }
-interface ddeSVGDefsElement extends SVGDefsElement{ append: ddeAppend; }
-interface ddeSVGDescElement extends SVGDescElement{ append: ddeAppend; }
-interface ddeSVGEllipseElement extends SVGEllipseElement{ append: ddeAppend; }
-interface ddeSVGFEBlendElement extends SVGFEBlendElement{ append: ddeAppend; }
-interface ddeSVGFEColorMatrixElement extends SVGFEColorMatrixElement{ append: ddeAppend; }
-interface ddeSVGFEComponentTransferElement extends SVGFEComponentTransferElement{ append: ddeAppend; }
-interface ddeSVGFECompositeElement extends SVGFECompositeElement{ append: ddeAppend; }
-interface ddeSVGFEConvolveMatrixElement extends SVGFEConvolveMatrixElement{ append: ddeAppend; }
-interface ddeSVGFEDiffuseLightingElement extends SVGFEDiffuseLightingElement{ append: ddeAppend; }
-interface ddeSVGFEDisplacementMapElement extends SVGFEDisplacementMapElement{ append: ddeAppend; }
-interface ddeSVGFEDistantLightElement extends SVGFEDistantLightElement{ append: ddeAppend; }
-interface ddeSVGFEDropShadowElement extends SVGFEDropShadowElement{ append: ddeAppend; }
-interface ddeSVGFEFloodElement extends SVGFEFloodElement{ append: ddeAppend; }
-interface ddeSVGFEFuncAElement extends SVGFEFuncAElement{ append: ddeAppend; }
-interface ddeSVGFEFuncBElement extends SVGFEFuncBElement{ append: ddeAppend; }
-interface ddeSVGFEFuncGElement extends SVGFEFuncGElement{ append: ddeAppend; }
-interface ddeSVGFEFuncRElement extends SVGFEFuncRElement{ append: ddeAppend; }
-interface ddeSVGFEGaussianBlurElement extends SVGFEGaussianBlurElement{ append: ddeAppend; }
-interface ddeSVGFEImageElement extends SVGFEImageElement{ append: ddeAppend; }
-interface ddeSVGFEMergeElement extends SVGFEMergeElement{ append: ddeAppend; }
-interface ddeSVGFEMergeNodeElement extends SVGFEMergeNodeElement{ append: ddeAppend; }
-interface ddeSVGFEMorphologyElement extends SVGFEMorphologyElement{ append: ddeAppend; }
-interface ddeSVGFEOffsetElement extends SVGFEOffsetElement{ append: ddeAppend; }
-interface ddeSVGFEPointLightElement extends SVGFEPointLightElement{ append: ddeAppend; }
-interface ddeSVGFESpecularLightingElement extends SVGFESpecularLightingElement{ append: ddeAppend; }
-interface ddeSVGFESpotLightElement extends SVGFESpotLightElement{ append: ddeAppend; }
-interface ddeSVGFETileElement extends SVGFETileElement{ append: ddeAppend; }
-interface ddeSVGFETurbulenceElement extends SVGFETurbulenceElement{ append: ddeAppend; }
-interface ddeSVGFilterElement extends SVGFilterElement{ append: ddeAppend; }
-interface ddeSVGForeignObjectElement extends SVGForeignObjectElement{ append: ddeAppend; }
-interface ddeSVGGElement extends SVGGElement{ append: ddeAppend; }
-interface ddeSVGImageElement extends SVGImageElement{ append: ddeAppend; }
-interface ddeSVGLineElement extends SVGLineElement{ append: ddeAppend; }
-interface ddeSVGLinearGradientElement extends SVGLinearGradientElement{ append: ddeAppend; }
-interface ddeSVGMarkerElement extends SVGMarkerElement{ append: ddeAppend; }
-interface ddeSVGMaskElement extends SVGMaskElement{ append: ddeAppend; }
-interface ddeSVGMetadataElement extends SVGMetadataElement{ append: ddeAppend; }
-interface ddeSVGMPathElement extends SVGMPathElement{ append: ddeAppend; }
-interface ddeSVGPathElement extends SVGPathElement{ append: ddeAppend; }
-interface ddeSVGPatternElement extends SVGPatternElement{ append: ddeAppend; }
-interface ddeSVGPolygonElement extends SVGPolygonElement{ append: ddeAppend; }
-interface ddeSVGPolylineElement extends SVGPolylineElement{ append: ddeAppend; }
-interface ddeSVGRadialGradientElement extends SVGRadialGradientElement{ append: ddeAppend; }
-interface ddeSVGRectElement extends SVGRectElement{ append: ddeAppend; }
-interface ddeSVGScriptElement extends SVGScriptElement{ append: ddeAppend; }
-interface ddeSVGSetElement extends SVGSetElement{ append: ddeAppend; }
-interface ddeSVGStopElement extends SVGStopElement{ append: ddeAppend; }
-interface ddeSVGStyleElement extends SVGStyleElement{ append: ddeAppend; }
-interface ddeSVGSVGElement extends SVGSVGElement{ append: ddeAppend; }
-interface ddeSVGSwitchElement extends SVGSwitchElement{ append: ddeAppend; }
-interface ddeSVGSymbolElement extends SVGSymbolElement{ append: ddeAppend; }
-interface ddeSVGTextElement extends SVGTextElement{ append: ddeAppend; }
-interface ddeSVGTextPathElement extends SVGTextPathElement{ append: ddeAppend; }
-interface ddeSVGTitleElement extends SVGTitleElement{ append: ddeAppend; }
-interface ddeSVGTSpanElement extends SVGTSpanElement{ append: ddeAppend; }
-interface ddeSVGUseElement extends SVGUseElement{ append: ddeAppend; }
-interface ddeSVGViewElement extends SVGViewElement{ append: ddeAppend; }
-// editorconfig-checker-enable
-export interface Signal {
- /** The current value of the signal */
- get(): V;
- /** Set new value of the signal */
- set(value: V): V;
- toJSON(): V;
- valueOf(): V;
-}
-type Action= (this: { value: V, stopPropagation(): void }, ...a: any[])=> typeof signal._ | void;
-//type SymbolSignal= Symbol;
-type SymbolOnclear= symbol;
-type Actions= Record>;
-type OnListenerOptions= Pick & { first_time?: boolean };
-interface signal{
- _: Symbol
- /**
- * Computations signal. This creates a signal which is computed from other signals.
- * */
- any>(computation: V): Signal, {}>
- /**
- * Simple example:
- * ```js
- * const hello= S("Hello Signal");
- * ```
- * …simple todo signal:
- * ```js
- * const todos= S([], {
- * add(v){ this.value.push(S(v)); },
- * remove(i){ this.value.splice(i, 1); },
- * [S.symbols.onclear](){ S.clear(...this.value); },
- * });
- * ```
- * …computed signal:
- * ```js
- * const name= S("Jan");
- * const surname= S("Andrle");
- * const fullname= S(()=> name.get()+" "+surname.get());
- * ```
- * @param value Initial signal value. Or function computing value from other signals.
- * @param actions Use to define actions on the signal. Such as add item to the array.
- * There is also a reserved function `S.symbol.onclear` which is called when the signal is cleared
- * by `S.clear`.
- * */
- >(value: V, actions?: A): Signal;
- action>, A extends (S extends Signal ? A : never), N extends keyof A>(
- signal: S,
- name: N,
- ...params: A[N] extends (...args: infer P)=> any ? P : never
- ): void;
- clear(...signals: Signal[]): void;
- on(signal: Signal, onchange: (a: T)=> void, options?: OnListenerOptions): void;
- symbols: {
- //signal: SymbolSignal;
- onclear: SymbolOnclear;
- }
- /**
- * Reactive element, which is rendered based on the given signal.
- * ```js
- * S.el(signal, value=> value ? el("b", "True") : el("i", "False"));
- * S.el(listS, list=> list.map(li=> el("li", li)));
- * ```
- * */
- el(signal: Signal, el: (v: S)=> Element | Element[] | DocumentFragment): DocumentFragment;
-
- observedAttributes(custom_element: HTMLElement): Record>;
-}
-export const signal: signal;
-export const S: signal;
-declare global {
- type ddeSignal= Signal;
- type ddeAction= Action
- type ddeActions= Actions
-}
\ No newline at end of file
diff --git a/dist/esm-with-signals.d.ts b/dist/esm-with-signals.d.ts
index c22a98a..1cf65ca 100644
--- a/dist/esm-with-signals.d.ts
+++ b/dist/esm-with-signals.d.ts
@@ -4,7 +4,7 @@ export interface Signal {
/** The current value of the signal */
get(): V;
/** Set new value of the signal */
- set(value: V): V;
+ set(value: V, force?: boolean): V;
toJSON(): V;
valueOf(): V;
}
@@ -173,17 +173,30 @@ declare function dispatchEvent$1(name: keyof DocumentEventMap | string, options?
declare function dispatchEvent$1(name: keyof DocumentEventMap | string, options: EventInit | null, host: Host): (data?: any) => void;
export interface On {
/** Listens to the DOM event. See {@link Document.addEventListener} */
- = ddeElementAddon>(type: Event, listener: (this: EE extends ddeElementAddon ? El : never, ev: DocumentEventMap[Event]) => any, options?: AddEventListenerOptions): EE;
+ (type: Event, listener: (this: EL, ev: DocumentEventMap[Event] & {
+ target: EL;
+ }) => any, options?: AddEventListenerOptions): ddeElementAddon;
= ddeElementAddon>(type: string, listener: (this: EE extends ddeElementAddon ? El : never, ev: Event | CustomEvent) => any, options?: AddEventListenerOptions): EE;
/** Listens to the element is connected to the live DOM. In case of custom elements uses [`connectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */ // editorconfig-checker-disable-line
- connected, El extends (EE extends ddeElementAddon ? El : never)>(listener: (this: El, event: CustomEvent) => any, options?: AddEventListenerOptions): EE;
+ connected(listener: (this: EL, event: CustomEvent>) => any, options?: AddEventListenerOptions): ddeElementAddon;
/** Listens to the element is disconnected from the live DOM. In case of custom elements uses [`disconnectedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */ // editorconfig-checker-disable-line
- disconnected, El extends (EE extends ddeElementAddon ? El : never)>(listener: (this: El, event: CustomEvent) => any, options?: AddEventListenerOptions): EE;
- /** Listens to the element attribute changes. In case of custom elements uses [`attributeChangedCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks), or {@link MutationObserver} else where */ // editorconfig-checker-disable-line
- attributeChanged, El extends (EE extends ddeElementAddon ? El : never)>(listener: (this: El, event: CustomEvent<[
- string,
- string
- ]>) => any, options?: AddEventListenerOptions): EE;
+ disconnected(listener: (this: EL, event: CustomEvent) => any, options?: AddEventListenerOptions): ddeElementAddon;
+ /**
+ * Fires after the next tick of the Javascript event loop.
+ * This is handy for example to apply some property depending on the element content:
+ * ```js
+ * const selected= "Z";
+ * //...
+ * return el("form").append(
+ * el("select", null, on.defer(e=> e.value=selected)).append(
+ * el("option", { value: "A", textContent: "A" }),
+ * //...
+ * el("option", { value: "Z", textContent: "Z" }),
+ * ),
+ * );
+ * ```
+ * */
+ defer(listener: (element: EL) => any): ddeElementAddon;
}
export const on: On;
export type Scope = {
diff --git a/dist/esm-with-signals.js b/dist/esm-with-signals.js
index d223107..06a87bb 100644
--- a/dist/esm-with-signals.js
+++ b/dist/esm-with-signals.js
@@ -55,38 +55,7 @@ var Defined = class extends Error {
}
};
-// src/signals-lib/common.js
-var signals_global = {
- /**
- * Checks if a value is a signal
- * @param {any} attributes - Value to check
- * @returns {boolean} Whether the value is a signal
- */
- isSignal(attributes) {
- return false;
- },
- /**
- * Processes an attribute that might be reactive
- * @param {Element} obj - Element that owns the attribute
- * @param {string} key - Attribute name
- * @param {any} attr - Attribute value
- * @param {Function} set - Function to set the attribute
- * @returns {any} Processed attribute value
- */
- processReactiveAttribute(obj, key, attr, set) {
- return attr;
- }
-};
-function registerReactivity(def, global = true) {
- if (global) return oAssign(signals_global, def);
- Object.setPrototypeOf(def, signals_global);
- return def;
-}
-function signals(_this) {
- return isProtoFrom(_this, signals_global) && _this !== signals_global ? _this : signals_global;
-}
-
-// src/dom-common.js
+// src/dom-lib/common.js
var enviroment = {
setDeleteAttr,
ssr: "",
@@ -112,7 +81,7 @@ var evc = "dde:connected";
var evd = "dde:disconnected";
var eva = "dde:attributeChanged";
-// src/events-observer.js
+// src/dom-lib/events-observer.js
var c_ch_o = enviroment.M ? connectionsChangesObserverConstructor() : new Proxy({}, {
get() {
return () => {
@@ -276,7 +245,7 @@ function connectionsChangesObserverConstructor() {
}
}
-// src/events.js
+// src/dom-lib/events.js
function dispatchEvent(name, options, host) {
if (typeof options === "function") {
host = options;
@@ -298,6 +267,7 @@ function on(event, listener, options) {
return element;
};
}
+on.defer = (fn) => setTimeout.bind(null, fn, 0);
var lifeOptions = (obj) => oAssign({}, typeof obj === "object" ? obj : null, { once: true });
on.connected = function(listener, options) {
options = lifeOptions(options);
@@ -321,10 +291,7 @@ on.disconnected = function(listener, options) {
};
};
-// src/dom.js
-function queue(promise) {
- return enviroment.q(promise);
-}
+// src/dom-lib/scopes.js
var scopes = [{
get scope() {
return enviroment.D.body;
@@ -399,6 +366,60 @@ var scope = {
return scopes.pop();
}
};
+
+// src/signals-lib/common.js
+var signals_global = {
+ /**
+ * Checks if a value is a signal
+ * @param {any} attributes - Value to check
+ * @returns {boolean} Whether the value is a signal
+ */
+ isSignal(attributes) {
+ return false;
+ },
+ /**
+ * Processes an attribute that might be reactive
+ * @param {Element} obj - Element that owns the attribute
+ * @param {string} key - Attribute name
+ * @param {any} attr - Attribute value
+ * @param {Function} set - Function to set the attribute
+ * @returns {any} Processed attribute value
+ */
+ processReactiveAttribute(obj, key, attr, set) {
+ return attr;
+ }
+};
+function registerReactivity(def, global = true) {
+ if (global) return oAssign(signals_global, def);
+ Object.setPrototypeOf(def, signals_global);
+ return def;
+}
+function signals(_this) {
+ return isProtoFrom(_this, signals_global) && _this !== signals_global ? _this : signals_global;
+}
+
+// src/dom-lib/helpers.js
+function setRemove(obj, prop, key, val) {
+ return obj[(isUndef(val) ? "remove" : "set") + prop](key, val);
+}
+function setRemoveNS(obj, prop, key, val, ns = null) {
+ return obj[(isUndef(val) ? "remove" : "set") + prop + "NS"](ns, key, val);
+}
+function setDelete(obj, key, val) {
+ Reflect.set(obj, key, val);
+ if (!isUndef(val)) return;
+ return Reflect.deleteProperty(obj, key);
+}
+function elementAttribute(element, op, key, value) {
+ if (isInstance(element, enviroment.H))
+ return element[op + "Attribute"](key, value);
+ return element[op + "AttributeNS"](null, key, value);
+}
+
+// src/dom-lib/el.js
+function queue(promise) {
+ return enviroment.q(promise);
+}
function append(...els) {
this.appendOriginal(...els);
return this;
@@ -414,7 +435,8 @@ function createElement(tag, attributes, ...addons) {
const s = signals(this);
let scoped = 0;
let el, el_host;
- if (Object(attributes) !== attributes || s.isSignal(attributes))
+ const att_type = typeof attributes;
+ if (att_type === "string" || att_type === "number" || s.isSignal(attributes))
attributes = { textContent: attributes };
switch (true) {
case typeof tag === "function": {
@@ -468,38 +490,6 @@ function createElementNS(ns) {
return el;
};
}
-function simulateSlots(element, root = element) {
- const mark_e = "\xB9\u2070", mark_s = "\u2713";
- const slots = Object.fromEntries(
- Array.from(root.querySelectorAll("slot")).filter((s) => !s.name.endsWith(mark_e)).map((s) => [s.name += mark_e, s])
- );
- element.append = new Proxy(element.append, {
- apply(orig, _, els) {
- if (els[0] === root) return orig.apply(element, els);
- for (const el of els) {
- const name = (el.slot || "") + mark_e;
- try {
- elementAttribute(el, "remove", "slot");
- } catch (_error) {
- }
- const slot = slots[name];
- if (!slot) return;
- if (!slot.name.startsWith(mark_s)) {
- slot.childNodes.forEach((c) => c.remove());
- slot.name = mark_s + name;
- }
- slot.append(el);
- }
- element.append = orig;
- return element;
- }
- });
- if (element !== root) {
- const els = Array.from(element.childNodes);
- element.append(...els);
- }
- return root;
-}
var assign_context = /* @__PURE__ */ new WeakMap();
var { setDeleteAttr: setDeleteAttr2 } = enviroment;
function assign(element, ...attributes) {
@@ -562,11 +552,6 @@ function classListDeclarative(element, toggle) {
);
return element;
}
-function elementAttribute(element, op, key, value) {
- if (isInstance(element, enviroment.H))
- return element[op + "Attribute"](key, value);
- return element[op + "AttributeNS"](null, key, value);
-}
function isPropSetter(el, key) {
if (!(key in el)) return false;
const des = getPropDescriptor(el, key);
@@ -590,19 +575,40 @@ function forEachEntries(s, target, element, obj, cb) {
cb(key, val);
});
}
-function setRemove(obj, prop, key, val) {
- return obj[(isUndef(val) ? "remove" : "set") + prop](key, val);
-}
-function setRemoveNS(obj, prop, key, val, ns = null) {
- return obj[(isUndef(val) ? "remove" : "set") + prop + "NS"](ns, key, val);
-}
-function setDelete(obj, key, val) {
- Reflect.set(obj, key, val);
- if (!isUndef(val)) return;
- return Reflect.deleteProperty(obj, key);
-}
-// src/customElement.js
+// src/dom-lib/customElement.js
+function simulateSlots(element, root = element) {
+ const mark_e = "\xB9\u2070", mark_s = "\u2713";
+ const slots = Object.fromEntries(
+ Array.from(root.querySelectorAll("slot")).filter((s) => !s.name.endsWith(mark_e)).map((s) => [s.name += mark_e, s])
+ );
+ element.append = new Proxy(element.append, {
+ apply(orig, _, els) {
+ if (els[0] === root) return orig.apply(element, els);
+ for (const el of els) {
+ const name = (el.slot || "") + mark_e;
+ try {
+ elementAttribute(el, "remove", "slot");
+ } catch (_error) {
+ }
+ const slot = slots[name];
+ if (!slot) return;
+ if (!slot.name.startsWith(mark_s)) {
+ slot.childNodes.forEach((c) => c.remove());
+ slot.name = mark_s + name;
+ }
+ slot.append(el);
+ }
+ element.append = orig;
+ return element;
+ }
+ });
+ if (element !== root) {
+ const els = Array.from(element.childNodes);
+ element.append(...els);
+ }
+ return root;
+}
function customElementRender(target, render, props = {}) {
const custom_element = target.host || target;
scope.push({
@@ -683,19 +689,19 @@ memo.scope = function memoScope(fun, { signal: signal2, onlyLast } = {}) {
// src/signals-lib/helpers.js
var mark = "__dde_signal";
var queueSignalWrite = /* @__PURE__ */ (() => {
- let pendingSignals = /* @__PURE__ */ new Set();
+ let pendingSignals = /* @__PURE__ */ new Map();
let scheduled = false;
function flushSignals() {
scheduled = false;
const todo = pendingSignals;
- pendingSignals = /* @__PURE__ */ new Set();
- for (const signal2 of todo) {
+ pendingSignals = /* @__PURE__ */ new Map();
+ for (const [signal2, force] of todo) {
const M = signal2[mark];
- if (M) M.listeners.forEach((l) => l(M.value));
+ if (M) M.listeners.forEach((l) => l(M.value, force));
}
}
- return function(s) {
- pendingSignals.add(s);
+ return function(s, force = false) {
+ pendingSignals.set(s, pendingSignals.get(s) || force);
if (scheduled) return;
scheduled = true;
queueMicrotask(flushSignals);
@@ -732,11 +738,11 @@ function signal(value, actions) {
return create(false, value, actions);
if (isSignal(value)) return value;
const out = create(true);
- function contextReWatch() {
+ function contextReWatch(_, force) {
const [origin, ...deps_old] = deps.get(contextReWatch);
deps.set(contextReWatch, /* @__PURE__ */ new Set([origin]));
stack_watch.push(contextReWatch);
- write(out, value());
+ write(out, value(), force);
stack_watch.pop();
if (!deps_old.length) return;
const deps_curr = deps.get(contextReWatch);
@@ -758,7 +764,7 @@ signal.action = function(s, name, ...a) {
throw new Error(`Action "${name}" not defined. See ${mark}.actions.`);
actions[name].apply(M, a);
if (M.skip) return delete M.skip;
- queueSignalWrite(s);
+ queueSignalWrite(s, true);
};
signal.on = function on2(s, listener, options = {}) {
const { signal: as } = options;
@@ -967,7 +973,7 @@ function write(s, value, force) {
const M = s[mark];
if (!M || !force && M.value === value) return;
M.value = value;
- queueSignalWrite(s);
+ queueSignalWrite(s, force);
return value;
}
function addSignalListener(s, listener) {
@@ -1004,7 +1010,6 @@ export {
dispatchEvent,
createElement as el,
createElementNS as elNS,
- elementAttribute,
isSignal,
lifecyclesToEvents,
memo,
diff --git a/dist/esm-with-signals.min.d.ts b/dist/esm-with-signals.min.d.ts
index c22a98a..1cf65ca 100644
--- a/dist/esm-with-signals.min.d.ts
+++ b/dist/esm-with-signals.min.d.ts
@@ -4,7 +4,7 @@ export interface Signal