@cocreate/api 1.7.3 → 1.8.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.8.0](https://github.com/CoCreate-app/CoCreate-api/compare/v1.7.3...v1.8.0) (2023-03-15)
2
+
3
+
4
+ ### Features
5
+
6
+ * type param to define an interaction. onload, input, action, attributeObserver and nodeObserver ([c2ecede](https://github.com/CoCreate-app/CoCreate-api/commit/c2ecedeae6911210e36d148319085c0a1d1c8443))
7
+
1
8
  ## [1.7.3](https://github.com/CoCreate-app/CoCreate-api/compare/v1.7.2...v1.7.3) (2023-02-12)
2
9
 
3
10
 
package/demo/client.js CHANGED
@@ -2,15 +2,33 @@ import api from "@cocreate/api";
2
2
 
3
3
  const CoCreateExample = {
4
4
  name: "example",
5
- actions: {
5
+ endPoints: {
6
6
  'tokens.create':{},
7
- create:{
8
- realtime: true,
9
- request: function (data) {
10
- },
11
- response: function (data) {
7
+ create: {
8
+ onload: function (name, endPoint, element) {
9
+
10
+ },
11
+ input: function (name, endPoint, element) {
12
+
13
+ },
14
+ action: function (name, endPoint, element){
15
+
16
+ },
17
+ observer: function (name, endPoint, element) {
18
+
19
+ },
20
+ request: function (name, endPoint, element) {
21
+
22
+ },
23
+ response: function (name, endPoint, element) {
12
24
 
13
25
  },
26
+ read: true,
27
+ realtime: true,
28
+ save: true,
29
+ update: true,
30
+ listen: true
31
+
14
32
  }
15
33
  }
16
34
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/api",
3
- "version": "1.7.3",
3
+ "version": "1.8.0",
4
4
  "description": "A simple api helper component in vanilla javascript used by JavaScript developers to create thirdparty api intergrations. CoCreate-api includes the client component and server side for api processing. Thirdparty apis can be accessible using HTML5 attributes and/or JavaScript API. ",
5
5
  "keywords": [
6
6
  "thirdparty-api-intergration",
package/src/client.js CHANGED
@@ -1,128 +1,186 @@
1
1
  /*globals CustomEvent, config*/
2
2
  import {getAttributes, getValueFromObject, dotNotationToObject} from "@cocreate/utils";
3
+ import observer from "@cocreate/observer";
3
4
  import socket from "@cocreate/socket-client";
4
- import CoCreateAction from '@cocreate/actions';
5
- import CoCreateRender from '@cocreate/render';
5
+ import action from '@cocreate/actions';
6
+ import render from '@cocreate/render';
6
7
  import '@cocreate/element-prototype';
7
- import utils from "@cocreate/utils/src/utils";
8
8
 
9
9
  const CoCreateApi = {
10
10
  components: {},
11
-
12
- init: function({name, actions, realtime}) {
13
- this.register({name, actions});
14
- if (!socket.sockets.size)
11
+
12
+ init: function({name, endPoints, options}) {
13
+ this.register({name, endPoints, options});
14
+ if (options.socket !== false && !socket.sockets.size)
15
15
  socket.create({prefix: 'api'});
16
- document.addEventListener('input', (e)=> {
17
- let action = e.target.getAttribute(name)
18
- if (action) {
19
- action = action.split('.', 1)
20
- action = action[0]
21
- if (actions[action].realtime !== false) {
22
- if (realtime !== false && actions[action].realtime !== undefined) {
23
- let functions = actions[action]
24
- if (typeof functions.request === 'function') {
25
- functions.request(name, action, e.target)
26
- }
27
- }
28
- }
29
- }
30
-
31
- })
32
16
  },
33
17
 
34
- register: function({name, actions}) {
18
+ register: function({name, endPoints, options}) {
35
19
  const self = this;
36
20
  if (typeof this.components[name] === 'undefined') {
37
- this.components[name] = {name, actions};
21
+ this.components[name] = {name, endPoints, options};
38
22
 
39
23
  socket.listen(name, (data) => {
40
24
  self.__response(name, data);
41
25
  });
42
26
 
43
- for (const action of Object.keys(actions)) {
44
- let functions = actions[action]
27
+ for (const endPoint of Object.keys(endPoints)) {
28
+ let functions = endPoints[endPoint]
45
29
  if (typeof functions.request !== 'function') {
46
30
  functions.request = self.__request;
47
31
  }
48
- CoCreateAction.init({
49
- name: action,
50
- endEvent: action,
32
+ action.init({
33
+ name: endPoint,
34
+ endEvent: endPoint,
51
35
  callback: (element) => {
52
- functions.request(name, action, element);
36
+ let params
37
+ let form = element.closest('form') || document
38
+ const selector = `[${name}^="${endPoint}."]`
39
+ let el = form.querySelector(selector)
40
+ if (!el) return
41
+ params = self.parseParams({name, element: el})
42
+ if (params) {
43
+ functions.request({name, ...params, element, form, type: 'action'})
44
+ }
53
45
  },
54
46
  });
55
47
  }
48
+
49
+ const inputEvent = (element) => {
50
+ const self = this
51
+ element.addEventListener('input', (e) => {
52
+ if (element.hasAttribute(name)) {
53
+ let params = self.parseParams({name, element})
54
+ if (params) {
55
+ if (!e.detail || e.detail && e.detail.skip != true) {
56
+ endPoints[params.endPoint].request({name, ...params, element, type: 'input'})
57
+ }
58
+ }
59
+ }
60
+ });
61
+ }
62
+
63
+ let elements = document.querySelectorAll(`[${name}]`)
64
+ for (let element of elements) {
65
+ let params = this.parseParams({name, element})
66
+ if (params) {
67
+ endPoints[params.endPoint].request({name, ...params, element, type:'onload'})
68
+ inputEvent(element)
69
+ }
70
+ }
71
+
72
+ observer.init({
73
+ name: `${name}NodeObserver`,
74
+ observe: ['addedNodes'],
75
+ target: `[${name}]`,
76
+ callback: function(mutation) {
77
+ let params = self.parseParams({name, element: mutation.target})
78
+ if (params) {
79
+ endPoints[params.endPoint].request({name, ...params, element: mutation.target, type: 'nodeObserver'});
80
+ inputEvent(mutation.target)
81
+ }
82
+ }
83
+ });
84
+
85
+ observer.init({
86
+ name: `${name}AttributeObserver`,
87
+ observe: ['attributes'],
88
+ attributeName: [name],
89
+ callback: function(mutation) {
90
+ let params = self.parseParams({name, element: mutation.target})
91
+ if (params) {
92
+ endPoints[params.endPoint].request({name, ...params, element: mutation.target, type: 'attributeObserver'});
93
+ }
94
+ }
95
+ });
56
96
  }
57
97
  },
58
98
 
59
- __request: function(name, action, element) {
99
+ __request: function({name, endPoint, element}) {
60
100
  let form = element.closest('form');
61
- let data = this.getData(name, action, form);
62
- this.send(name, action, data[action]);
101
+ let data = this.getData({name, endPoint, form});
102
+ this.send(name, endPoint, data[endPoint]);
63
103
  },
64
104
 
65
105
  __response: function(name, data) {
66
- const {action, response} = data;
106
+ const {endPoint, response} = data;
67
107
  const component = this.components[name];
68
- const functions = component.actions[action]
69
- if (typeof functions.response === 'function') {
70
- functions.response(response);
108
+ const functions = component.endPoints[endPoint]
109
+ if (functions.listen !== false) {
110
+ if (typeof functions.response === 'function') {
111
+ functions.response(response);
112
+ } else
113
+ this.setData({name, endPoint, data})
114
+
115
+ document.dispatchEvent(new CustomEvent(endPoint, {
116
+ detail: {
117
+ data: response
118
+ }
119
+ }));
71
120
  }
72
- else
73
- this.render(action, response);
74
-
75
- document.dispatchEvent(new CustomEvent(action, {
76
- detail: {
77
- data: response
78
- }
79
- }));
80
121
  },
81
122
 
82
- send: function(name, action, data) {
83
- socket.send(name, {action, data, broadcastBrowser: false});
123
+ send: function(name, endPoint, data) {
124
+ socket.send(name, {endPoint, data, broadcastBrowser: false});
84
125
  },
85
126
 
86
- render: function(action, data) {
87
- CoCreateRender.data({
88
- selector: `[template="${action}"]`,
89
- data: data
90
- });
91
- },
127
+ parseParams: function({name, endPoint, element}) {
128
+ let attribute = element.getAttribute(name)
129
+ if (!attribute)
130
+ return false
131
+
132
+ let dotNotation = attribute
133
+ let params = attribute.split('.')
134
+ endPoint = params[0]
135
+ let key = params[1]
136
+ return {endPoint, key, dotNotation, params}
92
137
 
93
- getData: function(attribute, action, form) {
94
- let data = {}
95
- const selector = `[${attribute}^="${action}."]`
96
- if (!form)
97
- form = document;
98
- let elements = form.querySelectorAll(selector);
99
- if (!elements || elements.length == 0) return
138
+ },
139
+
100
140
 
141
+ getData: function({name, endPoint, element, form}) {
142
+ const data = {}
143
+ const selector = `[${name}^="${endPoint}."]`
144
+ let elements
145
+ if (form)
146
+ elements = form.querySelectorAll(selector);
147
+ if (!elements || elements.length == 0)
148
+ elements = [element]
101
149
  for (let el of elements) {
102
- let name = el.getAttribute(attribute)
103
- let value = el.getValue();
104
- if (name)
105
- data[name] = value
106
- }
150
+ if (el.closest('[template]')) continue
151
+ let attribute = el.getAttribute(name)
152
+ if (attribute)
153
+ data[attribute] = el.getValue()
154
+ }
155
+
107
156
  return dotNotationToObject(data);
108
157
  },
109
158
 
110
- setData: function(attribute, action, data, form) {
111
- const selector = `[${attribute}^="${action}."]`
159
+ setData: function({name, endPoint, data, form}) {
160
+ const selector = `[${name}^="${endPoint}."]`
112
161
  if (!form)
113
162
  form = document;
114
163
  let elements = form.querySelectorAll(selector);
115
164
  if (!elements || elements.length == 0) return
116
165
 
117
166
  for (let el of elements) {
118
- let name = el.getAttribute(attribute)
119
- const { isRead, isUpdate, isCrdt } = getAttributes(el);
120
- if (!name || isRead == "false" || isUpdate == "false" || isCrdt == "true") continue;
121
-
122
- if (el.hasAttribute('actions')) continue;
123
-
124
- let value = getValueFromObject({[action]: {[name]: data}}, name);
125
- el.setValue(value);
167
+ let attribute = el.getAttribute(name)
168
+ if (attribute) {
169
+ if (el.hasAttribute('actions')) continue;
170
+ let templateid = el.getAttribute('template_id')
171
+ if (templateid) {
172
+ let items = document.querySelectorAll(`[templateid="${templateid}"]`)
173
+ for (let item of items)
174
+ item.remove()
175
+ render.data({
176
+ selector: `[template="${templateid}"]`,
177
+ data
178
+ });
179
+ } else {
180
+ let value = getValueFromObject(data, attribute);
181
+ el.setValue(value);
182
+ }
183
+ }
126
184
  }
127
185
 
128
186
  }