@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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +27 -0
  3. package/dist/blob/index.d.ts +42 -0
  4. package/dist/blob/index.d.ts.map +1 -0
  5. package/dist/blob/index.js +121 -0
  6. package/dist/blob/index.js.map +1 -0
  7. package/dist/cdc/index.d.ts +14 -0
  8. package/dist/cdc/index.d.ts.map +1 -0
  9. package/dist/cdc/index.js +41 -0
  10. package/dist/cdc/index.js.map +1 -0
  11. package/dist/client.d.ts +59 -0
  12. package/dist/client.d.ts.map +1 -0
  13. package/dist/client.js +68 -0
  14. package/dist/client.js.map +1 -0
  15. package/dist/columnar/index.d.ts +20 -0
  16. package/dist/columnar/index.d.ts.map +1 -0
  17. package/dist/columnar/index.js +60 -0
  18. package/dist/columnar/index.js.map +1 -0
  19. package/dist/datalog/index.d.ts +20 -0
  20. package/dist/datalog/index.d.ts.map +1 -0
  21. package/dist/datalog/index.js +53 -0
  22. package/dist/datalog/index.js.map +1 -0
  23. package/dist/document/index.d.ts +42 -0
  24. package/dist/document/index.d.ts.map +1 -0
  25. package/dist/document/index.js +154 -0
  26. package/dist/document/index.js.map +1 -0
  27. package/dist/errors.d.ts +39 -0
  28. package/dist/errors.d.ts.map +1 -0
  29. package/dist/errors.js +64 -0
  30. package/dist/errors.js.map +1 -0
  31. package/dist/features.d.ts +14 -0
  32. package/dist/features.d.ts.map +1 -0
  33. package/dist/features.js +85 -0
  34. package/dist/features.js.map +1 -0
  35. package/dist/fts/index.d.ts +35 -0
  36. package/dist/fts/index.d.ts.map +1 -0
  37. package/dist/fts/index.js +76 -0
  38. package/dist/fts/index.js.map +1 -0
  39. package/dist/geo/index.d.ts +34 -0
  40. package/dist/geo/index.d.ts.map +1 -0
  41. package/dist/geo/index.js +121 -0
  42. package/dist/geo/index.js.map +1 -0
  43. package/dist/graph/index.d.ts +43 -0
  44. package/dist/graph/index.d.ts.map +1 -0
  45. package/dist/graph/index.js +109 -0
  46. package/dist/graph/index.js.map +1 -0
  47. package/dist/helpers.d.ts +11 -0
  48. package/dist/helpers.d.ts.map +1 -0
  49. package/dist/helpers.js +47 -0
  50. package/dist/helpers.js.map +1 -0
  51. package/dist/index.d.ts +39 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +29 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/kv/index.d.ts +93 -0
  56. package/dist/kv/index.d.ts.map +1 -0
  57. package/dist/kv/index.js +223 -0
  58. package/dist/kv/index.js.map +1 -0
  59. package/dist/migrate.d.ts +37 -0
  60. package/dist/migrate.d.ts.map +1 -0
  61. package/dist/migrate.js +95 -0
  62. package/dist/migrate.js.map +1 -0
  63. package/dist/pubsub/index.d.ts +14 -0
  64. package/dist/pubsub/index.d.ts.map +1 -0
  65. package/dist/pubsub/index.js +44 -0
  66. package/dist/pubsub/index.js.map +1 -0
  67. package/dist/sql/index.d.ts +31 -0
  68. package/dist/sql/index.d.ts.map +1 -0
  69. package/dist/sql/index.js +65 -0
  70. package/dist/sql/index.js.map +1 -0
  71. package/dist/streams/index.d.ts +26 -0
  72. package/dist/streams/index.d.ts.map +1 -0
  73. package/dist/streams/index.js +83 -0
  74. package/dist/streams/index.js.map +1 -0
  75. package/dist/timeseries/index.d.ts +46 -0
  76. package/dist/timeseries/index.d.ts.map +1 -0
  77. package/dist/timeseries/index.js +122 -0
  78. package/dist/timeseries/index.js.map +1 -0
  79. package/dist/transport.d.ts +97 -0
  80. package/dist/transport.d.ts.map +1 -0
  81. package/dist/transport.js +477 -0
  82. package/dist/transport.js.map +1 -0
  83. package/dist/types.d.ts +58 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +5 -0
  86. package/dist/types.js.map +1 -0
  87. package/dist/vector/index.d.ts +34 -0
  88. package/dist/vector/index.d.ts.map +1 -0
  89. package/dist/vector/index.js +104 -0
  90. package/dist/vector/index.js.map +1 -0
  91. package/package.json +110 -0
