remult 0.16.3-exp.4 → 0.16.4

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.
Files changed (39) hide show
  1. package/esm/remult-knex/index.js +9 -2
  2. package/esm/server/expressBridge.d.ts +2 -0
  3. package/esm/server/expressBridge.js +14 -8
  4. package/esm/server/initAsyncHooks.js +0 -1
  5. package/esm/src/backend-tests/backend-database-test-setup.backend-spec.d.ts +1 -0
  6. package/esm/src/backend-tests/backend-database-test-setup.backend-spec.js +10 -0
  7. package/esm/src/backend-tests/my-test.backend-spec.js +48 -0
  8. package/esm/src/live-query/EventSourceLiveQuery.d.ts +5 -0
  9. package/esm/src/live-query/EventSourceLiveQuery.js +48 -0
  10. package/esm/src/live-query/EventSourceLiveQueryProvider.d.ts +6 -0
  11. package/esm/src/live-query/EventSourceLiveQueryProvider.js +24 -0
  12. package/esm/src/live-query/LiveQuery.d.ts +67 -0
  13. package/esm/src/live-query/LiveQuery.js +222 -0
  14. package/esm/src/live-query/LiveQueryManager.d.ts +33 -0
  15. package/esm/src/live-query/LiveQueryManager.js +97 -0
  16. package/esm/src/remult-proxy.js +4 -0
  17. package/esm/src/shared-tests/db-tests-setup.d.ts +1 -1
  18. package/esm/src/shared-tests/db-tests-setup.js +1 -0
  19. package/esm/src/valueConverters.js +2 -0
  20. package/package.json +1 -1
  21. package/remult-knex/index.js +16 -8
  22. package/server/expressBridge.d.ts +2 -0
  23. package/server/expressBridge.js +14 -8
  24. package/server/initAsyncHooks.js +0 -1
  25. package/src/backend-tests/backend-database-test-setup.backend-spec.d.ts +1 -0
  26. package/src/backend-tests/backend-database-test-setup.backend-spec.js +11 -1
  27. package/src/backend-tests/my-test.backend-spec.js +57 -0
  28. package/src/live-query/EventSourceLiveQuery.d.ts +5 -0
  29. package/src/live-query/EventSourceLiveQuery.js +62 -0
  30. package/src/live-query/EventSourceLiveQueryProvider.d.ts +6 -0
  31. package/src/live-query/EventSourceLiveQueryProvider.js +32 -0
  32. package/src/live-query/LiveQuery.d.ts +67 -0
  33. package/src/live-query/LiveQuery.js +305 -0
  34. package/src/live-query/LiveQueryManager.d.ts +33 -0
  35. package/src/live-query/LiveQueryManager.js +196 -0
  36. package/src/remult-proxy.js +4 -0
  37. package/src/shared-tests/db-tests-setup.d.ts +1 -1
  38. package/src/shared-tests/db-tests-setup.js +1 -0
  39. package/src/valueConverters.js +2 -0
