sprae 10.1.2 → 10.1.4
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/directive/each.js +6 -6
- package/directive/ref.js +1 -2
- package/directive/with.js +1 -14
- package/dist/sprae.js +8 -18
- package/dist/sprae.min.js +1 -1
- package/package.json +1 -1
- package/readme.md +8 -4
- package/store.js +2 -2
package/directive/each.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import sprae, { directive } from "../core.js";
|
|
2
|
-
import { _change, _signals } from "../store.js";
|
|
3
|
-
import { effect, untracked, computed } from '../signal.js';
|
|
2
|
+
import store, { _change, _signals } from "../store.js";
|
|
3
|
+
import { effect, untracked, computed, signal } from '../signal.js';
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
export const _each = Symbol(":each");
|
|
@@ -54,10 +54,10 @@ directive.each = (tpl, [itemVar, idxVar, evaluate], state) => {
|
|
|
54
54
|
for (; i < newl; i++) {
|
|
55
55
|
cur[i] = newItems[i]
|
|
56
56
|
let idx = i,
|
|
57
|
-
scope =
|
|
58
|
-
[itemVar]:
|
|
59
|
-
[idxVar]:
|
|
60
|
-
}),
|
|
57
|
+
scope = store({
|
|
58
|
+
[itemVar]: computed(() => cur[idx]),
|
|
59
|
+
[idxVar]: keys ? keys[idx] : idx
|
|
60
|
+
}, state),
|
|
61
61
|
el = (tpl.content || tpl).cloneNode(true),
|
|
62
62
|
frag = tpl.content ?
|
|
63
63
|
// fake fragment to init sprae
|
package/directive/ref.js
CHANGED
|
@@ -4,8 +4,7 @@ import { ipol } from './default.js';
|
|
|
4
4
|
|
|
5
5
|
// ref must be last within primaries, since that must be skipped by :each, but before secondaries
|
|
6
6
|
directive.ref = (el, expr, state) => {
|
|
7
|
-
|
|
8
|
-
Object.defineProperty(state, ipol(expr, state), { value: el })
|
|
7
|
+
state[ipol(expr, state)] = el
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
directive.ref.parse = expr => expr
|
package/directive/with.js
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import sprae, { directive } from "../core.js";
|
|
2
2
|
import store, { _signals } from '../store.js';
|
|
3
3
|
import { effect } from "../signal.js";
|
|
4
|
-
import { signal } from "ulive";
|
|
5
4
|
|
|
6
5
|
directive.with = (el, evaluate, rootState) => {
|
|
7
6
|
let state
|
|
8
7
|
return effect(() => {
|
|
9
8
|
let values = evaluate(rootState);
|
|
10
|
-
|
|
11
|
-
if (!state) {
|
|
12
|
-
state = store({});
|
|
13
|
-
// inherit root signals
|
|
14
|
-
Object.assign(state[_signals], rootState[_signals]);
|
|
15
|
-
// create local scope signals
|
|
16
|
-
for (let key in values) state[_signals][key] = null, state[key] = values[key]
|
|
17
|
-
|
|
18
|
-
sprae(el, state)
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
Object.assign(state, values)
|
|
22
|
-
}
|
|
9
|
+
sprae(el, state ? values : state = store(values, rootState))
|
|
23
10
|
})
|
|
24
11
|
};
|
package/dist/sprae.js
CHANGED
|
@@ -21,7 +21,7 @@ function use(s) {
|
|
|
21
21
|
// store.js
|
|
22
22
|
var _signals = Symbol("signals");
|
|
23
23
|
var _change = Symbol("length");
|
|
24
|
-
function store(values) {
|
|
24
|
+
function store(values, parent) {
|
|
25
25
|
if (!values)
|
|
26
26
|
return values;
|
|
27
27
|
if (values[_signals])
|
|
@@ -30,7 +30,7 @@ function store(values) {
|
|
|
30
30
|
return list(values);
|
|
31
31
|
if (values.constructor !== Object)
|
|
32
32
|
return values;
|
|
33
|
-
let signals = {}, _len = signal(Object.values(values).length);
|
|
33
|
+
let signals = { ...parent?.[_signals] }, _len = signal(Object.values(values).length);
|
|
34
34
|
const state = new Proxy(signals, {
|
|
35
35
|
get: (_, key) => key === _change ? _len : key === _signals ? signals : signals[key]?.valueOf(),
|
|
36
36
|
set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s || ++_len.value),
|
|
@@ -286,12 +286,10 @@ directive.each = (tpl, [itemVar, idxVar, evaluate], state) => {
|
|
|
286
286
|
}
|
|
287
287
|
for (; i < newl; i++) {
|
|
288
288
|
cur[i] = newItems[i];
|
|
289
|
-
let idx = i, scope =
|
|
290
|
-
[itemVar]:
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
[idxVar]: { value: keys2 ? keys2[idx] : idx }
|
|
294
|
-
}), el = (tpl.content || tpl).cloneNode(true), frag = tpl.content ? { children: [...el.children], remove() {
|
|
289
|
+
let idx = i, scope = store({
|
|
290
|
+
[itemVar]: computed(() => cur[idx]),
|
|
291
|
+
[idxVar]: keys2 ? keys2[idx] : idx
|
|
292
|
+
}, state), el = (tpl.content || tpl).cloneNode(true), frag = tpl.content ? { children: [...el.children], remove() {
|
|
295
293
|
this.children.map((el2) => el2.remove());
|
|
296
294
|
} } : el;
|
|
297
295
|
holder.before(el);
|
|
@@ -492,7 +490,7 @@ var ipol = (v, state) => {
|
|
|
492
490
|
|
|
493
491
|
// directive/ref.js
|
|
494
492
|
directive.ref = (el, expr, state) => {
|
|
495
|
-
|
|
493
|
+
state[ipol(expr, state)] = el;
|
|
496
494
|
};
|
|
497
495
|
directive.ref.parse = (expr) => expr;
|
|
498
496
|
|
|
@@ -501,15 +499,7 @@ directive.with = (el, evaluate, rootState) => {
|
|
|
501
499
|
let state;
|
|
502
500
|
return effect(() => {
|
|
503
501
|
let values = evaluate(rootState);
|
|
504
|
-
|
|
505
|
-
state = store({});
|
|
506
|
-
Object.assign(state[_signals], rootState[_signals]);
|
|
507
|
-
for (let key in values)
|
|
508
|
-
state[_signals][key] = null, state[key] = values[key];
|
|
509
|
-
sprae(el, state);
|
|
510
|
-
} else {
|
|
511
|
-
Object.assign(state, values);
|
|
512
|
-
}
|
|
502
|
+
sprae(el, state ? values : state = store(values, rootState));
|
|
513
503
|
});
|
|
514
504
|
};
|
|
515
505
|
|
package/dist/sprae.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,t,r,l,n,s=Object.defineProperty,a=Symbol("signals"),o=Symbol("length");function i(t){if(!t)return t;if(t[a])return t;if(Array.isArray(t))return function(t){let r;if(t[a])return t;let l=e(t.length),n=Array(t.length).fill(null);const s=new Proxy(n,{get:(s,c)=>"symbol"==typeof c?c===o?l:c===a?n:n[c]:"length"===c?Array.prototype[r]?l.peek():l.value:(r=c,n[c]?n[c].valueOf():c<n.length?(n[c]=e(i(t[c]))).value:void 0),set(e,t,r){if("length"===t){for(let e=r,t=n.length;e<t;e++)delete s[e];return l.value=n.length=r,!0}return c(n,t,r),t>=l.peek()&&(l.value=n.length=Number(t)+1),!0},deleteProperty:(e,t)=>(n[t]&&u(n,t),1)});return s}(t);if(t.constructor!==Object)return t;let
|
|
1
|
+
var e,t,r,l,n,s=Object.defineProperty,a=Symbol("signals"),o=Symbol("length");function i(t,r){if(!t)return t;if(t[a])return t;if(Array.isArray(t))return function(t){let r;if(t[a])return t;let l=e(t.length),n=Array(t.length).fill(null);const s=new Proxy(n,{get:(s,c)=>"symbol"==typeof c?c===o?l:c===a?n:n[c]:"length"===c?Array.prototype[r]?l.peek():l.value:(r=c,n[c]?n[c].valueOf():c<n.length?(n[c]=e(i(t[c]))).value:void 0),set(e,t,r){if("length"===t){for(let e=r,t=n.length;e<t;e++)delete s[e];return l.value=n.length=r,!0}return c(n,t,r),t>=l.peek()&&(l.value=n.length=Number(t)+1),!0},deleteProperty:(e,t)=>(n[t]&&u(n,t),1)});return s}(t);if(t.constructor!==Object)return t;let l={...r?.[a]},s=e(Object.values(t).length);const f=new Proxy(l,{get:(e,t)=>t===o?s:t===a?l:l[t]?.valueOf(),set:(e,t,r,n)=>(n=l[t],c(l,t,r),n||++s.value),deleteProperty:(e,t)=>(l[t]&&(u(l,t),s.value--),1),ownKeys:()=>(s.value,Reflect.ownKeys(l))});for(let e in t){const r=Object.getOwnPropertyDescriptor(t,e);r?.get?(l[e]=n(r.get.bind(f)))._set=r.set?.bind(f):(l[e]=null,c(l,e,t[e]))}return f}function c(t,n,s){let a=t[n];if(a)if(s===a.peek());else if(a._set)a._set(s);else if(Array.isArray(s)&&Array.isArray(a.peek())){const e=a.peek();e[o]?r((()=>{l((()=>{let t=0,r=s.length;for(;t<r;t++)e[t]=s[t];e.length=r}))})):a.value=s}else a.value=i(s);else t[n]=a=s?.peek?s:e(i(s))}function u(e,t){const r=e[t],l=r[Symbol.dispose];l&&delete r[Symbol.dispose],delete e[t],l?.()}var f=Symbol.dispose||=Symbol("dispose"),p={},d=new WeakMap;function y(e,t){if(!e?.children)return;if(d.has(e))return Object.assign(d.get(e),t);const r=i(t||{}),l=[];return function e(t,n=t.parentNode){if(t.attributes)for(let e=0;e<t.attributes.length;){let s=t.attributes[e];if(":"===s.name[0]){t.removeAttribute(s.name);let e=s.name.slice(1).split(":");for(let n of e){let e=p[n]||p.default,a=e(t,(e.parse||m)(s.value,m),r,n);a&&l.push(a)}if(d.has(t))return l.push(t[f]);if(t.parentNode!==n)return}else e++}for(let r of[...t.children])e(r,t)}(e),d.has(e)||d.set(e,r),e[f]=()=>{for(;l.length;)l.pop()();d.delete(e)},r}var v,h={},m=(e,t,r)=>{if(r=h[e=e.trim()])return r;try{r=v(e)}catch(r){throw Object.assign(r,{message:`∴ ${r.message}\n\n${t}${e?`="${e}"\n\n`:""}`,expr:e})}return h[e]=r};y.use=s=>{s.signal&&function(s){e=s.signal,t=s.effect,n=s.computed,l=s.batch||(e=>e()),r=s.untracked||l}(s),s.compile&&(v=s.compile)};var g,b,k={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(k,{batch:()=>O,computed:()=>w,effect:()=>S,signal:()=>A,untracked:()=>N});var A=(e,t,r=new Set)=>((t={get value(){return g?.deps.push(r.add(g)),e},set value(t){if(t!==e){e=t;for(let e of r)b?b.add(e):e()}},peek:()=>e}).toJSON=t.then=t.toString=t.valueOf=()=>t.value,t),S=(e,t,r,l)=>(l=(r=l=>{t?.call?.(),l=g,g=r;try{t=e()}finally{g=l}}).deps=[],r(),e=>{for(t?.call?.();e=l.pop();)e.delete(r)}),w=(e,t=A(),r,l)=>((r={get value(){return l||=S((()=>t.value=e())),t.value},peek:t.peek}).toJSON=r.then=r.toString=r.valueOf=()=>r.value,r),O=e=>{let t=b;t||(b=new Set);try{e()}finally{if(!t){t=b,b=null;for(const e of t)e()}}},N=(e,t,r)=>(t=g,g=null,r=e(),g=t,r),x=Symbol(":each");p.each=(e,[l,s,c],u)=>{const f=e[x]=document.createTextNode("");e.replaceWith(f);let p,d,v=0;const h=n((()=>{d=null;let e=c(u);return"number"==typeof e&&(e=Array.from({length:e},((e,t)=>t+1))),e?.constructor===Object&&(d=Object.keys(e),e=Object.values(e)),e||[]})),m=()=>{r((()=>{let t=0,r=h.value,c=r.length;if(p&&!p[o]){for(let e of p[a]||[])e[Symbol.dispose]();p=null,v=0}if(c<v)p.length=c;else{if(p)for(;t<v;t++)p[t]=r[t];else p=r;for(;t<c;t++){p[t]=r[t];let o=t,c=i({[l]:n((()=>p[o])),[s]:d?d[o]:o},u),v=(e.content||e).cloneNode(!0),h=e.content?{children:[...v.children],remove(){this.children.map((e=>e.remove()))}}:v;f.before(v),y(h,c),((p[a]||=[])[t]||={})[Symbol.dispose]=()=>{h[Symbol.dispose](),h.remove()}}}v=c}))};let g=0;return t((()=>{h.value[o]?.value,g?g++:(m(),queueMicrotask((()=>(g&&m(),g=0))))}))},p.each.parse=(e,t)=>{let[r,l]=e.split(/\s+in\s+/),[n,s="$"]=r.split(/\s*,\s*/);return[n,s,t(l)]};var j=Symbol("if");p.if=(e,r,l)=>{let n,s,a,o=e.parentNode,i=e.nextElementSibling,c=document.createTextNode(""),u=[];return e.after(c),e.content?(n=u,e.remove(),s=[...e.content.childNodes]):s=n=[e],i?.hasAttribute(":else")?(i.removeAttribute(":else"),i.hasAttribute(":if")?a=u:(i.remove(),a=i.content?[...i.content.childNodes]:[i])):a=u,t((()=>{const t=r(l)?s:e[j]?u:a;if(i&&(i[j]=t===s),n!=t){n[0]?.[x]&&(n=[n[0][x]]);for(let e of n)e.remove();n=t;for(let e of n)o.insertBefore(e,c),y(e,l)}}))},p.default=(e,r,l,n)=>{let s,a=n.startsWith("on")&&n.slice(2);return t(a?()=>(s?.(),s=$(e,a,r(l))):()=>{let t=r(l);if(n)C(e,n,D(t,l));else for(let r in t)C(e,_(r),D(t[r],l))})};var $=(e,t,r=(()=>{}))=>{const l={evt:"",target:e,test:()=>!0};l.evt=t.replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,r="")=>(l.test=E[t]?.(l,...r.split("-"))||l.test,"")));const{evt:n,target:s,test:a,defer:o,stop:i,prevent:c,...u}=l;o&&(r=o(r));const f=e=>a(e)&&(i&&e.stopPropagation(),c&&e.preventDefault(),r.call(s,e));return s.addEventListener(n,f,u),()=>s.removeEventListener(n,f,u)},E={prevent(e){e.prevent=!0},stop(e){e.stop=!0},once(e){e.once=!0},passive(e){e.passive=!0},capture(e){e.capture=!0},window(e){e.target=window},document(e){e.target=document},throttle(e,t){e.defer=e=>P(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>W(e,t?Number(t)||0:108)},outside:e=>t=>{let r=e.target;return!(r.contains(t.target)||!1===t.target.isConnected||r.offsetWidth<1&&r.offsetHeight<1)},self:e=>t=>t.target===e.target,ctrl:(e,...t)=>e=>T.ctrl(e)&&t.every((t=>T[t]?T[t](e):e.key===t)),shift:(e,...t)=>e=>T.shift(e)&&t.every((t=>T[t]?T[t](e):e.key===t)),alt:(e,...t)=>e=>T.alt(e)&&t.every((t=>T[t]?T[t](e):e.key===t)),meta:(e,...t)=>e=>T.meta(e)&&t.every((t=>T[t]?T[t](e):e.key===t)),arrow:()=>T.arrow,enter:()=>T.enter,escape:()=>T.escape,tab:()=>T.tab,space:()=>T.space,backspace:()=>T.backspace,delete:()=>T.delete,digit:()=>T.digit,letter:()=>T.letter,character:()=>T.character},T={ctrl:e=>e.ctrlKey||"Control"===e.key||"Ctrl"===e.key,shift:e=>e.shiftKey||"Shift"===e.key,alt:e=>e.altKey||"Alt"===e.key,meta:e=>e.metaKey||"Meta"===e.key||"Command"===e.key,arrow:e=>e.key.startsWith("Arrow"),enter:e=>"Enter"===e.key,escape:e=>e.key.startsWith("Esc"),tab:e=>"Tab"===e.key,space:e=>" "===e.key||"Space"===e.key||" "===e.key,backspace:e=>"Backspace"===e.key,delete:e=>"Delete"===e.key,digit:e=>/^\d$/.test(e.key),letter:e=>/^[a-zA-Z]$/.test(e.key),character:e=>/^\S$/.test(e.key)},C=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},P=(e,t)=>{let r,l,n=s=>{r=!0,setTimeout((()=>{if(r=!1,l)return l=!1,n(s),e(s)}),t)};return t=>r?l=!0:(n(t),e(t))},W=(e,t)=>{let r;return l=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(l)}),t)}},_=e=>e.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase())),D=(e,t)=>e?.replace?e.replace(/\$<([^>]+)>/g,((e,r)=>t[r]??"")):e;p.ref=(e,t,r)=>{r[D(t,r)]=e},p.ref.parse=e=>e,p.with=(e,r,l)=>{let n;return t((()=>{let t=r(l);y(e,n?t:n=i(t,l))}))},p.html=(e,t,r)=>{let l=t(r);if(!l)return;let n=(l.content||l).cloneNode(!0);e.replaceChildren(n),y(e,r)},p.text=(e,r,l)=>(e.content&&e.replaceWith(e=document.createTextNode("")),t((()=>{let t=r(l);e.textContent=null==t?"":t}))),p.class=(e,r,l)=>{let n=new Set;return t((()=>{let t=r(l),s=new Set;t&&("string"==typeof t?D(t,l).split(" ").map((e=>s.add(e))):Array.isArray(t)?t.map((e=>(e=D(e,l))&&s.add(e))):Object.entries(t).map((([e,t])=>t&&s.add(e))));for(let t of n)s.has(t)?s.delete(t):e.classList.remove(t);for(let t of n=s)e.classList.add(t)}))},p.style=(e,r,l)=>{let n=e.getAttribute("style")||"";return n.endsWith(";")||(n+="; "),t((()=>{let t=r(l);if("string"==typeof t)e.setAttribute("style",n+D(t,l));else{e.setAttribute("style",n);for(let r in t)e.style.setProperty(r,D(t[r],l))}}))},p.value=(e,r,l)=>{let n,s,a="text"===e.type||""===e.type?t=>e.setAttribute("value",e.value=null==t?"":t):"TEXTAREA"===e.tagName||"text"===e.type||""===e.type?t=>(n=e.selectionStart,s=e.selectionEnd,e.setAttribute("value",e.value=null==t?"":t),n&&e.setSelectionRange(n,s)):"checkbox"===e.type?t=>(e.checked=t,C(e,"checked",t)):"select-one"===e.type?t=>{for(let t in e.options)t.removeAttribute("selected");e.value=t,e.selectedOptions[0]?.setAttribute("selected","")}:t=>e.value=t;return t((()=>a(r(l))))},p.fx=(e,r,l)=>t((()=>r(l))),y.use(k),y.use({compile:e=>y.constructor("__scope",`with (__scope) { return ${e} };`)});var K=y;export{K as default};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -358,10 +358,14 @@ To destroy state and detach sprae handlers, call `element[Symbol.dispose]()`. --
|
|
|
358
358
|
|
|
359
359
|
## Justification
|
|
360
360
|
|
|
361
|
-
[Template-parts](https://github.com/dy/template-parts) is stuck with native HTML quirks ([parsing table](https://github.com/github/template-parts/issues/24), [SVG attributes](https://github.com/github/template-parts/issues/25), [liquid syntax](https://shopify.github.io/liquid/tags/template/#raw) conflict etc)
|
|
362
|
-
[Alpine](https://github.com/alpinejs/alpine) / [petite-vue](https://github.com/vuejs/petite-vue) / [lucia](https://github.com/aidenyabi/lucia) escape native HTML quirks, but have excessive API (`:`, `x-`, `{}`, `@`, `$`)
|
|
363
|
-
|
|
364
|
-
_Sprae_ holds open & minimalistic philosophy
|
|
361
|
+
* [Template-parts](https://github.com/dy/template-parts) is stuck with native HTML quirks ([parsing table](https://github.com/github/template-parts/issues/24), [SVG attributes](https://github.com/github/template-parts/issues/25), [liquid syntax](https://shopify.github.io/liquid/tags/template/#raw) conflict etc).
|
|
362
|
+
* [Alpine](https://github.com/alpinejs/alpine) / [petite-vue](https://github.com/vuejs/petite-vue) / [lucia](https://github.com/aidenyabi/lucia) escape native HTML quirks, but have excessive API (`:`, `x-`, `{}`, `@`, `$`), tend to [self-encapsulate](https://github.com/alpinejs/alpine/discussions/3223) and not care about size/performance.
|
|
363
|
+
|
|
364
|
+
_Sprae_ holds open & minimalistic philosophy:
|
|
365
|
+
* Slim `:` API and _signals_ reactivity.
|
|
366
|
+
* Pluggable directives & configurable internals.
|
|
367
|
+
* Small, safe & performant.
|
|
368
|
+
* Aims at making developers happy 🫰
|
|
365
369
|
|
|
366
370
|
<!--
|
|
367
371
|
| | [AlpineJS](https://github.com/alpinejs/alpine) | [Petite-Vue](https://github.com/vuejs/petite-vue) | Sprae |
|
package/store.js
CHANGED
|
@@ -4,7 +4,7 @@ import { signal, computed, effect, batch, untracked } from './signal.js'
|
|
|
4
4
|
export const _signals = Symbol('signals'), _change = Symbol('length');
|
|
5
5
|
|
|
6
6
|
// object store is not lazy
|
|
7
|
-
export default function store(values) {
|
|
7
|
+
export default function store(values, parent) {
|
|
8
8
|
if (!values) return values
|
|
9
9
|
|
|
10
10
|
// ignore existing state as argument
|
|
@@ -17,7 +17,7 @@ export default function store(values) {
|
|
|
17
17
|
if (values.constructor !== Object) return values;
|
|
18
18
|
|
|
19
19
|
// NOTE: if you decide to unlazy values, think about large arrays - init upfront can be costly
|
|
20
|
-
let signals = {}, _len = signal(Object.values(values).length)
|
|
20
|
+
let signals = { ...parent?.[_signals] }, _len = signal(Object.values(values).length)
|
|
21
21
|
|
|
22
22
|
// proxy conducts prop access to signals
|
|
23
23
|
const state = new Proxy(signals, {
|