@oscarpalmer/abydon 0.11.0 → 0.13.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.
Files changed (57) hide show
  1. package/dist/abydon.full.js +1247 -0
  2. package/dist/fragment.js +60 -0
  3. package/dist/helpers/dom.js +28 -0
  4. package/dist/helpers/index.js +11 -0
  5. package/dist/index.js +6 -885
  6. package/dist/node/attribute/index.js +34 -0
  7. package/dist/node/attribute/value.js +58 -0
  8. package/dist/node/event.js +32 -0
  9. package/dist/node/index.js +52 -0
  10. package/dist/node/value.js +93 -0
  11. package/dist/parse.js +21 -0
  12. package/package.json +41 -28
  13. package/src/fragment.ts +36 -15
  14. package/src/helpers/dom.ts +10 -10
  15. package/src/helpers/index.ts +0 -9
  16. package/src/index.ts +11 -1
  17. package/src/models.ts +7 -4
  18. package/src/node/attribute/index.ts +26 -7
  19. package/src/node/attribute/value.ts +31 -20
  20. package/src/node/event.ts +9 -9
  21. package/src/node/index.ts +22 -9
  22. package/src/node/value.ts +38 -37
  23. package/src/{html.ts → parse.ts} +5 -14
  24. package/types/fragment.d.cts +27 -0
  25. package/types/fragment.d.ts +1 -2
  26. package/types/helpers/dom.d.cts +7 -0
  27. package/types/helpers/dom.d.ts +3 -4
  28. package/types/helpers/index.d.cts +29 -0
  29. package/types/helpers/index.d.ts +0 -3
  30. package/types/index.d.cts +279 -4
  31. package/types/index.d.ts +4 -1
  32. package/types/models.d.cts +107 -0
  33. package/types/models.d.ts +8 -3
  34. package/types/node/attribute/index.d.cts +109 -0
  35. package/types/node/attribute/index.d.ts +3 -2
  36. package/types/node/attribute/value.d.cts +109 -0
  37. package/types/node/attribute/value.d.ts +3 -2
  38. package/types/node/event.d.cts +7 -0
  39. package/types/node/event.d.ts +3 -3
  40. package/types/node/index.d.cts +108 -0
  41. package/types/node/index.d.ts +2 -2
  42. package/types/node/value.d.cts +108 -0
  43. package/types/node/value.d.ts +2 -2
  44. package/types/parse.d.cts +108 -0
  45. package/types/parse.d.ts +2 -0
  46. package/dist/fragment.mjs +0 -58
  47. package/dist/helpers/dom.mjs +0 -44
  48. package/dist/helpers/index.mjs +0 -25
  49. package/dist/html.mjs +0 -36
  50. package/dist/index.mjs +0 -5
  51. package/dist/node/attribute/index.mjs +0 -35
  52. package/dist/node/attribute/value.mjs +0 -89
  53. package/dist/node/event.mjs +0 -39
  54. package/dist/node/index.mjs +0 -55
  55. package/dist/node/value.mjs +0 -123
  56. package/types/html.d.ts +0 -4
  57. /package/dist/{models.mjs → models.js} +0 -0
@@ -1,18 +1,20 @@
1
1
  import type {PlainObject} from '@oscarpalmer/atoms/models';
2
2
  import {getString} from '@oscarpalmer/atoms/string';
3
- import {effect, isReactive} from '@oscarpalmer/sentinel';
3
+ import {isReactive} from '@oscarpalmer/mora';
4
4
  import {
5
5
  isBooleanAttribute,
6
6
  setAttribute as setAttr,
7
7
  } from '@oscarpalmer/toretto/attribute';
8
- import type {ProperElement} from '../../models';
8
+ import type {HTMLOrSVGElement} from '@oscarpalmer/toretto/models';
9
+ import type {FragmentData} from '../../models';
9
10
 
10
11
  const classExpression = /^class\./;
11
12
  const styleFullExpression = /^style\.([\w-]+)(?:\.([\w-]+))?$/;
12
13
  const stylePrefixExpression = /^style\./;
13
14
 
