@aerogel/core 0.1.0 → 0.1.1-next.1a964fb10cbea49d0eed8de0623c9b71ce8442f4
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/dist/aerogel-core.d.ts +23 -6
- package/dist/aerogel-core.js +957 -927
- package/dist/aerogel-core.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ui/Form.vue +1 -1
- package/src/directives/index.ts +10 -8
- package/src/directives/safe-html.ts +10 -0
- package/src/utils/composition/reactiveSet.test.ts +32 -0
- package/src/utils/composition/reactiveSet.ts +53 -0
- package/src/utils/index.ts +1 -0
package/package.json
CHANGED
package/src/directives/index.ts
CHANGED
|
@@ -3,22 +3,26 @@ import type { Directive } from 'vue';
|
|
|
3
3
|
import { definePlugin } from '@aerogel/core/plugins';
|
|
4
4
|
|
|
5
5
|
import measure from './measure';
|
|
6
|
+
import safeHtml from './safe-html';
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
measure: measure,
|
|
9
|
-
|
|
8
|
+
export const aerogelDirectives = {
|
|
9
|
+
'measure': measure,
|
|
10
|
+
'safe-html': safeHtml,
|
|
11
|
+
} as const satisfies Record<string, Directive>;
|
|
12
|
+
|
|
13
|
+
export type AerogelDirectives = typeof aerogelDirectives;
|
|
10
14
|
|
|
11
15
|
export * from './measure';
|
|
12
16
|
|
|
13
17
|
export default definePlugin({
|
|
14
18
|
install(app, options) {
|
|
15
19
|
const directives = {
|
|
16
|
-
...
|
|
20
|
+
...aerogelDirectives,
|
|
17
21
|
...options.directives,
|
|
18
22
|
};
|
|
19
23
|
|
|
20
24
|
for (const [name, directive] of Object.entries(directives)) {
|
|
21
|
-
app.directive(name, directive);
|
|
25
|
+
app.directive(name, directive as Directive);
|
|
22
26
|
}
|
|
23
27
|
},
|
|
24
28
|
});
|
|
@@ -30,7 +34,5 @@ declare module '@aerogel/core/bootstrap/options' {
|
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
declare module 'vue' {
|
|
33
|
-
interface ComponentCustomDirectives {
|
|
34
|
-
measure: Directive<string, string>;
|
|
35
|
-
}
|
|
37
|
+
interface ComponentCustomDirectives extends AerogelDirectives {}
|
|
36
38
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { safeHtml } from '@aerogel/core/utils';
|
|
2
|
+
import { defineDirective } from '@aerogel/core/utils/vue';
|
|
3
|
+
|
|
4
|
+
export type SafeHTMLDirectiveValue = string;
|
|
5
|
+
|
|
6
|
+
export default defineDirective<SafeHTMLDirectiveValue>({
|
|
7
|
+
mounted(element: HTMLElement, { value }) {
|
|
8
|
+
element.innerHTML = safeHtml(value);
|
|
9
|
+
},
|
|
10
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { nextTick, watchEffect } from 'vue';
|
|
3
|
+
|
|
4
|
+
import { reactiveSet } from './reactiveSet';
|
|
5
|
+
|
|
6
|
+
describe('Vue reactiveSet', () => {
|
|
7
|
+
|
|
8
|
+
it('watches updates', async () => {
|
|
9
|
+
// Arrange
|
|
10
|
+
const set = reactiveSet();
|
|
11
|
+
let updates = 0;
|
|
12
|
+
|
|
13
|
+
watchEffect(() => (set.has('foo'), updates++));
|
|
14
|
+
|
|
15
|
+
// Act
|
|
16
|
+
set.add('foo');
|
|
17
|
+
await nextTick();
|
|
18
|
+
|
|
19
|
+
set.add('bar');
|
|
20
|
+
await nextTick();
|
|
21
|
+
|
|
22
|
+
set.add('baz');
|
|
23
|
+
await nextTick();
|
|
24
|
+
|
|
25
|
+
set.reset();
|
|
26
|
+
await nextTick();
|
|
27
|
+
|
|
28
|
+
// Assert
|
|
29
|
+
expect(updates).toEqual(5);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { fail } from '@noeldemartin/utils';
|
|
2
|
+
import { customRef } from 'vue';
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
5
|
+
export function reactiveSet<T>(initial?: T[] | Set<T>) {
|
|
6
|
+
let set: Set<T> = new Set(initial);
|
|
7
|
+
let trigger: () => void;
|
|
8
|
+
let track: () => void;
|
|
9
|
+
const ref = customRef((_track, _trigger) => {
|
|
10
|
+
track = _track;
|
|
11
|
+
trigger = _trigger;
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
get: () => set,
|
|
15
|
+
set: () => fail('Attempted to write read-only reactive set'),
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
values() {
|
|
21
|
+
track();
|
|
22
|
+
|
|
23
|
+
return Array.from(ref.value.values());
|
|
24
|
+
},
|
|
25
|
+
has(item: T) {
|
|
26
|
+
track();
|
|
27
|
+
|
|
28
|
+
return ref.value.has(item);
|
|
29
|
+
},
|
|
30
|
+
add(item: T) {
|
|
31
|
+
trigger();
|
|
32
|
+
|
|
33
|
+
ref.value.add(item);
|
|
34
|
+
},
|
|
35
|
+
delete(item: T) {
|
|
36
|
+
trigger();
|
|
37
|
+
|
|
38
|
+
ref.value.delete(item);
|
|
39
|
+
},
|
|
40
|
+
clear() {
|
|
41
|
+
trigger();
|
|
42
|
+
|
|
43
|
+
ref.value.clear();
|
|
44
|
+
},
|
|
45
|
+
reset(items?: T[] | Set<T>) {
|
|
46
|
+
trigger();
|
|
47
|
+
|
|
48
|
+
set = new Set(items);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type ReactiveSet<T = unknown> = ReturnType<typeof reactiveSet<T>>;
|
package/src/utils/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './composition/events';
|
|
|
4
4
|
export * from './composition/forms';
|
|
5
5
|
export * from './composition/hooks';
|
|
6
6
|
export * from './composition/persistent';
|
|
7
|
+
export * from './composition/reactiveSet';
|
|
7
8
|
export * from './composition/state';
|
|
8
9
|
export * from './markdown';
|
|
9
10
|
export * from './types';
|