@pulseindex/sdk 2.0.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 +102 -0
- package/LICENSE +21 -0
- package/README.md +326 -0
- package/dist/index.d.mts +324 -0
- package/dist/index.d.ts +324 -0
- package/dist/index.js +1195 -0
- package/dist/index.mjs +1158 -0
- package/package.json +69 -0
- package/proto/engine.proto +191 -0
- package/proto/health.proto +32 -0
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pulseindex/sdk",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Official Node.js & TypeScript SDK for PulseIndex — hosted search and filtering for large entity sets",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "PulseIndex",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"pulseindex",
|
|
9
|
+
"sdk",
|
|
10
|
+
"grpc",
|
|
11
|
+
"search",
|
|
12
|
+
"indexing",
|
|
13
|
+
"geohash",
|
|
14
|
+
"typescript",
|
|
15
|
+
"nodejs"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://usepulseindex.com",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://usepulseindex.com/support"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18"
|
|
23
|
+
},
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"module": "./dist/index.mjs",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"import": {
|
|
30
|
+
"types": "./dist/index.d.mts",
|
|
31
|
+
"default": "./dist/index.mjs"
|
|
32
|
+
},
|
|
33
|
+
"require": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"./proto/engine.proto": "./proto/engine.proto",
|
|
39
|
+
"./proto/health.proto": "./proto/health.proto"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"proto",
|
|
44
|
+
"README.md",
|
|
45
|
+
"LICENSE",
|
|
46
|
+
"CHANGELOG.md"
|
|
47
|
+
],
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsup",
|
|
53
|
+
"typecheck": "tsc --noEmit",
|
|
54
|
+
"check:proto": "node scripts/check-proto.mjs",
|
|
55
|
+
"test": "vitest run",
|
|
56
|
+
"test:watch": "vitest",
|
|
57
|
+
"prepublishOnly": "npm run build && npm run test"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@grpc/grpc-js": "^1.12.6",
|
|
61
|
+
"@grpc/proto-loader": "^0.7.13"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/node": "^22.13.10",
|
|
65
|
+
"tsup": "^8.4.0",
|
|
66
|
+
"typescript": "^5.8.2",
|
|
67
|
+
"vitest": "^3.0.9"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// PulseIndex Engine gRPC API
|
|
2
|
+
//
|
|
3
|
+
// Package: pulseindex.engine.v1
|
|
4
|
+
//
|
|
5
|
+
// The wire contract for the PulseIndex service. Client SDKs generate stubs
|
|
6
|
+
// directly from this file. Queries return matching entity IDs, which the caller
|
|
7
|
+
// hydrates from its own primary data store — record contents are never sent
|
|
8
|
+
// here and are never stored by the service.
|
|
9
|
+
//
|
|
10
|
+
// Authentication (transport metadata, not proto fields):
|
|
11
|
+
// - Header `x-api-key: <key>` OR
|
|
12
|
+
// - Header `authorization: Bearer <key>`
|
|
13
|
+
// Keys are issued and revoked from the PulseIndex dashboard.
|
|
14
|
+
//
|
|
15
|
+
// Multi-tenancy:
|
|
16
|
+
// Every mutating / query RPC that touches index state carries `tenant_id`.
|
|
17
|
+
// Empty `tenant_id` is normalized server-side to `"default"`. Tenants are
|
|
18
|
+
// fully isolated from one another.
|
|
19
|
+
//
|
|
20
|
+
syntax = "proto3";
|
|
21
|
+
|
|
22
|
+
package pulseindex.engine.v1;
|
|
23
|
+
|
|
24
|
+
// SearchEngineService is the PulseIndex query and indexing API.
|
|
25
|
+
service SearchEngineService {
|
|
26
|
+
// IndexEntity upserts a single entity into the tenant's index.
|
|
27
|
+
// Re-indexing the same entity_id within a tenant replaces its attributes and
|
|
28
|
+
// clears any soft-delete for that id.
|
|
29
|
+
rpc IndexEntity (IndexEntityRequest) returns (IndexEntityResponse);
|
|
30
|
+
|
|
31
|
+
// BatchIndexEntities indexes many entities in one RPC.
|
|
32
|
+
// Processing is ordered; capacity / auth failures abort the batch.
|
|
33
|
+
rpc BatchIndexEntities (BatchIndexEntitiesRequest) returns (BatchIndexEntitiesResponse);
|
|
34
|
+
|
|
35
|
+
// DeleteEntity soft-deletes an entity inside a tenant.
|
|
36
|
+
// The entity id is excluded from subsequent Search results for that tenant.
|
|
37
|
+
rpc DeleteEntity (DeleteEntityRequest) returns (DeleteEntityResponse);
|
|
38
|
+
|
|
39
|
+
// Search applies the boolean filters (MUST / SHOULD / MUST_NOT) plus optional
|
|
40
|
+
// numeric range predicates and returns matching entity IDs only.
|
|
41
|
+
// When `limit` > 0, `total_matches` may be approximate; it is exact when
|
|
42
|
+
// `limit` is 0.
|
|
43
|
+
rpc Search (SearchQueryRequest) returns (SearchQueryResponse);
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Indexing
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
// IndexEntityRequest describes a single entity to upsert.
|
|
54
|
+
// No record content (name, description, PII) is sent or stored — only the
|
|
55
|
+
// attributes you want to filter on.
|
|
56
|
+
message IndexEntityRequest {
|
|
57
|
+
// Stable application-level entity identifier (e.g. listing id).
|
|
58
|
+
// Dense, ascending ids index and query most efficiently.
|
|
59
|
+
uint64 entity_id = 1;
|
|
60
|
+
|
|
61
|
+
// Optional geohash-style location prefix. Matches the `location_prefix`
|
|
62
|
+
// filter on Search, and `location:<prefix>` as an attribute.
|
|
63
|
+
// Use 0 to omit location indexing.
|
|
64
|
+
uint64 location_prefix = 2;
|
|
65
|
+
|
|
66
|
+
// Numeric price (or similar scalar), filterable through RangePredicate.
|
|
67
|
+
uint32 price = 3;
|
|
68
|
+
|
|
69
|
+
// Attribute tokens already namespaced by the client, e.g.:
|
|
70
|
+
// "feature:pool", "furnishing:full", "amenity:parking"
|
|
71
|
+
// Tokens are matched exactly; they are never stored as readable text.
|
|
72
|
+
repeated string categories = 4;
|
|
73
|
+
|
|
74
|
+
// Tenant / namespace isolation key. Empty string → server uses "default".
|
|
75
|
+
// Two tenants may reuse the same entity_id without colliding.
|
|
76
|
+
string tenant_id = 5;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// IndexEntityResponse acknowledges a successful upsert.
|
|
80
|
+
message IndexEntityResponse {
|
|
81
|
+
// True when the entity was accepted into the index.
|
|
82
|
+
// Capacity violations return gRPC RESOURCE_EXHAUSTED instead.
|
|
83
|
+
bool success = 1;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// BatchIndexEntitiesRequest wraps multiple IndexEntityRequest messages.
|
|
87
|
+
message BatchIndexEntitiesRequest {
|
|
88
|
+
// Entities to index. Each entry may specify its own tenant_id.
|
|
89
|
+
repeated IndexEntityRequest entities = 1;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// BatchIndexEntitiesResponse reports how many entities were indexed.
|
|
93
|
+
message BatchIndexEntitiesResponse {
|
|
94
|
+
// Number of entities successfully indexed in this batch.
|
|
95
|
+
uint32 indexed_count = 1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Deletion
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
// DeleteEntityRequest soft-deletes one entity within a tenant.
|
|
103
|
+
message DeleteEntityRequest {
|
|
104
|
+
// Entity id to delete.
|
|
105
|
+
uint64 entity_id = 1;
|
|
106
|
+
|
|
107
|
+
// Tenant that owns the entity. Empty → "default".
|
|
108
|
+
string tenant_id = 2;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// DeleteEntityResponse reports whether a live entity was deleted.
|
|
112
|
+
message DeleteEntityResponse {
|
|
113
|
+
// True if the entity was present and marked deleted; false if unknown / already deleted.
|
|
114
|
+
bool success = 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// Search predicates
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
|
|
121
|
+
// FilterPredicate is a categorical / attribute filter.
|
|
122
|
+
message FilterPredicate {
|
|
123
|
+
// How this predicate combines with the matches accumulated so far.
|
|
124
|
+
enum Operation {
|
|
125
|
+
// Conjunction: narrows the current match set.
|
|
126
|
+
MUST = 0;
|
|
127
|
+
// Disjunction group: SHOULD predicates are OR'd, then narrow the match set.
|
|
128
|
+
SHOULD = 1;
|
|
129
|
+
// Exclusion: removes matches carrying this attribute.
|
|
130
|
+
MUST_NOT = 2;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// How this predicate combines with the current match set.
|
|
134
|
+
Operation op = 1;
|
|
135
|
+
|
|
136
|
+
// Attribute token identical to those used at index time, e.g. "feature:pool".
|
|
137
|
+
string attribute = 2;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// RangePredicate filters a continuous numeric field to an inclusive range.
|
|
141
|
+
message RangePredicate {
|
|
142
|
+
// Numeric field name. Currently supported: "price".
|
|
143
|
+
string field = 1;
|
|
144
|
+
|
|
145
|
+
// Inclusive lower bound of the requested range.
|
|
146
|
+
uint32 min_val = 2;
|
|
147
|
+
|
|
148
|
+
// Inclusive upper bound of the requested range.
|
|
149
|
+
uint32 max_val = 3;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Search
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
|
|
156
|
+
// SearchQueryRequest executes a filtered search inside one tenant.
|
|
157
|
+
message SearchQueryRequest {
|
|
158
|
+
// Optional location constraint (0 = no location filter).
|
|
159
|
+
// When non-zero, only entities indexed with that location_prefix match.
|
|
160
|
+
uint64 location_prefix = 1;
|
|
161
|
+
|
|
162
|
+
// Attribute predicates (MUST / SHOULD / MUST_NOT). Order does not affect the
|
|
163
|
+
// result.
|
|
164
|
+
repeated FilterPredicate filters = 2;
|
|
165
|
+
|
|
166
|
+
// Optional numeric range filters (e.g. price between min_val and max_val).
|
|
167
|
+
repeated RangePredicate ranges = 3;
|
|
168
|
+
|
|
169
|
+
// Maximum number of entity IDs to return.
|
|
170
|
+
// 0 means no limit, and makes `total_matches` exact.
|
|
171
|
+
uint32 limit = 4;
|
|
172
|
+
|
|
173
|
+
// Number of matches to skip before collecting results (pagination).
|
|
174
|
+
uint32 offset = 5;
|
|
175
|
+
|
|
176
|
+
// Tenant / namespace to search. Empty → "default".
|
|
177
|
+
string tenant_id = 6;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// SearchQueryResponse returns matched ids and timing metadata.
|
|
181
|
+
message SearchQueryResponse {
|
|
182
|
+
// Entity IDs that satisfied all predicates (after offset/limit).
|
|
183
|
+
// Caller hydrates full records from the primary data store.
|
|
184
|
+
repeated uint64 matched_entity_ids = 1;
|
|
185
|
+
|
|
186
|
+
// Number of matches. Exact when `limit` is 0; may be approximate otherwise.
|
|
187
|
+
uint32 total_matches = 2;
|
|
188
|
+
|
|
189
|
+
// Server-side execution time in microseconds (excludes network RTT).
|
|
190
|
+
uint64 execution_time_us = 3;
|
|
191
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// The standard gRPC health checking protocol, as served by the engine.
|
|
2
|
+
//
|
|
3
|
+
// This is a verbatim subset of grpc/health/v1/health.proto — only `Check` is
|
|
4
|
+
// used, so the streaming `Watch` RPC is omitted. It is vendored rather than
|
|
5
|
+
// pulled from a package because it is a frozen protocol: it has not changed
|
|
6
|
+
// since 2017, and a dependency for eleven lines is not worth the supply chain.
|
|
7
|
+
//
|
|
8
|
+
// It reports whether the service is ready to answer queries, and needs no
|
|
9
|
+
// particular scope on the API key.
|
|
10
|
+
|
|
11
|
+
syntax = "proto3";
|
|
12
|
+
|
|
13
|
+
package grpc.health.v1;
|
|
14
|
+
|
|
15
|
+
message HealthCheckRequest {
|
|
16
|
+
// Empty string means the health of the server as a whole.
|
|
17
|
+
string service = 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
message HealthCheckResponse {
|
|
21
|
+
enum ServingStatus {
|
|
22
|
+
UNKNOWN = 0;
|
|
23
|
+
SERVING = 1;
|
|
24
|
+
NOT_SERVING = 2;
|
|
25
|
+
SERVICE_UNKNOWN = 3;
|
|
26
|
+
}
|
|
27
|
+
ServingStatus status = 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
service Health {
|
|
31
|
+
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
|
|
32
|
+
}
|