remult 0.26.11-next.1 → 0.26.11

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.
@@ -29,13 +29,13 @@ export class SqliteCoreDataProvider {
29
29
  };
30
30
  }
31
31
  async transaction(action) {
32
- this.createCommand().execute('Begin Transaction');
32
+ await this.createCommand().execute('Begin Transaction');
33
33
  try {
34
34
  await action(this);
35
- this.createCommand().execute('Commit');
35
+ await this.createCommand().execute('Commit');
36
36
  }
37
37
  catch (err) {
38
- this.createCommand().execute('Rollback');
38
+ await this.createCommand().execute('Rollback');
39
39
  throw err;
40
40
  }
41
41
  }
@@ -0,0 +1,59 @@
1
+ import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
2
+ import { cast } from './src/isOfType.js';
3
+ export class TursoDataProvider extends SqliteCoreDataProvider {
4
+ client;
5
+ constructor(client) {
6
+ super(() => new TursoCommand(client), async () => {
7
+ await cast(this.client, 'close').close();
8
+ }, false);
9
+ this.client = client;
10
+ }
11
+ async transaction(action) {
12
+ const trans = await cast(this.client, 'transaction').transaction();
13
+ try {
14
+ await action(new TursoDataProvider(trans));
15
+ await trans.commit();
16
+ }
17
+ catch (err) {
18
+ await trans.rollback();
19
+ throw err;
20
+ }
21
+ }
22
+ }
23
+ class TursoCommand {
24
+ db;
25
+ values = {};
26
+ i = 1;
27
+ constructor(db) {
28
+ this.db = db;
29
+ }
30
+ async execute(sql) {
31
+ return new TursoSqlResult(await this.db.execute({
32
+ sql,
33
+ args: this.values,
34
+ }));
35
+ }
36
+ addParameterAndReturnSqlToken(val) {
37
+ return this.param(val);
38
+ }
39
+ param(val) {
40
+ if (val instanceof Date)
41
+ val = val.valueOf();
42
+ if (typeof val === 'boolean')
43
+ val = val ? 1 : 0;
44
+ const key = ':' + this.i++;
45
+ this.values[key.substring(1)] = val;
46
+ return key;
47
+ }
48
+ }
49
+ class TursoSqlResult {
50
+ result;
51
+ constructor(result) {
52
+ this.result = result;
53
+ this.rows = result.rows;
54
+ }
55
+ rows;
56
+ getColumnKeyInResultForIndexInSelect(index) {
57
+ return this.result.columns[index];
58
+ }
59
+ }
@@ -67,7 +67,7 @@ export class LiveQueryClient {
67
67
  onUnsubscribe = () => { };
68
68
  };
69
69
  }
