@joist/element 4.0.0-next.4 → 4.0.0-next.41

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.
Files changed (71) hide show
  1. package/README.md +102 -15
  2. package/package.json +7 -9
  3. package/src/lib/attr-changed.test.ts +34 -0
  4. package/src/lib/attr-changed.ts +15 -0
  5. package/src/lib/attr.test.ts +159 -97
  6. package/src/lib/attr.ts +26 -33
  7. package/src/lib/element.test.ts +95 -71
  8. package/src/lib/element.ts +107 -51
  9. package/src/lib/lifecycle.test.ts +31 -0
  10. package/src/lib/lifecycle.ts +9 -0
  11. package/src/lib/listen.test.ts +104 -0
  12. package/src/lib/listen.ts +27 -7
  13. package/src/lib/metadata.ts +21 -8
  14. package/src/lib/query.test.ts +21 -47
  15. package/src/lib/query.ts +2 -8
  16. package/src/lib/result.ts +1 -21
  17. package/src/lib/tags.ts +27 -12
  18. package/src/lib/template.test.ts +123 -0
  19. package/src/lib/template.ts +118 -0
  20. package/src/lib.ts +3 -2
  21. package/target/lib/attr-changed.d.ts +1 -0
  22. package/target/lib/attr-changed.js +10 -0
  23. package/target/lib/attr-changed.js.map +1 -0
  24. package/target/lib/attr-changed.test.d.ts +1 -0
  25. package/target/lib/attr-changed.test.js +54 -0
  26. package/target/lib/attr-changed.test.js.map +1 -0
  27. package/target/lib/attr.d.ts +3 -1
  28. package/target/lib/attr.js +23 -25
  29. package/target/lib/attr.js.map +1 -1
  30. package/target/lib/attr.test.js +373 -251
  31. package/target/lib/attr.test.js.map +1 -1
  32. package/target/lib/element.d.ts +8 -339
  33. package/target/lib/element.js +81 -39
  34. package/target/lib/element.js.map +1 -1
  35. package/target/lib/element.test.js +154 -178
  36. package/target/lib/element.test.js.map +1 -1
  37. package/target/lib/lifecycle.d.ts +1 -0
  38. package/target/lib/lifecycle.js +8 -0
  39. package/target/lib/lifecycle.js.map +1 -0
  40. package/target/lib/lifecycle.test.d.ts +1 -0
  41. package/target/lib/lifecycle.test.js +48 -0
  42. package/target/lib/lifecycle.test.js.map +1 -0
  43. package/target/lib/listen.d.ts +2 -2
  44. package/target/lib/listen.js +18 -3
  45. package/target/lib/listen.js.map +1 -1
  46. package/target/lib/listen.test.d.ts +1 -0
  47. package/target/lib/listen.test.js +167 -0
  48. package/target/lib/listen.test.js.map +1 -0
  49. package/target/lib/metadata.d.ts +20 -10
  50. package/target/lib/metadata.js +8 -2
  51. package/target/lib/metadata.js.map +1 -1
  52. package/target/lib/query.d.ts +1 -1
  53. package/target/lib/query.js +1 -6
  54. package/target/lib/query.js.map +1 -1
  55. package/target/lib/query.test.js +35 -74
  56. package/target/lib/query.test.js.map +1 -1
  57. package/target/lib/result.d.ts +1 -8
  58. package/target/lib/result.js +1 -14
  59. package/target/lib/result.js.map +1 -1
  60. package/target/lib/tags.d.ts +10 -6
  61. package/target/lib/tags.js +20 -11
  62. package/target/lib/tags.js.map +1 -1
  63. package/target/lib/template.d.ts +11 -0
  64. package/target/lib/template.js +87 -0
  65. package/target/lib/template.js.map +1 -0
  66. package/target/lib/template.test.d.ts +1 -0
  67. package/target/lib/template.test.js +91 -0
  68. package/target/lib/template.test.js.map +1 -0
  69. package/target/lib.d.ts +3 -2
  70. package/target/lib.js +3 -2
  71. package/target/lib.js.map +1 -1
@@ -1,93 +1,117 @@
1
- import { expect, fixture, html as litHtml } from '@open-wc/testing';
1
+ import { expect, assert } from 'chai';
2
2
 
3
3
  import { attr } from './attr.js';
