sprae 11.0.7 → 11.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/readme.md CHANGED
@@ -166,21 +166,21 @@ Run effect, not changing any attribute.
166
166
  <div :fx="id = setInterval(tick, 1000), () => clearInterval(id)" />
167
167
  ```
168
168
 
169
- #### `:ref="el => (...)"`
169
+ #### `:ref="name"`, `:ref="el => (...)"`
170
170
 
171
- Get reference to element (instead of `this`).
171
+ Expose element in state with `name` or get reference to element.
172
172
 
173
173
  ```html
174
- <!-- initialize element -->
175
- <textarea :ref="el => (/* onmount */, () => (/* onunmount */))" placeholder="Enter text..."></textarea>
176
-
177
- <!-- expose element in (sub)state -->
178
- <li :each="item in items" :with="{li:null}" :ref="el => li = el">
174
+ <!-- expose element in state -->
175
+ <li :each="item in items" :ref="li">
179
176
  <input :onfocus..onblur="e => (li.classList.add('editing'), e => li.classList.remove('editing'))"/>
180
177
  </li>
181
178
 
182
179
  <!-- set innerHTML -->
183
180
  <div :ref="el => el.innerHTML = '...'"></div>
181
+
182
+ <!-- initialize element -->
183
+ <textarea :ref="el => (/* onmount */, () => (/* onunmount */))" :if="show"></textarea>
184
184
  ```
185
185
 
186
186
  #### `:on<event>="handler"`, `:on<in>..on<out>="handler"`
@@ -326,7 +326,7 @@ _Sprae_ can be tailored to project needs via `sprae/core`:
326
326
 
327
327
  ```js
328
328
  // sprae.custom.js
329
- import sprae, { directive } from 'sprae/core'
329
+ import sprae, { dir, parse } from 'sprae/core'
330
330
  import * as signals from '@preact/signals'
331
331
  import compile from 'subscript'
332
332
 
@@ -336,9 +336,10 @@ import 'sprae/directive/if.js'
336
336
  import 'sprae/directive/text.js'
337
337
 
338
338
  // custom directive :id="expression"
339
- directive.id = (el, evaluate, state) => {
340
- return () => el.id = evaluate(state)
341
- }
339
+ dir('id', (el, state, expr) => {
340
+ // ...init
341
+ return value => el.id = value // update
342
+ })
342
343
 
343
344
  // configure signals
344
345
  sprae.use(signals)
@@ -368,6 +369,7 @@ Modern frontend stack is obese and unhealthy, like non-organic processed food. T
368
369
  * [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.
369
370
 
370
371
  _Sprae_ holds open & minimalistic philosophy:
372
+
371
373
  * Slim `:` API, _signals_ for reactivity.
372
374
  * Pluggable directives & configurable internals.
373
375
  * Small, safe & performant.
package/signal.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // ulive copy, stable minimal implementation
2
- let current, batched;
2
+ let current;
3
3
 
4
4
  export let signal = (v, s, obs = new Set) => (
5
5
  s = {
@@ -10,7 +10,7 @@ export let signal = (v, s, obs = new Set) => (
10
10
  set value(val) {
11
11
  if (val === v) return
12
12
  v = val;
13
- for (let sub of obs) batched ? batched.add(sub) : sub(); // notify effects
13
+ for (let sub of obs) sub(); // notify effects
14
14
  },
15
15
  peek() { return v },
16
16
  },
@@ -39,19 +39,8 @@ export let signal = (v, s, obs = new Set) => (
39
39
  c.toJSON = c.then = c.toString = c.valueOf = () => c.value,
40
40
  c
41
41
  ),
42
- batch = (fn) => {
43
- let fxs = batched;
44
- if (!fxs) batched = new Set;
45
- try { fn(); }
46
- finally {
47
- if (!fxs) {
48
- fxs = batched;
49
- batched = null;
50
- for (const fx of fxs) fx();
51
- }
52
- }
53
- },
54
- untracked = (fn, prev, v) => (prev = current, current = null, v = fn(), current = prev, v);
42
+ batch = fn => fn(),
43
+ untracked = batch
55
44
 
56
45
  // signals adapter - allows switching signals implementation and not depend on core
57
46
 
@@ -59,6 +48,6 @@ export function use(s) {
59
48
  signal = s.signal
60
49
  effect = s.effect
61
50
  computed = s.computed
62
- batch = s.batch || (fn => fn())
51
+ batch = s.batch || batch
63
52
  untracked = s.untracked || batch
64
53
  }
package/store.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // signals-based proxy
2
2
  import { signal, computed, batch, untracked } from './signal.js'
3
3
 
4
- export const _signals = Symbol('signals'), _change = Symbol('length');
4
+ export const _signals = Symbol('signals'), _change = Symbol('change');
5
5
 
6
6
  // object store is not lazy
7
7
  export default function store(values, parent) {
@@ -127,13 +127,13 @@ function set(signals, key, v) {
127
127
  else if (Array.isArray(v) && Array.isArray(s.peek())) {
128
128
  const cur = s.peek()
129
129
  // if we update plain array (stored in signal) - take over value instead
130
- if (cur[_change]) untracked(() => {
130
+ if (cur[_change]) {
131
131
  batch(() => {
132
132
  let i = 0, l = v.length;
133
133
  for (; i < l; i++) cur[i] = v[i]
134
134
  cur.length = l // forces deleting tail signals
135
135
  })
136
- })
136
+ }
137
137
  else {
138
138
  s.value = v
139
139
  }