graphile-search-plugin 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/esm/plugin.d.ts +4 -2
- package/esm/plugin.js +16 -21
- package/package.json +10 -12
- package/plugin.d.ts +4 -2
- package/plugin.js +16 -21
package/esm/plugin.d.ts
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates search condition fields for tsvector columns. When a search term
|
|
5
5
|
* is provided via the condition input, this plugin applies a
|
|
6
|
-
* `column @@ websearch_to_tsquery('english', $value)` WHERE clause
|
|
7
|
-
*
|
|
6
|
+
* `column @@ websearch_to_tsquery('english', $value)` WHERE clause.
|
|
7
|
+
* Results are ordered by `ts_rank` only when explicitly requested via
|
|
8
|
+
* the `FULL_TEXT_RANK_ASC/DESC` orderBy enum values (not automatically),
|
|
9
|
+
* ensuring cursor pagination digests remain stable across pages.
|
|
8
10
|
*
|
|
9
11
|
* Additionally provides:
|
|
10
12
|
* - `matches` filter operator for postgraphile-plugin-connection-filter
|
package/esm/plugin.js
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates search condition fields for tsvector columns. When a search term
|
|
5
5
|
* is provided via the condition input, this plugin applies a
|
|
6
|
-
* `column @@ websearch_to_tsquery('english', $value)` WHERE clause
|
|
7
|
-
*
|
|
6
|
+
* `column @@ websearch_to_tsquery('english', $value)` WHERE clause.
|
|
7
|
+
* Results are ordered by `ts_rank` only when explicitly requested via
|
|
8
|
+
* the `FULL_TEXT_RANK_ASC/DESC` orderBy enum values (not automatically),
|
|
9
|
+
* ensuring cursor pagination digests remain stable across pages.
|
|
8
10
|
*
|
|
9
11
|
* Additionally provides:
|
|
10
12
|
* - `matches` filter operator for postgraphile-plugin-connection-filter
|
|
@@ -32,14 +34,6 @@ import 'graphile-build';
|
|
|
32
34
|
import 'graphile-build-pg';
|
|
33
35
|
import { TYPES } from '@dataplan/pg';
|
|
34
36
|
const ftsRankSlots = new WeakMap();
|
|
35
|
-
/**
|
|
36
|
-
* FinalizationRegistry for defensive cleanup of ftsRankSlots entries.
|
|
37
|
-
* WeakMap entries are already eligible for GC when keys are unreachable,
|
|
38
|
-
* but this provides explicit cleanup and a hook for debugging leaks.
|
|
39
|
-
*/
|
|
40
|
-
const ftsRankCleanup = new FinalizationRegistry((heldValue) => {
|
|
41
|
-
ftsRankSlots.delete(heldValue);
|
|
42
|
-
});
|
|
43
37
|
function isTsvectorCodec(codec) {
|
|
44
38
|
return (codec?.extensions?.pg?.schemaName === 'pg_catalog' &&
|
|
45
39
|
codec?.extensions?.pg?.name === 'tsvector');
|
|
@@ -119,7 +113,6 @@ export function createPgSearchPlugin(options = {}) {
|
|
|
119
113
|
ftsRankSlots.set(alias, {
|
|
120
114
|
indices: Object.create(null),
|
|
121
115
|
});
|
|
122
|
-
ftsRankCleanup.register($select, alias);
|
|
123
116
|
}
|
|
124
117
|
// Return a lambda that reads the rank value from the result
|
|
125
118
|
// row at a dynamically-determined index. The index is set
|
|
@@ -231,20 +224,22 @@ export function createPgSearchPlugin(options = {}) {
|
|
|
231
224
|
slot.indices[baseFieldName] = rankIndex;
|
|
232
225
|
}
|
|
233
226
|
}
|
|
234
|
-
// ORDER BY ts_rank:
|
|
235
|
-
//
|
|
236
|
-
//
|
|
237
|
-
//
|
|
227
|
+
// ORDER BY ts_rank: only add when the user explicitly
|
|
228
|
+
// requested rank ordering via the FULL_TEXT_RANK_ASC/DESC
|
|
229
|
+
// enum values. The enum's apply stores direction in meta
|
|
230
|
+
// during planning; if no meta is set, skip the orderBy
|
|
231
|
+
// entirely so cursors remain stable across pages.
|
|
238
232
|
const metaKey = `fts_order_${baseFieldName}`;
|
|
239
233
|
const explicitDir = typeof $parent.getMetaRaw === 'function'
|
|
240
234
|
? $parent.getMetaRaw(metaKey)
|
|
241
235
|
: undefined;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
236
|
+
if (explicitDir) {
|
|
237
|
+
$parent.orderBy({
|
|
238
|
+
fragment: sql `ts_rank(${columnExpr}, ${tsquery})`,
|
|
239
|
+
codec: TYPES.float4,
|
|
240
|
+
direction: explicitDir,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
248
243
|
},
|
|
249
244
|
}),
|
|
250
245
|
}, `PgSearchPlugin adding condition field '${fieldName}' for tsvector column '${attributeName}' on '${pgCodec.name}'`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphile-search-plugin",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Generate search conditions for your tsvector columns (PostGraphile v5)",
|
|
5
5
|
"author": "Constructive <developers@constructive.io>",
|
|
6
6
|
"homepage": "https://github.com/constructive-io/constructive",
|
|
@@ -42,21 +42,19 @@
|
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/node": "^22.19.1",
|
|
45
|
-
"graphile-test": "^4.
|
|
45
|
+
"graphile-test": "^4.2.0",
|
|
46
46
|
"makage": "^0.1.10",
|
|
47
|
-
"pgsql-test": "^4.
|
|
47
|
+
"pgsql-test": "^4.2.0",
|
|
48
48
|
"postgraphile-plugin-connection-filter": "^3.0.0-rc.1"
|
|
49
49
|
},
|
|
50
|
-
"dependencies": {
|
|
51
|
-
"@dataplan/pg": "1.0.0-rc.3",
|
|
52
|
-
"graphile-build": "^5.0.0-rc.3",
|
|
53
|
-
"graphile-build-pg": "^5.0.0-rc.3",
|
|
54
|
-
"graphile-config": "1.0.0-rc.3",
|
|
55
|
-
"pg-sql2": "^5.0.0-rc.3"
|
|
56
|
-
},
|
|
57
50
|
"peerDependencies": {
|
|
51
|
+
"@dataplan/pg": "^1.0.0-rc.5",
|
|
52
|
+
"graphile-build": "^5.0.0-rc.4",
|
|
53
|
+
"graphile-build-pg": "^5.0.0-rc.5",
|
|
54
|
+
"graphile-config": "^1.0.0-rc.5",
|
|
58
55
|
"graphql": "^16.9.0",
|
|
59
|
-
"
|
|
56
|
+
"pg-sql2": "^5.0.0-rc.4",
|
|
57
|
+
"postgraphile": "^5.0.0-rc.7",
|
|
60
58
|
"postgraphile-plugin-connection-filter": "^3.0.0-rc.1"
|
|
61
59
|
},
|
|
62
60
|
"peerDependenciesMeta": {
|
|
@@ -64,5 +62,5 @@
|
|
|
64
62
|
"optional": true
|
|
65
63
|
}
|
|
66
64
|
},
|
|
67
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "b758178b808ce0bf451e86c0bd7e92079155db7c"
|
|
68
66
|
}
|
package/plugin.d.ts
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates search condition fields for tsvector columns. When a search term
|
|
5
5
|
* is provided via the condition input, this plugin applies a
|
|
6
|
-
* `column @@ websearch_to_tsquery('english', $value)` WHERE clause
|
|
7
|
-
*
|
|
6
|
+
* `column @@ websearch_to_tsquery('english', $value)` WHERE clause.
|
|
7
|
+
* Results are ordered by `ts_rank` only when explicitly requested via
|
|
8
|
+
* the `FULL_TEXT_RANK_ASC/DESC` orderBy enum values (not automatically),
|
|
9
|
+
* ensuring cursor pagination digests remain stable across pages.
|
|
8
10
|
*
|
|
9
11
|
* Additionally provides:
|
|
10
12
|
* - `matches` filter operator for postgraphile-plugin-connection-filter
|
package/plugin.js
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Generates search condition fields for tsvector columns. When a search term
|
|
6
6
|
* is provided via the condition input, this plugin applies a
|
|
7
|
-
* `column @@ websearch_to_tsquery('english', $value)` WHERE clause
|
|
8
|
-
*
|
|
7
|
+
* `column @@ websearch_to_tsquery('english', $value)` WHERE clause.
|
|
8
|
+
* Results are ordered by `ts_rank` only when explicitly requested via
|
|
9
|
+
* the `FULL_TEXT_RANK_ASC/DESC` orderBy enum values (not automatically),
|
|
10
|
+
* ensuring cursor pagination digests remain stable across pages.
|
|
9
11
|
*
|
|
10
12
|
* Additionally provides:
|
|
11
13
|
* - `matches` filter operator for postgraphile-plugin-connection-filter
|
|
@@ -36,14 +38,6 @@ require("graphile-build");
|
|
|
36
38
|
require("graphile-build-pg");
|
|
37
39
|
const pg_1 = require("@dataplan/pg");
|
|
38
40
|
const ftsRankSlots = new WeakMap();
|
|
39
|
-
/**
|
|
40
|
-
* FinalizationRegistry for defensive cleanup of ftsRankSlots entries.
|
|
41
|
-
* WeakMap entries are already eligible for GC when keys are unreachable,
|
|
42
|
-
* but this provides explicit cleanup and a hook for debugging leaks.
|
|
43
|
-
*/
|
|
44
|
-
const ftsRankCleanup = new FinalizationRegistry((heldValue) => {
|
|
45
|
-
ftsRankSlots.delete(heldValue);
|
|
46
|
-
});
|
|
47
41
|
function isTsvectorCodec(codec) {
|
|
48
42
|
return (codec?.extensions?.pg?.schemaName === 'pg_catalog' &&
|
|
49
43
|
codec?.extensions?.pg?.name === 'tsvector');
|
|
@@ -123,7 +117,6 @@ function createPgSearchPlugin(options = {}) {
|
|
|
123
117
|
ftsRankSlots.set(alias, {
|
|
124
118
|
indices: Object.create(null),
|
|
125
119
|
});
|
|
126
|
-
ftsRankCleanup.register($select, alias);
|
|
127
120
|
}
|
|
128
121
|
// Return a lambda that reads the rank value from the result
|
|
129
122
|
// row at a dynamically-determined index. The index is set
|
|
@@ -235,20 +228,22 @@ function createPgSearchPlugin(options = {}) {
|
|
|
235
228
|
slot.indices[baseFieldName] = rankIndex;
|
|
236
229
|
}
|
|
237
230
|
}
|
|
238
|
-
// ORDER BY ts_rank:
|
|
239
|
-
//
|
|
240
|
-
//
|
|
241
|
-
//
|
|
231
|
+
// ORDER BY ts_rank: only add when the user explicitly
|
|
232
|
+
// requested rank ordering via the FULL_TEXT_RANK_ASC/DESC
|
|
233
|
+
// enum values. The enum's apply stores direction in meta
|
|
234
|
+
// during planning; if no meta is set, skip the orderBy
|
|
235
|
+
// entirely so cursors remain stable across pages.
|
|
242
236
|
const metaKey = `fts_order_${baseFieldName}`;
|
|
243
237
|
const explicitDir = typeof $parent.getMetaRaw === 'function'
|
|
244
238
|
? $parent.getMetaRaw(metaKey)
|
|
245
239
|
: undefined;
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
240
|
+
if (explicitDir) {
|
|
241
|
+
$parent.orderBy({
|
|
242
|
+
fragment: sql `ts_rank(${columnExpr}, ${tsquery})`,
|
|
243
|
+
codec: pg_1.TYPES.float4,
|
|
244
|
+
direction: explicitDir,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
252
247
|
},
|
|
253
248
|
}),
|
|
254
249
|
}, `PgSearchPlugin adding condition field '${fieldName}' for tsvector column '${attributeName}' on '${pgCodec.name}'`);
|