@agelum/backend 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/README.md +401 -0
- package/dist/client/hooks.d.ts +65 -0
- package/dist/client/hooks.d.ts.map +1 -0
- package/dist/client/hooks.js +339 -0
- package/dist/client/hooks.js.map +1 -0
- package/dist/client/index.d.ts +10 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +37 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/manager.d.ts +137 -0
- package/dist/client/manager.d.ts.map +1 -0
- package/dist/client/manager.js +292 -0
- package/dist/client/manager.js.map +1 -0
- package/dist/client/provider.d.ts +25 -0
- package/dist/client/provider.d.ts.map +1 -0
- package/dist/client/provider.js +121 -0
- package/dist/client/provider.js.map +1 -0
- package/dist/client/revalidation.d.ts +101 -0
- package/dist/client/revalidation.d.ts.map +1 -0
- package/dist/client/revalidation.js +313 -0
- package/dist/client/revalidation.js.map +1 -0
- package/dist/client/session.d.ts +84 -0
- package/dist/client/session.d.ts.map +1 -0
- package/dist/client/session.js +186 -0
- package/dist/client/session.js.map +1 -0
- package/dist/client/sse-client.d.ts +81 -0
- package/dist/client/sse-client.d.ts.map +1 -0
- package/dist/client/sse-client.js +221 -0
- package/dist/client/sse-client.js.map +1 -0
- package/dist/client/storage.d.ts +124 -0
- package/dist/client/storage.d.ts.map +1 -0
- package/dist/client/storage.js +441 -0
- package/dist/client/storage.js.map +1 -0
- package/dist/client/trpc.d.ts +12 -0
- package/dist/client/trpc.d.ts.map +1 -0
- package/dist/client/trpc.js +36 -0
- package/dist/client/trpc.js.map +1 -0
- package/dist/client/types.d.ts +10 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +3 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +26 -0
- package/dist/client.js.map +1 -0
- package/dist/config/schema.d.ts +261 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +69 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/analyzer.d.ts +15 -0
- package/dist/core/analyzer.d.ts.map +1 -0
- package/dist/core/analyzer.js +217 -0
- package/dist/core/analyzer.js.map +1 -0
- package/dist/core/driver.d.ts +7 -0
- package/dist/core/driver.d.ts.map +1 -0
- package/dist/core/driver.js +261 -0
- package/dist/core/driver.js.map +1 -0
- package/dist/core/function.d.ts +97 -0
- package/dist/core/function.d.ts.map +1 -0
- package/dist/core/function.js +252 -0
- package/dist/core/function.js.map +1 -0
- package/dist/core/sse.d.ts +98 -0
- package/dist/core/sse.d.ts.map +1 -0
- package/dist/core/sse.js +331 -0
- package/dist/core/sse.js.map +1 -0
- package/dist/core/types.d.ts +179 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -0
- package/dist/examples/teamhub-integration.d.ts +56 -0
- package/dist/examples/teamhub-integration.d.ts.map +1 -0
- package/dist/examples/teamhub-integration.js +188 -0
- package/dist/examples/teamhub-integration.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/localStorage.d.ts +13 -0
- package/dist/providers/localStorage.d.ts.map +1 -0
- package/dist/providers/localStorage.js +64 -0
- package/dist/providers/localStorage.js.map +1 -0
- package/dist/providers/memory.d.ts +13 -0
- package/dist/providers/memory.d.ts.map +1 -0
- package/dist/providers/memory.js +40 -0
- package/dist/providers/memory.js.map +1 -0
- package/dist/providers/redis.d.ts +14 -0
- package/dist/providers/redis.d.ts.map +1 -0
- package/dist/providers/redis.js +36 -0
- package/dist/providers/redis.js.map +1 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +34 -0
- package/dist/server.js.map +1 -0
- package/dist/trpc/hooks.d.ts +82 -0
- package/dist/trpc/hooks.d.ts.map +1 -0
- package/dist/trpc/hooks.js +282 -0
- package/dist/trpc/hooks.js.map +1 -0
- package/dist/trpc/router.d.ts +75 -0
- package/dist/trpc/router.d.ts.map +1 -0
- package/dist/trpc/router.js +160 -0
- package/dist/trpc/router.js.map +1 -0
- package/dist/trpc/types.d.ts +105 -0
- package/dist/trpc/types.d.ts.map +1 -0
- package/dist/trpc/types.js +6 -0
- package/dist/trpc/types.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side SSE client for real-time cache invalidation
|
|
3
|
+
* NO HEARTBEATS - relies on event acknowledgments and connection health
|
|
4
|
+
*/
|
|
5
|
+
import type { InvalidationEvent } from '../core/types';
|
|
6
|
+
export interface SSEClientOptions {
|
|
7
|
+
url: string;
|
|
8
|
+
onInvalidation: (event: InvalidationEvent) => void;
|
|
9
|
+
onError: (error: Error) => void;
|
|
10
|
+
onReconnect?: () => void;
|
|
11
|
+
maxReconnectAttempts?: number;
|
|
12
|
+
reconnectDelay?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface SSEClientStats {
|
|
15
|
+
connectionAttempts: number;
|
|
16
|
+
successfulConnections: number;
|
|
17
|
+
failedConnections: number;
|
|
18
|
+
reconnectAttempts: number;
|
|
19
|
+
eventsReceived: number;
|
|
20
|
+
eventsAcknowledged: number;
|
|
21
|
+
lastEventTime: number;
|
|
22
|
+
connectionStartTime?: number;
|
|
23
|
+
totalUptime: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* SSE Client for real-time cache invalidation
|
|
27
|
+
* Uses event acknowledgments instead of heartbeats for reliability
|
|
28
|
+
*/
|
|
29
|
+
export declare class SSEClient {
|
|
30
|
+
private eventSource;
|
|
31
|
+
private reconnectTimer;
|
|
32
|
+
private isIntentionallyClosed;
|
|
33
|
+
private stats;
|
|
34
|
+
private options;
|
|
35
|
+
constructor(options: SSEClientOptions);
|
|
36
|
+
/**
|
|
37
|
+
* Connect to SSE stream
|
|
38
|
+
*/
|
|
39
|
+
connect(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Disconnect from SSE stream
|
|
42
|
+
*/
|
|
43
|
+
disconnect(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Handle incoming SSE messages
|
|
46
|
+
*/
|
|
47
|
+
private handleMessage;
|
|
48
|
+
/**
|
|
49
|
+
* Handle invalidation events
|
|
50
|
+
*/
|
|
51
|
+
private handleInvalidationEvent;
|
|
52
|
+
/**
|
|
53
|
+
* Send event acknowledgment to server
|
|
54
|
+
*/
|
|
55
|
+
private acknowledgeEvent;
|
|
56
|
+
/**
|
|
57
|
+
* Schedule reconnection attempt
|
|
58
|
+
*/
|
|
59
|
+
private scheduleReconnect;
|
|
60
|
+
/**
|
|
61
|
+
* Handle connection errors and schedule reconnection
|
|
62
|
+
*/
|
|
63
|
+
private handleConnectionError;
|
|
64
|
+
/**
|
|
65
|
+
* Clear reconnection timer
|
|
66
|
+
*/
|
|
67
|
+
private clearReconnectTimer;
|
|
68
|
+
/**
|
|
69
|
+
* Get connection statistics
|
|
70
|
+
*/
|
|
71
|
+
getStats(): SSEClientStats;
|
|
72
|
+
/**
|
|
73
|
+
* Check if currently connected
|
|
74
|
+
*/
|
|
75
|
+
isConnected(): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Get connection state
|
|
78
|
+
*/
|
|
79
|
+
getConnectionState(): 'connecting' | 'open' | 'closed';
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=sse-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-client.d.ts","sourceRoot":"","sources":["../../src/client/sse-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEtD,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,cAAc,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAClD,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;CAExB;AAED,MAAM,WAAW,cAAc;IAC7B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,cAAc,EAAE,MAAM,CAAA;IACtB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,qBAAqB,CAAQ;IACrC,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,OAAO,CAA4B;gBAE/B,OAAO,EAAE,gBAAgB;IAoBrC;;OAEG;IACH,OAAO,IAAI,IAAI;IAgCf;;OAEG;IACH,UAAU,IAAI,IAAI;IAkBlB;;OAEG;IACH,OAAO,CAAC,aAAa;IA8BrB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;OAEG;YACW,gBAAgB;IAsB9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA8BzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgB7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,QAAQ,IAAI,cAAc;IAI1B;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,kBAAkB,IAAI,YAAY,GAAG,MAAM,GAAG,QAAQ;CAcvD"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Client-side SSE client for real-time cache invalidation
|
|
4
|
+
* NO HEARTBEATS - relies on event acknowledgments and connection health
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SSEClient = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* SSE Client for real-time cache invalidation
|
|
10
|
+
* Uses event acknowledgments instead of heartbeats for reliability
|
|
11
|
+
*/
|
|
12
|
+
class SSEClient {
|
|
13
|
+
eventSource = null;
|
|
14
|
+
reconnectTimer = null;
|
|
15
|
+
isIntentionallyClosed = false;
|
|
16
|
+
stats;
|
|
17
|
+
options;
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.options = {
|
|
20
|
+
maxReconnectAttempts: 5,
|
|
21
|
+
reconnectDelay: 1000,
|
|
22
|
+
onReconnect: () => { },
|
|
23
|
+
...options,
|
|
24
|
+
};
|
|
25
|
+
this.stats = {
|
|
26
|
+
connectionAttempts: 0,
|
|
27
|
+
successfulConnections: 0,
|
|
28
|
+
failedConnections: 0,
|
|
29
|
+
reconnectAttempts: 0,
|
|
30
|
+
eventsReceived: 0,
|
|
31
|
+
eventsAcknowledged: 0,
|
|
32
|
+
lastEventTime: 0,
|
|
33
|
+
totalUptime: 0,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Connect to SSE stream
|
|
38
|
+
*/
|
|
39
|
+
connect() {
|
|
40
|
+
if (this.eventSource) {
|
|
41
|
+
this.disconnect();
|
|
42
|
+
}
|
|
43
|
+
this.stats.connectionAttempts++;
|
|
44
|
+
this.stats.connectionStartTime = Date.now();
|
|
45
|
+
try {
|
|
46
|
+
this.eventSource = new EventSource(this.options.url);
|
|
47
|
+
this.eventSource.onopen = () => {
|
|
48
|
+
this.stats.successfulConnections++;
|
|
49
|
+
console.log('[SSEClient] Connection opened');
|
|
50
|
+
};
|
|
51
|
+
this.eventSource.onmessage = (event) => {
|
|
52
|
+
this.handleMessage(event);
|
|
53
|
+
};
|
|
54
|
+
this.eventSource.onerror = (error) => {
|
|
55
|
+
this.stats.failedConnections++;
|
|
56
|
+
console.warn('[SSEClient] Connection error:', error);
|
|
57
|
+
this.handleConnectionError();
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
this.stats.failedConnections++;
|
|
62
|
+
console.error('[SSEClient] Failed to create connection:', error);
|
|
63
|
+
this.handleConnectionError();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Disconnect from SSE stream
|
|
68
|
+
*/
|
|
69
|
+
disconnect() {
|
|
70
|
+
this.isIntentionallyClosed = true;
|
|
71
|
+
this.clearReconnectTimer();
|
|
72
|
+
if (this.eventSource) {
|
|
73
|
+
this.eventSource.close();
|
|
74
|
+
this.eventSource = null;
|
|
75
|
+
}
|
|
76
|
+
// Update uptime stats
|
|
77
|
+
if (this.stats.connectionStartTime) {
|
|
78
|
+
this.stats.totalUptime += Date.now() - this.stats.connectionStartTime;
|
|
79
|
+
this.stats.connectionStartTime = undefined;
|
|
80
|
+
}
|
|
81
|
+
console.log('[SSEClient] Connection closed');
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Handle incoming SSE messages
|
|
85
|
+
*/
|
|
86
|
+
handleMessage(event) {
|
|
87
|
+
this.stats.lastEventTime = Date.now();
|
|
88
|
+
this.stats.eventsReceived++;
|
|
89
|
+
try {
|
|
90
|
+
const data = JSON.parse(event.data);
|
|
91
|
+
switch (data.type) {
|
|
92
|
+
case 'connected':
|
|
93
|
+
console.log('[SSEClient] Connection confirmed');
|
|
94
|
+
break;
|
|
95
|
+
// Removed heartbeat case - no heartbeats sent by server
|
|
96
|
+
case 'invalidation':
|
|
97
|
+
console.log(`[SSEClient] Invalidation received for table: ${data.table}`);
|
|
98
|
+
this.handleInvalidationEvent(data);
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
console.log('[SSEClient] Unknown event type:', data.type);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
console.warn('[SSEClient] Failed to parse event data:', error);
|
|
106
|
+
this.options.onError(error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Handle invalidation events
|
|
111
|
+
*/
|
|
112
|
+
handleInvalidationEvent(event) {
|
|
113
|
+
// Notify the invalidation handler
|
|
114
|
+
this.options.onInvalidation(event);
|
|
115
|
+
// Send acknowledgment if required
|
|
116
|
+
if (event.requiresAck && event.eventId) {
|
|
117
|
+
this.acknowledgeEvent(event.eventId);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Send event acknowledgment to server
|
|
122
|
+
*/
|
|
123
|
+
async acknowledgeEvent(eventId) {
|
|
124
|
+
try {
|
|
125
|
+
const response = await fetch('/api/events/ack', {
|
|
126
|
+
method: 'POST',
|
|
127
|
+
headers: {
|
|
128
|
+
'Content-Type': 'application/json',
|
|
129
|
+
},
|
|
130
|
+
body: JSON.stringify({ eventId }),
|
|
131
|
+
});
|
|
132
|
+
if (response.ok) {
|
|
133
|
+
this.stats.eventsAcknowledged++;
|
|
134
|
+
console.log(`[SSEClient] Event acknowledged: ${eventId}`);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
console.warn(`[SSEClient] Failed to acknowledge event: ${eventId}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.warn(`[SSEClient] Acknowledgment failed: ${eventId}`, error);
|
|
142
|
+
// Silent fail - server will retry if needed
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Schedule reconnection attempt
|
|
147
|
+
*/
|
|
148
|
+
scheduleReconnect() {
|
|
149
|
+
if (this.isIntentionallyClosed)
|
|
150
|
+
return;
|
|
151
|
+
if (this.stats.reconnectAttempts >= this.options.maxReconnectAttempts) {
|
|
152
|
+
console.error(`[SSEClient] Max reconnect attempts (${this.options.maxReconnectAttempts}) reached`);
|
|
153
|
+
this.options.onError(new Error('Max reconnection attempts exceeded'));
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
this.clearReconnectTimer();
|
|
157
|
+
const delay = Math.min(this.options.reconnectDelay * Math.pow(2, this.stats.reconnectAttempts), 30000 // Max 30 seconds
|
|
158
|
+
);
|
|
159
|
+
console.log(`[SSEClient] Scheduling reconnect in ${delay}ms (attempt ${this.stats.reconnectAttempts + 1})`);
|
|
160
|
+
this.reconnectTimer = setTimeout(() => {
|
|
161
|
+
this.stats.reconnectAttempts++;
|
|
162
|
+
this.connect();
|
|
163
|
+
}, delay);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Handle connection errors and schedule reconnection
|
|
167
|
+
*/
|
|
168
|
+
handleConnectionError() {
|
|
169
|
+
if (this.eventSource) {
|
|
170
|
+
this.eventSource.close();
|
|
171
|
+
this.eventSource = null;
|
|
172
|
+
}
|
|
173
|
+
// Update uptime stats
|
|
174
|
+
if (this.stats.connectionStartTime) {
|
|
175
|
+
this.stats.totalUptime += Date.now() - this.stats.connectionStartTime;
|
|
176
|
+
this.stats.connectionStartTime = undefined;
|
|
177
|
+
}
|
|
178
|
+
// Schedule reconnection
|
|
179
|
+
this.scheduleReconnect();
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Clear reconnection timer
|
|
183
|
+
*/
|
|
184
|
+
clearReconnectTimer() {
|
|
185
|
+
if (this.reconnectTimer) {
|
|
186
|
+
clearTimeout(this.reconnectTimer);
|
|
187
|
+
this.reconnectTimer = null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get connection statistics
|
|
192
|
+
*/
|
|
193
|
+
getStats() {
|
|
194
|
+
return { ...this.stats };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Check if currently connected
|
|
198
|
+
*/
|
|
199
|
+
isConnected() {
|
|
200
|
+
return this.eventSource?.readyState === EventSource.OPEN;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Get connection state
|
|
204
|
+
*/
|
|
205
|
+
getConnectionState() {
|
|
206
|
+
if (!this.eventSource)
|
|
207
|
+
return 'closed';
|
|
208
|
+
switch (this.eventSource.readyState) {
|
|
209
|
+
case EventSource.CONNECTING:
|
|
210
|
+
return 'connecting';
|
|
211
|
+
case EventSource.OPEN:
|
|
212
|
+
return 'open';
|
|
213
|
+
case EventSource.CLOSED:
|
|
214
|
+
return 'closed';
|
|
215
|
+
default:
|
|
216
|
+
return 'closed';
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
exports.SSEClient = SSEClient;
|
|
221
|
+
//# sourceMappingURL=sse-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-client.js","sourceRoot":"","sources":["../../src/client/sse-client.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA0BH;;;GAGG;AACH,MAAa,SAAS;IACZ,WAAW,GAAuB,IAAI,CAAA;IACtC,cAAc,GAA0B,IAAI,CAAA;IAC5C,qBAAqB,GAAG,KAAK,CAAA;IAC7B,KAAK,CAAgB;IACrB,OAAO,CAA4B;IAE3C,YAAY,OAAyB;QACnC,IAAI,CAAC,OAAO,GAAG;YACb,oBAAoB,EAAE,CAAC;YACvB,cAAc,EAAE,IAAI;YACpB,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;YACrB,GAAG,OAAO;SACX,CAAA;QAED,IAAI,CAAC,KAAK,GAAG;YACX,kBAAkB,EAAE,CAAC;YACrB,qBAAqB,EAAE,CAAC;YACxB,iBAAiB,EAAE,CAAC;YACpB,iBAAiB,EAAE,CAAC;YACpB,cAAc,EAAE,CAAC;YACjB,kBAAkB,EAAE,CAAC;YACrB,aAAa,EAAE,CAAC;YAChB,WAAW,EAAE,CAAC;SACf,CAAA;IACH,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,UAAU,EAAE,CAAA;QACnB,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAA;QAC/B,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAE3C,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAEpD,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,GAAG,EAAE;gBAC7B,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAA;gBAClC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;YAC9C,CAAC,CAAA;YAED,IAAI,CAAC,WAAW,CAAC,SAAS,GAAG,CAAC,KAAK,EAAE,EAAE;gBACrC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;YAC3B,CAAC,CAAA;YAED,IAAI,CAAC,WAAW,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;gBACnC,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAA;gBAC9B,OAAO,CAAC,IAAI,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAA;gBACpD,IAAI,CAAC,qBAAqB,EAAE,CAAA;YAC9B,CAAC,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAA;YAC9B,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAA;YAChE,IAAI,CAAC,qBAAqB,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAA;QACjC,IAAI,CAAC,mBAAmB,EAAE,CAAA;QAE1B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAA;YACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACzB,CAAC;QAED,sBAAsB;QACtB,IAAI,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;YACnC,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAA;YACrE,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,SAAS,CAAA;QAC5C,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;IAC9C,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,KAAmB;QACvC,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACrC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;QAE3B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAEnC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClB,KAAK,WAAW;oBACd,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAA;oBAC/C,MAAK;gBAEP,wDAAwD;gBAExD,KAAK,cAAc;oBACjB,OAAO,CAAC,GAAG,CACT,gDAAgD,IAAI,CAAC,KAAK,EAAE,CAC7D,CAAA;oBACD,IAAI,CAAC,uBAAuB,CAAC,IAAyB,CAAC,CAAA;oBACvD,MAAK;gBAEP;oBACE,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YAC7D,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAA;YAC9D,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAc,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,uBAAuB,CAAC,KAAwB;QACtD,kCAAkC;QAClC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;QAElC,kCAAkC;QAClC,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACvC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB,CAAC,OAAe;QAC5C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,iBAAiB,EAAE;gBAC9C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;aAClC,CAAC,CAAA;YAEF,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAChB,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAA;gBAC/B,OAAO,CAAC,GAAG,CAAC,mCAAmC,OAAO,EAAE,CAAC,CAAA;YAC3D,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,4CAA4C,OAAO,EAAE,CAAC,CAAA;YACrE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,sCAAsC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAA;YACpE,4CAA4C;QAC9C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,IAAI,IAAI,CAAC,qBAAqB;YAAE,OAAM;QAEtC,IAAI,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;YACtE,OAAO,CAAC,KAAK,CACX,uCAAuC,IAAI,CAAC,OAAO,CAAC,oBAAoB,WAAW,CACpF,CAAA;YACD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAA;YACrE,OAAM;QACR,CAAC;QAED,IAAI,CAAC,mBAAmB,EAAE,CAAA;QAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,IAAI,CAAC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,EACvE,KAAK,CAAC,iBAAiB;SACxB,CAAA;QAED,OAAO,CAAC,GAAG,CACT,uCAAuC,KAAK,eAC1C,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,CACjC,GAAG,CACJ,CAAA;QAED,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAA;YAC9B,IAAI,CAAC,OAAO,EAAE,CAAA;QAChB,CAAC,EAAE,KAAK,CAAC,CAAA;IACX,CAAC;IAED;;OAEG;IACK,qBAAqB;QAC3B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAA;YACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACzB,CAAC;QAED,sBAAsB;QACtB,IAAI,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;YACnC,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAA;YACrE,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,SAAS,CAAA;QAC5C,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,iBAAiB,EAAE,CAAA;IAC1B,CAAC;IAED;;OAEG;IACK,mBAAmB;QACzB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YACjC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAA;QAC5B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;IAC1B,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,WAAW,EAAE,UAAU,KAAK,WAAW,CAAC,IAAI,CAAA;IAC1D,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,QAAQ,CAAA;QAEtC,QAAQ,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;YACpC,KAAK,WAAW,CAAC,UAAU;gBACzB,OAAO,YAAY,CAAA;YACrB,KAAK,WAAW,CAAC,IAAI;gBACnB,OAAO,MAAM,CAAA;YACf,KAAK,WAAW,CAAC,MAAM;gBACrB,OAAO,QAAQ,CAAA;YACjB;gBACE,OAAO,QAAQ,CAAA;QACnB,CAAC;IACH,CAAC;CACF;AAvPD,8BAuPC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side storage management for reactive queries
|
|
3
|
+
* Handles localStorage-based query registry and session persistence
|
|
4
|
+
*/
|
|
5
|
+
import type { QueryRegistry, HookState } from '../core/types';
|
|
6
|
+
export declare class ReactiveStorage {
|
|
7
|
+
private storageKey;
|
|
8
|
+
private indexKey;
|
|
9
|
+
private activeHooks;
|
|
10
|
+
private sessionId;
|
|
11
|
+
private organizationId;
|
|
12
|
+
constructor(organizationId: string);
|
|
13
|
+
/** Derive the per-org index key */
|
|
14
|
+
private getIndexKey;
|
|
15
|
+
/** Derive per-query entry key */
|
|
16
|
+
private getEntryKey;
|
|
17
|
+
/** Simple 32-bit hash for stable short keys */
|
|
18
|
+
private hash;
|
|
19
|
+
/**
|
|
20
|
+
* Initialize the query registry for this organization
|
|
21
|
+
*/
|
|
22
|
+
private initializeRegistry;
|
|
23
|
+
/**
|
|
24
|
+
* Get the current query registry
|
|
25
|
+
*/
|
|
26
|
+
getRegistry(): QueryRegistry | null;
|
|
27
|
+
/**
|
|
28
|
+
* Save the query registry to localStorage
|
|
29
|
+
*/
|
|
30
|
+
private saveRegistry;
|
|
31
|
+
/**
|
|
32
|
+
* Register a query execution
|
|
33
|
+
*/
|
|
34
|
+
registerQuery(queryKey: string, dependencies: string[], data?: any, ttl?: number): void;
|
|
35
|
+
/**
|
|
36
|
+
* Mark a query as stale (needs revalidation)
|
|
37
|
+
*/
|
|
38
|
+
invalidateQuery(queryKey: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Mark a query as stale for testing (simulates server-side changes)
|
|
41
|
+
*/
|
|
42
|
+
markQueryStaleForTesting(queryKey: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Invalidate queries based on table changes
|
|
45
|
+
*/
|
|
46
|
+
invalidateByTable(table: string, relations: Record<string, string[]>): void;
|
|
47
|
+
/**
|
|
48
|
+
* Get cached data for a query
|
|
49
|
+
*/
|
|
50
|
+
getCachedData(queryKey: string): {
|
|
51
|
+
data: any;
|
|
52
|
+
isStale: boolean;
|
|
53
|
+
lastRevalidated: number;
|
|
54
|
+
} | null;
|
|
55
|
+
/**
|
|
56
|
+
* Detect session gaps and queries that need revalidation
|
|
57
|
+
*/
|
|
58
|
+
detectSessionGap(): {
|
|
59
|
+
hasGap: boolean;
|
|
60
|
+
gapDuration: number;
|
|
61
|
+
staleQueries: string[];
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Register an active hook for priority revalidation
|
|
65
|
+
*/
|
|
66
|
+
registerActiveHook(queryKey: string, dependencies: string[], organizationId?: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* Unregister an active hook
|
|
69
|
+
*/
|
|
70
|
+
unregisterActiveHook(queryKey: string): void;
|
|
71
|
+
/**
|
|
72
|
+
* Get active hooks for priority revalidation
|
|
73
|
+
*/
|
|
74
|
+
getActiveHooks(): HookState[];
|
|
75
|
+
/**
|
|
76
|
+
* Get active hooks sorted by priority (most recent access first)
|
|
77
|
+
*/
|
|
78
|
+
getActiveHooksByPriority(): HookState[];
|
|
79
|
+
/**
|
|
80
|
+
* Update real-time connection status
|
|
81
|
+
*/
|
|
82
|
+
updateRealtimeStatus(connected: boolean): void;
|
|
83
|
+
/**
|
|
84
|
+
* Get queries that should be revalidated first (active hooks)
|
|
85
|
+
*/
|
|
86
|
+
getPriorityQueries(): string[];
|
|
87
|
+
/**
|
|
88
|
+
* Get background queries that can be revalidated later
|
|
89
|
+
*/
|
|
90
|
+
getBackgroundQueries(): string[];
|
|
91
|
+
/**
|
|
92
|
+
* Clean up expired entries to free up localStorage space
|
|
93
|
+
*/
|
|
94
|
+
private cleanupExpiredEntries;
|
|
95
|
+
/**
|
|
96
|
+
* Clean up old entries when localStorage is full
|
|
97
|
+
*/
|
|
98
|
+
private cleanupOldEntries;
|
|
99
|
+
/**
|
|
100
|
+
* Generate a unique session ID
|
|
101
|
+
*/
|
|
102
|
+
private generateSessionId;
|
|
103
|
+
/**
|
|
104
|
+
* Get session information
|
|
105
|
+
*/
|
|
106
|
+
getSessionInfo(): {
|
|
107
|
+
startTime: number;
|
|
108
|
+
lastSync: number;
|
|
109
|
+
realtimeConnected: boolean;
|
|
110
|
+
} | null;
|
|
111
|
+
/**
|
|
112
|
+
* Clear all stored data for this organization
|
|
113
|
+
*/
|
|
114
|
+
clearRegistry(): void;
|
|
115
|
+
/**
|
|
116
|
+
* Export registry for debugging
|
|
117
|
+
*/
|
|
118
|
+
exportRegistry(): QueryRegistry | null;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create a storage instance for an organization
|
|
122
|
+
*/
|
|
123
|
+
export declare function createReactiveStorage(organizationId: string): ReactiveStorage;
|
|
124
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/client/storage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE7D,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,cAAc,CAAQ;gBAElB,cAAc,EAAE,MAAM;IAQlC,mCAAmC;IACnC,OAAO,CAAC,WAAW;IAInB,iCAAiC;IACjC,OAAO,CAAC,WAAW;IAInB,+CAA+C;IAC/C,OAAO,CAAC,IAAI;IASZ;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAsB1B;;OAEG;IACH,WAAW,IAAI,aAAa,GAAG,IAAI;IAmBnC;;OAEG;IACH,OAAO,CAAC,YAAY;IAuBpB;;OAEG;IACH,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EAAE,EACtB,IAAI,CAAC,EAAE,GAAG,EACV,GAAG,CAAC,EAAE,MAAM,GACX,IAAI;IA+DP;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAiBvC;;OAEG;IACH,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAiBhD;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI;IA6B3E;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG;QAC/B,IAAI,EAAE,GAAG,CAAA;QACT,OAAO,EAAE,OAAO,CAAA;QAChB,eAAe,EAAE,MAAM,CAAA;KACxB,GAAG,IAAI;IAgDR;;OAEG;IACH,gBAAgB,IAAI;QAClB,MAAM,EAAE,OAAO,CAAA;QACf,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,EAAE,CAAA;KACvB;IAgCD;;OAEG;IACH,kBAAkB,CAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EAAE,EACtB,cAAc,CAAC,EAAE,MAAM,GACtB,IAAI;IAUP;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI5C;;OAEG;IACH,cAAc,IAAI,SAAS,EAAE;IAI7B;;OAEG;IACH,wBAAwB,IAAI,SAAS,EAAE;IAIvC;;OAEG;IACH,oBAAoB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAS9C;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAK9B;;OAEG;IACH,oBAAoB,IAAI,MAAM,EAAE;IAUhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAqB7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA4BzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,cAAc;;;;;IAKd;;OAEG;IACH,aAAa,IAAI,IAAI;IAwBrB;;OAEG;IACH,cAAc,IAAI,aAAa,GAAG,IAAI;CAGvC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,eAAe,CAE7E"}
|