@soulbatical/tetra-core 0.1.36 → 0.1.37
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.
|
@@ -10,14 +10,6 @@
|
|
|
10
10
|
* Activation: set DUAL_WRITE=1 or STELLA_STORES=supabase,ruvector
|
|
11
11
|
*/
|
|
12
12
|
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
13
|
-
/**
|
|
14
|
-
* Check if dual-write is enabled via environment.
|
|
15
|
-
*/
|
|
16
13
|
export declare function isDualWriteEnabled(): boolean;
|
|
17
|
-
/**
|
|
18
|
-
* Wrap a SupabaseClient with dual-write proxy.
|
|
19
|
-
* Returns the same interface — all reads go to Supabase only,
|
|
20
|
-
* all writes go to both Supabase and RuVector daemon.
|
|
21
|
-
*/
|
|
22
14
|
export declare function withDualWrite(client: SupabaseClient): SupabaseClient;
|
|
23
15
|
//# sourceMappingURL=dualWriteProxy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dualWriteProxy.d.ts","sourceRoot":"","sources":["../../src/core/dualWriteProxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"dualWriteProxy.d.ts","sourceRoot":"","sources":["../../src/core/dualWriteProxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAoM3D,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CASpE"}
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { connect } from 'node:net';
|
|
13
13
|
const SOCKET_PATH = '/tmp/stella-daemon.sock';
|
|
14
|
-
const RPC_TIMEOUT_MS = 5_000;
|
|
15
14
|
// ─── Daemon RPC (lightweight, no dependency on stella) ──────
|
|
16
15
|
let daemonSocket = null;
|
|
17
16
|
let daemonConnected = false;
|
|
@@ -28,7 +27,7 @@ function connectDaemon() {
|
|
|
28
27
|
const timeout = setTimeout(() => {
|
|
29
28
|
sock.destroy();
|
|
30
29
|
daemonConnecting = false;
|
|
31
|
-
resolve();
|
|
30
|
+
resolve();
|
|
32
31
|
}, 2000);
|
|
33
32
|
sock.on('connect', () => {
|
|
34
33
|
clearTimeout(timeout);
|
|
@@ -46,7 +45,7 @@ function connectDaemon() {
|
|
|
46
45
|
daemonConnected = false;
|
|
47
46
|
daemonSocket = null;
|
|
48
47
|
daemonConnecting = false;
|
|
49
|
-
resolve();
|
|
48
|
+
resolve();
|
|
50
49
|
});
|
|
51
50
|
});
|
|
52
51
|
}
|
|
@@ -60,155 +59,142 @@ function daemonRpc(method, params) {
|
|
|
60
59
|
daemonSocket.write(JSON.stringify({ jsonrpc: '2.0', id, method, params }) + '\n');
|
|
61
60
|
}
|
|
62
61
|
catch {
|
|
63
|
-
// Socket write failed — daemon probably died, will reconnect next time
|
|
64
62
|
daemonConnected = false;
|
|
65
63
|
daemonSocket = null;
|
|
66
64
|
}
|
|
67
65
|
}).catch(() => { });
|
|
68
66
|
}
|
|
67
|
+
// ─── Proxy ──────────────────────────────────────────────────
|
|
69
68
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
69
|
+
* Strategy: intercept .from(table) and on the returned query builder,
|
|
70
|
+
* wrap insert/update/upsert/delete so that after the Supabase call resolves
|
|
71
|
+
* we fire-and-forget the same data to the daemon.
|
|
72
|
+
*
|
|
73
|
+
* We do this by monkey-patching the write methods to attach a post-resolve
|
|
74
|
+
* side-effect. The original chain is untouched — we just read the args.
|
|
72
75
|
*/
|
|
73
76
|
function proxyQueryBuilder(original, table) {
|
|
74
77
|
return new Proxy(original, {
|
|
75
78
|
get(target, prop) {
|
|
76
79
|
const value = target[prop];
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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;
|
|
82
93
|
};
|
|
83
94
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
// But we also need to preserve the full chain (.select(), .eq(), .single(), etc.)
|
|
100
|
-
// Track filter state for update/delete
|
|
101
|
-
const filters = [];
|
|
102
|
-
return new Proxy(builder, {
|
|
103
|
-
get(target, prop) {
|
|
104
|
-
const value = target[prop];
|
|
105
|
-
// Capture filter calls for update/delete mirroring
|
|
106
|
-
if (['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'is'].includes(prop) && typeof value === 'function') {
|
|
107
|
-
return function (...filterArgs) {
|
|
108
|
-
filters.push({ column: filterArgs[0], op: prop, value: filterArgs[1] });
|
|
109
|
-
const result = value.apply(target, filterArgs);
|
|
110
|
-
return proxyWriteResult(result, table, op, args);
|
|
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;
|
|
111
110
|
};
|
|
112
111
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
mirrorToDaemon(table, op, args, filters);
|
|
120
|
-
}
|
|
121
|
-
return onFulfilled ? onFulfilled(result) : result;
|
|
122
|
-
}, onRejected);
|
|
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;
|
|
123
118
|
};
|
|
124
119
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (result && typeof result.then === 'function') {
|
|
131
|
-
return proxyWriteResult(result, table, op, args);
|
|
132
|
-
}
|
|
133
|
-
return result;
|
|
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;
|
|
134
125
|
};
|
|
135
126
|
}
|
|
127
|
+
if (typeof value === 'function')
|
|
128
|
+
return value.bind(target);
|
|
136
129
|
return value;
|
|
137
130
|
}
|
|
138
131
|
});
|
|
139
132
|
}
|
|
140
133
|
/**
|
|
141
|
-
*
|
|
134
|
+
* Attach a post-resolve side-effect to a PostgREST builder.
|
|
135
|
+
* Patches the internal fetch so we can run our callback after success.
|
|
142
136
|
*/
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const record = args[0];
|
|
158
|
-
const options = args[1];
|
|
159
|
-
if (record && !Array.isArray(record)) {
|
|
160
|
-
daemonRpc('store.upsert', {
|
|
161
|
-
table,
|
|
162
|
-
record,
|
|
163
|
-
onConflict: options?.onConflict || 'id',
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
else if (Array.isArray(record)) {
|
|
167
|
-
// Bulk upsert — send as individual upserts
|
|
168
|
-
for (const r of record) {
|
|
169
|
-
daemonRpc('store.upsert', {
|
|
170
|
-
table,
|
|
171
|
-
record: r,
|
|
172
|
-
onConflict: options?.onConflict || 'id',
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
break;
|
|
137
|
+
function attachMirror(builder, onSuccess) {
|
|
138
|
+
// PostgREST builders use .then() — they're thenables.
|
|
139
|
+
// We patch .then on the builder prototype chain to inject our callback.
|
|
140
|
+
const originalThen = builder.then;
|
|
141
|
+
if (typeof originalThen !== 'function')
|
|
142
|
+
return;
|
|
143
|
+
// We need to intercept regardless of how deep the chain goes.
|
|
144
|
+
// The trick: override .then on THIS specific instance.
|
|
145
|
+
const origProto = Object.getPrototypeOf(builder);
|
|
146
|
+
const patchedThen = function (onFulfilled, onRejected) {
|
|
147
|
+
return originalThen.call(this, (result) => {
|
|
148
|
+
// Restore original .then to avoid re-triggering
|
|
149
|
+
if (Object.getPrototypeOf(this) !== origProto) {
|
|
150
|
+
Object.setPrototypeOf(this, origProto);
|
|
177
151
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
152
|
+
// Only mirror on success
|
|
153
|
+
if (!result?.error) {
|
|
154
|
+
try {
|
|
155
|
+
onSuccess();
|
|
182
156
|
}
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
case 'delete': {
|
|
186
|
-
if (filters.length) {
|
|
187
|
-
daemonRpc('store.delete', { table, filters });
|
|
188
|
-
}
|
|
189
|
-
break;
|
|
157
|
+
catch { /* never fail */ }
|
|
190
158
|
}
|
|
159
|
+
return onFulfilled ? onFulfilled(result) : result;
|
|
160
|
+
}, onRejected);
|
|
161
|
+
};
|
|
162
|
+
// Override .then on the instance
|
|
163
|
+
builder.then = patchedThen;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* For update/delete: capture .eq() filter calls to build the daemon filter list.
|
|
167
|
+
*/
|
|
168
|
+
function attachMirrorWithFilters(builder, table, op, changes) {
|
|
169
|
+
const filters = [];
|
|
170
|
+
// Patch common filter methods to capture their args
|
|
171
|
+
for (const method of ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'is']) {
|
|
172
|
+
const orig = builder[method];
|
|
173
|
+
if (typeof orig === 'function') {
|
|
174
|
+
builder[method] = function (column, val) {
|
|
175
|
+
filters.push({ column, op: method, value: val });
|
|
176
|
+
return orig.call(this, column, val);
|
|
177
|
+
};
|
|
191
178
|
}
|
|
192
179
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
+
});
|
|
196
190
|
}
|
|
197
191
|
// ─── Public API ─────────────────────────────────────────────
|
|
198
|
-
/**
|
|
199
|
-
* Check if dual-write is enabled via environment.
|
|
200
|
-
*/
|
|
201
192
|
export function isDualWriteEnabled() {
|
|
202
193
|
if (process.env.DUAL_WRITE === '1')
|
|
203
194
|
return true;
|
|
204
195
|
const stores = process.env.STELLA_STORES || '';
|
|
205
196
|
return stores.includes('ruvector');
|
|
206
197
|
}
|
|
207
|
-
/**
|
|
208
|
-
* Wrap a SupabaseClient with dual-write proxy.
|
|
209
|
-
* Returns the same interface — all reads go to Supabase only,
|
|
210
|
-
* all writes go to both Supabase and RuVector daemon.
|
|
211
|
-
*/
|
|
212
198
|
export function withDualWrite(client) {
|
|
213
199
|
const originalFrom = client.from.bind(client);
|
|
214
200
|
client.from = function proxiedFrom(table) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dualWriteProxy.js","sourceRoot":"","sources":["../../src/core/dualWriteProxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAe,MAAM,UAAU,CAAA;AAG/C,MAAM,WAAW,GAAG,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"dualWriteProxy.js","sourceRoot":"","sources":["../../src/core/dualWriteProxy.ts"],"names":[],"mappings":"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"}
|