sprae 6.1.1 → 7.0.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/package.json +9 -1
- package/readme.md +91 -44
- package/sprae.auto.js +601 -244
- package/sprae.auto.min.js +1 -1
- package/sprae.js +601 -244
- package/sprae.min.js +1 -1
- package/src/core.js +6 -13
- package/src/directives.js +38 -37
- package/src/{state.js → state.proxy.js} +36 -15
- package/src/state.signals-proxy.js +104 -0
- package/src/state.signals.js +82 -0
- package/.gitattributes +0 -2
- package/.github/workflows/node.js.yml +0 -30
- package/examples/todomvc.html +0 -98
- package/r&d.md +0 -620
- package/test/attrs.js +0 -754
- package/test/events.js +0 -138
- package/test/index.html +0 -36
- package/test/register.cjs +0 -20
- package/test/state.js +0 -296
- package/test/test.js +0 -13
- package/todo.md +0 -54
package/package.json
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprae",
|
|
3
3
|
"description": "DOM microhydration.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "7.0.0",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"module": "src/index.js",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"sprae.auto.js",
|
|
10
|
+
"sprae.auto.min.js",
|
|
11
|
+
"sprae.js",
|
|
12
|
+
"sprae.min.js",
|
|
13
|
+
"src"
|
|
14
|
+
],
|
|
8
15
|
"dependencies": {
|
|
16
|
+
"@preact/signals-core": "^1.5.0",
|
|
9
17
|
"swapdom": "^1.1.1"
|
|
10
18
|
},
|
|
11
19
|
"devDependencies": {
|
package/readme.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> DOM tree hydration with reactivity.
|
|
4
4
|
|
|
5
|
-
_Sprae_ is progressive enhancement framework, a tiny essential alternative to [alpine](https://github.com/alpinejs/alpine), [petite-vue](https://github.com/vuejs/petite-vue) or [template-parts](https://github.com/github/template-parts) with
|
|
5
|
+
_Sprae_ is progressive enhancement framework, a tiny essential alternative to [alpine](https://github.com/alpinejs/alpine), [petite-vue](https://github.com/vuejs/petite-vue) or [template-parts](https://github.com/github/template-parts) with enhanced ergonomics[*](#justification--alternatives). It enables simple markup logic without external scripts. Perfect for small websites, prototypes or UI logic.
|
|
6
6
|
|
|
7
7
|
## Use
|
|
8
8
|
|
|
@@ -12,9 +12,13 @@ To autoinit document, include [`sprae.auto.js`](./sprae.auto.js):
|
|
|
12
12
|
|
|
13
13
|
```html
|
|
14
14
|
<!-- <script src="https://cdn.jsdelivr.net/npm/sprae/sprae.auto.js" defer></script> -->
|
|
15
|
-
<script src="./path/to/sprae.auto.js"
|
|
15
|
+
<script defer src="./path/to/sprae.auto.js"></script>
|
|
16
16
|
|
|
17
|
-
<
|
|
17
|
+
<ul>
|
|
18
|
+
<li :each="item in ['apple', 'bananas', 'citrus']"">
|
|
19
|
+
<a :href="`#${item}`" :text="item" />
|
|
20
|
+
</li>
|
|
21
|
+
</ul>
|
|
18
22
|
```
|
|
19
23
|
|
|
20
24
|
### Manual init
|
|
@@ -23,19 +27,21 @@ To init manually as module, import [`sprae.js`](./sprae.js):
|
|
|
23
27
|
|
|
24
28
|
```html
|
|
25
29
|
<div id="container" :if="user">
|
|
26
|
-
Logged in as <span :text="user.
|
|
30
|
+
Logged in as <span :text="user.name">Guest.</span>
|
|
27
31
|
</div>
|
|
28
32
|
|
|
29
33
|
<script type="module">
|
|
30
34
|
// import sprae from 'https://cdn.jsdelivr.net/npm/sprae/sprae.js';
|
|
31
35
|
import sprae from './path/to/sprae.js';
|
|
32
36
|
|
|
33
|
-
const state = sprae(container, { user: {
|
|
34
|
-
state.user.
|
|
37
|
+
const state = sprae(container, { user: { name: 'Dmitry Ivanov' } });
|
|
38
|
+
state.user.name = 'dy'; // updates DOM
|
|
35
39
|
</script>
|
|
36
40
|
```
|
|
37
41
|
|
|
38
|
-
Sprae evaluates `:`-attributes and evaporates them
|
|
42
|
+
Sprae evaluates `:`-attributes and evaporates them.<br/>
|
|
43
|
+
Sprae creates reactive state representing current values in rendered DOM.<br/>
|
|
44
|
+
It is based on [preact signals](https://github.com/preactjs/signals) and can take them as inputs.
|
|
39
45
|
|
|
40
46
|
## Attributes
|
|
41
47
|
|
|
@@ -79,14 +85,14 @@ Welcome, <span :text="user.name">Guest</span>.
|
|
|
79
85
|
|
|
80
86
|
#### `:class="value"`
|
|
81
87
|
|
|
82
|
-
Set class value from either string, array or object.
|
|
88
|
+
Set class value from either a string, array or object.
|
|
83
89
|
|
|
84
90
|
```html
|
|
91
|
+
<!-- set from string -->
|
|
85
92
|
<div :class="`foo ${bar}`"></div>
|
|
86
93
|
|
|
87
|
-
<!--
|
|
94
|
+
<!-- extends existing class as "foo bar" -->
|
|
88
95
|
<div class="foo" :class="`bar`"></div>
|
|
89
|
-
<!-- <div class="foo bar"></div> -->
|
|
90
96
|
|
|
91
97
|
<!-- object with values -->
|
|
92
98
|
<div :class="{foo:true, bar: false}"></div>
|
|
@@ -94,11 +100,16 @@ Set class value from either string, array or object. Extends existing `class` at
|
|
|
94
100
|
|
|
95
101
|
#### `:style="value"`
|
|
96
102
|
|
|
97
|
-
Set style value from object or a string. Extends existing `style` attribute, if any.
|
|
103
|
+
Set style value from an object or a string. Extends existing `style` attribute, if any.
|
|
98
104
|
|
|
99
105
|
```html
|
|
100
|
-
|
|
106
|
+
<!-- from string -->
|
|
107
|
+
<div :style="`foo: ${bar}`"></div>
|
|
108
|
+
|
|
109
|
+
<!-- from object -->
|
|
101
110
|
<div :style="{foo: 'bar'}"></div>
|
|
111
|
+
|
|
112
|
+
<!-- set CSS variable -->
|
|
102
113
|
<div :style="{'--baz': qux}"></div>
|
|
103
114
|
```
|
|
104
115
|
|
|
@@ -107,9 +118,11 @@ Set style value from object or a string. Extends existing `style` attribute, if
|
|
|
107
118
|
Set value of an input, textarea or select. Takes handle of `checked` and `selected` attributes.
|
|
108
119
|
|
|
109
120
|
```html
|
|
110
|
-
|
|
111
|
-
<
|
|
121
|
+
<!-- set from value -->
|
|
122
|
+
<input :value="value" />
|
|
123
|
+
<textarea :value="value" />
|
|
112
124
|
|
|
125
|
+
<!-- selects right option -->
|
|
113
126
|
<select :value="selected">
|
|
114
127
|
<option :each="i in 5" :value="i" :text="i"></option>
|
|
115
128
|
</select>
|
|
@@ -132,15 +145,30 @@ Define or extend data scope for a subtree.
|
|
|
132
145
|
</x>
|
|
133
146
|
```
|
|
134
147
|
|
|
135
|
-
####
|
|
148
|
+
#### `:<prop>="value?"`
|
|
136
149
|
|
|
137
|
-
|
|
150
|
+
Set any attribute value or run an effect.
|
|
138
151
|
|
|
139
152
|
```html
|
|
140
|
-
|
|
153
|
+
<!-- Single property -->
|
|
154
|
+
<label :for="name" :text="name" />
|
|
141
155
|
|
|
142
|
-
|
|
143
|
-
<
|
|
156
|
+
<!-- Multiple properties -->
|
|
157
|
+
<input :id:name="name" />
|
|
158
|
+
|
|
159
|
+
<!-- Effect - returns undefined, triggers any time bar changes -->
|
|
160
|
+
<div :fx="void bar()" ></div>
|
|
161
|
+
|
|
162
|
+
<!-- Raw event listener (see events) -->
|
|
163
|
+
<div :onclick="e=>e.preventDefault()"></div>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### `:="props?"`
|
|
167
|
+
|
|
168
|
+
Spread multiple attibures.
|
|
169
|
+
|
|
170
|
+
```html
|
|
171
|
+
<input :="{ id: name, name, type:'text', value }" />
|
|
144
172
|
```
|
|
145
173
|
|
|
146
174
|
#### `:ref="id"`
|
|
@@ -160,30 +188,17 @@ Expose element to current data scope with the `id`:
|
|
|
160
188
|
</ul>
|
|
161
189
|
```
|
|
162
190
|
|
|
163
|
-
####
|
|
164
|
-
|
|
165
|
-
Spread multiple attibures.
|
|
166
|
-
|
|
167
|
-
```html
|
|
168
|
-
<input :="{ id: name, name, type:'text', value }" />
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
#### `:<prop>="value?"`
|
|
191
|
+
#### `:render="ref"`
|
|
172
192
|
|
|
173
|
-
|
|
193
|
+
Include template as element content.
|
|
174
194
|
|
|
175
195
|
```html
|
|
176
|
-
<!--
|
|
177
|
-
<
|
|
178
|
-
|
|
179
|
-
<!-- Multiple properties -->
|
|
180
|
-
<input :id:name="name" />
|
|
181
|
-
|
|
182
|
-
<!-- Effect - returns undefined, triggers any time bar changes -->
|
|
183
|
-
<div :fx="void bar()" ></div>
|
|
196
|
+
<!-- assign template element to foo variable -->
|
|
197
|
+
<template :ref="foo"><span :text="foo"></span></template>
|
|
184
198
|
|
|
185
|
-
<!--
|
|
186
|
-
<div :
|
|
199
|
+
<!-- rended template as content -->
|
|
200
|
+
<div :render="foo" :with="{foo:'bar'}">...inserted here...</div>
|
|
201
|
+
<div :render="foo" :with="{foo:'baz'}">...inserted here...</div>
|
|
187
202
|
```
|
|
188
203
|
|
|
189
204
|
|
|
@@ -191,7 +206,7 @@ Set any attribute value or run an effect.
|
|
|
191
206
|
|
|
192
207
|
#### `@<event>="handle"`, `@<foo>@<bar>.<baz>="handle"`
|
|
193
208
|
|
|
194
|
-
Attach event(s) listener with possible modifiers. `event` variable holds current event.
|
|
209
|
+
Attach event(s) listener with possible modifiers. `event` variable holds current event. Allows async handlers.
|
|
195
210
|
|
|
196
211
|
```html
|
|
197
212
|
<!-- Single event -->
|
|
@@ -224,7 +239,7 @@ Expressions are sandboxed, ie. don't access global/window scope by default (sinc
|
|
|
224
239
|
<!-- scrollY is undefined -->
|
|
225
240
|
```
|
|
226
241
|
|
|
227
|
-
Default sandbox provides: _window_, _document_, _console_, _history_, _location_,
|
|
242
|
+
Default sandbox provides: _window_, _document_, _console_, _history_, _location_, _Date_, _Set_, _Map_.
|
|
228
243
|
|
|
229
244
|
Sandbox can be extended as `Object.assign(sprae.globals, { BigInt })`.
|
|
230
245
|
|
|
@@ -237,13 +252,45 @@ To avoid _flash of unstyled content_, you can hide sprae attribute or add a cust
|
|
|
237
252
|
<style>[:each],[:hidden] {visibility: hidden}</style>
|
|
238
253
|
```
|
|
239
254
|
|
|
255
|
+
## Benchmark
|
|
256
|
+
|
|
257
|
+
Done via [js-framework-benchmark](https://github.com/krausest/js-framework-benchmark).
|
|
258
|
+
|
|
259
|
+
```sh
|
|
260
|
+
# prerequisite
|
|
261
|
+
npm ci
|
|
262
|
+
npm run install-server
|
|
263
|
+
npm start
|
|
264
|
+
|
|
265
|
+
# build
|
|
266
|
+
cd frameworks/keyed/sprae
|
|
267
|
+
npm ci
|
|
268
|
+
npm run build-prod
|
|
269
|
+
|
|
270
|
+
# bench
|
|
271
|
+
cd ../../..
|
|
272
|
+
cd webdriver-ts
|
|
273
|
+
npm ci
|
|
274
|
+
npm run compile
|
|
275
|
+
npm run bench keyed/sprae
|
|
276
|
+
|
|
277
|
+
# show results
|
|
278
|
+
cd ..
|
|
279
|
+
cd webdriver-ts-results
|
|
280
|
+
npm ci
|
|
281
|
+
cd ..
|
|
282
|
+
cd webdriver-ts
|
|
283
|
+
npm run results
|
|
284
|
+
```
|
|
285
|
+
|
|
240
286
|
## Examples
|
|
241
287
|
|
|
242
288
|
* TODO MVC: [demo](https://dy.github.io/sprae/examples/todomvc), [code](https://github.com/dy/sprae/blob/main/examples/todomvc.html)
|
|
243
289
|
* Wavearea: [demo](https://dy.github.io/wavearea?src=//cdn.freesound.org/previews/586/586281_2332564-lq.mp3), [code](https://github.com/dy/wavearea)
|
|
244
290
|
* Prostogreen [demo](http://web-being.org/prostogreen/), [code](https://github.com/web-being/prostogreen/)
|
|
245
291
|
|
|
246
|
-
|
|
292
|
+
|
|
293
|
+
## Justification
|
|
247
294
|
|
|
248
295
|
* [Template-parts](https://github.com/dy/template-parts) / [templize](https://github.com/dy/templize) is progressive, but 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). Also ergonomics of `attr="{{}}"` is inferior to `:attr=""` since it creates flash of uninitialized values. Also it's just nice to keep `{{}}` generic, regardless of markup, and attributes as part of markup.
|
|
249
296
|
* [Alpine](https://github.com/alpinejs/alpine) / [vue](https://github.com/vuejs/petite-vue) / [lit](https://github.com/lit/lit/tree/main/packages/lit-html) escape native HTML quirks, but the syntax space (`:attr`, `v-*`,`x-*`, `l-*` `@evt`, `{{}}`) is too broad, as well as functionality. Perfection is when there's nothing to take away, not add (c). Also they tend to [self-encapsulate](https://github.com/alpinejs/alpine/discussions/3223) making interop hard, invent own tooling or complex reactivity.
|
|
@@ -264,8 +311,8 @@ It is reminiscent of [XSLT](https://www.w3schools.com/xml/xsl_intro.asp), consid
|
|
|
264
311
|
## Alternatives
|
|
265
312
|
|
|
266
313
|
* [Alpine](https://github.com/alpinejs/alpine)
|
|
267
|
-
* [Lucia](https://github.com/aidenybai/lucia)
|
|
314
|
+
* ~~[Lucia](https://github.com/aidenybai/lucia)~~ deprecated
|
|
268
315
|
* [Petite-vue](https://github.com/vuejs/petite-vue)
|
|
269
|
-
* [
|
|
316
|
+
* [nuejs](https://github.com/nuejs/nuejs)
|
|
270
317
|
|
|
271
318
|
<p align="center"><a href="https://github.com/krsnzd/license/">🕉</a></p>
|