@basementuniverse/jsonpad-realtime-sdk 1.0.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.
@@ -0,0 +1,9 @@
1
+ {
2
+ "editor.codeActionsOnSave": {
3
+ "source.organizeImports": "explicit"
4
+ },
5
+ "[typescript]": {
6
+ "editor.formatOnSave": true,
7
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
8
+ }
9
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Gordon Larrigan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # JSONPad Realtime SDK
2
+
3
+ This package allows you to connect to JSONPad Realtime and get realtime updates when your lists or items change.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @basementuniverse/jsonpad-realtime-sdk
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Create an instance of the JSONPad Realtime SDK and pass in your API token:
14
+
15
+ Node (JS):
16
+
17
+ ```js
18
+ const JSONPadRealtime = require('@basementuniverse/jsonpad-realtime-sdk').default;
19
+
20
+ const jsonpadRealtime = new JSONPadRealtime('your-api-token');
21
+ ```
22
+
23
+ Node (TS):
24
+
25
+ ```ts
26
+ import JSONPadRealtime from '@basementuniverse/jsonpad-realtime-sdk';
27
+
28
+ const jsonpadRealtime = new JSONPadRealtime('your-api-token');
29
+ ```
30
+
31
+ Browser:
32
+
33
+ ```html
34
+ <script src="jsonpad-realtime-sdk.js"></script>
35
+ <script>
36
+ const jsonpadRealtime = new JSONPadRealtime.default('your-api-token');
37
+ </script>
38
+ ```
39
+
40
+ Next, start listening for events on your lists or items:
41
+
42
+ ```js
43
+ jsonpadRealtime.listen(
44
+ [
45
+ 'list-created',
46
+ 'list-updated',
47
+ 'list-deleted',
48
+ 'item-created',
49
+ 'item-updated',
50
+ 'item-restored',
51
+ 'item-deleted',
52
+ ]
53
+ );
54
+ ```
55
+
56
+ Attach event listeners to the JSONPad Realtime SDK instance:
57
+
58
+ ```js
59
+ jsonpadRealtime.addEventListener('list-created', e => {
60
+ console.log(`A list called ${e.detail.model.name} was created!`);
61
+ });
62
+ ```
63
+
64
+ If you want to stop listening for events and disconnect from the server, you can call the `close` method:
65
+
66
+ ```js
67
+ jsonpadRealtime.close();
68
+ ```
69
+
70
+ ## `listen()` method
71
+
72
+ The `listen()` method takes an array of event types to listen for. You can pass in any of the following event types:
73
+
74
+ - `list-created`
75
+ - `list-updated`
76
+ - `list-deleted`
77
+ - `item-created`
78
+ - `item-updated`
79
+ - `item-restored`
80
+ - `item-deleted`
81
+
82
+ You can also optionally pass in an array of list ids and item ids to listen for.
83
+
84
+ You can include `*` in the list ids and item ids arrays to listen for all lists or items.
85
+
86
+ ```js
87
+ jsonpadRealtime.listen(
88
+ [
89
+ 'list-created',
90
+ 'list-updated',
91
+ 'list-deleted',
92
+ 'item-created',
93
+ 'item-updated',
94
+ 'item-restored',
95
+ 'item-deleted',
96
+ ],
97
+ [
98
+ '86059de7-9b16-4469-a630-23c8f69944b6',
99
+ 'a2c706a6-5212-4e8a-92ad-bce1beea153f',
100
+ ],
101
+ [
102
+ 'e0bc4797-303a-49ff-b7b4-18781cc2460e',
103
+ '06ad5a22-c002-4c67-92bc-83ec85014461',
104
+ ]
105
+ );
106
+ ```
107
+
108
+ ## Event types
109
+
110
+ - `list-created`: A list was created.
111
+ - `list-updated`: A list was updated.
112
+ - `list-deleted`: A list was deleted.
113
+ - `item-created`: An item was created.
114
+ - `item-updated`: An item was updated.
115
+ - `item-restored`: An item was restored.
116
+ - `item-deleted`: An item was deleted.
117
+
118
+ ## Event object
119
+
120
+ The event object passed to the event listener has the following properties:
121
+
122
+ ```ts
123
+ {
124
+ type: string;
125
+ detail: {
126
+ listId: string;
127
+ itemId: string;
128
+ model: any; // This will be a List or Item, depending on the event type
129
+ };
130
+ }
131
+ ```
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@basementuniverse/jsonpad-realtime-sdk",
3
+ "version": "1.0.0",
4
+ "description": "JSONPad Realtime SDK for Node and browser",
5
+ "author": "Gordon Larrigan <gordonlarrigan@gmail.com> (https://gordonlarrigan.com)",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/basementuniverse/jsonpad-realtime-sdk#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/basementuniverse/jsonpad-realtime-sdk.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/basementuniverse/jsonpad-realtime-sdk/issues"
14
+ },
15
+ "main": "build/jsonpad-realtime-sdk.js",
16
+ "types": "build/jsonpad-realtime-sdk.d.ts",
17
+ "scripts": {
18
+ "build": "rollup -c && npm run clean",
19
+ "clean": "rm -rf build/types build/utilities build/models build/index.d.ts build/constants.d.ts"
20
+ },
21
+ "devDependencies": {
22
+ "-": "^0.0.1",
23
+ "@rollup/plugin-commonjs": "^28.0.1",
24
+ "@rollup/plugin-node-resolve": "^15.3.0",
25
+ "@rollup/plugin-terser": "^0.4.4",
26
+ "@rollup/plugin-typescript": "^12.1.1",
27
+ "rollup": "^4.24.3",
28
+ "rollup-plugin-dts": "^6.1.1",
29
+ "save-dev": "^0.0.1-security",
30
+ "tslib": "^2.8.1"
31
+ },
32
+ "dependencies": {
33
+ "socket.io-client": "^4.8.1"
34
+ }
35
+ }
@@ -0,0 +1,2 @@
1
+ export const API_URL = 'https://realtime.jsonpad.io';
2
+ export const API_TOKEN_HEADER = 'x-api-token';
package/src/index.ts ADDED
File without changes
@@ -0,0 +1,92 @@
1
+ import { io, Socket } from 'socket.io-client';
2
+ import * as constants from './constants';
3
+ import { EventType, MessageType } from './types';
4
+
5
+ export class JSONPadRealtime extends EventTarget {
6
+ private static readonly connected = new Event('connected');
7
+ private static readonly disconnected = new Event('disconnected');
8
+
9
+ private socket: Socket | null = null;
10
+
11
+ /**
12
+ * Create a new JSONPad realtime client instance
13
+ */
14
+ public constructor(private token: string) {
15
+ super();
16
+ }
17
+
18
+ /**
19
+ * Close the connection to the realtime server
20
+ */
21
+ public close() {
22
+ if (this.socket && this.socket.connected) {
23
+ this.socket.removeAllListeners();
24
+ this.socket.close();
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Start listening for realtime events
30
+ */
31
+ public listen(
32
+ eventTypes: EventType[],
33
+ listIds?: string[],
34
+ itemIds?: string[]
35
+ ) {
36
+ if (this.socket && this.socket.connected) {
37
+ this.socket.removeAllListeners();
38
+ this.socket.close();
39
+ }
40
+
41
+ if (eventTypes.length === 0) {
42
+ throw new Error('At least one event type must be provided');
43
+ }
44
+
45
+ this.socket = io(
46
+ `${constants.API_URL}?${new URLSearchParams({
47
+ eventTypes: eventTypes.join(','),
48
+ listIds: listIds?.join(',') ?? '',
49
+ itemIds: itemIds?.join(',') ?? '',
50
+ })}`,
51
+ {
52
+ extraHeaders: {
53
+ [constants.API_TOKEN_HEADER]: this.token,
54
+ },
55
+ }
56
+ );
57
+
58
+ this.socket.on('connect', this.handleConnected.bind(this));
59
+ this.socket.on('disconnect', this.handleDisconnected.bind(this));
60
+ this.socket.on('error', this.handleError.bind(this));
61
+ this.socket.on('list-created', this.handleEvent.bind(this, 'list-created'));
62
+ this.socket.on('list-updated', this.handleEvent.bind(this, 'list-updated'));
63
+ this.socket.on('list-deleted', this.handleEvent.bind(this, 'list-deleted'));
64
+ this.socket.on('item-created', this.handleEvent.bind(this, 'item-created'));
65
+ this.socket.on('item-updated', this.handleEvent.bind(this, 'item-updated'));
66
+ this.socket.on('item-deleted', this.handleEvent.bind(this, 'item-deleted'));
67
+ }
68
+
69
+ private handleConnected() {
70
+ this.dispatchEvent(JSONPadRealtime.connected);
71
+ }
72
+
73
+ private handleDisconnected() {
74
+ this.dispatchEvent(JSONPadRealtime.disconnected);
75
+ }
76
+
77
+ private handleError(message: string) {
78
+ this.dispatchEvent(new CustomEvent('error', { detail: message }));
79
+ }
80
+
81
+ private handleEvent(messageType: MessageType, data: string) {
82
+ let parsedData: any;
83
+ try {
84
+ parsedData = JSON.parse(data);
85
+ } catch (error) {
86
+ this.handleError('Failed to parse data');
87
+ return;
88
+ }
89
+
90
+ this.dispatchEvent(new CustomEvent(messageType, { detail: parsedData }));
91
+ }
92
+ }
@@ -0,0 +1,8 @@
1
+ export type EventType =
2
+ | 'list-created'
3
+ | 'list-updated'
4
+ | 'list-deleted'
5
+ | 'item-created'
6
+ | 'item-updated'
7
+ | 'item-restored'
8
+ | 'item-deleted';
@@ -0,0 +1,2 @@
1
+ export * from './event-type';
2
+ export * from './message-type';
@@ -0,0 +1,9 @@
1
+ export type MessageType =
2
+ | 'error'
3
+ | 'list-created'
4
+ | 'list-updated'
5
+ | 'list-deleted'
6
+ | 'item-created'
7
+ | 'item-updated'
8
+ | 'item-restored'
9
+ | 'item-deleted';
package/tsconfig.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "compileOnSave": false,
3
+ "compilerOptions": {
4
+ "target": "es2019",
5
+ "module": "ESNext",
6
+ "moduleResolution": "node",
7
+ "allowJs": false,
8
+ "declaration": true,
9
+ "outDir": "./build",
10
+ "rootDir": "./src",
11
+ "strict": true,
12
+ "noImplicitAny": true,
13
+ "strictNullChecks": true,
14
+ "strictFunctionTypes": true,
15
+ "strictBindCallApply": true,
16
+ "strictPropertyInitialization": true,
17
+ "noImplicitThis": true,
18
+ "alwaysStrict": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": false,
21
+ "noImplicitReturns": true,
22
+ "esModuleInterop": true,
23
+ "inlineSourceMap": true,
24
+ },
25
+ "include": ["src/**/*"]
26
+ }