fauxbase 0.4.0 → 0.5.1
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/README.md +585 -30
- package/dist/index.cjs +203 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -5
- package/dist/index.d.ts +57 -5
- package/dist/index.js +203 -5
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.cts
CHANGED
|
@@ -143,6 +143,51 @@ interface Driver {
|
|
|
143
143
|
clear(resource: string): void;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
type EventAction = 'created' | 'updated' | 'deleted' | 'bulkCreated' | 'bulkUpdated' | 'bulkDeleted';
|
|
147
|
+
interface FauxbaseEvent<T = any> {
|
|
148
|
+
action: EventAction;
|
|
149
|
+
resource: string;
|
|
150
|
+
data?: T;
|
|
151
|
+
id?: string;
|
|
152
|
+
ids?: string[];
|
|
153
|
+
timestamp: number;
|
|
154
|
+
source: 'local' | 'remote';
|
|
155
|
+
}
|
|
156
|
+
type EventHandler<T = any> = (event: FauxbaseEvent<T>) => void;
|
|
157
|
+
interface EventSourceAdapter {
|
|
158
|
+
connect(): void;
|
|
159
|
+
disconnect(): void;
|
|
160
|
+
}
|
|
161
|
+
interface SSEConfig {
|
|
162
|
+
type: 'sse';
|
|
163
|
+
url: string;
|
|
164
|
+
eventMap: Record<string, string>;
|
|
165
|
+
withCredentials?: boolean;
|
|
166
|
+
}
|
|
167
|
+
interface STOMPConfig {
|
|
168
|
+
type: 'stomp';
|
|
169
|
+
brokerUrl: string;
|
|
170
|
+
subscriptions: Record<string, string>;
|
|
171
|
+
connectHeaders?: Record<string, string>;
|
|
172
|
+
}
|
|
173
|
+
type EventSourceConfig = SSEConfig | STOMPConfig;
|
|
174
|
+
interface EventHandlersConfig {
|
|
175
|
+
[resource: string]: EventHandler;
|
|
176
|
+
}
|
|
177
|
+
type EventsConfig = true | {
|
|
178
|
+
source?: EventSourceConfig;
|
|
179
|
+
handlers?: EventHandlersConfig;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
declare class EventBus {
|
|
183
|
+
private listeners;
|
|
184
|
+
private anyListeners;
|
|
185
|
+
on(resource: string, handler: EventHandler): () => void;
|
|
186
|
+
onAny(handler: EventHandler): () => void;
|
|
187
|
+
emit(event: FauxbaseEvent): void;
|
|
188
|
+
destroy(): void;
|
|
189
|
+
}
|
|
190
|
+
|
|
146
191
|
declare function beforeCreate(): MethodDecorator;
|
|
147
192
|
declare function beforeUpdate(): MethodDecorator;
|
|
148
193
|
declare function afterCreate(): MethodDecorator;
|
|
@@ -153,6 +198,8 @@ declare abstract class Service<T extends Entity> {
|
|
|
153
198
|
protected driver: Driver;
|
|
154
199
|
protected resourceName: string;
|
|
155
200
|
protected client: any;
|
|
201
|
+
/** @internal */
|
|
202
|
+
_eventBus?: EventBus;
|
|
156
203
|
/** @internal — called by createClient to wire the service */
|
|
157
204
|
_init(driver: Driver, resourceName: string): void;
|
|
158
205
|
/** @internal — called by createClient to give services access to the client */
|
|
@@ -164,15 +211,16 @@ declare abstract class Service<T extends Entity> {
|
|
|
164
211
|
delete(id: string): Promise<ApiResponse<T>>;
|
|
165
212
|
count(filter?: Record<string, any>): Promise<number>;
|
|
166
213
|
get bulk(): {
|
|
167
|
-
create
|
|
168
|
-
update
|
|
214
|
+
create(items: Array<Partial<T>>): Promise<ApiResponse<T[]>>;
|
|
215
|
+
update(updates: Array<{
|
|
169
216
|
id: string;
|
|
170
217
|
data: Partial<T>;
|
|
171
|
-
}>)
|
|
172
|
-
delete
|
|
218
|
+
}>): Promise<ApiResponse<T[]>>;
|
|
219
|
+
delete(ids: string[]): Promise<ApiResponse<{
|
|
173
220
|
count: number;
|
|
174
221
|
}>>;
|
|
175
222
|
};
|
|
223
|
+
private emitEvent;
|
|
176
224
|
private runHooks;
|
|
177
225
|
}
|
|
178
226
|
|
|
@@ -270,6 +318,9 @@ type ClientResult<S extends Record<string, new (...args: any[]) => Service<any>>
|
|
|
270
318
|
auth: InstanceType<A>;
|
|
271
319
|
} : {}) & {
|
|
272
320
|
readonly ready: Promise<void>;
|
|
321
|
+
} & {
|
|
322
|
+
_eventBus?: EventBus;
|
|
323
|
+
disconnect?: () => void;
|
|
273
324
|
};
|
|
274
325
|
declare function createClient<S extends Record<string, new (...args: any[]) => Service<any>>, A extends (new (...args: any[]) => AuthService<any>) | undefined = undefined>(config: {
|
|
275
326
|
driver?: DriverConfig;
|
|
@@ -279,6 +330,7 @@ declare function createClient<S extends Record<string, new (...args: any[]) => S
|
|
|
279
330
|
overrides?: Record<string, {
|
|
280
331
|
driver: DriverConfig;
|
|
281
332
|
}>;
|
|
333
|
+
events?: EventsConfig;
|
|
282
334
|
}): ClientResult<S, A>;
|
|
283
335
|
|
|
284
336
|
declare function seed<T>(entityClass: new (...args: any[]) => T, data: Array<Partial<T>>): SeedDefinition<T>;
|
|
@@ -384,4 +436,4 @@ declare const expressPreset: Preset;
|
|
|
384
436
|
|
|
385
437
|
declare function getPreset(name: string): Preset;
|
|
386
438
|
|
|
387
|
-
export { type ApiResponse, type AuthContext, AuthService, type AuthState, type BaseFields, ConflictError, type Driver, type DriverConfig, Entity, FauxbaseError, type FauxbaseErrorPayload, type FieldOptions, type FilterOperator, type FilterStyle, ForbiddenError, type HookType, HttpDriver, type HttpDriverConfig, HttpError, LocalDriver, type LocalDriverConfig, type LoginCredentials, NetworkError, NotFoundError, type PageMeta, type PagedResponse, type Preset, type QueryParams, type SeedDefinition, Service, type SortParams, TimeoutError, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, defaultPreset, definePreset, djangoPreset, expressPreset, field, getPreset, laravelPreset, nestjsPreset, relation, seed, springBootPreset };
|
|
439
|
+
export { type ApiResponse, type AuthContext, AuthService, type AuthState, type BaseFields, ConflictError, type Driver, type DriverConfig, Entity, type EventAction, EventBus, type EventHandler, type EventHandlersConfig, type EventSourceAdapter, type EventSourceConfig, type EventsConfig, FauxbaseError, type FauxbaseErrorPayload, type FauxbaseEvent, type FieldOptions, type FilterOperator, type FilterStyle, ForbiddenError, type HookType, HttpDriver, type HttpDriverConfig, HttpError, LocalDriver, type LocalDriverConfig, type LoginCredentials, NetworkError, NotFoundError, type PageMeta, type PagedResponse, type Preset, type QueryParams, type SSEConfig, type STOMPConfig, type SeedDefinition, Service, type SortParams, TimeoutError, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, defaultPreset, definePreset, djangoPreset, expressPreset, field, getPreset, laravelPreset, nestjsPreset, relation, seed, springBootPreset };
|
package/dist/index.d.ts
CHANGED
|
@@ -143,6 +143,51 @@ interface Driver {
|
|
|
143
143
|
clear(resource: string): void;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
type EventAction = 'created' | 'updated' | 'deleted' | 'bulkCreated' | 'bulkUpdated' | 'bulkDeleted';
|
|
147
|
+
interface FauxbaseEvent<T = any> {
|
|
148
|
+
action: EventAction;
|
|
149
|
+
resource: string;
|
|
150
|
+
data?: T;
|
|
151
|
+
id?: string;
|
|
152
|
+
ids?: string[];
|
|
153
|
+
timestamp: number;
|
|
154
|
+
source: 'local' | 'remote';
|
|
155
|
+
}
|
|
156
|
+
type EventHandler<T = any> = (event: FauxbaseEvent<T>) => void;
|
|
157
|
+
interface EventSourceAdapter {
|
|
158
|
+
connect(): void;
|
|
159
|
+
disconnect(): void;
|
|
160
|
+
}
|
|
161
|
+
interface SSEConfig {
|
|
162
|
+
type: 'sse';
|
|
163
|
+
url: string;
|
|
164
|
+
eventMap: Record<string, string>;
|
|
165
|
+
withCredentials?: boolean;
|
|
166
|
+
}
|
|
167
|
+
interface STOMPConfig {
|
|
168
|
+
type: 'stomp';
|
|
169
|
+
brokerUrl: string;
|
|
170
|
+
subscriptions: Record<string, string>;
|
|
171
|
+
connectHeaders?: Record<string, string>;
|
|
172
|
+
}
|
|
173
|
+
type EventSourceConfig = SSEConfig | STOMPConfig;
|
|
174
|
+
interface EventHandlersConfig {
|
|
175
|
+
[resource: string]: EventHandler;
|
|
176
|
+
}
|
|
177
|
+
type EventsConfig = true | {
|
|
178
|
+
source?: EventSourceConfig;
|
|
179
|
+
handlers?: EventHandlersConfig;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
declare class EventBus {
|
|
183
|
+
private listeners;
|
|
184
|
+
private anyListeners;
|
|
185
|
+
on(resource: string, handler: EventHandler): () => void;
|
|
186
|
+
onAny(handler: EventHandler): () => void;
|
|
187
|
+
emit(event: FauxbaseEvent): void;
|
|
188
|
+
destroy(): void;
|
|
189
|
+
}
|
|
190
|
+
|
|
146
191
|
declare function beforeCreate(): MethodDecorator;
|
|
147
192
|
declare function beforeUpdate(): MethodDecorator;
|
|
148
193
|
declare function afterCreate(): MethodDecorator;
|
|
@@ -153,6 +198,8 @@ declare abstract class Service<T extends Entity> {
|
|
|
153
198
|
protected driver: Driver;
|
|
154
199
|
protected resourceName: string;
|
|
155
200
|
protected client: any;
|
|
201
|
+
/** @internal */
|
|
202
|
+
_eventBus?: EventBus;
|
|
156
203
|
/** @internal — called by createClient to wire the service */
|
|
157
204
|
_init(driver: Driver, resourceName: string): void;
|
|
158
205
|
/** @internal — called by createClient to give services access to the client */
|
|
@@ -164,15 +211,16 @@ declare abstract class Service<T extends Entity> {
|
|
|
164
211
|
delete(id: string): Promise<ApiResponse<T>>;
|
|
165
212
|
count(filter?: Record<string, any>): Promise<number>;
|
|
166
213
|
get bulk(): {
|
|
167
|
-
create
|
|
168
|
-
update
|
|
214
|
+
create(items: Array<Partial<T>>): Promise<ApiResponse<T[]>>;
|
|
215
|
+
update(updates: Array<{
|
|
169
216
|
id: string;
|
|
170
217
|
data: Partial<T>;
|
|
171
|
-
}>)
|
|
172
|
-
delete
|
|
218
|
+
}>): Promise<ApiResponse<T[]>>;
|
|
219
|
+
delete(ids: string[]): Promise<ApiResponse<{
|
|
173
220
|
count: number;
|
|
174
221
|
}>>;
|
|
175
222
|
};
|
|
223
|
+
private emitEvent;
|
|
176
224
|
private runHooks;
|
|
177
225
|
}
|
|
178
226
|
|
|
@@ -270,6 +318,9 @@ type ClientResult<S extends Record<string, new (...args: any[]) => Service<any>>
|
|
|
270
318
|
auth: InstanceType<A>;
|
|
271
319
|
} : {}) & {
|
|
272
320
|
readonly ready: Promise<void>;
|
|
321
|
+
} & {
|
|
322
|
+
_eventBus?: EventBus;
|
|
323
|
+
disconnect?: () => void;
|
|
273
324
|
};
|
|
274
325
|
declare function createClient<S extends Record<string, new (...args: any[]) => Service<any>>, A extends (new (...args: any[]) => AuthService<any>) | undefined = undefined>(config: {
|
|
275
326
|
driver?: DriverConfig;
|
|
@@ -279,6 +330,7 @@ declare function createClient<S extends Record<string, new (...args: any[]) => S
|
|
|
279
330
|
overrides?: Record<string, {
|
|
280
331
|
driver: DriverConfig;
|
|
281
332
|
}>;
|
|
333
|
+
events?: EventsConfig;
|
|
282
334
|
}): ClientResult<S, A>;
|
|
283
335
|
|
|
284
336
|
declare function seed<T>(entityClass: new (...args: any[]) => T, data: Array<Partial<T>>): SeedDefinition<T>;
|
|
@@ -384,4 +436,4 @@ declare const expressPreset: Preset;
|
|
|
384
436
|
|
|
385
437
|
declare function getPreset(name: string): Preset;
|
|
386
438
|
|
|
387
|
-
export { type ApiResponse, type AuthContext, AuthService, type AuthState, type BaseFields, ConflictError, type Driver, type DriverConfig, Entity, FauxbaseError, type FauxbaseErrorPayload, type FieldOptions, type FilterOperator, type FilterStyle, ForbiddenError, type HookType, HttpDriver, type HttpDriverConfig, HttpError, LocalDriver, type LocalDriverConfig, type LoginCredentials, NetworkError, NotFoundError, type PageMeta, type PagedResponse, type Preset, type QueryParams, type SeedDefinition, Service, type SortParams, TimeoutError, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, defaultPreset, definePreset, djangoPreset, expressPreset, field, getPreset, laravelPreset, nestjsPreset, relation, seed, springBootPreset };
|
|
439
|
+
export { type ApiResponse, type AuthContext, AuthService, type AuthState, type BaseFields, ConflictError, type Driver, type DriverConfig, Entity, type EventAction, EventBus, type EventHandler, type EventHandlersConfig, type EventSourceAdapter, type EventSourceConfig, type EventsConfig, FauxbaseError, type FauxbaseErrorPayload, type FauxbaseEvent, type FieldOptions, type FilterOperator, type FilterStyle, ForbiddenError, type HookType, HttpDriver, type HttpDriverConfig, HttpError, LocalDriver, type LocalDriverConfig, type LoginCredentials, NetworkError, NotFoundError, type PageMeta, type PagedResponse, type Preset, type QueryParams, type SSEConfig, type STOMPConfig, type SeedDefinition, Service, type SortParams, TimeoutError, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, defaultPreset, definePreset, djangoPreset, expressPreset, field, getPreset, laravelPreset, nestjsPreset, relation, seed, springBootPreset };
|
package/dist/index.js
CHANGED
|
@@ -181,6 +181,8 @@ var Service = class {
|
|
|
181
181
|
driver;
|
|
182
182
|
resourceName;
|
|
183
183
|
client;
|
|
184
|
+
/** @internal */
|
|
185
|
+
_eventBus;
|
|
184
186
|
/** @internal — called by createClient to wire the service */
|
|
185
187
|
_init(driver, resourceName) {
|
|
186
188
|
this.driver = driver;
|
|
@@ -201,27 +203,56 @@ var Service = class {
|
|
|
201
203
|
await this.runHooks("beforeCreate", data, allItems);
|
|
202
204
|
const result = await this.driver.create(this.resourceName, data);
|
|
203
205
|
await this.runHooks("afterCreate", result.data);
|
|
206
|
+
this.emitEvent("created", { data: result.data, id: result.data.id });
|
|
204
207
|
return result;
|
|
205
208
|
}
|
|
206
209
|
async update(id, data) {
|
|
207
210
|
await this.runHooks("beforeUpdate", id, data);
|
|
208
211
|
const result = await this.driver.update(this.resourceName, id, data);
|
|
209
212
|
await this.runHooks("afterUpdate", result.data);
|
|
213
|
+
this.emitEvent("updated", { data: result.data, id });
|
|
210
214
|
return result;
|
|
211
215
|
}
|
|
212
216
|
async delete(id) {
|
|
213
|
-
|
|
217
|
+
const result = await this.driver.delete(this.resourceName, id);
|
|
218
|
+
this.emitEvent("deleted", { data: result.data, id });
|
|
219
|
+
return result;
|
|
214
220
|
}
|
|
215
221
|
async count(filter) {
|
|
216
222
|
return this.driver.count(this.resourceName, filter);
|
|
217
223
|
}
|
|
218
224
|
get bulk() {
|
|
225
|
+
const self = this;
|
|
219
226
|
return {
|
|
220
|
-
create
|
|
221
|
-
|
|
222
|
-
|
|
227
|
+
async create(items) {
|
|
228
|
+
const result = await self.driver.bulkCreate(self.resourceName, items);
|
|
229
|
+
self.emitEvent("bulkCreated", { data: result.data });
|
|
230
|
+
return result;
|
|
231
|
+
},
|
|
232
|
+
async update(updates) {
|
|
233
|
+
const result = await self.driver.bulkUpdate(self.resourceName, updates);
|
|
234
|
+
self.emitEvent("bulkUpdated", { data: result.data, ids: updates.map((u) => u.id) });
|
|
235
|
+
return result;
|
|
236
|
+
},
|
|
237
|
+
async delete(ids) {
|
|
238
|
+
const result = await self.driver.bulkDelete(self.resourceName, ids);
|
|
239
|
+
self.emitEvent("bulkDeleted", { ids });
|
|
240
|
+
return result;
|
|
241
|
+
}
|
|
223
242
|
};
|
|
224
243
|
}
|
|
244
|
+
emitEvent(action, extra) {
|
|
245
|
+
if (!this._eventBus) return;
|
|
246
|
+
this._eventBus.emit({
|
|
247
|
+
action,
|
|
248
|
+
resource: this.resourceName,
|
|
249
|
+
data: extra.data,
|
|
250
|
+
id: extra.id,
|
|
251
|
+
ids: extra.ids,
|
|
252
|
+
timestamp: Date.now(),
|
|
253
|
+
source: "local"
|
|
254
|
+
});
|
|
255
|
+
}
|
|
225
256
|
async runHooks(hookType, ...args) {
|
|
226
257
|
const methods = getHooks(this.constructor, hookType);
|
|
227
258
|
for (const methodName of methods) {
|
|
@@ -1358,6 +1389,146 @@ var HttpDriver = class {
|
|
|
1358
1389
|
}
|
|
1359
1390
|
};
|
|
1360
1391
|
|
|
1392
|
+
// src/events/event-bus.ts
|
|
1393
|
+
var EventBus = class {
|
|
1394
|
+
listeners = /* @__PURE__ */ new Map();
|
|
1395
|
+
anyListeners = /* @__PURE__ */ new Set();
|
|
1396
|
+
on(resource, handler) {
|
|
1397
|
+
if (!this.listeners.has(resource)) {
|
|
1398
|
+
this.listeners.set(resource, /* @__PURE__ */ new Set());
|
|
1399
|
+
}
|
|
1400
|
+
this.listeners.get(resource).add(handler);
|
|
1401
|
+
return () => {
|
|
1402
|
+
this.listeners.get(resource)?.delete(handler);
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
onAny(handler) {
|
|
1406
|
+
this.anyListeners.add(handler);
|
|
1407
|
+
return () => {
|
|
1408
|
+
this.anyListeners.delete(handler);
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
emit(event) {
|
|
1412
|
+
const resourceListeners = this.listeners.get(event.resource);
|
|
1413
|
+
if (resourceListeners) {
|
|
1414
|
+
for (const handler of resourceListeners) {
|
|
1415
|
+
handler(event);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
for (const handler of this.anyListeners) {
|
|
1419
|
+
handler(event);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
destroy() {
|
|
1423
|
+
this.listeners.clear();
|
|
1424
|
+
this.anyListeners.clear();
|
|
1425
|
+
}
|
|
1426
|
+
};
|
|
1427
|
+
|
|
1428
|
+
// src/events/sse-source.ts
|
|
1429
|
+
var SSESource = class {
|
|
1430
|
+
constructor(config, eventBus) {
|
|
1431
|
+
this.config = config;
|
|
1432
|
+
this.eventBus = eventBus;
|
|
1433
|
+
}
|
|
1434
|
+
eventSource = null;
|
|
1435
|
+
connect() {
|
|
1436
|
+
this.eventSource = new EventSource(this.config.url, {
|
|
1437
|
+
withCredentials: this.config.withCredentials
|
|
1438
|
+
});
|
|
1439
|
+
for (const [eventType, resource] of Object.entries(this.config.eventMap)) {
|
|
1440
|
+
this.eventSource.addEventListener(eventType, (e) => {
|
|
1441
|
+
const parsed = this.parseEvent(e, resource);
|
|
1442
|
+
if (parsed) {
|
|
1443
|
+
this.eventBus.emit(parsed);
|
|
1444
|
+
}
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
disconnect() {
|
|
1449
|
+
if (this.eventSource) {
|
|
1450
|
+
this.eventSource.close();
|
|
1451
|
+
this.eventSource = null;
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
parseEvent(e, resource) {
|
|
1455
|
+
try {
|
|
1456
|
+
const raw = JSON.parse(e.data);
|
|
1457
|
+
return {
|
|
1458
|
+
action: raw.action,
|
|
1459
|
+
resource,
|
|
1460
|
+
data: raw.data,
|
|
1461
|
+
id: raw.id,
|
|
1462
|
+
ids: raw.ids,
|
|
1463
|
+
timestamp: raw.timestamp ?? Date.now(),
|
|
1464
|
+
source: "remote"
|
|
1465
|
+
};
|
|
1466
|
+
} catch {
|
|
1467
|
+
return null;
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
|
|
1472
|
+
// src/events/stomp-source.ts
|
|
1473
|
+
var STOMPSource = class {
|
|
1474
|
+
constructor(config, eventBus) {
|
|
1475
|
+
this.config = config;
|
|
1476
|
+
this.eventBus = eventBus;
|
|
1477
|
+
}
|
|
1478
|
+
client = null;
|
|
1479
|
+
connect() {
|
|
1480
|
+
this.connectAsync();
|
|
1481
|
+
}
|
|
1482
|
+
async connectAsync() {
|
|
1483
|
+
let StompJs;
|
|
1484
|
+
try {
|
|
1485
|
+
const moduleName = "@stomp/stompjs";
|
|
1486
|
+
StompJs = await Function("m", "return import(m)")(moduleName);
|
|
1487
|
+
} catch {
|
|
1488
|
+
throw new Error(
|
|
1489
|
+
"STOMP source requires @stomp/stompjs. Install it: npm install @stomp/stompjs"
|
|
1490
|
+
);
|
|
1491
|
+
}
|
|
1492
|
+
this.client = new StompJs.Client({
|
|
1493
|
+
brokerURL: this.config.brokerUrl,
|
|
1494
|
+
connectHeaders: this.config.connectHeaders,
|
|
1495
|
+
onConnect: () => {
|
|
1496
|
+
for (const [destination, resource] of Object.entries(this.config.subscriptions)) {
|
|
1497
|
+
this.client.subscribe(destination, (message) => {
|
|
1498
|
+
const parsed = this.parseMessage(message, resource);
|
|
1499
|
+
if (parsed) {
|
|
1500
|
+
this.eventBus.emit(parsed);
|
|
1501
|
+
}
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
});
|
|
1506
|
+
this.client.activate();
|
|
1507
|
+
}
|
|
1508
|
+
disconnect() {
|
|
1509
|
+
if (this.client) {
|
|
1510
|
+
this.client.deactivate();
|
|
1511
|
+
this.client = null;
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
parseMessage(message, resource) {
|
|
1515
|
+
try {
|
|
1516
|
+
const raw = JSON.parse(message.body);
|
|
1517
|
+
return {
|
|
1518
|
+
action: raw.action,
|
|
1519
|
+
resource,
|
|
1520
|
+
data: raw.data,
|
|
1521
|
+
id: raw.id,
|
|
1522
|
+
ids: raw.ids,
|
|
1523
|
+
timestamp: raw.timestamp ?? Date.now(),
|
|
1524
|
+
source: "remote"
|
|
1525
|
+
};
|
|
1526
|
+
} catch {
|
|
1527
|
+
return null;
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
|
|
1361
1532
|
// src/seed.ts
|
|
1362
1533
|
function seed(entityClass, data) {
|
|
1363
1534
|
const entityName = entityClass.name.toLowerCase();
|
|
@@ -1456,6 +1627,33 @@ function createClient(config) {
|
|
|
1456
1627
|
svc._setClient(client);
|
|
1457
1628
|
}
|
|
1458
1629
|
}
|
|
1630
|
+
let eventSource = null;
|
|
1631
|
+
if (config.events) {
|
|
1632
|
+
const eventBus = new EventBus();
|
|
1633
|
+
client._eventBus = eventBus;
|
|
1634
|
+
for (const [name, ServiceClass] of Object.entries(config.services)) {
|
|
1635
|
+
const svc = client[name];
|
|
1636
|
+
svc._eventBus = eventBus;
|
|
1637
|
+
}
|
|
1638
|
+
const eventsConfig = config.events === true ? {} : config.events;
|
|
1639
|
+
if (eventsConfig.handlers) {
|
|
1640
|
+
for (const [resource, handler] of Object.entries(eventsConfig.handlers)) {
|
|
1641
|
+
eventBus.on(resource, handler);
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
if (eventsConfig.source) {
|
|
1645
|
+
if (eventsConfig.source.type === "sse") {
|
|
1646
|
+
eventSource = new SSESource(eventsConfig.source, eventBus);
|
|
1647
|
+
} else if (eventsConfig.source.type === "stomp") {
|
|
1648
|
+
eventSource = new STOMPSource(eventsConfig.source, eventBus);
|
|
1649
|
+
}
|
|
1650
|
+
eventSource?.connect();
|
|
1651
|
+
}
|
|
1652
|
+
client.disconnect = () => {
|
|
1653
|
+
eventSource?.disconnect();
|
|
1654
|
+
eventBus.destroy();
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1459
1657
|
let readyPromise;
|
|
1460
1658
|
if (defaultDriver instanceof LocalDriver) {
|
|
1461
1659
|
if (defaultDriver.isReady) {
|
|
@@ -1501,6 +1699,6 @@ function applySeedsIfNeeded(driver, seeds) {
|
|
|
1501
1699
|
driver.setSeedVersion(newVersion);
|
|
1502
1700
|
}
|
|
1503
1701
|
|
|
1504
|
-
export { AuthService, ConflictError, Entity, FauxbaseError, ForbiddenError, HttpDriver, HttpError, LocalDriver, NetworkError, NotFoundError, Service, TimeoutError, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, defaultPreset, definePreset, djangoPreset, expressPreset, field, getPreset, laravelPreset, nestjsPreset, relation, seed, springBootPreset };
|
|
1702
|
+
export { AuthService, ConflictError, Entity, EventBus, FauxbaseError, ForbiddenError, HttpDriver, HttpError, LocalDriver, NetworkError, NotFoundError, Service, TimeoutError, ValidationError, afterCreate, afterUpdate, beforeCreate, beforeUpdate, computed, createClient, defaultPreset, definePreset, djangoPreset, expressPreset, field, getPreset, laravelPreset, nestjsPreset, relation, seed, springBootPreset };
|
|
1505
1703
|
//# sourceMappingURL=index.js.map
|
|
1506
1704
|
//# sourceMappingURL=index.js.map
|