70
- _actuallyClose() {
70
+ closeIfNoListeners() {
71
71
  if (this.client)
72
72
  if (this.queries.size === 0 && this.channels.size === 0) {
73
73
  this.runPromise(this.client.then((x) => x.close()));
@@ -76,12 +76,6 @@ export class LiveQueryClient {
76
76
  this.interval = undefined;
77
77
  }
78
78
  }
79
- keepAliveMs = 1000;
80
- closeIfNoListeners() {
81
- setTimeout(() => {
82
- this._actuallyClose();
83
- }, this.keepAliveMs);
84
- }
85
79
  subscribe(repo, options, listener) {
86
80
  let alive = true;
87
81
  let onUnsubscribe = () => {
@@ -168,8 +162,7 @@ export class LiveQueryClient {
168
162
  this.interval = setInterval(async () => {
169
163
  const ids = [];
170
164
  for (const q of this.queries.values()) {
171
- if (q.gotAnyResult)
172
- ids.push(q.queryChannel);
165
+ ids.push(q.queryChannel);
173
166
  }
174
167
  if (ids.length > 0) {
175
168
  let p = this.apiProvider();
@@ -10,12 +10,10 @@ export class LiveQuerySubscriber {
10
10
  sendDefaultState(onResult) {
11
11
  onResult(this.createReducerType(() => [...this.defaultQueryState], this.allItemsMessage(this.defaultQueryState)));
12
12
  }
13
- gotAnyResult = false;
14
13
  queryChannel;
15
14
  subscribeCode;
16
15
  unsubscribe = () => { };
17
16
  async setAllItems(result) {
18
- this.gotAnyResult = true;
19
17
  const items = await getRepositoryInternals(this.repo)._fromJsonArray(result, this.query.options);
20
18
  this.forListeners((listener) => {
21
19
  listener(() => {
@@ -3,7 +3,6 @@ export const flags = {
3
3
  };
4
4
  //y2 - soft-delete-discussion https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
5
5
  //y1 - live query with count #436
6
- //y1 - live query errort that appears in tests but I can't understand why - `open connection error `
7
6
  //y1 TODO - In the esm version of our tutorial - the imports are automatically .ts and not .js in react and not in vue
8
7
  //y1 TODO - consider id to also support keyof (id:['company','index']) - had problem with | (keyof Partial<entityType>)[] & `entity`
9
8
  //y1 TODO - readonly key: keyof MembersOnly<entityType> & string
@@ -23,7 +22,8 @@ export const flags = {
23
22
  }))
24
23
  */
25
24
  //p1 - consider upsert (where,set)
26
- //p1 - wait a second to close stream
25
+ //y1 - wait a second to close stream -see pr
26
+ //p1 - Consider enforcing serial operations on JSON database to prevent data loss
27
27
  //p1 - prepare the createEntity discussion
28
28
  //p1 - return error on connection error
29
29
  //p1 - article on displayValue including it's definition for entities that is used in relations
@@ -81,6 +81,8 @@ export const flags = {
81
81
  //p1 - when a tasks table exists in a different schema - we get many errors
82
82
  //p1 - live query with include
83
83
  //p1 - adjust angular tutorial starter kit for latest angular (as is in tutorial)
84
+ //y2 - Fix problem with promise all in sql expression recurssion - when using PromiseAll in row relation loading, some sql expressions appear is recursion call even if they are not
85
+ //p2 - when subscribe is forbidden - the query still runs after the renew process
84
86
  //p2 - 'update tasks set where id = $1
85
87
  //p2 - type metadata.key - to keyof entity - based on cwis input
86
88
  //y2 - remove __dirname from tutorials
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.26.11-next.1",
3
+ "version": "0.26.11",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -116,6 +116,11 @@
116
116
  "import": "./esm/remult-sqlite3.js",
117
117
  "types": "./remult-sqlite3.d.ts"
118
118
  },
119
+ "./remult-turso": {
120
+ "require": "./remult-turso.js",
121
+ "import": "./esm/remult-turso.js",
122
+ "types": "./remult-turso.d.ts"
123
+ },
119
124
  "./remult-bun-sqlite": {
120
125
  "require": "./remult-bun-sqlite.js",
121
126
  "import": "./esm/remult-bun-sqlite.js",
@@ -52,21 +52,26 @@ var SqliteCoreDataProvider = /** @class */ (function () {
52
52
  var err_1;
53
53
  return tslib_1.__generator(this, function (_a) {
54
54
  switch (_a.label) {
55
- case 0:
56
- this.createCommand().execute('Begin Transaction');
57
- _a.label = 1;
55
+ case 0: return [4 /*yield*/, this.createCommand().execute('Begin Transaction')];
58
56
  case 1:
59
- _a.trys.push([1, 3, , 4]);
60
- return [4 /*yield*/, action(this)];
61
- case 2:
62
57
  _a.sent();
63
- this.createCommand().execute('Commit');
64
- return [3 /*break*/, 4];
58
+ _a.label = 2;
59
+ case 2:
60
+ _a.trys.push([2, 5, , 7]);
61
+ return [4 /*yield*/, action(this)];
65
62
  case 3:
63
+ _a.sent();
64
+ return [4 /*yield*/, this.createCommand().execute('Commit')];
65
+ case 4:
66
+ _a.sent();
67
+ return [3 /*break*/, 7];
68
+ case 5:
66
69
  err_1 = _a.sent();
67
- this.createCommand().execute('Rollback');
70
+ return [4 /*yield*/, this.createCommand().execute('Rollback')];
71
+ case 6:
72
+ _a.sent();
68
73
  throw err_1;
69
- case 4: return [2 /*return*/];
74
+ case 7: return [2 /*return*/];
70
75
  }
71
76
  });
72
77
  });
@@ -1,5 +1,5 @@
1
1
  import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
2
- import { Database } from 'sqlite3';
2
+ import type { Database } from 'sqlite3';
3
3
  export declare class Sqlite3DataProvider extends SqliteCoreDataProvider {
4
4
  constructor(db: Database);
5
5
  }
@@ -0,0 +1,8 @@
1
+ import { SqlImplementation } from './index.js';
2
+ import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
3
+ import type { Client } from '@libsql/client';
4
+ export declare class TursoDataProvider extends SqliteCoreDataProvider {
5
+ private client;
6
+ constructor(client: Pick<Client, 'execute'>);
7
+ transaction(action: (sql: SqlImplementation) => Promise<void>): Promise<void>;
8
+ }
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TursoDataProvider = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var remult_sqlite_core_js_1 = require("./remult-sqlite-core.js");
6
+ var isOfType_js_1 = require("./src/isOfType.js");
7
+ var TursoDataProvider = /** @class */ (function (_super) {
8
+ tslib_1.__extends(TursoDataProvider, _super);
9
+ function TursoDataProvider(client) {
10
+ var _this = _super.call(this, function () { return new TursoCommand(client); }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
11
+ return tslib_1.__generator(this, function (_a) {
12
+ switch (_a.label) {
13
+ case 0: return [4 /*yield*/, (0, isOfType_js_1.cast)(this.client, 'close').close()];
14
+ case 1:
15
+ _a.sent();
16
+ return [2 /*return*/];
17
+ }
18
+ });
19
+ }); }, false) || this;
20
+ _this.client = client;
21
+ return _this;
22
+ }
23
+ TursoDataProvider.prototype.transaction = function (action) {
24
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
25
+ var trans, err_1;
26
+ return tslib_1.__generator(this, function (_a) {
27
+ switch (_a.label) {
28
+ case 0: return [4 /*yield*/, (0, isOfType_js_1.cast)(this.client, 'transaction').transaction()];
29
+ case 1:
30
+ trans = _a.sent();
31
+ _a.label = 2;
32
+ case 2:
33
+ _a.trys.push([2, 5, , 7]);
34
+ return [4 /*yield*/, action(new TursoDataProvider(trans))];
35
+ case 3:
36
+ _a.sent();
37
+ return [4 /*yield*/, trans.commit()];
38
+ case 4:
39
+ _a.sent();
40
+ return [3 /*break*/, 7];
41
+ case 5:
42
+ err_1 = _a.sent();
43
+ return [4 /*yield*/, trans.rollback()];
44
+ case 6:
45
+ _a.sent();
46
+ throw err_1;
47
+ case 7: return [2 /*return*/];
48
+ }
49
+ });
50
+ });
51
+ };
52
+ return TursoDataProvider;
53
+ }(remult_sqlite_core_js_1.SqliteCoreDataProvider));
54
+ exports.TursoDataProvider = TursoDataProvider;
55
+ var TursoCommand = /** @class */ (function () {
56
+ function TursoCommand(db) {
57
+ this.db = db;
58
+ this.values = {};
59
+ this.i = 1;
60
+ }
61
+ TursoCommand.prototype.execute = function (sql) {
62
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
63
+ var _a;
64
+ return tslib_1.__generator(this, function (_b) {
65
+ switch (_b.label) {
66
+ case 0:
67
+ _a = TursoSqlResult.bind;
68
+ return [4 /*yield*/, this.db.execute({
69
+ sql: sql,
70
+ args: this.values,
71
+ })];
72
+ case 1: return [2 /*return*/, new (_a.apply(TursoSqlResult, [void 0, _b.sent()]))()];
73
+ }
74
+ });
75
+ });
76
+ };
77
+ TursoCommand.prototype.addParameterAndReturnSqlToken = function (val) {
78
+ return this.param(val);
79
+ };
80
+ TursoCommand.prototype.param = function (val) {
81
+ if (val instanceof Date)
82
+ val = val.valueOf();
83
+ if (typeof val === 'boolean')
84
+ val = val ? 1 : 0;
85
+ var key = ':' + this.i++;
86
+ this.values[key.substring(1)] = val;
87
+ return key;
88
+ };
89
+ return TursoCommand;
90
+ }());
91
+ var TursoSqlResult = /** @class */ (function () {
92
+ function TursoSqlResult(result) {
93
+ this.result = result;
94
+ this.rows = result.rows;
95
+ }
96
+ TursoSqlResult.prototype.getColumnKeyInResultForIndexInSelect = function (index) {
97
+ return this.result.columns[index];
98
+ };
99
+ return TursoSqlResult;
100
+ }());
@@ -14,7 +14,6 @@ var LiveQueryClient = /** @class */ (function () {
14
14
  this.getUserId = getUserId;
15
15
  this.queries = new Map();
16
16
  this.channels = new Map();
17
- this.keepAliveMs = 1000;
18
17
  }
19
18
  LiveQueryClient.prototype.wrapMessageHandling = function (handleMessage) {
20
19
  var x = this.apiProvider().wrapMessageHandling;
@@ -88,7 +87,7 @@ var LiveQueryClient = /** @class */ (function () {
88
87
  });
89
88
  });
90
89
  };
91
- LiveQueryClient.prototype._actuallyClose = function () {
90
+ LiveQueryClient.prototype.closeIfNoListeners = function () {
92
91
  if (this.client)
93
92
  if (this.queries.size === 0 && this.channels.size === 0) {
94
93
  this.runPromise(this.client.then(function (x) { return x.close(); }));
@@ -97,12 +96,6 @@ var LiveQueryClient = /** @class */ (function () {
97
96
  this.interval = undefined;
98
97
  }
99
98
  };
100
- LiveQueryClient.prototype.closeIfNoListeners = function () {
101
- var _this = this;
102
- setTimeout(function () {
103
- _this._actuallyClose();
104
- }, this.keepAliveMs);
105
- };
106
99
  LiveQueryClient.prototype.subscribe = function (repo, options, listener) {
107
100
  var _this = this;
108
101
  var alive = true;
@@ -196,8 +189,7 @@ var LiveQueryClient = /** @class */ (function () {
196
189
  try {
197
190
  for (_a = tslib_1.__values(this.queries.values()), _b = _a.next(); !_b.done; _b = _a.next()) {
198
191
  q = _b.value;
199
- if (q.gotAnyResult)
200
- ids.push(q.queryChannel);
192
+ ids.push(q.queryChannel);
201
193
  }
202
194
  }
203
195
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -12,7 +12,6 @@ var LiveQuerySubscriber = /** @class */ (function () {
12
12
  function LiveQuerySubscriber(repo, query, userId) {
13
13
  this.repo = repo;
14
14
  this.query = query;
15
- this.gotAnyResult = false;
16
15
  this.unsubscribe = function () { };
17
16
  this.defaultQueryState = [];
18
17
  this.listeners = [];
@@ -29,9 +28,7 @@ var LiveQuerySubscriber = /** @class */ (function () {
29
28
  var items;
30
29
  return tslib_1.__generator(this, function (_a) {
31
30
  switch (_a.label) {
32
- case 0:
33
- this.gotAnyResult = true;
34
- return [4 /*yield*/, (0, repository_internals_js_1.getRepositoryInternals)(this.repo)._fromJsonArray(result, this.query.options)];
31
+ case 0: return [4 /*yield*/, (0, repository_internals_js_1.getRepositoryInternals)(this.repo)._fromJsonArray(result, this.query.options)];
35
32
  case 1:
36
33
  items = _a.sent();
37
34
  this.forListeners(function (listener) {
@@ -6,7 +6,6 @@ exports.flags = {
6
6
  };
7
7
  //y2 - soft-delete-discussion https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
8
8
  //y1 - live query with count #436
9
- //y1 - live query errort that appears in tests but I can't understand why - `open connection error `
10
9
  //y1 TODO - In the esm version of our tutorial - the imports are automatically .ts and not .js in react and not in vue
11
10
  //y1 TODO - consider id to also support keyof (id:['company','index']) - had problem with | (keyof Partial<entityType>)[] & `entity`
12
11
  //y1 TODO - readonly key: keyof MembersOnly<entityType> & string
@@ -26,7 +25,8 @@ exports.flags = {
26
25
  }))
27
26
  */
28
27
  //p1 - consider upsert (where,set)
29
- //p1 - wait a second to close stream
28
+ //y1 - wait a second to close stream -see pr
29
+ //p1 - Consider enforcing serial operations on JSON database to prevent data loss
30
30
  //p1 - prepare the createEntity discussion
31
31
  //p1 - return error on connection error
32
32
  //p1 - article on displayValue including it's definition for entities that is used in relations
@@ -84,6 +84,8 @@ exports.flags = {
84
84
  //p1 - when a tasks table exists in a different schema - we get many errors
85
85
  //p1 - live query with include
86
86
  //p1 - adjust angular tutorial starter kit for latest angular (as is in tutorial)
87
+ //y2 - Fix problem with promise all in sql expression recurssion - when using PromiseAll in row relation loading, some sql expressions appear is recursion call even if they are not
88
+ //p2 - when subscribe is forbidden - the query still runs after the renew process
87
89
  //p2 - 'update tasks set where id = $1
88
90
  //p2 - type metadata.key - to keyof entity - based on cwis input
89
91
  //y2 - remove __dirname from tutorials