@joist/observable 3.1.0 → 3.1.1
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 +3 -2
- package/src/lib/{meta.test.ts → metadata.test.ts} +3 -4
- package/src/lib/metadata.ts +45 -0
- package/src/lib/observe.test.ts +4 -2
- package/src/lib/observe.ts +26 -51
- package/src/lib/watch.test.ts +24 -0
- package/src/lib/watch.ts +11 -0
- package/target/lib/meta.d.ts +16 -4
- package/target/lib/meta.js +24 -10
- package/target/lib/meta.js.map +1 -1
- package/target/lib/meta.test.js +3 -3
- package/target/lib/meta.test.js.map +1 -1
- package/target/lib/observe.d.ts +2 -7
- package/target/lib/observe.js +17 -20
- package/target/lib/observe.js.map +1 -1
- package/target/lib/observe.test.js +3 -0
- package/target/lib/observe.test.js.map +1 -1
- package/target/lib/watch.d.ts +2 -0
- package/target/lib/watch.js +9 -0
- package/target/lib/watch.js.map +1 -0
- package/target/lib/watch.test.d.ts +1 -0
- package/target/lib/watch.test.js +33 -0
- package/target/lib/watch.test.js.map +1 -0
- package/src/lib/meta.ts +0 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@joist/observable",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./target/lib.js",
|
|
6
6
|
"module": "./target/lib.js",
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
"clean": "if-file-deleted",
|
|
47
47
|
"files": [
|
|
48
48
|
"src/**",
|
|
49
|
-
"tsconfig.json"
|
|
49
|
+
"tsconfig.json",
|
|
50
|
+
"../../tsconfig.json"
|
|
50
51
|
],
|
|
51
52
|
"output": [
|
|
52
53
|
"target/**",
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { expect } from '@open-wc/testing';
|
|
2
|
-
import {
|
|
2
|
+
import { ObservableInstanceMetaDataStore } from './metadata.js';
|
|
3
3
|
|
|
4
4
|
describe('meta:meta', () => {
|
|
5
5
|
it('should return default metadata', () => {
|
|
6
6
|
const key = {};
|
|
7
|
-
const data = new
|
|
7
|
+
const data = new ObservableInstanceMetaDataStore().read(key);
|
|
8
8
|
|
|
9
9
|
expect(data).to.deep.equal({
|
|
10
10
|
changes: new Set(),
|
|
11
|
-
upgradable: new Map(),
|
|
12
11
|
scheduler: null,
|
|
13
12
|
});
|
|
14
13
|
});
|
|
15
14
|
|
|
16
15
|
it('should return the same metadata object after init', () => {
|
|
17
16
|
const key = {};
|
|
18
|
-
const data = new
|
|
17
|
+
const data = new ObservableInstanceMetaDataStore();
|
|
19
18
|
|
|
20
19
|
expect(data.read(key)).to.equal(data.read(key));
|
|
21
20
|
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
(Symbol as any).metadata ??= Symbol('Symbol.metadata');
|
|
2
|
+
|
|
3
|
+
export type EffectFn = (changes: Set<string | symbol>) => void;
|
|
4
|
+
|
|
5
|
+
export abstract class MetadataStore<Metadata> {
|
|
6
|
+
#data = new WeakMap<object, Metadata>();
|
|
7
|
+
|
|
8
|
+
read<T extends object>(value: T): Metadata {
|
|
9
|
+
let data = this.#data.get(value);
|
|
10
|
+
|
|
11
|
+
if (!data) {
|
|
12
|
+
data = this.init();
|
|
13
|
+
|
|
14
|
+
this.#data.set(value, data);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return data;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
abstract init(): Metadata;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class ObservableInstanceMetadata {
|
|
24
|
+
scheduler: Promise<void> | null = null;
|
|
25
|
+
changes = new Set<string | symbol>();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class ObservableInstanceMetaDataStore extends MetadataStore<ObservableInstanceMetadata> {
|
|
29
|
+
init() {
|
|
30
|
+
return new ObservableInstanceMetadata();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class ObservableMetadata {
|
|
35
|
+
effects: Set<EffectFn> = new Set();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class ObservableMetadataStore extends MetadataStore<ObservableMetadata> {
|
|
39
|
+
init() {
|
|
40
|
+
return new ObservableMetadata();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const instanceMetadataStore = new ObservableInstanceMetaDataStore();
|
|
45
|
+
export const observableMetadataStore = new ObservableMetadataStore();
|
package/src/lib/observe.test.ts
CHANGED
|
@@ -98,9 +98,11 @@ describe('observable: observe()', () => {
|
|
|
98
98
|
fixture<any>(html`<observable-1></observable-1>`).then((el) => {
|
|
99
99
|
el.value = 100;
|
|
100
100
|
|
|
101
|
-
customElements.
|
|
101
|
+
customElements.whenDefined('observable-1').then(() => {
|
|
102
|
+
el.value++;
|
|
103
|
+
});
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
customElements.define('observable-1', Counter);
|
|
104
106
|
});
|
|
105
107
|
});
|
|
106
108
|
});
|
package/src/lib/observe.ts
CHANGED
|
@@ -1,76 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
(Symbol as any).metadata ??= Symbol('Symbol.metadata');
|
|
3
|
-
|
|
4
|
-
import { EffectFn, MetaData } from './meta.js';
|
|
5
|
-
|
|
6
|
-
const metaData = new MetaData();
|
|
7
|
-
|
|
8
|
-
export interface ObservableCtx {
|
|
9
|
-
metadata: {
|
|
10
|
-
effects?: Set<EffectFn>;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
1
|
+
import { EffectFn, instanceMetadataStore, observableMetadataStore } from './metadata.js';
|
|
13
2
|
|
|
14
3
|
export function observe<This extends object, Value>(
|
|
15
4
|
base: ClassAccessorDecoratorTarget<This, Value>,
|
|
16
|
-
ctx: ClassAccessorDecoratorContext<This, Value>
|
|
5
|
+
ctx: ClassAccessorDecoratorContext<This, Value>
|
|
17
6
|
): ClassAccessorDecoratorResult<This, Value> {
|
|
18
|
-
// handle upgradable values (specifically custom elements)
|
|
19
|
-
ctx.addInitializer(function (this: This) {
|
|
20
|
-
const meta = metaData.read(this);
|
|
21
|
-
|
|
22
|
-
let value: Value | undefined;
|
|
23
|
-
|
|
24
|
-
// attempt to read value.
|
|
25
|
-
try {
|
|
26
|
-
value = ctx.access.get(this);
|
|
27
|
-
} catch {}
|
|
28
|
-
|
|
29
|
-
if (value) {
|
|
30
|
-
// if there is a value, delete it and cache it for init
|
|
31
|
-
delete (<any>this)[ctx.name];
|
|
32
|
-
|
|
33
|
-
meta.upgradable.set(ctx.name, value);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
7
|
return {
|
|
38
8
|
init(value) {
|
|
39
|
-
|
|
9
|
+
let val: Value | null = null;
|
|
40
10
|
|
|
41
|
-
|
|
42
|
-
|
|
11
|
+
// START: Make upgradable custom elements work
|
|
12
|
+
try {
|
|
13
|
+
val = ctx.access.get(this);
|
|
14
|
+
} catch {}
|
|
15
|
+
|
|
16
|
+
if (val) {
|
|
17
|
+
delete (<any>this)[ctx.name];
|
|
18
|
+
|
|
19
|
+
return val;
|
|
43
20
|
}
|
|
21
|
+
// END
|
|
44
22
|
|
|
45
23
|
return value;
|
|
46
24
|
},
|
|
47
25
|
set(value) {
|
|
48
|
-
const
|
|
26
|
+
const instanceMeta = instanceMetadataStore.read(this);
|
|
27
|
+
const observableMeta = observableMetadataStore.read(ctx.metadata);
|
|
49
28
|
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
effect.call(this, meta.changes);
|
|
55
|
-
}
|
|
29
|
+
if (instanceMeta.scheduler === null) {
|
|
30
|
+
instanceMeta.scheduler = Promise.resolve().then(() => {
|
|
31
|
+
for (let effect of observableMeta.effects) {
|
|
32
|
+
effect.call(this, instanceMeta.changes);
|
|
56
33
|
}
|
|
57
34
|
|
|
58
|
-
|
|
59
|
-
|
|
35
|
+
instanceMeta.scheduler = null;
|
|
36
|
+
instanceMeta.changes.clear();
|
|
60
37
|
});
|
|
61
38
|
}
|
|
62
39
|
|
|
63
|
-
|
|
40
|
+
instanceMeta.changes.add(ctx.name);
|
|
64
41
|
|
|
65
42
|
base.set.call(this, value);
|
|
66
43
|
},
|
|
67
44
|
};
|
|
68
45
|
}
|
|
69
46
|
|
|
70
|
-
export function effect<T extends object>(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
)
|
|
74
|
-
ctx.metadata.effects ??= new Set();
|
|
75
|
-
ctx.metadata.effects.add(value);
|
|
47
|
+
export function effect<T extends object>(value: EffectFn, ctx: ClassMethodDecoratorContext<T>) {
|
|
48
|
+
const data = observableMetadataStore.read(ctx.metadata);
|
|
49
|
+
|
|
50
|
+
data.effects.add(value);
|
|
76
51
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { expect } from '@open-wc/testing';
|
|
2
|
+
|
|
3
|
+
import { observe } from './observe.js';
|
|
4
|
+
import { watch } from './watch.js';
|
|
5
|
+
|
|
6
|
+
describe('observable: observe()', () => {
|
|
7
|
+
it('should watch externally from the class', (done) => {
|
|
8
|
+
class Counter {
|
|
9
|
+
@observe static accessor value = 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
watch(Counter, () => {
|
|
13
|
+
expect(Counter.value).to.equal(1);
|
|
14
|
+
|
|
15
|
+
done();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
expect(Counter.value).to.equal(0);
|
|
19
|
+
|
|
20
|
+
Counter.value++;
|
|
21
|
+
|
|
22
|
+
expect(Counter.value).to.equal(1);
|
|
23
|
+
});
|
|
24
|
+
});
|
package/src/lib/watch.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { EffectFn, observableMetadataStore } from './metadata.js';
|
|
2
|
+
|
|
3
|
+
export function watch(value: new () => object, cb: EffectFn) {
|
|
4
|
+
const key = value[Symbol.metadata];
|
|
5
|
+
|
|
6
|
+
if (key) {
|
|
7
|
+
const meta = observableMetadataStore.read(key);
|
|
8
|
+
|
|
9
|
+
meta.effects.add(cb);
|
|
10
|
+
}
|
|
11
|
+
}
|
package/target/lib/meta.d.ts
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
export type EffectFn = (changes: Set<string | symbol>) => void;
|
|
2
|
-
export declare class
|
|
2
|
+
export declare abstract class MetadataStore<T> {
|
|
3
|
+
#private;
|
|
4
|
+
read<T extends object>(value: T): NonNullable<T>;
|
|
5
|
+
abstract init(): T;
|
|
6
|
+
}
|
|
7
|
+
export declare class ObservableInstanceMetadata {
|
|
3
8
|
scheduler: Promise<void> | null;
|
|
4
9
|
upgradable: Map<string | symbol, unknown>;
|
|
5
10
|
changes: Set<string | symbol>;
|
|
6
11
|
}
|
|
7
|
-
export declare class
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
export declare class ObservableInstanceMetaDataStore extends MetadataStore<ObservableInstanceMetadata> {
|
|
13
|
+
init(): ObservableInstanceMetadata;
|
|
14
|
+
}
|
|
15
|
+
export declare class ObservableMetadata {
|
|
16
|
+
effects: Set<EffectFn>;
|
|
17
|
+
}
|
|
18
|
+
export declare class ObservableMetadataStore extends MetadataStore<ObservableMetadata> {
|
|
19
|
+
init(): ObservableMetadata;
|
|
10
20
|
}
|
|
21
|
+
export declare const instanceMetadataStore: ObservableInstanceMetaDataStore;
|
|
22
|
+
export declare const observableMetadataStore: ObservableMetadataStore;
|
package/target/lib/meta.js
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
Symbol.metadata ??= Symbol('Symbol.metadata');
|
|
2
|
+
export class MetadataStore {
|
|
3
|
+
#data = new WeakMap();
|
|
4
|
+
read(value) {
|
|
5
|
+
if (!this.#data.has(value)) {
|
|
6
|
+
this.#data.set(value, this.init());
|
|
7
|
+
}
|
|
8
|
+
return this.#data.get(value);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class ObservableInstanceMetadata {
|
|
2
12
|
scheduler = null;
|
|
3
13
|
upgradable = new Map();
|
|
4
14
|
changes = new Set();
|
|
5
15
|
}
|
|
6
|
-
export class
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
export class ObservableInstanceMetaDataStore extends MetadataStore {
|
|
17
|
+
init() {
|
|
18
|
+
return new ObservableInstanceMetadata();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class ObservableMetadata {
|
|
22
|
+
effects = new Set();
|
|
23
|
+
}
|
|
24
|
+
export class ObservableMetadataStore extends MetadataStore {
|
|
25
|
+
init() {
|
|
26
|
+
return new ObservableMetadata();
|
|
15
27
|
}
|
|
16
28
|
}
|
|
29
|
+
export const instanceMetadataStore = new ObservableInstanceMetaDataStore();
|
|
30
|
+
export const observableMetadataStore = new ObservableMetadataStore();
|
|
17
31
|
//# sourceMappingURL=meta.js.map
|
package/target/lib/meta.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/lib/meta.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/lib/meta.ts"],"names":[],"mappings":"AAAC,MAAc,CAAC,QAAQ,KAAK,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAIvD,MAAM,OAAgB,aAAa;IACjC,KAAK,GAAG,IAAI,OAAO,EAAa,CAAC;IAEjC,IAAI,CAAmB,KAAQ;QAC7B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;IAChC,CAAC;CAGF;AAED,MAAM,OAAO,0BAA0B;IACrC,SAAS,GAAyB,IAAI,CAAC;IACvC,UAAU,GAAG,IAAI,GAAG,EAA4B,CAAC;IACjD,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;CACtC;AAED,MAAM,OAAO,+BAAgC,SAAQ,aAAyC;IAC5F,IAAI;QACF,OAAO,IAAI,0BAA0B,EAAE,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,OAAO,kBAAkB;IAC7B,OAAO,GAAkB,IAAI,GAAG,EAAE,CAAC;CACpC;AAED,MAAM,OAAO,uBAAwB,SAAQ,aAAiC;IAC5E,IAAI;QACF,OAAO,IAAI,kBAAkB,EAAE,CAAC;IAClC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,+BAA+B,EAAE,CAAC;AAC3E,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,uBAAuB,EAAE,CAAC"}
|
package/target/lib/meta.test.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { expect } from '@open-wc/testing';
|
|
2
|
-
import {
|
|
2
|
+
import { ObservableInstanceMetaDataStore } from './meta.js';
|
|
3
3
|
describe('meta:meta', () => {
|
|
4
4
|
it('should return default metadata', () => {
|
|
5
5
|
const key = {};
|
|
6
|
-
const data = new
|
|
6
|
+
const data = new ObservableInstanceMetaDataStore().read(key);
|
|
7
7
|
expect(data).to.deep.equal({
|
|
8
8
|
changes: new Set(),
|
|
9
9
|
upgradable: new Map(),
|
|
@@ -12,7 +12,7 @@ describe('meta:meta', () => {
|
|
|
12
12
|
});
|
|
13
13
|
it('should return the same metadata object after init', () => {
|
|
14
14
|
const key = {};
|
|
15
|
-
const data = new
|
|
15
|
+
const data = new ObservableInstanceMetaDataStore();
|
|
16
16
|
expect(data.read(key)).to.equal(data.read(key));
|
|
17
17
|
});
|
|
18
18
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.test.js","sourceRoot":"","sources":["../../src/lib/meta.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"meta.test.js","sourceRoot":"","sources":["../../src/lib/meta.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,+BAA+B,EAAE,MAAM,WAAW,CAAC;AAE5D,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,GAAG,GAAG,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,+BAA+B,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE7D,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;YACzB,OAAO,EAAE,IAAI,GAAG,EAAE;YAClB,UAAU,EAAE,IAAI,GAAG,EAAE;YACrB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,GAAG,GAAG,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,+BAA+B,EAAE,CAAC;QAEnD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/target/lib/observe.d.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
1
|
import { EffectFn } from './meta.js';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
effects?: Set<EffectFn>;
|
|
5
|
-
};
|
|
6
|
-
}
|
|
7
|
-
export declare function observe<This extends object, Value>(base: ClassAccessorDecoratorTarget<This, Value>, ctx: ClassAccessorDecoratorContext<This, Value> & ObservableCtx): ClassAccessorDecoratorResult<This, Value>;
|
|
8
|
-
export declare function effect<T extends object>(value: EffectFn, ctx: ClassMethodDecoratorContext<T> & ObservableCtx): void;
|
|
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, ctx: ClassMethodDecoratorContext<T>): void;
|
package/target/lib/observe.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import { MetaData } from './meta.js';
|
|
3
|
-
const metaData = new MetaData();
|
|
1
|
+
import { instanceMetadataStore, observableMetadataStore } from './meta.js';
|
|
4
2
|
export function observe(base, ctx) {
|
|
5
3
|
ctx.addInitializer(function () {
|
|
6
|
-
const
|
|
4
|
+
const instanceMeta = instanceMetadataStore.read(this);
|
|
7
5
|
let value;
|
|
8
6
|
try {
|
|
9
7
|
value = ctx.access.get(this);
|
|
@@ -11,37 +9,36 @@ export function observe(base, ctx) {
|
|
|
11
9
|
catch { }
|
|
12
10
|
if (value) {
|
|
13
11
|
delete this[ctx.name];
|
|
14
|
-
|
|
12
|
+
instanceMeta.upgradable.set(ctx.name, value);
|
|
15
13
|
}
|
|
16
14
|
});
|
|
17
15
|
return {
|
|
18
16
|
init(value) {
|
|
19
|
-
const
|
|
20
|
-
if (
|
|
21
|
-
return
|
|
17
|
+
const instanceMeta = instanceMetadataStore.read(this);
|
|
18
|
+
if (instanceMeta.upgradable.has(ctx.name)) {
|
|
19
|
+
return instanceMeta.upgradable.get(ctx.name);
|
|
22
20
|
}
|
|
23
21
|
return value;
|
|
24
22
|
},
|
|
25
23
|
set(value) {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
24
|
+
const instanceMeta = instanceMetadataStore.read(this);
|
|
25
|
+
const observableMeta = observableMetadataStore.read(ctx.metadata);
|
|
26
|
+
if (instanceMeta.scheduler === null) {
|
|
27
|
+
instanceMeta.scheduler = Promise.resolve().then(() => {
|
|
28
|
+
for (let effect of observableMeta.effects) {
|
|
29
|
+
effect.call(this, instanceMeta.changes);
|
|
33
30
|
}
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
instanceMeta.scheduler = null;
|
|
32
|
+
instanceMeta.changes.clear();
|
|
36
33
|
});
|
|
37
34
|
}
|
|
38
|
-
|
|
35
|
+
instanceMeta.changes.add(ctx.name);
|
|
39
36
|
base.set.call(this, value);
|
|
40
37
|
},
|
|
41
38
|
};
|
|
42
39
|
}
|
|
43
40
|
export function effect(value, ctx) {
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
const data = observableMetadataStore.read(ctx.metadata);
|
|
42
|
+
data.effects.add(value);
|
|
46
43
|
}
|
|
47
44
|
//# sourceMappingURL=observe.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../../src/lib/observe.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../../src/lib/observe.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAErF,MAAM,UAAU,OAAO,CACrB,IAA+C,EAC/C,GAA+C;IAG/C,GAAG,CAAC,cAAc,CAAC;QACjB,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtD,IAAI,KAAwB,CAAC;QAG7B,IAAI,CAAC;YACH,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,IAAI,KAAK,EAAE,CAAC;YAEV,OAAa,IAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE7B,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,CAAC,KAAK;YACR,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEtD,IAAI,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1C,OAAO,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAU,CAAC;YACxD,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;QACD,GAAG,CAAC,KAAK;YACP,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtD,MAAM,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAElE,IAAI,YAAY,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;gBACpC,YAAY,CAAC,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;oBACnD,KAAK,IAAI,MAAM,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;wBAC1C,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;oBAC1C,CAAC;oBAED,YAAY,CAAC,SAAS,GAAG,IAAI,CAAC;oBAC9B,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC/B,CAAC,CAAC,CAAC;YACL,CAAC;YAED,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAEnC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM,CAAmB,KAAe,EAAE,GAAmC;IAC3F,MAAM,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAExD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -81,11 +81,14 @@ describe('observable: observe()', () => {
|
|
|
81
81
|
set value(value) { this.#value_accessor_storage = value; }
|
|
82
82
|
onChange(changes) {
|
|
83
83
|
expect(changes.has('value')).to.be.true;
|
|
84
|
+
console.log('####################', this.value);
|
|
84
85
|
done();
|
|
85
86
|
}
|
|
86
87
|
};
|
|
87
88
|
})();
|
|
88
89
|
const counter = new Counter();
|
|
90
|
+
const counter2 = new Counter();
|
|
91
|
+
console.log(counter2);
|
|
89
92
|
counter.value++;
|
|
90
93
|
});
|
|
91
94
|
it('should work as an even emitter', (done) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe.test.js","sourceRoot":"","sources":["../../src/lib/observe.test.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE/C,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,mCAAmC,EAAE,CAAC,IAAI,EAAE,EAAE;YACzC,OAAO;;;;;yBAAP,OAAO;;;gDACV,OAAO;wDAEP,MAAM;oBAFE,0KAAgB,KAAK,6BAAL,KAAK,4FAAK;oBAE3B,gMAAO,aAAa,2DAI3B;;oBAPG,kDAAO;;gBACF,MAAM,+EAAkB,CAAC,EAAC;gBAA1B,MAAM,KAAU,KAAK,YAD1B,OAAO,2BACwB;gBAA1B,WAAgB,KAAK,UAD1B,OAAO,mCACwB;gBAE3B,MAAM,CAAC,aAAa;oBAC1B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAElC,IAAI,EAAE,CAAC;gBACT,CAAC;;;QAGH,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAElC,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,CAAC,IAAI,EAAE,EAAE;YAC3C,OAAO;;;;;;yBAAP,OAAO;;;yCACV,OAAO;oDAIP,MAAM;oBAJE,oKAAS,KAAK,6BAAL,KAAK,uFAAK;oBAIpB,oDAAA,yBAAA;4BACN,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;4BAE/B,IAAI,EAAE,CAAC;wBACT,CAAC,cAAA,2HAJO,SAAS,yBAAT,SAAS,6DAIhB;;;gBARQ,6HAAiB,CAAC,GAAC;gBAAnB,IAAS,KAAK,2CAAK;gBAAnB,IAAS,KAAK,iDAAK;gBAIpB,IAAA,SAAS,iDAIhB;;;QAGH,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAE9B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAElC,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,CAAC,IAAI,EAAE,EAAE;YAC5C,OAAO;;;;;yBAAP,OAAO;;;yCACV,OAAO;4CAEP,MAAM;oBAFE,oKAAS,KAAK,6BAAL,KAAK,uFAAK;oBAEpB,2KAAA,QAAQ,
|
|
1
|
+
{"version":3,"file":"observe.test.js","sourceRoot":"","sources":["../../src/lib/observe.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/lib/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAE9D,MAAM,UAAU,KAAK,CAAC,KAAuB,EAAE,EAAY;IACzD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEnC,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE/C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { __esDecorate, __runInitializers } from "tslib";
|
|
2
|
+
import { expect } from '@open-wc/testing';
|
|
3
|
+
import { observe } from './observe.js';
|
|
4
|
+
import { watch } from './watch.js';
|
|
5
|
+
describe('observable: observe()', () => {
|
|
6
|
+
it('should watch externally from the class', (done) => {
|
|
7
|
+
let Counter = (() => {
|
|
8
|
+
let _staticExtraInitializers = [];
|
|
9
|
+
let _static_value_decorators;
|
|
10
|
+
let _static_value_initializers = [];
|
|
11
|
+
return class Counter {
|
|
12
|
+
static {
|
|
13
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
14
|
+
_static_value_decorators = [observe];
|
|
15
|
+
__esDecorate(this, null, _static_value_decorators, { kind: "accessor", name: "value", static: true, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _static_value_initializers, _staticExtraInitializers);
|
|
16
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
17
|
+
__runInitializers(this, _staticExtraInitializers);
|
|
18
|
+
}
|
|
19
|
+
static #value_accessor_storage = __runInitializers(this, _static_value_initializers, 0);
|
|
20
|
+
static get value() { return Counter.#value_accessor_storage; }
|
|
21
|
+
static set value(value) { Counter.#value_accessor_storage = value; }
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
watch(Counter, () => {
|
|
25
|
+
expect(Counter.value).to.equal(1);
|
|
26
|
+
done();
|
|
27
|
+
});
|
|
28
|
+
expect(Counter.value).to.equal(0);
|
|
29
|
+
Counter.value++;
|
|
30
|
+
expect(Counter.value).to.equal(1);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=watch.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.test.js","sourceRoot":"","sources":["../../src/lib/watch.test.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,wCAAwC,EAAE,CAAC,IAAI,EAAE,EAAE;YAC9C,OAAO;;;;yBAAP,OAAO;;;gDACV,OAAO;oBAAC,0KAAgB,KAAK,6BAAL,KAAK,4FAAK;;oBAD/B,kDAAO;;gBACF,MAAM,+EAAkB,CAAC,EAAC;gBAA1B,MAAM,KAAU,KAAK,YAD1B,OAAO,2BACwB;gBAA1B,WAAgB,KAAK,UAD1B,OAAO,mCACwB;;;QAGrC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAElC,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAElC,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/src/lib/meta.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export type EffectFn = (changes: Set<string | symbol>) => void;
|
|
2
|
-
|
|
3
|
-
export class ObservableMetaData {
|
|
4
|
-
scheduler: Promise<void> | null = null;
|
|
5
|
-
upgradable = new Map<string | symbol, unknown>();
|
|
6
|
-
changes = new Set<string | symbol>();
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export class MetaData {
|
|
10
|
-
#data = new WeakMap<object, ObservableMetaData>();
|
|
11
|
-
|
|
12
|
-
read<T extends object>(value: T) {
|
|
13
|
-
if (this.#data.has(value)) {
|
|
14
|
-
return this.#data.get(value) as ObservableMetaData;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const data = new ObservableMetaData();
|
|
18
|
-
|
|
19
|
-
this.#data.set(value, data);
|
|
20
|
-
|
|
21
|
-
return data;
|
|
22
|
-
}
|
|
23
|
-
}
|