yandel 1.1.0 → 1.1.2
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 +112 -71
- package/dist/index.d.ts +1 -1
- package/dist/node.d.ts +3 -2
- package/dist/node.js +50 -61
- package/dist/tags.d.ts +1 -1
- package/dist/utils.d.ts +4 -5
- package/dist/utils.js +22 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -124,8 +124,8 @@ Allows you to mount elements over a different parent, remaining in the same tree
|
|
|
124
124
|
import { Portal, div, span, h1 } from "yandel";
|
|
125
125
|
|
|
126
126
|
|
|
127
|
-
Portal(document.body, div());
|
|
128
127
|
// Renders a div inside body
|
|
128
|
+
Portal(document.body, div());
|
|
129
129
|
|
|
130
130
|
Portal(document.querySelector("#someid")!, div(), span(), h1(), ...);
|
|
131
131
|
|
|
@@ -136,7 +136,7 @@ Example:
|
|
|
136
136
|
```ts
|
|
137
137
|
import { Portal, div, span, ValidTemplateReturn } from "yandel";
|
|
138
138
|
|
|
139
|
-
function
|
|
139
|
+
function Notifications(): ValidTemplateReturn {
|
|
140
140
|
return div(
|
|
141
141
|
Portal(document.body, span("Notification 1"), span("Notification 2")),
|
|
142
142
|
button("Remove notifications")
|
|
@@ -149,10 +149,18 @@ function Notification(): ValidTemplateReturn {
|
|
|
149
149
|
|
|
150
150
|
### Templates
|
|
151
151
|
|
|
152
|
-
Templates are functions that return
|
|
152
|
+
Templates are functions that return `ValidNodeChild`. They help you customize and modularize:
|
|
153
153
|
|
|
154
154
|
```ts
|
|
155
|
-
import {
|
|
155
|
+
import {
|
|
156
|
+
aside,
|
|
157
|
+
div,
|
|
158
|
+
p,
|
|
159
|
+
strong,
|
|
160
|
+
span,
|
|
161
|
+
button,
|
|
162
|
+
ValidTemplateReturn,
|
|
163
|
+
} from "yandel";
|
|
156
164
|
|
|
157
165
|
function TotalPriceButton(
|
|
158
166
|
qTy: number,
|
|
@@ -165,29 +173,89 @@ function TotalPriceButton(
|
|
|
165
173
|
);
|
|
166
174
|
}
|
|
167
175
|
|
|
168
|
-
TotalPriceButton(4, 2, () => buy());
|
|
176
|
+
aside(TotalPriceButton(4, 2, () => buy()));
|
|
169
177
|
/**
|
|
178
|
+
* <aside>
|
|
170
179
|
* <div>
|
|
171
180
|
* <p><strong>Total is:</strong>8 $</>
|
|
172
181
|
* <button>Buy</button>
|
|
173
182
|
* </div>
|
|
183
|
+
* </aside>
|
|
174
184
|
*/
|
|
175
185
|
```
|
|
176
186
|
|
|
187
|
+
Templates can return an array, when no parent is needed:
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
function NotificationList(notifications: string[]): ValidTemplateReturn {
|
|
191
|
+
return notifications.map((notification) => div(icon(), span(notification)));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function AppNotifications() {
|
|
195
|
+
const notifications: string[] = [...];
|
|
196
|
+
return div(...NotificationList(notifications));
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### Future node
|
|
201
|
+
|
|
202
|
+
Future nodes are `templates` (functions) and will be created at render time (as `components` and `text`). This applies for all type of functions that return a `ValidTemplateReturn`; also the generic tags like `div`, `span`, etc. are allowed
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import { div, main, nav } from "yandel"
|
|
206
|
+
|
|
207
|
+
function MyGridOfPhotos () {
|
|
208
|
+
return div(...);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function App () {
|
|
212
|
+
return main(
|
|
213
|
+
nav(...),
|
|
214
|
+
MyGridOfPhotos // This function will be executed at render time
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
This might be necessary in some kind of situations, like explained in the [`Contexts`](#contexts) section.
|
|
221
|
+
|
|
222
|
+
In this example:
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { button, div, p } from "yandel";
|
|
226
|
+
|
|
227
|
+
function BuyButton(onclick: EventListener) {
|
|
228
|
+
return button(
|
|
229
|
+
{
|
|
230
|
+
onclick,
|
|
231
|
+
className: "button",
|
|
232
|
+
},
|
|
233
|
+
"Buy"
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function TotalPriceButton(price: number) {
|
|
238
|
+
const handleBuy = () => {
|
|
239
|
+
...
|
|
240
|
+
};
|
|
241
|
+
return div(p(`Total is: ${price}`), BuyButton(handleBuy));
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The tree will be completely generated when you call `TotalPriceButton`.
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
return div(p(`Total is: ${price}`), () => BuyButton(handleBuy));
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Now, `BuyButton` will be created at render time.
|
|
252
|
+
|
|
177
253
|
### Components
|
|
178
254
|
|
|
179
|
-
Components add the reactivity to the game. They are defined extending the `
|
|
255
|
+
Components add the reactivity to the game. They are defined extending the `Component` class and must provide a `render` method (a template):
|
|
180
256
|
|
|
181
257
|
```ts
|
|
182
|
-
import {
|
|
183
|
-
Component,
|
|
184
|
-
div,
|
|
185
|
-
p,
|
|
186
|
-
strong,
|
|
187
|
-
span,
|
|
188
|
-
button,
|
|
189
|
-
ValidTemplateReturn,
|
|
190
|
-
} from "yandel";
|
|
258
|
+
import { Component, div, p, strong, button, ValidTemplateReturn } from "yandel";
|
|
191
259
|
|
|
192
260
|
class TotalPriceButton extends Component {
|
|
193
261
|
private readonly total: number;
|
|
@@ -199,7 +267,7 @@ class TotalPriceButton extends Component {
|
|
|
199
267
|
}
|
|
200
268
|
public render(): ValidTemplateReturn {
|
|
201
269
|
return div(
|
|
202
|
-
p(strong("Total is:"),
|
|
270
|
+
p(strong("Total is:"), ` ${this.total} $`),
|
|
203
271
|
button({ onclick: this.onClick }, "Buy")
|
|
204
272
|
);
|
|
205
273
|
}
|
|
@@ -223,21 +291,13 @@ section(new TotalPriceButton(4, 2, buyFn));
|
|
|
223
291
|
Components can return an array:
|
|
224
292
|
|
|
225
293
|
```ts
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
this.total = qTy * uPrice;
|
|
232
|
-
this.onClick = onClick;
|
|
233
|
-
}
|
|
234
|
-
public render(): ValidTemplateReturn {
|
|
235
|
-
return [
|
|
236
|
-
p(strong("Total is:"), span(`${this.total} $`)),
|
|
237
|
-
button({ onclick: this.onClick }, "Buy"),
|
|
238
|
-
];
|
|
239
|
-
}
|
|
294
|
+
public render(): ValidTemplateReturn {
|
|
295
|
+
return [
|
|
296
|
+
p(strong("Total is:"), span(`${this.total} $`)),
|
|
297
|
+
button({ onclick: this.onClick }, "Buy"),
|
|
298
|
+
];
|
|
240
299
|
}
|
|
300
|
+
|
|
241
301
|
```
|
|
242
302
|
|
|
243
303
|
#### Reactivity
|
|
@@ -245,15 +305,7 @@ class TotalPriceButton extends Component {
|
|
|
245
305
|
`State` object type is defined using the `Component's` generic argument. To set the `initial state`, `defineState` must be called in the constructor.
|
|
246
306
|
|
|
247
307
|
```ts
|
|
248
|
-
import {
|
|
249
|
-
Component,
|
|
250
|
-
div,
|
|
251
|
-
p,
|
|
252
|
-
strong,
|
|
253
|
-
span,
|
|
254
|
-
button,
|
|
255
|
-
ValidTemplateReturn,
|
|
256
|
-
} from "yandel";
|
|
308
|
+
import { Component, div, p, strong, button, ValidTemplateReturn } from "yandel";
|
|
257
309
|
|
|
258
310
|
class TotalPriceButton extends Component<{
|
|
259
311
|
loading: boolean;
|
|
@@ -279,7 +331,7 @@ class TotalPriceButton extends Component<{
|
|
|
279
331
|
}
|
|
280
332
|
public render(): ValidTemplateReturn {
|
|
281
333
|
return div(
|
|
282
|
-
p(strong("Total is:"),
|
|
334
|
+
p(strong("Total is:"), ` ${this.total} $`),
|
|
283
335
|
button(
|
|
284
336
|
{
|
|
285
337
|
onclick: this.handleClick.bind(this), // Don't forget to bind if needed
|
|
@@ -323,7 +375,7 @@ this.state = { loading: false }; // state is a read-only property!
|
|
|
323
375
|
|
|
324
376
|
---
|
|
325
377
|
|
|
326
|
-
`Effects` are callbacks that are executed when the component is
|
|
378
|
+
`Effects` are callbacks that are executed when the component is attached or updated. They are created providing a callback to `this.effect` and should be called inside the `render` method. Components can have more than one effect/cleanup and they're executed in the order they are defined (FIFO).
|
|
327
379
|
|
|
328
380
|
```ts
|
|
329
381
|
import { Component, p, ValidTemplateReturn } from "yandel";
|
|
@@ -414,8 +466,8 @@ public render(): ValidTemplateReturn {
|
|
|
414
466
|
|
|
415
467
|
```
|
|
416
468
|
|
|
417
|
-
In this example, if the component is removed
|
|
418
|
-
Handle timeouts
|
|
469
|
+
In this example, if the component is removed or updated by other reasons, the timeout will still run and an error will be thrown (`Error: Component is deleted`).
|
|
470
|
+
Handle timeouts and more in the cleanups to prevent weird behavior:
|
|
419
471
|
|
|
420
472
|
```ts
|
|
421
473
|
|
|
@@ -437,7 +489,7 @@ public render(): ValidTemplateReturn {
|
|
|
437
489
|
|
|
438
490
|
### Contexts
|
|
439
491
|
|
|
440
|
-
Sharing data
|
|
492
|
+
Sharing data is easier with `contexts`. Define your context using `createContext`:
|
|
441
493
|
|
|
442
494
|
```ts
|
|
443
495
|
import { createContext } from "yandel";
|
|
@@ -453,7 +505,7 @@ Then, inside of your `render` function, call `provide` to hydrate your context.
|
|
|
453
505
|
- The component's instance.
|
|
454
506
|
- The value to store in the context.
|
|
455
507
|
|
|
456
|
-
Contexts that have not been provided are inaccesible. **A context can't be provided by more than one component**.
|
|
508
|
+
Contexts that have not been provided are inaccesible. **A context can't be provided by more than one component at the same time**.
|
|
457
509
|
|
|
458
510
|
```ts
|
|
459
511
|
|
|
@@ -468,22 +520,10 @@ class UserProvider extends Component<{user: User | null}> {
|
|
|
468
520
|
}
|
|
469
521
|
```
|
|
470
522
|
|
|
471
|
-
Once it has been provided, it's accesible everywhere, even for
|
|
472
|
-
**Note**: when a component provider changes (for example, a setState update), the context value will be again provided (re-hydrated). Don't forget that nodes that are not a child
|
|
473
|
-
|
|
474
|
-
```ts
|
|
475
|
-
public render(): ValidTemplateReturn {
|
|
476
|
-
return [
|
|
477
|
-
new UserProvider(),
|
|
478
|
-
UserConsumer()
|
|
479
|
-
];
|
|
480
|
-
}
|
|
481
|
-
// UserProvider provides the context.
|
|
482
|
-
// As it is before the consumer, the consumer will be able to consume it (if the consumer is called before the provider, an error would be thrown)
|
|
483
|
-
// When UserProvider changes (state update) its children will update. Therefore UserConsumer won't be updated.
|
|
484
|
-
```
|
|
523
|
+
Once it has been provided, it's accesible everywhere, even for those that are not children (if so, you must be responsible of the context life-time, and when/where is or not aviable).
|
|
524
|
+
**Note**: when a component provider changes (for example, a setState update), the context value will be again provided (re-hydrated) by the render function. Don't forget that nodes that are not a child of the component's tree won't be updated:
|
|
485
525
|
|
|
486
|
-
To consume a context, call `consume
|
|
526
|
+
To consume a context, call `consume`;
|
|
487
527
|
|
|
488
528
|
```ts
|
|
489
529
|
function UserConsumer() {
|
|
@@ -498,7 +538,7 @@ class UserConsumer extends Component {
|
|
|
498
538
|
}
|
|
499
539
|
}
|
|
500
540
|
|
|
501
|
-
function
|
|
541
|
+
function nonUiFunction () {
|
|
502
542
|
const { user } = userContext.consume();
|
|
503
543
|
...;
|
|
504
544
|
}
|
|
@@ -519,7 +559,6 @@ function UserConsumerWithError() {
|
|
|
519
559
|
|
|
520
560
|
```ts
|
|
521
561
|
function UserConsumerWithError() {
|
|
522
|
-
// Not checking if context is accesible
|
|
523
562
|
const { user } = userContext.consume(); // Error: cannot destructure property as it's undefined!!
|
|
524
563
|
return ...;
|
|
525
564
|
}
|
|
@@ -527,19 +566,21 @@ function UserConsumerWithError() {
|
|
|
527
566
|
|
|
528
567
|
#### Future nodes
|
|
529
568
|
|
|
530
|
-
|
|
569
|
+
As explained in the section of [future nodes](#future-node), `components`, `text` and `future nodes` are created at render time, and if your consumer is a function, like in the next example:
|
|
531
570
|
|
|
532
571
|
```ts
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
572
|
+
function UserConsumer() {
|
|
573
|
+
const { user } = userContext.consume();
|
|
574
|
+
return ...;
|
|
575
|
+
}
|
|
576
|
+
class App extends Component {
|
|
577
|
+
public render(): ValidTemplateReturn {
|
|
578
|
+
return [new UserProvider(), UserConsumer()];
|
|
579
|
+
}
|
|
538
580
|
}
|
|
539
581
|
```
|
|
540
582
|
|
|
541
|
-
`UserConsumer`
|
|
542
|
-
In this situations, you can use `Future Nodes`. They are functions that are valid as child, and will be created at render time.
|
|
583
|
+
`UserConsumer` will be created before the `UserProvider` is rendered and provides, leading to an undefined context.
|
|
543
584
|
|
|
544
585
|
```ts
|
|
545
586
|
public render(): ValidTemplateReturn {
|
|
@@ -550,7 +591,7 @@ public render(): ValidTemplateReturn {
|
|
|
550
591
|
}
|
|
551
592
|
```
|
|
552
593
|
|
|
553
|
-
Now, `UserConsumer` will be able to consume.
|
|
594
|
+
Now, `UserConsumer` will be able to consume. Don't forget that nodes outside the provider component
|
|
554
595
|
|
|
555
596
|
### Ref
|
|
556
597
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Component, createContext, createRoot, EffectHandler, Element, ElementRef, HTMLProps, HTMLTags, Portal, StateHandler, Stores, Styles, ValidNodeChild, ValidTemplateReturn, } from "./node";
|
|
1
|
+
export { Component, createContext, createRoot, EffectHandler, Element, ElementRef, HTMLProps, HTMLTags, Portal, StateHandler, Stores, Styles, ValidNode, ValidNodeChild, ValidTemplateReturn, FutureNode, } from "./node";
|
|
2
2
|
export * from "./tags";
|
package/dist/node.d.ts
CHANGED
|
@@ -17,7 +17,8 @@ interface SwitchableNode<T extends Node> {
|
|
|
17
17
|
switch(t: T): boolean;
|
|
18
18
|
}
|
|
19
19
|
type FutureNode = () => ValidNodeChild;
|
|
20
|
-
type
|
|
20
|
+
type ValidNode = Node | Component | Component<KeyedObject> | FutureNode;
|
|
21
|
+
type ValidNodeChild = ValidNode | null | string;
|
|
21
22
|
type ValidTemplateReturn = ValidNodeChild | ValidNodeChild[];
|
|
22
23
|
type EffectHandler = (() => void) | (() => () => void);
|
|
23
24
|
type ExcludeFunctions<T> = {
|
|
@@ -140,4 +141,4 @@ declare function createRoot<T extends HTMLElement>(root: T): {
|
|
|
140
141
|
render: (...children: ValidNodeChild[]) => void;
|
|
141
142
|
};
|
|
142
143
|
declare function createContext<T extends KeyedObject>(): Context<T>;
|
|
143
|
-
export { Component, createContext, createRoot, EffectHandler, Element, ElementRef, HTMLProps, HTMLTags, HTMLSVGTags, SVGProps, Node, Portal, StateHandler, Stores, Styles, TagNode, ValidNodeChild, ValidTemplateReturn, };
|
|
144
|
+
export { Component, createContext, createRoot, EffectHandler, Element, ElementRef, HTMLProps, HTMLTags, HTMLSVGTags, SVGProps, Node, Portal, StateHandler, Stores, Styles, TagNode, ValidNode, ValidNodeChild, ValidTemplateReturn, FutureNode, };
|
package/dist/node.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _is_fn, _is_string, asDeletable,
|
|
1
|
+
import { _is_fn, _is_string, asDeletable, InmutBool, setDeletable, } from "./utils";
|
|
2
2
|
const SVG_TAGS = new Set([
|
|
3
3
|
"a",
|
|
4
4
|
"animate",
|
|
@@ -122,8 +122,10 @@ class ComponentUpdateQueue {
|
|
|
122
122
|
function queueNodesDeletion(ns) {
|
|
123
123
|
queueMicrotask(() => {
|
|
124
124
|
for (const c of ns) {
|
|
125
|
-
if (c
|
|
125
|
+
if (c instanceof Node)
|
|
126
126
|
c.delete();
|
|
127
|
+
else
|
|
128
|
+
console.warn("Unknown child");
|
|
127
129
|
}
|
|
128
130
|
});
|
|
129
131
|
}
|
|
@@ -223,14 +225,16 @@ class ContentNode extends Node {
|
|
|
223
225
|
super.delete();
|
|
224
226
|
}
|
|
225
227
|
}
|
|
226
|
-
function
|
|
227
|
-
let n;
|
|
228
|
+
function create_template(t) {
|
|
228
229
|
try {
|
|
229
|
-
|
|
230
|
+
return t();
|
|
230
231
|
}
|
|
231
232
|
catch (error) {
|
|
232
|
-
throw new Error(
|
|
233
|
+
throw new Error(`Template create error: ${error}`);
|
|
233
234
|
}
|
|
235
|
+
}
|
|
236
|
+
function _get_node_from_future(t) {
|
|
237
|
+
const n = create_template(t);
|
|
234
238
|
if (_is_fn(n))
|
|
235
239
|
return _get_node_from_future(n);
|
|
236
240
|
return n;
|
|
@@ -271,7 +275,6 @@ function _apply_dom_prop(dom, props, prop) {
|
|
|
271
275
|
return;
|
|
272
276
|
}
|
|
273
277
|
}
|
|
274
|
-
// const pn = prop.toLowerCase();
|
|
275
278
|
if (typeof v === "boolean") {
|
|
276
279
|
if (v)
|
|
277
280
|
dom.setAttribute(prop, "");
|
|
@@ -300,7 +303,6 @@ function _remove_dom_prop(dom, props, prop) {
|
|
|
300
303
|
if (prop === "style" && typeof v === "object") {
|
|
301
304
|
try {
|
|
302
305
|
Object.entries(v).forEach(([cssProp]) => {
|
|
303
|
-
// Solo aplicar si la propiedad existe en CSSStyleDeclaration
|
|
304
306
|
if (cssProp in dom.style) {
|
|
305
307
|
dom.style[cssProp] = "";
|
|
306
308
|
}
|
|
@@ -557,22 +559,19 @@ class ComponentNode extends Node {
|
|
|
557
559
|
create() {
|
|
558
560
|
if (this._deleted)
|
|
559
561
|
throw new Error("Attempt to create a deleted node");
|
|
560
|
-
if (this._template.
|
|
562
|
+
if (asDeletable(this._template).deleted)
|
|
561
563
|
throw new Error("Template has been deleted");
|
|
562
564
|
nextInternalTick(this._template);
|
|
563
|
-
let child;
|
|
564
565
|
try {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
566
|
+
const child = create_template(this._template.render.bind(this._template));
|
|
567
|
+
if (child == null) {
|
|
568
|
+
if (this.hasChildren) {
|
|
569
|
+
this.clearChildren();
|
|
570
|
+
}
|
|
570
571
|
return;
|
|
571
572
|
}
|
|
572
|
-
if (child == null)
|
|
573
|
-
return;
|
|
574
573
|
const nc = Array.isArray(child)
|
|
575
|
-
? child
|
|
574
|
+
? [...child]
|
|
576
575
|
: typeof child === "string"
|
|
577
576
|
? [new ContentNode(child)]
|
|
578
577
|
: [child];
|
|
@@ -612,7 +611,7 @@ class ComponentNode extends Node {
|
|
|
612
611
|
if (this._deleted)
|
|
613
612
|
return;
|
|
614
613
|
this.clearChildren();
|
|
615
|
-
this._template.
|
|
614
|
+
asDeletable(this._template).delete();
|
|
616
615
|
super.delete();
|
|
617
616
|
}
|
|
618
617
|
switch(t) {
|
|
@@ -632,7 +631,7 @@ class ComponentNode extends Node {
|
|
|
632
631
|
return this.needs_update;
|
|
633
632
|
}
|
|
634
633
|
switchTemplate(t) {
|
|
635
|
-
this._template.
|
|
634
|
+
asDeletable(this._template).delete();
|
|
636
635
|
this._template = t;
|
|
637
636
|
getInternals(this._template).switch(this);
|
|
638
637
|
this.needs_update = true;
|
|
@@ -707,7 +706,7 @@ class ComponentInternals {
|
|
|
707
706
|
this._state = undefined;
|
|
708
707
|
this._state_defined = false;
|
|
709
708
|
for (const c of this.p) {
|
|
710
|
-
asDeletable(c)
|
|
709
|
+
asDeletable(c).delete();
|
|
711
710
|
}
|
|
712
711
|
}
|
|
713
712
|
get deleted() {
|
|
@@ -752,11 +751,15 @@ function nextInternalTick(target) {
|
|
|
752
751
|
}
|
|
753
752
|
}
|
|
754
753
|
class Component {
|
|
754
|
+
// public readonly id = Symbol();
|
|
755
755
|
static is(t) {
|
|
756
756
|
return t instanceof this;
|
|
757
757
|
}
|
|
758
758
|
constructor() {
|
|
759
|
-
|
|
759
|
+
setDeletable(this, () => {
|
|
760
|
+
nextInternalTick(this);
|
|
761
|
+
deleteInternals(this);
|
|
762
|
+
});
|
|
760
763
|
Object.defineProperties(this, {
|
|
761
764
|
[ComponentInternalKey]: {
|
|
762
765
|
value: new ComponentInternals(),
|
|
@@ -764,24 +767,6 @@ class Component {
|
|
|
764
767
|
writable: false,
|
|
765
768
|
configurable: true,
|
|
766
769
|
},
|
|
767
|
-
_deleted: {
|
|
768
|
-
get: () => deleted,
|
|
769
|
-
set: (d) => {
|
|
770
|
-
deleted = d;
|
|
771
|
-
},
|
|
772
|
-
configurable: false,
|
|
773
|
-
enumerable: false,
|
|
774
|
-
},
|
|
775
|
-
_delete: {
|
|
776
|
-
value: () => {
|
|
777
|
-
nextInternalTick(this);
|
|
778
|
-
deleteInternals(this);
|
|
779
|
-
this._deleted = true;
|
|
780
|
-
},
|
|
781
|
-
writable: false,
|
|
782
|
-
configurable: false,
|
|
783
|
-
enumerable: false,
|
|
784
|
-
},
|
|
785
770
|
});
|
|
786
771
|
}
|
|
787
772
|
get state() {
|
|
@@ -813,17 +798,17 @@ class Context {
|
|
|
813
798
|
});
|
|
814
799
|
}
|
|
815
800
|
get ok() {
|
|
816
|
-
return asDeletable(this)
|
|
801
|
+
return asDeletable(this).deleted === false && this.#_p !== undefined;
|
|
817
802
|
}
|
|
818
803
|
consume() {
|
|
819
|
-
if (asDeletable(this)
|
|
804
|
+
if (asDeletable(this).deleted && !this.#_p) {
|
|
820
805
|
console.warn("You are consuming a deleted context");
|
|
821
806
|
return undefined;
|
|
822
807
|
}
|
|
823
808
|
return this.#_s.stores;
|
|
824
809
|
}
|
|
825
810
|
provide(c, v) {
|
|
826
|
-
asDeletable(this)
|
|
811
|
+
asDeletable(this).deleted = false;
|
|
827
812
|
if (this.#_p) {
|
|
828
813
|
getInternals(this.#_p).p.delete(this);
|
|
829
814
|
this.#_p = undefined;
|
|
@@ -891,7 +876,7 @@ function diffChildren(a, b) {
|
|
|
891
876
|
continue;
|
|
892
877
|
}
|
|
893
878
|
if (_is_string(ca) || _is_fn(ca)) {
|
|
894
|
-
console.warn("
|
|
879
|
+
console.warn("Not a valid node to diff");
|
|
895
880
|
continue;
|
|
896
881
|
}
|
|
897
882
|
else if (Component.is(ca)) {
|
|
@@ -936,26 +921,32 @@ function diffChildren(a, b) {
|
|
|
936
921
|
}
|
|
937
922
|
else if (Component.is(node)) {
|
|
938
923
|
if (ComponentNode.is(ca)) {
|
|
924
|
+
if (node === ca.template) {
|
|
925
|
+
ca.needs_update = true;
|
|
926
|
+
continue;
|
|
927
|
+
}
|
|
939
928
|
ca.switchTemplate(node);
|
|
940
929
|
}
|
|
941
930
|
else {
|
|
942
931
|
ca.delete();
|
|
943
932
|
a[i] = new ComponentNode(node).setIndex_of(ri++);
|
|
944
|
-
changed.set(true);
|
|
945
933
|
}
|
|
934
|
+
changed.set(true);
|
|
946
935
|
}
|
|
947
|
-
else {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
changed.set(true);
|
|
952
|
-
}
|
|
953
|
-
else
|
|
954
|
-
changed.set(diff(ca, node));
|
|
936
|
+
else if (ca.$typeof !== node.$typeof) {
|
|
937
|
+
ca.delete();
|
|
938
|
+
a[i] = node.setIndex_of(ri++);
|
|
939
|
+
changed.set(true);
|
|
955
940
|
}
|
|
941
|
+
else
|
|
942
|
+
changed.set(diff(ca, node));
|
|
956
943
|
}
|
|
957
944
|
else if (Component.is(cb)) {
|
|
958
945
|
if (ComponentNode.is(ca)) {
|
|
946
|
+
if (cb === ca.template) {
|
|
947
|
+
ca.needs_update = true;
|
|
948
|
+
continue;
|
|
949
|
+
}
|
|
959
950
|
ca.switchTemplate(cb);
|
|
960
951
|
}
|
|
961
952
|
else {
|
|
@@ -964,15 +955,13 @@ function diffChildren(a, b) {
|
|
|
964
955
|
changed.set(true);
|
|
965
956
|
}
|
|
966
957
|
}
|
|
967
|
-
else {
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
changed.set(true);
|
|
972
|
-
}
|
|
973
|
-
else
|
|
974
|
-
changed.set(diff(ca, cb));
|
|
958
|
+
else if (ca.$typeof !== cb.$typeof) {
|
|
959
|
+
ca.delete();
|
|
960
|
+
a[i] = cb.setIndex_of(ri++);
|
|
961
|
+
changed.set(true);
|
|
975
962
|
}
|
|
963
|
+
else
|
|
964
|
+
changed.set(diff(ca, cb));
|
|
976
965
|
}
|
|
977
966
|
}
|
|
978
967
|
}
|
package/dist/tags.d.ts
CHANGED
|
@@ -317,7 +317,7 @@ export declare function hgroup(props: HTMLProps<"hgroup">, ...children: ValidNod
|
|
|
317
317
|
/**
|
|
318
318
|
* hr - Creates hr Tag node
|
|
319
319
|
*/
|
|
320
|
-
export declare function hr(props
|
|
320
|
+
export declare function hr(props?: HTMLProps<"hr">): TagNode<"hr">;
|
|
321
321
|
/**
|
|
322
322
|
* html - Creates html Tag node
|
|
323
323
|
*/
|
package/dist/utils.d.ts
CHANGED
|
@@ -8,11 +8,10 @@ export declare class InmutBool {
|
|
|
8
8
|
}
|
|
9
9
|
export declare const DELETE_KEY: unique symbol;
|
|
10
10
|
export declare const DELETED_KEY: unique symbol;
|
|
11
|
-
interface
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
set [DELETED_KEY](v: boolean);
|
|
11
|
+
interface ExposedDeletable {
|
|
12
|
+
deleted: boolean;
|
|
13
|
+
delete(): void;
|
|
15
14
|
}
|
|
16
|
-
export declare function asDeletable(t: object):
|
|
15
|
+
export declare function asDeletable(t: object): ExposedDeletable;
|
|
17
16
|
export declare function setDeletable(t: object, deleter: VoidFunction): void;
|
|
18
17
|
export {};
|
package/dist/utils.js
CHANGED
|
@@ -22,7 +22,28 @@ export class InmutBool {
|
|
|
22
22
|
export const DELETE_KEY = Symbol("_d");
|
|
23
23
|
export const DELETED_KEY = Symbol("_dd");
|
|
24
24
|
export function asDeletable(t) {
|
|
25
|
-
return
|
|
25
|
+
return Object.defineProperties({}, {
|
|
26
|
+
delete: {
|
|
27
|
+
value: () => {
|
|
28
|
+
t[DELETE_KEY]();
|
|
29
|
+
},
|
|
30
|
+
writable: false,
|
|
31
|
+
enumerable: false,
|
|
32
|
+
configurable: false,
|
|
33
|
+
},
|
|
34
|
+
deleted: {
|
|
35
|
+
set: (v) => {
|
|
36
|
+
if (typeof v !== "boolean")
|
|
37
|
+
return;
|
|
38
|
+
t[DELETED_KEY] = v;
|
|
39
|
+
},
|
|
40
|
+
get: () => {
|
|
41
|
+
return t[DELETED_KEY];
|
|
42
|
+
},
|
|
43
|
+
enumerable: false,
|
|
44
|
+
configurable: false,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
26
47
|
}
|
|
27
48
|
export function setDeletable(t, deleter) {
|
|
28
49
|
let _d = false;
|