@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aerogel/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1-next.1a964fb10cbea49d0eed8de0623c9b71ce8442f4",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "exports": {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <form @submit.prevent="form?.submit()">
2
+ <form @submit.prevent="form ? form.submit() : $emit('submit')">
3
3
  <slot />
4
4
  </form>
5
5
  </template>
@@ -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 builtInDirectives: Record<string, Directive> = {
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
- ...builtInDirectives,
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>>;
@@ -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';