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 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 Notification(): ValidTemplateReturn {
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 nodes. They help you customize and modularize:
152
+ Templates are functions that return `ValidNodeChild`. They help you customize and modularize:
153
153
 
154
154
  ```ts
155
- import { div, p, strong, span, button, ValidTemplateReturn } from "yandel";
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 `Context` class and must provide a `render` method (a template):
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:"), span(`${this.total} $`)),
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
- class TotalPriceButton extends Component {
227
- private readonly total: number;
228
- private readonly onClick: VoidFunction;
229
- constructor(qTy: number, uPrice: number, onClick: VoidFunction) {
230
- super();
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:"), span(`${this.total} $`)),
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 mounted or unmounted. They are created with `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).
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, if not handled the timeout will run and an error will be thrown (`Error: Component is deleted`).
418
- Handle timeouts, deletions and more in the cleanups to prevent weird behavior:
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 between components is easier with `contexts`. Define your context using `createContext`:
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 non descendant nodes (if so, you must be responsible of the context life-time, and when/where is or not aviable).
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 inside the component's tree won't be updated:
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`. You can call this from a Component, a template, or wherever you want.
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 notAnUiFunction () {
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
- In this previous example:
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
- public render(): ValidTemplateReturn {
534
- return [
535
- new UserProvider(),
536
- UserConsumer()
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` won't be able to access the `UserContext`. `UserConsumer` is called before the `UserProvider` `render` method.
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 ValidNodeChild = Node | Component | Component<KeyedObject> | FutureNode | null | string;
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, DELETE_KEY, DELETED_KEY, InmutBool, setDeletable, } from "./utils";
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 && !_is_string(c) && !_is_fn(c) && !Component.is(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 _get_node_from_future(t) {
227
- let n;
228
+ function create_template(t) {
228
229
  try {
229
- n = t();
230
+ return t();
230
231
  }
231
232
  catch (error) {
232
- throw new Error("Future 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._deleted)
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
- try {
566
- child = this._template.render();
567
- }
568
- catch (error) {
569
- console.warn("Template create error:", error);
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._delete();
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._delete();
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)[DELETE_KEY]();
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
- let deleted = false;
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)[DELETED_KEY] === false && this.#_p !== undefined;
801
+ return asDeletable(this).deleted === false && this.#_p !== undefined;
817
802
  }
818
803
  consume() {
819
- if (asDeletable(this)[DELETED_KEY] && !this.#_p) {
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)[DELETED_KEY] = false;
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("Diffing a Future node");
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
- if (ca.$typeof !== node.$typeof) {
949
- ca.delete();
950
- a[i] = node.setIndex_of(ri++);
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
- if (ca.$typeof !== cb.$typeof) {
969
- ca.delete();
970
- a[i] = cb.setIndex_of(ri++);
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: HTMLProps<"hr">): TagNode<"hr">;
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 Deletable {
12
- [DELETE_KEY](): void;
13
- get [DELETED_KEY](): boolean;
14
- set [DELETED_KEY](v: boolean);
11
+ interface ExposedDeletable {
12
+ deleted: boolean;
13
+ delete(): void;
15
14
  }
16
- export declare function asDeletable(t: object): Deletable;
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 t;
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;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "yandel",
3
3
  "description": "A reactive lightweight TS frontend framework",
4
- "version": "1.1.0",
4
+ "version": "1.1.2",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [