@pulseindex/sdk 3.1.0 → 3.2.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.
- package/CHANGELOG.md +22 -0
- package/README.md +5 -0
- package/dist/index.d.mts +29 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.js +34 -0
- package/dist/index.mjs +34 -0
- package/package.json +1 -1
- package/proto/engine.proto +26 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.2.0
|
|
4
|
+
|
|
5
|
+
### Delete many entities in one call
|
|
6
|
+
|
|
7
|
+
`delete()` takes a single id, so clearing a catalogue meant one round trip per
|
|
8
|
+
row. There was no other way to do it through the API at all.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
for (const page of pages(idsToRemove, 10_000)) {
|
|
12
|
+
const { deletedCount } = await client.batchDelete(page);
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Up to 10,000 ids per call. A larger page is refused by name rather than
|
|
17
|
+
truncated, so a page that is too big fails loudly instead of deleting part of
|
|
18
|
+
itself and reporting success.
|
|
19
|
+
|
|
20
|
+
Ids that are unknown or already deleted are skipped rather than refused, so
|
|
21
|
+
retrying a page that half-applied is safe. `deletedCount` is the number of rows
|
|
22
|
+
that actually changed, which is lower than the number of ids you sent whenever
|
|
23
|
+
some were already gone.
|
|
24
|
+
|
|
3
25
|
## 3.1.0
|
|
4
26
|
|
|
5
27
|
### A radius no longer merges with your own OR
|
package/README.md
CHANGED
|
@@ -140,6 +140,10 @@ await client.batchIndex([
|
|
|
140
140
|
]);
|
|
141
141
|
|
|
142
142
|
await client.delete('1001');
|
|
143
|
+
|
|
144
|
+
// Clearing many rows: send ids in pages of up to 10,000. A larger page is
|
|
145
|
+
// refused by name rather than truncated.
|
|
146
|
+
await client.batchDelete([1002, 1003, 1004]);
|
|
143
147
|
```
|
|
144
148
|
|
|
145
149
|
Low-level PHP-compatible helper:
|
|
@@ -293,6 +297,7 @@ than failing your own requests immediately; if it persists, contact support.
|
|
|
293
297
|
| `client.index(id, attributes)` | `{ success }` | Upsert one entity |
|
|
294
298
|
| `client.batchIndex(entities)` | `{ indexedCount }` | Batch upsert |
|
|
295
299
|
| `client.delete(id)` | `{ success }` | Soft-delete an entity |
|
|
300
|
+
| `client.batchDelete(ids)` | `{ deletedCount }` | Soft-delete up to 10,000 entities in one call |
|
|
296
301
|
| `client.health()` | `boolean` | Whether the service is ready to answer queries |
|
|
297
302
|
| `client.servingStatus()` | `number` | Readiness as a status code, when you need more than a boolean |
|
|
298
303
|
| `client.close()` | `void` | Shut down the channel pool |
|
package/dist/index.d.mts
CHANGED
|
@@ -64,6 +64,13 @@ interface BatchIndexResponse {
|
|
|
64
64
|
interface DeleteResponse {
|
|
65
65
|
success: boolean;
|
|
66
66
|
}
|
|
67
|
+
interface BatchDeleteResponse {
|
|
68
|
+
/**
|
|
69
|
+
* How many rows actually changed. Lower than the number of ids sent when
|
|
70
|
+
* some were unknown or already deleted, which is not an error.
|
|
71
|
+
*/
|
|
72
|
+
deletedCount: number;
|
|
73
|
+
}
|
|
67
74
|
interface RadiusOptions {
|
|
68
75
|
lat: number;
|
|
69
76
|
lng?: number;
|
|
@@ -233,6 +240,7 @@ interface SearchEngineServiceClient extends grpc.Client {
|
|
|
233
240
|
indexEntity(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
234
241
|
batchIndexEntities(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
235
242
|
deleteEntity(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
243
|
+
batchDeleteEntities(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
236
244
|
search(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
237
245
|
}
|
|
238
246
|
/** `grpc.health.v1.Health` — the readiness check that needs no scope. */
|
|
@@ -295,6 +303,26 @@ declare class PulseIndexClient implements QueryExecutor {
|
|
|
295
303
|
batchIndex(entities: Array<EntityInput | BatchEntityInput>): Promise<BatchIndexResponse>;
|
|
296
304
|
delete(entityId: EntityId, tenantId?: string): Promise<DeleteResponse>;
|
|
297
305
|
deleteEntity(entityId: EntityId, tenantId?: string): Promise<boolean>;
|
|
306
|
+
/**
|
|
307
|
+
* Delete many entities in one call.
|
|
308
|
+
*
|
|
309
|
+
* `delete` takes a single id, so clearing a catalogue that way is one round
|
|
310
|
+
* trip per row. Send ids in pages of up to 10,000; the engine refuses a
|
|
311
|
+
* larger batch by name rather than truncating it, so a page that is too big
|
|
312
|
+
* fails loudly instead of deleting part of itself.
|
|
313
|
+
*
|
|
314
|
+
* Ids that are unknown or already deleted are skipped, so retrying a page
|
|
315
|
+
* that half-applied is safe. `deletedCount` is the number of rows that
|
|
316
|
+
* actually changed, which is lower than `entityIds.length` whenever some of
|
|
317
|
+
* them were already gone.
|
|
318
|
+
*
|
|
319
|
+
* ```ts
|
|
320
|
+
* for (const page of pages(allIds, 10_000)) {
|
|
321
|
+
* await client.batchDelete(page);
|
|
322
|
+
* }
|
|
323
|
+
* ```
|
|
324
|
+
*/
|
|
325
|
+
batchDelete(entityIds: readonly EntityId[], tenantId?: string): Promise<BatchDeleteResponse>;
|
|
298
326
|
/**
|
|
299
327
|
* True only when the engine can serve reads.
|
|
300
328
|
*
|
|
@@ -388,4 +416,4 @@ declare class PulseIndexQueryError extends PulseIndexError {
|
|
|
388
416
|
constructor(message: string, options?: ConstructorParameters<typeof PulseIndexError>[1]);
|
|
389
417
|
}
|
|
390
418
|
|
|
391
|
-
export { type BatchEntityInput, type BatchIndexResponse, ConnectionManager, DEFAULT_LIMIT, type DeleteResponse, type EncodedEntity, type EntityAttributes, type EntityId, type EntityInput, FilterOperation, type FilterPredicate, GeoHash, type IndexEntityRequest, type IndexEntityResponse, PulseIndex, PulseIndexAuthError, PulseIndexClient, type PulseIndexClientConfig, PulseIndexConnectionError, PulseIndexError, PulseIndexQueryError, QueryBuilder, type RadiusOptions, type RangePredicate, SERVING_STATUS, type SearchQueryRequest, type SearchRequestOptions, type SearchResponse, type SortSpec, PulseIndex as default, encodeEntity, sslEnabled, toUint64String };
|
|
419
|
+
export { type BatchDeleteResponse, type BatchEntityInput, type BatchIndexResponse, ConnectionManager, DEFAULT_LIMIT, type DeleteResponse, type EncodedEntity, type EntityAttributes, type EntityId, type EntityInput, FilterOperation, type FilterPredicate, GeoHash, type IndexEntityRequest, type IndexEntityResponse, PulseIndex, PulseIndexAuthError, PulseIndexClient, type PulseIndexClientConfig, PulseIndexConnectionError, PulseIndexError, PulseIndexQueryError, QueryBuilder, type RadiusOptions, type RangePredicate, SERVING_STATUS, type SearchQueryRequest, type SearchRequestOptions, type SearchResponse, type SortSpec, PulseIndex as default, encodeEntity, sslEnabled, toUint64String };
|
package/dist/index.d.ts
CHANGED
|
@@ -64,6 +64,13 @@ interface BatchIndexResponse {
|
|
|
64
64
|
interface DeleteResponse {
|
|
65
65
|
success: boolean;
|
|
66
66
|
}
|
|
67
|
+
interface BatchDeleteResponse {
|
|
68
|
+
/**
|
|
69
|
+
* How many rows actually changed. Lower than the number of ids sent when
|
|
70
|
+
* some were unknown or already deleted, which is not an error.
|
|
71
|
+
*/
|
|
72
|
+
deletedCount: number;
|
|
73
|
+
}
|
|
67
74
|
interface RadiusOptions {
|
|
68
75
|
lat: number;
|
|
69
76
|
lng?: number;
|
|
@@ -233,6 +240,7 @@ interface SearchEngineServiceClient extends grpc.Client {
|
|
|
233
240
|
indexEntity(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
234
241
|
batchIndexEntities(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
235
242
|
deleteEntity(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
243
|
+
batchDeleteEntities(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
236
244
|
search(request: unknown, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<unknown>): grpc.ClientUnaryCall;
|
|
237
245
|
}
|
|
238
246
|
/** `grpc.health.v1.Health` — the readiness check that needs no scope. */
|
|
@@ -295,6 +303,26 @@ declare class PulseIndexClient implements QueryExecutor {
|
|
|
295
303
|
batchIndex(entities: Array<EntityInput | BatchEntityInput>): Promise<BatchIndexResponse>;
|
|
296
304
|
delete(entityId: EntityId, tenantId?: string): Promise<DeleteResponse>;
|
|
297
305
|
deleteEntity(entityId: EntityId, tenantId?: string): Promise<boolean>;
|
|
306
|
+
/**
|
|
307
|
+
* Delete many entities in one call.
|
|
308
|
+
*
|
|
309
|
+
* `delete` takes a single id, so clearing a catalogue that way is one round
|
|
310
|
+
* trip per row. Send ids in pages of up to 10,000; the engine refuses a
|
|
311
|
+
* larger batch by name rather than truncating it, so a page that is too big
|
|
312
|
+
* fails loudly instead of deleting part of itself.
|
|
313
|
+
*
|
|
314
|
+
* Ids that are unknown or already deleted are skipped, so retrying a page
|
|
315
|
+
* that half-applied is safe. `deletedCount` is the number of rows that
|
|
316
|
+
* actually changed, which is lower than `entityIds.length` whenever some of
|
|
317
|
+
* them were already gone.
|
|
318
|
+
*
|
|
319
|
+
* ```ts
|
|
320
|
+
* for (const page of pages(allIds, 10_000)) {
|
|
321
|
+
* await client.batchDelete(page);
|
|
322
|
+
* }
|
|
323
|
+
* ```
|
|
324
|
+
*/
|
|
325
|
+
batchDelete(entityIds: readonly EntityId[], tenantId?: string): Promise<BatchDeleteResponse>;
|
|
298
326
|
/**
|
|
299
327
|
* True only when the engine can serve reads.
|
|
300
328
|
*
|
|
@@ -388,4 +416,4 @@ declare class PulseIndexQueryError extends PulseIndexError {
|
|
|
388
416
|
constructor(message: string, options?: ConstructorParameters<typeof PulseIndexError>[1]);
|
|
389
417
|
}
|
|
390
418
|
|
|
391
|
-
export { type BatchEntityInput, type BatchIndexResponse, ConnectionManager, DEFAULT_LIMIT, type DeleteResponse, type EncodedEntity, type EntityAttributes, type EntityId, type EntityInput, FilterOperation, type FilterPredicate, GeoHash, type IndexEntityRequest, type IndexEntityResponse, PulseIndex, PulseIndexAuthError, PulseIndexClient, type PulseIndexClientConfig, PulseIndexConnectionError, PulseIndexError, PulseIndexQueryError, QueryBuilder, type RadiusOptions, type RangePredicate, SERVING_STATUS, type SearchQueryRequest, type SearchRequestOptions, type SearchResponse, type SortSpec, PulseIndex as default, encodeEntity, sslEnabled, toUint64String };
|
|
419
|
+
export { type BatchDeleteResponse, type BatchEntityInput, type BatchIndexResponse, ConnectionManager, DEFAULT_LIMIT, type DeleteResponse, type EncodedEntity, type EntityAttributes, type EntityId, type EntityInput, FilterOperation, type FilterPredicate, GeoHash, type IndexEntityRequest, type IndexEntityResponse, PulseIndex, PulseIndexAuthError, PulseIndexClient, type PulseIndexClientConfig, PulseIndexConnectionError, PulseIndexError, PulseIndexQueryError, QueryBuilder, type RadiusOptions, type RangePredicate, SERVING_STATUS, type SearchQueryRequest, type SearchRequestOptions, type SearchResponse, type SortSpec, PulseIndex as default, encodeEntity, sslEnabled, toUint64String };
|
package/dist/index.js
CHANGED
|
@@ -1146,6 +1146,40 @@ var PulseIndexClient = class _PulseIndexClient {
|
|
|
1146
1146
|
const response = await this.delete(entityId, tenantId || this.connection.tenantId);
|
|
1147
1147
|
return response.success;
|
|
1148
1148
|
}
|
|
1149
|
+
/**
|
|
1150
|
+
* Delete many entities in one call.
|
|
1151
|
+
*
|
|
1152
|
+
* `delete` takes a single id, so clearing a catalogue that way is one round
|
|
1153
|
+
* trip per row. Send ids in pages of up to 10,000; the engine refuses a
|
|
1154
|
+
* larger batch by name rather than truncating it, so a page that is too big
|
|
1155
|
+
* fails loudly instead of deleting part of itself.
|
|
1156
|
+
*
|
|
1157
|
+
* Ids that are unknown or already deleted are skipped, so retrying a page
|
|
1158
|
+
* that half-applied is safe. `deletedCount` is the number of rows that
|
|
1159
|
+
* actually changed, which is lower than `entityIds.length` whenever some of
|
|
1160
|
+
* them were already gone.
|
|
1161
|
+
*
|
|
1162
|
+
* ```ts
|
|
1163
|
+
* for (const page of pages(allIds, 10_000)) {
|
|
1164
|
+
* await client.batchDelete(page);
|
|
1165
|
+
* }
|
|
1166
|
+
* ```
|
|
1167
|
+
*/
|
|
1168
|
+
async batchDelete(entityIds, tenantId) {
|
|
1169
|
+
const ids = entityIds.map((id, i) => toUint64String(id, `entityIds[${i}]`));
|
|
1170
|
+
const raw = await this.unary(
|
|
1171
|
+
(stub, metadata, options, callback) => stub.batchDeleteEntities(
|
|
1172
|
+
{
|
|
1173
|
+
entityIds: ids,
|
|
1174
|
+
tenantId: tenantId ?? this.connection.tenantId
|
|
1175
|
+
},
|
|
1176
|
+
metadata,
|
|
1177
|
+
options,
|
|
1178
|
+
callback
|
|
1179
|
+
)
|
|
1180
|
+
);
|
|
1181
|
+
return { deletedCount: Number(raw.deletedCount ?? 0) };
|
|
1182
|
+
}
|
|
1149
1183
|
/**
|
|
1150
1184
|
* True only when the engine can serve reads.
|
|
1151
1185
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -1123,6 +1123,40 @@ var PulseIndexClient = class _PulseIndexClient {
|
|
|
1123
1123
|
const response = await this.delete(entityId, tenantId || this.connection.tenantId);
|
|
1124
1124
|
return response.success;
|
|
1125
1125
|
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Delete many entities in one call.
|
|
1128
|
+
*
|
|
1129
|
+
* `delete` takes a single id, so clearing a catalogue that way is one round
|
|
1130
|
+
* trip per row. Send ids in pages of up to 10,000; the engine refuses a
|
|
1131
|
+
* larger batch by name rather than truncating it, so a page that is too big
|
|
1132
|
+
* fails loudly instead of deleting part of itself.
|
|
1133
|
+
*
|
|
1134
|
+
* Ids that are unknown or already deleted are skipped, so retrying a page
|
|
1135
|
+
* that half-applied is safe. `deletedCount` is the number of rows that
|
|
1136
|
+
* actually changed, which is lower than `entityIds.length` whenever some of
|
|
1137
|
+
* them were already gone.
|
|
1138
|
+
*
|
|
1139
|
+
* ```ts
|
|
1140
|
+
* for (const page of pages(allIds, 10_000)) {
|
|
1141
|
+
* await client.batchDelete(page);
|
|
1142
|
+
* }
|
|
1143
|
+
* ```
|
|
1144
|
+
*/
|
|
1145
|
+
async batchDelete(entityIds, tenantId) {
|
|
1146
|
+
const ids = entityIds.map((id, i) => toUint64String(id, `entityIds[${i}]`));
|
|
1147
|
+
const raw = await this.unary(
|
|
1148
|
+
(stub, metadata, options, callback) => stub.batchDeleteEntities(
|
|
1149
|
+
{
|
|
1150
|
+
entityIds: ids,
|
|
1151
|
+
tenantId: tenantId ?? this.connection.tenantId
|
|
1152
|
+
},
|
|
1153
|
+
metadata,
|
|
1154
|
+
options,
|
|
1155
|
+
callback
|
|
1156
|
+
)
|
|
1157
|
+
);
|
|
1158
|
+
return { deletedCount: Number(raw.deletedCount ?? 0) };
|
|
1159
|
+
}
|
|
1126
1160
|
/**
|
|
1127
1161
|
* True only when the engine can serve reads.
|
|
1128
1162
|
*
|
package/package.json
CHANGED
package/proto/engine.proto
CHANGED
|
@@ -36,6 +36,10 @@ service SearchEngineService {
|
|
|
36
36
|
// The entity id is excluded from subsequent Search results for that tenant.
|
|
37
37
|
rpc DeleteEntity (DeleteEntityRequest) returns (DeleteEntityResponse);
|
|
38
38
|
|
|
39
|
+
// BatchDeleteEntities soft-deletes many entities in one RPC.
|
|
40
|
+
// Use this to clear a catalogue: DeleteEntity takes a single id.
|
|
41
|
+
rpc BatchDeleteEntities (BatchDeleteEntitiesRequest) returns (BatchDeleteEntitiesResponse);
|
|
42
|
+
|
|
39
43
|
// Search applies the boolean filters (MUST / SHOULD / MUST_NOT) plus optional
|
|
40
44
|
// numeric range predicates and returns matching entity IDs only.
|
|
41
45
|
// When `limit` > 0, `total_matches` may be approximate; it is exact when
|
|
@@ -114,6 +118,28 @@ message DeleteEntityResponse {
|
|
|
114
118
|
bool success = 1;
|
|
115
119
|
}
|
|
116
120
|
|
|
121
|
+
// BatchDeleteEntitiesRequest deletes many entities in one tenant.
|
|
122
|
+
message BatchDeleteEntitiesRequest {
|
|
123
|
+
// Entity ids to delete. Ids that are unknown or already deleted are skipped
|
|
124
|
+
// rather than refused, so retrying a batch that half-applied is safe.
|
|
125
|
+
// Repeating an id inside one batch deletes it once.
|
|
126
|
+
//
|
|
127
|
+
// A batch above the server's maximum is refused with INVALID_ARGUMENT naming
|
|
128
|
+
// the ceiling, never silently truncated.
|
|
129
|
+
repeated uint64 entity_ids = 1;
|
|
130
|
+
|
|
131
|
+
// Tenant that owns the entities. Empty → "default". One tenant per batch.
|
|
132
|
+
string tenant_id = 2;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// BatchDeleteEntitiesResponse reports how many rows actually changed.
|
|
136
|
+
message BatchDeleteEntitiesResponse {
|
|
137
|
+
// Number of entities that were live and are now deleted. Lower than the
|
|
138
|
+
// number of ids sent when some were unknown or already deleted; that is not
|
|
139
|
+
// an error.
|
|
140
|
+
uint32 deleted_count = 1;
|
|
141
|
+
}
|
|
142
|
+
|
|
117
143
|
// ---------------------------------------------------------------------------
|
|
118
144
|
// Search predicates
|
|
119
145
|
// ---------------------------------------------------------------------------
|