@praxisjs/decorators 1.2.0 → 1.3.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,18 +1,55 @@
1
1
  import { computed } from "@praxisjs/core/internal";
2
2
 
3
- import { createGetterDecorator } from "../create-getter-decorator";
3
+ import { createAccessorDecorator } from "../create-accessor-decorator";
4
+ import { createWritableGetterDecorator } from "../create-getter-decorator";
4
5
 
5
- export function Computed() {
6
- const cache = new WeakMap<object, () => unknown>();
6
+ export interface ComputedOptions<T = unknown> {
7
+ get?: (this: object) => T;
8
+ set?: (this: object, value: T) => void;
9
+ }
10
+
11
+ // Accessor form — @Computed({ get, set }) on an `accessor` field.
12
+ // TypeScript sees the accessor as writable; no cast needed when assigning.
13
+ // The `Owner` generic is inferred from the `this` type of the provided functions.
14
+ export function Computed<T, Owner extends object = object>(options: {
15
+ get: (this: Owner) => T;
16
+ set: (this: Owner, value: T) => void;
17
+ }): <This extends object>(
18
+ target: ClassAccessorDecoratorTarget<This, T>,
19
+ context: ClassAccessorDecoratorContext<This, T>,
20
+ ) => ClassAccessorDecoratorResult<This, T>;
21
+
22
+ // Getter form — @Computed() or @Computed({ set }) on a `get` accessor.
23
+ export function Computed(options?: {
24
+ set?: (this: object, value: unknown) => void;
25
+ }): <This, R>(
26
+ target: (this: This) => R,
27
+ context: ClassGetterDecoratorContext<This, R>,
28
+ ) => (this: This) => R;
29
+
30
+ export function Computed<T = unknown>(options?: ComputedOptions<T>): unknown {
31
+ const optionsGet = options?.get as ((this: object) => unknown) | undefined;
32
+ const optionsSet = options?.set as ((this: object, value: unknown) => void) | undefined;
33
+
34
+ if (optionsGet) {
35
+ return createAccessorDecorator({
36
+ bind(instance, _name, _initialValue) {
37
+ const c = computed(() => optionsGet.call(instance));
38
+ return {
39
+ get: c,
40
+ set: optionsSet ? (value) => { optionsSet.call(instance, value); } : undefined,
41
+ };
42
+ },
43
+ });
44
+ }
7
45
 
8
- return createGetterDecorator({
9
- wrap(original, instance) {
10
- let c = cache.get(instance);
11
- if (!c) {
12
- c = computed(() => original.call(instance));
13
- cache.set(instance, c);
14
- }
15
- return c;
46
+ return createWritableGetterDecorator({
47
+ bind(instance, _name, original) {
48
+ const c = computed(() => original.call(instance));
49
+ return {
50
+ get: c,
51
+ set: optionsSet ? (value) => { optionsSet.call(instance, value); } : undefined,
52
+ };
16
53
  },
17
54
  });
18
55
  }