Merge pull request 'feat(pouch-service): move toContainsRegex method to PouchService and add listIndexes and explain methods' (#22) from core/new-feature-pouch into main

Reviewed-on: eigen/fe-monorepo-template#22
This commit is contained in:
2026-07-06 04:59:53 +00:00
2 changed files with 27 additions and 25 deletions
@@ -52,16 +52,6 @@ export class PouchEnvelopeService<DefaultEntity extends object = any> extends Po
// ─── Private Helpers ──────────────────────────────────────── // ─── Private Helpers ────────────────────────────────────────
/**
* Build a case-insensitive regex pattern for keyword search
* without relying on `$options` (which PouchDB doesn't support).
*/
private toContainsRegex(keyword: string): string {
return keyword
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // escape special regex chars
.replace(/[a-zA-Z]/g, (c) => `[${c.toLowerCase()}${c.toUpperCase()}]`); // case-insensitive
}
private buildEnvelope(id: string, payload: Record<string, any>): Omit<CouchEnvelope, '_rev'> { private buildEnvelope(id: string, payload: Record<string, any>): Omit<CouchEnvelope, '_rev'> {
return { return {
_id: `${this.entity}:${id}`, _id: `${this.entity}:${id}`,
@@ -311,19 +301,4 @@ export class PouchEnvelopeService<DefaultEntity extends object = any> extends Po
index: { fields, ...(name ? { name } : {}) }, index: { fields, ...(name ? { name } : {}) },
}); });
} }
/**
* List currently defined indexes. Useful for debugging with `explain()`.
*/
async listIndexes(): Promise<PouchDB.Find.GetIndexesResponse<object>> {
return this.raw.getIndexes();
}
/**
* Explain how a given selector will be executed — shows which index (if any) is used.
* Returns `index.name === '_all_docs'` when the query falls back to a full scan.
*/
async explain<T extends object = DefaultEntity>(options: PouchDB.Find.FindRequest<T>): Promise<any> {
return (this.raw as any).explain(options as PouchDB.Find.FindRequest<object>);
}
} }
@@ -88,6 +88,16 @@ export class PouchService<DefaultType extends object = any> {
return this._status; return this._status;
} }
/**
* Build a case-insensitive regex pattern for keyword search
* without relying on `$options` (which PouchDB doesn't support).
*/
toContainsRegex(keyword: string): string {
return keyword
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // escape special regex chars
.replace(/[a-zA-Z]/g, (c) => `[${c.toLowerCase()}${c.toUpperCase()}]`); // case-insensitive
}
/** Turn sync ON for this DB. No-op if already connected or no remoteUrl configured. */ /** Turn sync ON for this DB. No-op if already connected or no remoteUrl configured. */
connect(): void { connect(): void {
this.startLiveSync(); this.startLiveSync();
@@ -294,4 +304,21 @@ export class PouchService<DefaultType extends object = any> {
this.listeners.delete(callback); this.listeners.delete(callback);
}; };
} }
// ─── New Methods (no base equivalent) ───────────────────────
/**
* List currently defined indexes. Useful for debugging with `explain()`.
*/
async listIndexes(): Promise<PouchDB.Find.GetIndexesResponse<object>> {
return this.raw.getIndexes();
}
/**
* Explain how a given selector will be executed — shows which index (if any) is used.
* Returns `index.name === '_all_docs'` when the query falls back to a full scan.
*/
async explain<T extends object = DefaultType>(options: PouchDB.Find.FindRequest<T>): Promise<any> {
return (this.raw as any).explain(options as PouchDB.Find.FindRequest<object>);
}
} }