@soulbatical/tetra-core 0.1.37 → 0.1.39
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.
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
* Wraps a SupabaseClient so that every insert/update/upsert/delete on .from()
|
|
5
5
|
* also fires a fire-and-forget RPC to the Stella daemon's RuVectorStore.
|
|
6
6
|
*
|
|
7
|
-
* The proxy is transparent: it returns the same SupabaseClient interface,
|
|
8
|
-
* same return types, same behavior. RuVector sync failures are silently logged.
|
|
9
|
-
*
|
|
10
7
|
* Activation: set DUAL_WRITE=1 or STELLA_STORES=supabase,ruvector
|
|
11
8
|
*/
|
|
12
9
|
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dualWriteProxy.d.ts","sourceRoot":"","sources":["../../src/core/dualWriteProxy.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"dualWriteProxy.d.ts","sourceRoot":"","sources":["../../src/core/dualWriteProxy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAuS3D,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CASpE"}
|
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
* Wraps a SupabaseClient so that every insert/update/upsert/delete on .from()
|
|
5
5
|
* also fires a fire-and-forget RPC to the Stella daemon's RuVectorStore.
|
|
6
6
|
*
|
|
7
|
-
* The proxy is transparent: it returns the same SupabaseClient interface,
|
|
8
|
-
* same return types, same behavior. RuVector sync failures are silently logged.
|
|
9
|
-
*
|
|
10
7
|
* Activation: set DUAL_WRITE=1 or STELLA_STORES=supabase,ruvector
|
|
11
8
|
*/
|
|
12
9
|
import { connect } from 'node:net';
|
|
@@ -14,42 +11,47 @@ const SOCKET_PATH = '/tmp/stella-daemon.sock';
|
|
|
14
11
|
// ─── Daemon RPC (lightweight, no dependency on stella) ──────
|
|
15
12
|
let daemonSocket = null;
|
|
16
13
|
let daemonConnected = false;
|
|
17
|
-
let
|
|
14
|
+
let connectPromise = null;
|
|
18
15
|
let rpcId = 0;
|
|
19
16
|
function connectDaemon() {
|
|
20
|
-
if (daemonConnected)
|
|
17
|
+
if (daemonConnected && daemonSocket)
|
|
21
18
|
return Promise.resolve();
|
|
22
|
-
if (
|
|
23
|
-
return
|
|
24
|
-
|
|
25
|
-
return new Promise((resolve) => {
|
|
19
|
+
if (connectPromise)
|
|
20
|
+
return connectPromise;
|
|
21
|
+
connectPromise = new Promise((resolve) => {
|
|
26
22
|
const sock = connect(SOCKET_PATH);
|
|
27
23
|
const timeout = setTimeout(() => {
|
|
28
24
|
sock.destroy();
|
|
29
|
-
|
|
25
|
+
connectPromise = null;
|
|
30
26
|
resolve();
|
|
31
27
|
}, 2000);
|
|
32
28
|
sock.on('connect', () => {
|
|
33
29
|
clearTimeout(timeout);
|
|
34
30
|
daemonSocket = sock;
|
|
35
31
|
daemonConnected = true;
|
|
36
|
-
|
|
32
|
+
connectPromise = null;
|
|
33
|
+
// unref so this socket doesn't keep the process alive
|
|
34
|
+
sock.unref();
|
|
37
35
|
resolve();
|
|
38
36
|
});
|
|
37
|
+
// Consume incoming data (daemon responses) — we don't need them
|
|
38
|
+
// but must drain the buffer to prevent backpressure
|
|
39
|
+
sock.on('data', () => { });
|
|
39
40
|
sock.on('close', () => {
|
|
40
41
|
daemonConnected = false;
|
|
41
42
|
daemonSocket = null;
|
|
43
|
+
connectPromise = null;
|
|
42
44
|
});
|
|
43
45
|
sock.on('error', () => {
|
|
44
46
|
clearTimeout(timeout);
|
|
45
47
|
daemonConnected = false;
|
|
46
48
|
daemonSocket = null;
|
|
47
|
-
|
|
49
|
+
connectPromise = null;
|
|
48
50
|
resolve();
|
|
49
51
|
});
|
|
50
52
|
});
|
|
53
|
+
return connectPromise;
|
|
51
54
|
}
|
|
52
|
-
/** Fire-and-forget RPC to daemon. Never throws, never blocks. */
|
|
53
55
|
function daemonRpc(method, params) {
|
|
54
56
|
connectDaemon().then(() => {
|
|
55
57
|
if (!daemonSocket || !daemonConnected)
|
|
@@ -64,129 +66,197 @@ function daemonRpc(method, params) {
|
|
|
64
66
|
}
|
|
65
67
|
}).catch(() => { });
|
|
66
68
|
}
|
|
67
|
-
// ───
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
function
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (prop === 'insert' && typeof value === 'function') {
|
|
81
|
-
return function (data, options) {
|
|
82
|
-
const builder = value.call(target, data, options);
|
|
83
|
-
// Attach side-effect: after this entire chain resolves, mirror to daemon
|
|
84
|
-
attachMirror(builder, () => {
|
|
85
|
-
if (Array.isArray(data)) {
|
|
86
|
-
daemonRpc('store.seed', { table, records: data });
|
|
87
|
-
}
|
|
88
|
-
else if (data) {
|
|
89
|
-
daemonRpc('store.insert', { table, record: data });
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
return builder;
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
if (prop === 'upsert' && typeof value === 'function') {
|
|
96
|
-
return function (data, options) {
|
|
97
|
-
const builder = value.call(target, data, options);
|
|
98
|
-
attachMirror(builder, () => {
|
|
99
|
-
const onConflict = options?.onConflict || 'id';
|
|
100
|
-
if (Array.isArray(data)) {
|
|
101
|
-
for (const record of data) {
|
|
102
|
-
daemonRpc('store.upsert', { table, record, onConflict });
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
else if (data) {
|
|
106
|
-
daemonRpc('store.upsert', { table, record: data, onConflict });
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
return builder;
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
if (prop === 'update' && typeof value === 'function') {
|
|
113
|
-
return function (data, options) {
|
|
114
|
-
const builder = value.call(target, data, options);
|
|
115
|
-
// For update we need the filter chain — we'll capture it from the URL later
|
|
116
|
-
attachMirrorWithFilters(builder, table, 'update', data);
|
|
117
|
-
return builder;
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
if (prop === 'delete' && typeof value === 'function') {
|
|
121
|
-
return function (options) {
|
|
122
|
-
const builder = value.call(target, options);
|
|
123
|
-
attachMirrorWithFilters(builder, table, 'delete', null);
|
|
124
|
-
return builder;
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
if (typeof value === 'function')
|
|
128
|
-
return value.bind(target);
|
|
129
|
-
return value;
|
|
69
|
+
// ─── Mirror logic ───────────────────────────────────────────
|
|
70
|
+
function mirrorInsert(table, data) {
|
|
71
|
+
if (Array.isArray(data)) {
|
|
72
|
+
daemonRpc('store.seed', { table, records: data });
|
|
73
|
+
}
|
|
74
|
+
else if (data) {
|
|
75
|
+
daemonRpc('store.insert', { table, record: data });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function mirrorUpsert(table, data, onConflict) {
|
|
79
|
+
if (Array.isArray(data)) {
|
|
80
|
+
for (const record of data) {
|
|
81
|
+
daemonRpc('store.upsert', { table, record, onConflict });
|
|
130
82
|
}
|
|
131
|
-
}
|
|
83
|
+
}
|
|
84
|
+
else if (data) {
|
|
85
|
+
daemonRpc('store.upsert', { table, record: data, onConflict });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function mirrorUpdate(table, changes, filters) {
|
|
89
|
+
if (filters.length && changes) {
|
|
90
|
+
daemonRpc('store.update', { table, filters, changes });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function mirrorDelete(table, filters) {
|
|
94
|
+
if (filters.length) {
|
|
95
|
+
daemonRpc('store.delete', { table, filters });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
class DualWriteQueryBuilder {
|
|
99
|
+
original;
|
|
100
|
+
table;
|
|
101
|
+
constructor(original, table) {
|
|
102
|
+
this.original = original;
|
|
103
|
+
this.table = table;
|
|
104
|
+
}
|
|
105
|
+
// ─── Write methods with dual-write ───
|
|
106
|
+
insert(data, options) {
|
|
107
|
+
const result = this.original.insert(data, options);
|
|
108
|
+
return this.wrapResult(result, () => mirrorInsert(this.table, data));
|
|
109
|
+
}
|
|
110
|
+
upsert(data, options) {
|
|
111
|
+
const result = this.original.upsert(data, options);
|
|
112
|
+
const onConflict = options?.onConflict || 'id';
|
|
113
|
+
return this.wrapResult(result, () => mirrorUpsert(this.table, data, onConflict));
|
|
114
|
+
}
|
|
115
|
+
update(changes, options) {
|
|
116
|
+
const result = this.original.update(changes, options);
|
|
117
|
+
return this.wrapFilteredResult(result, (filters) => mirrorUpdate(this.table, changes, filters));
|
|
118
|
+
}
|
|
119
|
+
delete(options) {
|
|
120
|
+
const result = this.original.delete(options);
|
|
121
|
+
return this.wrapFilteredResult(result, (filters) => mirrorDelete(this.table, filters));
|
|
122
|
+
}
|
|
123
|
+
// ─── Read methods (pass-through) ───
|
|
124
|
+
select(...args) { return this.original.select(...args); }
|
|
125
|
+
// ─── Wrap a write result to trigger mirror on success ───
|
|
126
|
+
wrapResult(builder, onSuccess) {
|
|
127
|
+
return new DualWriteResultBuilder(builder, onSuccess);
|
|
128
|
+
}
|
|
129
|
+
wrapFilteredResult(builder, onSuccess) {
|
|
130
|
+
return new DualWriteFilterBuilder(builder, onSuccess);
|
|
131
|
+
}
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
134
|
+
* Wraps a PostgREST result builder (after insert/upsert).
|
|
135
|
+
* Intercepts await/.then() to trigger the daemon mirror on success.
|
|
136
136
|
*/
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
137
|
+
class DualWriteResultBuilder {
|
|
138
|
+
builder;
|
|
139
|
+
onSuccess;
|
|
140
|
+
constructor(builder, onSuccess) {
|
|
141
|
+
this.builder = builder;
|
|
142
|
+
this.onSuccess = onSuccess;
|
|
143
|
+
}
|
|
144
|
+
// Chain methods — delegate to original, keep wrapping
|
|
145
|
+
select(...args) {
|
|
146
|
+
this.builder = this.builder.select(...args);
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
single() {
|
|
150
|
+
this.builder = this.builder.single();
|
|
151
|
+
return this;
|
|
152
|
+
}
|
|
153
|
+
maybeSingle() {
|
|
154
|
+
this.builder = this.builder.maybeSingle();
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
order(...args) {
|
|
158
|
+
this.builder = this.builder.order(...args);
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
limit(...args) {
|
|
162
|
+
this.builder = this.builder.limit(...args);
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
165
|
+
eq(...args) {
|
|
166
|
+
this.builder = this.builder.eq(...args);
|
|
167
|
+
return this;
|
|
168
|
+
}
|
|
169
|
+
// Thenable — this is what await calls
|
|
170
|
+
then(onFulfilled, onRejected) {
|
|
171
|
+
return this.builder.then((result) => {
|
|
153
172
|
if (!result?.error) {
|
|
154
173
|
try {
|
|
155
|
-
onSuccess();
|
|
174
|
+
this.onSuccess();
|
|
156
175
|
}
|
|
157
176
|
catch { /* never fail */ }
|
|
158
177
|
}
|
|
159
178
|
return onFulfilled ? onFulfilled(result) : result;
|
|
160
179
|
}, onRejected);
|
|
161
|
-
}
|
|
162
|
-
// Override .then on the instance
|
|
163
|
-
builder.then = patchedThen;
|
|
180
|
+
}
|
|
164
181
|
}
|
|
165
182
|
/**
|
|
166
|
-
*
|
|
183
|
+
* Wraps update/delete result builders. Captures .eq() filter calls
|
|
184
|
+
* to pass to the daemon mirror.
|
|
167
185
|
*/
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
186
|
+
class DualWriteFilterBuilder {
|
|
187
|
+
builder;
|
|
188
|
+
onSuccess;
|
|
189
|
+
filters = [];
|
|
190
|
+
constructor(builder, onSuccess) {
|
|
191
|
+
this.builder = builder;
|
|
192
|
+
this.onSuccess = onSuccess;
|
|
193
|
+
}
|
|
194
|
+
// Filter methods — capture and delegate
|
|
195
|
+
eq(column, value) {
|
|
196
|
+
this.filters.push({ column, op: 'eq', value });
|
|
197
|
+
this.builder = this.builder.eq(column, value);
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
neq(column, value) {
|
|
201
|
+
this.filters.push({ column, op: 'neq', value });
|
|
202
|
+
this.builder = this.builder.neq(column, value);
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
gt(column, value) {
|
|
206
|
+
this.filters.push({ column, op: 'gt', value });
|
|
207
|
+
this.builder = this.builder.gt(column, value);
|
|
208
|
+
return this;
|
|
209
|
+
}
|
|
210
|
+
gte(column, value) {
|
|
211
|
+
this.filters.push({ column, op: 'gte', value });
|
|
212
|
+
this.builder = this.builder.gte(column, value);
|
|
213
|
+
return this;
|
|
214
|
+
}
|
|
215
|
+
lt(column, value) {
|
|
216
|
+
this.filters.push({ column, op: 'lt', value });
|
|
217
|
+
this.builder = this.builder.lt(column, value);
|
|
218
|
+
return this;
|
|
219
|
+
}
|
|
220
|
+
lte(column, value) {
|
|
221
|
+
this.filters.push({ column, op: 'lte', value });
|
|
222
|
+
this.builder = this.builder.lte(column, value);
|
|
223
|
+
return this;
|
|
224
|
+
}
|
|
225
|
+
in(column, values) {
|
|
226
|
+
this.filters.push({ column, op: 'in', value: values });
|
|
227
|
+
this.builder = this.builder.in(column, values);
|
|
228
|
+
return this;
|
|
229
|
+
}
|
|
230
|
+
is(column, value) {
|
|
231
|
+
this.filters.push({ column, op: 'is', value });
|
|
232
|
+
this.builder = this.builder.is(column, value);
|
|
233
|
+
return this;
|
|
234
|
+
}
|
|
235
|
+
// Chain methods
|
|
236
|
+
select(...args) {
|
|
237
|
+
this.builder = this.builder.select(...args);
|
|
238
|
+
return this;
|
|
239
|
+
}
|
|
240
|
+
single() {
|
|
241
|
+
this.builder = this.builder.single();
|
|
242
|
+
return this;
|
|
243
|
+
}
|
|
244
|
+
maybeSingle() {
|
|
245
|
+
this.builder = this.builder.maybeSingle();
|
|
246
|
+
return this;
|
|
247
|
+
}
|
|
248
|
+
// Thenable
|
|
249
|
+
then(onFulfilled, onRejected) {
|
|
250
|
+
return this.builder.then((result) => {
|
|
251
|
+
if (!result?.error) {
|
|
252
|
+
try {
|
|
253
|
+
this.onSuccess(this.filters);
|
|
254
|
+
}
|
|
255
|
+
catch { /* never fail */ }
|
|
256
|
+
}
|
|
257
|
+
return onFulfilled ? onFulfilled(result) : result;
|
|
258
|
+
}, onRejected);
|
|
179
259
|
}
|
|
180
|
-
attachMirror(builder, () => {
|
|
181
|
-
if (filters.length === 0)
|
|
182
|
-
return; // No filters = unsafe, skip
|
|
183
|
-
if (op === 'update' && changes) {
|
|
184
|
-
daemonRpc('store.update', { table, filters, changes });
|
|
185
|
-
}
|
|
186
|
-
else if (op === 'delete') {
|
|
187
|
-
daemonRpc('store.delete', { table, filters });
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
260
|
}
|
|
191
261
|
// ─── Public API ─────────────────────────────────────────────
|
|
192
262
|
export function isDualWriteEnabled() {
|
|
@@ -199,7 +269,7 @@ export function withDualWrite(client) {
|
|
|
199
269
|
const originalFrom = client.from.bind(client);
|
|
200
270
|
client.from = function proxiedFrom(table) {
|
|
201
271
|
const queryBuilder = originalFrom(table);
|
|
202
|
-
return
|
|
272
|
+
return new DualWriteQueryBuilder(queryBuilder, table);
|
|
203
273
|
};
|
|
204
274
|
return client;
|
|
205
275
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dualWriteProxy.js","sourceRoot":"","sources":["../../src/core/dualWriteProxy.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"dualWriteProxy.js","sourceRoot":"","sources":["../../src/core/dualWriteProxy.ts"],"names":[],"mappings":"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"}
|