saasufy-components 8.4.0 → 8.4.2
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 +8 -2
- package/WEBSOCKET_API.md +181 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -129,6 +129,12 @@ import {
|
|
|
129
129
|
} from 'saasufy-components/utils.js';
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
+
A reference to a socket can be obtained from a `socket-provider` element like this:
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
let socket = document.querySelector('socket-provider').getSocket();
|
|
136
|
+
```
|
|
137
|
+
|
|
132
138
|
**Available functions:**
|
|
133
139
|
|
|
134
140
|
- `getRecordIds({ socket, type, viewName, viewParams, startPage, maxPages, pageSize })`: Retrieves record IDs from a collection view across multiple pages. Returns an array of IDs.
|
|
@@ -139,8 +145,8 @@ import {
|
|
|
139
145
|
**Example usage:**
|
|
140
146
|
```javascript
|
|
141
147
|
// Process all products one by one without loading them all into memory at once
|
|
142
|
-
|
|
143
|
-
socket
|
|
148
|
+
let productGenerator = generateRecords({
|
|
149
|
+
socket,
|
|
144
150
|
type: 'Product',
|
|
145
151
|
viewName: 'alphabeticalView',
|
|
146
152
|
viewParams: { category: 'electronics' },
|
package/WEBSOCKET_API.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# WebSocket API
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Saasufy exposes a powerful WebSocket API which allows you to integrate with your Saasufy service in complex ways; it supports CRUD operations and subscriptions for data changes. This API can be used to build custom components which interact with Saasufy data or to integrate with third-party services.
|
|
6
|
+
|
|
7
|
+
The Saasufy WebSocket CRUD API and Subscribe API are implemented on top of the SocketCluster protocol.
|
|
8
|
+
It is recommended to use the `socketcluster-client` library: http://npmjs.org/socketcluster-client
|
|
9
|
+
|
|
10
|
+
You can connect a SocketCluster client socket to your Saasufy service like this:
|
|
11
|
+
```js
|
|
12
|
+
// The the script URL/path may differ depending on your setup
|
|
13
|
+
import {
|
|
14
|
+
create as createSocket
|
|
15
|
+
} from 'https://saasufy.com/node_modules/socketcluster-client/socketcluster-client.min.js';
|
|
16
|
+
|
|
17
|
+
// Change the path with that of your own service
|
|
18
|
+
let clientSocket = createSocket({
|
|
19
|
+
hostname: 'saasufy.com',
|
|
20
|
+
port: 443,
|
|
21
|
+
secure: true,
|
|
22
|
+
path: '/sid8001/socketcluster/'
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## CRUD API
|
|
27
|
+
|
|
28
|
+
All CRUD operations can be invoked on a client socket like this:
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
await clientSocket.invoke('crud', queryObject);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The format of the `queryObject` for various operations is shown below.
|
|
35
|
+
|
|
36
|
+
### Read collection view
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"action": "read",
|
|
40
|
+
"type": "Product",
|
|
41
|
+
"offset": 0,
|
|
42
|
+
"view": "categoryView",
|
|
43
|
+
"viewParams": {
|
|
44
|
+
"categoryName": "Electronics"
|
|
45
|
+
},
|
|
46
|
+
"pageSize": 10
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
This API returns a response object with `data` and `isLastPage` properties. The `data` property holds an array of IDs - The recommended approach is to load the list of IDs and then fetch individual properties on demand. The Saasufy service uses lightweight WebSocket frames and caches resources on the back end so it's acceptable to make a relatively large number of requests for individual fields.
|
|
50
|
+
|
|
51
|
+
If `getCount` is true, the operation will return the total number of records which exist in the specified view via a `count` property. Note that this can become computationally expensive if the view has a large number of records.
|
|
52
|
+
|
|
53
|
+
### Create model instance
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"action": "create",
|
|
57
|
+
"type": "Product",
|
|
58
|
+
"value": {
|
|
59
|
+
"name": "Pixel 7",
|
|
60
|
+
"brand": "Google",
|
|
61
|
+
"categoryName": "Electronics"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
An optional `id` field can be specified as part of the `value` object. If it is not specified, then the `id` will be created automatically by Saasufy.
|
|
66
|
+
|
|
67
|
+
### Update model instance
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"action": "update",
|
|
71
|
+
"type": "Product",
|
|
72
|
+
"id": "2201ec45-1c7c-4a5f-8432-1015b7fc4b92",
|
|
73
|
+
"value": {
|
|
74
|
+
"name": "Pixel 7"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
By default, for efficiency reasons, change notifications related to a specific CRUD action are not sent to the socket which initiated the action. In order to receive such notifications, you should add a top level `publisherId` property to the object. It should be a string of length between 1 and 50 characters. The `publisherId` will be sent to the origin client socket alongside the change notification. It can be used to identify where the action originated.
|
|
79
|
+
|
|
80
|
+
### Delete model instance
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"action": "delete",
|
|
84
|
+
"type": "Product",
|
|
85
|
+
"id": "2201ec45-1c7c-4a5f-8432-1015b7fc4b92"
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
In order to receive change notifications back from the client socket which initiated an action, you should add a top level `publisherId` property to the object above. It should be a string of length between 1 and 50 characters. The `publisherId` will be sent to the origin client socket alongside the change notification.
|
|
89
|
+
|
|
90
|
+
### Read model field
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"action": "read",
|
|
94
|
+
"type": "Product",
|
|
95
|
+
"id": "2201ec45-1c7c-4a5f-8432-1015b7fc4b92",
|
|
96
|
+
"field": "name"
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
The `field` property can be omitted to read the entire resource object with all available fields.
|
|
100
|
+
|
|
101
|
+
### Update model field
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"action": "update",
|
|
105
|
+
"type": "Product",
|
|
106
|
+
"id": "2201ec45-1c7c-4a5f-8432-1015b7fc4b92",
|
|
107
|
+
"field": "name",
|
|
108
|
+
"value": "Pixel 7"
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
In order to receive change notifications back from the client socket which initiated an action, you should add a top level `publisherId` property to the object above. It should be a string of length between 1 and 50 characters. The `publisherId` will be sent to the origin client socket alongside the change notification.
|
|
112
|
+
|
|
113
|
+
### Update multiple model fields
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"action": "update",
|
|
117
|
+
"type": "Product",
|
|
118
|
+
"id": "2201ec45-1c7c-4a5f-8432-1015b7fc4b92",
|
|
119
|
+
"value": {
|
|
120
|
+
"name": "Pixel 7",
|
|
121
|
+
"qty": 3
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Delete model field
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"action": "delete",
|
|
130
|
+
"type": "Product",
|
|
131
|
+
"id": "2201ec45-1c7c-4a5f-8432-1015b7fc4b92",
|
|
132
|
+
"field": "qty"
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Subscribe API
|
|
137
|
+
|
|
138
|
+
All subscribe operations can be invoked on a client socket like this:
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
let channel = clientSocket.subscribe(channelName);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Changes can be consumed like this:
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
for await (let data of channel) {
|
|
148
|
+
// data represents the change object.
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### View changes
|
|
153
|
+
|
|
154
|
+
The format of the `channelName` is this:
|
|
155
|
+
|
|
156
|
+
```js
|
|
157
|
+
`crud>${viewName}(${viewPrimaryParamsString}):${modelType}`
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
For example, to subscribe to changes to the `categoryView` of the `Product` collection, with the view params `{ categoryName: 'Electronics' }`, the `channelName` to use would be:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
'crud>categoryView({"categoryName":"Electronics"}):Product'
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
If there are multiple view params, they must be specified in alphabetical order based on the property name.
|
|
167
|
+
|
|
168
|
+
### Field changes
|
|
169
|
+
|
|
170
|
+
The format of the `channelName` is this:
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
`crud>${modelType}/${modelId}/${modelField}`
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
For example, to subscribe to changes to the `name` field of a `Product` with ID `a3647d32-1aa2-4332-b8bb-8f3c84648cfa`, the `channelName` to use would be:
|
|
177
|
+
|
|
178
|
+
```js
|
|
179
|
+
'crud>Product/a3647d32-1aa2-4332-b8bb-8f3c84648cfa/name'
|
|
180
|
+
```
|
|
181
|
+
|