@@ -31,6 +31,10 @@ export class RemultProxy {
31
31
  clearAllCache() {
32
32
  return this.remultFactory().clearAllCache();
33
33
  }
34
+ /*@internal*/
35
+ resetFactory() {
36
+ this.remultFactory = () => defaultRemult;
37
+ }
34
38
  get user() {
35
39
  return this.remultFactory().user;
36
40
  }
@@ -6,7 +6,7 @@ import { CategoriesForTesting } from "../tests/remult-3-entities";
6
6
  import { Status } from "../tests/testModel/models";
7
7
  export declare function itWithFocus(key: string, what: () => Promise<void>, focus?: boolean): void;
8
8
  export declare function testAll(key: string, what: dbTestWhatSignature, focus?: boolean): void;
9
- export declare function addDatabaseToTest(tester: dbTestMethodSignature): void;
9
+ export declare function addDatabaseToTest(tester: dbTestMethodSignature): dbTestMethodSignature;
10
10
  export declare function testInMemory(key: string, what: dbTestWhatSignature, focus?: boolean): void;
11
11
  export declare type dbTestWhatSignature = (db: {
12
12
  db: DataProvider;
@@ -22,6 +22,7 @@ export function addDatabaseToTest(tester) {
22
22
  test(tester);
23
23
  }
24
24
  databasesTesters.push(tester);
25
+ return tester;
25
26
  }
26
27
  export function testInMemory(key, what, focus = false) {
27
28
  itWithFocus(key + " - in memory", async () => {
@@ -100,6 +100,8 @@ ValueConverters.Boolean = {
100
100
  fromJson: value => {
101
101
  if (typeof value === "boolean")
102
102
  return value;
103
+ if (value === 1)
104
+ return true;
103
105
  if (value !== undefined && value !== null) {
104
106
  return value.toString().trim().toLowerCase() == 'true';
105
107
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.16.3-exp.4",
3
+ "version": "0.16.4",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -257,7 +257,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
257
257
  };
258
258
  KnexEntityDataProvider.prototype.insert = function (data) {
259
259
  return tslib_1.__awaiter(this, void 0, void 0, function () {
260
- var e, resultFilter, insertObject, _a, _b, x, v, key, e_3_1, insert, result, newId_1;
260
+ var e, resultFilter, insertObject, _a, _b, x, v, key, e_3_1, insert, newId_1, result, result;
261
261
  var e_3, _c;
262
262
  var _this = this;
263
263
  return tslib_1.__generator(this, function (_d) {
@@ -304,18 +304,26 @@ var KnexEntityDataProvider = /** @class */ (function () {
304
304
  return [7 /*endfinally*/];
305
305
  case 10:
306
306
  insert = this.knex(e.entityName).insert(insertObject);
307
- if (!remult3_1.isAutoIncrement(this.entity.idMetadata.field)) return [3 /*break*/, 12];
308
- return [4 /*yield*/, insert.returning(this.entity.idMetadata.field.key)];
307
+ if (!remult3_1.isAutoIncrement(this.entity.idMetadata.field)) return [3 /*break*/, 15];
308
+ if (!(this.knex.client.config.client === 'mysql2')) return [3 /*break*/, 12];
309
+ return [4 /*yield*/, this.knex(e.entityName).insert(insertObject, this.entity.idMetadata.field.key)];
309
310
  case 11:
310
311
  result = _d.sent();
311
- newId_1 = result[0].id;
312
- resultFilter = new filter_interfaces_1.Filter(function (x) { return x.isEqualTo(_this.entity.idMetadata.field, newId_1); });
312
+ newId_1 = result[0];
313
313
  return [3 /*break*/, 14];
314
- case 12: return [4 /*yield*/, insert];
314
+ case 12: return [4 /*yield*/, insert.returning(this.entity.idMetadata.field.key)];
315
315
  case 13:
316
- _d.sent();
316
+ result = _d.sent();
317
+ newId_1 = result[0].id;
317
318
  _d.label = 14;
318
- case 14: return [2 /*return*/, this.find({ where: resultFilter }).then(function (y) {
319
+ case 14:
320
+ resultFilter = new filter_interfaces_1.Filter(function (x) { return x.isEqualTo(_this.entity.idMetadata.field, newId_1); });
321
+ return [3 /*break*/, 17];
322
+ case 15: return [4 /*yield*/, insert];
323
+ case 16:
324
+ _d.sent();
325
+ _d.label = 17;
326
+ case 17: return [2 /*return*/, this.find({ where: resultFilter }).then(function (y) {
319
327
  return y[0];
320
328
  })];
321
329
  }
@@ -59,6 +59,8 @@ export interface GenericResponse {
59
59
  }
60
60
  export declare class RemultAsyncLocalStorage {
61
61
  private readonly remultObjectStorage;
62
+ static enable(): void;
63
+ static disable(): void;
62
64
  constructor(remultObjectStorage: import('async_hooks').AsyncLocalStorage<Remult>);
63
65
  run(remult: Remult, callback: VoidFunction): void;
64
66
  getRemult(): Remult;
@@ -40,6 +40,7 @@ function createRemultServer(options) {
40
40
  }
41
41
  });
42
42
  }); });
43
+ RemultAsyncLocalStorage.enable();
43
44
  if (options.initApi) {
44
45
  dataProvider = dataProvider.then(function (dp) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
45
46
  var remult;
@@ -90,6 +91,18 @@ var RemultAsyncLocalStorage = /** @class */ (function () {
90
91
  function RemultAsyncLocalStorage(remultObjectStorage) {
91
92
  this.remultObjectStorage = remultObjectStorage;
92
93
  }
94
+ RemultAsyncLocalStorage.enable = function () {
95
+ remult_proxy_1.remult.remultFactory = function () {
96
+ var r = RemultAsyncLocalStorage.instance.getRemult();
97
+ if (r)
98
+ return r;
99
+ else
100
+ throw new Error("remult object was requested outside of a valid context, try running it within initApi or a remult request cycle");
101
+ };
102
+ };
103
+ RemultAsyncLocalStorage.disable = function () {
104
+ remult_proxy_1.remult.resetFactory();
105
+ };
93
106
  RemultAsyncLocalStorage.prototype.run = function (remult, callback) {
94
107
  if (this.remultObjectStorage)
95
108
  this.remultObjectStorage.run(remult, callback);
@@ -98,7 +111,7 @@ var RemultAsyncLocalStorage = /** @class */ (function () {
98
111
  };
99
112
  RemultAsyncLocalStorage.prototype.getRemult = function () {
100
113
  if (!this.remultObjectStorage) {
101
- throw new Error("can't use static remult in this environment, `async_hooks` were not found");
114
+ throw new Error("can't use static remult in this environment, `async_hooks` were not initialized");
102
115
  }
103
116
  return this.remultObjectStorage.getStore();
104
117
  };
@@ -106,13 +119,6 @@ var RemultAsyncLocalStorage = /** @class */ (function () {
106
119
  return RemultAsyncLocalStorage;
107
120
  }());
108
121
  exports.RemultAsyncLocalStorage = RemultAsyncLocalStorage;
109
- remult_proxy_1.remult.remultFactory = function () {
110
- var r = RemultAsyncLocalStorage.instance.getRemult();
111
- if (r)
112
- return r;
113
- else
114
- throw new Error("remult object was requested outside of a valid context, try running it within initApi or a remult request cycle");
115
- };
116
122
  var RemultServerImplementation = /** @class */ (function () {
117
123
  function RemultServerImplementation(queue, options, dataProvider) {
118
124
  this.queue = queue;
@@ -5,7 +5,6 @@ var async_hooks_1 = require("async_hooks");
5
5
  var expressBridge_1 = require("./expressBridge");
6
6
  var init = false;
7
7
  function initAsyncHooks() {
8
- return;
9
8
  if (init)
10
9
  return;
11
10
  init = true;
@@ -1,5 +1,6 @@
1
1
  import { dbTestWhatSignature } from "../shared-tests/db-tests-setup";
2
2
  export declare const testKnexPGSqlImpl: (key: string, what: dbTestWhatSignature, focus?: boolean) => void;
3
+ export declare const mySqlTest: import("../shared-tests/db-tests-setup").dbTestMethodSignature;
3
4
  export declare function testPostgresImplementation(key: string, what: dbTestWhatSignature, focus?: boolean): void;
4
5
  export declare function testMongo(key: string, what: dbTestWhatSignature, focus?: boolean): void;
5
6
  import '../shared-tests';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.testMongo = exports.testPostgresImplementation = exports.testKnexPGSqlImpl = void 0;
3
+ exports.testMongo = exports.testPostgresImplementation = exports.mySqlTest = exports.testKnexPGSqlImpl = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var context_1 = require("../context");
6
6
  var remult_knex_1 = require("../../remult-knex");
@@ -87,6 +87,16 @@ if (true)
87
87
  filename: ":memory:"
88
88
  },
89
89
  }), "sqlite3"));
90
+ exports.mySqlTest = db_tests_setup_1.addDatabaseToTest(testKnexSqlImpl(Knex.default({
91
+ client: 'mysql2',
92
+ connection: {
93
+ user: 'root',
94
+ password: 'MASTERKEY',
95
+ host: '127.0.0.1',
96
+ database: 'test'
97
+ }
98
+ //debug: true
99
+ }), "mysql2"));
90
100
  var pg = postgres_1.createPostgresConnection({
91
101
  autoCreateTables: false
92
102
  });
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var tslib_1 = require("tslib");
4
+ var context_1 = require("../context");
4
5
  var remult_knex_1 = require("../../remult-knex");
5
6
  var dotenv_1 = require("dotenv");
6
7
  var backend_database_test_setup_backend_spec_1 = require("./backend-database-test-setup.backend-spec");
7
8
  var entityWithValidations_1 = require("../shared-tests/entityWithValidations");
8
9
  var sql_database_1 = require("../data-providers/sql-database");
10
+ var expressBridge_1 = require("../../server/expressBridge");
11
+ var initAsyncHooks_1 = require("../../server/initAsyncHooks");
12
+ var remult_proxy_1 = require("../remult-proxy");
9
13
  dotenv_1.config();
10
14
  backend_database_test_setup_backend_spec_1.testPostgresImplementation("default order by", function (_a) {
11
15
  var createEntity = _a.createEntity;
@@ -158,3 +162,56 @@ backend_database_test_setup_backend_spec_1.testKnexPGSqlImpl("knex filter2", fun
158
162
  });
159
163
  });
160
164
  }, false);
165
+ it("test async hooks and static remult", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
166
+ var gotException, promises;
167
+ return tslib_1.__generator(this, function (_a) {
168
+ switch (_a.label) {
169
+ case 0:
170
+ gotException = true;
171
+ try {
172
+ expressBridge_1.RemultAsyncLocalStorage.instance.getRemult();
173
+ gotException = false;
174
+ }
175
+ catch (_b) { }
176
+ expect(gotException).toBe(true);
177
+ initAsyncHooks_1.initAsyncHooks();
178
+ expect(expressBridge_1.RemultAsyncLocalStorage.instance.getRemult()).toBe(undefined);
179
+ expressBridge_1.RemultAsyncLocalStorage.enable();
180
+ try {
181
+ remult_proxy_1.remult.isAllowed(false);
182
+ gotException = false;
183
+ }
184
+ catch (_c) { }
185
+ expect(gotException).toBe(true);
186
+ promises = [];
187
+ expressBridge_1.RemultAsyncLocalStorage.instance.run(new context_1.Remult(), function () {
188
+ remult_proxy_1.remult.user = { id: 'noam' };
189
+ promises.push(new Promise(function (res) {
190
+ setTimeout(function () {
191
+ expect(remult_proxy_1.remult.user.id).toBe('noam');
192
+ res({});
193
+ }, 10);
194
+ }));
195
+ expressBridge_1.RemultAsyncLocalStorage.instance.run(new context_1.Remult(), function () {
196
+ remult_proxy_1.remult.user = { id: 'yoni' };
197
+ promises.push(new Promise(function (res) {
198
+ setTimeout(function () {
199
+ expect(remult_proxy_1.remult.user.id).toBe('yoni');
200
+ res({});
201
+ }, 10);
202
+ }));
203
+ });
204
+ promises.push(new Promise(function (res) {
205
+ setTimeout(function () {
206
+ expect(remult_proxy_1.remult.user.id).toBe('noam');
207
+ res({});
208
+ }, 10);
209
+ }));
210
+ });
211
+ return [4 /*yield*/, Promise.all(promises)];
212
+ case 1:
213
+ _a.sent();
214
+ return [2 /*return*/];
215
+ }
216
+ });
217
+ }); });
@@ -0,0 +1,5 @@
1
+ import { LiveQueryClient } from './LiveQuery';
2
+ export declare class EventSourceLiveQuery extends LiveQueryClient {
3
+ private wrapMessage?;
4
+ constructor(wrapMessage?: (what: () => void) => void);
5
+ }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventSourceLiveQuery = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var LiveQuery_1 = require("./LiveQuery");
6
+ var fetch_event_source_1 = require("@microsoft/fetch-event-source");
7
+ var remult_proxy_1 = require("../remult-proxy");
8
+ var EventSourceLiveQuery = /** @class */ (function (_super) {
9
+ tslib_1.__extends(EventSourceLiveQuery, _super);
10
+ function EventSourceLiveQuery(wrapMessage) {
11
+ var _this = _super.call(this, new EventSourceLiveQueryProvider(wrapMessage)) || this;
12
+ _this.wrapMessage = wrapMessage;
13
+ return _this;
14
+ }
15
+ return EventSourceLiveQuery;
16
+ }(LiveQuery_1.LiveQueryClient));
17
+ exports.EventSourceLiveQuery = EventSourceLiveQuery;
18
+ var EventSourceLiveQueryProvider = /** @class */ (function () {
19
+ function EventSourceLiveQueryProvider(wrapMessage, url, jwtToken) {
20
+ if (url === void 0) { url = undefined; }
21
+ this.wrapMessage = wrapMessage;
22
+ this.url = url;
23
+ this.jwtToken = jwtToken;
24
+ this.lastId = 0;
25
+ if (!this.wrapMessage)
26
+ this.wrapMessage = function (x) { return x(); };
27
+ if (!this.url) {
28
+ this.url = remult_proxy_1.remult.apiClient.url + '/' + LiveQuery_1.streamUrl;
29
+ }
30
+ }
31
+ EventSourceLiveQueryProvider.prototype.openStreamAndReturnCloseFunction = function (clientId, onMessage) {
32
+ var _this = this;
33
+ var ctrl = new AbortController();
34
+ var headers = {
35
+ "client-id": clientId
36
+ };
37
+ if (this.jwtToken) {
38
+ headers["Authorization"] = "Bearer " + this.jwtToken;
39
+ }
40
+ fetch_event_source_1.fetchEventSource(this.url, {
41
+ headers: headers,
42
+ onmessage: function (message) {
43
+ var mid = +message.id;
44
+ if (mid <= _this.lastId && _this.lastId - mid < 10)
45
+ return;
46
+ _this.lastId = mid;
47
+ console.log(message.data);
48
+ if (message.event !== 'keep-alive') {
49
+ _this.wrapMessage(function () { return onMessage(message); });
50
+ }
51
+ },
52
+ onopen: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
53
+ return tslib_1.__generator(this, function (_a) {
54
+ return [2 /*return*/];
55
+ });
56
+ }); },
57
+ signal: ctrl.signal,
58
+ });
59
+ return function () { return ctrl.abort(); };
60
+ };
61
+ return EventSourceLiveQueryProvider;
62
+ }());
@@ -0,0 +1,6 @@
1
+ import { LiveQueryProvider, MessageHandler } from "./LiveQuery";
2
+ export declare class EventSourceLiveQueryProvider implements LiveQueryProvider {
3
+ private wrapMessage?;
4
+ constructor(wrapMessage?: (what: () => void) => void);
5
+ openStreamAndReturnCloseFunction(clientId: string, onMessage: MessageHandler): Promise<VoidFunction>;
6
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventSourceLiveQueryProvider = void 0;
4
+ var remult_proxy_1 = require("../remult-proxy");
5
+ var LiveQuery_1 = require("./LiveQuery");
6
+ var EventSourceLiveQueryProvider = /** @class */ (function () {
7
+ function EventSourceLiveQueryProvider(wrapMessage) {
8
+ this.wrapMessage = wrapMessage;
9
+ if (!this.wrapMessage)
10
+ this.wrapMessage = function (x) { return x(); };
11
+ }
12
+ EventSourceLiveQueryProvider.prototype.openStreamAndReturnCloseFunction = function (clientId, onMessage) {
13
+ var _this = this;
14
+ var source = new EventSource(remult_proxy_1.remult.apiClient.url + '/' + LiveQuery_1.streamUrl + "?id=" + clientId, {
15
+ withCredentials: true
16
+ });
17
+ source.onmessage = function (e) {
18
+ _this.wrapMessage(function () {
19
+ return onMessage(JSON.parse(e.data));
20
+ });
21
+ };
22
+ return new Promise(function (res) {
23
+ source.onopen = function (e) {
24
+ res(function () {
25
+ source.close();
26
+ });
27
+ };
28
+ });
29
+ };
30
+ return EventSourceLiveQueryProvider;
31
+ }());
32
+ exports.EventSourceLiveQueryProvider = EventSourceLiveQueryProvider;
@@ -0,0 +1,67 @@
1
+ import { EntityOrderBy, FindOptions, Remult, Repository, RestDataProviderHttpProvider } from '../../index';
2
+ import { Allowed } from '../context';
3
+ import { ServerEventDispatcher } from './LiveQueryManager';
4
+ export declare const streamUrl = "stream1";
5
+ export interface LiveQueryProvider {
6
+ openStreamAndReturnCloseFunction(clientId: string, onMessage: MessageHandler): Promise<VoidFunction>;
7
+ }
8
+ export declare type MessageHandler = (message: {
9
+ data: any;
10
+ event: string;
11
+ }) => void;
12
+ export declare class LiveQueryClient {
13
+ lqp: LiveQueryProvider;
14
+ private provider?;
15
+ clientId: any;
16
+ private queries;
17
+ private channels;
18
+ constructor(lqp: LiveQueryProvider, provider?: RestDataProviderHttpProvider);
19
+ runPromise(p: Promise<any>): Promise<any>;
20
+ close(): void;
21
+ subscribeChannel<T>(key: string, onResult: (item: T) => void): () => void;
22
+ private closeIfNoListeners;
23
+ subscribe<entityType>(repo: Repository<entityType>, options: FindOptions<entityType>, onResult: (reducer: (prevState: entityType[]) => entityType[]) => void): () => void;
24
+ closeListener: Promise<VoidFunction>;
25
+ private openIfNoOpened;
26
+ }
27
+ export declare type listener = (message: any) => void;
28
+ export interface SubscribeToQueryArgs<entityType = any> {
29
+ entityKey: string;
30
+ orderBy?: EntityOrderBy<entityType>;
31
+ }
32
+ export declare type liveQueryMessage = {
33
+ type: "all";
34
+ data: any[];
35
+ } | {
36
+ type: "add";
37
+ data: any;
38
+ } | {
39
+ type: 'replace';
40
+ data: {
41
+ oldId: any;
42
+ item: any;
43
+ };
44
+ } | {
45
+ type: "remove";
46
+ data: {
47
+ id: any;
48
+ };
49
+ };
50
+ export interface SubscribeResult {
51
+ result: [];
52
+ id: string;
53
+ }
54
+ export interface ChannelSubscribe {
55
+ clientId: string;
56
+ channel: string;
57
+ remove: boolean;
58
+ }
59
+ export declare class AMessageChannel<messageType> {
60
+ private subscribedAllowed;
61
+ userCanSubscribe(channel: string, remult: Remult): boolean;
62
+ private key;
63
+ constructor(key: (string | ((remult: Remult) => string)), subscribedAllowed: Allowed);
64
+ send(what: messageType, remult?: Remult): void;
65
+ subscribe(client: LiveQueryClient, onValue: (value: messageType) => void, remult?: Remult): void;
66
+ dispatcher: ServerEventDispatcher;
67
+ }