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.
- package/esm/remult-sqlite-core.js +3 -3
- package/esm/remult-turso.js +59 -0
- package/esm/src/live-query/LiveQueryClient.js +2 -9
- package/esm/src/live-query/SubscriptionChannel.js +0 -2
- package/esm/src/remult3/remult3.js +4 -2
- package/package.json +6 -1
- package/remult-sqlite-core.js +15 -10
- package/remult-sqlite3.d.ts +1 -1
- package/remult-turso.d.ts +8 -0
- package/remult-turso.js +100 -0
- package/src/live-query/LiveQueryClient.js +2 -10
- package/src/live-query/SubscriptionChannel.js +1 -4
- package/src/remult3/remult3.js +4 -2
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
|
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",
|
package/remult-sqlite-core.js
CHANGED
|
@@ -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
|
-
|
|
64
|
-
|
|
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
|
|
74
|
+
case 7: return [2 /*return*/];
|
|
70
75
|
}
|
|
71
76
|
});
|
|
72
77
|
});
|
package/remult-sqlite3.d.ts
CHANGED
|
@@ -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
|
+
}
|
package/remult-turso.js
ADDED
|
@@ -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.
|
|
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
|
-
|
|
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) {
|
package/src/remult3/remult3.js
CHANGED
|
@@ -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
|
-
//
|
|
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
|