remult 3.3.17-next.0 → 3.3.18-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.
@@ -1,9 +1,8 @@
1
1
  import type { GenericResponse } from './server/index.js';
2
- import type { SubscriptionServerRouteApi, SubscriptionServerWithRoutes } from './server/remult-api-server.js';
3
2
  import type { Remult } from './src/context.js';
4
- export declare class SseSubscriptionServer implements SubscriptionServerWithRoutes {
3
+ import type { SubscriptionServer } from './src/live-query/SubscriptionServer.js';
4
+ export declare class SseSubscriptionServer implements SubscriptionServer {
5
5
  private canUserConnectToChannel?;
6
- initApiServer(api: SubscriptionServerRouteApi): void;
7
6
  constructor(canUserConnectToChannel?: ((channel: string, remult: Remult) => boolean) | undefined);
8
7
  publishMessage<T>(channel: string, message: any): Promise<void>;
9
8
  }
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.clientConnection = exports.SseSubscriptionServer = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var SseSubscriptionClient_js_1 = require("./src/live-query/SseSubscriptionClient.js");
6
- var SubscriptionChannel_js_1 = require("./src/live-query/SubscriptionChannel.js");
7
6
  var SseSubscriptionServer = /** @class */ (function () {
8
7
  function SseSubscriptionServer(canUserConnectToChannel) {
9
8
  this.canUserConnectToChannel = canUserConnectToChannel;
@@ -17,45 +16,6 @@ var SseSubscriptionServer = /** @class */ (function () {
17
16
  this.canUserConnectToChannel = function () { return true; };
18
17
  }
19
18
  }
20
- SseSubscriptionServer.prototype.initApiServer = function (api) {
21
- var _this = this;
22
- var streamPath = '/' + SubscriptionChannel_js_1.streamUrl;
23
- api.addRoute(streamPath, 'get', function (_a) { return tslib_1.__awaiter(_this, [_a], void 0, function (_b) {
24
- var req = _b.req, origRes = _b.origRes;
25
- return tslib_1.__generator(this, function (_c) {
26
- this.openHttpServerStream(req, origRes);
27
- return [2 /*return*/];
28
- });
29
- }); });
30
- api.addRoute(streamPath + '/subscribe', 'post', function (_a) { return tslib_1.__awaiter(_this, [_a], void 0, function (_b) {
31
- var _c;
32
- var remult = _b.remult, res = _b.res, getBody = _b.getBody;
33
- return tslib_1.__generator(this, function (_d) {
34
- switch (_d.label) {
35
- case 0:
36
- _c = this.subscribeToChannel;
37
- return [4 /*yield*/, getBody()];
38
- case 1:
39
- _c.apply(this, [_d.sent(), res, remult]);
40
- return [2 /*return*/];
41
- }
42
- });
43
- }); });
44
- api.addRoute(streamPath + '/unsubscribe', 'post', function (_a) { return tslib_1.__awaiter(_this, [_a], void 0, function (_b) {
45
- var _c;
46
- var remult = _b.remult, res = _b.res, getBody = _b.getBody;
47
- return tslib_1.__generator(this, function (_d) {
48
- switch (_d.label) {
49
- case 0:
50
- _c = this.subscribeToChannel;
51
- return [4 /*yield*/, getBody()];
52
- case 1:
53
- _c.apply(this, [_d.sent(), res, remult, true]);
54
- return [2 /*return*/];
55
- }
56
- });
57
- }); });
58
- };
59
19
  //@internal
60
20
  SseSubscriptionServer.prototype.subscribeToChannel = function (_a, res, remult, remove) {
61
21
  var e_1, _b;
@@ -1,19 +1,6 @@
1
1
  import { ConnectionNotFoundError } from './src/live-query/SseSubscriptionClient.js';
2
- import { streamUrl } from './src/live-query/SubscriptionChannel.js';
3
2
  export class SseSubscriptionServer {
4
3
  canUserConnectToChannel;
5
- initApiServer(api) {
6
- const streamPath = '/' + streamUrl;
7
- api.addRoute(streamPath, 'get', async ({ req, origRes }) => {
8
- this.openHttpServerStream(req, origRes);
9
- });
10
- api.addRoute(streamPath + '/subscribe', 'post', async ({ remult, res, getBody }) => {
11
- this.subscribeToChannel(await getBody(), res, remult);
12
- });
13
- api.addRoute(streamPath + '/unsubscribe', 'post', async ({ remult, res, getBody }) => {
14
- this.subscribeToChannel(await getBody(), res, remult, true);
15
- });
16
- }
17
4
  //@internal
18
5
  subscribeToChannel({ channel, clientId }, res, remult, remove = false) {
19
6
  for (const c of this.connections) {
package/esm/internals.js CHANGED
@@ -9,3 +9,4 @@ export { isOfType } from './src/isOfType.js';
9
9
  export { flags } from './src/remult3/remult3.js';
10
10
  export { DataProviderPromiseWrapper } from './src/data-interfaces.js';
11
11
  export { pagedQueryResult } from './src/remult3/pagedQueryResult.js';
12
+ export { withFetch } from './src/context.js';
@@ -16,7 +16,7 @@ export function initAsyncHooks() {
16
16
  }
17
17
  });
18
18
  }
19
- export class AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl {
19
+ export class AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore {
20
20
  asyncLocalStorage = new AsyncLocalStorage();
21
21
  wasImplemented = 'yes';
22
22
  run(store, callback) {
@@ -36,8 +36,14 @@ export class AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl {
36
36
  getStore() {
37
37
  return this.asyncLocalStorage.getStore();
38
38
  }
39
+ createDataProviderAsyncLocalStorage() {
40
+ return new AsyncLocalStorage();
41
+ }
39
42
  }
40
43
  export class StubRemultAsyncLocalStorageCore {
44
+ createDataProviderAsyncLocalStorage() {
45
+ return undefined;
46
+ }
41
47
  isStub = true;
42
48
  wasImplemented = 'yes';
43
49
  async run(store, callback) {
@@ -50,5 +56,3 @@ export class StubRemultAsyncLocalStorageCore {
50
56
  lastPromise = Promise.resolve(undefined);
51
57
  currentValue;
52
58
  }
53
- export class AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore extends AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl {
54
- }
@@ -2,7 +2,7 @@ import { __decorate, __metadata } from "tslib";
2
2
  import { SseSubscriptionServer } from '../SseSubscriptionServer.js';
3
3
  import { Remult, RemultAsyncLocalStorage, withRemult } from '../src/context.js';
4
4
  import { DataApi, serializeError } from '../src/data-api.js';
5
- import { liveQueryKeepAliveRoute } from '../src/live-query/SubscriptionChannel.js';
5
+ import { liveQueryKeepAliveRoute, streamUrl, } from '../src/live-query/SubscriptionChannel.js';
6
6
  import { InMemoryLiveQueryStorage, LiveQueryPublisher, } from '../src/live-query/SubscriptionServer.js';
7
7
  import { IdEntity } from '../src/remult3/IdEntity.js';
8
8
  import { Fields } from '../src/remult3/Fields.js';
@@ -266,20 +266,19 @@ export class RemultServerImplementation {
266
266
  r.route(this.options.rootPath + '/admin').get(admin());
267
267
  }
268
268
  r.route(this.options.rootPath + '/me').get(this.process(async (remult, req, res) => res.success(remult.user ?? null)));
269
- const subscriptionServer = this.options.subscriptionServer;
270
- if (isOfType(subscriptionServer, 'initApiServer')) {
271
- subscriptionServer.initApiServer({
272
- rootPath: this.options.rootPath,
273
- addRoute: (relativePath, method, handler) => {
274
- r.route(this.options.rootPath + relativePath)[method](this.process(async (remult, _, res, req, origRes, origReq) => handler({
275
- remult,
276
- res,
277
- req,
278
- origRes,
279
- getBody: () => this.coreOptions.getRequestBody(origReq),
280
- })));
281
- },
282
- });
269
+ if (this.options.subscriptionServer instanceof SseSubscriptionServer) {
270
+ const streamPath = this.options.rootPath + '/' + streamUrl;
271
+ r.route(streamPath).get(this.process(async (remult, req, res, origReq, origRes) => {
272
+ ;
273
+ remult.subscriptionServer.openHttpServerStream(origReq, origRes);
274
+ }));
275
+ r.route(streamPath + '/subscribe').post(this.process(async (remult, _2, res, _, _1, origReq) => {
276
+ const body = remult.subscriptionServer.subscribeToChannel(await this.coreOptions.getRequestBody(origReq), res, remult);
277
+ }));
278
+ r.route(streamPath + '/unsubscribe').post(this.process(async (remult, req, res, reqInfo, origRes, origReq) => {
279
+ ;
280
+ remult.subscriptionServer.subscribeToChannel(await this.coreOptions.getRequestBody(origReq), res, remult, true);
281
+ }));
283
282
  }
284
283
  r.route(this.options.rootPath + '/' + liveQueryKeepAliveRoute).post(this.process(async (remult, req, res, reqInfo, origRes, origReq) => {
285
284
  res.success(await remult.liveQueryStorage.keepAliveAndReturnUnknownQueryIds(await this.coreOptions.getRequestBody(origReq)));
@@ -98,6 +98,7 @@ async function MakeServerCallWithDifferentStaticRemult(what) {
98
98
  store.remult.user = user;
99
99
  return callback();
100
100
  },
101
+ createDataProviderAsyncLocalStorage: () => undefined,
101
102
  wasImplemented: 'yes',
102
103
  });
103
104
  return await what();
@@ -45,6 +45,9 @@ export class RemultAsyncLocalStorage {
45
45
  if (val || this.remultObjectStorage?.isStub)
46
46
  store.inInitRequest = val;
47
47
  }
48
+ createDataProviderAsyncLocalStorage() {
49
+ return this.remultObjectStorage?.createDataProviderAsyncLocalStorage();
50
+ }
48
51
  getStore() {
49
52
  if (!this.remultObjectStorage) {
50
53
  throw new Error("can't use static remult in this environment, `async_hooks` were not initialized");
@@ -183,8 +186,15 @@ export class Remult {
183
186
  httpClient: fetch,
184
187
  }));
185
188
  }
189
+ /* @internal */
190
+ _myDataProviderStore = new RemultInstanceDataProviderStore(new RestDataProvider(() => this.apiClient));
186
191
  /** The current data provider */
187
- dataProvider = new RestDataProvider(() => this.apiClient);
192
+ set dataProvider(dataProvider) {
193
+ this._myDataProviderStore.getStore().dataProvider = dataProvider;
194
+ }
195
+ get dataProvider() {
196
+ return this._myDataProviderStore.getStore().dataProvider;
197
+ }
188
198
  /* @internal */
189
199
  repCache = new Map();
190
200
  constructor(provider) {
@@ -311,10 +321,11 @@ export async function doTransaction(remult, what) {
311
321
  const prev = remult.dataProvider;
312
322
  try {
313
323
  await remult.dataProvider.transaction(async (ds) => {
314
- remult.dataProvider = ds;
315
- remult.liveQueryPublisher = trans;
316
- await what(ds);
317
- ok = true;
324
+ await withRemultDataProvider({ dataProvider: ds, remult }, async () => {
325
+ remult.liveQueryPublisher = trans;
326
+ await what(ds);
327
+ ok = true;
328
+ });
318
329
  });
319
330
  if (ok)
320
331
  await trans.flush();
@@ -358,6 +369,54 @@ class transactionLiveQueryPublisher {
358
369
  }
359
370
  export async function withRemult(callback, options) {
360
371
  const remult = new Remult();
361
- remult.dataProvider = await initDataProvider(options?.dataProvider, true, async () => remult.dataProvider);
362
- return remultStatic.asyncContext.run(remult, (r) => callback(r));
372
+ return remultStatic.asyncContext.run(remult, async (r) => {
373
+ remult.dataProvider = await initDataProvider(options?.dataProvider, true, async () => remult.dataProvider);
374
+ return await callback(r);
375
+ });
376
+ }
377
+ export class RemultInstanceDataProviderStore {
378
+ constructor(dataProvider) {
379
+ this._myDataProviderStore = { dataProvider };
380
+ }
381
+ _myDataProviderStore;
382
+ getStore = () => this._myDataProviderStore;
383
+ asyncStore;
384
+ async withDataProvider(dataProvider, callback) {
385
+ if (!this.asyncStore) {
386
+ this.asyncStore =
387
+ remultStatic.asyncContext.createDataProviderAsyncLocalStorage();
388
+ if (this.asyncStore) {
389
+ this.getStore = () => this.asyncStore.getStore() ?? this._myDataProviderStore;
390
+ }
391
+ }
392
+ if (this.asyncStore) {
393
+ return this.asyncStore.run({ dataProvider }, async () => {
394
+ return await callback();
395
+ });
396
+ }
397
+ else {
398
+ const prev = this._myDataProviderStore;
399
+ try {
400
+ this._myDataProviderStore = { dataProvider };
401
+ return await callback();
402
+ }
403
+ finally {
404
+ this._myDataProviderStore = prev;
405
+ }
406
+ }
407
+ }
408
+ }
409
+ export function withRemultDataProvider({ dataProvider, remult }, callback) {
410
+ remult = remult ?? remultStatic.remultFactory();
411
+ return remult._myDataProviderStore.withDataProvider(dataProvider, callback);
412
+ }
413
+ export function withFetch(fetch, callback) {
414
+ const remult = remultStatic.remultFactory();
415
+ return withRemultDataProvider({
416
+ remult,
417
+ dataProvider: new RestDataProvider(() => ({
418
+ ...remult.apiClient,
419
+ httpClient: fetch,
420
+ })),
421
+ }, callback);
363
422
  }
@@ -215,5 +215,9 @@ export class RemultProxy {
215
215
  set subscriptionServer(value) {
216
216
  remultStatic.remultFactory().subscriptionServer = value;
217
217
  }
218
+ /** @internal */
219
+ get _myDataProviderStore() {
220
+ return remultStatic.remultFactory()._myDataProviderStore;
221
+ }
218
222
  }
219
223
  export const remult = new RemultProxy();
@@ -1698,8 +1698,10 @@ export class rowHelperImplementation extends rowHelperBase {
1698
1698
  }
1699
1699
  }
1700
1700
  else if (!getRelationFieldInfo(col))
1701
- if (data[col.key] === undefined)
1702
- delete this.instance[col.key];
1701
+ if (data[col.key] === undefined) {
1702
+ if (!Reflect.deleteProperty(this.instance, col.key))
1703
+ this.instance[col.key] = undefined;
1704
+ }
1703
1705
  else
1704
1706
  this.instance[col.key] = data[col.key];
1705
1707
  }
package/internals.d.ts CHANGED
@@ -14,8 +14,7 @@ export declare const actionInfo: {
14
14
  };
15
15
  export { isOfType } from './src/isOfType.js';
16
16
  export type { ClassType } from './classType.js';
17
- export type { SubscriptionServerWithRoutes, SubscriptionServerRouteApi, SubscriptionServerRouteHandlerArgs, } from './server/remult-api-server.js';
18
- export type { DataApiResponse } from './src/data-api.js';
19
17
  export { flags } from './src/remult3/remult3.js';
20
18
  export { DataProviderPromiseWrapper } from './src/data-interfaces.js';
21
19
  export { pagedQueryResult } from './src/remult3/pagedQueryResult.js';
20
+ export { withFetch } from './src/context.js';
package/internals.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.pagedQueryResult = exports.DataProviderPromiseWrapper = exports.flags = exports.isOfType = exports.actionInfo = exports.__updateEntityBasedOnWhere = exports.getEntitySettings = exports.fieldOptionsEnricher = exports.getControllerRef = exports.controllerRefImpl = exports.decorateColumnSettings = exports.getRelationFieldInfo = exports.getRelationInfo = exports.sqlRelationsFilter = exports.sqlRelations = void 0;
3
+ exports.withFetch = exports.pagedQueryResult = exports.DataProviderPromiseWrapper = exports.flags = exports.isOfType = exports.actionInfo = exports.__updateEntityBasedOnWhere = exports.getEntitySettings = exports.fieldOptionsEnricher = exports.getControllerRef = exports.controllerRefImpl = exports.decorateColumnSettings = exports.getRelationFieldInfo = exports.getRelationInfo = exports.sqlRelationsFilter = exports.sqlRelations = void 0;
4
4
  var remult_static_js_1 = require("./src/remult-static.js");
5
5
  var sql_relations_js_1 = require("./src/data-providers/sql-relations.js");
6
6
  Object.defineProperty(exports, "sqlRelations", { enumerable: true, get: function () { return sql_relations_js_1.sqlRelations; } });
@@ -26,3 +26,5 @@ var data_interfaces_js_1 = require("./src/data-interfaces.js");
26
26
  Object.defineProperty(exports, "DataProviderPromiseWrapper", { enumerable: true, get: function () { return data_interfaces_js_1.DataProviderPromiseWrapper; } });
27
27
  var pagedQueryResult_js_1 = require("./src/remult3/pagedQueryResult.js");
28
28
  Object.defineProperty(exports, "pagedQueryResult", { enumerable: true, get: function () { return pagedQueryResult_js_1.pagedQueryResult; } });
29
+ var context_js_1 = require("./src/context.js");
30
+ Object.defineProperty(exports, "withFetch", { enumerable: true, get: function () { return context_js_1.withFetch; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "3.3.17-next.0",
3
+ "version": "3.3.18-next.0",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -1,18 +1,22 @@
1
- import { type RemultAsyncLocalStorageCore } from '../src/context.js';
1
+ import { AsyncLocalStorage } from 'async_hooks';
2
+ import { type RemultAsyncLocalStorageCore, type RemultInAsyncLocalStorage } from '../src/context.js';
3
+ import type { DataProvider } from '../src/data-interfaces.js';
2
4
  export declare function initAsyncHooks(): void;
3
- export declare class AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl<T> implements RemultAsyncLocalStorageCore<T> {
5
+ export declare class AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore implements RemultAsyncLocalStorageCore {
4
6
  private asyncLocalStorage;
5
7
  wasImplemented: "yes";
6
- run<R>(store: T, callback: () => Promise<R>): Promise<R>;
7
- getStore(): T | undefined;
8
+ run<R>(store: RemultInAsyncLocalStorage, callback: () => Promise<R>): Promise<R>;
9
+ getStore(): RemultInAsyncLocalStorage | undefined;
10
+ createDataProviderAsyncLocalStorage(): AsyncLocalStorage<{
11
+ dataProvider: DataProvider;
12
+ }>;
8
13
  }
9
- export declare class StubRemultAsyncLocalStorageCore<T> implements RemultAsyncLocalStorageCore<T> {
14
+ export declare class StubRemultAsyncLocalStorageCore implements RemultAsyncLocalStorageCore {
15
+ createDataProviderAsyncLocalStorage(): undefined;
10
16
  isStub: boolean;
11
17
  wasImplemented: "yes";
12
- run<R>(store: T, callback: () => Promise<R>): Promise<R>;
13
- getStore(): T | undefined;
14
- lastPromise: Promise<T | undefined>;
15
- currentValue?: T;
16
- }
17
- export declare class AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore<T> extends AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl<T> {
18
+ run<R>(store: RemultInAsyncLocalStorage, callback: () => Promise<R>): Promise<R>;
19
+ getStore(): RemultInAsyncLocalStorage | undefined;
20
+ lastPromise: Promise<RemultInAsyncLocalStorage | undefined>;
21
+ currentValue?: RemultInAsyncLocalStorage;
18
22
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore = exports.StubRemultAsyncLocalStorageCore = exports.AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl = void 0;
3
+ exports.StubRemultAsyncLocalStorageCore = exports.AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore = void 0;
4
4
  exports.initAsyncHooks = initAsyncHooks;
5
5
  var tslib_1 = require("tslib");
6
6
  var async_hooks_1 = require("async_hooks");
@@ -29,12 +29,12 @@ function initAsyncHooks() {
29
29
  });
30
30
  }); });
31
31
  }
32
- var AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl = /** @class */ (function () {
33
- function AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl() {
32
+ var AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore = /** @class */ (function () {
33
+ function AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore() {
34
34
  this.asyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
35
35
  this.wasImplemented = 'yes';
36
36
  }
37
- AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl.prototype.run = function (store, callback) {
37
+ AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore.prototype.run = function (store, callback) {
38
38
  var _this = this;
39
39
  var r;
40
40
  this.asyncLocalStorage.run(store, function () {
@@ -60,18 +60,24 @@ var AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl = /** @class */ (fu
60
60
  });
61
61
  return r;
62
62
  };
63
- AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl.prototype.getStore = function () {
63
+ AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore.prototype.getStore = function () {
64
64
  return this.asyncLocalStorage.getStore();
65
65
  };
66
- return AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl;
66
+ AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore.prototype.createDataProviderAsyncLocalStorage = function () {
67
+ return new async_hooks_1.AsyncLocalStorage();
68
+ };
69
+ return AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore;
67
70
  }());
68
- exports.AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl = AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl;
71
+ exports.AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore = AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore;
69
72
  var StubRemultAsyncLocalStorageCore = /** @class */ (function () {
70
73
  function StubRemultAsyncLocalStorageCore() {
71
74
  this.isStub = true;
72
75
  this.wasImplemented = 'yes';
73
76
  this.lastPromise = Promise.resolve(undefined);
74
77
  }
78
+ StubRemultAsyncLocalStorageCore.prototype.createDataProviderAsyncLocalStorage = function () {
79
+ return undefined;
80
+ };
75
81
  StubRemultAsyncLocalStorageCore.prototype.run = function (store, callback) {
76
82
  return tslib_1.__awaiter(this, void 0, void 0, function () {
77
83
  return tslib_1.__generator(this, function (_a) {
@@ -90,11 +96,3 @@ var StubRemultAsyncLocalStorageCore = /** @class */ (function () {
90
96
  return StubRemultAsyncLocalStorageCore;
91
97
  }());
92
98
  exports.StubRemultAsyncLocalStorageCore = StubRemultAsyncLocalStorageCore;
93
- var AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore = /** @class */ (function (_super) {
94
- tslib_1.__extends(AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore, _super);
95
- function AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore() {
96
- return _super !== null && _super.apply(this, arguments) || this;
97
- }
98
- return AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore;
99
- }(AsyncLocalStorageBridgeToRemultAsyncLocalStorageCoreImpl));
100
- exports.AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore = AsyncLocalStorageBridgeToRemultAsyncLocalStorageCore;
@@ -1,7 +1,6 @@
1
1
  import type { ClassType } from '../classType.js';
2
2
  import type { Allowed, UserInfo } from '../src/context.js';
3
3
  import { Remult } from '../src/context.js';
4
- import type { DataApiResponse } from '../src/data-api.js';
5
4
  import type { DataProvider } from '../src/data-interfaces.js';
6
5
  import type { LiveQueryStorage, SubscriptionServer } from '../src/live-query/SubscriptionServer.js';
7
6
  import { IdEntity } from '../src/remult3/IdEntity.js';
@@ -168,22 +167,6 @@ export interface GenericResponse {
168
167
  status(statusCode: number): GenericResponse;
169
168
  end(): void;
170
169
  }
171
- /** A `SubscriptionServer` that also needs to serve http routes (for example SSE),
172
- * can implement this interface to register them on the api server */
173
- export interface SubscriptionServerWithRoutes extends SubscriptionServer {
174
- initApiServer(api: SubscriptionServerRouteApi): void;
175
- }
176
- export interface SubscriptionServerRouteApi {
177
- rootPath: string;
178
- addRoute(relativePath: string, method: 'get' | 'post', handler: (args: SubscriptionServerRouteHandlerArgs) => Promise<void>): void;
179
- }
180
- export interface SubscriptionServerRouteHandlerArgs {
181
- remult: Remult;
182
- res: DataApiResponse;
183
- req: GenericRequestInfo;
184
- origRes: GenericResponse;
185
- getBody(): Promise<any>;
186
- }
187
170
  export interface queuedJobInfo {
188
171
  info: queuedJobInfoResponse;
189
172
  userId: string;
@@ -441,25 +441,45 @@ var RemultServerImplementation = /** @class */ (function () {
441
441
  r.route(this.options.rootPath + '/me').get(this.process(function (remult, req, res) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var _a; return tslib_1.__generator(this, function (_b) {
442
442
  return [2 /*return*/, res.success((_a = remult.user) !== null && _a !== void 0 ? _a : null)];
443
443
  }); }); }));
444
- var subscriptionServer = this.options.subscriptionServer;
445
- if ((0, isOfType_js_1.isOfType)(subscriptionServer, 'initApiServer')) {
446
- subscriptionServer.initApiServer({
447
- rootPath: this.options.rootPath,
448
- addRoute: function (relativePath, method, handler) {
449
- r.route(_this.options.rootPath + relativePath)[method](_this.process(function (remult, _, res, req, origRes, origReq) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
450
- var _this = this;
451
- return tslib_1.__generator(this, function (_a) {
452
- return [2 /*return*/, handler({
453
- remult: remult,
454
- res: res,
455
- req: req,
456
- origRes: origRes,
457
- getBody: function () { return _this.coreOptions.getRequestBody(origReq); },
458
- })];
459
- });
460
- }); }));
461
- },
462
- });
444
+ if (this.options.subscriptionServer instanceof SseSubscriptionServer_js_1.SseSubscriptionServer) {
445
+ var streamPath = this.options.rootPath + '/' + SubscriptionChannel_js_1.streamUrl;
446
+ r.route(streamPath).get(this.process(function (remult, req, res, origReq, origRes) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
447
+ return tslib_1.__generator(this, function (_a) {
448
+ ;
449
+ remult.subscriptionServer.openHttpServerStream(origReq, origRes);
450
+ return [2 /*return*/];
451
+ });
452
+ }); }));
453
+ r.route(streamPath + '/subscribe').post(this.process(function (remult, _2, res, _, _1, origReq) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
454
+ var body, _a, _b;
455
+ return tslib_1.__generator(this, function (_c) {
456
+ switch (_c.label) {
457
+ case 0:
458
+ _b = (_a = remult.subscriptionServer).subscribeToChannel;
459
+ return [4 /*yield*/, this.coreOptions.getRequestBody(origReq)];
460
+ case 1:
461
+ body = _b.apply(_a, [_c.sent(), res,
462
+ remult]);
463
+ return [2 /*return*/];
464
+ }
465
+ });
466
+ }); }));
467
+ r.route(streamPath + '/unsubscribe').post(this.process(function (remult, req, res, reqInfo, origRes, origReq) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
468
+ var _a, _b;
469
+ return tslib_1.__generator(this, function (_c) {
470
+ switch (_c.label) {
471
+ case 0:
472
+ ;
473
+ _b = (_a = remult.subscriptionServer).subscribeToChannel;
474
+ return [4 /*yield*/, this.coreOptions.getRequestBody(origReq)];
475
+ case 1:
476
+ _b.apply(_a, [_c.sent(), res,
477
+ remult,
478
+ true]);
479
+ return [2 /*return*/];
480
+ }
481
+ });
482
+ }); }));
463
483
  }
464
484
  r.route(this.options.rootPath + '/' + SubscriptionChannel_js_1.liveQueryKeepAliveRoute).post(this.process(function (remult, req, res, reqInfo, origRes, origReq) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
465
485
  var _a, _b, _c, _d;
@@ -161,6 +161,7 @@ function MakeServerCallWithDifferentStaticRemult(what) {
161
161
  store.remult.user = user;
162
162
  return callback();
163
163
  },
164
+ createDataProviderAsyncLocalStorage: function () { return undefined; },
164
165
  wasImplemented: 'yes',
165
166
  });
166
167
  return [4 /*yield*/, what()];
package/src/context.d.ts CHANGED
@@ -8,23 +8,31 @@ export declare class RemultAsyncLocalStorage {
8
8
  private readonly remultObjectStorage;
9
9
  static enable(): void;
10
10
  static disable(): void;
11
- constructor(remultObjectStorage: RemultAsyncLocalStorageCore<{
12
- remult: Remult;
13
- inInitRequest?: boolean;
14
- }> | undefined);
11
+ constructor(remultObjectStorage: RemultAsyncLocalStorageCore | undefined);
15
12
  run<T>(remult: Remult, callback: (remult: Remult) => Promise<T>): Promise<T>;
16
13
  isInInitRequest(): boolean | undefined;
17
14
  setInInitRequest(val: boolean): void;
18
- getStore(): {
19
- remult: Remult;
20
- inInitRequest?: boolean;
21
- } | undefined;
15
+ createDataProviderAsyncLocalStorage(): DataProviderAsyncLocalStorage | undefined;
16
+ getStore(): RemultInAsyncLocalStorage | undefined;
22
17
  }
23
- export type RemultAsyncLocalStorageCore<T> = {
24
- run<R>(store: T, callback: () => Promise<R>): Promise<R>;
25
- getStore(): T | undefined;
18
+ export type RemultAsyncLocalStorageCore = {
19
+ run<R>(store: RemultInAsyncLocalStorage, callback: () => Promise<R>): Promise<R>;
20
+ getStore(): RemultInAsyncLocalStorage | undefined;
26
21
  wasImplemented: 'yes';
27
22
  isStub?: boolean;
23
+ createDataProviderAsyncLocalStorage(): DataProviderAsyncLocalStorage | undefined;
24
+ };
25
+ export type RemultInAsyncLocalStorage = {
26
+ remult: Remult;
27
+ inInitRequest?: boolean;
28
+ };
29
+ export type DataProviderAsyncLocalStorage = {
30
+ run<R>(data: {
31
+ dataProvider: DataProvider;
32
+ }, callback: () => Promise<R>): Promise<R>;
33
+ getStore(): {
34
+ dataProvider: DataProvider;
35
+ } | undefined;
28
36
  };
29
37
  export declare function isBackend(): boolean;
30
38
  export declare class Remult {
@@ -72,7 +80,8 @@ export declare class Remult {
72
80
  */
73
81
  useFetch(fetch: ApiClient['httpClient']): void;
74
82
  /** The current data provider */
75
- dataProvider: DataProvider;
83
+ set dataProvider(dataProvider: DataProvider);
84
+ get dataProvider(): DataProvider;
76
85
  /** Creates a new instance of the `remult` object.
77
86
  *
78
87
  * Can receive either an HttpProvider or a DataProvider as a parameter - which will be used to fetch data from.
@@ -250,3 +259,19 @@ export declare function doTransaction(remult: Remult, what: (dp: DataProvider) =
250
259
  export declare function withRemult<T>(callback: (remult: Remult) => Promise<T>, options?: {
251
260
  dataProvider?: DataProvider | Promise<DataProvider> | (() => Promise<DataProvider | undefined>);
252
261
  }): Promise<T>;
262
+ export declare class RemultInstanceDataProviderStore {
263
+ constructor(dataProvider: DataProvider);
264
+ _myDataProviderStore: {
265
+ dataProvider: DataProvider;
266
+ };
267
+ getStore: () => {
268
+ dataProvider: DataProvider;
269
+ };
270
+ asyncStore?: DataProviderAsyncLocalStorage;
271
+ withDataProvider<T>(dataProvider: DataProvider, callback: () => Promise<T>): Promise<T>;
272
+ }
273
+ export declare function withRemultDataProvider<T>({ dataProvider, remult }: {
274
+ dataProvider: DataProvider;
275
+ remult?: Remult;
276
+ }, callback: () => Promise<T>): Promise<T>;
277
+ export declare function withFetch<T>(fetch: ApiClient['httpClient'], callback: () => Promise<T>): Promise<T>;
package/src/context.js CHANGED
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EventSource = exports.queryConfig = exports.Allow = exports.ClassHelper = exports.Remult = exports.RemultAsyncLocalStorage = void 0;
3
+ exports.RemultInstanceDataProviderStore = exports.EventSource = exports.queryConfig = exports.Allow = exports.ClassHelper = exports.Remult = exports.RemultAsyncLocalStorage = void 0;
4
4
  exports.isBackend = isBackend;
5
5
  exports.setControllerSettings = setControllerSettings;
6
6
  exports.doTransaction = doTransaction;
7
7
  exports.withRemult = withRemult;
8
+ exports.withRemultDataProvider = withRemultDataProvider;
9
+ exports.withFetch = withFetch;
8
10
  var tslib_1 = require("tslib");
9
11
  var data_interfaces_js_1 = require("./data-interfaces.js");
10
12
  var rest_data_provider_js_1 = require("./data-providers/rest-data-provider.js");
@@ -59,6 +61,10 @@ var RemultAsyncLocalStorage = /** @class */ (function () {
59
61
  if (val || ((_b = this.remultObjectStorage) === null || _b === void 0 ? void 0 : _b.isStub))
60
62
  store.inInitRequest = val;
61
63
  };
64
+ RemultAsyncLocalStorage.prototype.createDataProviderAsyncLocalStorage = function () {
65
+ var _a;
66
+ return (_a = this.remultObjectStorage) === null || _a === void 0 ? void 0 : _a.createDataProviderAsyncLocalStorage();
67
+ };
62
68
  RemultAsyncLocalStorage.prototype.getStore = function () {
63
69
  if (!this.remultObjectStorage) {
64
70
  throw new Error("can't use static remult in this environment, `async_hooks` were not initialized");
@@ -109,8 +115,8 @@ var Remult = /** @class */ (function () {
109
115
  }
110
116
  return r;
111
117
  };
112
- /** The current data provider */
113
- this.dataProvider = new rest_data_provider_js_1.RestDataProvider(function () { return _this.apiClient; });
118
+ /* @internal */
119
+ this._myDataProviderStore = new RemultInstanceDataProviderStore(new rest_data_provider_js_1.RestDataProvider(function () { return _this.apiClient; }));
114
120
  /* @internal */
115
121
  this.repCache = new Map();
116
122
  /* @internal*/
@@ -287,6 +293,17 @@ var Remult = /** @class */ (function () {
287
293
  httpClient: fetch,
288
294
  }); });
289
295
  };
296
+ Object.defineProperty(Remult.prototype, "dataProvider", {
297
+ get: function () {
298
+ return this._myDataProviderStore.getStore().dataProvider;
299
+ },
300
+ /** The current data provider */
301
+ set: function (dataProvider) {
302
+ this._myDataProviderStore.getStore().dataProvider = dataProvider;
303
+ },
304
+ enumerable: false,
305
+ configurable: true
306
+ });
290
307
  //@ts-ignore // type error of typescript regarding args that doesn't appear in my normal development
291
308
  /** Used to call a `backendMethod` using a specific `remult` object
292
309
  * @example
@@ -434,15 +451,24 @@ function doTransaction(remult, what) {
434
451
  case 1:
435
452
  _a.trys.push([1, , 5, 6]);
436
453
  return [4 /*yield*/, remult.dataProvider.transaction(function (ds) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
454
+ var _this = this;
437
455
  return tslib_1.__generator(this, function (_a) {
438
456
  switch (_a.label) {
439
- case 0:
440
- remult.dataProvider = ds;
441
- remult.liveQueryPublisher = trans;
442
- return [4 /*yield*/, what(ds)];
457
+ case 0: return [4 /*yield*/, withRemultDataProvider({ dataProvider: ds, remult: remult }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
458
+ return tslib_1.__generator(this, function (_a) {
459
+ switch (_a.label) {
460
+ case 0:
461
+ remult.liveQueryPublisher = trans;
462
+ return [4 /*yield*/, what(ds)];
463
+ case 1:
464
+ _a.sent();
465
+ ok = true;
466
+ return [2 /*return*/];
467
+ }
468
+ });
469
+ }); })];
443
470
  case 1:
444
471
  _a.sent();
445
- ok = true;
446
472
  return [2 /*return*/];
447
473
  }
448
474
  });
@@ -549,20 +575,87 @@ var transactionLiveQueryPublisher = /** @class */ (function () {
549
575
  }());
550
576
  function withRemult(callback, options) {
551
577
  return tslib_1.__awaiter(this, void 0, void 0, function () {
552
- var remult, _a;
578
+ var remult;
553
579
  var _this = this;
554
- return tslib_1.__generator(this, function (_b) {
555
- switch (_b.label) {
556
- case 0:
557
- remult = new Remult();
558
- _a = remult;
559
- return [4 /*yield*/, (0, initDataProvider_js_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) {
560
- return [2 /*return*/, remult.dataProvider];
561
- }); }); })];
562
- case 1:
563
- _a.dataProvider = _b.sent();
564
- return [2 /*return*/, remult_static_js_1.remultStatic.asyncContext.run(remult, function (r) { return callback(r); })];
565
- }
580
+ return tslib_1.__generator(this, function (_a) {
581
+ remult = new Remult();
582
+ return [2 /*return*/, remult_static_js_1.remultStatic.asyncContext.run(remult, function (r) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
583
+ var _a;
584
+ var _this = this;
585
+ return tslib_1.__generator(this, function (_b) {
586
+ switch (_b.label) {
587
+ case 0:
588
+ _a = remult;
589
+ return [4 /*yield*/, (0, initDataProvider_js_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) {
590
+ return [2 /*return*/, remult.dataProvider];
591
+ }); }); })];
592
+ case 1:
593
+ _a.dataProvider = _b.sent();
594
+ return [4 /*yield*/, callback(r)];
595
+ case 2: return [2 /*return*/, _b.sent()];
596
+ }
597
+ });
598
+ }); })];
566
599
  });
567
600
  });
568
601
  }
602
+ var RemultInstanceDataProviderStore = /** @class */ (function () {
603
+ function RemultInstanceDataProviderStore(dataProvider) {
604
+ var _this = this;
605
+ this.getStore = function () { return _this._myDataProviderStore; };
606
+ this._myDataProviderStore = { dataProvider: dataProvider };
607
+ }
608
+ RemultInstanceDataProviderStore.prototype.withDataProvider = function (dataProvider, callback) {
609
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
610
+ var prev;
611
+ var _this = this;
612
+ return tslib_1.__generator(this, function (_a) {
613
+ switch (_a.label) {
614
+ case 0:
615
+ if (!this.asyncStore) {
616
+ this.asyncStore =
617
+ remult_static_js_1.remultStatic.asyncContext.createDataProviderAsyncLocalStorage();
618
+ if (this.asyncStore) {
619
+ this.getStore = function () { var _a; return (_a = _this.asyncStore.getStore()) !== null && _a !== void 0 ? _a : _this._myDataProviderStore; };
620
+ }
621
+ }
622
+ if (!this.asyncStore) return [3 /*break*/, 1];
623
+ return [2 /*return*/, this.asyncStore.run({ dataProvider: dataProvider }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
624
+ return tslib_1.__generator(this, function (_a) {
625
+ switch (_a.label) {
626
+ case 0: return [4 /*yield*/, callback()];
627
+ case 1: return [2 /*return*/, _a.sent()];
628
+ }
629
+ });
630
+ }); })];
631
+ case 1:
632
+ prev = this._myDataProviderStore;
633
+ _a.label = 2;
634
+ case 2:
635
+ _a.trys.push([2, , 4, 5]);
636
+ this._myDataProviderStore = { dataProvider: dataProvider };
637
+ return [4 /*yield*/, callback()];
638
+ case 3: return [2 /*return*/, _a.sent()];
639
+ case 4:
640
+ this._myDataProviderStore = prev;
641
+ return [7 /*endfinally*/];
642
+ case 5: return [2 /*return*/];
643
+ }
644
+ });
645
+ });
646
+ };
647
+ return RemultInstanceDataProviderStore;
648
+ }());
649
+ exports.RemultInstanceDataProviderStore = RemultInstanceDataProviderStore;
650
+ function withRemultDataProvider(_a, callback) {
651
+ var dataProvider = _a.dataProvider, remult = _a.remult;
652
+ remult = remult !== null && remult !== void 0 ? remult : remult_static_js_1.remultStatic.remultFactory();
653
+ return remult._myDataProviderStore.withDataProvider(dataProvider, callback);
654
+ }
655
+ function withFetch(fetch, callback) {
656
+ var remult = remult_static_js_1.remultStatic.remultFactory();
657
+ return withRemultDataProvider({
658
+ remult: remult,
659
+ dataProvider: new rest_data_provider_js_1.RestDataProvider(function () { return (tslib_1.__assign(tslib_1.__assign({}, remult.apiClient), { httpClient: fetch })); }),
660
+ }, callback);
661
+ }
@@ -379,6 +379,14 @@ var RemultProxy = /** @class */ (function () {
379
379
  enumerable: false,
380
380
  configurable: true
381
381
  });
382
+ Object.defineProperty(RemultProxy.prototype, "_myDataProviderStore", {
383
+ /** @internal */
384
+ get: function () {
385
+ return remult_static_js_1.remultStatic.remultFactory()._myDataProviderStore;
386
+ },
387
+ enumerable: false,
388
+ configurable: true
389
+ });
382
390
  return RemultProxy;
383
391
  }());
384
392
  exports.RemultProxy = RemultProxy;
@@ -2856,8 +2856,10 @@ var rowHelperImplementation = /** @class */ (function (_super) {
2856
2856
  case 6: return [3 /*break*/, 8];
2857
2857
  case 7:
2858
2858
  if (!(0, relationInfoMember_js_1.getRelationFieldInfo)(col))
2859
- if (data[col.key] === undefined)
2860
- delete this.instance[col.key];
2859
+ if (data[col.key] === undefined) {
2860
+ if (!Reflect.deleteProperty(this.instance, col.key))
2861
+ this.instance[col.key] = undefined;
2862
+ }
2861
2863
  else
2862
2864
  this.instance[col.key] = data[col.key];
2863
2865
  _d.label = 8;