@joist/observable 4.0.0-next.5 → 4.0.0-next.50
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/README.md +8 -4
- package/package.json +4 -7
- package/src/lib/metadata.test.ts +6 -5
- package/src/lib/metadata.ts +37 -23
- package/src/lib/observe.test.ts +16 -11
- package/src/lib/observe.ts +36 -24
- package/src/lib.ts +2 -1
- package/target/lib/metadata.d.ts +13 -12
- package/target/lib/metadata.js +17 -15
- package/target/lib/metadata.js.map +1 -1
- package/target/lib/metadata.test.js +5 -5
- package/target/lib/metadata.test.js.map +1 -1
- package/target/lib/observe.d.ts +2 -2
- package/target/lib/observe.js +21 -15
- package/target/lib/observe.js.map +1 -1
- package/target/lib/observe.test.js +13 -10
- package/target/lib/observe.test.js.map +1 -1
- package/target/lib.d.ts +2 -1
- package/target/lib.js +2 -1
- package/target/lib.js.map +1 -1
package/README.md
CHANGED
|
@@ -5,17 +5,21 @@ Adds the ability to monitor class properties (static and instance) for changes
|
|
|
5
5
|
#### Installation:
|
|
6
6
|
|
|
7
7
|
```BASH
|
|
8
|
-
npm i @joist/observable
|
|
8
|
+
npm i @joist/observable@next
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
```TS
|
|
12
12
|
import { observe, effect } from '@joist/observable';
|
|
13
13
|
|
|
14
14
|
class AppState {
|
|
15
|
-
@observe
|
|
16
|
-
|
|
15
|
+
@observe()
|
|
16
|
+
accessor todos: string[] = [];
|
|
17
17
|
|
|
18
|
-
@
|
|
18
|
+
@observe()
|
|
19
|
+
accessor userName?: string;
|
|
20
|
+
|
|
21
|
+
@effect()
|
|
22
|
+
onChange(changes: Changes) {
|
|
19
23
|
console.log(changes);
|
|
20
24
|
}
|
|
21
25
|
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joist/observable",
|
|
3
|
-
"version": "4.0.0-next.
|
|
3
|
+
"version": "4.0.0-next.50",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./target/lib.js",
|
|
6
6
|
"module": "./target/lib.js",
|
|
7
7
|
"exports": {
|
|
8
|
-
".":
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"./*": {
|
|
12
|
-
"import": "./target/lib/*.js"
|
|
13
|
-
}
|
|
8
|
+
".": "./target/lib.js",
|
|
9
|
+
"./*": "./target/lib/*",
|
|
10
|
+
"./package.json": "./package.json"
|
|
14
11
|
},
|
|
15
12
|
"files": [
|
|
16
13
|
"src",
|
package/src/lib/metadata.test.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { assert } from
|
|
2
|
-
import { ObservableInstanceMetaDataStore } from './metadata.js';
|
|
1
|
+
import { assert } from "chai";
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { Changes, ObservableInstanceMetaDataStore } from "./metadata.js";
|
|
4
|
+
|
|
5
|
+
it("should return default metadata", () => {
|
|
5
6
|
const key = {};
|
|
6
7
|
const data = new ObservableInstanceMetaDataStore().read(key);
|
|
7
8
|
|
|
8
|
-
assert.deepEqual(data, { changes: new
|
|
9
|
+
assert.deepEqual(data, { changes: new Changes(), scheduler: null });
|
|
9
10
|
});
|
|
10
11
|
|
|
11
|
-
it(
|
|
12
|
+
it("should return the same metadata object after init", () => {
|
|
12
13
|
const key = {};
|
|
13
14
|
const data = new ObservableInstanceMetaDataStore();
|
|
14
15
|
|
package/src/lib/metadata.ts
CHANGED
|
@@ -1,43 +1,57 @@
|
|
|
1
|
-
(Symbol as any).metadata ??= Symbol(
|
|
1
|
+
(Symbol as any).metadata ??= Symbol("Symbol.metadata");
|
|
2
2
|
|
|
3
|
-
export type EffectFn = (changes:
|
|
3
|
+
export type EffectFn<T> = (changes: Changes<T>) => void;
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
|
|
5
|
+
export class Changes<T> extends Map<
|
|
6
|
+
keyof T,
|
|
7
|
+
{ oldValue: unknown; newValue: unknown }
|
|
8
|
+
> {}
|
|
9
|
+
|
|
10
|
+
export class ObservableInstanceMetadata<T> {
|
|
11
|
+
scheduler: Promise<void> | null = null;
|
|
12
|
+
changes: Changes<T> = new Changes();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class ObservableInstanceMetaDataStore extends WeakMap<
|
|
16
|
+
object,
|
|
17
|
+
ObservableInstanceMetadata<unknown>
|
|
18
|
+
> {
|
|
19
|
+
read<T extends object>(key: T): ObservableInstanceMetadata<T> {
|
|
7
20
|
let data = this.get(key);
|
|
8
21
|
|
|
9
22
|
if (!data) {
|
|
10
|
-
data =
|
|
23
|
+
data = new ObservableInstanceMetadata();
|
|
11
24
|
|
|
12
25
|
this.set(key, data);
|
|
13
26
|
}
|
|
14
27
|
|
|
15
28
|
return data;
|
|
16
29
|
}
|
|
17
|
-
|
|
18
|
-
abstract init(): Metadata;
|
|
19
30
|
}
|
|
20
31
|
|
|
21
|
-
export class
|
|
22
|
-
|
|
23
|
-
changes = new Set<string | symbol>();
|
|
32
|
+
export class ObservableMetadata<T> {
|
|
33
|
+
effects: Set<EffectFn<T>> = new Set();
|
|
24
34
|
}
|
|
25
35
|
|
|
26
|
-
export class
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
export class ObservableMetadataStore extends WeakMap<
|
|
37
|
+
object,
|
|
38
|
+
ObservableMetadata<unknown>
|
|
39
|
+
> {
|
|
40
|
+
read<T extends object>(key: object): ObservableMetadata<T> {
|
|
41
|
+
let data = this.get(key);
|
|
31
42
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
43
|
+
if (!data) {
|
|
44
|
+
data = new ObservableMetadata();
|
|
35
45
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
46
|
+
this.set(key, data);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return data as ObservableMetadata<T>;
|
|
39
50
|
}
|
|
40
51
|
}
|
|
41
52
|
|
|
42
|
-
export const instanceMetadataStore =
|
|
43
|
-
|
|
53
|
+
export const instanceMetadataStore: ObservableInstanceMetaDataStore =
|
|
54
|
+
new ObservableInstanceMetaDataStore();
|
|
55
|
+
|
|
56
|
+
export const observableMetadataStore: ObservableMetadataStore =
|
|
57
|
+
new ObservableMetadataStore();
|
package/src/lib/observe.test.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { assert } from
|
|
1
|
+
import { assert } from "chai";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import type { Changes } from "./metadata.js";
|
|
4
|
+
import { effect, observe } from "./observe.js";
|
|
4
5
|
|
|
5
|
-
it(
|
|
6
|
+
it("should work with static accessors", () => {
|
|
6
7
|
return new Promise<void>((resolve) => {
|
|
8
|
+
// biome-ignore lint/complexity/noStaticOnlyClass: <explanation>
|
|
7
9
|
class Counter {
|
|
8
10
|
@observe()
|
|
9
11
|
static accessor value = 0;
|
|
@@ -23,7 +25,7 @@ it('should work with static accessors', () => {
|
|
|
23
25
|
});
|
|
24
26
|
});
|
|
25
27
|
|
|
26
|
-
it(
|
|
28
|
+
it("should work with instance accessors", () => {
|
|
27
29
|
return new Promise<void>((resolve) => {
|
|
28
30
|
class Counter {
|
|
29
31
|
@observe()
|
|
@@ -48,13 +50,16 @@ it('should work with instance accessors', () => {
|
|
|
48
50
|
});
|
|
49
51
|
});
|
|
50
52
|
|
|
51
|
-
it(
|
|
53
|
+
it("should return a set of changed props", () => {
|
|
52
54
|
return new Promise<void>((resolve) => {
|
|
53
55
|
class Counter {
|
|
54
56
|
@observe() accessor value = 0;
|
|
55
57
|
|
|
56
|
-
@effect() onChange(changes:
|
|
57
|
-
assert.
|
|
58
|
+
@effect() onChange(changes: Changes<this>) {
|
|
59
|
+
assert.deepEqual(changes.get("value"), {
|
|
60
|
+
oldValue: 0,
|
|
61
|
+
newValue: 1,
|
|
62
|
+
});
|
|
58
63
|
|
|
59
64
|
resolve();
|
|
60
65
|
}
|
|
@@ -65,7 +70,7 @@ it('should return a set of changed props', () => {
|
|
|
65
70
|
});
|
|
66
71
|
});
|
|
67
72
|
|
|
68
|
-
it(
|
|
73
|
+
it("should upgrade custom elements", () => {
|
|
69
74
|
return new Promise<void>((resolve) => {
|
|
70
75
|
class Counter extends HTMLElement {
|
|
71
76
|
@observe()
|
|
@@ -84,15 +89,15 @@ it('should upgrade custom elements', () => {
|
|
|
84
89
|
}
|
|
85
90
|
}
|
|
86
91
|
|
|
87
|
-
const el = document.createElement(
|
|
92
|
+
const el = document.createElement("observable-1") as Counter;
|
|
88
93
|
el.value = 100;
|
|
89
94
|
|
|
90
95
|
document.body.append(el);
|
|
91
96
|
|
|
92
|
-
customElements.whenDefined(
|
|
97
|
+
customElements.whenDefined("observable-1").then(() => {
|
|
93
98
|
el.value++;
|
|
94
99
|
});
|
|
95
100
|
|
|
96
|
-
customElements.define(
|
|
101
|
+
customElements.define("observable-1", Counter);
|
|
97
102
|
});
|
|
98
103
|
});
|
package/src/lib/observe.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type EffectFn,
|
|
3
|
+
instanceMetadataStore,
|
|
4
|
+
observableMetadataStore,
|
|
5
|
+
} from "./metadata.js";
|
|
2
6
|
|
|
3
7
|
export function observe() {
|
|
4
8
|
return function observeDecorator<This extends object, Value>(
|
|
5
9
|
base: ClassAccessorDecoratorTarget<This, Value>,
|
|
6
|
-
ctx: ClassAccessorDecoratorContext<This, Value
|
|
10
|
+
ctx: ClassAccessorDecoratorContext<This, Value>,
|
|
7
11
|
): ClassAccessorDecoratorResult<This, Value> {
|
|
12
|
+
const observableMeta = observableMetadataStore.read<This>(ctx.metadata);
|
|
13
|
+
|
|
8
14
|
return {
|
|
9
15
|
init(value) {
|
|
10
16
|
let val: Value | null = null;
|
|
@@ -15,7 +21,7 @@ export function observe() {
|
|
|
15
21
|
} catch {}
|
|
16
22
|
|
|
17
23
|
if (val) {
|
|
18
|
-
|
|
24
|
+
Reflect.deleteProperty(this, ctx.name);
|
|
19
25
|
|
|
20
26
|
return val;
|
|
21
27
|
}
|
|
@@ -23,35 +29,41 @@ export function observe() {
|
|
|
23
29
|
|
|
24
30
|
return value;
|
|
25
31
|
},
|
|
26
|
-
set(
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
instanceMeta.changes.clear();
|
|
38
|
-
});
|
|
39
|
-
}
|
|
32
|
+
set(newValue: Value) {
|
|
33
|
+
const oldValue = base.get.call(this);
|
|
34
|
+
|
|
35
|
+
if (newValue !== oldValue) {
|
|
36
|
+
const instanceMeta = instanceMetadataStore.read<This>(this);
|
|
37
|
+
|
|
38
|
+
if (instanceMeta.scheduler === null) {
|
|
39
|
+
instanceMeta.scheduler = Promise.resolve().then(() => {
|
|
40
|
+
for (const effect of observableMeta.effects) {
|
|
41
|
+
effect.call(this, instanceMeta.changes);
|
|
42
|
+
}
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
instanceMeta.scheduler = null;
|
|
45
|
+
instanceMeta.changes.clear();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
instanceMeta.changes.set(ctx.name as keyof This, {
|
|
50
|
+
oldValue,
|
|
51
|
+
newValue,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
base.set.call(this, newValue);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
45
57
|
};
|
|
46
58
|
};
|
|
47
59
|
}
|
|
48
60
|
|
|
49
61
|
export function effect() {
|
|
50
62
|
return function effectDecorator<T extends object>(
|
|
51
|
-
value: EffectFn
|
|
52
|
-
ctx: ClassMethodDecoratorContext<T
|
|
53
|
-
) {
|
|
54
|
-
const data = observableMetadataStore.read(ctx.metadata);
|
|
63
|
+
value: EffectFn<T>,
|
|
64
|
+
ctx: ClassMethodDecoratorContext<T>,
|
|
65
|
+
): void {
|
|
66
|
+
const data = observableMetadataStore.read<T>(ctx.metadata);
|
|
55
67
|
|
|
56
68
|
data.effects.add(value);
|
|
57
69
|
};
|
package/src/lib.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { observe, effect } from
|
|
1
|
+
export { observe, effect } from "./lib/observe.js";
|
|
2
|
+
export { Changes } from "./lib/metadata.js";
|
package/target/lib/metadata.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
export type EffectFn = (changes:
|
|
2
|
-
export declare
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export type EffectFn<T> = (changes: Changes<T>) => void;
|
|
2
|
+
export declare class Changes<T> extends Map<keyof T, {
|
|
3
|
+
oldValue: unknown;
|
|
4
|
+
newValue: unknown;
|
|
5
|
+
}> {
|
|
5
6
|
}
|
|
6
|
-
export declare class ObservableInstanceMetadata {
|
|
7
|
+
export declare class ObservableInstanceMetadata<T> {
|
|
7
8
|
scheduler: Promise<void> | null;
|
|
8
|
-
changes:
|
|
9
|
+
changes: Changes<T>;
|
|
9
10
|
}
|
|
10
|
-
export declare class ObservableInstanceMetaDataStore extends
|
|
11
|
-
|
|
11
|
+
export declare class ObservableInstanceMetaDataStore extends WeakMap<object, ObservableInstanceMetadata<unknown>> {
|
|
12
|
+
read<T extends object>(key: T): ObservableInstanceMetadata<T>;
|
|
12
13
|
}
|
|
13
|
-
export declare class ObservableMetadata {
|
|
14
|
-
effects: Set<EffectFn
|
|
14
|
+
export declare class ObservableMetadata<T> {
|
|
15
|
+
effects: Set<EffectFn<T>>;
|
|
15
16
|
}
|
|
16
|
-
export declare class ObservableMetadataStore extends
|
|
17
|
-
|
|
17
|
+
export declare class ObservableMetadataStore extends WeakMap<object, ObservableMetadata<unknown>> {
|
|
18
|
+
read<T extends object>(key: object): ObservableMetadata<T>;
|
|
18
19
|
}
|
|
19
20
|
export declare const instanceMetadataStore: ObservableInstanceMetaDataStore;
|
|
20
21
|
export declare const observableMetadataStore: ObservableMetadataStore;
|
package/target/lib/metadata.js
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
Symbol.metadata ??= Symbol(
|
|
2
|
-
export class
|
|
1
|
+
Symbol.metadata ??= Symbol("Symbol.metadata");
|
|
2
|
+
export class Changes extends Map {
|
|
3
|
+
}
|
|
4
|
+
export class ObservableInstanceMetadata {
|
|
5
|
+
scheduler = null;
|
|
6
|
+
changes = new Changes();
|
|
7
|
+
}
|
|
8
|
+
export class ObservableInstanceMetaDataStore extends WeakMap {
|
|
3
9
|
read(key) {
|
|
4
10
|
let data = this.get(key);
|
|
5
11
|
if (!data) {
|
|
6
|
-
data =
|
|
12
|
+
data = new ObservableInstanceMetadata();
|
|
7
13
|
this.set(key, data);
|
|
8
14
|
}
|
|
9
15
|
return data;
|
|
10
16
|
}
|
|
11
17
|
}
|
|
12
|
-
export class ObservableInstanceMetadata {
|
|
13
|
-
scheduler = null;
|
|
14
|
-
changes = new Set();
|
|
15
|
-
}
|
|
16
|
-
export class ObservableInstanceMetaDataStore extends MetadataStore {
|
|
17
|
-
init() {
|
|
18
|
-
return new ObservableInstanceMetadata();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
18
|
export class ObservableMetadata {
|
|
22
19
|
effects = new Set();
|
|
23
20
|
}
|
|
24
|
-
export class ObservableMetadataStore extends
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
export class ObservableMetadataStore extends WeakMap {
|
|
22
|
+
read(key) {
|
|
23
|
+
let data = this.get(key);
|
|
24
|
+
if (!data) {
|
|
25
|
+
data = new ObservableMetadata();
|
|
26
|
+
this.set(key, data);
|
|
27
|
+
}
|
|
28
|
+
return data;
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
export const instanceMetadataStore = new ObservableInstanceMetaDataStore();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/lib/metadata.ts"],"names":[],"mappings":"AAAC,MAAc,CAAC,QAAQ,KAAK,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAIvD,MAAM,
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/lib/metadata.ts"],"names":[],"mappings":"AAAC,MAAc,CAAC,QAAQ,KAAK,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAIvD,MAAM,OAAO,OAAW,SAAQ,GAG/B;CAAG;AAEJ,MAAM,OAAO,0BAA0B;IACrC,SAAS,GAAyB,IAAI,CAAC;IACvC,OAAO,GAAe,IAAI,OAAO,EAAE,CAAC;CACrC;AAED,MAAM,OAAO,+BAAgC,SAAQ,OAGpD;IACC,IAAI,CAAmB,GAAM;QAC3B,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEzB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,IAAI,0BAA0B,EAAE,CAAC;YAExC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,MAAM,OAAO,kBAAkB;IAC7B,OAAO,GAAqB,IAAI,GAAG,EAAE,CAAC;CACvC;AAED,MAAM,OAAO,uBAAwB,SAAQ,OAG5C;IACC,IAAI,CAAmB,GAAW;QAChC,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEzB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,IAAI,kBAAkB,EAAE,CAAC;YAEhC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtB,CAAC;QAED,OAAO,IAA6B,CAAC;IACvC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,qBAAqB,GAChC,IAAI,+BAA+B,EAAE,CAAC;AAExC,MAAM,CAAC,MAAM,uBAAuB,GAClC,IAAI,uBAAuB,EAAE,CAAC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { assert } from
|
|
2
|
-
import { ObservableInstanceMetaDataStore } from
|
|
3
|
-
it(
|
|
1
|
+
import { assert } from "chai";
|
|
2
|
+
import { Changes, ObservableInstanceMetaDataStore } from "./metadata.js";
|
|
3
|
+
it("should return default metadata", () => {
|
|
4
4
|
const key = {};
|
|
5
5
|
const data = new ObservableInstanceMetaDataStore().read(key);
|
|
6
|
-
assert.deepEqual(data, { changes: new
|
|
6
|
+
assert.deepEqual(data, { changes: new Changes(), scheduler: null });
|
|
7
7
|
});
|
|
8
|
-
it(
|
|
8
|
+
it("should return the same metadata object after init", () => {
|
|
9
9
|
const key = {};
|
|
10
10
|
const data = new ObservableInstanceMetaDataStore();
|
|
11
11
|
assert.equal(data.read(key), data.read(key));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.test.js","sourceRoot":"","sources":["../../src/lib/metadata.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"metadata.test.js","sourceRoot":"","sources":["../../src/lib/metadata.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,OAAO,EAAE,OAAO,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAEzE,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;IACxC,MAAM,GAAG,GAAG,EAAE,CAAC;IACf,MAAM,IAAI,GAAG,IAAI,+BAA+B,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE7D,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC3D,MAAM,GAAG,GAAG,EAAE,CAAC;IACf,MAAM,IAAI,GAAG,IAAI,+BAA+B,EAAE,CAAC;IAEnD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC"}
|
package/target/lib/observe.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { EffectFn } from
|
|
1
|
+
import { type EffectFn } from "./metadata.js";
|
|
2
2
|
export declare function observe(): <This extends object, Value>(base: ClassAccessorDecoratorTarget<This, Value>, ctx: ClassAccessorDecoratorContext<This, Value>) => ClassAccessorDecoratorResult<This, Value>;
|
|
3
|
-
export declare function effect(): <T extends object>(value: EffectFn
|
|
3
|
+
export declare function effect(): <T extends object>(value: EffectFn<T>, ctx: ClassMethodDecoratorContext<T>) => void;
|
package/target/lib/observe.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { instanceMetadataStore, observableMetadataStore } from
|
|
1
|
+
import { instanceMetadataStore, observableMetadataStore, } from "./metadata.js";
|
|
2
2
|
export function observe() {
|
|
3
3
|
return function observeDecorator(base, ctx) {
|
|
4
|
+
const observableMeta = observableMetadataStore.read(ctx.metadata);
|
|
4
5
|
return {
|
|
5
6
|
init(value) {
|
|
6
7
|
let val = null;
|
|
@@ -9,26 +10,31 @@ export function observe() {
|
|
|
9
10
|
}
|
|
10
11
|
catch { }
|
|
11
12
|
if (val) {
|
|
12
|
-
|
|
13
|
+
Reflect.deleteProperty(this, ctx.name);
|
|
13
14
|
return val;
|
|
14
15
|
}
|
|
15
16
|
return value;
|
|
16
17
|
},
|
|
17
|
-
set(
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
instanceMeta.scheduler
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
set(newValue) {
|
|
19
|
+
const oldValue = base.get.call(this);
|
|
20
|
+
if (newValue !== oldValue) {
|
|
21
|
+
const instanceMeta = instanceMetadataStore.read(this);
|
|
22
|
+
if (instanceMeta.scheduler === null) {
|
|
23
|
+
instanceMeta.scheduler = Promise.resolve().then(() => {
|
|
24
|
+
for (const effect of observableMeta.effects) {
|
|
25
|
+
effect.call(this, instanceMeta.changes);
|
|
26
|
+
}
|
|
27
|
+
instanceMeta.scheduler = null;
|
|
28
|
+
instanceMeta.changes.clear();
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
instanceMeta.changes.set(ctx.name, {
|
|
32
|
+
oldValue,
|
|
33
|
+
newValue,
|
|
27
34
|
});
|
|
35
|
+
base.set.call(this, newValue);
|
|
28
36
|
}
|
|
29
|
-
|
|
30
|
-
base.set.call(this, value);
|
|
31
|
-
}
|
|
37
|
+
},
|
|
32
38
|
};
|
|
33
39
|
};
|
|
34
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../../src/lib/observe.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../../src/lib/observe.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAEvB,MAAM,UAAU,OAAO;IACrB,OAAO,SAAS,gBAAgB,CAC9B,IAA+C,EAC/C,GAA+C;QAE/C,MAAM,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAO,GAAG,CAAC,QAAQ,CAAC,CAAC;QAExE,OAAO;YACL,IAAI,CAAC,KAAK;gBACR,IAAI,GAAG,GAAiB,IAAI,CAAC;gBAG7B,IAAI,CAAC;oBACH,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC7B,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;gBAEV,IAAI,GAAG,EAAE,CAAC;oBACR,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;oBAEvC,OAAO,GAAG,CAAC;gBACb,CAAC;gBAGD,OAAO,KAAK,CAAC;YACf,CAAC;YACD,GAAG,CAAC,QAAe;gBACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAErC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAC1B,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAO,IAAI,CAAC,CAAC;oBAE5D,IAAI,YAAY,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;wBACpC,YAAY,CAAC,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;4BACnD,KAAK,MAAM,MAAM,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;gCAC5C,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;4BAC1C,CAAC;4BAED,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC;4BAC9B,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;wBAC/B,CAAC,CAAC,CAAC;oBACL,CAAC;oBAED,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAkB,EAAE;wBAC/C,QAAQ;wBACR,QAAQ;qBACT,CAAC,CAAC;oBAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,OAAO,SAAS,eAAe,CAC7B,KAAkB,EAClB,GAAmC;QAEnC,MAAM,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE3D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __esDecorate, __runInitializers, __setFunctionName } from "tslib";
|
|
2
|
-
import { assert } from
|
|
3
|
-
import { effect, observe } from
|
|
4
|
-
it(
|
|
2
|
+
import { assert } from "chai";
|
|
3
|
+
import { effect, observe } from "./observe.js";
|
|
4
|
+
it("should work with static accessors", () => {
|
|
5
5
|
return new Promise((resolve) => {
|
|
6
6
|
let Counter = (() => {
|
|
7
7
|
let _staticExtraInitializers = [];
|
|
@@ -35,7 +35,7 @@ it('should work with static accessors', () => {
|
|
|
35
35
|
assert.equal(Counter.value, 1);
|
|
36
36
|
});
|
|
37
37
|
});
|
|
38
|
-
it(
|
|
38
|
+
it("should work with instance accessors", () => {
|
|
39
39
|
return new Promise((resolve) => {
|
|
40
40
|
let Counter = (() => {
|
|
41
41
|
let _instanceExtraInitializers = [];
|
|
@@ -71,7 +71,7 @@ it('should work with instance accessors', () => {
|
|
|
71
71
|
assert.equal(counter.value, 1);
|
|
72
72
|
});
|
|
73
73
|
});
|
|
74
|
-
it(
|
|
74
|
+
it("should return a set of changed props", () => {
|
|
75
75
|
return new Promise((resolve) => {
|
|
76
76
|
let Counter = (() => {
|
|
77
77
|
let _instanceExtraInitializers = [];
|
|
@@ -92,7 +92,10 @@ it('should return a set of changed props', () => {
|
|
|
92
92
|
get value() { return this.#value_accessor_storage; }
|
|
93
93
|
set value(value) { this.#value_accessor_storage = value; }
|
|
94
94
|
onChange(changes) {
|
|
95
|
-
assert.
|
|
95
|
+
assert.deepEqual(changes.get("value"), {
|
|
96
|
+
oldValue: 0,
|
|
97
|
+
newValue: 1,
|
|
98
|
+
});
|
|
96
99
|
resolve();
|
|
97
100
|
}
|
|
98
101
|
constructor() {
|
|
@@ -104,7 +107,7 @@ it('should return a set of changed props', () => {
|
|
|
104
107
|
counter.value++;
|
|
105
108
|
});
|
|
106
109
|
});
|
|
107
|
-
it(
|
|
110
|
+
it("should upgrade custom elements", () => {
|
|
108
111
|
return new Promise((resolve) => {
|
|
109
112
|
let Counter = (() => {
|
|
110
113
|
let _classSuper = HTMLElement;
|
|
@@ -136,13 +139,13 @@ it('should upgrade custom elements', () => {
|
|
|
136
139
|
}
|
|
137
140
|
};
|
|
138
141
|
})();
|
|
139
|
-
const el = document.createElement(
|
|
142
|
+
const el = document.createElement("observable-1");
|
|
140
143
|
el.value = 100;
|
|
141
144
|
document.body.append(el);
|
|
142
|
-
customElements.whenDefined(
|
|
145
|
+
customElements.whenDefined("observable-1").then(() => {
|
|
143
146
|
el.value++;
|
|
144
147
|
});
|
|
145
|
-
customElements.define(
|
|
148
|
+
customElements.define("observable-1", Counter);
|
|
146
149
|
});
|
|
147
150
|
});
|
|
148
151
|
//# sourceMappingURL=observe.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe.test.js","sourceRoot":"","sources":["../../src/lib/observe.test.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"observe.test.js","sourceRoot":"","sources":["../../src/lib/observe.test.ts"],"names":[],"mappings":"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"}
|
package/target/lib.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { observe, effect } from
|
|
1
|
+
export { observe, effect } from "./lib/observe.js";
|
|
2
|
+
export { Changes } from "./lib/metadata.js";
|
package/target/lib.js
CHANGED
package/target/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC"}
|