Skip to content

Commit 1238015

Browse files
committed
feat: init a module and its attributes using
- Attrinbutes "api="stripe" or module="stripe" - <input stripe="customers.create" stripe-key="furst_name">
1 parent e442059 commit 1238015

File tree

1 file changed

+116
-133
lines changed

1 file changed

+116
-133
lines changed

src/client.js

Lines changed: 116 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,198 +1,168 @@
11
/*globals CustomEvent, config*/
2-
import { getAttributes, getValueFromObject, dotNotationToObject } from "@cocreate/utils";
3-
import observer from "@cocreate/observer";
4-
import socket from "@cocreate/socket-client";
5-
import action from '@cocreate/actions';
2+
import { getValueFromObject, dotNotationToObject } from "@cocreate/utils";
3+
import Observer from "@cocreate/observer";
4+
import Socket from "@cocreate/socket-client";
5+
import Actions from '@cocreate/actions';
66
import { render } from '@cocreate/render';
77
import '@cocreate/element-prototype';
88

99
const CoCreateApi = {
10-
components: {},
11-
12-
init: function ({ name, endPoints, options }) {
13-
this.register({ name, endPoints, options });
14-
if (options && options.socket !== false && !socket.sockets.size)
15-
socket.create({ prefix: 'api' });
10+
modules: {},
11+
12+
init: function (moduleConfig) {
13+
if (!moduleConfig) {
14+
let elements = document.querySelectorAll('[api], [module]')
15+
for (let i = 0; i < elements.length; i++) {
16+
let name = elements[i].getAttribute('api') || elements[i].getAttribute('module')
17+
this.register({ name, endPoints: {} });
18+
}
19+
} else {
20+
let { name, endPoints, options } = moduleConfig
21+
this.register({ name, endPoints, options });
22+
if (options && options.socket !== false && !Socket.sockets.size)
23+
Socket.create({ prefix: 'api' });
24+
}
1625
},
1726

1827
register: function ({ name, endPoints, options }) {
1928
const self = this;
20-
if (typeof this.components[name] === 'undefined') {
21-
this.components[name] = { name, endPoints, options };
29+
if (typeof this.modules[name] === 'undefined') {
30+
this.modules[name] = { name, endPoints, options };
2231

23-
socket.listen(name, (data) => {
24-
self.__response(name, data);
32+
Socket.listen(name, (data) => {
33+
self.response(name, data);
2534
});
2635

27-
for (const endPoint of Object.keys(endPoints)) {
28-
socket.listen(name + '.' + endPoint, (data) => {
29-
self.__response(name, data);
30-
});
31-
32-
let functions = endPoints[endPoint]
33-
if (typeof functions.request !== 'function') {
34-
functions.request = self.__request;
36+
Actions.init({
37+
name,
38+
callback: (action) => {
39+
action.form = action.form || document
40+
self.request({ ...action, type: 'action' })
3541
}
36-
action.init({
37-
name: endPoint,
38-
endEvent: endPoint,
39-
callback: (data) => {
40-
const element = data.element
41-
let form = data.form || document
42-
const selector = `[${name}^="${endPoint}."]`
43-
let el = form.querySelector(selector)
44-
if (!el) return
45-
let params = self.parseParams({ name, element: el })
46-
if (params) {
47-
functions.request({ name, ...params, element, form, type: 'action' })
48-
}
49-
},
50-
});
51-
}
42+
});
5243

5344
const inputEvent = (element) => {
54-
const self = this
5545
element.addEventListener('input', (e) => {
56-
if (element.hasAttribute(name)) {
57-
let params = self.parseParams({ name, element })
58-
if (params) {
59-
if (!e.detail || e.detail && e.detail.skip != true) {
60-
endPoints[params.endPoint].request({ name, ...params, element, type: 'input' })
61-
}
62-
}
46+
if (!e.detail || e.detail && e.detail.skip != true) {
47+
self.request({ name, element, type: 'input' })
6348
}
6449
});
6550
}
6651

6752
let elements = document.querySelectorAll(`[${name}]`)
68-
for (let element of elements) {
69-
let params = this.parseParams({ name, element })
70-
if (params) {
71-
endPoints[params.endPoint].request({ name, ...params, element, type: 'onload' })
72-
inputEvent(element)
73-
}
53+
for (let i = 0; i < elements.length; i++) {
54+
inputEvent(elements[i])
55+
this.request({ name, element: elements[i], type: 'onload' })
7456
}
7557

76-
observer.init({
58+
Observer.init({
7759
name: `${name}NodeObserver`,
7860
observe: ['addedNodes'],
7961
target: `[${name}]`,
8062
callback: function (mutation) {
81-
let params = self.parseParams({ name, element: mutation.target })
82-
if (params) {
83-
endPoints[params.endPoint].request({ name, ...params, element: mutation.target, type: 'nodeObserver' });
84-
inputEvent(mutation.target)
85-
}
63+
inputEvent(mutation.target)
64+
self.request({ name, element: mutation.target, type: 'nodeObserver' })
8665
}
8766
});
8867

89-
observer.init({
68+
Observer.init({
9069
name: `${name}AttributeObserver`,
9170
observe: ['attributes'],
9271
attributeName: [name],
9372
callback: function (mutation) {
94-
let params = self.parseParams({ name, element: mutation.target })
95-
if (params) {
96-
endPoints[params.endPoint].request({ name, ...params, element: mutation.target, type: 'attributeObserver' });
97-
}
73+
self.request({ name, element: mutation.target, type: 'attributeObserver' })
9874
}
9975
});
10076
}
10177
},
10278

10379

104-
__request: async function (object) {
105-
if (object.type !== 'action')
106-
return
107-
if (!object.form)
108-
object.form = element.closest('form');
109-
let data = await CoCreateApi.getData(object);
110-
CoCreateApi.send(object.name, object.endPoint, data);
111-
},
112-
113-
__response: function (name, data) {
114-
const endPoint = data.method.substring(name.length + 1);
115-
const component = this.components[name];
116-
const functions = component.endPoints[endPoint]
117-
if (functions.listen !== false) {
118-
if (typeof functions.response === 'function') {
119-
functions.response(data[name]);
120-
} else if (data.error) {
121-
render({
122-
selector: `[template*='${name}']`,
123-
data: [{
124-
type: name,
125-
status: 'failed',
126-
message: data.error
127-
}]
128-
});
129-
} else {
130-
CoCreateApi.setData({ name, endPoint, data })
131-
132-
document.dispatchEvent(new CustomEvent(endPoint, {
133-
detail: {
134-
data: data[name]
135-
}
136-
}));
137-
}
80+
request: async function (object) {
81+
if (object.element) {
82+
if (!object.method)
83+
object.method = object.element.getAttribute(object.name)
84+
if (!object.key)
85+
object.key = object.element.getAttribute(`${object.name}-key`)
86+
if (!object.event)
87+
object.event = object.element.getAttribute(`${object.name}-event`)
13888
}
139-
},
14089

141-
send: function (name, endPoint, data) {
142-
let method = name + '.' + endPoint
143-
socket.send({ method, endPoint, [name]: data, broadcastBrowser: false, status: 'await' });
90+
if (this.modules[object.name][object.method] && this.modules[object.name][object.method].request)
91+
this.modules[object.name][object.method].request(object)
92+
else if (!object.event && object.type === 'action' || object.event && object.event.includes(object.type)) {
93+
let data = await CoCreateApi.getData(object);
94+
CoCreateApi.send(object.name, object.method, data);
95+
}
14496
},
14597

146-
parseParams: function ({ name, endPoint, element }) {
147-
let attribute = element.getAttribute(name)
148-
if (!attribute)
149-
return false
98+
response: function (name, data) {
99+
const method = data.method.substring(name.length + 1);
100+
if (this.modules[name][method] && this.modules[name][method].response)
101+
this.modules[name][method].response(data[name])
102+
else if (data.error) {
103+
render({
104+
selector: `[template*='${name}']`,
105+
data: [{
106+
type: name,
107+
method,
108+
status: 'failed',
109+
message: data.error
110+
}]
111+
});
112+
} else {
113+
CoCreateApi.setData({ name, method, data })
150114

151-
let endPoints = this.components[name].endPoints
152-
for (let k of Object.keys(endPoints)) {
153-
if (attribute.startsWith(k)) {
154-
endPoint = k
155-
break;
156-
}
115+
document.dispatchEvent(new CustomEvent(name, {
116+
detail: {
117+
data: data[name]
118+
}
119+
}));
157120
}
158-
159-
let key = attribute.substring(endPoint.length + 1);
160-
return { endPoint, key, dotNotation: attribute }
161-
162121
},
163122

123+
send: function (name, method, data) {
124+
Socket.send({ method: name + '.' + method, [name]: data, broadcastBrowser: false, status: 'await' });
125+
},
164126

165-
getData: async function ({ name, endPoint, element, form }) {
127+
// TODO: handle $param operator
128+
getData: async function ({ name, method, element, form }) {
166129
const data = {}
167-
const selector = `[${name}^="${endPoint}."]`
130+
131+
if (!form && element)
132+
form = element.closest('form');
133+
168134
let elements
169135
if (form)
170-
elements = form.querySelectorAll(selector);
136+
elements = form.querySelectorAll(`[${name}="${method}"]`);
171137
if (!elements || elements.length == 0)
172138
elements = [element]
173-
for (let el of elements) {
174-
if (!el || el.closest('[template]')) continue
175-
let params = this.parseParams({ name, element: el })
176-
if (params.key) {
177-
data[params.key] = await el.getValue()
139+
140+
for (let i = 0; i < elements.length; i++) {
141+
if (!elements[i] || elements[i].closest('[template]'))
142+
continue
143+
let key = elements[i].getAttribute(`${name}-key`)
144+
if (key) {
145+
data[key] = await elements[i].getValue()
178146
}
179147
}
180148

181149
return dotNotationToObject(data);
182150
},
183151

184-
setData: function ({ name, endPoint, data, form }) {
185-
const selector = `[${name}^="${endPoint}."]`
152+
// TODO: handle $param operator
153+
setData: function ({ name, method, data, form }) {
186154
if (!form)
187155
form = document;
188-
let elements = form.querySelectorAll(selector);
189-
if (!elements || elements.length == 0) return
190156

191-
for (let el of elements) {
192-
let attribute = el.getAttribute(name)
157+
let elements = form.querySelectorAll(`[${name}="${method}"]`);
158+
if (!elements || elements.length == 0)
159+
return
160+
161+
for (let i = 0; i < elements.length; i++) {
162+
let attribute = elements[i].getAttribute(name)
193163
if (attribute) {
194-
if (el.hasAttribute('actions')) continue;
195-
let templateid = el.getAttribute('template_id')
164+
if (elements[i].hasAttribute('actions')) continue;
165+
let templateid = elements[i].getAttribute('template_id')
196166
if (templateid) {
197167
let items = document.querySelectorAll(`[templateid="${templateid}"]`)
198168
for (let item of items)
@@ -202,8 +172,9 @@ const CoCreateApi = {
202172
data
203173
});
204174
} else {
205-
let value = getValueFromObject(data, attribute);
206-
el.setValue(value);
175+
let key = elements[i].getAttribute(`${name}-key`)
176+
let value = getValueFromObject(data[name], key);
177+
elements[i].setValue(value);
207178
}
208179
}
209180
}
@@ -212,4 +183,16 @@ const CoCreateApi = {
212183

213184
};
214185

186+
Observer.init({
187+
name: `apiNodeObserver`,
188+
observe: ['addedNodes'],
189+
target: '[module], [api]',
190+
callback: function (mutation) {
191+
let name = mutation.target.getAttribute('api') || mutation.target.getAttribute('module')
192+
CoCreateApi.register({ name, endPoints: {} });
193+
}
194+
});
195+
196+
CoCreateApi.init()
197+
215198
export default CoCreateApi;

0 commit comments

Comments
 (0)