@livequery/rest 1.0.18 → 1.0.21

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.
@@ -1,5 +1,4 @@
1
1
  import { Transporter, QueryOption, QueryStream } from '@livequery/types';
2
- import { Observable } from 'rxjs';
3
2
  declare type MaybePromise<T> = T | Promise<T>;
4
3
  export declare type RestTransporterConfig = {
5
4
  websocket_url: () => MaybePromise<string>;
@@ -7,22 +6,21 @@ export declare type RestTransporterConfig = {
7
6
  headers?: () => Promise<{
8
7
  [key: string]: string;
9
8
  }>;
10
- realtime?: boolean;
11
9
  };
12
10
  export declare class RestTransporter implements Transporter {
11
+ #private;
13
12
  private config;
14
- private queries;
15
13
  private socket;
16
14
  constructor(config: RestTransporterConfig);
17
- get<T>(ref: string, query?: any): Promise<T>;
18
15
  query<T extends {
19
16
  id: string;
20
- }>(ref: string, options?: Partial<QueryOption<T>>): Observable<QueryStream<T> | {
17
+ }>(ref: string, options?: Partial<QueryOption<T>>): import("rxjs").Observable<QueryStream<T> | {
21
18
  error: any;
22
19
  }> & {
23
20
  reload: () => void;
24
21
  };
25
22
  private call;
23
+ get<T>(ref: string, query?: any): Promise<T>;
26
24
  add<T extends {} = {}>(ref: string, data: Partial<T>): Promise<any>;
27
25
  update<T extends {} = {}>(ref: string, data: Partial<T>, method?: 'PATCH' | 'PUT'): Promise<any>;
28
26
  remove(ref: string): Promise<void>;
@@ -8,6 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
12
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
13
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
14
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
15
+ };
16
+ var _RestTransporter_instances, _RestTransporter_encode_query;
11
17
  Object.defineProperty(exports, "__esModule", { value: true });
12
18
  exports.RestTransporter = void 0;
13
19
  const rxjs_1 = require("rxjs");
@@ -18,44 +24,40 @@ const query_string_1 = require("query-string");
18
24
  class RestTransporter {
19
25
  constructor(config) {
20
26
  this.config = config;
21
- this.queries = new Set();
22
- config.realtime && (this.socket = new Socket_1.Socket(config.websocket_url));
23
- }
24
- get(ref, query = {}) {
25
- return __awaiter(this, void 0, void 0, function* () {
26
- return yield this.call(ref, 'GET', query, null);
27
- });
27
+ _RestTransporter_instances.add(this);
28
+ config.websocket_url && (this.socket = new Socket_1.Socket(config.websocket_url));
28
29
  }
29
30
  query(ref, options) {
30
31
  var _a;
31
32
  const $on_reload = new rxjs_2.Subject();
32
- const $when_socket_ready = ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.$last_state.pipe(operators_1.filter(s => s == 1))) || rxjs_1.of(true);
33
- const $on_can_reload = $on_reload.pipe(operators_1.filter(() => !this.socket || this.socket.$last_state.getValue() == 1));
34
- const http_request = rxjs_2.merge($when_socket_ready, $on_can_reload)
35
- .pipe(operators_1.mergeMap(() => this.call(ref, 'GET', options)), operators_1.map(response => {
36
- const collection_response = response;
37
- const document_response = response;
33
+ const http_request = (0, rxjs_2.merge)((0, rxjs_1.of)(1), ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.$reconnect) || (0, rxjs_1.of)(), $on_reload)
34
+ .pipe((0, operators_1.mergeMap)(() => this.call(ref, 'GET', options)), (0, operators_1.map)(({ data, error }) => {
35
+ var _a;
36
+ if (error)
37
+ throw error;
38
+ data.realtime_token && ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.subscribe(data.realtime_token));
38
39
  // If collection
39
- if (collection_response.items) {
40
- const { items, paging } = collection_response;
40
+ const collection = data;
41
+ if (collection.items) {
41
42
  return {
42
43
  data: {
43
- changes: items.map(data => ({ data, type: 'added', ref })),
44
- paging: Object.assign(Object.assign({}, paging), { n: 0 })
44
+ changes: collection.items.map(data => ({ data, type: 'added', ref })),
45
+ paging: Object.assign(Object.assign({}, collection.paging), { n: 0 })
45
46
  }
46
47
  };
47
48
  }
48
49
  // If document
50
+ const document = data;
49
51
  return {
50
52
  data: {
51
- changes: [{ data: document_response, type: 'added', ref }],
53
+ changes: [{ data: document.item, type: 'added', ref }],
52
54
  paging: { n: 0 }
53
55
  }
54
56
  };
55
- }), operators_1.catchError(error => rxjs_1.of({ error })));
56
- const websocket_sync = (!this.socket || options._cursor) ? rxjs_2.from([]) : (this.socket.listen(ref).pipe(operators_1.map((change) => ({ data: { changes: [change] } }))));
57
- return Object.assign(rxjs_2.merge(http_request, websocket_sync), {
58
- reload: () => $on_reload.next(0)
57
+ }), (0, operators_1.catchError)(error => (0, rxjs_1.of)({ error })));
58
+ const websocket_sync = (!this.socket || options._cursor) ? (0, rxjs_1.of)() : (this.socket.listen(ref).pipe((0, operators_1.map)((change) => ({ data: { changes: [change] } }))));
59
+ return Object.assign((0, rxjs_2.merge)(http_request, websocket_sync), {
60
+ reload: () => $on_reload.next()
59
61
  });
60
62
  }
61
63
  call(url, method, query = {}, payload) {
@@ -63,21 +65,20 @@ class RestTransporter {
63
65
  return __awaiter(this, void 0, void 0, function* () {
64
66
  const headers = Object.assign(Object.assign(Object.assign({}, (yield ((_b = (_a = this.config).headers) === null || _b === void 0 ? void 0 : _b.call(_a))) || {}), payload ? {
65
67
  'Content-Type': 'application/json'
66
- } : {}), this.config.realtime ? { socket_id: this.socket.socket_session } : {});
68
+ } : {}), this.socket ? { socket_id: this.socket.socket_session } : {});
67
69
  try {
68
- const { data, error, statusCode, message } = yield fetch(`${this.config.base_url()}/${url}${query ? `?${query_string_1.stringify(query)}` : ''}`, Object.assign({ method, headers: headers }, payload ? { body: JSON.stringify(payload) } : {}))
69
- .then(r => r.json());
70
- if (error)
71
- throw typeof error == 'string' ? { error: { message: error, code: error } } : error;
72
- if (statusCode > 205)
73
- throw { message };
74
- return data;
70
+ return yield fetch(`${this.config.base_url()}/${url}${__classPrivateFieldGet(this, _RestTransporter_instances, "m", _RestTransporter_encode_query).call(this, query)}`, Object.assign({ method, headers: headers }, payload ? { body: JSON.stringify(payload) } : {})).then(r => r.json());
75
71
  }
76
- catch (e) {
77
- throw e.error || e;
72
+ catch (error) {
73
+ throw error;
78
74
  }
79
75
  });
80
76
  }
77
+ get(ref, query = {}) {
78
+ return __awaiter(this, void 0, void 0, function* () {
79
+ return yield this.call(ref, 'GET', query, null);
80
+ });
81
+ }
81
82
  add(ref, data) {
82
83
  return __awaiter(this, void 0, void 0, function* () {
83
84
  return yield this.call(ref, 'POST', {}, data);
@@ -100,3 +101,9 @@ class RestTransporter {
100
101
  }
101
102
  }
102
103
  exports.RestTransporter = RestTransporter;
104
+ _RestTransporter_instances = new WeakSet(), _RestTransporter_encode_query = function _RestTransporter_encode_query(query) {
105
+ if (!query || Object.keys(query || {}).length == 0)
106
+ return '';
107
+ const encoded_query = Object.keys(query).reduce((o, key) => (Object.assign(Object.assign({}, o), { [key]: typeof query[key] == 'object' ? JSON.stringify(query[key]) : query[key] })), {});
108
+ return `?${(0, query_string_1.stringify)(encoded_query)}`;
109
+ };
package/build/Socket.d.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  import { UpdatedData } from "@livequery/types";
2
- import { Observable, BehaviorSubject } from "rxjs";
2
+ import { Observable, Subject } from "rxjs";
3
3
  export declare class Socket {
4
+ #private;
4
5
  private ws_url_fatory;
5
6
  private topics;
6
7
  private $input;
7
- readonly $last_state: BehaviorSubject<number>;
8
+ readonly $reconnect: Subject<void>;
8
9
  readonly socket_session: string;
9
- private init;
10
10
  constructor(ws_url_fatory: () => string | Promise<string>);
11
11
  private $sync;
12
+ subscribe(realtime_token: string): void;
12
13
  listen(ref: string): Observable<UpdatedData>;
13
14
  }
package/build/Socket.js CHANGED
@@ -8,6 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
12
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
13
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
14
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
15
+ };
16
+ var _Socket_instances, _Socket_init;
11
17
  Object.defineProperty(exports, "__esModule", { value: true });
12
18
  exports.Socket = void 0;
13
19
  const rxjs_1 = require("rxjs");
@@ -16,41 +22,12 @@ const uuid_1 = require("uuid");
16
22
  class Socket {
17
23
  constructor(ws_url_fatory) {
18
24
  this.ws_url_fatory = ws_url_fatory;
25
+ _Socket_instances.add(this);
19
26
  this.topics = new Map();
20
- this.$input = new rxjs_1.Subject();
21
- this.$last_state = new rxjs_1.BehaviorSubject(0);
22
- this.socket_session = uuid_1.v4();
23
- this.init();
24
- }
25
- init() {
26
- return __awaiter(this, void 0, void 0, function* () {
27
- if (typeof WebSocket == 'undefined')
28
- return;
29
- console.log('Use websocket to sync realtime data');
30
- for (let n = 0; true; n++) {
31
- console.log('Try connecting websocket .... ');
32
- const ws = new WebSocket(yield this.ws_url_fatory());
33
- const messages_handler = rxjs_1.fromEvent(ws, 'message').subscribe((evt) => {
34
- var _a;
35
- const { data, event } = JSON.parse(evt.data);
36
- (_a = this[`$${event}`]) === null || _a === void 0 ? void 0 : _a.call(this, data);
37
- });
38
- const connection_handler = rxjs_1.fromEvent(ws, 'open').subscribe(() => {
39
- console.log('Websocket connected');
40
- ws.send(JSON.stringify({ event: 'start', data: { id: this.socket_session } }));
41
- const { unsubscribe } = this.$input.subscribe(data => ws.send(JSON.stringify(data)));
42
- this.$last_state.next(ws.readyState);
43
- return unsubscribe;
44
- });
45
- yield rxjs_1.firstValueFrom(rxjs_1.merge(rxjs_1.fromEvent(ws, 'error'), rxjs_1.fromEvent(ws, 'close'), rxjs_1.fromEvent(ws, 'closed')));
46
- this.$last_state.next(ws.readyState);
47
- connection_handler.unsubscribe();
48
- messages_handler.unsubscribe();
49
- ws.close();
50
- console.log(`Websocket connection droped, reconnect in 1s`);
51
- yield new Promise(s => setTimeout(s, 1000));
52
- }
53
- });
27
+ this.$input = new rxjs_1.ReplaySubject(1000);
28
+ this.$reconnect = new rxjs_1.Subject();
29
+ this.socket_session = (0, uuid_1.v4)();
30
+ __classPrivateFieldGet(this, _Socket_instances, "m", _Socket_init).call(this);
54
31
  }
55
32
  $sync(data) {
56
33
  var _a, _b;
@@ -62,13 +39,16 @@ class Socket {
62
39
  (_b = this.topics.get(ref)) === null || _b === void 0 ? void 0 : _b.stream.next(Object.assign(Object.assign({}, change), { ref }));
63
40
  }
64
41
  }
42
+ subscribe(realtime_token) {
43
+ this.$input.next({ event: 'subscribe', data: { realtime_token } });
44
+ }
65
45
  listen(ref) {
66
46
  if (!this.topics.has(ref)) {
67
47
  const stream = new rxjs_1.Subject();
68
48
  this.topics.set(ref, { stream, listen_count: 0 });
69
49
  }
70
50
  this.topics.get(ref).listen_count++;
71
- const stream = this.topics.get(ref).stream.pipe(operators_1.finalize(() => {
51
+ return this.topics.get(ref).stream.pipe((0, operators_1.finalize)(() => {
72
52
  this.topics.get(ref).listen_count--;
73
53
  setTimeout(() => {
74
54
  if (this.topics.get(ref).listen_count == 0) {
@@ -76,7 +56,38 @@ class Socket {
76
56
  }
77
57
  }, 2000);
78
58
  }));
79
- return stream;
80
59
  }
81
60
  }
82
61
  exports.Socket = Socket;
62
+ _Socket_instances = new WeakSet(), _Socket_init = function _Socket_init() {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ if (typeof WebSocket == 'undefined')
65
+ return;
66
+ for (let n = 0; true; n++) {
67
+ console.log('Connecting websocket .... ');
68
+ const ws = new WebSocket(yield this.ws_url_fatory());
69
+ const messages_handler = (0, rxjs_1.fromEvent)(ws, 'message').subscribe((evt) => {
70
+ var _a;
71
+ const { data, event } = JSON.parse(evt.data);
72
+ (_a = this[`$${event}`]) === null || _a === void 0 ? void 0 : _a.call(this, data);
73
+ });
74
+ const data_sender = (0, rxjs_1.fromEvent)(ws, 'open').subscribe(() => {
75
+ console.log(n == 0 ? 'Websocket connected' : 'Websocket re-connected');
76
+ ws.send(JSON.stringify({ event: 'start', data: { id: this.socket_session } }));
77
+ const subscription = this.$input.subscribe(data => ws.send(JSON.stringify(data)));
78
+ n > 0 && this.$reconnect.next();
79
+ return () => {
80
+ subscription.unsubscribe();
81
+ this.$input.complete();
82
+ };
83
+ });
84
+ yield (0, rxjs_1.firstValueFrom)((0, rxjs_1.merge)((0, rxjs_1.fromEvent)(ws, 'error'), (0, rxjs_1.fromEvent)(ws, 'close'), (0, rxjs_1.fromEvent)(ws, 'closed')));
85
+ this.$input = new rxjs_1.ReplaySubject(1000);
86
+ data_sender.unsubscribe();
87
+ messages_handler.unsubscribe();
88
+ ws.close();
89
+ console.log(`Websocket connection dropped, reconnect in 1s ...`);
90
+ yield new Promise(s => setTimeout(s, 1000));
91
+ }
92
+ });
93
+ };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "repository": {
4
4
  "url": "https://github.com/livequery/rest"
5
5
  },
6
- "version": "1.0.18",
6
+ "version": "1.0.21",
7
7
  "description": "",
8
8
  "main": "build/index.js",
9
9
  "types": "build/index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "uuid": "^8.3.2"
18
18
  },
19
19
  "devDependencies": {
20
- "@livequery/types": "^1.0.29"
20
+ "@livequery/types": "1.0.37"
21
21
  },
22
22
  "peerDependencies": {},
23
23
  "scripts": {