@oscarpalmer/abydon 0.22.0 → 0.23.1

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/src/node/value.ts CHANGED
@@ -10,9 +10,30 @@ import type {FragmentData, FragmentItem} from '../models';
10
10
 
11
11
  //
12
12
 
13
+ type ArrayData = {
14
+ next: ArrayDataIdentifiers;
15
+ previous: ArrayDataIdentifiers;
16
+ template: ArrayDataTemplate;
17
+ };
18
+
19
+ type ArrayDataIdentifiers = {
20
+ array: unknown[];
21
+ set: Set<unknown>;
22
+ };
23
+
24
+ type ArrayDataTemplate = {
25
+ empty: boolean;
26
+ items: Fragment[];
27
+ };
28
+
13
29
  type Identifiers = {
14
- next: Set<unknown>;
15
- previous: Set<unknown>;
30
+ next: IdentifiersValues;
31
+ previous: IdentifiersValues;
32
+ };
33
+
34
+ type IdentifiersValues = {
35
+ array: unknown[];
36
+ set: Set<unknown>;
16
37
  };
17
38
 
18
39
  type BaseItems = {
@@ -34,7 +55,7 @@ function addToArray(
34
55
  ): void {
35
56
  let position = nodes[0];
36
57
 
37
- const before = added && !identifiers.previous.has(items.templates[0].identifier);
58
+ const before = added && !identifiers.previous.set.has(items.templates[0].identifier);
38
59
 
39
60
  const next = items.next.flatMap(fragment =>
40
61
  fragment.get().flatMap(node => ({
@@ -48,7 +69,7 @@ function addToArray(
48
69
  for (let index = 0; index < length; index += 1) {
49
70
  const node = next[index];
50
71
 
51
- if (!(added && identifiers.previous.has(node.identifier))) {
72
+ if (!(added && identifiers.previous.set.has(node.identifier))) {
52
73
  if (index === 0 && before) {
53
74
  position.before(node.value);
54
75
  } else {
@@ -60,6 +81,46 @@ function addToArray(
60
81
  }
61
82
  }
62
83
 
84
+ function getArrayData(item: FragmentItem, values: unknown[]): ArrayData {
85
+ const {length} = values;
86
+
87
+ const next: unknown[] = [];
88
+
89
+ let templates: Fragment[] = [];
90
+
91
+ for (let index = 0; index < length; index += 1) {
92
+ const value = values[index];
93
+
94
+ if (isFragment(value) && value.identifier != null) {
95
+ next.push(value.identifier);
96
+ templates.push(value);
97
+ }
98
+ }
99
+
100
+ const previous = item.fragments?.map(fragment => fragment.identifier) ?? [];
101
+
102
+ const nextSet = new Set(next);
103
+
104
+ if (nextSet.size !== templates.length) {
105
+ templates = [];
106
+ }
107
+
108
+ return {
109
+ next: {
110
+ array: next,
111
+ set: nextSet,
112
+ },
113
+ previous: {
114
+ array: previous,
115
+ set: new Set(previous),
116
+ },
117
+ template: {
118
+ empty: templates.length === 0,
119
+ items: templates,
120
+ },
121
+ };
122
+ }
123
+
63
124
  function handleArray(
64
125
  identifiers: Identifiers,
65
126
  items: BaseItems,
@@ -67,17 +128,18 @@ function handleArray(
67
128
  ): Partial<FragmentItem> {
68
129
  const next = items.templates.map(
69
130
  template =>
70
- items.fragments?.find(fragment => fragment.identifier === template.identifier) ?? template,
131
+ items.fragments.find(fragment => fragment.identifier === template.identifier) ?? template,
71
132
  );
72
133
 
73
- const comparison = compareArrays(items.fragments ?? [], items.templates);
134
+ const comparison = compareArrays(identifiers.previous.array, identifiers.next.array);
74
135
 
75
136
  if (comparison !== ARRAY_COMPARISON_REMOVED) {
76
137
  addToArray(identifiers, {...items, next}, nodes, comparison === ARRAY_COMPARISON_ADDED);
77
138
  }
78
139
 
79
- const toRemove =
80
- items.fragments?.filter(fragment => !identifiers.next.has(fragment.identifier)) ?? [];
140
+ const toRemove = items.fragments.filter(
141
+ fragment => !identifiers.next.set.has(fragment.identifier),
142
+ );
81
143
 
82
144
  const {length} = toRemove;
83
145
 
@@ -91,84 +153,70 @@ function handleArray(
91
153
  };
92
154
  }
93
155
 
94
- function removeFragments(fragments: Fragment[] | undefined): void {
95
- if (fragments != null) {
96
- const {length} = fragments;
156
+ function removeArray(item: FragmentItem, comment: Comment): Partial<FragmentItem> {
157
+ const fragments = (item.fragments ?? []).slice();
97
158
 
98
- for (let index = 0; index < length; index += 1) {
99
- fragments[index].remove();
100
- }
101
- }
159
+ const result = {
160
+ nodes: setText(item, comment),
161
+ };
162
+
163
+ removeFragmentsItems(fragments);
164
+
165
+ return result;
102
166
  }
103
167
 
104
- function replaceText(item: FragmentItem, comment: Comment, isNullable: boolean): void {
105
- let to: ChildNode[];
168
+ function removeFragmentsItems(fragments: Fragment[]): void {
169
+ const {length} = fragments;
106
170
 
107
- if (isNullable) {
108
- to = [comment];
109
- } else {
110
- to = item.text == null ? [] : [item.text];
171
+ for (let index = 0; index < length; index += 1) {
172
+ fragments[index].remove();
111
173
  }
112
-
113
- replaceNodes(item.nodes ?? [], to);
114
174
  }
115
175
 
116
176
  function setArray(item: FragmentItem, comment: Comment, value: unknown[]): Partial<FragmentItem> {
117
177
  if (value.length === 0) {
118
- return {
119
- nodes: setText(item, comment, value),
120
- };
178
+ return removeArray(item, comment);
121
179
  }
122
180
 
123
- let templates = value.filter(item => isFragment(item) && item.identifier != null) as Fragment[];
181
+ const {next, previous, template} = getArrayData(item, value);
124
182
 
125
- const next = templates.map(fragment => fragment.identifier) as unknown[];
126
- const previous = item.fragments?.map(fragment => fragment.identifier) ?? [];
183
+ if (
184
+ template.empty ||
185
+ item.nodes == null ||
186
+ previous.array.some(identifier => identifier == null)
187
+ ) {
188
+ const fragments = (item.fragments ?? []).slice();
127
189
 
128
- const nextSet = new Set(next);
129
-
130
- if (nextSet.size !== templates.length) {
131
- templates = [];
132
- }
133
-
134
- const noTemplates = templates.length === 0;
135
-
136
- if (noTemplates || item.nodes == null || previous.some(identifier => identifier == null)) {
137
- return {
138
- fragments: noTemplates ? undefined : templates,
139
- nodes: setNodes(
140
- item,
141
- comment,
142
- noTemplates
190
+ const result = {
191
+ fragments: template.empty ? undefined : template.items,
192
+ nodes: replaceNodes(
193
+ item.nodes ?? [comment],
194
+ template.empty
143
195
  ? value.flatMap(item => createNodes(item))
144
- : templates.flatMap(template => template.get()),
196
+ : template.items.flatMap(template => template.get()),
145
197
  ),
146
198
  };
199
+
200
+ removeFragmentsItems(fragments);
201
+
202
+ return result;
147
203
  }
148
204
 
149
205
  return handleArray(
150
206
  {
151
- next: nextSet,
152
- previous: new Set(previous),
207
+ next,
208
+ previous,
153
209
  },
154
210
  {
155
- templates,
156
211
  fragments: item.fragments ?? [],
212
+ templates: template.items,
157
213
  },
158
214
  item.nodes,
159
215
  );
160
216
  }
161
217
 
162
218
  function setNodes(item: FragmentItem, comment: Comment, next: ChildNode[]): ChildNode[] {
163
- if (item.nodes == null) {
164
- replaceNodes([comment], next);
165
- } else {
166
- replaceNodes(item.nodes, next);
167
- }
168
-
169
- removeFragments(item.fragments);
170
-
171
- return next;
219
+ return replaceNodes(item.nodes ?? [comment], next);
172
220
  }
173
221
 
174
222
  export function setReactiveValue(
@@ -180,8 +228,6 @@ export function setReactiveValue(
180
228
 
181
229
  item ??= {};
182
230
 
183
- item.text = new Text();
184
-
185
231
  data.mora.subscribers.add(
186
232
  reactive.subscribe(value => {
187
233
  if (Array.isArray(value)) {
@@ -189,8 +235,6 @@ export function setReactiveValue(
189
235
  } else {
190
236
  setReactiveValueForSingle(item, comment, value);
191
237
  }
192
-
193
- item.nodes ??= [comment];
194
238
  }),
195
239
  );
196
240
  }
@@ -203,43 +247,31 @@ function setReactiveValueForArray(item: FragmentItem, comment: Comment, value: u
203
247
  }
204
248
 
205
249
  function setReactiveValueForSingle(item: FragmentItem, comment: Comment, value: unknown): void {
206
- const valueIsFragment = isFragment(value);
250
+ const fragments = (item.fragments ?? []).slice();
207
251
 
208
- item.fragments = valueIsFragment ? [value] : undefined;
252
+ const valueIsFragment = isFragment(value);
209
253
 
210
254
  if (valueIsFragment || isChildNode(value)) {
211
255
  item.nodes = setNodes(item, comment, createNodes(value));
212
256
  } else {
213
257
  item.nodes = setText(item, comment, value);
214
258
  }
215
- }
216
259
 
217
- function setText(item: FragmentItem, comment: Comment, value: unknown): ChildNode[] | undefined {
218
- const isNullable = isNullableOrWhitespace(value);
260
+ item.fragments = valueIsFragment ? [value] : undefined;
219
261
 
220
- if (item.text != null) {
221
- item.text.textContent = isNullable ? '' : getString(value);
222
- }
262
+ removeFragmentsItems(fragments);
263
+ }
223
264
 
224
- let result = false;
265
+ function setText(item: FragmentItem, comment: Comment, value?: unknown): ChildNode[] {
266
+ const valueIsNullable = isNullableOrWhitespace(value);
225
267
 
226
- if (item.nodes != null) {
227
- replaceText(item, comment, isNullable);
268
+ item.text ??= new Text();
228
269
 
229
- result = !isNullable;
230
- } else if (isNullable && comment.parentNode == null) {
231
- item.text?.replaceWith(comment);
232
- } else if (!isNullable && item?.text?.parentNode == null) {
233
- if (item.text != null) {
234
- comment.replaceWith(item.text);
235
- }
270
+ item.text.textContent = valueIsNullable ? '' : getString(value);
236
271
 
237
- result = true;
238
- }
272
+ const result = valueIsNullable ? [comment] : [item.text];
239
273
 
240
- removeFragments(item.fragments);
274
+ replaceNodes(item.nodes ?? [comment], result);
241
275
 
242
- if (result) {
243
- return item.text == null ? [] : [item.text];
244
- }
276
+ return result;
245
277
  }
package/src/parse.ts CHANGED
@@ -48,7 +48,7 @@ export function parse(data: FragmentData): string {
48
48
  data.template = data.template.replaceAll(EXPRESSION_ABYDON_ATTRIBUTE_FULL, transformAttribute);
49
49
 
50
50
  data.expressions = [];
51
- data.strings = [] as never;
51
+ data.strings = [];
52
52
 
53
53
  return data.template;
54
54
  }