@joist/observable 2.0.0-alpha.13 → 2.0.0-alpha.16

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 CHANGED
@@ -96,6 +96,6 @@ class TestElement extends HTMLElement {
96
96
  read: (val: string) => new Date(val),
97
97
  write: (val: Date) => val.toString()
98
98
  })
99
- count: number = 0;
99
+ count: Date = 0;
100
100
  }
101
101
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joist/observable",
3
- "version": "2.0.0-alpha.13",
3
+ "version": "2.0.0-alpha.16",
4
4
  "main": "./target/build/lib.js",
5
5
  "module": "./target/build/lib.js",
6
6
  "exports": {
@@ -34,5 +34,5 @@
34
34
  "test": "tsc -p tsconfig.test.json && wtr --config ../../wtr.config.mjs --port 8002",
35
35
  "build": "tsc -p tsconfig.build.json"
36
36
  },
37
- "gitHead": "e9d8689c31099c04f23e0511270f45eca6ae4cea"
37
+ "gitHead": "4bf8cd9a23400b1a2d6c95fe5b9b5f5ae3c3b072"
38
38
  }
@@ -0,0 +1,6 @@
1
+ export interface AttributeParser<T> {
2
+ read(val: string): T;
3
+ write(val: T): string;
4
+ }
5
+ export declare type AttributeParsers = Record<string, AttributeParser<unknown>>;
6
+ export declare function defaultParser(): AttributeParser<boolean | string>;
@@ -0,0 +1,12 @@
1
+ export function defaultParser() {
2
+ return {
3
+ read(val) {
4
+ // if a boolean assume such
5
+ if (val === 'true' || val === 'false') {
6
+ return val === 'true';
7
+ }
8
+ return val;
9
+ },
10
+ write: String,
11
+ };
12
+ }
@@ -1,8 +1,5 @@
1
+ import { AttributeParser } from './attribute-parsers';
1
2
  export declare function getObservableAttributes(c: typeof HTMLElement): Array<string>;
2
- export declare function getAttributeParsers<T extends typeof HTMLElement>(c: T): Record<string, AttributeParser>;
3
- export interface AttributeParser {
4
- read(val: string): any;
5
- write(val: unknown): string;
6
- }
7
- export declare function attr<T extends HTMLElement>(p: Partial<AttributeParser>): (t: T, key: string) => void;
3
+ export declare function getAttributeParsers<T extends typeof HTMLElement>(c: T): Record<string, AttributeParser<unknown>>;
4
+ export declare function attr<T extends HTMLElement>(p: Partial<AttributeParser<unknown>>): (t: T, key: string) => void;
8
5
  export declare function attr<T extends HTMLElement>(t: T, key: string): void;
@@ -1,13 +1,7 @@
1
+ import { defaultParser } from './attribute-parsers';
1
2
  export function getObservableAttributes(c) {
2
3
  return Reflect.get(c, 'observedAttributes') || [];
3
4
  }
4
- function defaultRead(val) {
5
- // if a boolean assume such
6
- if (val === 'true' || val === 'false') {
7
- return val === 'true';
8
- }
9
- return val;
10
- }
11
5
  export function getAttributeParsers(c) {
12
6
  const parsers = Reflect.get(c, 'attributeParsers') || {};
13
7
  return parsers;
@@ -36,12 +30,10 @@ function defineAttribute(target, key) {
36
30
  }
37
31
  const attributeParsers = Reflect.get(target.constructor, 'attributeParsers');
38
32
  if (attributeParsers) {
39
- attributeParsers[key] = { read: defaultRead, write: String };
33
+ attributeParsers[key] = defaultParser();
40
34
  }
41
35
  else {
42
- const attributeParsers = {};
43
- attributeParsers[key] = { read: defaultRead, write: String };
44
- Reflect.set(target.constructor, 'attributeParsers', attributeParsers);
36
+ Reflect.set(target.constructor, 'attributeParsers', { [key]: defaultParser() });
45
37
  }
46
38
  return void 0;
47
39
  }
@@ -32,24 +32,21 @@ export function observable(Base) {
32
32
  Object.defineProperties(this, descriptors);
33
33
  }
34
34
  connectedCallback() {
35
- attributes.forEach((key) => {
36
- const { write } = parsers[key];
37
- const val = this.getAttribute(key);
38
- if (val === null) {
35
+ for (let i = 0; i < attributes.length; i++) {
36
+ const key = attributes[i];
37
+ if (this.getAttribute(key) === null) {
39
38
  const propVal = Reflect.get(this, key);
40
- const parsedVal = write(propVal);
41
- if (propVal !== undefined && propVal !== null && propVal !== '' && val !== parsedVal) {
42
- this.setAttribute(key, parsedVal);
39
+ if (propVal !== undefined && propVal !== null && propVal !== '') {
40
+ this.setAttribute(key, parsers[key].write(propVal));
43
41
  }
44
42
  }
45
- });
43
+ }
46
44
  if (super.connectedCallback) {
47
45
  super.connectedCallback();
48
46
  }
49
47
  }
50
48
  attributeChangedCallback(name, oldVal, newVal) {
51
- const { read } = parsers[name];
52
- Reflect.set(this, name, read(newVal));
49
+ Reflect.set(this, name, parsers[name].read(newVal));
53
50
  if (super.attributeChangedCallback) {
54
51
  super.attributeChangedCallback(name, oldVal, newVal);
55
52
  }
@@ -58,10 +55,9 @@ export function observable(Base) {
58
55
  if (this instanceof HTMLElement) {
59
56
  for (let change in changes) {
60
57
  if (attributes.includes(change)) {
61
- const { write } = parsers[change];
62
- const value = write(changes[change].value);
58
+ const value = parsers[change].write(changes[change].value);
63
59
  if (value !== this.getAttribute(change)) {
64
- this.setAttribute(change, write(changes[change].value));
60
+ this.setAttribute(change, value);
65
61
  }
66
62
  }
67
63
  }
@@ -104,17 +100,19 @@ function definePropChange(key, propChange) {
104
100
  // If there is no previous change defined set it up
105
101
  this.propChange = Promise.resolve().then(() => {
106
102
  // run onPropChanges here. This makes sure we capture all changes
107
- // keep track of whether or not this is the first time a given property has changes
103
+ const changes = {};
104
+ // Copy changes and keep track of whether or not this is the first time a given property has changes
108
105
  for (let change in this.propChanges) {
109
- this.propChanges[change].firstChange = !this.initializedChanges.has(change);
106
+ changes[change] = this.propChanges[change];
107
+ changes[change].firstChange = !this.initializedChanges.has(change);
110
108
  this.initializedChanges.add(change);
111
109
  }
110
+ // clear out before calling to account for changes made INSIDE of the onPropertyChanged callback
111
+ this.propChange = null;
112
+ this.propChanges = {};
112
113
  if (this.onPropertyChanged) {
113
- this.onPropertyChanged(this.propChanges);
114
+ this.onPropertyChanged(changes);
114
115
  }
115
- // reset for next time
116
- this.propChanges = {};
117
- this.propChange = null;
118
116
  });
119
117
  }
120
118
  return this.propChange;