@neutron-build/nucleus 0.1.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/LICENSE +21 -0
- package/README.md +27 -0
- package/dist/blob/index.d.ts +42 -0
- package/dist/blob/index.d.ts.map +1 -0
- package/dist/blob/index.js +121 -0
- package/dist/blob/index.js.map +1 -0
- package/dist/cdc/index.d.ts +14 -0
- package/dist/cdc/index.d.ts.map +1 -0
- package/dist/cdc/index.js +41 -0
- package/dist/cdc/index.js.map +1 -0
- package/dist/client.d.ts +59 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +68 -0
- package/dist/client.js.map +1 -0
- package/dist/columnar/index.d.ts +20 -0
- package/dist/columnar/index.d.ts.map +1 -0
- package/dist/columnar/index.js +60 -0
- package/dist/columnar/index.js.map +1 -0
- package/dist/datalog/index.d.ts +20 -0
- package/dist/datalog/index.d.ts.map +1 -0
- package/dist/datalog/index.js +53 -0
- package/dist/datalog/index.js.map +1 -0
- package/dist/document/index.d.ts +42 -0
- package/dist/document/index.d.ts.map +1 -0
- package/dist/document/index.js +154 -0
- package/dist/document/index.js.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +64 -0
- package/dist/errors.js.map +1 -0
- package/dist/features.d.ts +14 -0
- package/dist/features.d.ts.map +1 -0
- package/dist/features.js +85 -0
- package/dist/features.js.map +1 -0
- package/dist/fts/index.d.ts +35 -0
- package/dist/fts/index.d.ts.map +1 -0
- package/dist/fts/index.js +76 -0
- package/dist/fts/index.js.map +1 -0
- package/dist/geo/index.d.ts +34 -0
- package/dist/geo/index.d.ts.map +1 -0
- package/dist/geo/index.js +121 -0
- package/dist/geo/index.js.map +1 -0
- package/dist/graph/index.d.ts +43 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +109 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/helpers.d.ts +11 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +47 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/kv/index.d.ts +93 -0
- package/dist/kv/index.d.ts.map +1 -0
- package/dist/kv/index.js +223 -0
- package/dist/kv/index.js.map +1 -0
- package/dist/migrate.d.ts +37 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +95 -0
- package/dist/migrate.js.map +1 -0
- package/dist/pubsub/index.d.ts +14 -0
- package/dist/pubsub/index.d.ts.map +1 -0
- package/dist/pubsub/index.js +44 -0
- package/dist/pubsub/index.js.map +1 -0
- package/dist/sql/index.d.ts +31 -0
- package/dist/sql/index.d.ts.map +1 -0
- package/dist/sql/index.js +65 -0
- package/dist/sql/index.js.map +1 -0
- package/dist/streams/index.d.ts +26 -0
- package/dist/streams/index.d.ts.map +1 -0
- package/dist/streams/index.js +83 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/timeseries/index.d.ts +46 -0
- package/dist/timeseries/index.d.ts.map +1 -0
- package/dist/timeseries/index.js +122 -0
- package/dist/timeseries/index.js.map +1 -0
- package/dist/transport.d.ts +97 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +477 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/vector/index.d.ts +34 -0
- package/dist/vector/index.d.ts.map +1 -0
- package/dist/vector/index.js +104 -0
- package/dist/vector/index.js.map +1 -0
- package/package.json +110 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { NucleusPlugin } from '../types.js';
|
|
2
|
+
export interface DocFindOptions {
|
|
3
|
+
/** Sort by this field. */
|
|
4
|
+
sortField?: string;
|
|
5
|
+
/** Sort ascending (`true`) or descending (`false`). */
|
|
6
|
+
sortAsc?: boolean;
|
|
7
|
+
/** Skip the first `n` results. */
|
|
8
|
+
skip?: number;
|
|
9
|
+
/** Maximum number of results. */
|
|
10
|
+
limit?: number;
|
|
11
|
+
/** Only return these fields from each document. */
|
|
12
|
+
fields?: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface DocumentModel {
|
|
15
|
+
/** Insert a document. Returns the generated document ID. */
|
|
16
|
+
insert(collection: string, doc: Record<string, unknown>): Promise<number>;
|
|
17
|
+
/** Get a document by ID. Returns `null` if not found. */
|
|
18
|
+
get(id: number): Promise<Record<string, unknown> | null>;
|
|
19
|
+
/** Get a document and cast it to `T`. Returns `null` if not found. */
|
|
20
|
+
getTyped<T>(id: number): Promise<T | null>;
|
|
21
|
+
/** Query documents matching a JSON filter. Returns matching IDs. */
|
|
22
|
+
queryDocs(filter: Record<string, unknown>): Promise<number[]>;
|
|
23
|
+
/** Extract a nested value from a document by key path. */
|
|
24
|
+
path(id: number, ...keys: string[]): Promise<string | null>;
|
|
25
|
+
/** Return the total number of documents. */
|
|
26
|
+
count(): Promise<number>;
|
|
27
|
+
/** Find full documents matching a filter. */
|
|
28
|
+
find(collection: string, filter: Record<string, unknown>, opts?: DocFindOptions): Promise<Record<string, unknown>[]>;
|
|
29
|
+
/** Find and return typed results. */
|
|
30
|
+
findTyped<T>(collection: string, filter: Record<string, unknown>, opts?: DocFindOptions): Promise<T[]>;
|
|
31
|
+
/** Find the first document matching a filter. */
|
|
32
|
+
findOne(collection: string, filter: Record<string, unknown>): Promise<Record<string, unknown> | null>;
|
|
33
|
+
/** Update documents matching a filter with the given partial. Returns count of updated docs. */
|
|
34
|
+
update(collection: string, filter: Record<string, unknown>, update: Record<string, unknown>): Promise<number>;
|
|
35
|
+
/** Delete documents matching a filter. Returns count of deleted docs. */
|
|
36
|
+
delete(collection: string, filter: Record<string, unknown>): Promise<number>;
|
|
37
|
+
}
|
|
38
|
+
/** Plugin: adds `.document` to the client. */
|
|
39
|
+
export declare const withDocument: NucleusPlugin<{
|
|
40
|
+
document: DocumentModel;
|
|
41
|
+
}>;
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/document/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAa,aAAa,EAAmB,MAAM,aAAa,CAAC;AAO7E,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAMD,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1E,yDAAyD;IACzD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAEzD,sEAAsE;IACtE,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAE3C,oEAAoE;IACpE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE9D,0DAA0D;IAC1D,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE5D,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzB,6CAA6C;IAC7C,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAErH,qCAAqC;IACrC,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAEvG,iDAAiD;IACjD,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAEtG,gGAAgG;IAChG,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE9G,yEAAyE;IACzE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9E;AAgLD,8CAA8C;AAC9C,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,CAKnE,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @neutron/nucleus/document — Document / JSON model plugin
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { requireNucleus } from '../helpers.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Implementation
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
class DocumentModelImpl {
|
|
9
|
+
transport;
|
|
10
|
+
features;
|
|
11
|
+
constructor(transport, features) {
|
|
12
|
+
this.transport = transport;
|
|
13
|
+
this.features = features;
|
|
14
|
+
}
|
|
15
|
+
require() {
|
|
16
|
+
requireNucleus(this.features, 'Document');
|
|
17
|
+
}
|
|
18
|
+
async insert(_collection, doc) {
|
|
19
|
+
this.require();
|
|
20
|
+
const data = JSON.stringify(doc);
|
|
21
|
+
return (await this.transport.fetchval('SELECT DOC_INSERT($1)', [data])) ?? 0;
|
|
22
|
+
}
|
|
23
|
+
async get(id) {
|
|
24
|
+
this.require();
|
|
25
|
+
const raw = await this.transport.fetchval('SELECT DOC_GET($1)', [id]);
|
|
26
|
+
if (raw === null)
|
|
27
|
+
return null;
|
|
28
|
+
return JSON.parse(raw);
|
|
29
|
+
}
|
|
30
|
+
async getTyped(id) {
|
|
31
|
+
this.require();
|
|
32
|
+
const raw = await this.transport.fetchval('SELECT DOC_GET($1)', [id]);
|
|
33
|
+
if (raw === null)
|
|
34
|
+
return null;
|
|
35
|
+
return JSON.parse(raw);
|
|
36
|
+
}
|
|
37
|
+
async queryDocs(filter) {
|
|
38
|
+
this.require();
|
|
39
|
+
const q = JSON.stringify(filter);
|
|
40
|
+
const raw = await this.transport.fetchval('SELECT DOC_QUERY($1)', [q]);
|
|
41
|
+
if (!raw)
|
|
42
|
+
return [];
|
|
43
|
+
return raw
|
|
44
|
+
.split(',')
|
|
45
|
+
.map((s) => s.trim())
|
|
46
|
+
.filter(Boolean)
|
|
47
|
+
.map(Number)
|
|
48
|
+
.filter((n) => !Number.isNaN(n));
|
|
49
|
+
}
|
|
50
|
+
async path(id, ...keys) {
|
|
51
|
+
this.require();
|
|
52
|
+
const placeholders = keys.map((_, i) => `$${i + 2}`).join(', ');
|
|
53
|
+
const sql = `SELECT DOC_PATH($1, ${placeholders})`;
|
|
54
|
+
return this.transport.fetchval(sql, [id, ...keys]);
|
|
55
|
+
}
|
|
56
|
+
async count() {
|
|
57
|
+
this.require();
|
|
58
|
+
return (await this.transport.fetchval('SELECT DOC_COUNT()')) ?? 0;
|
|
59
|
+
}
|
|
60
|
+
async find(collection, filter, opts = {}) {
|
|
61
|
+
const ids = await this.queryDocs(filter);
|
|
62
|
+
let results = [];
|
|
63
|
+
for (const id of ids) {
|
|
64
|
+
const doc = await this.get(id);
|
|
65
|
+
if (doc)
|
|
66
|
+
results.push(doc);
|
|
67
|
+
}
|
|
68
|
+
// Sort
|
|
69
|
+
if (opts.sortField) {
|
|
70
|
+
const field = opts.sortField;
|
|
71
|
+
const asc = opts.sortAsc ?? true;
|
|
72
|
+
results.sort((a, b) => {
|
|
73
|
+
const va = String(a[field] ?? '');
|
|
74
|
+
const vb = String(b[field] ?? '');
|
|
75
|
+
return asc ? va.localeCompare(vb) : vb.localeCompare(va);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// Skip
|
|
79
|
+
if (opts.skip && opts.skip > 0) {
|
|
80
|
+
results = results.slice(opts.skip);
|
|
81
|
+
}
|
|
82
|
+
// Limit
|
|
83
|
+
if (opts.limit && opts.limit > 0) {
|
|
84
|
+
results = results.slice(0, opts.limit);
|
|
85
|
+
}
|
|
86
|
+
// Projection
|
|
87
|
+
if (opts.fields && opts.fields.length > 0) {
|
|
88
|
+
const keep = new Set(opts.fields);
|
|
89
|
+
results = results.map((doc) => {
|
|
90
|
+
const projected = {};
|
|
91
|
+
for (const f of keep) {
|
|
92
|
+
if (f in doc)
|
|
93
|
+
projected[f] = doc[f];
|
|
94
|
+
}
|
|
95
|
+
return projected;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return results;
|
|
99
|
+
}
|
|
100
|
+
async findTyped(collection, filter, opts = {}) {
|
|
101
|
+
const ids = await this.queryDocs(filter);
|
|
102
|
+
let results = [];
|
|
103
|
+
for (const id of ids) {
|
|
104
|
+
const item = await this.getTyped(id);
|
|
105
|
+
if (item !== null)
|
|
106
|
+
results.push(item);
|
|
107
|
+
}
|
|
108
|
+
if (opts.skip && opts.skip > 0)
|
|
109
|
+
results = results.slice(opts.skip);
|
|
110
|
+
if (opts.limit && opts.limit > 0)
|
|
111
|
+
results = results.slice(0, opts.limit);
|
|
112
|
+
return results;
|
|
113
|
+
}
|
|
114
|
+
async findOne(collection, filter) {
|
|
115
|
+
const docs = await this.find(collection, filter, { limit: 1 });
|
|
116
|
+
return docs.length > 0 ? docs[0] : null;
|
|
117
|
+
}
|
|
118
|
+
async update(collection, filter, update) {
|
|
119
|
+
this.require();
|
|
120
|
+
const ids = await this.queryDocs(filter);
|
|
121
|
+
let count = 0;
|
|
122
|
+
for (const id of ids) {
|
|
123
|
+
const doc = await this.get(id);
|
|
124
|
+
if (!doc)
|
|
125
|
+
continue;
|
|
126
|
+
Object.assign(doc, update);
|
|
127
|
+
const data = JSON.stringify(doc);
|
|
128
|
+
await this.transport.execute('UPDATE documents SET data = $1::jsonb WHERE id = $2', [data, id]);
|
|
129
|
+
count++;
|
|
130
|
+
}
|
|
131
|
+
return count;
|
|
132
|
+
}
|
|
133
|
+
async delete(collection, filter) {
|
|
134
|
+
this.require();
|
|
135
|
+
const ids = await this.queryDocs(filter);
|
|
136
|
+
let count = 0;
|
|
137
|
+
for (const id of ids) {
|
|
138
|
+
await this.transport.execute('DELETE FROM documents WHERE id = $1', [id]);
|
|
139
|
+
count++;
|
|
140
|
+
}
|
|
141
|
+
return count;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
// Plugin
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
/** Plugin: adds `.document` to the client. */
|
|
148
|
+
export const withDocument = {
|
|
149
|
+
name: 'document',
|
|
150
|
+
init(transport, features) {
|
|
151
|
+
return { document: new DocumentModelImpl(transport, features) };
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/document/index.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface NucleusErrorOptions {
|
|
2
|
+
cause?: Error;
|
|
3
|
+
meta?: Record<string, unknown>;
|
|
4
|
+
}
|
|
5
|
+
/** Base error for all Nucleus operations. */
|
|
6
|
+
export declare class NucleusError extends Error {
|
|
7
|
+
readonly code: string;
|
|
8
|
+
readonly meta?: Record<string, unknown>;
|
|
9
|
+
constructor(code: string, message: string, options?: NucleusErrorOptions);
|
|
10
|
+
}
|
|
11
|
+
/** Thrown when a connection cannot be established or is lost. */
|
|
12
|
+
export declare class NucleusConnectionError extends NucleusError {
|
|
13
|
+
constructor(message: string, options?: NucleusErrorOptions);
|
|
14
|
+
}
|
|
15
|
+
/** Thrown when a SQL query or command fails on the server. */
|
|
16
|
+
export declare class NucleusQueryError extends NucleusError {
|
|
17
|
+
constructor(message: string, options?: NucleusErrorOptions);
|
|
18
|
+
}
|
|
19
|
+
/** Thrown when an expected row or resource is not found. */
|
|
20
|
+
export declare class NucleusNotFoundError extends NucleusError {
|
|
21
|
+
constructor(message: string, options?: NucleusErrorOptions);
|
|
22
|
+
}
|
|
23
|
+
/** Thrown on unique-constraint violations or optimistic-lock conflicts. */
|
|
24
|
+
export declare class NucleusConflictError extends NucleusError {
|
|
25
|
+
constructor(message: string, options?: NucleusErrorOptions);
|
|
26
|
+
}
|
|
27
|
+
/** Thrown when a transaction fails to commit or is aborted. */
|
|
28
|
+
export declare class NucleusTransactionError extends NucleusError {
|
|
29
|
+
constructor(message: string, options?: NucleusErrorOptions);
|
|
30
|
+
}
|
|
31
|
+
/** Thrown when a Nucleus-only feature is used against plain PostgreSQL. */
|
|
32
|
+
export declare class NucleusFeatureError extends NucleusError {
|
|
33
|
+
constructor(feature: string, options?: NucleusErrorOptions);
|
|
34
|
+
}
|
|
35
|
+
/** Thrown when the server rejects the request for authentication reasons. */
|
|
36
|
+
export declare class NucleusAuthError extends NucleusError {
|
|
37
|
+
constructor(message: string, options?: NucleusErrorOptions);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,6CAA6C;AAC7C,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE5B,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAMzE;AAED,iEAAiE;AACjE,qBAAa,sBAAuB,SAAQ,YAAY;gBAC1C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAI3D;AAED,8DAA8D;AAC9D,qBAAa,iBAAkB,SAAQ,YAAY;gBACrC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAI3D;AAED,4DAA4D;AAC5D,qBAAa,oBAAqB,SAAQ,YAAY;gBACxC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAI3D;AAED,2EAA2E;AAC3E,qBAAa,oBAAqB,SAAQ,YAAY;gBACxC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAI3D;AAED,+DAA+D;AAC/D,qBAAa,uBAAwB,SAAQ,YAAY;gBAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAI3D;AAED,2EAA2E;AAC3E,qBAAa,mBAAoB,SAAQ,YAAY;gBACvC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAQ3D;AAED,6EAA6E;AAC7E,qBAAa,gBAAiB,SAAQ,YAAY;gBACpC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB;CAI3D"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Nucleus client — error hierarchy
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/** Base error for all Nucleus operations. */
|
|
5
|
+
export class NucleusError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
meta;
|
|
8
|
+
constructor(code, message, options) {
|
|
9
|
+
super(message, { cause: options?.cause });
|
|
10
|
+
this.name = 'NucleusError';
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.meta = options?.meta;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** Thrown when a connection cannot be established or is lost. */
|
|
16
|
+
export class NucleusConnectionError extends NucleusError {
|
|
17
|
+
constructor(message, options) {
|
|
18
|
+
super('CONNECTION_ERROR', message, options);
|
|
19
|
+
this.name = 'NucleusConnectionError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Thrown when a SQL query or command fails on the server. */
|
|
23
|
+
export class NucleusQueryError extends NucleusError {
|
|
24
|
+
constructor(message, options) {
|
|
25
|
+
super('QUERY_ERROR', message, options);
|
|
26
|
+
this.name = 'NucleusQueryError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Thrown when an expected row or resource is not found. */
|
|
30
|
+
export class NucleusNotFoundError extends NucleusError {
|
|
31
|
+
constructor(message, options) {
|
|
32
|
+
super('NOT_FOUND', message, options);
|
|
33
|
+
this.name = 'NucleusNotFoundError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Thrown on unique-constraint violations or optimistic-lock conflicts. */
|
|
37
|
+
export class NucleusConflictError extends NucleusError {
|
|
38
|
+
constructor(message, options) {
|
|
39
|
+
super('CONFLICT', message, options);
|
|
40
|
+
this.name = 'NucleusConflictError';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Thrown when a transaction fails to commit or is aborted. */
|
|
44
|
+
export class NucleusTransactionError extends NucleusError {
|
|
45
|
+
constructor(message, options) {
|
|
46
|
+
super('TRANSACTION_ERROR', message, options);
|
|
47
|
+
this.name = 'NucleusTransactionError';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Thrown when a Nucleus-only feature is used against plain PostgreSQL. */
|
|
51
|
+
export class NucleusFeatureError extends NucleusError {
|
|
52
|
+
constructor(feature, options) {
|
|
53
|
+
super('FEATURE_UNAVAILABLE', `${feature} requires Nucleus database, but connected to plain PostgreSQL`, options);
|
|
54
|
+
this.name = 'NucleusFeatureError';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Thrown when the server rejects the request for authentication reasons. */
|
|
58
|
+
export class NucleusAuthError extends NucleusError {
|
|
59
|
+
constructor(message, options) {
|
|
60
|
+
super('AUTH_ERROR', message, options);
|
|
61
|
+
this.name = 'NucleusAuthError';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mCAAmC;AACnC,8EAA8E;AAO9E,6CAA6C;AAC7C,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAS;IACb,IAAI,CAA2B;IAExC,YAAY,IAAY,EAAE,OAAe,EAAE,OAA6B;QACtE,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;IAC5B,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,OAAO,sBAAuB,SAAQ,YAAY;IACtD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,kBAAkB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,8DAA8D;AAC9D,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IACjD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,aAAa,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED,4DAA4D;AAC5D,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IACpD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,2EAA2E;AAC3E,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IACpD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,+DAA+D;AAC/D,MAAM,OAAO,uBAAwB,SAAQ,YAAY;IACvD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,mBAAmB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,2EAA2E;AAC3E,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IACnD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CACH,qBAAqB,EACrB,GAAG,OAAO,+DAA+D,EACzE,OAAO,CACR,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IAChD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Transport, NucleusFeatures } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Detect capabilities of the connected database.
|
|
4
|
+
*
|
|
5
|
+
* Detection strategy:
|
|
6
|
+
* 1. `SELECT VERSION()` — if it contains "Nucleus", we know this is Nucleus.
|
|
7
|
+
* 2. If Nucleus is detected, query `nucleus_features()` for granular per-model
|
|
8
|
+
* availability. This allows partial installations where some engines are
|
|
9
|
+
* disabled or not yet loaded.
|
|
10
|
+
* 3. On plain PostgreSQL the result is a standard PG version string and only
|
|
11
|
+
* SQL features are enabled.
|
|
12
|
+
*/
|
|
13
|
+
export declare function detectFeatures(transport: Transport): Promise<NucleusFeatures>;
|
|
14
|
+
//# sourceMappingURL=features.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7D;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC,CAwEnF"}
|
package/dist/features.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Nucleus client — feature detection
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/**
|
|
5
|
+
* Detect capabilities of the connected database.
|
|
6
|
+
*
|
|
7
|
+
* Detection strategy:
|
|
8
|
+
* 1. `SELECT VERSION()` — if it contains "Nucleus", we know this is Nucleus.
|
|
9
|
+
* 2. If Nucleus is detected, query `nucleus_features()` for granular per-model
|
|
10
|
+
* availability. This allows partial installations where some engines are
|
|
11
|
+
* disabled or not yet loaded.
|
|
12
|
+
* 3. On plain PostgreSQL the result is a standard PG version string and only
|
|
13
|
+
* SQL features are enabled.
|
|
14
|
+
*/
|
|
15
|
+
export async function detectFeatures(transport) {
|
|
16
|
+
const version = await transport.fetchval('SELECT VERSION()');
|
|
17
|
+
const ver = version ?? '';
|
|
18
|
+
const isNucleus = ver.includes('Nucleus');
|
|
19
|
+
if (!isNucleus) {
|
|
20
|
+
return {
|
|
21
|
+
isNucleus: false,
|
|
22
|
+
hasKV: false,
|
|
23
|
+
hasVector: false,
|
|
24
|
+
hasTimeSeries: false,
|
|
25
|
+
hasDocument: false,
|
|
26
|
+
hasGraph: false,
|
|
27
|
+
hasFTS: false,
|
|
28
|
+
hasGeo: false,
|
|
29
|
+
hasBlob: false,
|
|
30
|
+
hasStreams: false,
|
|
31
|
+
hasColumnar: false,
|
|
32
|
+
hasDatalog: false,
|
|
33
|
+
hasCDC: false,
|
|
34
|
+
hasPubSub: false,
|
|
35
|
+
version: ver,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// Attempt granular feature detection via nucleus_features() function.
|
|
39
|
+
// If the function does not exist (older Nucleus builds), fall back to all=true.
|
|
40
|
+
try {
|
|
41
|
+
const raw = await transport.fetchval('SELECT NUCLEUS_FEATURES()');
|
|
42
|
+
if (raw) {
|
|
43
|
+
const features = JSON.parse(raw);
|
|
44
|
+
return {
|
|
45
|
+
isNucleus: true,
|
|
46
|
+
hasKV: features.kv !== false,
|
|
47
|
+
hasVector: features.vector !== false,
|
|
48
|
+
hasTimeSeries: features.timeseries !== false,
|
|
49
|
+
hasDocument: features.document !== false,
|
|
50
|
+
hasGraph: features.graph !== false,
|
|
51
|
+
hasFTS: features.fts !== false,
|
|
52
|
+
hasGeo: features.geo !== false,
|
|
53
|
+
hasBlob: features.blob !== false,
|
|
54
|
+
hasStreams: features.streams !== false,
|
|
55
|
+
hasColumnar: features.columnar !== false,
|
|
56
|
+
hasDatalog: features.datalog !== false,
|
|
57
|
+
hasCDC: features.cdc !== false,
|
|
58
|
+
hasPubSub: features.pubsub !== false,
|
|
59
|
+
version: ver,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// NUCLEUS_FEATURES() not available — fall through to all-enabled default.
|
|
65
|
+
}
|
|
66
|
+
// All models enabled by default on Nucleus.
|
|
67
|
+
return {
|
|
68
|
+
isNucleus: true,
|
|
69
|
+
hasKV: true,
|
|
70
|
+
hasVector: true,
|
|
71
|
+
hasTimeSeries: true,
|
|
72
|
+
hasDocument: true,
|
|
73
|
+
hasGraph: true,
|
|
74
|
+
hasFTS: true,
|
|
75
|
+
hasGeo: true,
|
|
76
|
+
hasBlob: true,
|
|
77
|
+
hasStreams: true,
|
|
78
|
+
hasColumnar: true,
|
|
79
|
+
hasDatalog: true,
|
|
80
|
+
hasCDC: true,
|
|
81
|
+
hasPubSub: true,
|
|
82
|
+
version: ver,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features.js","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,qCAAqC;AACrC,8EAA8E;AAI9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAoB;IACvD,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAS,kBAAkB,CAAC,CAAC;IACrE,MAAM,GAAG,GAAG,OAAO,IAAI,EAAE,CAAC;IAE1B,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE1C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,KAAK,EAAE,KAAK;YACZ,SAAS,EAAE,KAAK;YAChB,aAAa,EAAE,KAAK;YACpB,WAAW,EAAE,KAAK;YAClB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,KAAK;YACjB,WAAW,EAAE,KAAK;YAClB,UAAU,EAAE,KAAK;YACjB,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,GAAG;SACb,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,gFAAgF;IAChF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAS,2BAA2B,CAAC,CAAC;QAC1E,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;YAC5D,OAAO;gBACL,SAAS,EAAE,IAAI;gBACf,KAAK,EAAE,QAAQ,CAAC,EAAE,KAAK,KAAK;gBAC5B,SAAS,EAAE,QAAQ,CAAC,MAAM,KAAK,KAAK;gBACpC,aAAa,EAAE,QAAQ,CAAC,UAAU,KAAK,KAAK;gBAC5C,WAAW,EAAE,QAAQ,CAAC,QAAQ,KAAK,KAAK;gBACxC,QAAQ,EAAE,QAAQ,CAAC,KAAK,KAAK,KAAK;gBAClC,MAAM,EAAE,QAAQ,CAAC,GAAG,KAAK,KAAK;gBAC9B,MAAM,EAAE,QAAQ,CAAC,GAAG,KAAK,KAAK;gBAC9B,OAAO,EAAE,QAAQ,CAAC,IAAI,KAAK,KAAK;gBAChC,UAAU,EAAE,QAAQ,CAAC,OAAO,KAAK,KAAK;gBACtC,WAAW,EAAE,QAAQ,CAAC,QAAQ,KAAK,KAAK;gBACxC,UAAU,EAAE,QAAQ,CAAC,OAAO,KAAK,KAAK;gBACtC,MAAM,EAAE,QAAQ,CAAC,GAAG,KAAK,KAAK;gBAC9B,SAAS,EAAE,QAAQ,CAAC,MAAM,KAAK,KAAK;gBACpC,OAAO,EAAE,GAAG;aACb,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;IAC5E,CAAC;IAED,4CAA4C;IAC5C,OAAO;QACL,SAAS,EAAE,IAAI;QACf,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,IAAI;QAChB,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,IAAI;QACZ,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,GAAG;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { NucleusPlugin } from '../types.js';
|
|
2
|
+
export interface FTSResult {
|
|
3
|
+
docId: number;
|
|
4
|
+
score: number;
|
|
5
|
+
highlight?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export interface FTSSearchOptions {
|
|
8
|
+
/** Enable fuzzy matching with the given edit distance. */
|
|
9
|
+
fuzzyDistance?: number;
|
|
10
|
+
/** Maximum number of results (default 10). */
|
|
11
|
+
limit?: number;
|
|
12
|
+
/** Fields to highlight in results. */
|
|
13
|
+
highlight?: string[];
|
|
14
|
+
/** Fields to compute facet counts for. */
|
|
15
|
+
facets?: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface FTSModel {
|
|
18
|
+
/** Add a document's text to the full-text index. */
|
|
19
|
+
index(docId: number, text: string): Promise<boolean>;
|
|
20
|
+
/** Search the full-text index. */
|
|
21
|
+
search(query: string, opts?: FTSSearchOptions): Promise<FTSResult[]>;
|
|
22
|
+
/** Remove a document from the index. */
|
|
23
|
+
remove(docId: number): Promise<boolean>;
|
|
24
|
+
/** Return the number of indexed documents. */
|
|
25
|
+
docCount(): Promise<number>;
|
|
26
|
+
/** Return the number of indexed terms. */
|
|
27
|
+
termCount(): Promise<number>;
|
|
28
|
+
/** Create a named FTS index with the given configuration. */
|
|
29
|
+
createIndex(name: string, config: Record<string, unknown>): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/** Plugin: adds `.fts` to the client. */
|
|
32
|
+
export declare const withFTS: NucleusPlugin<{
|
|
33
|
+
fts: FTSModel;
|
|
34
|
+
}>;
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fts/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAa,aAAa,EAAmB,MAAM,aAAa,CAAC;AAO7E,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAMD,MAAM,WAAW,QAAQ;IACvB,oDAAoD;IACpD,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAErD,kCAAkC;IAClC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAErE,wCAAwC;IACxC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAExC,8CAA8C;IAC9C,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5B,0CAA0C;IAC1C,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE7B,6DAA6D;IAC7D,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E;AA2ED,yCAAyC;AACzC,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC;IAAE,GAAG,EAAE,QAAQ,CAAA;CAAE,CAKpD,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @neutron/nucleus/fts — Full-Text Search model plugin
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { requireNucleus } from '../helpers.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Implementation
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
class FTSModelImpl {
|
|
9
|
+
transport;
|
|
10
|
+
features;
|
|
11
|
+
constructor(transport, features) {
|
|
12
|
+
this.transport = transport;
|
|
13
|
+
this.features = features;
|
|
14
|
+
}
|
|
15
|
+
require() {
|
|
16
|
+
requireNucleus(this.features, 'FTS');
|
|
17
|
+
}
|
|
18
|
+
async index(docId, text) {
|
|
19
|
+
this.require();
|
|
20
|
+
return (await this.transport.fetchval('SELECT FTS_INDEX($1, $2)', [docId, text])) ?? false;
|
|
21
|
+
}
|
|
22
|
+
async search(query, opts = {}) {
|
|
23
|
+
this.require();
|
|
24
|
+
const limit = opts.limit ?? 10;
|
|
25
|
+
let raw;
|
|
26
|
+
if (opts.fuzzyDistance && opts.fuzzyDistance > 0) {
|
|
27
|
+
raw = await this.transport.fetchval('SELECT FTS_FUZZY_SEARCH($1, $2, $3)', [
|
|
28
|
+
query,
|
|
29
|
+
opts.fuzzyDistance,
|
|
30
|
+
limit,
|
|
31
|
+
]);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
raw = await this.transport.fetchval('SELECT FTS_SEARCH($1, $2)', [query, limit]);
|
|
35
|
+
}
|
|
36
|
+
if (!raw)
|
|
37
|
+
return [];
|
|
38
|
+
const results = JSON.parse(raw);
|
|
39
|
+
// Ensure highlight map is present when requested
|
|
40
|
+
if (opts.highlight && opts.highlight.length > 0) {
|
|
41
|
+
for (const r of results) {
|
|
42
|
+
if (!r.highlight)
|
|
43
|
+
r.highlight = {};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return results;
|
|
47
|
+
}
|
|
48
|
+
async remove(docId) {
|
|
49
|
+
this.require();
|
|
50
|
+
return (await this.transport.fetchval('SELECT FTS_REMOVE($1)', [docId])) ?? false;
|
|
51
|
+
}
|
|
52
|
+
async docCount() {
|
|
53
|
+
this.require();
|
|
54
|
+
return (await this.transport.fetchval('SELECT FTS_DOC_COUNT()')) ?? 0;
|
|
55
|
+
}
|
|
56
|
+
async termCount() {
|
|
57
|
+
this.require();
|
|
58
|
+
return (await this.transport.fetchval('SELECT FTS_TERM_COUNT()')) ?? 0;
|
|
59
|
+
}
|
|
60
|
+
async createIndex(name, config) {
|
|
61
|
+
this.require();
|
|
62
|
+
const configJson = JSON.stringify(config);
|
|
63
|
+
await this.transport.execute('SELECT FTS_INDEX($1, $2)', [name, configJson]);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Plugin
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
/** Plugin: adds `.fts` to the client. */
|
|
70
|
+
export const withFTS = {
|
|
71
|
+
name: 'fts',
|
|
72
|
+
init(transport, features) {
|
|
73
|
+
return { fts: new FTSModelImpl(transport, features) };
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fts/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { NucleusPlugin } from '../types.js';
|
|
2
|
+
export interface GeoPoint {
|
|
3
|
+
lat: number;
|
|
4
|
+
lon: number;
|
|
5
|
+
}
|
|
6
|
+
export interface GeoFeature {
|
|
7
|
+
id: string;
|
|
8
|
+
lat: number;
|
|
9
|
+
lon: number;
|
|
10
|
+
properties: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
export interface GeoModel {
|
|
13
|
+
/** Haversine distance in metres between two points. */
|
|
14
|
+
distance(a: GeoPoint, b: GeoPoint): Promise<number>;
|
|
15
|
+
/** Euclidean distance between two points. */
|
|
16
|
+
distanceEuclidean(a: GeoPoint, b: GeoPoint): Promise<number>;
|
|
17
|
+
/** Check if `b` is within `radiusMeters` of `a`. */
|
|
18
|
+
within(a: GeoPoint, b: GeoPoint, radiusMeters: number): Promise<boolean>;
|
|
19
|
+
/** Calculate the area of a polygon (minimum 3 points). */
|
|
20
|
+
area(points: GeoPoint[]): Promise<number>;
|
|
21
|
+
/** Find features within a radius of a point. */
|
|
22
|
+
nearestTo(layer: string, point: GeoPoint, radiusMeters: number, limit: number): Promise<GeoFeature[]>;
|
|
23
|
+
/** Find features inside a bounding box. */
|
|
24
|
+
withinBBox(layer: string, minLat: number, minLon: number, maxLat: number, maxLon: number): Promise<GeoFeature[]>;
|
|
25
|
+
/** Find features inside a polygon. Each coordinate is `[lat, lon]`. */
|
|
26
|
+
withinPolygon(layer: string, polygon: [number, number][]): Promise<GeoFeature[]>;
|
|
27
|
+
/** Insert a geographic feature into a layer table. */
|
|
28
|
+
insert(layer: string, lat: number, lon: number, props: Record<string, unknown>): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/** Plugin: adds `.geo` to the client. */
|
|
31
|
+
export declare const withGeo: NucleusPlugin<{
|
|
32
|
+
geo: GeoModel;
|
|
33
|
+
}>;
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/geo/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAa,aAAa,EAAmB,MAAM,aAAa,CAAC;AAO7E,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAMD,MAAM,WAAW,QAAQ;IACvB,uDAAuD;IACvD,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpD,6CAA6C;IAC7C,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE7D,oDAAoD;IACpD,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEzE,0DAA0D;IAC1D,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1C,gDAAgD;IAChD,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAEtG,2CAA2C;IAC3C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAEjH,uEAAuE;IACvE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAEjF,sDAAsD;IACtD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChG;AAkKD,yCAAyC;AACzC,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC;IAAE,GAAG,EAAE,QAAQ,CAAA;CAAE,CAKpD,CAAC"}
|