remult 0.17.0-exp.2 → 0.17.0-exp.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/esm/postgres/schema-builder.js +4 -4
  2. package/esm/remult-express.d.ts +2 -2
  3. package/esm/remult-express.js +6 -8
  4. package/esm/remult-knex/index.js +2 -2
  5. package/esm/server/expressBridge.d.ts +1 -1
  6. package/esm/server/expressBridge.js +2 -2
  7. package/esm/src/context.d.ts +1 -1
  8. package/esm/src/context.js +1 -1
  9. package/esm/src/data-api.js +18 -8
  10. package/esm/src/data-providers/sql-database.js +1 -1
  11. package/esm/src/data-providers/web-sql-data-provider.js +1 -1
  12. package/esm/src/live-query/EventSourceLiveQueryProvider.d.ts +2 -2
  13. package/esm/src/live-query/EventSourceLiveQueryProvider.js +9 -2
  14. package/esm/src/live-query/LiveQuery.d.ts +1 -1
  15. package/esm/src/live-query/LiveQuery.js +3 -2
  16. package/esm/src/live-query/LiveQueryPublisher.d.ts +33 -0
  17. package/esm/src/live-query/LiveQueryPublisher.js +102 -0
  18. package/esm/src/live-query/LiveQuerySubscriber.d.ts +67 -0
  19. package/esm/src/live-query/LiveQuerySubscriber.js +238 -0
  20. package/esm/src/remult3/RepositoryImplementation.js +0 -1
  21. package/esm/src/server-action.d.ts +4 -0
  22. package/esm/src/server-action.js +1 -1
  23. package/esm/src/valueConverters.js +1 -1
  24. package/package.json +1 -1
  25. package/postgres/schema-builder.js +4 -4
  26. package/remult-express.d.ts +2 -2
  27. package/remult-express.js +8 -10
  28. package/remult-knex/index.js +2 -2
  29. package/server/expressBridge.d.ts +1 -1
  30. package/server/expressBridge.js +2 -2
  31. package/src/context.d.ts +1 -1
  32. package/src/context.js +2 -2
  33. package/src/data-api.js +43 -19
  34. package/src/data-providers/sql-database.js +1 -1
  35. package/src/data-providers/web-sql-data-provider.js +1 -1
  36. package/src/live-query/EventSourceLiveQueryProvider.d.ts +2 -2
  37. package/src/live-query/EventSourceLiveQueryProvider.js +10 -3
  38. package/src/live-query/LiveQuery.d.ts +1 -1
  39. package/src/live-query/LiveQuery.js +8 -7
  40. package/src/live-query/LiveQueryPublisher.d.ts +33 -0
  41. package/src/live-query/LiveQueryPublisher.js +201 -0
  42. package/src/live-query/LiveQuerySubscriber.d.ts +67 -0
  43. package/src/live-query/LiveQuerySubscriber.js +332 -0
  44. package/src/remult3/RepositoryImplementation.js +0 -1
  45. package/src/server-action.d.ts +4 -0
  46. package/src/server-action.js +2 -1
  47. package/src/valueConverters.js +1 -1
@@ -43,7 +43,7 @@ export class PostgresSchemaBuilder {
43
43
  }
44
44
  }
45
45
  async verifyStructureOfAllEntities(remult) {
46
- console.log("start verify structure");
46
+ console.log("start verify structure"); //keep me
47
47
  for (const entityClass of allEntities) {
48
48
  let entity = remult.repo(entityClass).metadata;
49
49
  let e = await getDbNameProvider(entity);
@@ -56,7 +56,7 @@ export class PostgresSchemaBuilder {
56
56
  }
57
57
  }
58
58
  catch (err) {
59
- console.log("failed verify structure of " + e.entityName + " ", err);
59
+ /*keep me */ console.log("failed verify structure of " + e.entityName + " ", err);
60
60
  }
61
61
  }
62
62
  }
@@ -102,7 +102,7 @@ export class PostgresSchemaBuilder {
102
102
  }
103
103
  }
104
104
  catch (err) {
105
- console.log(err);
105
+ console.error(err);
106
106
  }
107
107
  }
108
108
  async verifyAllColumns(entity) {
@@ -122,7 +122,7 @@ export class PostgresSchemaBuilder {
122
122
  }
123
123
  }
124
124
  catch (err) {
125
- console.log(err);
125
+ console.error(err);
126
126
  }
127
127
  }
128
128
  }
