@livequery/rest 1.0.17 → 1.0.20

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,17 +6,16 @@ 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
15
  get<T>(ref: string, query?: any): Promise<T>;
18
16
  query<T extends {
19
17
  id: string;
20
- }>(query_id: number, ref: string, options?: Partial<QueryOption<T>>): Observable<QueryStream<T> | {
18
+ }>(ref: string, options?: Partial<QueryOption<T>>): import("rxjs").Observable<QueryStream<T> | {
21
19
  error: any;
22
20
  }> & {
23
21
  reload: () => 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,45 +24,45 @@ 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));
27
+ _RestTransporter_instances.add(this);
28
+ config.websocket_url && (this.socket = new Socket_1.Socket(config.websocket_url));
23
29
  }
24
30
  get(ref, query = {}) {
25
31
  return __awaiter(this, void 0, void 0, function* () {
26
32
  return yield this.call(ref, 'GET', query, null);
27
33
  });
28
34
  }
29
- query(query_id, ref, options) {
35
+ query(ref, options) {
30
36
  var _a;
31
37
  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;
38
+ 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)
39
+ .pipe((0, operators_1.mergeMap)(() => this.call(ref, 'GET', options)), (0, operators_1.map)(({ data, error }) => {
40
+ var _a;
41
+ if (error)
42
+ throw error;
43
+ data.realtime_token && ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.subscribe(data.realtime_token));
38
44
  // If collection
39
- if (collection_response.items) {
40
- const { items, paging } = collection_response;
45
+ const collection = data;
46
+ if (collection.items) {
41
47
  return {
42
48
  data: {
43
- changes: items.map(data => ({ data, type: 'added', ref })),
44
- paging: Object.assign(Object.assign({}, paging), { n: 0 })
49
+ changes: collection.items.map(data => ({ data, type: 'added', ref })),
50
+ paging: Object.assign(Object.assign({}, collection.paging), { n: 0 })
45
51
  }
46
52
  };
47
53
  }
48
54
  // If document
55
+ const document = data;
49
56
  return {
50
57
  data: {
51
- changes: [{ data: document_response, type: 'added', ref }],
58
+ changes: [{ data: document.item, type: 'added', ref }],
52
59
  paging: { n: 0 }
53
60
  }
54
61
  };
55
- }), operators_1.catchError(error => rxjs_1.of({ error })));
56
- const websocket_sync = (!this.socket || this.queries.has(query_id)) ? rxjs_2.from([]) : (this.queries.add(query_id),
57
- this.socket.listen(ref).pipe(operators_1.map((change) => ({ data: { changes: [change] } })), operators_1.finalize(() => this.queries.delete(query_id))));
58
- return Object.assign(rxjs_2.merge(http_request, websocket_sync), {
59
- reload: () => $on_reload.next(0)
62
+ }), (0, operators_1.catchError)(error => (0, rxjs_1.of)({ error })));
63
+ const websocket_sync = (!this.socket || options._cursor) ? (0, rxjs_1.of)() : (this.socket.listen(ref).pipe((0, operators_1.map)((change) => ({ data: { changes: [change] } }))));
64
+ return Object.assign((0, rxjs_2.merge)(http_request, websocket_sync), {
65
+ reload: () => $on_reload.next()
60
66
  });
61
67
  }
62
68
  call(url, method, query = {}, payload) {
@@ -64,14 +70,12 @@ class RestTransporter {
64
70
  return __awaiter(this, void 0, void 0, function* () {
65
71
  const headers = Object.assign(Object.assign(Object.assign({}, (yield ((_b = (_a = this.config).headers) === null || _b === void 0 ? void 0 : _b.call(_a))) || {}), payload ? {
66
72
  'Content-Type': 'application/json'
67
- } : {}), this.config.realtime ? { socket_id: this.socket.socket_session } : {});
73
+ } : {}), this.socket ? { socket_id: this.socket.socket_session } : {});
68
74
  try {
69
- 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) } : {}))
75
+ const { data, error } = 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) } : {}))
70
76
  .then(r => r.json());
71
77
  if (error)
72
- throw typeof error == 'string' ? { error: { message: error, code: error } } : error;
73
- if (statusCode > 205)
74
- throw { message };
78
+ throw error;
75
79
  return data;
76
80
  }
77
81
  catch (e) {
@@ -101,3 +105,9 @@ class RestTransporter {
101
105
  }
102
106
  }
103
107
  exports.RestTransporter = RestTransporter;
108
+ _RestTransporter_instances = new WeakSet(), _RestTransporter_encode_query = function _RestTransporter_encode_query(query) {
109
+ if (!query || Object.keys(query || {}).length == 0)
110
+ return '';
111
+ 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] })), {});
112
+ return `?${(0, query_string_1.stringify)(encoded_query)}`;
113
+ };
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,19 +39,55 @@ 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
- if (this.topics.get(ref).listen_count == 0) {
74
- this.$input.next({ event: 'unsubscribe', data: { ref } });
75
- }
53
+ setTimeout(() => {
54
+ if (this.topics.get(ref).listen_count == 0) {
55
+ this.$input.next({ event: 'unsubscribe', data: { ref } });
56
+ }
57
+ }, 2000);
76
58
  }));
77
- return stream;
78
59
  }
79
60
  }
80
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('Websocket 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.17",
6
+ "version": "1.0.20",
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.24"
20
+ "@livequery/types": "1.0.37"
21
21
  },
22
22
  "peerDependencies": {},
23
23
  "scripts": {