remult 0.26.11-next.1 → 0.26.12-next.0
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/live-query/data-provider-live-query-storage.js +2 -2
- package/esm/migrations/generate-migrations.js +2 -2
- package/esm/migrations/migrate.js +2 -2
- package/esm/remult-sqlite-core.js +3 -3
- package/esm/remult-turso.js +59 -0
- package/esm/server/JsonEntityFileStorage.js +1 -1
- package/esm/server/initDataProvider.js +7 -2
- package/esm/server/initDataProviderOrJson.js +6 -0
- package/esm/server/remult-api-server.js +44 -32
- package/esm/src/context.js +16 -7
- package/esm/src/data-providers/json-data-provider.js +8 -4
- package/esm/src/live-query/LiveQueryClient.js +2 -9
- package/esm/src/live-query/SubscriptionChannel.js +0 -2
- package/esm/src/remult-static.js +1 -0
- package/esm/src/remult3/remult3.js +15 -8
- package/live-query/data-provider-live-query-storage.js +2 -2
- package/migrations/generate-migrations.js +2 -2
- package/migrations/migrate.js +2 -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/server/JsonEntityFileStorage.js +1 -1
- package/server/initDataProvider.d.ts +1 -1
- package/server/initDataProvider.js +11 -3
- package/server/initDataProviderOrJson.d.ts +2 -0
- package/server/initDataProviderOrJson.js +17 -0
- package/server/remult-api-server.js +36 -23
- package/src/context.d.ts +11 -3
- package/src/context.js +33 -8
- package/src/data-providers/json-data-provider.d.ts +2 -1
- package/src/data-providers/json-data-provider.js +14 -9
- package/src/live-query/LiveQueryClient.js +2 -10
- package/src/live-query/SubscriptionChannel.js +1 -4
- package/src/remult-static.d.ts +2 -0
- package/src/remult-static.js +1 -0
- package/src/remult3/remult3.js +15 -8
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
|
-
import { initDataProvider } from '../server/initDataProvider.js';
|
|
3
2
|
import { Remult } from '../src/context.js';
|
|
4
3
|
import { EntityBase } from '../src/remult3/RepositoryImplementation.js';
|
|
5
4
|
import { Fields } from '../src/remult3/Fields.js';
|
|
6
5
|
import { Entity } from '../src/remult3/entity.js';
|
|
7
6
|
import { remultStatic } from '../src/remult-static.js';
|
|
7
|
+
import { initDataProviderOrJson } from '../server/initDataProviderOrJson';
|
|
8
8
|
export class DataProviderLiveQueryStorage {
|
|
9
9
|
repo;
|
|
10
10
|
dataProvider;
|
|
11
11
|
constructor(dataProvider) {
|
|
12
|
-
this.dataProvider =
|
|
12
|
+
this.dataProvider = initDataProviderOrJson(dataProvider);
|
|
13
13
|
this.repo = this.dataProvider.then((dp) => new Remult(dp).repo(LiveQueryStorageEntity));
|
|
14
14
|
}
|
|
15
15
|
async ensureSchema() {
|
|
@@ -4,7 +4,7 @@ import { compareMigrationSnapshot, emptySnapshot, } from './compare-migration-sn
|
|
|
4
4
|
import { updateMigrationsFile } from './update-migrations-ts-file.js';
|
|
5
5
|
import { DefaultMigrationBuilder, } from './migration-types.js';
|
|
6
6
|
import { isOfType } from '../src/isOfType.js';
|
|
7
|
-
import {
|
|
7
|
+
import { initDataProviderOrJson } from '../server/initDataProviderOrJson';
|
|
8
8
|
/**
|
|
9
9
|
* Generates migration scripts based on changes in entities.
|
|
10
10
|
*
|
|
@@ -21,7 +21,7 @@ export async function generateMigrations(options) {
|
|
|
21
21
|
const migrationDir = options.migrationsFolder || path.join(process.cwd(), 'src/migrations');
|
|
22
22
|
const snapshotFileName = options.snapshotFile || path.join(migrationDir, 'migrations-snapshot.json');
|
|
23
23
|
const migrationsTSFilename = options.migrationsTSFile || path.join(migrationDir, 'migrations.ts');
|
|
24
|
-
const dataProvider = await
|
|
24
|
+
const dataProvider = await initDataProviderOrJson(options.dataProvider);
|
|
25
25
|
for (const p of [snapshotFileName, migrationsTSFilename]) {
|
|
26
26
|
if (!fs.existsSync(path.dirname(p))) {
|
|
27
27
|
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
2
|
import { Entity, IdEntity, Fields, remult, Remult, } from '../index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { initDataProviderOrJson } from '../server/initDataProviderOrJson';
|
|
4
4
|
import { doTransaction } from '../src/context.js';
|
|
5
5
|
import { cast, isOfType } from '../src/isOfType.js';
|
|
6
6
|
/**
|
|
@@ -17,7 +17,7 @@ import { cast, isOfType } from '../src/isOfType.js';
|
|
|
17
17
|
*/
|
|
18
18
|
export async function migrate(options) {
|
|
19
19
|
let migrationTableName = options.migrationsTable || '__remult_migrations_version';
|
|
20
|
-
const dataProvider = await
|
|
20
|
+
const dataProvider = await initDataProviderOrJson(options.dataProvider);
|
|
21
21
|
const prev = remult.dataProvider;
|
|
22
22
|
remult.dataProvider = dataProvider;
|
|
23
23
|
try {
|
|
@@ -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
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { remultStatic } from '../src/remult-static';
|
|
2
|
+
export function initDataProvider(optionsDataProvider, useStaticDefault, defaultDataProvider) {
|
|
2
3
|
let dataProvider;
|
|
3
4
|
if (typeof optionsDataProvider === 'function') {
|
|
4
5
|
dataProvider = optionsDataProvider();
|
|
@@ -8,7 +9,11 @@ export function initDataProvider(optionsDataProvider) {
|
|
|
8
9
|
dataProvider = dataProvider.then(async (dp) => {
|
|
9
10
|
if (dp)
|
|
10
11
|
return dp;
|
|
11
|
-
|
|
12
|
+
if (useStaticDefault)
|
|
13
|
+
dp = await remultStatic.defaultDataProvider();
|
|
14
|
+
if (dp)
|
|
15
|
+
return dp;
|
|
16
|
+
return defaultDataProvider?.();
|
|
12
17
|
});
|
|
13
18
|
return dataProvider;
|
|
14
19
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { initDataProvider } from './initDataProvider';
|
|
2
|
+
export function initDataProviderOrJson(dataProvider) {
|
|
3
|
+
return initDataProvider(dataProvider, false, async () => {
|
|
4
|
+
return new (await import('./JsonEntityFileStorage.js')).JsonFileDataProvider('./db');
|
|
5
|
+
});
|
|
6
|
+
}
|
|
@@ -10,10 +10,10 @@ import { Entity } from '../src/remult3/entity.js';
|
|
|
10
10
|
import { getEntityKey } from '../src/remult3/getEntityRef.js';
|
|
11
11
|
import { Action, classBackendMethodsArray } from '../src/server-action.js';
|
|
12
12
|
import { serverActionField } from '../src/server-action-info.js';
|
|
13
|
-
import { initDataProvider } from './initDataProvider.js';
|
|
14
13
|
import { remultStatic } from '../src/remult-static.js';
|
|
15
14
|
import remultAdminHtml from './remult-admin.js';
|
|
16
15
|
import { isOfType } from '../src/isOfType.js';
|
|
16
|
+
import { initDataProviderOrJson } from './initDataProviderOrJson';
|
|
17
17
|
export function createRemultServerCore(options, serverCoreOptions) {
|
|
18
18
|
if (!options) {
|
|
19
19
|
options = {};
|
|
@@ -30,7 +30,8 @@ export function createRemultServerCore(options, serverCoreOptions) {
|
|
|
30
30
|
if (!options.queueStorage) {
|
|
31
31
|
options.queueStorage = new InMemoryQueueStorage();
|
|
32
32
|
}
|
|
33
|
-
let dataProvider =
|
|
33
|
+
let dataProvider = initDataProviderOrJson(options.dataProvider);
|
|
34
|
+
remultStatic.defaultDataProvider = () => dataProvider;
|
|
34
35
|
if (options.ensureSchema === undefined)
|
|
35
36
|
options.ensureSchema = true;
|
|
36
37
|
RemultAsyncLocalStorage.enable();
|
|
@@ -277,6 +278,8 @@ export class RemultServerImplementation {
|
|
|
277
278
|
x.subscriptionServer = this.subscriptionServer;
|
|
278
279
|
x.liveQueryStorage = this.liveQueryStorage;
|
|
279
280
|
return await what(x);
|
|
281
|
+
}, {
|
|
282
|
+
dataProvider,
|
|
280
283
|
});
|
|
281
284
|
}
|
|
282
285
|
process(what) {
|
|
@@ -293,37 +296,46 @@ export class RemultServerImplementation {
|
|
|
293
296
|
}
|
|
294
297
|
let myReq = new ExpressRequestBridgeToDataApiRequest(genReq);
|
|
295
298
|
let myRes = new ExpressResponseBridgeToDataApiResponse(origRes, req, this.options.error);
|
|
296
|
-
|
|
297
|
-
await
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
299
|
+
if (remultStatic.asyncContext.isInInitRequest())
|
|
300
|
+
return await what(remultStatic.asyncContext.getStore().remult, myReq, myRes, genReq, origRes, req);
|
|
301
|
+
else
|
|
302
|
+
try {
|
|
303
|
+
await this.runWithRemult(async (remult) => {
|
|
304
|
+
if (req) {
|
|
305
|
+
remultStatic.asyncContext.setInInitRequest(true);
|
|
306
|
+
try {
|
|
307
|
+
let user;
|
|
308
|
+
if (this.options.getUser)
|
|
309
|
+
user = await this.options.getUser(req);
|
|
310
|
+
else {
|
|
311
|
+
user = req['user'];
|
|
312
|
+
if (!user)
|
|
313
|
+
user = req['auth'];
|
|
314
|
+
}
|
|
315
|
+
if (user)
|
|
316
|
+
remult.user = user;
|
|
317
|
+
if (this.options.initRequest) {
|
|
318
|
+
await this.options.initRequest(req, {
|
|
319
|
+
remult,
|
|
320
|
+
get liveQueryStorage() {
|
|
321
|
+
return remult.liveQueryStorage;
|
|
322
|
+
},
|
|
323
|
+
set liveQueryStorage(value) {
|
|
324
|
+
remult.liveQueryStorage = value;
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
finally {
|
|
330
|
+
remultStatic.asyncContext.setInInitRequest(false);
|
|
331
|
+
}
|
|
319
332
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
333
|
+
await what(remult, myReq, myRes, genReq, origRes, req);
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
catch (err) {
|
|
337
|
+
myRes.error(err, undefined);
|
|
338
|
+
}
|
|
327
339
|
};
|
|
328
340
|
}
|
|
329
341
|
async getRemult(req) {
|
package/esm/src/context.js
CHANGED
|
@@ -7,13 +7,14 @@ import { serverActionField } from './server-action-info.js';
|
|
|
7
7
|
import { buildRestDataProvider, isExternalHttpProvider, } from './buildRestDataProvider.js';
|
|
8
8
|
import { verifyFieldRelationInfo } from './remult3/relationInfoMember.js';
|
|
9
9
|
import { remultStatic, resetFactory } from './remult-static.js';
|
|
10
|
+
import { initDataProvider } from '../server/initDataProvider';
|
|
10
11
|
export class RemultAsyncLocalStorage {
|
|
11
12
|
remultObjectStorage;
|
|
12
13
|
static enable() {
|
|
13
14
|
remultStatic.remultFactory = () => {
|
|
14
|
-
const r = remultStatic.asyncContext.
|
|
15
|
+
const r = remultStatic.asyncContext.getStore();
|
|
15
16
|
if (r)
|
|
16
|
-
return r;
|
|
17
|
+
return r.remult;
|
|
17
18
|
else
|
|
18
19
|
throw new Error('remult object was requested outside of a valid context, try running it within initApi or a remult request cycle');
|
|
19
20
|
};
|
|
@@ -26,12 +27,21 @@ export class RemultAsyncLocalStorage {
|
|
|
26
27
|
}
|
|
27
28
|
async run(remult, callback) {
|
|
28
29
|
if (this.remultObjectStorage) {
|
|
29
|
-
return this.remultObjectStorage.run(remult, () => callback(remult));
|
|
30
|
+
return this.remultObjectStorage.run({ remult }, () => callback(remult));
|
|
30
31
|
}
|
|
31
32
|
else
|
|
32
33
|
return callback(remult);
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
+
isInInitRequest() {
|
|
36
|
+
return this.remultObjectStorage?.getStore()?.inInitRequest;
|
|
37
|
+
}
|
|
38
|
+
setInInitRequest(val) {
|
|
39
|
+
const store = this.remultObjectStorage?.getStore();
|
|
40
|
+
if (!store)
|
|
41
|
+
return;
|
|
42
|
+
store.inInitRequest = val;
|
|
43
|
+
}
|
|
44
|
+
getStore() {
|
|
35
45
|
if (!this.remultObjectStorage) {
|
|
36
46
|
throw new Error("can't use static remult in this environment, `async_hooks` were not initialized");
|
|
37
47
|
}
|
|
@@ -282,9 +292,8 @@ class transactionLiveQueryPublisher {
|
|
|
282
292
|
}
|
|
283
293
|
}
|
|
284
294
|
}
|
|
285
|
-
export function withRemult(callback, options) {
|
|
295
|
+
export async function withRemult(callback, options) {
|
|
286
296
|
const remult = new Remult();
|
|
287
|
-
|
|
288
|
-
remult.dataProvider = options.dataProvider;
|
|
297
|
+
remult.dataProvider = await initDataProvider(options?.dataProvider, true, async () => remult.dataProvider);
|
|
289
298
|
return remultStatic.asyncContext.run(remult, (r) => callback(r));
|
|
290
299
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { ArrayEntityDataProvider } from './array-entity-data-provider.js';
|
|
2
2
|
export class JsonDataProvider {
|
|
3
3
|
storage;
|
|
4
|
-
|
|
4
|
+
formatted;
|
|
5
|
+
constructor(storage, formatted = false) {
|
|
5
6
|
this.storage = storage;
|
|
7
|
+
this.formatted = formatted;
|
|
6
8
|
}
|
|
7
9
|
getEntityDataProvider(entity) {
|
|
8
|
-
return new JsonEntityDataProvider(entity, this.storage);
|
|
10
|
+
return new JsonEntityDataProvider(entity, this.storage, this.formatted);
|
|
9
11
|
}
|
|
10
12
|
async transaction(action) {
|
|
11
13
|
await action(this);
|
|
@@ -14,9 +16,11 @@ export class JsonDataProvider {
|
|
|
14
16
|
class JsonEntityDataProvider {
|
|
15
17
|
entity;
|
|
16
18
|
helper;
|
|
17
|
-
|
|
19
|
+
formatted;
|
|
20
|
+
constructor(entity, helper, formatted) {
|
|
18
21
|
this.entity = entity;
|
|
19
22
|
this.helper = helper;
|
|
23
|
+
this.formatted = formatted;
|
|
20
24
|
}
|
|
21
25
|
async loadEntityData(what) {
|
|
22
26
|
let data = [];
|
|
@@ -25,7 +29,7 @@ class JsonEntityDataProvider {
|
|
|
25
29
|
if (s)
|
|
26
30
|
data = JSON.parse(s);
|
|
27
31
|
let dp = new ArrayEntityDataProvider(this.entity, () => data);
|
|
28
|
-
return what(dp, async () => await this.helper.setItem(dbName, JSON.stringify(data, undefined, 2)));
|
|
32
|
+
return what(dp, async () => await this.helper.setItem(dbName, JSON.stringify(data, undefined, this.formatted ? 2 : undefined)));
|
|
29
33
|
}
|
|
30
34
|
p = Promise.resolve();
|
|
31
35
|
find(options) {
|
|
@@ -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(() => {
|
package/esm/src/remult-static.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
export const flags = {
|
|
2
2
|
error500RetryCount: 4,
|
|
3
3
|
};
|
|
4
|
-
//y2 - soft-delete-discussion https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
|
|
5
4
|
//y1 - live query with count #436
|
|
6
|
-
//y1 -
|
|
5
|
+
//y1 - https://github.com/remult/remult/discussions/438
|
|
6
|
+
//p1 - discuss next auth withRemult paradox
|
|
7
|
+
//p1 - maybe the default withRemult should by default use the data provider set by the remultExpress
|
|
8
|
+
//p1 - withRemult to support the full range of data provider.
|
|
7
9
|
//y1 TODO - In the esm version of our tutorial - the imports are automatically .ts and not .js in react and not in vue
|
|
8
10
|
//y1 TODO - consider id to also support keyof (id:['company','index']) - had problem with | (keyof Partial<entityType>)[] & `entity`
|
|
9
11
|
//y1 TODO - readonly key: keyof MembersOnly<entityType> & string
|
|
10
12
|
//y1 - talk about insert / update / delete with relations
|
|
11
13
|
/*
|
|
12
|
-
|
|
14
|
+
repo(Order).insert({},{
|
|
13
15
|
relations:{
|
|
14
16
|
orderItems:[{},{},{}]
|
|
15
17
|
}
|
|
@@ -17,13 +19,16 @@ export const flags = {
|
|
|
17
19
|
*/
|
|
18
20
|
//y1 - repo batch - for multiple operations:
|
|
19
21
|
/*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const result = await repo.batch(x=>({
|
|
23
|
+
data:x.find(),
|
|
24
|
+
count:x.count()
|
|
25
|
+
}))
|
|
24
26
|
*/
|
|
27
|
+
//p1 - consider in json storage, to store the json without spaces
|
|
25
28
|
//p1 - consider upsert (where,set)
|
|
26
|
-
//
|
|
29
|
+
//y1 - wait a second to close stream -see pr
|
|
30
|
+
//p1 - Consider enforcing serial operations on JSON database to prevent data loss
|
|
31
|
+
//y2 - soft-delete-discussion https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
|
|
27
32
|
//p1 - prepare the createEntity discussion
|
|
28
33
|
//p1 - return error on connection error
|
|
29
34
|
//p1 - article on displayValue including it's definition for entities that is used in relations
|
|
@@ -81,6 +86,8 @@ export const flags = {
|
|
|
81
86
|
//p1 - when a tasks table exists in a different schema - we get many errors
|
|
82
87
|
//p1 - live query with include
|
|
83
88
|
//p1 - adjust angular tutorial starter kit for latest angular (as is in tutorial)
|
|
89
|
+
//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
|
|
90
|
+
//p2 - when subscribe is forbidden - the query still runs after the renew process
|
|
84
91
|
//p2 - 'update tasks set where id = $1
|
|
85
92
|
//p2 - type metadata.key - to keyof entity - based on cwis input
|
|
86
93
|
//y2 - remove __dirname from tutorials
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LiveQueryStorageEntity = exports.DataProviderLiveQueryStorage = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
var initDataProvider_js_1 = require("../server/initDataProvider.js");
|
|
6
5
|
var context_js_1 = require("../src/context.js");
|
|
7
6
|
var RepositoryImplementation_js_1 = require("../src/remult3/RepositoryImplementation.js");
|
|
8
7
|
var Fields_js_1 = require("../src/remult3/Fields.js");
|
|
9
8
|
var entity_js_1 = require("../src/remult3/entity.js");
|
|
10
9
|
var remult_static_js_1 = require("../src/remult-static.js");
|
|
10
|
+
var initDataProviderOrJson_1 = require("../server/initDataProviderOrJson");
|
|
11
11
|
var DataProviderLiveQueryStorage = /** @class */ (function () {
|
|
12
12
|
function DataProviderLiveQueryStorage(dataProvider) {
|
|
13
|
-
this.dataProvider = (0,
|
|
13
|
+
this.dataProvider = (0, initDataProviderOrJson_1.initDataProviderOrJson)(dataProvider);
|
|
14
14
|
this.repo = this.dataProvider.then(function (dp) {
|
|
15
15
|
return new context_js_1.Remult(dp).repo(LiveQueryStorageEntity);
|
|
16
16
|
});
|
|
@@ -8,7 +8,7 @@ var compare_migration_snapshots_js_1 = require("./compare-migration-snapshots.js
|
|
|
8
8
|
var update_migrations_ts_file_js_1 = require("./update-migrations-ts-file.js");
|
|
9
9
|
var migration_types_js_1 = require("./migration-types.js");
|
|
10
10
|
var isOfType_js_1 = require("../src/isOfType.js");
|
|
11
|
-
var
|
|
11
|
+
var initDataProviderOrJson_1 = require("../server/initDataProviderOrJson");
|
|
12
12
|
/**
|
|
13
13
|
* Generates migration scripts based on changes in entities.
|
|
14
14
|
*
|
|
@@ -31,7 +31,7 @@ function generateMigrations(options) {
|
|
|
31
31
|
migrationDir = options.migrationsFolder || path_1.default.join(process.cwd(), 'src/migrations');
|
|
32
32
|
snapshotFileName = options.snapshotFile || path_1.default.join(migrationDir, 'migrations-snapshot.json');
|
|
33
33
|
migrationsTSFilename = options.migrationsTSFile || path_1.default.join(migrationDir, 'migrations.ts');
|
|
34
|
-
return [4 /*yield*/, (0,
|
|
34
|
+
return [4 /*yield*/, (0, initDataProviderOrJson_1.initDataProviderOrJson)(options.dataProvider)];
|
|
35
35
|
case 1:
|
|
36
36
|
dataProvider = _d.sent();
|
|
37
37
|
try {
|
package/migrations/migrate.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.migrate = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var index_js_1 = require("../index.js");
|
|
6
|
-
var
|
|
6
|
+
var initDataProviderOrJson_1 = require("../server/initDataProviderOrJson");
|
|
7
7
|
var context_js_1 = require("../src/context.js");
|
|
8
8
|
var isOfType_js_1 = require("../src/isOfType.js");
|
|
9
9
|
/**
|
|
@@ -26,7 +26,7 @@ function migrate(options) {
|
|
|
26
26
|
switch (_a.label) {
|
|
27
27
|
case 0:
|
|
28
28
|
migrationTableName = options.migrationsTable || '__remult_migrations_version';
|
|
29
|
-
return [4 /*yield*/, (0,
|
|
29
|
+
return [4 /*yield*/, (0, initDataProviderOrJson_1.initDataProviderOrJson)(options.dataProvider)];
|
|
30
30
|
case 1:
|
|
31
31
|
dataProvider = _a.sent();
|
|
32
32
|
prev = index_js_1.remult.dataProvider;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remult",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.12-next.0",
|
|
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
|
+
}());
|
|
@@ -28,7 +28,7 @@ exports.JsonEntityFileStorage = JsonEntityFileStorage;
|
|
|
28
28
|
var JsonFileDataProvider = /** @class */ (function (_super) {
|
|
29
29
|
tslib_1.__extends(JsonFileDataProvider, _super);
|
|
30
30
|
function JsonFileDataProvider(folderPath) {
|
|
31
|
-
return _super.call(this, new JsonEntityFileStorage(folderPath)) || this;
|
|
31
|
+
return _super.call(this, new JsonEntityFileStorage(folderPath), true) || this;
|
|
32
32
|
}
|
|
33
33
|
return JsonFileDataProvider;
|
|
34
34
|
}(index_js_1.JsonDataProvider));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { DataProvider } from '../src/data-interfaces.js';
|
|
2
|
-
export declare function initDataProvider(optionsDataProvider
|
|
2
|
+
export declare function initDataProvider(optionsDataProvider: DataProvider | Promise<DataProvider> | (() => Promise<DataProvider | undefined>) | undefined, useStaticDefault: boolean, defaultDataProvider: () => Promise<DataProvider>): Promise<DataProvider>;
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.initDataProvider = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
|
|
5
|
+
var remult_static_1 = require("../src/remult-static");
|
|
6
|
+
function initDataProvider(optionsDataProvider, useStaticDefault, defaultDataProvider) {
|
|
6
7
|
var _this = this;
|
|
7
8
|
var dataProvider;
|
|
8
9
|
if (typeof optionsDataProvider === 'function') {
|
|
@@ -16,8 +17,15 @@ function initDataProvider(optionsDataProvider) {
|
|
|
16
17
|
case 0:
|
|
17
18
|
if (dp)
|
|
18
19
|
return [2 /*return*/, dp];
|
|
19
|
-
return [
|
|
20
|
-
|
|
20
|
+
if (!useStaticDefault) return [3 /*break*/, 2];
|
|
21
|
+
return [4 /*yield*/, remult_static_1.remultStatic.defaultDataProvider()];
|
|
22
|
+
case 1:
|
|
23
|
+
dp = _a.sent();
|
|
24
|
+
_a.label = 2;
|
|
25
|
+
case 2:
|
|
26
|
+
if (dp)
|
|
27
|
+
return [2 /*return*/, dp];
|
|
28
|
+
return [2 /*return*/, defaultDataProvider === null || defaultDataProvider === void 0 ? void 0 : defaultDataProvider()];
|
|
21
29
|
}
|
|
22
30
|
});
|
|
23
31
|
}); });
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initDataProviderOrJson = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var initDataProvider_1 = require("./initDataProvider");
|
|
6
|
+
function initDataProviderOrJson(dataProvider) {
|
|
7
|
+
var _this = this;
|
|
8
|
+
return (0, initDataProvider_1.initDataProvider)(dataProvider, false, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
9
|
+
return tslib_1.__generator(this, function (_a) {
|
|
10
|
+
switch (_a.label) {
|
|
11
|
+
case 0: return [4 /*yield*/, Promise.resolve().then(function () { return tslib_1.__importStar(require('./JsonEntityFileStorage.js')); })];
|
|
12
|
+
case 1: return [2 /*return*/, new (_a.sent()).JsonFileDataProvider('./db')];
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}); });
|
|
16
|
+
}
|
|
17
|
+
exports.initDataProviderOrJson = initDataProviderOrJson;
|
|
@@ -13,10 +13,10 @@ var entity_js_1 = require("../src/remult3/entity.js");
|
|
|
13
13
|
var getEntityRef_js_1 = require("../src/remult3/getEntityRef.js");
|
|
14
14
|
var server_action_js_1 = require("../src/server-action.js");
|
|
15
15
|
var server_action_info_js_1 = require("../src/server-action-info.js");
|
|
16
|
-
var initDataProvider_js_1 = require("./initDataProvider.js");
|
|
17
16
|
var remult_static_js_1 = require("../src/remult-static.js");
|
|
18
17
|
var remult_admin_js_1 = tslib_1.__importDefault(require("./remult-admin.js"));
|
|
19
18
|
var isOfType_js_1 = require("../src/isOfType.js");
|
|
19
|
+
var initDataProviderOrJson_1 = require("./initDataProviderOrJson");
|
|
20
20
|
function createRemultServerCore(options, serverCoreOptions) {
|
|
21
21
|
if (!options) {
|
|
22
22
|
options = {};
|
|
@@ -33,7 +33,8 @@ function createRemultServerCore(options, serverCoreOptions) {
|
|
|
33
33
|
if (!options.queueStorage) {
|
|
34
34
|
options.queueStorage = new InMemoryQueueStorage();
|
|
35
35
|
}
|
|
36
|
-
var dataProvider = (0,
|
|
36
|
+
var dataProvider = (0, initDataProviderOrJson_1.initDataProviderOrJson)(options.dataProvider);
|
|
37
|
+
remult_static_js_1.remultStatic.defaultDataProvider = function () { return dataProvider; };
|
|
37
38
|
if (options.ensureSchema === undefined)
|
|
38
39
|
options.ensureSchema = true;
|
|
39
40
|
context_js_1.RemultAsyncLocalStorage.enable();
|
|
@@ -524,7 +525,9 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
524
525
|
case 1: return [2 /*return*/, _a.sent()];
|
|
525
526
|
}
|
|
526
527
|
});
|
|
527
|
-
}); }
|
|
528
|
+
}); }, {
|
|
529
|
+
dataProvider: dataProvider,
|
|
530
|
+
})];
|
|
528
531
|
case 3: return [2 /*return*/, _a.sent()];
|
|
529
532
|
}
|
|
530
533
|
});
|
|
@@ -550,30 +553,36 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
550
553
|
}
|
|
551
554
|
myReq = new ExpressRequestBridgeToDataApiRequest(genReq);
|
|
552
555
|
myRes = new ExpressResponseBridgeToDataApiResponse(origRes, req, this.options.error);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
+
if (!remult_static_js_1.remultStatic.asyncContext.isInInitRequest()) return [3 /*break*/, 2];
|
|
557
|
+
return [4 /*yield*/, what(remult_static_js_1.remultStatic.asyncContext.getStore().remult, myReq, myRes, genReq, origRes, req)];
|
|
558
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
559
|
+
case 2:
|
|
560
|
+
_a.trys.push([2, 4, , 5]);
|
|
556
561
|
return [4 /*yield*/, this.runWithRemult(function (remult) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
557
562
|
var user;
|
|
558
563
|
return tslib_1.__generator(this, function (_a) {
|
|
559
564
|
switch (_a.label) {
|
|
560
565
|
case 0:
|
|
561
|
-
if (!req) return [3 /*break*/,
|
|
566
|
+
if (!req) return [3 /*break*/, 8];
|
|
567
|
+
remult_static_js_1.remultStatic.asyncContext.setInInitRequest(true);
|
|
568
|
+
_a.label = 1;
|
|
569
|
+
case 1:
|
|
570
|
+
_a.trys.push([1, , 7, 8]);
|
|
562
571
|
user = void 0;
|
|
563
|
-
if (!this.options.getUser) return [3 /*break*/,
|
|
572
|
+
if (!this.options.getUser) return [3 /*break*/, 3];
|
|
564
573
|
return [4 /*yield*/, this.options.getUser(req)];
|
|
565
|
-
case 1:
|
|
566
|
-
user = _a.sent();
|
|
567
|
-
return [3 /*break*/, 3];
|
|
568
574
|
case 2:
|
|
575
|
+
user = _a.sent();
|
|
576
|
+
return [3 /*break*/, 4];
|
|
577
|
+
case 3:
|
|
569
578
|
user = req['user'];
|
|
570
579
|
if (!user)
|
|
571
580
|
user = req['auth'];
|
|
572
|
-
_a.label =
|
|
573
|
-
case
|
|
581
|
+
_a.label = 4;
|
|
582
|
+
case 4:
|
|
574
583
|
if (user)
|
|
575
584
|
remult.user = user;
|
|
576
|
-
if (!this.options.initRequest) return [3 /*break*/,
|
|
585
|
+
if (!this.options.initRequest) return [3 /*break*/, 6];
|
|
577
586
|
return [4 /*yield*/, this.options.initRequest(req, {
|
|
578
587
|
remult: remult,
|
|
579
588
|
get liveQueryStorage() {
|
|
@@ -583,24 +592,28 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
583
592
|
remult.liveQueryStorage = value;
|
|
584
593
|
},
|
|
585
594
|
})];
|
|
586
|
-
case
|
|
595
|
+
case 5:
|
|
587
596
|
_a.sent();
|
|
588
|
-
_a.label =
|
|
589
|
-
case
|
|
590
|
-
case
|
|
597
|
+
_a.label = 6;
|
|
598
|
+
case 6: return [3 /*break*/, 8];
|
|
599
|
+
case 7:
|
|
600
|
+
remult_static_js_1.remultStatic.asyncContext.setInInitRequest(false);
|
|
601
|
+
return [7 /*endfinally*/];
|
|
602
|
+
case 8: return [4 /*yield*/, what(remult, myReq, myRes, genReq, origRes, req)];
|
|
603
|
+
case 9:
|
|
591
604
|
_a.sent();
|
|
592
605
|
return [2 /*return*/];
|
|
593
606
|
}
|
|
594
607
|
});
|
|
595
608
|
}); })];
|
|
596
|
-
case 2:
|
|
597
|
-
_a.sent();
|
|
598
|
-
return [3 /*break*/, 4];
|
|
599
609
|
case 3:
|
|
610
|
+
_a.sent();
|
|
611
|
+
return [3 /*break*/, 5];
|
|
612
|
+
case 4:
|
|
600
613
|
err_1 = _a.sent();
|
|
601
614
|
myRes.error(err_1, undefined);
|
|
602
|
-
return [3 /*break*/,
|
|
603
|
-
case
|
|
615
|
+
return [3 /*break*/, 5];
|
|
616
|
+
case 5: return [2 /*return*/];
|
|
604
617
|
}
|
|
605
618
|
});
|
|
606
619
|
}); };
|
package/src/context.d.ts
CHANGED
|
@@ -8,9 +8,17 @@ export declare class RemultAsyncLocalStorage {
|
|
|
8
8
|
private readonly remultObjectStorage;
|
|
9
9
|
static enable(): void;
|
|
10
10
|
static disable(): void;
|
|
11
|
-
constructor(remultObjectStorage: RemultAsyncLocalStorageCore<
|
|
11
|
+
constructor(remultObjectStorage: RemultAsyncLocalStorageCore<{
|
|
12
|
+
remult: Remult;
|
|
13
|
+
inInitRequest?: boolean;
|
|
14
|
+
}>);
|
|
12
15
|
run<T>(remult: Remult, callback: (remult: Remult) => Promise<T>): Promise<T>;
|
|
13
|
-
|
|
16
|
+
isInInitRequest(): boolean;
|
|
17
|
+
setInInitRequest(val: boolean): void;
|
|
18
|
+
getStore(): {
|
|
19
|
+
remult: Remult;
|
|
20
|
+
inInitRequest?: boolean;
|
|
21
|
+
};
|
|
14
22
|
}
|
|
15
23
|
export type RemultAsyncLocalStorageCore<T> = {
|
|
16
24
|
run<R>(store: T, callback: () => Promise<R>): Promise<R>;
|
|
@@ -195,5 +203,5 @@ export interface itemChange {
|
|
|
195
203
|
}
|
|
196
204
|
export declare function doTransaction(remult: Remult, what: (dp: DataProvider) => Promise<void>): Promise<void>;
|
|
197
205
|
export declare function withRemult<T>(callback: (remult: any) => Promise<T>, options?: {
|
|
198
|
-
dataProvider?: DataProvider;
|
|
206
|
+
dataProvider?: DataProvider | Promise<DataProvider> | (() => Promise<DataProvider | undefined>);
|
|
199
207
|
}): Promise<T>;
|
package/src/context.js
CHANGED
|
@@ -11,15 +11,16 @@ var server_action_info_js_1 = require("./server-action-info.js");
|
|
|
11
11
|
var buildRestDataProvider_js_1 = require("./buildRestDataProvider.js");
|
|
12
12
|
var relationInfoMember_js_1 = require("./remult3/relationInfoMember.js");
|
|
13
13
|
var remult_static_js_1 = require("./remult-static.js");
|
|
14
|
+
var initDataProvider_1 = require("../server/initDataProvider");
|
|
14
15
|
var RemultAsyncLocalStorage = /** @class */ (function () {
|
|
15
16
|
function RemultAsyncLocalStorage(remultObjectStorage) {
|
|
16
17
|
this.remultObjectStorage = remultObjectStorage;
|
|
17
18
|
}
|
|
18
19
|
RemultAsyncLocalStorage.enable = function () {
|
|
19
20
|
remult_static_js_1.remultStatic.remultFactory = function () {
|
|
20
|
-
var r = remult_static_js_1.remultStatic.asyncContext.
|
|
21
|
+
var r = remult_static_js_1.remultStatic.asyncContext.getStore();
|
|
21
22
|
if (r)
|
|
22
|
-
return r;
|
|
23
|
+
return r.remult;
|
|
23
24
|
else
|
|
24
25
|
throw new Error('remult object was requested outside of a valid context, try running it within initApi or a remult request cycle');
|
|
25
26
|
};
|
|
@@ -31,7 +32,7 @@ var RemultAsyncLocalStorage = /** @class */ (function () {
|
|
|
31
32
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
32
33
|
return tslib_1.__generator(this, function (_a) {
|
|
33
34
|
if (this.remultObjectStorage) {
|
|
34
|
-
return [2 /*return*/, this.remultObjectStorage.run(remult, function () { return callback(remult); })];
|
|
35
|
+
return [2 /*return*/, this.remultObjectStorage.run({ remult: remult }, function () { return callback(remult); })];
|
|
35
36
|
}
|
|
36
37
|
else
|
|
37
38
|
return [2 /*return*/, callback(remult)];
|
|
@@ -39,7 +40,18 @@ var RemultAsyncLocalStorage = /** @class */ (function () {
|
|
|
39
40
|
});
|
|
40
41
|
});
|
|
41
42
|
};
|
|
42
|
-
RemultAsyncLocalStorage.prototype.
|
|
43
|
+
RemultAsyncLocalStorage.prototype.isInInitRequest = function () {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
return (_b = (_a = this.remultObjectStorage) === null || _a === void 0 ? void 0 : _a.getStore()) === null || _b === void 0 ? void 0 : _b.inInitRequest;
|
|
46
|
+
};
|
|
47
|
+
RemultAsyncLocalStorage.prototype.setInInitRequest = function (val) {
|
|
48
|
+
var _a;
|
|
49
|
+
var store = (_a = this.remultObjectStorage) === null || _a === void 0 ? void 0 : _a.getStore();
|
|
50
|
+
if (!store)
|
|
51
|
+
return;
|
|
52
|
+
store.inInitRequest = val;
|
|
53
|
+
};
|
|
54
|
+
RemultAsyncLocalStorage.prototype.getStore = function () {
|
|
43
55
|
if (!this.remultObjectStorage) {
|
|
44
56
|
throw new Error("can't use static remult in this environment, `async_hooks` were not initialized");
|
|
45
57
|
}
|
|
@@ -455,9 +467,22 @@ var transactionLiveQueryPublisher = /** @class */ (function () {
|
|
|
455
467
|
return transactionLiveQueryPublisher;
|
|
456
468
|
}());
|
|
457
469
|
function withRemult(callback, options) {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
470
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
471
|
+
var remult, _a;
|
|
472
|
+
var _this = this;
|
|
473
|
+
return tslib_1.__generator(this, function (_b) {
|
|
474
|
+
switch (_b.label) {
|
|
475
|
+
case 0:
|
|
476
|
+
remult = new Remult();
|
|
477
|
+
_a = remult;
|
|
478
|
+
return [4 /*yield*/, (0, initDataProvider_1.initDataProvider)(options === null || options === void 0 ? void 0 : options.dataProvider, true, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
|
|
479
|
+
return [2 /*return*/, remult.dataProvider];
|
|
480
|
+
}); }); })];
|
|
481
|
+
case 1:
|
|
482
|
+
_a.dataProvider = _b.sent();
|
|
483
|
+
return [2 /*return*/, remult_static_js_1.remultStatic.asyncContext.run(remult, function (r) { return callback(r); })];
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
});
|
|
462
487
|
}
|
|
463
488
|
exports.withRemult = withRemult;
|
|
@@ -6,7 +6,8 @@ export interface JsonEntityStorage {
|
|
|
6
6
|
}
|
|
7
7
|
export declare class JsonDataProvider implements DataProvider {
|
|
8
8
|
private storage;
|
|
9
|
-
|
|
9
|
+
private formatted;
|
|
10
|
+
constructor(storage: JsonEntityStorage, formatted?: boolean);
|
|
10
11
|
getEntityDataProvider(entity: EntityMetadata): EntityDataProvider;
|
|
11
12
|
transaction(action: (dataProvider: DataProvider) => Promise<void>): Promise<void>;
|
|
12
13
|
}
|
|
@@ -4,11 +4,13 @@ exports.JsonDataProvider = void 0;
|
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var array_entity_data_provider_js_1 = require("./array-entity-data-provider.js");
|
|
6
6
|
var JsonDataProvider = /** @class */ (function () {
|
|
7
|
-
function JsonDataProvider(storage) {
|
|
7
|
+
function JsonDataProvider(storage, formatted) {
|
|
8
|
+
if (formatted === void 0) { formatted = false; }
|
|
8
9
|
this.storage = storage;
|
|
10
|
+
this.formatted = formatted;
|
|
9
11
|
}
|
|
10
12
|
JsonDataProvider.prototype.getEntityDataProvider = function (entity) {
|
|
11
|
-
return new JsonEntityDataProvider(entity, this.storage);
|
|
13
|
+
return new JsonEntityDataProvider(entity, this.storage, this.formatted);
|
|
12
14
|
};
|
|
13
15
|
JsonDataProvider.prototype.transaction = function (action) {
|
|
14
16
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
@@ -26,9 +28,10 @@ var JsonDataProvider = /** @class */ (function () {
|
|
|
26
28
|
}());
|
|
27
29
|
exports.JsonDataProvider = JsonDataProvider;
|
|
28
30
|
var JsonEntityDataProvider = /** @class */ (function () {
|
|
29
|
-
function JsonEntityDataProvider(entity, helper) {
|
|
31
|
+
function JsonEntityDataProvider(entity, helper, formatted) {
|
|
30
32
|
this.entity = entity;
|
|
31
33
|
this.helper = helper;
|
|
34
|
+
this.formatted = formatted;
|
|
32
35
|
this.p = Promise.resolve();
|
|
33
36
|
}
|
|
34
37
|
JsonEntityDataProvider.prototype.loadEntityData = function (what) {
|
|
@@ -48,12 +51,14 @@ var JsonEntityDataProvider = /** @class */ (function () {
|
|
|
48
51
|
if (s)
|
|
49
52
|
data = JSON.parse(s);
|
|
50
53
|
dp = new array_entity_data_provider_js_1.ArrayEntityDataProvider(this.entity, function () { return data; });
|
|
51
|
-
return [2 /*return*/, what(dp, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
return [2 /*return*/, what(dp, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
55
|
+
return tslib_1.__generator(this, function (_a) {
|
|
56
|
+
switch (_a.label) {
|
|
57
|
+
case 0: return [4 /*yield*/, this.helper.setItem(dbName, JSON.stringify(data, undefined, this.formatted ? 2 : undefined))];
|
|
58
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}); })];
|
|
57
62
|
}
|
|
58
63
|
});
|
|
59
64
|
});
|
|
@@ -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/remult-static.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ClassType } from '../classType.js';
|
|
2
2
|
import type { ClassHelper, Remult, RemultAsyncLocalStorage } from './context.js';
|
|
3
|
+
import { DataProvider } from './data-interfaces';
|
|
3
4
|
import type { columnInfo } from './remult3/columnInfo.js';
|
|
4
5
|
export declare const remultStatic: {
|
|
5
6
|
defaultRemultFactory: () => Remult;
|
|
@@ -19,6 +20,7 @@ export declare const remultStatic: {
|
|
|
19
20
|
};
|
|
20
21
|
};
|
|
21
22
|
captionTransformer: any;
|
|
23
|
+
defaultDataProvider: () => Promise<DataProvider>;
|
|
22
24
|
};
|
|
23
25
|
export declare function defaultFactory(): Remult;
|
|
24
26
|
export declare function resetFactory(): void;
|
package/src/remult-static.js
CHANGED
package/src/remult3/remult3.js
CHANGED
|
@@ -4,15 +4,17 @@ exports.flags = void 0;
|
|
|
4
4
|
exports.flags = {
|
|
5
5
|
error500RetryCount: 4,
|
|
6
6
|
};
|
|
7
|
-
//y2 - soft-delete-discussion https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
|
|
8
7
|
//y1 - live query with count #436
|
|
9
|
-
//y1 -
|
|
8
|
+
//y1 - https://github.com/remult/remult/discussions/438
|
|
9
|
+
//p1 - discuss next auth withRemult paradox
|
|
10
|
+
//p1 - maybe the default withRemult should by default use the data provider set by the remultExpress
|
|
11
|
+
//p1 - withRemult to support the full range of data provider.
|
|
10
12
|
//y1 TODO - In the esm version of our tutorial - the imports are automatically .ts and not .js in react and not in vue
|
|
11
13
|
//y1 TODO - consider id to also support keyof (id:['company','index']) - had problem with | (keyof Partial<entityType>)[] & `entity`
|
|
12
14
|
//y1 TODO - readonly key: keyof MembersOnly<entityType> & string
|
|
13
15
|
//y1 - talk about insert / update / delete with relations
|
|
14
16
|
/*
|
|
15
|
-
|
|
17
|
+
repo(Order).insert({},{
|
|
16
18
|
relations:{
|
|
17
19
|
orderItems:[{},{},{}]
|
|
18
20
|
}
|
|
@@ -20,13 +22,16 @@ exports.flags = {
|
|
|
20
22
|
*/
|
|
21
23
|
//y1 - repo batch - for multiple operations:
|
|
22
24
|
/*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const result = await repo.batch(x=>({
|
|
26
|
+
data:x.find(),
|
|
27
|
+
count:x.count()
|
|
28
|
+
}))
|
|
27
29
|
*/
|
|
30
|
+
//p1 - consider in json storage, to store the json without spaces
|
|
28
31
|
//p1 - consider upsert (where,set)
|
|
29
|
-
//
|
|
32
|
+
//y1 - wait a second to close stream -see pr
|
|
33
|
+
//p1 - Consider enforcing serial operations on JSON database to prevent data loss
|
|
34
|
+
//y2 - soft-delete-discussion https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
|
|
30
35
|
//p1 - prepare the createEntity discussion
|
|
31
36
|
//p1 - return error on connection error
|
|
32
37
|
//p1 - article on displayValue including it's definition for entities that is used in relations
|
|
@@ -84,6 +89,8 @@ exports.flags = {
|
|
|
84
89
|
//p1 - when a tasks table exists in a different schema - we get many errors
|
|
85
90
|
//p1 - live query with include
|
|
86
91
|
//p1 - adjust angular tutorial starter kit for latest angular (as is in tutorial)
|
|
92
|
+
//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
|
|
93
|
+
//p2 - when subscribe is forbidden - the query still runs after the renew process
|
|
87
94
|
//p2 - 'update tasks set where id = $1
|
|
88
95
|
//p2 - type metadata.key - to keyof entity - based on cwis input
|
|
89
96
|
//y2 - remove __dirname from tutorials
|