@telestack/db-sdk 1.0.6 → 1.0.9
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/dist/index.d.ts +6 -0
- package/dist/index.js +64 -31
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -116,6 +116,8 @@ export declare class Query<T = any> {
|
|
|
116
116
|
private buildWhereClause;
|
|
117
117
|
/** Fetch documents matching the query */
|
|
118
118
|
get(): Promise<T[]>;
|
|
119
|
+
/** Apply sorting and limiting in-memory */
|
|
120
|
+
private applyOptions;
|
|
119
121
|
/** Check if a document matches the local filters */
|
|
120
122
|
private matches;
|
|
121
123
|
/** Subscribe to realtime updates for this query */
|
|
@@ -126,6 +128,10 @@ export declare class Query<T = any> {
|
|
|
126
128
|
user: string;
|
|
127
129
|
clientId: string;
|
|
128
130
|
}) => void): () => void;
|
|
131
|
+
/** Broadcast a transient signal to this collection (bypasses database) */
|
|
132
|
+
signal(data: any): Promise<void>;
|
|
133
|
+
/** Listen for transient signals on this collection */
|
|
134
|
+
onSignal(callback: (data: any) => void): () => void;
|
|
129
135
|
}
|
|
130
136
|
/**
|
|
131
137
|
* CollectionReference extends Query with add() and doc() methods
|
package/dist/index.js
CHANGED
|
@@ -364,23 +364,33 @@ export class Query {
|
|
|
364
364
|
const filtered = allDocs
|
|
365
365
|
.filter(d => d.path.startsWith(this.path) && this.matches(d.data))
|
|
366
366
|
.map(d => ({ id: d.path.split('/').pop(), data: d.data, metadata: { fromCache: true, hasPendingWrites: true } }));
|
|
367
|
-
|
|
368
|
-
if (this.orderByField) {
|
|
369
|
-
filtered.sort((a, b) => {
|
|
370
|
-
const valA = a[this.orderByField];
|
|
371
|
-
const valB = b[this.orderByField];
|
|
372
|
-
if (this.orderDirection === 'asc')
|
|
373
|
-
return valA > valB ? 1 : -1;
|
|
374
|
-
return valA < valB ? 1 : -1;
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
if (this.limitCount)
|
|
378
|
-
return filtered.slice(0, this.limitCount);
|
|
379
|
-
return filtered;
|
|
367
|
+
return this.applyOptions(filtered);
|
|
380
368
|
}
|
|
381
369
|
throw e;
|
|
382
370
|
}
|
|
383
371
|
}
|
|
372
|
+
/** Apply sorting and limiting in-memory */
|
|
373
|
+
applyOptions(docs) {
|
|
374
|
+
let results = [...docs];
|
|
375
|
+
if (this.orderByField) {
|
|
376
|
+
results.sort((a, b) => {
|
|
377
|
+
const valA = a.data ? a.data[this.orderByField] : a[this.orderByField];
|
|
378
|
+
const valB = b.data ? b.data[this.orderByField] : b[this.orderByField];
|
|
379
|
+
if (valA === undefined || valA === null)
|
|
380
|
+
return 1;
|
|
381
|
+
if (valB === undefined || valB === null)
|
|
382
|
+
return -1;
|
|
383
|
+
if (valA === valB)
|
|
384
|
+
return 0;
|
|
385
|
+
const comparison = valA > valB ? 1 : -1;
|
|
386
|
+
return this.orderDirection === 'asc' ? comparison : -comparison;
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
if (this.limitCount) {
|
|
390
|
+
results = results.slice(0, this.limitCount);
|
|
391
|
+
}
|
|
392
|
+
return results;
|
|
393
|
+
}
|
|
384
394
|
/** Check if a document matches the local filters */
|
|
385
395
|
matches(doc) {
|
|
386
396
|
for (const filter of this.filters) {
|
|
@@ -434,8 +444,8 @@ export class Query {
|
|
|
434
444
|
}
|
|
435
445
|
const debouncedCallback = () => {
|
|
436
446
|
if (this.debounceTimer)
|
|
437
|
-
|
|
438
|
-
this.debounceTimer =
|
|
447
|
+
cancelAnimationFrame(this.debounceTimer);
|
|
448
|
+
this.debounceTimer = requestAnimationFrame(() => callback([...this.docsCache]));
|
|
439
449
|
};
|
|
440
450
|
sub.on('publication', async (ctx) => {
|
|
441
451
|
const event = ctx.data;
|
|
@@ -446,26 +456,14 @@ export class Query {
|
|
|
446
456
|
const docId = event.id || (event.doc && event.doc.id);
|
|
447
457
|
if (event.type === 'CREATED' || event.type === 'SET') {
|
|
448
458
|
if (this.matches(event.doc.data)) {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
this.docsCache = docs;
|
|
452
|
-
callback(docs);
|
|
453
|
-
}
|
|
454
|
-
else {
|
|
455
|
-
this.docsCache = [...this.docsCache.filter(d => d.id !== docId), { id: docId, data: event.doc.data }];
|
|
456
|
-
changed = true;
|
|
457
|
-
}
|
|
459
|
+
this.docsCache = [...this.docsCache.filter(d => d.id !== docId), { id: docId, data: event.doc.data }];
|
|
460
|
+
changed = true;
|
|
458
461
|
}
|
|
459
462
|
}
|
|
460
463
|
else if (event.type === 'UPDATED') {
|
|
461
464
|
const docData = event.doc ? event.doc.data : (event.patch ? event.patch : {});
|
|
462
465
|
const matches = this.matches(docData);
|
|
463
|
-
if (
|
|
464
|
-
const docs = await this.get();
|
|
465
|
-
this.docsCache = docs;
|
|
466
|
-
callback(docs);
|
|
467
|
-
}
|
|
468
|
-
else if (matches) {
|
|
466
|
+
if (matches) {
|
|
469
467
|
this.docsCache = this.docsCache.map(d => d.id === docId ? { ...d, data: { ...d.data, ...docData } } : d);
|
|
470
468
|
changed = true;
|
|
471
469
|
}
|
|
@@ -478,7 +476,8 @@ export class Query {
|
|
|
478
476
|
this.docsCache = this.docsCache.filter(d => d.id !== docId);
|
|
479
477
|
changed = true;
|
|
480
478
|
}
|
|
481
|
-
if (changed
|
|
479
|
+
if (changed) {
|
|
480
|
+
this.docsCache = this.applyOptions(this.docsCache);
|
|
482
481
|
debouncedCallback();
|
|
483
482
|
}
|
|
484
483
|
});
|
|
@@ -517,6 +516,40 @@ export class Query {
|
|
|
517
516
|
sub.removeAllListeners();
|
|
518
517
|
};
|
|
519
518
|
}
|
|
519
|
+
/** Broadcast a transient signal to this collection (bypasses database) */
|
|
520
|
+
async signal(data) {
|
|
521
|
+
const centrifuge = this.client.getCentrifuge();
|
|
522
|
+
if (!centrifuge)
|
|
523
|
+
return;
|
|
524
|
+
const channel = `collection:${this.path.replace(/\//g, '_')}`;
|
|
525
|
+
let sub = centrifuge.getSubscription(channel);
|
|
526
|
+
if (!sub) {
|
|
527
|
+
sub = centrifuge.newSubscription(channel);
|
|
528
|
+
sub.subscribe();
|
|
529
|
+
}
|
|
530
|
+
await sub.publish({ type: 'SIGNAL', data, userId: this.client.config.userId });
|
|
531
|
+
}
|
|
532
|
+
/** Listen for transient signals on this collection */
|
|
533
|
+
onSignal(callback) {
|
|
534
|
+
const centrifuge = this.client.getCentrifuge();
|
|
535
|
+
if (!centrifuge)
|
|
536
|
+
return () => { };
|
|
537
|
+
const channel = `collection:${this.path.replace(/\//g, '_')}`;
|
|
538
|
+
let sub = centrifuge.getSubscription(channel);
|
|
539
|
+
if (!sub) {
|
|
540
|
+
sub = centrifuge.newSubscription(channel);
|
|
541
|
+
}
|
|
542
|
+
const handler = (ctx) => {
|
|
543
|
+
if (ctx.data.type === 'SIGNAL') {
|
|
544
|
+
callback({ ...ctx.data.data, _userId: ctx.data.userId });
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
sub.on('publication', handler);
|
|
548
|
+
sub.subscribe();
|
|
549
|
+
return () => {
|
|
550
|
+
sub.off('publication', handler);
|
|
551
|
+
};
|
|
552
|
+
}
|
|
520
553
|
}
|
|
521
554
|
/**
|
|
522
555
|
* CollectionReference extends Query with add() and doc() methods
|