microtags 0.0.14 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +554 -20
  2. package/dist/build.cjs +412 -0
  3. package/dist/build.cjs.map +7 -0
  4. package/dist/build.d.ts +17 -0
  5. package/dist/build.d.ts.map +1 -0
  6. package/dist/build.js +395 -0
  7. package/dist/build.js.map +7 -0
  8. package/dist/builders.d.ts +70 -4
  9. package/dist/builders.d.ts.map +1 -1
  10. package/dist/{chunk-CCYWRJW6.js → chunk-46UEUDVX.js} +4 -26
  11. package/dist/chunk-46UEUDVX.js.map +7 -0
  12. package/dist/chunk-LS4L5QRD.js +26 -0
  13. package/dist/chunk-LS4L5QRD.js.map +7 -0
  14. package/dist/chunk-RKWPTT6P.js +69 -0
  15. package/dist/chunk-RKWPTT6P.js.map +7 -0
  16. package/dist/chunk-ZZ4ZLOQY.js +33 -0
  17. package/dist/chunk-ZZ4ZLOQY.js.map +7 -0
  18. package/dist/cli.cjs +536 -0
  19. package/dist/cli.cjs.map +7 -0
  20. package/dist/context.js +2 -1
  21. package/dist/esbuild.cjs +451 -0
  22. package/dist/esbuild.cjs.map +7 -0
  23. package/dist/esbuild.d.ts +7 -0
  24. package/dist/esbuild.d.ts.map +1 -0
  25. package/dist/esbuild.js +434 -0
  26. package/dist/esbuild.js.map +7 -0
  27. package/dist/factory.d.ts +7 -1
  28. package/dist/factory.d.ts.map +1 -1
  29. package/dist/htm.browser.cjs +591 -0
  30. package/dist/htm.browser.cjs.map +7 -0
  31. package/dist/htm.browser.d.ts +30 -0
  32. package/dist/htm.browser.d.ts.map +1 -0
  33. package/dist/htm.browser.js +498 -0
  34. package/dist/htm.browser.js.map +7 -0
  35. package/dist/htm.browser.min.js +3 -0
  36. package/dist/htm.browser.min.js.map +7 -0
  37. package/dist/htm.cjs +284 -0
  38. package/dist/htm.cjs.map +7 -0
  39. package/dist/htm.d.ts +14 -0
  40. package/dist/htm.d.ts.map +1 -0
  41. package/dist/htm.js +196 -0
  42. package/dist/htm.js.map +7 -0
  43. package/dist/htm.min.js +3 -0
  44. package/dist/htm.min.js.map +7 -0
  45. package/dist/index.cjs +125 -11
  46. package/dist/index.cjs.map +2 -2
  47. package/dist/index.d.ts +3 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +133 -17
  50. package/dist/index.js.map +2 -2
  51. package/dist/index.min.js +1 -1
  52. package/dist/index.min.js.map +3 -3
  53. package/dist/meta.json +411 -26
  54. package/dist/preact-shared.d.ts +61 -0
  55. package/dist/preact-shared.d.ts.map +1 -0
  56. package/dist/preact.browser.d.ts +8 -0
  57. package/dist/preact.browser.d.ts.map +1 -0
  58. package/dist/preact.browser.js +45 -0
  59. package/dist/preact.browser.js.map +7 -0
  60. package/dist/preact.browser.min.js +2 -0
  61. package/dist/preact.browser.min.js.map +7 -0
  62. package/dist/preact.cjs +128 -0
  63. package/dist/preact.cjs.map +7 -0
  64. package/dist/preact.d.ts +9 -0
  65. package/dist/preact.d.ts.map +1 -0
  66. package/dist/preact.js +35 -0
  67. package/dist/preact.js.map +7 -0
  68. package/dist/render-support.cjs +86 -0
  69. package/dist/render-support.cjs.map +7 -0
  70. package/dist/render-support.d.ts +23 -0
  71. package/dist/render-support.d.ts.map +1 -0
  72. package/dist/render-support.js +12 -0
  73. package/dist/render-support.js.map +7 -0
  74. package/dist/render-support.min.js +2 -0
  75. package/dist/render-support.min.js.map +7 -0
  76. package/dist/types.d.ts +8 -0
  77. package/dist/types.d.ts.map +1 -1
  78. package/dist/vite.cjs +448 -0
  79. package/dist/vite.cjs.map +7 -0
  80. package/dist/vite.d.ts +7 -0
  81. package/dist/vite.d.ts.map +1 -0
  82. package/dist/vite.js +429 -0
  83. package/dist/vite.js.map +7 -0
  84. package/package.json +92 -13
  85. package/dist/chunk-CCYWRJW6.js.map +0 -7