@@ -0,0 +1,83 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @neutron/nucleus/streams — Streams model plugin (Redis Streams-compatible)
3
+ // ---------------------------------------------------------------------------
4
+ import { requireNucleus } from '../helpers.js';
5
+ // ---------------------------------------------------------------------------
6
+ // Implementation
7
+ // ---------------------------------------------------------------------------
8
+ class StreamsModelImpl {
9
+ transport;
10
+ features;
11
+ constructor(transport, features) {
12
+ this.transport = transport;
13
+ this.features = features;
14
+ }
15
+ require() {
16
+ requireNucleus(this.features, 'Streams');
17
+ }
18
+ async xadd(stream, fields) {
19
+ this.require();
20
+ // Build variadic args: stream, k1, v1, k2, v2, ...
21
+ const args = [stream];
22
+ for (const [k, v] of Object.entries(fields)) {
23
+ args.push(k, v);
24
+ }
25
+ const placeholders = args.map((_, i) => `$${i + 1}`).join(', ');
26
+ const sql = `SELECT STREAM_XADD(${placeholders})`;
27
+ return (await this.transport.fetchval(sql, args)) ?? '';
28
+ }
29
+ async xlen(stream) {
30
+ this.require();
31
+ return (await this.transport.fetchval('SELECT STREAM_XLEN($1)', [stream])) ?? 0;
32
+ }
33
+ async xrange(stream, startMs, endMs, count) {
34
+ this.require();
35
+ const raw = await this.transport.fetchval('SELECT STREAM_XRANGE($1, $2, $3, $4)', [
36
+ stream, startMs, endMs, count,
37
+ ]);
38
+ if (!raw)
39
+ return [];
40
+ return JSON.parse(raw);
41
+ }
42
+ async xread(stream, lastIdMs, count) {
43
+ this.require();
44
+ const raw = await this.transport.fetchval('SELECT STREAM_XREAD($1, $2, $3)', [
45
+ stream, lastIdMs, count,
46
+ ]);
47
+ if (!raw)
48
+ return [];
49
+ return JSON.parse(raw);
50
+ }
51
+ async xgroupCreate(stream, group, startId) {
52
+ this.require();
53
+ return ((await this.transport.fetchval('SELECT STREAM_XGROUP_CREATE($1, $2, $3)', [
54
+ stream, group, startId,
55
+ ])) ?? false);
56
+ }
57
+ async xreadGroup(stream, group, consumer, count) {
58
+ this.require();
59
+ const raw = await this.transport.fetchval('SELECT STREAM_XREADGROUP($1, $2, $3, $4)', [
60
+ stream, group, consumer, count,
61
+ ]);
62
+ if (!raw)
63
+ return [];
64
+ return JSON.parse(raw);
65
+ }
66
+ async xack(stream, group, idMs, idSeq) {
67
+ this.require();
68
+ return ((await this.transport.fetchval('SELECT STREAM_XACK($1, $2, $3, $4)', [
69
+ stream, group, idMs, idSeq,
70
+ ])) ?? false);
71
+ }
72
+ }
73
+ // ---------------------------------------------------------------------------
74
+ // Plugin
75
+ // ---------------------------------------------------------------------------
76
+ /** Plugin: adds `.streams` to the client. */
77
+ export const withStreams = {
78
+ name: 'streams',
79
+ init(transport, features) {
80
+ return { streams: new StreamsModelImpl(transport, features) };
81
+ },
82
+ };
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/streams/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { NucleusPlugin } from '../types.js';
2
+ export interface TimeSeriesPoint {
3
+ timestamp: Date;
4
+ value: number;
5
+ tags?: Record<string, string>;
6
+ }
7
+ export type AggFunc = 'sum' | 'avg' | 'min' | 'max' | 'count' | 'first' | 'last';
8
+ export type BucketInterval = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month';
9
+ export interface TimeSeriesQueryOptions {
10
+ /** Filter by tags. */
11
+ tags?: Record<string, string>;
12
+ /** Downsample into buckets. */
13
+ downsample?: {
14
+ /** Bucket interval name. */
15
+ interval: BucketInterval;
16
+ /** Aggregation function. */
17
+ fn: AggFunc;
18
+ };
19
+ }
20
+ export interface TimeSeriesModel {
21
+ /** Write data points to a measurement (series). */
22
+ write(measurement: string, points: TimeSeriesPoint[]): Promise<void>;
23
+ /** Return the most recent value for a series. */
24
+ last(measurement: string): Promise<number | null>;
25
+ /** Return the total number of data points. */
26
+ count(measurement: string): Promise<number>;
27
+ /** Count data points in a time range. */
28
+ rangeCount(measurement: string, from: Date, to: Date): Promise<number>;
29
+ /** Average value in a time range. */
30
+ rangeAvg(measurement: string, from: Date, to: Date): Promise<number | null>;
31
+ /** Set the data retention period (in days). */
32
+ retention(measurement: string, days: number): Promise<boolean>;
33
+ /** Match series names against a pattern. */
34
+ match(measurement: string, pattern: string): Promise<string>;
35
+ /** Truncate a timestamp to a bucket boundary. */
36
+ timeBucket(interval: BucketInterval, timestamp: Date): Promise<number>;
37
+ /** Query raw data points in a time range. */
38
+ query(measurement: string, from: Date, to: Date, opts?: TimeSeriesQueryOptions): Promise<TimeSeriesPoint[]>;
39
+ /** Aggregate data points into time buckets. */
40
+ aggregate(measurement: string, from: Date, to: Date, interval: BucketInterval, fn: AggFunc): Promise<TimeSeriesPoint[]>;
41
+ }
42
+ /** Plugin: adds `.timeseries` to the client. */
43
+ export declare const withTimeSeries: NucleusPlugin<{
44
+ timeseries: TimeSeriesModel;
45
+ }>;
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/timeseries/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAa,aAAa,EAAmB,MAAM,aAAa,CAAC;AAO7E,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAEjF,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAErF,MAAM,WAAW,sBAAsB;IACrC,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,+BAA+B;IAC/B,UAAU,CAAC,EAAE;QACX,4BAA4B;QAC5B,QAAQ,EAAE,cAAc,CAAC;QACzB,4BAA4B;QAC5B,EAAE,EAAE,OAAO,CAAC;KACb,CAAC;CACH;AAMD,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE,iDAAiD;IACjD,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAElD,8CAA8C;IAC9C,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5C,yCAAyC;IACzC,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEvE,qCAAqC;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE5E,+CAA+C;IAC/C,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,4CAA4C;IAC5C,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE7D,iDAAiD;IACjD,UAAU,CAAC,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEvE,6CAA6C;IAC7C,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAE5G,+CAA+C;IAC/C,SAAS,CACP,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,IAAI,EACR,QAAQ,EAAE,cAAc,EACxB,EAAE,EAAE,OAAO,GACV,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CAC/B;AAmJD,gDAAgD;AAChD,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC;IAAE,UAAU,EAAE,eAAe,CAAA;CAAE,CAKzE,CAAC"}
@@ -0,0 +1,122 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @neutron/nucleus/timeseries — Time-Series model plugin
3
+ // ---------------------------------------------------------------------------
4
+ import { requireNucleus } from '../helpers.js';
5
+ // ---------------------------------------------------------------------------
6
+ // Implementation
7
+ // ---------------------------------------------------------------------------
8
+ class TimeSeriesModelImpl {
9
+ transport;
10
+ features;
11
+ constructor(transport, features) {
12
+ this.transport = transport;
13
+ this.features = features;
14
+ }
15
+ require() {
16
+ requireNucleus(this.features, 'TimeSeries');
17
+ }
18
+ async write(measurement, points) {
19
+ this.require();
20
+ for (const p of points) {
21
+ const tsMs = p.timestamp.getTime();
22
+ await this.transport.execute('SELECT TS_INSERT($1, $2, $3)', [measurement, tsMs, p.value]);
23
+ }
24
+ }
25
+ async last(measurement) {
26
+ this.require();
27
+ return this.transport.fetchval('SELECT TS_LAST($1)', [measurement]);
28
+ }
29
+ async count(measurement) {
30
+ this.require();
31
+ return (await this.transport.fetchval('SELECT TS_COUNT($1)', [measurement])) ?? 0;
32
+ }
33
+ async rangeCount(measurement, from, to) {
34
+ this.require();
35
+ return ((await this.transport.fetchval('SELECT TS_RANGE_COUNT($1, $2, $3)', [
36
+ measurement, from.getTime(), to.getTime(),
37
+ ])) ?? 0);
38
+ }
39
+ async rangeAvg(measurement, from, to) {
40
+ this.require();
41
+ return this.transport.fetchval('SELECT TS_RANGE_AVG($1, $2, $3)', [
42
+ measurement, from.getTime(), to.getTime(),
43
+ ]);
44
+ }
45
+ async retention(measurement, days) {
46
+ this.require();
47
+ return (await this.transport.fetchval('SELECT TS_RETENTION($1, $2)', [measurement, days])) ?? false;
48
+ }
49
+ async match(measurement, pattern) {
50
+ this.require();
51
+ return (await this.transport.fetchval('SELECT TS_MATCH($1, $2)', [measurement, pattern])) ?? '';
52
+ }
53
+ async timeBucket(interval, timestamp) {
54
+ this.require();
55
+ return ((await this.transport.fetchval('SELECT TIME_BUCKET($1, $2)', [interval, timestamp.getTime()])) ?? 0);
56
+ }
57
+ async query(measurement, from, to, opts = {}) {
58
+ this.require();
59
+ // Delegate to aggregate if downsample is requested
60
+ if (opts.downsample) {
61
+ return this.aggregate(measurement, from, to, opts.downsample.interval, opts.downsample.fn);
62
+ }
63
+ const fromMs = from.getTime();
64
+ const toMs = to.getTime();
65
+ let sql;
66
+ let params;
67
+ if (opts.tags && Object.keys(opts.tags).length > 0) {
68
+ const tagsJson = JSON.stringify(opts.tags);
69
+ sql =
70
+ `SELECT COALESCE((SELECT json_agg(row_to_json(t)) FROM (` +
71
+ `SELECT timestamp_ms, value FROM ts_data WHERE series = $1 AND timestamp_ms >= $2 AND timestamp_ms <= $3 AND tags @> $4::jsonb ORDER BY timestamp_ms` +
72
+ `) t), '[]')`;
73
+ params = [measurement, fromMs, toMs, tagsJson];
74
+ }
75
+ else {
76
+ sql =
77
+ `SELECT COALESCE((SELECT json_agg(row_to_json(t)) FROM (` +
78
+ `SELECT timestamp_ms, value FROM ts_data WHERE series = $1 AND timestamp_ms >= $2 AND timestamp_ms <= $3 ORDER BY timestamp_ms` +
79
+ `) t), '[]')`;
80
+ params = [measurement, fromMs, toMs];
81
+ }
82
+ const raw = await this.transport.fetchval(sql, params);
83
+ if (!raw)
84
+ return [];
85
+ const points = JSON.parse(raw);
86
+ return points.map((p) => ({
87
+ timestamp: new Date(p.timestamp_ms),
88
+ value: p.value,
89
+ }));
90
+ }
91
+ async aggregate(measurement, from, to, interval, fn) {
92
+ this.require();
93
+ const VALID_AGG_FUNCS = ['sum', 'avg', 'min', 'max', 'count', 'first', 'last'];
94
+ if (!VALID_AGG_FUNCS.includes(fn)) {
95
+ throw new Error(`Invalid aggregation function: ${fn}. Must be one of: ${VALID_AGG_FUNCS.join(', ')}`);
96
+ }
97
+ const sql = `SELECT COALESCE((SELECT json_agg(row_to_json(t)) FROM (` +
98
+ `SELECT TIME_BUCKET($1, timestamp_ms) AS bucket_ms, ${fn}(value) AS value ` +
99
+ `FROM ts_data WHERE series = $2 AND timestamp_ms >= $3 AND timestamp_ms <= $4 ` +
100
+ `GROUP BY bucket_ms ORDER BY bucket_ms` +
101
+ `) t), '[]')`;
102
+ const raw = await this.transport.fetchval(sql, [interval, measurement, from.getTime(), to.getTime()]);
103
+ if (!raw)
104
+ return [];
105
+ const points = JSON.parse(raw);
106
+ return points.map((p) => ({
107
+ timestamp: new Date(p.bucket_ms),
108
+ value: p.value,
109
+ }));
110
+ }
111
+ }
112
+ // ---------------------------------------------------------------------------
113
+ // Plugin
114
+ // ---------------------------------------------------------------------------
115
+ /** Plugin: adds `.timeseries` to the client. */
116
+ export const withTimeSeries = {
117
+ name: 'timeseries',
118
+ init(transport, features) {
119
+ return { timeseries: new TimeSeriesModelImpl(transport, features) };
120
+ },
121
+ };
122
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/timeseries/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import type { Transport, TransactionTransport, QueryResult, IsolationLevel } from './types.js';
2
+ /** Configuration for the base HTTP transport. */
3
+ export interface TransportConfig {
4
+ /** Base URL of the Nucleus server. */
5
+ url: string;
6
+ /** Extra HTTP headers sent with every request. */
7
+ headers?: Record<string, string>;
8
+ /** Request timeout in milliseconds (default 30000). */
9
+ timeout?: number;
10
+ }
11
+ /** Extended configuration for mobile transport with retry, cache, and offline queue. */
12
+ export interface MobileTransportConfig extends TransportConfig {
13
+ /** Maximum number of retry attempts for failed requests (default 3). */
14
+ maxRetries?: number;
15
+ /** Base delay in ms between retries — uses exponential backoff (default 1000). */
16
+ retryDelay?: number;
17
+ /** Whether to cache SELECT query results (default true). */
18
+ cacheEnabled?: boolean;
19
+ /** Time-to-live for cached entries in ms (default 60000). */
20
+ cacheTTL?: number;
21
+ /** Whether to queue writes when the device is offline (default true). */
22
+ offlineQueueEnabled?: boolean;
23
+ /** Maximum number of queued offline operations (default 100). */
24
+ maxQueueSize?: number;
25
+ }
26
+ export declare class HttpTransport implements Transport {
27
+ private readonly baseUrl;
28
+ private readonly headers;
29
+ private readonly timeout;
30
+ constructor(url: string, headers?: Record<string, string>, timeout?: number);
31
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
32
+ execute(sql: string, params?: unknown[]): Promise<number>;
33
+ fetchval<T = unknown>(sql: string, params?: unknown[]): Promise<T | null>;
34
+ beginTransaction(isolationLevel?: IsolationLevel): Promise<TransactionTransport>;
35
+ close(): Promise<void>;
36
+ ping(): Promise<void>;
37
+ }
38
+ /**
39
+ * Transport for mobile (React Native) environments.
40
+ *
41
+ * Wraps `HttpTransport` and adds:
42
+ * - Automatic retry with exponential backoff for transient failures
43
+ * - In-memory cache for SELECT queries
44
+ * - Offline write queue that flushes when connectivity is restored
45
+ */
46
+ export declare class MobileTransport implements Transport {
47
+ private readonly http;
48
+ private readonly cache;
49
+ private readonly cacheTTL;
50
+ private readonly cacheEnabled;
51
+ private readonly maxRetries;
52
+ private readonly retryDelay;
53
+ private readonly offlineQueueEnabled;
54
+ private readonly maxQueueSize;
55
+ private offlineQueue;
56
+ private isOnline;
57
+ constructor(config: MobileTransportConfig);
58
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
59
+ execute(sql: string, params?: unknown[]): Promise<number>;
60
+ fetchval<T = unknown>(sql: string, params?: unknown[]): Promise<T | null>;
61
+ beginTransaction(isolationLevel?: IsolationLevel): Promise<TransactionTransport>;
62
+ close(): Promise<void>;
63
+ ping(): Promise<void>;
64
+ /** Clear all cached query results, or only those matching `pattern`. */
65
+ invalidateCache(pattern?: string): void;
66
+ /** Number of operations waiting in the offline queue. */
67
+ get queueSize(): number;
68
+ private withRetry;
69
+ private flushQueue;
70
+ }
71
+ /**
72
+ * Transport for desktop environments where Nucleus is embedded via Tauri.
73
+ *
74
+ * Skips HTTP serialization overhead by calling Tauri's IPC `invoke()` directly.
75
+ * Falls back to the `neutron://` custom protocol when Tauri internals are not
76
+ * available.
77
+ */
78
+ export declare class EmbeddedTransport implements Transport {
79
+ private readonly invoke;
80
+ constructor();
81
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
82
+ execute(sql: string, params?: unknown[]): Promise<number>;
83
+ fetchval<T = unknown>(sql: string, params?: unknown[]): Promise<T | null>;
84
+ beginTransaction(isolationLevel?: IsolationLevel): Promise<TransactionTransport>;
85
+ close(): Promise<void>;
86
+ ping(): Promise<void>;
87
+ }
88
+ /**
89
+ * Create the best transport for the current platform.
90
+ *
91
+ * Detection order:
92
+ * 1. Desktop with Tauri internals -> `EmbeddedTransport` (IPC, zero serialization overhead)
93
+ * 2. React Native -> `MobileTransport` (retries, caching, offline queue)
94
+ * 3. Everything else -> `HttpTransport` (standard fetch)
95
+ */
96
+ export declare function createTransport(config: MobileTransportConfig): Transport;
97
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}