@@ -1,8 +1,8 @@
1
1
  import * as express from 'express';
2
2
  import { RemultServer, RemultServerOptions } from './server/expressBridge';
3
3
  import { Remult } from './src/context';
4
- import { AMessageChannel, ChannelSubscribe } from './src/live-query/LiveQuery';
5
- import { ServerEventDispatcher, ServerEventMessage } from './src/live-query/LiveQueryManager';
4
+ import { AMessageChannel, ChannelSubscribe } from './src/live-query/LiveQuerySubscriber';
5
+ import { ServerEventDispatcher, ServerEventMessage } from './src/live-query/LiveQueryPublisher';
6
6
  export declare function remultExpress(options?: RemultServerOptions<express.Request> & {
7
7
  bodyParser?: boolean;
8
8
  bodySizeLimit?: string;
@@ -1,8 +1,7 @@
1
1
  import * as express from 'express';
2
2
  import { createRemultServer } from './server/expressBridge';
3
- import { streamUrl } from './src/live-query/LiveQuery';
4
- import { LiveQueryPublisher } from './src/live-query/LiveQueryManager';
5
- import { remult } from './src/remult-proxy';
3
+ import { streamUrl } from './src/live-query/LiveQuerySubscriber';
4
+ import { LiveQueryPublisher } from './src/live-query/LiveQueryPublisher';
6
5
  export function remultExpress(options) {
7
6
  let app = express.Router();
8
7
  if (!options) {
@@ -24,7 +23,9 @@ export function remultExpress(options) {
24
23
  httpServerEvents.openHttpServerStream(req, res);
25
24
  });
26
25
  app.post(streamPath, (r, res, next) => server.withRemult(r, res, next), (req, res) => {
27
- httpServerEvents.subscribeToChannel(remult, req.body, res);
26
+ server.liveQueryManager.unsubscribe(req.body);
27
+ res.json("ok");
28
+ //httpServerEvents.subscribeToChannel(remult, req.body, res)
28
29
  });
29
30
  app.get(streamPath + '/stats', (req, res) => {
30
31
  httpServerEvents.consoleInfo();
@@ -50,7 +51,7 @@ export class ServerEventsController {
50
51
  }
51
52
  }
52
53
  consoleInfo() {
53
- console.log(this.connections.map(x => ({
54
+ console.info(this.connections.map(x => ({
54
55
  client: x.clientId,
55
56
  channels: x.channels
56
57
  })));
@@ -111,7 +112,6 @@ export class ServerEventsController {
111
112
  z.messages.push({ id, message: message, eventType });
112
113
  while (z.messages.length > z.messageHistoryLength)
113
114
  z.messages.shift();
114
- //console.log({ sendingTo: z.connections.length })
115
115
  z.connections.forEach(y => y.write(id, message, eventType));
116
116
  }
117
117
  }
@@ -121,12 +121,10 @@ class clientConnection {
121
121
  this.clientId = clientId;
122
122
  this.channels = {};
123
123
  this.closed = false;
124
- //console.log("open connection");
125
124
  response.write("event:authenticate\ndata:" + "key" + "\n\n");
126
125
  this.sendLiveMessage();
127
126
  }
128
127
  close() {
129
- //console.log("close connection");
130
128
  this.closed = true;
131
129
  }
132
130
  write(id, message, eventType) {
@@ -256,7 +256,7 @@ export class KnexSchemaBuilder {
256
256
  this.additionalWhere = '';
257
257
  }
258
258
  async verifyStructureOfAllEntities(remult) {
259
- console.log("start verify structure");
259
+ console.info("start verify structure");
260
260
  for (const entity of allEntities) {
261
261
  let metadata = remult.repo(entity).metadata;
262
262
  try {
@@ -319,7 +319,7 @@ export class KnexSchemaBuilder {
319
319
  }
320
320
  }
321
321
  catch (err) {
322
- console.log(err);
322
+ console.error(err);
323
323
  }
324
324
  }
325
325
  }
@@ -5,7 +5,7 @@ import { AllowedForInstance, Remult, UserInfo } from '../src/context';
5
5
  import { ClassType } from '../classType';
6
6
  import { Repository } from '../src/remult3';
7
7
  import { IdEntity } from '../src/id-entity';
8
- import { LiveQueryPublisher } from '../src/live-query/LiveQueryManager';
8
+ import { LiveQueryPublisher } from '../src/live-query/LiveQueryPublisher';
9
9
  export interface RemultServerOptions<RequestType extends GenericRequest> {
10
10
  /** Sets a database connection for Remult.
11
11
  *
@@ -162,7 +162,7 @@ export class RemultServerImplementation {
162
162
  add(key, dataApiFactory, r) {
163
163
  let myRoute = this.options.rootPath + '/' + key;
164
164
  if (this.options.logApiEndPoints)
165
- console.log("[remult] " + myRoute);
165
+ console.info("[remult] " + myRoute);
166
166
  r.route(myRoute)
167
167
  .get(this.process((c, req, res) => dataApiFactory(c).httpGet(res, req))).put(this.process(async (c, req, res, orig) => dataApiFactory(c).put(res, '', orig.body)))
168
168
  .delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, '')))
@@ -225,7 +225,7 @@ export class RemultServerImplementation {
225
225
  })();
226
226
  this.backendMethodsOpenApi.push({ path: myUrl, allowed, tag });
227
227
  if (this.options.logApiEndPoints)
228
- console.log("[remult] " + myUrl);
228
+ console.info("[remult] " + myUrl);
229
229
  if (queue) {
230
230
  this.hasQueue = true;
231
231
  this.queue.mapQueuedAction(myUrl, what);
@@ -2,7 +2,7 @@ import { DataProvider, RestDataProviderHttpProvider } from "./data-interfaces";
2
2
  import { RestDataProviderHttpProviderUsingFetch } from './data-providers/rest-data-provider';
3
3
  import { EntityMetadata, EntityRef, FindOptions, Repository } from "./remult3";
4
4
  import { ClassType } from "../classType";
5
- import { LiveQueryClient } from "./live-query/LiveQuery";
5
+ import { LiveQueryClient } from "./live-query/LiveQuerySubscriber";
6
6
  export interface ExternalHttpProvider {
7
7
  post(url: string, data: any): Promise<any> | {
8
8
  toPromise(): Promise<any>;
@@ -1,7 +1,7 @@
1
1
  import { actionInfo, serverActionField } from './server-action';
2
2
  import { RestDataProvider, RestDataProviderHttpProviderUsingFetch } from './data-providers/rest-data-provider';
3
3
  import { RepositoryImplementation } from "./remult3/RepositoryImplementation";
4
- import { LiveQueryClient } from "./live-query/LiveQuery";
4
+ import { LiveQueryClient } from "./live-query/LiveQuerySubscriber";
5
5
  import { EventSourceLiveQueryProvider } from "./live-query/EventSourceLiveQueryProvider";
6
6
  import { RemultProxy } from "./remult-proxy";
7
7
  export class HttpProviderBridgeToRestDataProviderHttpProvider {
@@ -1,5 +1,6 @@
1
1
  import { customUrlToken, buildFilterFromRequestParameters } from './filter/filter-interfaces';
2
2
  import { Filter } from './filter/filter-interfaces';
3
+ import { ForbiddenError } from './server-action';
3
4
  export class DataApi {
4
5
  constructor(repository, remult, liveQueryProvider) {
5
6
  this.repository = repository;
@@ -175,17 +176,26 @@ export class DataApi {
175
176
  }
176
177
  async post(response, body) {
177
178
  try {
178
- let newr = this.repository.create();
179
- await this.repository.getEntityRef(newr)._updateEntityBasedOnApi(body);
180
- if (!this.repository.getEntityRef(newr).apiInsertAllowed) {
181
- response.forbidden();
182
- return;
179
+ const insert = async (what) => {
180
+ let newr = this.repository.create();
181
+ await this.repository.getEntityRef(newr)._updateEntityBasedOnApi(what);
182
+ if (!this.repository.getEntityRef(newr).apiInsertAllowed) {
183
+ throw new ForbiddenError();
184
+ }
185
+ await this.repository.getEntityRef(newr).save();
186
+ return this.repository.getEntityRef(newr).toApiJson();
187
+ };
188
+ if (Array.isArray(body)) {
189
+ response.created(await Promise.all(body.map(x => insert(x))));
183
190
  }
184
- await this.repository.getEntityRef(newr).save();
185
- response.created(this.repository.getEntityRef(newr).toApiJson());
191
+ else
192
+ response.created(await insert(body));
186
193
  }
187
194
  catch (err) {
188
- response.error(err);
195
+ if (err.isForbiddenError)
196
+ response.forbidden();
197
+ else
198
+ response.error(err);
189
199
  }
190
200
  }
191
201
  }
@@ -76,7 +76,7 @@ class LogSQLCommand {
76
76
  if (this.allQueries) {
77
77
  var d = new Date().valueOf() - start.valueOf();
78
78
  if (d > SqlDatabase.durationThreshold) {
79
- console.log({ query: sql, arguments: this.args, duration: d / 1000 });
79
+ console.info({ query: sql, arguments: this.args, duration: d / 1000 });
80
80
  }
81
81
  }
82
82
  return r;
@@ -18,7 +18,7 @@ export class WebSqlDataProvider {
18
18
  let e = await getDbNameProvider(entity);
19
19
  let sql = 'drop table if exists ' + e.entityName;
20
20
  if (SqlDatabase.LogToConsole)
21
- console.log(sql);
21
+ console.info(sql);
22
22
  await this.createCommand().execute(sql);
23
23
  }
24
24
  async createTable(entity) {
@@ -1,6 +1,6 @@
1
- import { LiveQueryProvider, MessageHandler } from "./LiveQuery";
1
+ import { LiveQueryProvider, MessageHandler } from "./LiveQuerySubscriber";
2
2
  export declare class EventSourceLiveQueryProvider implements LiveQueryProvider {
3
3
  private wrapMessage?;
4
4
  constructor(wrapMessage?: (what: () => void) => void);
5
- openStreamAndReturnCloseFunction(clientId: string, onMessage: MessageHandler): Promise<VoidFunction>;
5
+ openStreamAndReturnCloseFunction(clientId: string, onMessage: MessageHandler, onReconnect: VoidFunction): Promise<VoidFunction>;
6
6
  }
@@ -1,20 +1,27 @@
1
1
  import { remult } from "../remult-proxy";
2
- import { streamUrl } from "./LiveQuery";
2
+ import { streamUrl } from "./LiveQuerySubscriber";
3
3
  export class EventSourceLiveQueryProvider {
4
4
  constructor(wrapMessage) {
5
5
  this.wrapMessage = wrapMessage;
6
6
  if (!this.wrapMessage)
7
7
  this.wrapMessage = x => x();
8
8
  }
9
- openStreamAndReturnCloseFunction(clientId, onMessage) {
9
+ openStreamAndReturnCloseFunction(clientId, onMessage, onReconnect) {
10
10
  const source = new EventSource(remult.apiClient.url + '/' + streamUrl + "?id=" + clientId, {
11
11
  withCredentials: true
12
12
  });
13
13
  source.onmessage = e => {
14
14
  this.wrapMessage(() => onMessage(JSON.parse(e.data)));
15
15
  };
16
+ source.onerror = e => {
17
+ console.error("Live Query Event Source Error", e);
18
+ };
16
19
  return new Promise((res) => {
20
+ let connected = false;
17
21
  source.onopen = e => {
22
+ if (connected)
23
+ onReconnect();
24
+ connected = true;
18
25
  res(() => {
19
26
  source.close();
20
27
  });
@@ -1,6 +1,6 @@
1
1
  import { EntityOrderBy, FindOptions, Remult, Repository, RestDataProviderHttpProvider } from '../../index';
2
2
  import { Allowed } from '../context';
3
- import { ServerEventDispatcher } from './LiveQueryManager';
3
+ import { ServerEventDispatcher } from './LiveQueryPublisher';
4
4
  export declare const streamUrl = "stream1";
5
5
  export interface LiveQueryProvider {
6
6
  openStreamAndReturnCloseFunction(clientId: string, onMessage: MessageHandler): Promise<VoidFunction>;
@@ -4,7 +4,7 @@ import { RestEntityDataProvider } from '../data-providers/rest-data-provider';
4
4
  import { buildRestDataProvider } from '../context';
5
5
  import { getId } from '../remult3/getId';
6
6
  export const streamUrl = 'stream1';
7
- class LiveQueryOnFrontEnd {
7
+ class LiveQuerySubscriber {
8
8
  constructor(repo, query) {
9
9
  this.repo = repo;
10
10
  this.query = query;
@@ -54,6 +54,7 @@ class LiveQueryOnFrontEnd {
54
54
  this.forListeners(listener => listener(items => {
55
55
  if (!items)
56
56
  items = [];
57
+ items = items.filter(x => getId(this.repo.metadata, x) !== getId(this.repo.metadata, item));
57
58
  items.push(item);
58
59
  return sort(items);
59
60
  }));
@@ -141,7 +142,7 @@ export class LiveQueryClient {
141
142
  const eventTypeKey = JSON.stringify({ url, filterObject });
142
143
  let q = this.queries.get(eventTypeKey);
143
144
  if (!q) {
144
- this.queries.set(eventTypeKey, q = new LiveQueryOnFrontEnd(repo, { entityKey: repo.metadata.key, orderBy: options.orderBy }));
145
+ this.queries.set(eventTypeKey, q = new LiveQuerySubscriber(repo, { entityKey: repo.metadata.key, orderBy: options.orderBy }));
145
146
  url.add("__action", 'subscribe|' + this.clientId);
146
147
  const thenResult = (r) => {
147
148
  this.runPromise(q.setAllItems(r.result));
@@ -0,0 +1,33 @@
1
+ import { Remult } from '../..';
2
+ import { Repository, EntityRef, FindOptions } from '../remult3';
3
+ import { LiveQueryProvider } from '../data-api';
4
+ import { ChannelSubscribe, liveQueryMessage } from './LiveQuerySubscriber';
5
+ export declare class LiveQueryPublisher implements LiveQueryProvider {
6
+ private dispatcher;
7
+ unsubscribe(data: ChannelSubscribe): void;
8
+ constructor(dispatcher: ServerEventDispatcher);
9
+ subscribe(repo: Repository<any>, clientId: string, findOptions: FindOptions<any>, remult: Remult, ids: any[]): string;
10
+ clients: clientInfo[];
11
+ hasListeners(ref: EntityRef<any>): boolean;
12
+ runPromise(p: Promise<any>): void;
13
+ saved(ref: EntityRef<any>): void;
14
+ deleted(ref: EntityRef<any>): void;
15
+ }
16
+ export interface clientInfo {
17
+ clientId: string;
18
+ queries: ({
19
+ id: string;
20
+ repo: Repository<any>;
21
+ findOptions: FindOptions<any>;
22
+ ids: any[];
23
+ })[];
24
+ }
25
+ export interface ServerEventDispatcher {
26
+ sendQueryMessage(message: ServerEventMessage): void;
27
+ sendChannelMessage<T>(channel: string, message: any): void;
28
+ }
29
+ export interface ServerEventMessage {
30
+ clientId: string;
31
+ queryId: string;
32
+ message: liveQueryMessage;
33
+ }
@@ -0,0 +1,102 @@
1
+ import { v4 as uuid } from 'uuid';
2
+ export class LiveQueryPublisher {
3
+ constructor(dispatcher) {
4
+ this.dispatcher = dispatcher;
5
+ this.clients = [];
6
+ }
7
+ unsubscribe(data) {
8
+ let client = this.clients.find(c => c.clientId === data.clientId);
9
+ if (client)
10
+ client.queries = client.queries.filter(q => q.id !== data.channel);
11
+ }
12
+ subscribe(repo, clientId, findOptions, remult, ids) {
13
+ let client = this.clients.find(c => c.clientId === clientId);
14
+ if (!client) {
15
+ this.clients.push(client = { clientId: clientId, queries: [] });
16
+ }
17
+ const id = uuid();
18
+ client.queries.push({
19
+ id,
20
+ findOptions: findOptions,
21
+ repo,
22
+ ids
23
+ });
24
+ return id;
25
+ }
26
+ hasListeners(ref) {
27
+ for (const c of this.clients) {
28
+ for (const q of c.queries) {
29
+ if (q.repo.metadata.key === ref.metadata.key)
30
+ return true;
31
+ }
32
+ }
33
+ return false;
34
+ }
35
+ runPromise(p) {
36
+ }
37
+ //TODO - reconsider usage of zone
38
+ saved(ref) {
39
+ const isNew = ref.isNew();
40
+ const origId = isNew ? ref.getId() : ref.getOriginalId();
41
+ for (const c of this.clients) {
42
+ for (const q of c.queries) {
43
+ if (q.repo.metadata.key === ref.metadata.key) {
44
+ this.runPromise(q.repo.find(q.findOptions).then(currentItems => {
45
+ const currentIds = currentItems.map(x => q.repo.getEntityRef(x).getId());
46
+ const sendMessage = (message) => {
47
+ this.dispatcher.sendQueryMessage({ clientId: c.clientId, queryId: q.id, message });
48
+ };
49
+ for (const id of q.ids.filter(y => !currentIds.includes(y))) {
50
+ if (id != origId || !currentIds.includes(ref.getId()))
51
+ sendMessage({
52
+ type: "remove",
53
+ data: {
54
+ id: id
55
+ }
56
+ });
57
+ }
58
+ for (const item of currentItems) {
59
+ const itemRef = q.repo.getEntityRef(item);
60
+ if (itemRef.getId() == ref.getId() && q.ids.includes(origId)) {
61
+ sendMessage({
62
+ type: "replace",
63
+ data: {
64
+ oldId: origId,
65
+ item: itemRef.toApiJson()
66
+ }
67
+ });
68
+ }
69
+ else if (!q.ids.includes(itemRef.getId())) {
70
+ sendMessage({
71
+ type: "add",
72
+ data: { item: itemRef.toApiJson() }
73
+ });
74
+ }
75
+ }
76
+ q.ids = currentIds;
77
+ }));
78
+ }
79
+ }
80
+ }
81
+ }
82
+ deleted(ref) {
83
+ const id = ref.getOriginalId();
84
+ for (const c of this.clients) {
85
+ for (const q of c.queries) {
86
+ if (q.repo.metadata.key === ref.metadata.key) {
87
+ if (q.ids.includes(id)) {
88
+ this.dispatcher.sendQueryMessage({
89
+ clientId: c.clientId, queryId: q.id, message: {
90
+ type: "remove",
91
+ data: {
92
+ id: id
93
+ }
94
+ }
95
+ });
96
+ q.ids = q.ids.filter(y => y != id);
97
+ }
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,67 @@
1
+ import { EntityOrderBy, FindOptions, Remult, Repository, RestDataProviderHttpProvider } from '../../index';
2
+ import { Allowed } from '../context';
3
+ import { ServerEventDispatcher } from './LiveQueryPublisher';
4
+ export declare const streamUrl = "stream1";
5
+ export interface LiveQueryProvider {
6
+ openStreamAndReturnCloseFunction(clientId: string, onMessage: MessageHandler, onReconnect: VoidFunction): Promise<VoidFunction>;
7
+ }
8
+ export declare type MessageHandler = (message: {
9
+ data: any;
10
+ event: string;
11
+ }) => void;
12
+ export declare class LiveQueryClient {
13
+ lqp: LiveQueryProvider;
14
+ private provider?;
15
+ clientId: any;
16
+ private queries;
17
+ private channels;
18
+ constructor(lqp: LiveQueryProvider, provider?: RestDataProviderHttpProvider);
19
+ runPromise(p: Promise<any>): Promise<any>;
20
+ close(): void;
21
+ subscribeChannel<T>(key: string, onResult: (item: T) => void): () => void;
22
+ private closeIfNoListeners;
23
+ subscribe<entityType>(repo: Repository<entityType>, options: FindOptions<entityType>, onResult: (reducer: (prevState: entityType[]) => entityType[]) => void): () => void;
24
+ closeListener: Promise<VoidFunction>;
25
+ private openIfNoOpened;
26
+ }
27
+ export declare type listener = (message: any) => void;
28
+ export interface SubscribeToQueryArgs<entityType = any> {
29
+ entityKey: string;
30
+ orderBy?: EntityOrderBy<entityType>;
31
+ }
32
+ export declare type liveQueryMessage = {
33
+ type: "all";
34
+ data: any[];
35
+ } | {
36
+ type: "add";
37
+ data: any;
38
+ } | {
39
+ type: 'replace';
40
+ data: {
41
+ oldId: any;
42
+ item: any;
43
+ };
44
+ } | {
45
+ type: "remove";
46
+ data: {
47
+ id: any;
48
+ };
49
+ };
50
+ export interface SubscribeResult {
51
+ result: [];
52
+ id: string;
53
+ }
54
+ export interface ChannelSubscribe {
55
+ clientId: string;
56
+ channel: string;
57
+ remove: boolean;
58
+ }
59
+ export declare class AMessageChannel<messageType> {
60
+ private subscribedAllowed;
61
+ userCanSubscribe(channel: string, remult: Remult): boolean;
62
+ private key;
63
+ constructor(key: (string | ((remult: Remult) => string)), subscribedAllowed: Allowed);
64
+ send(what: messageType, remult?: Remult): void;
65
+ subscribe(client: LiveQueryClient, onValue: (value: messageType) => void, remult?: Remult): void;
66
+ dispatcher: ServerEventDispatcher;
67
+ }