14
15
  export function setAttribute(
15
- element: ProperElement,
16
+ data: FragmentData,
17
+ element: HTMLOrSVGElement,
16
18
  name: string,
17
19
  value: unknown,
18
20
  ): void {
@@ -20,21 +22,22 @@ export function setAttribute(
20
22
 
21
23
  switch (true) {
22
24
  case classExpression.test(name):
23
- setClasses(element, name, value);
25
+ setClasses(data, element, name, value);
24
26
  return;
25
27
 
26
28
  case stylePrefixExpression.test(name):
27
- setStyle(element, name, value);
29
+ setStyle(data, element, name, value);
28
30
  return;
29
31
 
30
32
  default:
31
- setValue(element, name, value);
33
+ setValue(data, element, name, value);
32
34
  break;
33
35
  }
34
36
  }
35
37
 
36
38
  function setClasses(
37
- element: ProperElement,
39
+ data: FragmentData,
40
+ element: HTMLOrSVGElement,
38
41
  name: string,
39
42
  value: unknown,
40
43
  ): void {
@@ -49,15 +52,18 @@ function setClasses(
49
52
  const classes = name.slice(6).split('.');
50
53
 
51
54
  if (isReactive(value)) {
52
- effect(() => {
53
- update(value.get());
54
- });
55
+ data.mora.subscribers.add(value.subscribe(update));
55
56
  } else {
56
57
  update(value);
57
58
  }
58
59
  }
59
60
 
60
- function setStyle(element: ProperElement, name: string, value: unknown): void {
61
+ function setStyle(
62
+ data: FragmentData,
63
+ element: HTMLOrSVGElement,
64
+ name: string,
65
+ value: unknown,
66
+ ): void {
61
67
  function update(value: unknown): void {
62
68
  if (value == null || value === false || (value === true && unit == null)) {
63
69
  element.style.removeProperty(property);
@@ -73,16 +79,19 @@ function setStyle(element: ProperElement, name: string, value: unknown): void {
73
79
 
74
80
  if (property != null) {
75
81
  if (isReactive(value)) {
76
- effect(() => {
77
- update(value.get());
78
- });
82
+ data.mora.subscribers.add(value.subscribe(update));
79
83
  } else {
80
84
  update(value);
81
85
  }
82
86
  }
83
87
  }
84
88
 
85
- function setValue(element: ProperElement, name: string, value: unknown): void {
89
+ function setValue(
90
+ data: FragmentData,
91
+ element: HTMLOrSVGElement,
92
+ name: string,
93
+ value: unknown,
94
+ ): void {
86
95
  const callback =
87
96
  isBooleanAttribute(name) && name in element
88
97
  ? name === 'selected'
@@ -91,9 +100,11 @@ function setValue(element: ProperElement, name: string, value: unknown): void {
91
100
  : setAttr;
92
101
 
93
102
  if (isReactive(value)) {
94
- effect(() => {
95
- callback(element, name, value.get());
96
- });
103
+ data.mora.subscribers.add(
104
+ value.subscribe(next => {
105
+ callback(element, name, next);
106
+ }),
107
+ );
97
108
  } else {
98
109
  callback(element, name, value);
99
110
  }
@@ -106,7 +117,7 @@ function triggerSelectChange(select: HTMLSelectElement): void {
106
117
  }
107
118
 
108
119
  function updateProperty(
109
- element: ProperElement,
120
+ element: HTMLOrSVGElement,
110
121
  name: string,
111
122
  value: unknown,
112
123
  ): void {
@@ -114,7 +125,7 @@ function updateProperty(
114
125
  }
115
126
 
116
127
  function updateSelected(
117
- element: ProperElement,
128
+ element: HTMLOrSVGElement,
118
129
  name: string,
119
130
  value: unknown,
120
131
  ): void {
package/src/node/event.ts CHANGED
@@ -1,10 +1,12 @@
1
- import type {ProperElement} from '../models';
1
+ import type {HTMLOrSVGElement} from '@oscarpalmer/toretto/models';
2
2
 
3
- const controllers = new WeakMap<ProperElement, AbortController>();
3
+ const controllers = new WeakMap<HTMLOrSVGElement, AbortController>();
4
4
 
5
5
  const eventNamePattern = /^@([\w-]+)(?::([a-z:]+))?$/i;
6
6
 
7
- function getController(element: ProperElement): AbortController {
7
+ const reason = 'Event removed as element was removed from document by Abydon';
8
+
9
+ function getController(element: HTMLOrSVGElement): AbortController {
8
10
  let controller = controllers.get(element);
9
11
 
10
12
  if (controller == null) {
@@ -27,7 +29,7 @@ function getOptions(options: string): AddEventListenerOptions {
27
29
  }
28
30
 
29
31
  export function mapEvent(
30
- element: ProperElement,
32
+ element: HTMLOrSVGElement,
31
33
  name: string,
32
34
  value: unknown,
33
35
  ): void {
@@ -43,9 +45,7 @@ export function mapEvent(
43
45
  }
44
46
  }
45
47
 
46
- export function removeEvents(element: ProperElement): void {
47
- if (controllers.has(element)) {
48
- controllers.get(element)?.abort();
49
- controllers.delete(element);
50
- }
48
+ export function removeEvents(element: HTMLOrSVGElement): void {
49
+ controllers.get(element)?.abort(reason);
50
+ controllers.delete(element);
51
51
  }
package/src/node/index.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import type {GenericCallback} from '@oscarpalmer/atoms/models';
2
- import {computed, isReactive} from '@oscarpalmer/sentinel';
3
- import {isFragment, isProperElement} from '../helpers';
2
+ import {computed, isReactive} from '@oscarpalmer/mora';
3
+ import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
4
+ import {isFragment} from '../helpers';
4
5
  import {createNodes} from '../helpers/dom';
5
- import type {FragmentData, ProperNode} from '../models';
6
+ import type {FragmentData} from '../models';
6
7
  import {mapAttributes} from './attribute';
7
- import {setReactiveNode} from './value';
8
+ import {setReactiveValue} from './value';
8
9
 
9
10
  const commentExpression = /^abydon\.(\d+)$/;
10
11
 
@@ -17,7 +18,7 @@ function mapNode(data: FragmentData, comment: Comment): void {
17
18
  }
18
19
  }
19
20
 
20
- export function mapNodes(data: FragmentData, nodes: ProperNode[]): void {
21
+ export function mapNodes(data: FragmentData, nodes: ChildNode[]): void {
21
22
  const {length} = nodes;
22
23
 
23
24
  for (let index = 0; index < length; index += 1) {
@@ -29,12 +30,12 @@ export function mapNodes(data: FragmentData, nodes: ProperNode[]): void {
29
30
  continue;
30
31
  }
31
32
 
32
- if (isProperElement(node)) {
33
+ if (isHTMLOrSVGElement(node)) {
33
34
  mapAttributes(data, node);
34
35
  }
35
36
 
36
37
  if (node.hasChildNodes()) {
37
- mapNodes(data, [...node.childNodes] as ProperNode[]);
38
+ mapNodes(data, [...node.childNodes] as ChildNode[]);
38
39
  }
39
40
  }
40
41
  }
@@ -42,11 +43,11 @@ export function mapNodes(data: FragmentData, nodes: ProperNode[]): void {
42
43
  function mapValue(data: FragmentData, comment: Comment, value: unknown): void {
43
44
  switch (true) {
44
45
  case typeof value === 'function':
45
- setReactiveNode(data, comment, computed(value as GenericCallback));
46
+ setComputedValue(data, comment, value as GenericCallback);
46
47
  break;
47
48
 
48
49
  case isReactive(value):
49
- setReactiveNode(data, comment, value);
50
+ setReactiveValue(data, comment, value);
50
51
  break;
51
52
 
52
53
  default:
@@ -70,3 +71,15 @@ function replaceComment(
70
71
 
71
72
  comment.replaceWith(...nodes);
72
73
  }
74
+
75
+ function setComputedValue(
76
+ data: FragmentData,
77
+ comment: Comment,
78
+ callback: GenericCallback,
79
+ ): void {
80
+ const value = computed(callback);
81
+
82
+ data.mora.values.add(value);
83
+
84
+ setReactiveValue(data, comment, value);
85
+ }
package/src/node/value.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
2
2
  import type {Key} from '@oscarpalmer/atoms/models';
3
3
  import {getString} from '@oscarpalmer/atoms/string';
4
- import {type Reactive, effect} from '@oscarpalmer/sentinel';
4
+ import type {Reactive} from '@oscarpalmer/mora';
5
+ import {isChildNode} from '@oscarpalmer/toretto/is';
5
6
  import type {Fragment} from '../fragment';
6
- import {compareArrays, isFragment, isProperNode} from '../helpers';
7
+ import {compareArrays, isFragment} from '../helpers';
7
8
  import {createNodes, replaceNodes} from '../helpers/dom';
8
- import type {FragmentData, FragmentItem, ProperNode} from '../models';
9
+ import type {FragmentData, FragmentItem} from '../models';
9
10
 
10
11
  function removeFragments(fragments: Fragment[] | undefined): void {
11
12
  if (fragments != null) {
@@ -19,7 +20,7 @@ function removeFragments(fragments: Fragment[] | undefined): void {
19
20
 
20
21
  function setArray(
21
22
  fragments: Fragment[] | undefined,
22
- nodes: ProperNode[] | undefined,
23
+ nodes: ChildNode[] | undefined,
23
24
  comment: Comment,
24
25
  text: Text,
25
26
  value: unknown[],
@@ -124,11 +125,11 @@ function setArray(
124
125
 
125
126
  function setNodes(
126
127
  fragments: Fragment[] | undefined,
127
- nodes: ProperNode[] | undefined,
128
+ nodes: ChildNode[] | undefined,
128
129
  comment: Comment,
129
130
  text: Text,
130
- next: ProperNode[],
131
- ): ProperNode[] {
131
+ next: ChildNode[],
132
+ ): ChildNode[] {
132
133
  if (nodes == null) {
133
134
  if (comment.parentNode != null) {
134
135
  replaceNodes([comment], next);
@@ -144,57 +145,57 @@ function setNodes(
144
145
  return next;
145
146
  }
146
147
 
147
- export function setReactiveNode(
148
+ export function setReactiveValue(
148
149
  data: FragmentData,
149
150
  comment: Comment,
150
- reactive: Reactive,
151
+ reactive: Reactive<unknown>,
151
152
  ): void {
152
153
  const item = data.items.find(item => item.nodes.includes(comment));
153
154
  const text = new Text();
154
155
 
155
156
  let fragments: Fragment[] | undefined;
156
- let nodes: ProperNode[] | undefined;
157
+ let nodes: ChildNode[] | undefined;
157
158
 
158
- effect(() => {
159
- const value = reactive.get();
159
+ data.mora.subscribers.add(
160
+ reactive.subscribe(value => {
161
+ if (Array.isArray(value)) {
162
+ const result = setArray(fragments, nodes, comment, text, value);
160
163
 
161
- if (Array.isArray(value)) {
162
- const result = setArray(fragments, nodes, comment, text, value);
164
+ fragments = typeof result === 'boolean' ? undefined : result?.fragments;
163
165
 
164
- fragments = typeof result === 'boolean' ? undefined : result?.fragments;
165
-
166
- nodes =
167
- typeof result === 'boolean'
168
- ? result
169
- ? [text]
170
- : undefined
171
- : result?.nodes;
172
- } else {
173
- const valueIsFragment = isFragment(value);
166
+ nodes =
167
+ typeof result === 'boolean'
168
+ ? result
169
+ ? [text]
170
+ : undefined
171
+ : result?.nodes;
172
+ } else {
173
+ const valueIsFragment = isFragment(value);
174
174
 
175
- fragments = valueIsFragment ? [value] : undefined;
175
+ fragments = valueIsFragment ? [value] : undefined;
176
176
 
177
- if (valueIsFragment || isProperNode(value)) {
178
- nodes = setNodes(fragments, nodes, comment, text, createNodes(value));
179
- } else {
180
- nodes = setText(fragments, nodes, comment, text, value);
177
+ if (valueIsFragment || isChildNode(value)) {
178
+ nodes = setNodes(fragments, nodes, comment, text, createNodes(value));
179
+ } else {
180
+ nodes = setText(fragments, nodes, comment, text, value);
181
+ }
181
182
  }
182
- }
183
183
 
184
- if (item != null) {
185
- item.fragments = fragments;
186
- item.nodes = [...(nodes ?? [comment])];
187
- }
188
- });
184
+ if (item != null) {
185
+ item.fragments = fragments;
186
+ item.nodes = [...(nodes ?? [comment])];
187
+ }
188
+ }),
189
+ );
189
190
  }
190
191
 
191
192
  function setText(
192
193
  fragments: Fragment[] | undefined,
193
- nodes: ProperNode[] | undefined,
194
+ nodes: ChildNode[] | undefined,
194
195
  comment: Comment,
195
196
  text: Text,
196
197
  value: unknown,
197
- ): ProperNode[] | undefined {
198
+ ): ChildNode[] | undefined {
198
199
  const isNullable = isNullableOrWhitespace(value);
199
200
 
200
201
  text.textContent = isNullable ? '' : getString(value);
@@ -1,5 +1,4 @@
1
1
  import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
2
- import {Fragment} from './fragment';
3
2
  import type {FragmentData} from './models';
4
3
 
5
4
  function handleExpression(
@@ -7,10 +6,6 @@ function handleExpression(
7
6
  prefix: string,
8
7
  expression: unknown,
9
8
  ): string {
10
- if (isNullableOrWhitespace(expression)) {
11
- return prefix;
12
- }
13
-
14
9
  if (Array.isArray(expression)) {
15
10
  const {length} = expression;
16
11
 
@@ -23,20 +18,16 @@ function handleExpression(
23
18
  return `${prefix}${expressions}`;
24
19
  }
25
20
 
26
- if (typeof expression === 'function' || typeof expression === 'object') {
21
+ if (
22
+ typeof expression === 'function' ||
23
+ (typeof expression === 'object' && expression != null)
24
+ ) {
27
25
  const index = data.values.push(expression) - 1;
28
26
 
29
27
  return `${prefix}<!--abydon.${index}-->`;
30
28
  }
31
29
 
32
- return `${prefix}${expression}`;
33
- }
34
-
35
- export function html(
36
- strings: TemplateStringsArray,
37
- ...values: unknown[]
38
- ): Fragment {
39
- return new Fragment(strings, values);
30
+ return isNullableOrWhitespace(expression) ? prefix : `${prefix}${expression}`;
40
31
  }
41
32
 
42
33
  export function parse(data: FragmentData): string {
@@ -0,0 +1,27 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ /**
4
+ * A generic key type
5
+ */
6
+ export type Key = number | string;
7
+ export declare class Fragment {
8
+ private readonly $fragment;
9
+ private readonly data;
10
+ get identifier(): Key | undefined;
11
+ constructor(strings: TemplateStringsArray, expressions: unknown[]);
12
+ /**
13
+ * Appends the fragment to the given element
14
+ */
15
+ appendTo(element: Element): void;
16
+ /**
17
+ * Gets a list of the fragment's nodes
18
+ */
19
+ get(): ChildNode[];
20
+ identify(identifier: Key): Fragment;
21
+ /**
22
+ * Removes the fragment from the DOM
23
+ */
24
+ remove(): void;
25
+ }
26
+
27
+ export {};
@@ -1,5 +1,4 @@
1
1
  import type { Key } from '@oscarpalmer/atoms/models';
2
- import type { ProperNode } from './models';
3
2
  export declare class Fragment {
4
3
  private readonly $fragment;
5
4
  private readonly data;
@@ -12,7 +11,7 @@ export declare class Fragment {
12
11
  /**
13
12
  * Gets a list of the fragment's nodes
14
13
  */
15
- get(): ProperNode[];
14
+ get(): ChildNode[];
16
15
  identify(identifier: Key): Fragment;
17
16
  /**
18
17
  * Removes the fragment from the DOM
@@ -0,0 +1,7 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ export declare function createNodes(value: unknown): ChildNode[];
4
+ export declare function removeNodes(nodes: ChildNode[]): void;
5
+ export declare function replaceNodes(from: ChildNode[], to: ChildNode[]): void;
6
+
7
+ export {};
@@ -1,4 +1,3 @@
1
- import type { ProperNode } from '../models';
2
- export declare function createNodes(value: unknown): ProperNode[];
3
- export declare function removeNodes(nodes: ProperNode[]): void;
4
- export declare function replaceNodes(from: ProperNode[], to: ProperNode[]): void;
1
+ export declare function createNodes(value: unknown): ChildNode[];
2
+ export declare function removeNodes(nodes: ChildNode[]): void;
3
+ export declare function replaceNodes(from: ChildNode[], to: ChildNode[]): void;
@@ -0,0 +1,29 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ /**
4
+ * A generic key type
5
+ */
6
+ export type Key = number | string;
7
+ declare class Fragment {
8
+ private readonly $fragment;
9
+ private readonly data;
10
+ get identifier(): Key | undefined;
11
+ constructor(strings: TemplateStringsArray, expressions: unknown[]);
12
+ /**
13
+ * Appends the fragment to the given element
14
+ */
15
+ appendTo(element: Element): void;
16
+ /**
17
+ * Gets a list of the fragment's nodes
18
+ */
19
+ get(): ChildNode[];
20
+ identify(identifier: Key): Fragment;
21
+ /**
22
+ * Removes the fragment from the DOM
23
+ */
24
+ remove(): void;
25
+ }
26
+ export declare function compareArrays(first: unknown[], second: unknown[]): "added" | "dissimilar" | "removed";
27
+ export declare function isFragment(value: unknown): value is Fragment;
28
+
29
+ export {};
@@ -1,6 +1,3 @@
1
1
  import type { Fragment } from '../fragment';
2
- import type { ProperElement, ProperNode } from '../models';
3
2
  export declare function compareArrays(first: unknown[], second: unknown[]): 'added' | 'dissimilar' | 'removed';
4
3
  export declare function isFragment(value: unknown): value is Fragment;
5
- export declare function isProperElement(value: unknown): value is ProperElement;
6
- export declare function isProperNode(value: unknown): value is ProperNode;