@oscarpalmer/abydon 0.23.1 → 0.24.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.
@@ -1,27 +1,52 @@
1
- import { ERROR_FRAGMENT, ERROR_IDENTIFIER_DUPLICATE, ERROR_IDENTIFIER_TYPE, NAME_FRAGMENTS } from "./constants.mjs";
2
- import { isFragment, isFragments } from "./helpers/index.mjs";
1
+ import { MESSAGE_FRAGMENTS_FRAGMENT_RESULT, MESSAGE_FRAGMENTS_FRAGMENT_TYPE, MESSAGE_FRAGMENTS_IDENTIFIER_RESULT_DUPLICATE, MESSAGE_FRAGMENTS_IDENTIFIER_RESULT_TYPE, MESSAGE_FRAGMENTS_IDENTIFIER_TYPE, MESSAGE_FRAGMENTS_VALUE, NAME_FRAGMENTS, SYMBOL } from "./constants.mjs";
2
+ import { isFragment } from "./helpers/index.mjs";
3
3
  import { getString } from "@oscarpalmer/atoms/string";
4
- import { array } from "@oscarpalmer/mora";
4
+ import { array, isReactiveArray } from "@oscarpalmer/mora";
5
5
  //#region src/fragments.ts
6
- var Fragments = class {
7
- #state;
8
- constructor(items, identify, fragment) {
9
- Object.defineProperty(this, NAME_FRAGMENTS, { value: true });
10
- this.#state = {
11
- fragment,
12
- identify,
13
- array: items,
14
- instances: {},
15
- mapped: array([]),
16
- subscriber: void 0
17
- };
18
- fragmentsStates.set(this, this.#state);
19
- initializeFragments(this.#state);
20
- }
21
- };
22
- function handleFragments(item, remove) {
23
- const state = isFragments(item) ? fragmentsStates.get(item) : item;
24
- (remove ? removeFragments : initializeFragments)(state);
6
+ function Fragments(items, identify, fragment) {
7
+ this[SYMBOL] = {
8
+ fragment,
9
+ identify,
10
+ array: items,
11
+ instances: {},
12
+ mapped: array([]),
13
+ name: NAME_FRAGMENTS,
14
+ subscription: void 0
15
+ };
16
+ initializeFragments.call(this);
17
+ }
18
+ Fragments.prototype.remove = removeFragments;
19
+ /**
20
+ * Create a _Fragments_ instance from a reactive array
21
+ *
22
+ * _A Fragments instance can be used to efficiently render a list of items that may change over time, using unique identifiers to track each item, only adding, removing, or updating each related Fragment._
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const fruits = array(['Apple', 'Banana', 'Cherry']);
27
+ * const items = fragments(
28
+ * fruits,
29
+ * fruit => fruit, // Identifies a unique item
30
+ * fruit => html`<p>${fruit}</p>`, // Creates a Fragment from an item
31
+ * );
32
+ * html`${items}`.appendTo(document.body) // Renders '<p>Apple</p><p>Banana</p><p>Cherry</p>'
33
+ * fruits.push(['Date', 'Elderberry', 'Fig']); // Appends '<p>Date</p><p>Elderberry</p><p>Fig</p>'
34
+ * // without re-rendering the existing Fragments
35
+ * ```
36
+ *
37
+ * @param array Reactive array
38
+ * @param identify Function to identify item uniquely _(non-nullable)_
39
+ * @param fragment Function to create _Fragment_ from item
40
+ * @returns _Fragments_
41
+ */
42
+ function fragments(array, identify, fragment) {
43
+ if (!isReactiveArray(array)) throw new TypeError(MESSAGE_FRAGMENTS_VALUE);
44
+ if (typeof identify !== "function") throw new TypeError(MESSAGE_FRAGMENTS_IDENTIFIER_TYPE);
45
+ if (typeof fragment !== "function") throw new TypeError(MESSAGE_FRAGMENTS_FRAGMENT_TYPE);
46
+ return new Fragments(array, identify, fragment);
47
+ }
48
+ function handleFragments(instance, remove) {
49
+ (remove ? removeFragments : initializeFragments).call(instance);
25
50
  }
26
51
  function handleItems(state, items) {
27
52
  const keys = /* @__PURE__ */ new Set();
@@ -30,13 +55,13 @@ function handleItems(state, items) {
30
55
  for (let index = 0; index < length; index += 1) {
31
56
  const item = items[index];
32
57
  const identifier = state.identify(item);
33
- if (identifier == null) throw new TypeError(ERROR_IDENTIFIER_TYPE);
58
+ if (identifier == null) throw new TypeError(MESSAGE_FRAGMENTS_IDENTIFIER_RESULT_TYPE);
34
59
  const key = getString(identifier);
35
- if (keys.has(key)) throw new Error(ERROR_IDENTIFIER_DUPLICATE.replace("<>", key));
60
+ if (keys.has(key)) throw new Error(MESSAGE_FRAGMENTS_IDENTIFIER_RESULT_DUPLICATE.replace("<>", key));
36
61
  let instance = state.instances[key];
37
62
  if (instance == null) {
38
63
  instance = state.fragment(item);
39
- if (!isFragment(instance)) throw new Error(ERROR_FRAGMENT);
64
+ if (!isFragment(instance)) throw new Error(MESSAGE_FRAGMENTS_FRAGMENT_RESULT);
40
65
  }
41
66
  instance.configure({ identifier: key });
42
67
  state.instances[key] = instance;
@@ -46,15 +71,18 @@ function handleItems(state, items) {
46
71
  state.mapped.set(mapped);
47
72
  updateFragments(state, keys);
48
73
  }
49
- function initializeFragments(state) {
50
- state.subscriber ??= state.array.subscribe((items) => {
74
+ function initializeFragments() {
75
+ const state = this[SYMBOL];
76
+ state.subscription ??= state.array.subscribe((items) => {
51
77
  handleItems(state, items);
52
78
  });
53
79
  }
54
- function removeFragments(state) {
55
- state.subscriber?.();
80
+ function removeFragments() {
81
+ const state = this[SYMBOL];
82
+ state.subscription?.unsubscribe();
83
+ state.mapped.set([]);
56
84
  updateFragments(state);
57
- state.subscriber = void 0;
85
+ state.subscription = void 0;
58
86
  }
59
87
  function updateFragments(state, active) {
60
88
  const next = {};
@@ -64,11 +92,10 @@ function updateFragments(state, active) {
64
92
  for (let index = 0; index < length; index += 1) {
65
93
  const key = keys[index];
66
94
  if (active?.has(key)) next[key] = previous[key];
67
- else previous[key].remove();
95
+ else if (active == null) previous[key].remove();
68
96
  }
69
97
  state.instances = next;
70
98
  active?.clear();
71
99
  }
72
- const fragmentsStates = /* @__PURE__ */ new WeakMap();
73
100
  //#endregion
74
- export { Fragments, fragmentsStates, handleFragments };
101
+ export { fragments, handleFragments };
@@ -1,6 +1,5 @@
1
1
  //#region src/helpers/dom.d.ts
2
- declare function createNodes(value: unknown): ChildNode[];
3
- declare function removeNodes(nodes: ChildNode[]): void;
4
- declare function replaceNodes(from: ChildNode[], to: ChildNode[]): ChildNode[];
5
- //#endregion
6
- export { createNodes, removeNodes, replaceNodes };
2
+ export declare function createNodes(value: unknown): ChildNode[];
3
+ export declare function removeNodes(nodes: ChildNode[]): void;
4
+ export declare function replaceNodes(from: ChildNode[], to: ChildNode[]): ChildNode[];
5
+ //#endregion
@@ -1,24 +1,22 @@
1
- import { Fragment } from "../fragment.mjs";
2
- import { FragmentData } from "../models.mjs";
3
1
  import { ARRAY_COMPARISON_ADDED, ARRAY_COMPARISON_DISSIMILAR, ARRAY_COMPARISON_REMOVED } from "../constants.mjs";
4
- import { Fragments } from "../fragments.mjs";
2
+ import { Fragment, FragmentState, Fragments } from "../models.mjs";
5
3
  import { Computed } from "@oscarpalmer/mora";
6
4
  import { GenericCallback } from "@oscarpalmer/atoms/models";
7
-
8
5
  //#region src/helpers/index.d.ts
9
- declare function compareArrays(first: unknown[], second: unknown[]): typeof ARRAY_COMPARISON_ADDED | typeof ARRAY_COMPARISON_DISSIMILAR | typeof ARRAY_COMPARISON_REMOVED;
6
+ export declare function compareArrays(first: unknown[], second: unknown[]): typeof ARRAY_COMPARISON_ADDED | typeof ARRAY_COMPARISON_DISSIMILAR | typeof ARRAY_COMPARISON_REMOVED;
10
7
  /**
11
8
  * Is the value a _Fragment_?
9
+ *
12
10
  * @param value Value to check
13
11
  * @returns `true` if the value is a _Fragment_, otherwise `false`
14
12
  */
15
- declare function isFragment(value: unknown): value is Fragment;
13
+ export declare function isFragment(value: unknown): value is Fragment;
16
14
  /**
17
15
  * Is the value a _Fragments_ instance?
16
+ *
18
17
  * @param value Value to check
19
18
  * @returns `true` if the value is a _Fragments_ instance, otherwise `false`
20
19
  */
21
- declare function isFragments(value: unknown): value is Fragments;
22
- declare function setComputedValue(data: FragmentData, callback: GenericCallback, after: (computation: Computed<unknown>) => void): void;
23
- //#endregion
24
- export { compareArrays, isFragment, isFragments, setComputedValue };
20
+ export declare function isFragments(value: unknown): value is Fragments;
21
+ export declare function setComputedValue(data: FragmentState, callback: GenericCallback, after: (computation: Computed<unknown>) => void): void;
22
+ //#endregion
@@ -1,4 +1,4 @@
1
- import { ARRAY_COMPARISON_ADDED, ARRAY_COMPARISON_DISSIMILAR, ARRAY_COMPARISON_REMOVED, NAME_FRAGMENT, NAME_FRAGMENTS } from "../constants.mjs";
1
+ import { ARRAY_COMPARISON_ADDED, ARRAY_COMPARISON_DISSIMILAR, ARRAY_COMPARISON_REMOVED, NAME_FRAGMENT, NAME_FRAGMENTS, SYMBOL } from "../constants.mjs";
2
2
  import { computed } from "@oscarpalmer/mora";
3
3
  //#region src/helpers/index.ts
4
4
  function compareArrays(first, second) {
@@ -10,6 +10,7 @@ function compareArrays(first, second) {
10
10
  }
11
11
  /**
12
12
  * Is the value a _Fragment_?
13
+ *
13
14
  * @param value Value to check
14
15
  * @returns `true` if the value is a _Fragment_, otherwise `false`
15
16
  */
@@ -18,6 +19,7 @@ function isFragment(value) {
18
19
  }
19
20
  /**
20
21
  * Is the value a _Fragments_ instance?
22
+ *
21
23
  * @param value Value to check
22
24
  * @returns `true` if the value is a _Fragments_ instance, otherwise `false`
23
25
  */
@@ -25,7 +27,7 @@ function isFragments(value) {
25
27
  return isNamed(value, NAME_FRAGMENTS);
26
28
  }
27
29
  function isNamed(value, name) {
28
- return typeof value === "object" && value != null && name in value && value[name] === true;
30
+ return typeof value === "object" && value !== null && SYMBOL in value && value[SYMBOL].name === name;
29
31
  }
30
32
  function setComputedValue(data, callback, after) {
31
33
  const computation = computed(callback);
package/dist/index.d.mts CHANGED
@@ -1,49 +1,7 @@
1
- import { Fragment } from "./fragment.mjs";
2
- import { Fragments } from "./fragments.mjs";
1
+ import { Fragment, Fragments } from "./models.mjs";
2
+ import { fragment } from "./fragment.mjs";
3
+ import { fragments } from "./fragments.mjs";
3
4
  import { isFragment, isFragments } from "./helpers/index.mjs";
4
- import { ReactiveArray } from "@oscarpalmer/mora";
5
+ import "@oscarpalmer/mora";
5
6
  export * from "@oscarpalmer/mora";
6
-
7
- //#region src/index.d.ts
8
- /**
9
- * Create a _Fragments_ instance from a reactive array
10
- *
11
- * _A Fragments instance can be used to efficiently render a list of items that may change over time, using unique identifiers to track each item, only adding, removing, or updating each related Fragment._
12
- *
13
- * @example
14
- * ```ts
15
- * const fruits = array(['Apple', 'Banana', 'Cherry']);
16
- * const items = fragments(
17
- * fruits,
18
- * fruit => fruit, // Identifies a unique item
19
- * fruit => html`<p>${fruit}</p>`, // Creates a Fragment from an item
20
- * );
21
- * html`${items}`.appendTo(document.body) // Renders '<p>Apple</p><p>Banana</p><p>Cherry</p>'
22
- * fruits.push(['Date', 'Elderberry', 'Fig']); // Appends '<p>Date</p><p>Elderberry</p><p>Fig</p>'
23
- * // without re-rendering the existing Fragments
24
- * ```
25
- *
26
- * @param array Reactive array
27
- * @param identify Function to identify item uniquely _(non-nullable)_
28
- * @param fragment Function to create _Fragment_ from item
29
- * @returns _Fragments_
30
- */
31
- declare function fragments<Item>(array: ReactiveArray<Item>, identify: (item: Item) => unknown, fragment: (item: Item) => Fragment): Fragments;
32
- /**
33
- * Create a _Fragment_ from a template
34
- *
35
- * _A Fragment can be used to efficiently render a template that may change over time, only updating the necessary parts of the DOM._
36
- *
37
- * @example
38
- * ```ts
39
- * const name = signal('World');
40
- * const fragment = html`<p>Hello, ${name}!</p>`;
41
- * fragment.appendTo(document.body); // Renders '<p>Hello, World!</p>'
42
- * name.set('Alice'); // Replaces 'World' with 'Alice'
43
- * ```
44
- *
45
- * @returns _Fragment_
46
- */
47
- declare function html(template: TemplateStringsArray, ...values: unknown[]): Fragment;
48
- //#endregion
49
- export { type Fragment, type Fragments, fragments, html, isFragment, isFragments };
7
+ export { type Fragment, type Fragments, fragment, fragments, fragment as html, isFragment, isFragments };
package/dist/index.mjs CHANGED
@@ -1,55 +1,6 @@
1
1
  import { isFragment, isFragments } from "./helpers/index.mjs";
2
- import { Fragments } from "./fragments.mjs";
3
- import { Fragment } from "./fragment.mjs";
4
- import { isArray } from "@oscarpalmer/mora";
2
+ import { fragments } from "./fragments.mjs";
3
+ import { fragment } from "./fragment.mjs";
4
+ import "@oscarpalmer/mora";
5
5
  export * from "@oscarpalmer/mora";
6
- //#region src/index.ts
7
- /**
8
- * Create a _Fragments_ instance from a reactive array
9
- *
10
- * _A Fragments instance can be used to efficiently render a list of items that may change over time, using unique identifiers to track each item, only adding, removing, or updating each related Fragment._
11
- *
12
- * @example
13
- * ```ts
14
- * const fruits = array(['Apple', 'Banana', 'Cherry']);
15
- * const items = fragments(
16
- * fruits,
17
- * fruit => fruit, // Identifies a unique item
18
- * fruit => html`<p>${fruit}</p>`, // Creates a Fragment from an item
19
- * );
20
- * html`${items}`.appendTo(document.body) // Renders '<p>Apple</p><p>Banana</p><p>Cherry</p>'
21
- * fruits.push(['Date', 'Elderberry', 'Fig']); // Appends '<p>Date</p><p>Elderberry</p><p>Fig</p>'
22
- * // without re-rendering the existing Fragments
23
- * ```
24
- *
25
- * @param array Reactive array
26
- * @param identify Function to identify item uniquely _(non-nullable)_
27
- * @param fragment Function to create _Fragment_ from item
28
- * @returns _Fragments_
29
- */
30
- function fragments(array, identify, fragment) {
31
- if (!isArray(array)) throw new TypeError("Fragments array must be a reactive array");
32
- if (typeof identify !== "function") throw new TypeError("Fragments identify must be a function");
33
- if (typeof fragment !== "function") throw new TypeError("Fragments fragment must be a function");
34
- return new Fragments(array, identify, fragment);
35
- }
36
- /**
37
- * Create a _Fragment_ from a template
38
- *
39
- * _A Fragment can be used to efficiently render a template that may change over time, only updating the necessary parts of the DOM._
40
- *
41
- * @example
42
- * ```ts
43
- * const name = signal('World');
44
- * const fragment = html`<p>Hello, ${name}!</p>`;
45
- * fragment.appendTo(document.body); // Renders '<p>Hello, World!</p>'
46
- * name.set('Alice'); // Replaces 'World' with 'Alice'
47
- * ```
48
- *
49
- * @returns _Fragment_
50
- */
51
- function html(template, ...values) {
52
- return new Fragment(template, values);
53
- }
54
- //#endregion
55
- export { fragments, html, isFragment, isFragments };
6
+ export { fragment, fragments, fragment as html, isFragment, isFragments };
package/dist/models.d.mts CHANGED
@@ -1,11 +1,72 @@
1
- import { Fragment } from "./fragment.mjs";
2
- import { Reactive, ReactiveArray, Unsubscribe } from "@oscarpalmer/mora";
3
-
1
+ import { SYMBOL } from "./constants.mjs";
2
+ import { Reactive, ReactiveArray, Subscription } from "@oscarpalmer/mora";
4
3
  //#region src/models.d.ts
4
+ export type InternalFragment = {
5
+ [SYMBOL]: FragmentState;
6
+ } & Fragment;
7
+ export type InternalFragments = {
8
+ [SYMBOL]: FragmentsState;
9
+ } & Fragments;
10
+ export type Fragment = {
11
+ /**
12
+ * Is template caching enabled?
13
+ */
14
+ get cache(): boolean;
15
+ /**
16
+ * Identifier for the _Fragment_
17
+ *
18
+ * _An identifier can be used to uniquely identify a Fragment, which helps prevent re-rendering in reactive arrays and Fragments_
19
+ */
20
+ get identifier(): unknown;
21
+ /**
22
+ * Insert the _Fragment_ after the given element
23
+ *
24
+ * @param element Element to insert after
25
+ */
26
+ after(element: Element): void;
27
+ /**
28
+ * Append the _Fragment_ to the given element
29
+ *
30
+ * @param element Element to append to
31
+ */
32
+ appendTo(element: Element): void;
33
+ /**
34
+ * Insert the _Fragment_ before the given element
35
+ *
36
+ * @param element Element to insert before
37
+ */
38
+ before(element: Element): void;
39
+ /**
40
+ * Configure the _Fragment_
41
+ *
42
+ * @param configuration Configuration options
43
+ * @returns _Fragment_
44
+ */
45
+ configure(configuration: FragmentConfiguration): Fragment;
46
+ /**
47
+ * Get a list of the _Fragment_'s nodes
48
+ *
49
+ * @returns List of nodes
50
+ */
51
+ get(): ChildNode[];
52
+ /**
53
+ * Prepend the _Fragment_ to the given element
54
+ *
55
+ * @param element Element to prepend to
56
+ */
57
+ prependTo(element: Element): void;
58
+ /**
59
+ * Remove the _Fragment_ _(and all its descendants)_ from the _DOM_
60
+ *
61
+ * - _Any events, reactive values, and Fragments will also be cleaned up and removed_
62
+ * - _After being removed, the Fragment can be re-inserted into the DOM_
63
+ */
64
+ remove(): void;
65
+ };
5
66
  /**
6
67
  * Configuration for a _Fragment_
7
68
  */
8
- type FragmentConfiguration = {
69
+ export type FragmentConfiguration = {
9
70
  /**
10
71
  * Should the template be cached? _(defaults to `true`)_
11
72
  */
@@ -17,30 +78,39 @@ type FragmentConfiguration = {
17
78
  */
18
79
  identifier?: unknown;
19
80
  };
20
- type FragmentData = {
81
+ export type FragmentItem = {
82
+ fragments?: Fragment[];
83
+ nodes?: ChildNode[];
84
+ text?: Text;
85
+ };
86
+ export type FragmentState = {
87
+ cache: boolean;
21
88
  expressions: unknown[];
89
+ identifier: unknown;
22
90
  items: FragmentItem[];
23
91
  mora: MoraData;
92
+ name: string;
24
93
  strings: TemplateStringsArray | string[];
25
94
  template?: string;
26
95
  values: unknown[];
27
96
  };
28
- type FragmentItem = {
29
- fragments?: Fragment[];
30
- nodes?: ChildNode[];
31
- text?: Text;
97
+ export type Fragments = {
98
+ /**
99
+ * Remove the _Fragments_ _(and all its descendants)_ from the _DOM_, including any events, reactive values, and Fragments
100
+ */
101
+ remove(): void;
32
102
  };
33
- type FragmentsState = {
103
+ export type FragmentsState = {
34
104
  array: ReactiveArray<unknown>;
35
105
  fragment: (item: unknown) => Fragment;
36
106
  identify: (item: unknown) => unknown;
37
107
  instances: Record<string, Fragment>;
38
108
  mapped: ReactiveArray<Fragment>;
39
- subscriber: Unsubscribe | undefined;
109
+ name: string;
110
+ subscription: Subscription | undefined;
40
111
  };
41
112
  type MoraData = {
42
- subscribers: Set<() => void>;
113
+ subscriptions: Set<Subscription>;
43
114
  values: Set<Reactive<unknown>>;
44
115
  };
45
- //#endregion
46
- export { FragmentConfiguration, FragmentData, FragmentItem, FragmentsState };
116
+ //#endregion
@@ -1,4 +1,3 @@
1
1
  //#region src/node/event.d.ts
2
- declare function mapEvent(element: HTMLElement | SVGElement, name: string, value: unknown): void;
3
- //#endregion
4
- export { mapEvent };
2
+ export declare function mapEvent(element: HTMLElement | SVGElement, name: string, value: unknown): void;
3
+ //#endregion
@@ -1,6 +1,4 @@
1
- import { FragmentData } from "../models.mjs";
2
-
1
+ import { FragmentState } from "../models.mjs";
3
2
  //#region src/node/index.d.ts
4
- declare function mapNodes(data: FragmentData, nodes: ChildNode[]): void;
5
- //#endregion
6
- export { mapNodes };
3
+ export declare function mapNodes(data: FragmentState, nodes: ChildNode[]): void;
4
+ //#endregion
@@ -1,6 +1,6 @@
1
- import { EXPRESSION_ABYDON_CONTENT, EXPRESSION_TEXTAREA_VALUE } from "../constants.mjs";
1
+ import { EXPRESSION_ABYDON_CONTENT, EXPRESSION_TEXTAREA_VALUE, SYMBOL } from "../constants.mjs";
2
2
  import { isFragment, isFragments, setComputedValue } from "../helpers/index.mjs";
3
- import { fragmentsStates, handleFragments } from "../fragments.mjs";
3
+ import { handleFragments } from "../fragments.mjs";
4
4
  import { createNodes } from "../helpers/dom.mjs";
5
5
  import { mapAttributeValue, mapAttributes } from "../attribute/index.mjs";
6
6
  import { setReactiveValue } from "./value.mjs";
@@ -47,9 +47,7 @@ function mapValue(data, comment, value) {
47
47
  case isReactive(value):
48
48
  setReactiveValue(data, comment, value);
49
49
  break;
50
- default:
51
- replaceComment(data, comment, value);
52
- break;
50
+ default: replaceComment(data, comment, value);
53
51
  }
54
52
  }
55
53
  function replaceComment(data, comment, value) {
@@ -67,9 +65,8 @@ function setComputedNode(data, comment, callback) {
67
65
  });
68
66
  }
69
67
  function setFragmentsNode(data, comment, fragments) {
70
- const state = fragmentsStates.get(fragments);
71
- handleFragments(state, false);
72
- setReactiveValue(data, comment, state.mapped);
68
+ handleFragments(fragments, false);
69
+ setReactiveValue(data, comment, fragments[SYMBOL].mapped);
73
70
  }
74
71
  //#endregion
75
72
  export { mapNodes };
@@ -1,7 +1,5 @@
1
- import { FragmentData } from "../models.mjs";
1
+ import { FragmentState } from "../models.mjs";
2
2
  import { Reactive } from "@oscarpalmer/mora";
3
-
4
3
  //#region src/node/value.d.ts
5
- declare function setReactiveValue(data: FragmentData, comment: Comment, reactive: Reactive<unknown>): void;
6
- //#endregion
7
- export { setReactiveValue };
4
+ export declare function setReactiveValue(data: FragmentState, comment: Comment, reactive: Reactive<unknown>): void;
5
+ //#endregion
@@ -15,8 +15,10 @@ function addToArray(identifiers, items, nodes, added) {
15
15
  const { length } = next;
16
16
  for (let index = 0; index < length; index += 1) {
17
17
  const node = next[index];
18
- if (!(added && identifiers.previous.set.has(node.identifier))) if (index === 0 && before) position.before(node.value);
19
- else position.after(node.value);
18
+ if (!(added && identifiers.previous.set.has(node.identifier))) {
19
+ if (index === 0 && before) position.before(node.value);
20
+ else position.after(node.value);
21
+ }
20
22
  position = node.value;
21
23
  }
22
24
  }
@@ -77,7 +79,7 @@ function removeFragmentsItems(fragments) {
77
79
  function setArray(item, comment, value) {
78
80
  if (value.length === 0) return removeArray(item, comment);
79
81
  const { next, previous, template } = getArrayData(item, value);
80
- if (template.empty || item.nodes == null || previous.array.some((identifier) => identifier == null)) {
82
+ if (template.empty || item.nodes == null || item.fragments == null || previous.array.some((identifier) => identifier == null)) {
81
83
  const fragments = (item.fragments ?? []).slice();
82
84
  const result = {
83
85
  fragments: template.empty ? void 0 : template.items,
@@ -90,7 +92,7 @@ function setArray(item, comment, value) {
90
92
  next,
91
93
  previous
92
94
  }, {
93
- fragments: item.fragments ?? [],
95
+ fragments: item.fragments,
94
96
  templates: template.items
95
97
  }, item.nodes);
96
98
  }
@@ -100,7 +102,7 @@ function setNodes(item, comment, next) {
100
102
  function setReactiveValue(data, comment, reactive) {
101
103
  let item = data.items.find((item) => item.nodes?.includes(comment));
102
104
  item ??= {};
103
- data.mora.subscribers.add(reactive.subscribe((value) => {
105
+ data.mora.subscriptions.add(reactive.subscribe((value) => {
104
106
  if (Array.isArray(value)) setReactiveValueForArray(item, comment, value);
105
107
  else setReactiveValueForSingle(item, comment, value);
106
108
  }));
@@ -123,8 +125,7 @@ function setText(item, comment, value) {
123
125
  item.text ??= new Text();
124
126
  item.text.textContent = valueIsNullable ? "" : getString(value);
125
127
  const result = valueIsNullable ? [comment] : [item.text];
126
- replaceNodes(item.nodes ?? [comment], result);
127
- return result;
128
+ return replaceNodes(item.nodes ?? [comment], result);
128
129
  }
129
130
  //#endregion
130
131
  export { setReactiveValue };
package/dist/parse.d.mts CHANGED
@@ -1,6 +1,4 @@
1
- import { FragmentData } from "./models.mjs";
2
-
1
+ import { FragmentState } from "./models.mjs";
3
2
  //#region src/parse.d.ts
4
- declare function parse(data: FragmentData): string;
5
- //#endregion
6
- export { parse };
3
+ export declare function parse(data: FragmentState): string;
4
+ //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/abydon",
3
- "version": "0.23.1",
3
+ "version": "0.24.0",
4
4
  "keywords": [
5
5
  "components",
6
6
  "dom",
@@ -35,25 +35,25 @@
35
35
  }
36
36
  },
37
37
  "scripts": {
38
- "build": "npm run tsdown:build && npx vp pack",
39
- "tsdown:build": "npx tsdown -c ./tsdown.config.ts",
40
- "tsdown:watch": "npx tsdown -c ./tsdown.config.ts --watch",
38
+ "build": "npm run tsdown && npx vp pack",
41
39
  "test": "npx vp test run --coverage",
42
- "test:leak": "npx vp test run --detect-async-leaks --coverage"
40
+ "test:leak": "npx vp test run --detect-async-leaks --coverage",
41
+ "tsdown": "npx tsdown -c ./tsdown.config.ts",
42
+ "watch": "npx tsdown -c ./tsdown.config.ts --watch"
43
43
  },
44
44
  "dependencies": {
45
- "@oscarpalmer/atoms": "^0.185",
46
- "@oscarpalmer/mora": "^0.29",
47
- "@oscarpalmer/toretto": "^0.45"
45
+ "@oscarpalmer/atoms": "^0.204",
46
+ "@oscarpalmer/mora": "^0.37",
47
+ "@oscarpalmer/toretto": "^0.54"
48
48
  },
49
49
  "devDependencies": {
50
- "@oscarpalmer/oui": "^0.20",
51
- "@oxlint/plugins": "^1.62",
52
- "@types/node": "^25.6",
50
+ "@oscarpalmer/oui": "^0.38",
51
+ "@oxlint/plugins": "^1.83",
52
+ "@types/node": "^26.5",
53
53
  "@vitest/coverage-istanbul": "^4.1",
54
- "jsdom": "^29.1",
55
- "tsdown": "^0.21",
56
- "typescript": "^5.9",
54
+ "jsdom": "^30.1",
55
+ "tsdown": "^0.23",
56
+ "typescript": "^6",
57
57
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
58
58
  "vite-plus": "latest",
59
59
  "vitest": "npm:@voidzero-dev/vite-plus-test@latest"