4
4
  import { element } from './element.js';
5
5
  import { css, html } from './tags.js';
6
6
 
7
- describe('@element()', () => {
8
- it('should write default value to attribute', async () => {
9
- @element({
10
- tagName: 'element-1'
11
- })
12
- class MyElement extends HTMLElement {
13
- @attr()
14
- accessor value1 = 'hello'; // no attribute
7
+ it('should write default value to attribute', async () => {
8
+ @element({
9
+ tagName: 'element-1'
10
+ })
11
+ class MyElement extends HTMLElement {
12
+ @attr()
13
+ accessor value1 = 'hello'; // no attribute
15
14
 
16
- @attr()
17
- accessor value2 = 0; // number
15
+ @attr()
16
+ accessor value2 = 0; // number
18
17
 
19
- @attr()
20
- accessor value3 = true; // boolean
21
- }
18
+ @attr()
19
+ accessor value3 = true; // boolean
22
20
 
23
- const el = await fixture<MyElement>(litHtml`<element-1></element-1>`);
21
+ @attr({ reflect: false })
22
+ accessor value4 = 'foo';
23
+ }
24
24
 
25
- expect(el.getAttribute('value1')).to.equal('hello');
26
- expect(el.getAttribute('value2')).to.equal('0');
27
- expect(el.getAttribute('value3')).to.equal('');
28
- });
25
+ const el = new MyElement();
29
26
 
30
- it('should register attributes', async () => {
31
- @element({
32
- tagName: 'element-2'
33
- })
34
- class MyElement extends HTMLElement {
35
- @attr()
36
- accessor value1 = 'hello'; // no attribute
27
+ document.body.append(el);
37
28
 
38
- @attr()
39
- accessor value2 = 0; // number
29
+ expect(el.getAttribute('value1')).to.equal('hello');
30
+ expect(el.getAttribute('value2')).to.equal('0');
31
+ expect(el.getAttribute('value3')).to.equal('');
32
+ expect(el.getAttribute('value4')).to.equal(null);
40
33
 
41
- @attr()
42
- accessor value3 = true; // boolean
34
+ el.remove();
35
+ });
43
36
 
44
- @attr({ observe: false }) // should be filtered out
45
- accessor value4 = 'hello world';
46
- }
37
+ // TODO: Figure out test
38
+ // it('should register attributes', async () => {
39
+ // @element({
40
+ // tagName: 'element-2'
41
+ // })
42
+ // class MyElement extends HTMLElement {
43
+ // @attr()
44
+ // accessor value1 = 'hello'; // no attribute
45
+
46
+ // @attr()
47
+ // accessor value2 = 0; // number
48
+
49
+ // @attr()
50
+ // accessor value3 = true; // boolean
51
+
52
+ // @attr({ observed: false }) // should be filtered out
53
+ // accessor value4 = 'hello world';
54
+ // }
55
+
56
+ // expect(Reflect.get(MyElement, 'observedAttributes')).to.deep.equal([
57
+ // 'value1',
58
+ // 'value2',
59
+ // 'value3'
60
+ // ]);
61
+ // });
62
+
63
+ it('should attach shadow root when the shadow property exists', async () => {
64
+ @element({
65
+ tagName: 'element-3',
66
+ shadowDom: []
67
+ })
68
+ class MyElement extends HTMLElement {}
69
+
70
+ const el = new MyElement();
71
+
72
+ expect(el.shadowRoot).to.be.instanceOf(ShadowRoot);
73
+ });
47
74
 
48
- expect(Reflect.get(MyElement, 'observedAttributes')).to.deep.equal([
49
- 'value1',
50
- 'value2',
51
- 'value3'
52
- ]);
53
- });
54
-
55
- it('should attach shadow root when the shadow property exists', async () => {
56
- @element({
57
- tagName: 'element-3',
58
- shadow: []
59
- })
60
- class MyElement extends HTMLElement {}
61
-
62
- const el = new MyElement();
63
-
64
- expect(el.shadowRoot).to.be.instanceOf(ShadowRoot);
65
- });
66
-
67
- it('should apply html and css', async () => {
68
- @element({
69
- tagName: 'element-4',
70
- shadow: [
71
- css`
72
- :host {
73
- display: contents;
74
- }
75
- `,
76
- html`<slot></slot>`,
77
- (el) => {
75
+ it('should apply html and css', async () => {
76
+ @element({
77
+ tagName: 'element-4',
78
+ shadowDom: [
79
+ css`
80
+ :host {
81
+ display: contents;
82
+ }
83
+ `,
84
+ html`<slot></slot>`,
85
+ {
86
+ apply(el) {
78
87
  const div = document.createElement('div');
79
88
  div.innerHTML = 'hello world';
80
89
 
81
90
  el.append(div);
82
91
  }
83
- ]
84
- })
85
- class MyElement extends HTMLElement {}
92
+ }
93
+ ]
94
+ })
95
+ class MyElement extends HTMLElement {}
96
+
97
+ const el = new MyElement();
98
+
99
+ expect(el.shadowRoot!.adoptedStyleSheets.length).to.equal(1);
100
+ expect(el.shadowRoot!.innerHTML).to.equal(`<slot></slot>`);
101
+ expect(el.innerHTML).to.equal(`<div>hello world</div>`);
102
+ });
103
+
104
+ it('should the correct shadow dom mode', async () => {
105
+ @element({
106
+ tagName: 'element-5',
107
+ shadowDom: [],
108
+ shadowDomOpts: {
109
+ mode: 'closed'
110
+ }
111
+ })
112
+ class MyElement extends HTMLElement {}
86
113
 
87
- const el = new MyElement();
114
+ const el = new MyElement();
88
115
 
89
- expect(el.shadowRoot!.adoptedStyleSheets.length).to.equal(1);
90
- expect(el.shadowRoot!.innerHTML).to.equal(`<slot></slot>`);
91
- expect(el.innerHTML).to.equal(`<div>hello world</div>`);
92
- });
116
+ assert.equal(el.shadowRoot, null);
93
117
  });
@@ -1,23 +1,21 @@
1
- import { AttrDef, metadataStore } from './metadata.js';
1
+ import { AttrMetadata, metadataStore } from './metadata.js';
2
2
  import { ShadowResult } from './result.js';
3
3
 
4
- export interface ElementOpts<T> {
4
+ export interface ElementOpts {
5
5
  tagName?: string;
6
- shadow?: Array<ShadowResult | ((el: T) => void)>;
6
+ shadowDom?: ShadowResult[];
7
+ shadowDomOpts?: ShadowRootInit;
7
8
  }
8
9
 
9
- export const LifeCycle = {
10
- onInit: Symbol('onInit')
11
- };
10
+ interface ElementConstructor {
11
+ new (...args: any[]): HTMLElement;
12
+ }
12
13
 
13
- export function element<
14
- Target extends CustomElementConstructor,
15
- Instance extends InstanceType<Target>
16
- >(opts?: ElementOpts<Instance>) {
17
- return function elementDecorator(Base: Target, ctx: ClassDecoratorContext<Target>) {
14
+ export function element<T extends ElementConstructor>(opts?: ElementOpts) {
15
+ return function elementDecorator(Base: T, ctx: ClassDecoratorContext<T>): T {
18
16
  const meta = metadataStore.read(ctx.metadata);
19
17
 
20
- ctx.addInitializer(function (this: Target) {
18
+ ctx.addInitializer(function () {
21
19
  if (opts?.tagName) {
22
20
  if (!customElements.get(opts.tagName)) {
23
21
  customElements.define(opts.tagName, this);
@@ -25,68 +23,126 @@ export function element<
25
23
  }
26
24
  });
27
25
 
28
- return class JoistElement extends Base {
29
- static observedAttributes = meta.attrs
30
- .filter(({ observe }) => observe) // filter out attributes that are not to be observed
31
- .map(({ attrName }) => attrName);
26
+ const def = {
27
+ [Base.name]: class extends Base {
28
+ static observedAttributes: string[] = Array.from(meta.attrs.keys());
32
29
 
33
- constructor(...args: any[]) {
34
- super(...args);
30
+ #removeListeners: Set<Function> = new Set();
35
31
 
36
- if (opts?.shadow) {
37
- if (!this.shadowRoot) {
38
- this.attachShadow({ mode: 'open' });
39
- }
32
+ constructor(...args: any[]) {
33
+ super(...args);
34
+
35
+ if (opts?.shadowDom) {
36
+ if (!this.shadowRoot) {
37
+ this.attachShadow(opts.shadowDomOpts ?? { mode: 'open' });
38
+ }
40
39
 
41
- for (let res of opts.shadow) {
42
- if (typeof res === 'function') {
43
- res(this as unknown as Instance);
44
- } else {
45
- res.run(this);
40
+ for (let res of opts.shadowDom) {
41
+ res.apply(this);
46
42
  }
47
43
  }
44
+
45
+ for (let cb of meta.onReady) {
46
+ cb.call(this);
47
+ }
48
48
  }
49
49
 
50
- for (let [event, { cb, root }] of meta.listeners) {
51
- root(this).addEventListener(event, cb.bind(this));
50
+ attributeChangedCallback(name: string, oldValue: string, newValue: string) {
51
+ const attr = meta.attrs.get(name);
52
+ const cbs = meta.attrChanges.get(name);
53
+
54
+ if (attr) {
55
+ if (oldValue !== newValue) {
56
+ const ogValue = attr.getPropValue.call(this);
57
+
58
+ if (newValue === '') {
59
+ // treat as boolean
60
+ attr.setPropValue.call(this, true);
61
+ } else if (typeof ogValue === 'number') {
62
+ // treat as number
63
+ attr.setPropValue.call(this, Number(newValue));
64
+ } else {
65
+ // treat as string
66
+ attr.setPropValue.call(this, newValue);
67
+ }
68
+ }
69
+
70
+ if (cbs) {
71
+ for (let cb of cbs) {
72
+ cb.call(this, oldValue, newValue);
73
+ }
74
+ }
75
+
76
+ if (super.attributeChangedCallback) {
77
+ super.attributeChangedCallback(name, oldValue, newValue);
78
+ }
79
+ }
52
80
  }
53
81
 
54
- if (LifeCycle.onInit in this) {
55
- const onInit = Reflect.get(this, LifeCycle.onInit);
82
+ connectedCallback() {
83
+ if (this.isConnected) {
84
+ for (let { event, cb, selector } of meta.listeners) {
85
+ const root = selector(this);
56
86
 
57
- if (typeof onInit === 'function') {
58
- onInit();
87
+ if (root) {
88
+ const thisCb = cb.bind(this);
89
+
90
+ root.addEventListener(event, thisCb);
91
+
92
+ this.#removeListeners.add(() => {
93
+ root.removeEventListener(event, thisCb);
94
+ });
95
+ } else {
96
+ throw new Error(`could not add listener to ${root}`);
97
+ }
98
+ }
99
+
100
+ reflectAttributeValues(this, meta.attrs);
101
+
102
+ if (super.connectedCallback) {
103
+ super.connectedCallback();
104
+ }
59
105
  }
60
106
  }
61
- }
62
107
 
63
- connectedCallback() {
64
- if (this.isConnected) {
65
- reflectAttributeValues(this, meta.attrs);
108
+ disconnectedCallback(): void {
109
+ for (let remove of this.#removeListeners) {
110
+ remove();
111
+ }
66
112
 
67
- if (super.connectedCallback) {
68
- super.connectedCallback();
113
+ if (super.disconnectedCallback) {
114
+ super.disconnectedCallback();
69
115
  }
70
116
  }
71
117
  }
72
118
  };
119
+
120
+ return def[Base.name];
73
121
  };
74
122
  }
75
123
 
76
- function reflectAttributeValues(el: HTMLElement, attrs: AttrDef[]) {
77
- for (let { propName, attrName } of attrs) {
78
- const value = Reflect.get(el, propName);
124
+ function reflectAttributeValues<T extends HTMLElement>(el: T, attrs: AttrMetadata) {
125
+ for (let [attrName, { getPropValue, reflect }] of attrs) {
126
+ if (reflect) {
127
+ const value = getPropValue.call(el);
128
+
129
+ // reflect values back to attributes
130
+ if (value !== null && value !== undefined && value !== '') {
131
+ if (typeof value === 'boolean') {
132
+ if (value === true) {
133
+ // set boolean attribute
134
+ if (!el.hasAttribute(attrName)) {
135
+ el.setAttribute(attrName, '');
136
+ }
137
+ }
138
+ } else {
139
+ // set key/value attribute
140
+ const strValue = String(value);
79
141
 
80
- // reflect values back to attributes
81
- if (value !== null && value !== undefined && value !== '') {
82
- if (typeof value === 'boolean') {
83
- if (value === true) {
84
- // set boolean attribute
85
- el.setAttribute(attrName, '');
142
+ if (el.getAttribute(attrName) !== strValue) {
143
+ el.setAttribute(attrName, strValue);
144
+ }
86
145
  }
87
- } else {
88
- // set key/value attribute
89
- el.setAttribute(attrName, String(value));
90
146
  }
91
147
  }
92
148
  }
@@ -0,0 +1,31 @@
1
+ import { assert } from 'chai';
2
+ import { element } from './element.js';
3
+ import { ready } from './lifecycle.js';
4
+
5
+ it('should call all callbacks when template is ready', () => {
6
+ @element({
7
+ tagName: 'template-ready-1'
8
+ })
9
+ class MyElement extends HTMLElement {
10
+ callCount: Record<string, number> = {};
11
+
12
+ @ready()
13
+ onTemplateReady1() {
14
+ this.callCount['onTemplateReady1'] ??= 0;
15
+ this.callCount['onTemplateReady1']++;
16
+ }
17
+
18
+ @ready()
19
+ onTemplateReady2() {
20
+ this.callCount['onTemplateReady2'] ??= 0;
21
+ this.callCount['onTemplateReady2']++;
22
+ }
23
+ }
24
+
25
+ const el = new MyElement();
26
+
27
+ assert.deepEqual(el.callCount, {
28
+ onTemplateReady1: 1,
29
+ onTemplateReady2: 1
30
+ });
31
+ });
@@ -0,0 +1,9 @@
1
+ import { metadataStore } from './metadata.js';
2
+
3
+ export function ready() {
4
+ return function readyDecorator(val: Function, ctx: ClassMethodDecoratorContext): void {
5
+ const metadata = metadataStore.read(ctx.metadata);
6
+
7
+ metadata.onReady.add(val);
8
+ };
9
+ }
@@ -0,0 +1,104 @@
1
+ import { assert } from 'chai';
2
+
3
+ import { element } from './element.js';
4
+ import { listen } from './listen.js';
5
+
6
+ describe('@listen()', () => {
7
+ it('should add listener to an outer HTMLElement', (done) => {
8
+ @element({
9
+ tagName: 'listener-1'
10
+ })
11
+ class MyElement extends HTMLElement {
12
+ @listen('click')
13
+ onClick(e: Event) {
14
+ assert.equal(e.type, 'click');
15
+
16
+ done();
17
+ }
18
+ }
19
+
20
+ const el = new MyElement();
21
+
22
+ document.body.append(el);
23
+
24
+ el.dispatchEvent(new Event('click'));
25
+
26
+ el.remove();
27
+ });
28
+
29
+ it('should add listener to the shadow root if available', (done) => {
30
+ @element({
31
+ tagName: 'listener-2',
32
+ shadowDom: []
33
+ })
34
+ class MyElement extends HTMLElement {
35
+ @listen('click')
36
+ onClick(e: Event) {
37
+ assert.equal(e.type, 'click');
38
+
39
+ done();
40
+ }
41
+ }
42
+
43
+ const el = new MyElement();
44
+
45
+ document.body.append(el);
46
+
47
+ el.shadowRoot!.dispatchEvent(new Event('click'));
48
+
49
+ el.remove();
50
+ });
51
+
52
+ it('should restrict argument to an event or an event subtype', (done) => {
53
+ class CustomEvent extends Event {
54
+ test = 'Hello World';
55
+
56
+ constructor() {
57
+ super('customevent');
58
+ }
59
+ }
60
+
61
+ @element({
62
+ tagName: 'listener-3'
63
+ })
64
+ class MyElement extends HTMLElement {
65
+ @listen('customevent')
66
+ onClick(e: CustomEvent) {
67
+ assert.equal(e.type, 'customevent');
68
+
69
+ done();
70
+ }
71
+ }
72
+
73
+ const el = new MyElement();
74
+
75
+ document.body.append(el);
76
+
77
+ el.dispatchEvent(new CustomEvent());
78
+
79
+ el.remove();
80
+ });
81
+
82
+ it('should respect a provided selector function', (done) => {
83
+ @element({
84
+ tagName: 'listener-4',
85
+ shadowDom: []
86
+ })
87
+ class MyElement extends HTMLElement {
88
+ @listen('click', (host) => host)
89
+ onClick(e: Event) {
90
+ assert.equal(e.type, 'click');
91
+
92
+ done();
93
+ }
94
+ }
95
+
96
+ const el = new MyElement();
97
+
98
+ document.body.append(el);
99
+
100
+ el.dispatchEvent(new Event('click'));
101
+
102
+ el.remove();
103
+ });
104
+ });
package/src/lib/listen.ts CHANGED
@@ -1,15 +1,35 @@
1
- import { ListenerRootSelector, metadataStore } from './metadata.js';
1
+ import { ListenerSelector, metadataStore } from './metadata.js';
2
2
 
3
- export function listen<This extends HTMLElement>(event: string, root?: ListenerRootSelector) {
3
+ export function listen<This extends HTMLElement>(
4
+ event: string,
5
+ selector?: ListenerSelector<This> | string
6
+ ) {
4
7
  return function listenDecorator(
5
- value: (e: Event) => void,
8
+ value: (e: any) => void,
6
9
  ctx: ClassMethodDecoratorContext<This>
7
- ) {
8
- const metadata = metadataStore.read(ctx.metadata);
10
+ ): void {
11
+ const metadata = metadataStore.read<This>(ctx.metadata);
9
12
 
10
- metadata.listeners.set(event, {
13
+ let selectorInternal: ListenerSelector<This> = (el) => el.shadowRoot ?? el;
14
+
15
+ if (selector) {
16
+ if (typeof selector === 'string') {
17
+ selectorInternal = (el: This) => {
18
+ if (el.shadowRoot) {
19
+ return el.shadowRoot.querySelector(selector);
20
+ }
21
+
22
+ return el.querySelector(selector);
23
+ };
24
+ } else {
25
+ selectorInternal = selector;
26
+ }
27
+ }
28
+
29
+ metadata.listeners.push({
30
+ event,
11
31
  cb: value,
12
- root: root ?? ((el: HTMLElement) => el.shadowRoot ?? el)
32
+ selector: selectorInternal
13
33
  });
14
34
  };
15
35
  }
@@ -2,19 +2,32 @@
2
2
 
3
3
  export interface AttrDef {
4
4
  propName: string | symbol;
5
- attrName: string;
6
5
  observe: boolean;
6
+ reflect: boolean;
7
+ getPropValue: Function;
8
+ setPropValue: Function;
7
9
  }
8
10
 
9
- export type ListenerRootSelector = (el: HTMLElement) => HTMLElement | ShadowRoot;
11
+ export type ListenerSelector<T> = (el: T) => Element | ShadowRoot | null;
10
12
 
11
- export class ElementMetadata {
12
- attrs: AttrDef[] = [];
13
- listeners = new Map<string, { cb: (e: Event) => void; root: ListenerRootSelector }>();
13
+ export interface Listener<T> {
14
+ event: string;
15
+ cb: (e: Event) => void;
16
+ selector: ListenerSelector<T>;
14
17
  }
15
18
 
16
- export class MetadataStore extends WeakMap<object, ElementMetadata> {
17
- read(value: object) {
19
+ export class AttrMetadata extends Map<string, AttrDef> {}
20
+ export class AttrChangeMetadata extends Map<string, Set<Function>> {}
21
+
22
+ export class ElementMetadata<T> {
23
+ attrs: AttrMetadata = new AttrMetadata();
24
+ attrChanges: AttrChangeMetadata = new AttrChangeMetadata();
25
+ listeners: Listener<T>[] = [];
26
+ onReady: Set<Function> = new Set();
27
+ }
28
+
29
+ export class MetadataStore extends WeakMap<object, ElementMetadata<unknown>> {
30
+ read<T>(value: object): ElementMetadata<T> {
18
31
  if (!this.has(value)) {
19
32
  this.set(value, new ElementMetadata());
20
33
  }
@@ -23,4 +36,4 @@ export class MetadataStore extends WeakMap<object, ElementMetadata> {
23
36
  }
24
37
  }
25
38
 
26
- export const metadataStore = new MetadataStore();
39
+ export const metadataStore: MetadataStore = new MetadataStore();