package/dist/htm.js ADDED
@@ -0,0 +1,196 @@
1
+ import "./chunk-RKWPTT6P.js";
2
+ import {
3
+ __name
4
+ } from "./chunk-7QVYU63E.js";
5
+
6
+ // src/htm.ts
7
+ import htm from "htm";
8
+ var _esc = {
9
+ "&": "&",
10
+ '"': """,
11
+ "'": "'",
12
+ "<": "&lt;",
13
+ ">": "&gt;"
14
+ };
15
+ function _escHtml(s) {
16
+ return s.replace(/[&"'<>]/g, (c) => _esc[c]);
17
+ }
18
+ __name(_escHtml, "_escHtml");
19
+ var VOID = /* @__PURE__ */ new Set([
20
+ "area",
21
+ "base",
22
+ "br",
23
+ "col",
24
+ "embed",
25
+ "hr",
26
+ "img",
27
+ "input",
28
+ "link",
29
+ "meta",
30
+ "param",
31
+ "source",
32
+ "track",
33
+ "wbr"
34
+ ]);
35
+ function _checkVoid(type, children) {
36
+ if (typeof type === "string" && VOID.has(type) && children.length) {
37
+ throw new Error(
38
+ `<${type}> has children: an unclosed void element swallows what follows it. Write it as <${type} />.`
39
+ );
40
+ }
41
+ }
42
+ __name(_checkVoid, "_checkVoid");
43
+ var _M = /* @__PURE__ */ Symbol.for("microtags.markup");
44
+ var Markup = class {
45
+ static {
46
+ __name(this, "Markup");
47
+ }
48
+ _v;
49
+ constructor(v) {
50
+ this._v = v;
51
+ }
52
+ toString() {
53
+ return this._v;
54
+ }
55
+ };
56
+ Markup.prototype[_M] = true;
57
+ function _isMarkup(v) {
58
+ return v != null && v[_M] === true;
59
+ }
60
+ __name(_isMarkup, "_isMarkup");
61
+ var _Escaped = class extends Markup {
62
+ static {
63
+ __name(this, "_Escaped");
64
+ }
65
+ _raw;
66
+ constructor(raw2) {
67
+ super(_escHtml(raw2));
68
+ this._raw = raw2;
69
+ }
70
+ };
71
+ function raw(s) {
72
+ return new Markup(s);
73
+ }
74
+ __name(raw, "raw");
75
+ function _isMicrotag(t) {
76
+ return typeof t === "function" && "TAG" in t && "render" in t && "props" in t;
77
+ }
78
+ __name(_isMicrotag, "_isMicrotag");
79
+ var _OPEN = "<!--[-->";
80
+ var _KIDS = "<!--[c-->";
81
+ var _CLOSE = "<!--]-->";
82
+ function _region(f) {
83
+ const v = f();
84
+ const out = Array.isArray(v) ? _flatten(v.map(_trust)) : _flatten([_trust(v)]);
85
+ return _OPEN + out + _CLOSE;
86
+ }
87
+ __name(_region, "_region");
88
+ function _trust(v) {
89
+ return typeof v === "string" ? _escHtml(v) : v;
90
+ }
91
+ __name(_trust, "_trust");
92
+ function _flatten(children) {
93
+ let out = "";
94
+ for (const c of children) {
95
+ if (c == null || c === false) continue;
96
+ if (Array.isArray(c)) {
97
+ out += _flatten(c);
98
+ } else if (typeof c === "function") {
99
+ out += _region(c);
100
+ } else {
101
+ out += String(c);
102
+ }
103
+ }
104
+ return out;
105
+ }
106
+ __name(_flatten, "_flatten");
107
+ function _val(v) {
108
+ const r = typeof v === "function" ? v() : v;
109
+ return r instanceof _Escaped ? r._raw : r;
110
+ }
111
+ __name(_val, "_val");
112
+ function _isListener(k, v) {
113
+ return typeof v === "function" && k.startsWith("on");
114
+ }
115
+ __name(_isListener, "_isListener");
116
+ var _ATTR = /^[a-z_:][-\w:.]*$/i;
117
+ function h(type, props, ...children) {
118
+ _checkVoid(type, children);
119
+ const inner = _flatten(children);
120
+ if (_isMicrotag(type)) {
121
+ const declared = new Set(
122
+ type.props
123
+ );
124
+ const compProps = {};
125
+ const attrs = {};
126
+ if (props) {
127
+ for (const [k, pv] of Object.entries(props)) {
128
+ if (_isListener(k, pv)) continue;
129
+ const v = _val(pv);
130
+ if (declared.has(k)) {
131
+ compProps[k] = v;
132
+ } else if (!_ATTR.test(k)) {
133
+ continue;
134
+ } else if (v === true) {
135
+ attrs[k] = "";
136
+ } else if (v !== false && v != null) {
137
+ attrs[k] = String(v);
138
+ }
139
+ }
140
+ }
141
+ const result = type.render(
142
+ compProps,
143
+ {
144
+ children: children.length > 0 ? _KIDS + inner + _CLOSE : inner,
145
+ attrs: Object.keys(attrs).length > 0 ? attrs : void 0
146
+ }
147
+ );
148
+ return new Markup(String(result));
149
+ }
150
+ if (typeof type === "string") {
151
+ let a = "";
152
+ if (props) {
153
+ for (const [k, pv] of Object.entries(props)) {
154
+ if (_isListener(k, pv) || !_ATTR.test(k)) continue;
155
+ const v = _val(pv);
156
+ if (v === true) {
157
+ a += ` ${k}`;
158
+ } else if (v !== false && v != null) {
159
+ a += ` ${k}="${_escHtml(String(v))}"`;
160
+ }
161
+ }
162
+ }
163
+ if (VOID.has(type)) {
164
+ return new Markup(`<${type}${a}>`);
165
+ }
166
+ return new Markup(
167
+ `<${type}${a}>${inner}</${type}>`
168
+ );
169
+ }
170
+ return new Markup(inner);
171
+ }
172
+ __name(h, "h");
173
+ var _htm = htm.bind(h);
174
+ function html(strings, ...values) {
175
+ const escaped = values.map((v) => {
176
+ if (typeof v === "string") {
177
+ return new _Escaped(v);
178
+ }
179
+ return v;
180
+ });
181
+ const result = _htm(
182
+ strings,
183
+ ...escaped
184
+ );
185
+ if (_isMarkup(result)) return result;
186
+ if (Array.isArray(result)) return new Markup(_flatten(result));
187
+ return new Markup(String(result ?? ""));
188
+ }
189
+ __name(html, "html");
190
+ export {
191
+ Markup,
192
+ h,
193
+ html,
194
+ raw
195
+ };
196
+ //# sourceMappingURL=htm.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/htm.ts"],
4
+ "sourcesContent": ["import htm from 'htm'\n// Registers the server render support module, so `render` statics work.\nimport './render-support.js'\nimport type { MicrotagElementClass } from './builders.js'\nimport type { PropDef } from './types.js'\n\nconst _esc:Record<string, string> = {\n '&': '&amp;',\n '\"': '&quot;',\n \"'\": '&#39;',\n '<': '&lt;',\n '>': '&gt;',\n}\n\nfunction _escHtml (s:string):string {\n return s.replace(/[&\"'<>]/g, c => _esc[c])\n}\n\nconst VOID = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr',\n 'img', 'input', 'link', 'meta', 'param',\n 'source', 'track', 'wbr',\n])\n\n// htm does not know void tags, so an unclosed one takes everything\n// after it as children. Fail loudly instead of dropping them.\nfunction _checkVoid (type:unknown, children:unknown[]):void {\n if (typeof type === 'string' && VOID.has(type) && children.length) {\n throw new Error(\n `<${type}> has children: an unclosed void element ` +\n `swallows what follows it. Write it as <${type} />.`\n )\n }\n}\n\n// Brands markup across package copies, where `instanceof` fails.\nconst _M = Symbol.for('microtags.markup')\n\n/**\n * Opaque, trusted output of the templater. Convert it with `String(m)`\n * to get the HTML. Interpolating markup into `html` never escapes it.\n */\nexport class Markup {\n readonly _v:string\n constructor (v:string) { this._v = v }\n toString ():string { return this._v }\n}\n\n// on the prototype, so the brand stays out of the declared type\n(Markup.prototype as unknown as Record<symbol, boolean>)[_M] = true\n\nfunction _isMarkup (v:unknown):v is Markup {\n return v != null && (v as Record<symbol, unknown>)[_M] === true\n}\n\n// An interpolated string, escaped for markup. Components receive the\n// original text as a prop, so their own serializer escapes it once.\nclass _Escaped extends Markup {\n readonly _raw:string\n constructor (raw:string) {\n super(_escHtml(raw))\n this._raw = raw\n }\n}\n\nexport function raw (s:string):Markup {\n return new Markup(s)\n}\n\nfunction _isMicrotag (\n t:unknown\n):t is MicrotagElementClass<Record<string, PropDef>> {\n return (\n typeof t === 'function' &&\n 'TAG' in t &&\n 'render' in t &&\n 'props' in t\n )\n}\n\n// Comment markers around a reactive region, so the browser can find it.\n// Component children open with their own marker, so the browser can\n// tell them from regions in the component's own render.\nconst _OPEN = '<!--[-->'\nconst _KIDS = '<!--[c-->'\nconst _CLOSE = '<!--]-->'\n\n// A signal or function in child position is evaluated once. Its result\n// did not pass through `html`, so plain strings are escaped here.\nfunction _region (f:() => unknown):string {\n const v = f()\n const out = Array.isArray(v) ?\n _flatten(v.map(_trust)) :\n _flatten([_trust(v)])\n return _OPEN + out + _CLOSE\n}\n\nfunction _trust (v:unknown):unknown {\n return typeof v === 'string' ? _escHtml(v) : v\n}\n\nfunction _flatten (\n children:unknown[]\n):string {\n let out = ''\n for (const c of children) {\n if (c == null || c === false) continue\n if (Array.isArray(c)) {\n out += _flatten(c)\n } else if (typeof c === 'function') {\n out += _region(c as () => unknown)\n } else {\n out += String(c)\n }\n }\n return out\n}\n\n// Evaluate a signal or function in a prop or attribute hole, and\n// unwrap an interpolated string, so attributes are escaped only once.\nfunction _val (v:unknown):unknown {\n const r = typeof v === 'function' ? v() : v\n return r instanceof _Escaped ? r._raw : r\n}\n\n// A function-valued on<event> prop is a listener, which the browser\n// binds. It has no server output.\nfunction _isListener (k:string, v:unknown):boolean {\n return typeof v === 'function' && k.startsWith('on')\n}\n\n// A key that is not a valid attribute name, e.g. from a spread of user\n// data, is skipped so it cannot break out of the tag.\nconst _ATTR = /^[a-z_:][-\\w:.]*$/i\n\nexport function h (\n type:string | ((...a:unknown[]) => unknown),\n props:Record<string, unknown> | null,\n ...children:unknown[]\n):Markup {\n _checkVoid(type, children)\n const inner = _flatten(children)\n\n if (_isMicrotag(type)) {\n const declared = new Set(\n type.props as readonly string[]\n )\n const compProps:Record<string, unknown> = {}\n const attrs:Record<string, string> = {}\n\n if (props) {\n for (const [k, pv] of Object.entries(props)) {\n if (_isListener(k, pv)) continue\n const v = _val(pv)\n if (declared.has(k)) {\n compProps[k] = v\n } else if (!_ATTR.test(k)) {\n continue\n } else if (v === true) {\n attrs[k] = ''\n } else if (v !== false && v != null) {\n attrs[k] = String(v)\n }\n }\n }\n\n const result = type.render(\n compProps as any,\n {\n children: children.length > 0 ?\n _KIDS + inner + _CLOSE :\n inner,\n attrs: Object.keys(attrs).length > 0 ?\n attrs :\n undefined,\n }\n )\n return new Markup(String(result))\n }\n\n if (typeof type === 'string') {\n let a = ''\n if (props) {\n for (const [k, pv] of Object.entries(props)) {\n if (_isListener(k, pv) || !_ATTR.test(k)) continue\n const v = _val(pv)\n if (v === true) {\n a += ` ${k}`\n } else if (\n v !== false &&\n v != null\n ) {\n a += ` ${k}=\"${_escHtml(String(v))}\"`\n }\n }\n }\n\n if (VOID.has(type)) {\n return new Markup(`<${type}${a}>`)\n }\n return new Markup(\n `<${type}${a}>${inner}</${type}>`\n )\n }\n\n return new Markup(inner)\n}\n\nconst _htm = htm.bind(h)\n\nexport function html (\n strings:TemplateStringsArray,\n ...values:unknown[]\n):Markup {\n const escaped = values.map(v => {\n if (typeof v === 'string') {\n return new _Escaped(v)\n }\n return v\n })\n const result = (_htm as (...a:unknown[]) => unknown)(\n strings, ...escaped\n )\n if (_isMarkup(result)) return result\n if (Array.isArray(result)) return new Markup(_flatten(result))\n return new Markup(String(result ?? ''))\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["raw"]
7
+ }
@@ -0,0 +1,3 @@
1
+ var x=Object.defineProperty;var u=(n,t)=>x(n,"name",{value:t,configurable:!0});var b=u(function(n,t,s,e){var c;t[0]=0;for(var r=1;r<t.length;r++){var o=t[r++],i=t[r]?(t[0]|=o?1:2,s[t[r++]]):t[++r];o===3?e[0]=i:o===4?e[1]=Object.assign(e[1]||{},i):o===5?(e[1]=e[1]||{})[t[++r]]=i:o===6?e[1][t[++r]]+=i+"":o?(c=n.apply(i,b(n,i,s,["",null])),e.push(c),i[0]?t[0]|=2:(t[r-2]=0,t[r]=c)):e.push(i)}return e},"n"),y=new Map;function p(n){var t=y.get(this);return t||(t=new Map,y.set(this,t)),(t=b(this,t.get(n)||(t.set(n,t=(function(s){for(var e,c,r=1,o="",i="",a=[0],g=function(d){r===1&&(d||(o=o.replace(/^\s*\n\s*|\s*\n\s*$/g,"")))?a.push(0,d,o):r===3&&(d||o)?(a.push(3,d,o),r=2):r===2&&o==="..."&&d?a.push(4,d,0):r===2&&o&&!d?a.push(5,0,!0,o):r>=5&&((o||!d&&r===5)&&(a.push(r,0,o,c),r=6),d&&(a.push(r,d,0,c),r=6)),o=""},l=0;l<s.length;l++){l&&(r===1&&g(),g(l));for(var k=0;k<s[l].length;k++)e=s[l][k],r===1?e==="<"?(g(),a=[a],r=3):o+=e:r===4?o==="--"&&e===">"?(r=1,o=""):o=e+o[0]:i?e===i?i="":o+=e:e==='"'||e==="'"?i=e:e===">"?(g(),r=1):r&&(e==="="?(r=5,c=o,o=""):e==="/"&&(r<5||s[l][k+1]===">")?(g(),r===3&&(a=a[0]),r=a,(a=a[0]).push(2,0,r),r=0):e===" "||e===" "||e===`
2
+ `||e==="\r"?(g(),r=2):o+=e),r===3&&o==="!--"&&(r=4,a=a[0])}return g(),a})(n)),t),arguments,[])).length>1?t:t[0]}u(p,"default");var O={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"};function P(n){return n.replace(/[&"'<>]/g,t=>O[t])}u(P,"_escAttr");var T=/^[a-z_:][-\w:.]*$/i;function D(n,t){return n.kind==="prop-only"||t==null?null:n.kind==="boolean"?t===!0?"":null:n.kind==="json"?JSON.stringify(t):String(t)}u(D,"_serialize");function E(n,t){return t===""?` ${n}`:` ${n}="${P(t)}"`}u(E,"_attr");function R(n,t,s){let e=s?.attrs??{},c=String(n.f({props:t,refs:n.r,TAG:n.t,children:s?.children??"",attrs:e})),r=Object.create(null);for(let o in n.m){let i=o in t?D(n.m[o],t[o]):null;i!==null&&(r[o]=i)}for(let[o,i]of Object.entries(e))T.test(o)&&(r[o]??=i);return{tag:n.t,attrs:r,html:c}}u(R,"renderParts");function z(n,t,s){let{tag:e,attrs:c,html:r}=R(n,t,s),o="";for(let i in c)o+=E(i,c[i]);return`<${e}${o}>${r}</${e}>`}u(z,"renderHost");function C(){let n=globalThis;n[Symbol.for("microtags.render")]=z,n[Symbol.for("microtags.renderParts")]=R}u(C,"register");C();var N={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"};function _(n){return n.replace(/[&"'<>]/g,t=>N[t])}u(_,"_escHtml");var A=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function q(n,t){if(typeof n=="string"&&A.has(n)&&t.length)throw new Error(`<${n}> has children: an unclosed void element swallows what follows it. Write it as <${n} />.`)}u(q,"_checkVoid");var j=Symbol.for("microtags.markup"),f=class{static{u(this,"Markup")}_v;constructor(t){this._v=t}toString(){return this._v}};f.prototype[j]=!0;function G(n){return n!=null&&n[j]===!0}u(G,"_isMarkup");var m=class extends f{static{u(this,"_Escaped")}_raw;constructor(t){super(_(t)),this._raw=t}};function Z(n){return new f(n)}u(Z,"raw");function H(n){return typeof n=="function"&&"TAG"in n&&"render"in n&&"props"in n}u(H,"_isMicrotag");var I="<!--[-->",L="<!--[c-->",v="<!--]-->";function V(n){let t=n(),s=Array.isArray(t)?w(t.map($)):w([$(t)]);return I+s+v}u(V,"_region");function $(n){return typeof n=="string"?_(n):n}u($,"_trust");function w(n){let t="";for(let s of n)s==null||s===!1||(Array.isArray(s)?t+=w(s):typeof s=="function"?t+=V(s):t+=String(s));return t}u(w,"_flatten");function h(n){let t=typeof n=="function"?n():n;return t instanceof m?t._raw:t}u(h,"_val");function S(n,t){return typeof t=="function"&&n.startsWith("on")}u(S,"_isListener");var M=/^[a-z_:][-\w:.]*$/i;function W(n,t,...s){q(n,s);let e=w(s);if(H(n)){let c=new Set(n.props),r={},o={};if(t)for(let[a,g]of Object.entries(t)){if(S(a,g))continue;let l=h(g);if(c.has(a))r[a]=l;else if(M.test(a))l===!0?o[a]="":l!==!1&&l!=null&&(o[a]=String(l));else continue}let i=n.render(r,{children:s.length>0?L+e+v:e,attrs:Object.keys(o).length>0?o:void 0});return new f(String(i))}if(typeof n=="string"){let c="";if(t)for(let[r,o]of Object.entries(t)){if(S(r,o)||!M.test(r))continue;let i=h(o);i===!0?c+=` ${r}`:i!==!1&&i!=null&&(c+=` ${r}="${_(String(i))}"`)}return A.has(n)?new f(`<${n}${c}>`):new f(`<${n}${c}>${e}</${n}>`)}return new f(e)}u(W,"h");var J=p.bind(W);function nn(n,...t){let s=t.map(c=>typeof c=="string"?new m(c):c),e=J(n,...s);return G(e)?e:Array.isArray(e)?new f(w(e)):new f(String(e??""))}u(nn,"html");export{f as Markup,W as h,nn as html,Z as raw};
3
+ //# sourceMappingURL=htm.min.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../node_modules/htm/dist/htm.module.js", "../src/render-support.ts", "../src/htm.ts"],
4
+ "sourcesContent": ["var n=function(t,s,r,e){var u;s[0]=0;for(var h=1;h<s.length;h++){var p=s[h++],a=s[h]?(s[0]|=p?1:2,r[s[h++]]):s[++h];3===p?e[0]=a:4===p?e[1]=Object.assign(e[1]||{},a):5===p?(e[1]=e[1]||{})[s[++h]]=a:6===p?e[1][s[++h]]+=a+\"\":p?(u=t.apply(a,n(t,a,r,[\"\",null])),e.push(u),a[0]?s[0]|=2:(s[h-2]=0,s[h]=u)):e.push(a)}return e},t=new Map;export default function(s){var r=t.get(this);return r||(r=new Map,t.set(this,r)),(r=n(this,r.get(s)||(r.set(s,r=function(n){for(var t,s,r=1,e=\"\",u=\"\",h=[0],p=function(n){1===r&&(n||(e=e.replace(/^\\s*\\n\\s*|\\s*\\n\\s*$/g,\"\")))?h.push(0,n,e):3===r&&(n||e)?(h.push(3,n,e),r=2):2===r&&\"...\"===e&&n?h.push(4,n,0):2===r&&e&&!n?h.push(5,0,!0,e):r>=5&&((e||!n&&5===r)&&(h.push(r,0,e,s),r=6),n&&(h.push(r,n,0,s),r=6)),e=\"\"},a=0;a<n.length;a++){a&&(1===r&&p(),p(a));for(var l=0;l<n[a].length;l++)t=n[a][l],1===r?\"<\"===t?(p(),h=[h],r=3):e+=t:4===r?\"--\"===e&&\">\"===t?(r=1,e=\"\"):e=t+e[0]:u?t===u?u=\"\":e+=t:'\"'===t||\"'\"===t?u=t:\">\"===t?(p(),r=1):r&&(\"=\"===t?(r=5,s=e,e=\"\"):\"/\"===t&&(r<5||\">\"===n[a][l+1])?(p(),3===r&&(h=h[0]),r=h,(h=h[0]).push(2,0,r),r=0):\" \"===t||\"\\t\"===t||\"\\n\"===t||\"\\r\"===t?(p(),r=2):e+=t),3===r&&\"!--\"===e&&(r=4,h=h[0])}return p(),h}(s)),r),arguments,[])).length>1?r:r[0]}\n", "// Server render support: the host-tag builder, prop serializers and\n// attribute escaping. Importing this module registers `renderHost`\n// under a registry symbol on `globalThis`, where a component's `render`\n// static finds it. Core never imports this module, so a bundle with\n// every render link stripped leaves it out. See ADR-009.\nimport type {\n PropMeta,\n RenderParts,\n RenderRecord,\n} from './builders.js'\n\nconst _esc:Record<string, string> = {\n '&': '&amp;',\n '\"': '&quot;',\n \"'\": '&#39;',\n '<': '&lt;',\n '>': '&gt;',\n}\nfunction _escAttr (s:string):string {\n return s.replace(/[&\"'<>]/g, c => _esc[c])\n}\n\n// HTML attribute name grammar: a letter, `_` or `:`, then letters,\n// digits, `-`, `_`, `:` or `.`. Extra attrs may come from data.\nconst _attrName = /^[a-z_:][-\\w:.]*$/i\n\n// The kind is decided by core, so no coercer is compared here and any\n// copy of this module serves any copy of core.\nfunction _serialize (m:PropMeta, v:unknown):string | null {\n if (m.kind === 'prop-only' || v == null) return null\n if (m.kind === 'boolean') return v === true ? '' : null\n if (m.kind === 'json') return JSON.stringify(v)\n return String(v)\n}\n\nfunction _attr (k:string, v:string):string {\n return v === '' ? ` ${k}` : ` ${k}=\"${_escAttr(v)}\"`\n}\n\n/**\n * Render a component as parts: the host tag name, its serialized\n * (unescaped) attributes, declared props first, and the inner HTML.\n * `attrs` has no prototype, so a name like `__proto__` from data is a\n * plain key. A declared prop keeps its value over an extra attr of the\n * same name, as an HTML parser keeps the first of a duplicate.\n */\nexport function renderParts (\n rec:RenderRecord,\n props:Record<string, unknown>,\n options?:{ children?:string; attrs?:Record<string, string> }\n):RenderParts {\n const extra = options?.attrs ?? {}\n const html = String(rec.f({\n props,\n refs: rec.r,\n TAG: rec.t,\n children: options?.children ?? '',\n attrs: extra,\n }))\n const attrs:Record<string, string> = Object.create(null)\n for (const k in rec.m) {\n const s = k in props ? _serialize(rec.m[k], props[k]) : null\n if (s !== null) attrs[k] = s\n }\n for (const [k, v] of Object.entries(extra)) {\n if (_attrName.test(k)) attrs[k] ??= v\n }\n return { tag: rec.t, attrs, html }\n}\n\n/** Render a component's host tag around the output of its render link. */\nexport function renderHost (\n rec:RenderRecord,\n props:Record<string, unknown>,\n options?:{ children?:string; attrs?:Record<string, string> }\n):string {\n const { tag, attrs, html } = renderParts(rec, props, options)\n let a = ''\n for (const k in attrs) a += _attr(k, attrs[k])\n return `<${tag}${a}>${html}</${tag}>`\n}\n\n/**\n * Store `renderHost` and `renderParts` where the `render` and\n * `renderParts` statics look them up.\n */\nexport function register ():void {\n const g = globalThis as any\n g[Symbol.for('microtags.render')] = renderHost\n g[Symbol.for('microtags.renderParts')] = renderParts\n}\n\nregister()\n", "import htm from 'htm'\n// Registers the server render support module, so `render` statics work.\nimport './render-support.js'\nimport type { MicrotagElementClass } from './builders.js'\nimport type { PropDef } from './types.js'\n\nconst _esc:Record<string, string> = {\n '&': '&amp;',\n '\"': '&quot;',\n \"'\": '&#39;',\n '<': '&lt;',\n '>': '&gt;',\n}\n\nfunction _escHtml (s:string):string {\n return s.replace(/[&\"'<>]/g, c => _esc[c])\n}\n\nconst VOID = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr',\n 'img', 'input', 'link', 'meta', 'param',\n 'source', 'track', 'wbr',\n])\n\n// htm does not know void tags, so an unclosed one takes everything\n// after it as children. Fail loudly instead of dropping them.\nfunction _checkVoid (type:unknown, children:unknown[]):void {\n if (typeof type === 'string' && VOID.has(type) && children.length) {\n throw new Error(\n `<${type}> has children: an unclosed void element ` +\n `swallows what follows it. Write it as <${type} />.`\n )\n }\n}\n\n// Brands markup across package copies, where `instanceof` fails.\nconst _M = Symbol.for('microtags.markup')\n\n/**\n * Opaque, trusted output of the templater. Convert it with `String(m)`\n * to get the HTML. Interpolating markup into `html` never escapes it.\n */\nexport class Markup {\n readonly _v:string\n constructor (v:string) { this._v = v }\n toString ():string { return this._v }\n}\n\n// on the prototype, so the brand stays out of the declared type\n(Markup.prototype as unknown as Record<symbol, boolean>)[_M] = true\n\nfunction _isMarkup (v:unknown):v is Markup {\n return v != null && (v as Record<symbol, unknown>)[_M] === true\n}\n\n// An interpolated string, escaped for markup. Components receive the\n// original text as a prop, so their own serializer escapes it once.\nclass _Escaped extends Markup {\n readonly _raw:string\n constructor (raw:string) {\n super(_escHtml(raw))\n this._raw = raw\n }\n}\n\nexport function raw (s:string):Markup {\n return new Markup(s)\n}\n\nfunction _isMicrotag (\n t:unknown\n):t is MicrotagElementClass<Record<string, PropDef>> {\n return (\n typeof t === 'function' &&\n 'TAG' in t &&\n 'render' in t &&\n 'props' in t\n )\n}\n\n// Comment markers around a reactive region, so the browser can find it.\n// Component children open with their own marker, so the browser can\n// tell them from regions in the component's own render.\nconst _OPEN = '<!--[-->'\nconst _KIDS = '<!--[c-->'\nconst _CLOSE = '<!--]-->'\n\n// A signal or function in child position is evaluated once. Its result\n// did not pass through `html`, so plain strings are escaped here.\nfunction _region (f:() => unknown):string {\n const v = f()\n const out = Array.isArray(v) ?\n _flatten(v.map(_trust)) :\n _flatten([_trust(v)])\n return _OPEN + out + _CLOSE\n}\n\nfunction _trust (v:unknown):unknown {\n return typeof v === 'string' ? _escHtml(v) : v\n}\n\nfunction _flatten (\n children:unknown[]\n):string {\n let out = ''\n for (const c of children) {\n if (c == null || c === false) continue\n if (Array.isArray(c)) {\n out += _flatten(c)\n } else if (typeof c === 'function') {\n out += _region(c as () => unknown)\n } else {\n out += String(c)\n }\n }\n return out\n}\n\n// Evaluate a signal or function in a prop or attribute hole, and\n// unwrap an interpolated string, so attributes are escaped only once.\nfunction _val (v:unknown):unknown {\n const r = typeof v === 'function' ? v() : v\n return r instanceof _Escaped ? r._raw : r\n}\n\n// A function-valued on<event> prop is a listener, which the browser\n// binds. It has no server output.\nfunction _isListener (k:string, v:unknown):boolean {\n return typeof v === 'function' && k.startsWith('on')\n}\n\n// A key that is not a valid attribute name, e.g. from a spread of user\n// data, is skipped so it cannot break out of the tag.\nconst _ATTR = /^[a-z_:][-\\w:.]*$/i\n\nexport function h (\n type:string | ((...a:unknown[]) => unknown),\n props:Record<string, unknown> | null,\n ...children:unknown[]\n):Markup {\n _checkVoid(type, children)\n const inner = _flatten(children)\n\n if (_isMicrotag(type)) {\n const declared = new Set(\n type.props as readonly string[]\n )\n const compProps:Record<string, unknown> = {}\n const attrs:Record<string, string> = {}\n\n if (props) {\n for (const [k, pv] of Object.entries(props)) {\n if (_isListener(k, pv)) continue\n const v = _val(pv)\n if (declared.has(k)) {\n compProps[k] = v\n } else if (!_ATTR.test(k)) {\n continue\n } else if (v === true) {\n attrs[k] = ''\n } else if (v !== false && v != null) {\n attrs[k] = String(v)\n }\n }\n }\n\n const result = type.render(\n compProps as any,\n {\n children: children.length > 0 ?\n _KIDS + inner + _CLOSE :\n inner,\n attrs: Object.keys(attrs).length > 0 ?\n attrs :\n undefined,\n }\n )\n return new Markup(String(result))\n }\n\n if (typeof type === 'string') {\n let a = ''\n if (props) {\n for (const [k, pv] of Object.entries(props)) {\n if (_isListener(k, pv) || !_ATTR.test(k)) continue\n const v = _val(pv)\n if (v === true) {\n a += ` ${k}`\n } else if (\n v !== false &&\n v != null\n ) {\n a += ` ${k}=\"${_escHtml(String(v))}\"`\n }\n }\n }\n\n if (VOID.has(type)) {\n return new Markup(`<${type}${a}>`)\n }\n return new Markup(\n `<${type}${a}>${inner}</${type}>`\n )\n }\n\n return new Markup(inner)\n}\n\nconst _htm = htm.bind(h)\n\nexport function html (\n strings:TemplateStringsArray,\n ...values:unknown[]\n):Markup {\n const escaped = values.map(v => {\n if (typeof v === 'string') {\n return new _Escaped(v)\n }\n return v\n })\n const result = (_htm as (...a:unknown[]) => unknown)(\n strings, ...escaped\n )\n if (_isMarkup(result)) return result\n if (Array.isArray(result)) return new Markup(_flatten(result))\n return new Markup(String(result ?? ''))\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["n", "__name", "t", "s", "r", "u", "h", "p", "a", "htm_module_default", "e", "l", "_esc", "_escAttr", "s", "c", "__name", "_attrName", "_serialize", "m", "v", "_attr", "k", "renderParts", "rec", "props", "options", "extra", "html", "attrs", "renderHost", "tag", "a", "register", "g", "_esc", "_escHtml", "s", "c", "__name", "VOID", "_checkVoid", "type", "children", "_M", "Markup", "v", "_isMarkup", "_Escaped", "raw", "_isMicrotag", "t", "_OPEN", "_KIDS", "_CLOSE", "_region", "f", "out", "_flatten", "_trust", "_val", "r", "_isListener", "k", "_ATTR", "h", "props", "inner", "declared", "compProps", "attrs", "pv", "result", "a", "_htm", "htm_module_default", "html", "strings", "values", "escaped"]
7
+ }
package/dist/index.cjs CHANGED
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/index.ts
22
22
  var index_exports = {};
23
23
  __export(index_exports, {
24
+ bindProp: () => bindProp,
24
25
  define: () => define,
25
26
  peek: () => peek,
26
27
  untracked: () => untracked
@@ -228,18 +229,39 @@ function factory(config) {
228
229
  return observedAttrNames;
229
230
  }
230
231
  _props = {};
232
+ // Per prop: the external signal assigned to the accessor, if any.
233
+ _bound = {};
231
234
  _cleanups = [];
235
+ // Connected and set up, not yet torn down.
236
+ _live = false;
232
237
  constructor() {
233
238
  super();
234
239
  for (const [name, coercer] of Object.entries(propDefs)) {
235
- this._props[name] = (0, import_alien_signals.signal)(coercer(null));
240
+ const own = (0, import_alien_signals.signal)(coercer(null));
241
+ const bound = (0, import_alien_signals.signal)(void 0);
242
+ this._bound[name] = bound;
243
+ this._props[name] = ((...args) => {
244
+ const ext = bound();
245
+ if (!args.length) return ext ? ext() : own();
246
+ if (ext) {
247
+ throw new Error(`${this.localName}: prop "${name}" is bound and read-only; emit an event instead`);
248
+ }
249
+ own(args[0]);
250
+ });
251
+ if (Object.prototype.hasOwnProperty.call(this, name)) {
252
+ const pre = this[name];
253
+ delete this[name];
254
+ this[name] = pre;
255
+ }
236
256
  }
237
257
  }
238
258
  connectedCallback() {
259
+ if (this._live) return;
260
+ this._live = true;
239
261
  this._cleanups = [];
240
262
  for (const [name, coercer] of Object.entries(propDefs)) {
241
263
  const attrVal = this.getAttribute(name);
242
- if (attrVal !== null) {
264
+ if (attrVal !== null && !this._bound[name]()) {
243
265
  this._props[name](coercer(attrVal));
244
266
  }
245
267
  }
@@ -296,19 +318,48 @@ function factory(config) {
296
318
  }
297
319
  attributeChangedCallback(name, _old, next) {
298
320
  const coercer = propDefs[name];
299
- if (coercer !== void 0 && this._props[name] !== void 0) {
321
+ if (coercer !== void 0 && this._props[name] !== void 0 && !this._bound[name]()) {
300
322
  this._props[name](coercer(next));
301
323
  }
302
324
  }
325
+ // A DOM move (`moveBefore`) keeps the host set up
326
+ connectedMoveCallback() {
327
+ }
328
+ // Teardown waits a microtask, so a host removed and re-inserted
329
+ // in the same tick (`insertBefore` without `moveBefore`) keeps
330
+ // its setup.
303
331
  disconnectedCallback() {
304
- const fns = this._cleanups;
305
- this._cleanups = [];
306
- runAll(fns);
332
+ queueMicrotask(() => {
333
+ if (this.isConnected || !this._live) return;
334
+ this._live = false;
335
+ const fns = this._cleanups;
336
+ this._cleanups = [];
337
+ runAll(fns);
338
+ });
307
339
  }
308
340
  }
341
+ for (const name of Object.keys(propDefs)) {
342
+ Object.defineProperty(MicrotagElement.prototype, name, {
343
+ get() {
344
+ return this._props[name]();
345
+ },
346
+ set(v) {
347
+ if (typeof v === "function") {
348
+ this._bound[name](v);
349
+ } else {
350
+ this._bound[name](void 0);
351
+ this._props[name](v);
352
+ }
353
+ },
354
+ configurable: true
355
+ });
356
+ }
309
357
  return MicrotagElement;
310
358
  }
311
359
  __name(factory, "factory");
360
+ var bindProp = /* @__PURE__ */ __name((host, name, source) => {
361
+ host[name] = source;
362
+ }, "bindProp");
312
363
 
313
364
  // src/builders.ts
314
365
  var propDSL = {
@@ -325,12 +376,15 @@ var refsDSL = {
325
376
  };
326
377
  var contextDSL = {};
327
378
  var ComponentBuilder = class _ComponentBuilder {
328
- constructor(tagName, coercers = {}, observed = [], refDefs = {}, ctxDefs = {}) {
379
+ constructor(tagName, coercers = {}, observed = [], refDefs = {}, ctxDefs = {}, propNames = [], propMetas = {}, renderFn) {
329
380
  this.tagName = tagName;
330
381
  this._coercers = coercers;
331
382
  this._observed = observed;
383
+ this._propNames = propNames;
384
+ this._propMetas = propMetas;
332
385
  this._refDefs = refDefs;
333
386
  this._ctxDefs = ctxDefs;
387
+ this._renderFn = renderFn;
334
388
  }
335
389
  tagName;
336
390
  static {
@@ -338,8 +392,11 @@ var ComponentBuilder = class _ComponentBuilder {
338
392
  }
339
393
  _coercers;
340
394
  _observed;
395
+ _propNames;
396
+ _propMetas;
341
397
  _refDefs;
342
398
  _ctxDefs;
399
+ _renderFn;
343
400
  /**
344
401
  * The custom element tag name, e.g. 'my-counter'. Available at every
345
402
  * point in the fluent chain since each builder method returns a new
@@ -352,8 +409,17 @@ var ComponentBuilder = class _ComponentBuilder {
352
409
  const defs = fn(propDSL);
353
410
  const coercers = {};
354
411
  const observed = [];
412
+ const propNames = [];
413
+ const propMetas = {};
355
414
  for (const [name, def] of Object.entries(defs)) {
356
- coercers[name] = normalizePropDef(name, def);
415
+ const coercer = normalizePropDef(
416
+ name,
417
+ def
418
+ );
419
+ coercers[name] = coercer;
420
+ propNames.push(name);
421
+ const kind = isPropOnly(def) ? "prop-only" : isStandardSchema(def) ? "schema" : coercer === coerceBoolean ? "boolean" : coercer === coerceJson ? "json" : "coercer";
422
+ propMetas[name] = { kind, coercer };
357
423
  if (!isPropOnly(def)) {
358
424
  observed.push(name);
359
425
  }
@@ -363,7 +429,9 @@ var ComponentBuilder = class _ComponentBuilder {
363
429
  coercers,
364
430
  observed,
365
431
  this._refDefs,
366
- this._ctxDefs
432
+ this._ctxDefs,
433
+ propNames,
434
+ propMetas
367
435
  );
368
436
  }
369
437
  withRefs(fn) {
@@ -373,7 +441,10 @@ var ComponentBuilder = class _ComponentBuilder {
373
441
  this._coercers,
374
442
  this._observed,
375
443
  defs,
376
- this._ctxDefs
444
+ this._ctxDefs,
445
+ this._propNames,
446
+ this._propMetas,
447
+ this._renderFn
377
448
  );
378
449
  }
379
450
  withContexts(fn) {
@@ -383,7 +454,22 @@ var ComponentBuilder = class _ComponentBuilder {
383
454
  this._coercers,
384
455
  this._observed,
385
456
  this._refDefs,
386
- defs
457
+ defs,
458
+ this._propNames,
459
+ this._propMetas,
460
+ this._renderFn
461
+ );
462
+ }
463
+ render(fn, _options) {
464
+ return new _ComponentBuilder(
465
+ this.tagName,
466
+ this._coercers,
467
+ this._observed,
468
+ this._refDefs,
469
+ this._ctxDefs,
470
+ this._propNames,
471
+ this._propMetas,
472
+ fn
387
473
  );
388
474
  }
389
475
  setup(fn) {
@@ -406,6 +492,34 @@ var ComponentBuilder = class _ComponentBuilder {
406
492
  value: Object.freeze(refNames),
407
493
  enumerable: true
408
494
  });
495
+ Object.defineProperty(El, "props", {
496
+ value: Object.freeze([...this._propNames]),
497
+ enumerable: true
498
+ });
499
+ if (this._renderFn) {
500
+ const rec = {
501
+ t: this.tagName,
502
+ m: this._propMetas,
503
+ r: Object.freeze({ ...refNames }),
504
+ f: this._renderFn
505
+ };
506
+ const link = /* @__PURE__ */ __name((k) => (p, o) => {
507
+ const f = globalThis[/* @__PURE__ */ Symbol.for("microtags." + k)];
508
+ if (!f) {
509
+ throw new Error(
510
+ `microtags: ${k} needs "microtags/render-support"`
511
+ );
512
+ }
513
+ return f(rec, p, o);
514
+ }, "link");
515
+ Object.defineProperties(El, {
516
+ render: { value: link("render"), enumerable: true },
517
+ renderParts: {
518
+ value: link("renderParts"),
519
+ enumerable: true
520
+ }
521
+ });
522
+ }
409
523
  if (typeof customElements !== "undefined") {
410
524
  customElements.define(this.tagName, El);
411
525
  }