@omnibase/core-js 0.5.10 → 0.7.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.
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/database/index.ts
21
21
  var database_exports = {};
22
22
  __export(database_exports, {
23
+ EventsClient: () => EventsClient,
23
24
  createClient: () => createClient
24
25
  });
25
26
  module.exports = __toCommonJS(database_exports);
@@ -27,14 +28,227 @@ module.exports = __toCommonJS(database_exports);
27
28
  // src/database/client.ts
28
29
  var import_postgrest_js = require("@supabase/postgrest-js");
29
30
  var createClient = (url, anonKey, getCookie) => {
30
- const jwt = getCookie("postgrest_jwt") || anonKey;
31
+ const jwt = getCookie("omnibase_postgrest_jwt") || anonKey;
31
32
  return new import_postgrest_js.PostgrestClient(url, {
32
33
  headers: {
33
34
  Authorization: `Bearer ${jwt}`
34
35
  }
35
36
  });
36
37
  };
38
+
39
+ // src/database/events.ts
40
+ var WS = typeof globalThis !== "undefined" && globalThis.WebSocket ? globalThis.WebSocket : null;
41
+ var EventsClient = class {
42
+ url;
43
+ jwt;
44
+ subscriptions = [];
45
+ ws = null;
46
+ reconnectDelay = 1e3;
47
+ listeners = /* @__PURE__ */ new Map();
48
+ shouldReconnect = true;
49
+ /**
50
+ * Creates a new EventsClient instance
51
+ *
52
+ * @param url - WebSocket endpoint URL (e.g., 'ws://localhost:8080/api/v1/events/ws')
53
+ * @param jwt - JWT authentication token for RLS checks
54
+ */
55
+ constructor(url, jwt) {
56
+ if (!WS) {
57
+ throw new Error(
58
+ 'WebSocket is not available in this environment. Install "ws" package for Node.js.'
59
+ );
60
+ }
61
+ this.url = url;
62
+ this.jwt = jwt;
63
+ this.connect();
64
+ }
65
+ /**
66
+ * Establishes WebSocket connection with automatic reconnection
67
+ * @private
68
+ */
69
+ connect() {
70
+ if (!WS) return;
71
+ this.ws = new WS(this.url);
72
+ this.ws.onopen = () => {
73
+ console.log("\u2705 Connected to database events");
74
+ this.reconnectDelay = 1e3;
75
+ this.subscriptions.forEach((sub) => this.send(sub));
76
+ };
77
+ this.ws.onmessage = (event) => {
78
+ const data = typeof event.data === "string" ? event.data : event.data.toString();
79
+ const msg = JSON.parse(data);
80
+ this.handleMessage(msg);
81
+ };
82
+ this.ws.onerror = (error) => {
83
+ console.error("\u274C WebSocket error:", error);
84
+ };
85
+ this.ws.onclose = () => {
86
+ if (this.shouldReconnect) {
87
+ console.log(
88
+ `\u26A0\uFE0F Disconnected, reconnecting in ${this.reconnectDelay}ms`
89
+ );
90
+ setTimeout(() => this.connect(), this.reconnectDelay);
91
+ this.reconnectDelay = Math.min(this.reconnectDelay * 2, 3e4);
92
+ } else {
93
+ console.log("Disconnected from database events");
94
+ }
95
+ };
96
+ }
97
+ /**
98
+ * Subscribe to database changes for a table
99
+ *
100
+ * @param table - Table name to subscribe to
101
+ * @param options - Subscription options (rowId, columns, onChange callback)
102
+ *
103
+ * @example
104
+ * Subscribe to entire table:
105
+ * ```typescript
106
+ * client.subscribe('tasks', {
107
+ * onChange: (task) => console.log('Task changed:', task)
108
+ * });
109
+ * ```
110
+ *
111
+ * @example
112
+ * Subscribe to specific row:
113
+ * ```typescript
114
+ * client.subscribe('users', {
115
+ * rowId: 123,
116
+ * onChange: (user) => console.log('User 123 changed:', user)
117
+ * });
118
+ * ```
119
+ */
120
+ subscribe(table, options = {}) {
121
+ const { rowId, columns, onChange } = options;
122
+ const sub = {
123
+ action: "subscribe",
124
+ subscription: {
125
+ table,
126
+ ...rowId !== void 0 && { row_id: rowId },
127
+ ...columns && { columns },
128
+ jwt: this.jwt
129
+ }
130
+ };
131
+ this.subscriptions.push(sub);
132
+ if (onChange) {
133
+ const key = `${table}:${rowId ?? "*"}`;
134
+ this.listeners.set(key, onChange);
135
+ }
136
+ this.send(sub);
137
+ }
138
+ /**
139
+ * Unsubscribe from database changes
140
+ *
141
+ * @param table - Table name to unsubscribe from
142
+ * @param rowId - Optional row ID (if subscribing to specific row)
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * client.unsubscribe('tasks');
147
+ * client.unsubscribe('users', 123);
148
+ * ```
149
+ */
150
+ unsubscribe(table, rowId) {
151
+ const sub = {
152
+ action: "unsubscribe",
153
+ subscription: {
154
+ table,
155
+ ...rowId !== void 0 && { row_id: rowId },
156
+ jwt: this.jwt
157
+ }
158
+ };
159
+ this.subscriptions = this.subscriptions.filter(
160
+ (s) => !(s.subscription.table === table && s.subscription.row_id === rowId)
161
+ );
162
+ const key = `${table}:${rowId ?? "*"}`;
163
+ this.listeners.delete(key);
164
+ this.send(sub);
165
+ }
166
+ /**
167
+ * Send message to WebSocket server
168
+ * @private
169
+ */
170
+ send(data) {
171
+ if (!WS) return;
172
+ if (this.ws?.readyState === WS.OPEN || this.ws?.readyState === 1) {
173
+ this.ws.send(JSON.stringify(data));
174
+ }
175
+ }
176
+ /**
177
+ * Handle incoming WebSocket messages
178
+ * @private
179
+ */
180
+ handleMessage(msg) {
181
+ if ("type" in msg && msg.type === "update") {
182
+ const key = `${msg.table}:${msg.row_id}`;
183
+ const wildcardKey = `${msg.table}:*`;
184
+ const listener = this.listeners.get(key) || this.listeners.get(wildcardKey);
185
+ if (listener) {
186
+ listener(msg.data, msg);
187
+ }
188
+ } else if ("status" in msg) {
189
+ if (msg.status === "subscribed") {
190
+ console.log(
191
+ "\u2705 Subscribed to",
192
+ msg.table,
193
+ msg.row_id ? `(row ${msg.row_id})` : "(all rows)"
194
+ );
195
+ } else if (msg.status === "unsubscribed") {
196
+ console.log(
197
+ "Unsubscribed from",
198
+ msg.table,
199
+ msg.row_id ? `(row ${msg.row_id})` : "(all rows)"
200
+ );
201
+ } else if (msg.status === "error") {
202
+ console.error(
203
+ "\u274C Subscription error:",
204
+ msg.error,
205
+ "for table:",
206
+ msg.table
207
+ );
208
+ }
209
+ }
210
+ }
211
+ /**
212
+ * Update JWT token for authentication
213
+ *
214
+ * @param jwt - New JWT token
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * client.updateJWT(newToken);
219
+ * ```
220
+ */
221
+ updateJWT(jwt) {
222
+ this.jwt = jwt;
223
+ this.subscriptions = this.subscriptions.map((sub) => ({
224
+ ...sub,
225
+ subscription: { ...sub.subscription, jwt }
226
+ }));
227
+ }
228
+ /**
229
+ * Close WebSocket connection and prevent reconnection
230
+ *
231
+ * @example
232
+ * ```typescript
233
+ * client.close();
234
+ * ```
235
+ */
236
+ close() {
237
+ this.shouldReconnect = false;
238
+ this.ws?.close();
239
+ }
240
+ /**
241
+ * Check if WebSocket is currently connected
242
+ *
243
+ * @returns true if connected, false otherwise
244
+ */
245
+ isConnected() {
246
+ if (!WS) return false;
247
+ return this.ws?.readyState === WS.OPEN || this.ws?.readyState === 1;
248
+ }
249
+ };
37
250
  // Annotate the CommonJS export names for ESM import in node:
38
251
  0 && (module.exports = {
252
+ EventsClient,
39
253
  createClient
40
254
  });
@@ -102,4 +102,197 @@ import { PostgrestClient } from '@supabase/postgrest-js';
102
102
  */
103
103
  declare const createClient: <T = any>(url: string, anonKey: string, getCookie: (cookie: string) => string) => PostgrestClient<T>;
104
104
 
105
- export { createClient };
105
+ /**
106
+ * Real-time database events client for WebSocket subscriptions
107
+ *
108
+ * This module provides a universal WebSocket client for subscribing to real-time
109
+ * database changes with Row-Level Security (RLS) authentication. Works in both
110
+ * browser and Node.js environments.
111
+ *
112
+ * @module Database Events
113
+ */
114
+ /**
115
+ * Subscription options for database events
116
+ */
117
+ interface SubscriptionOptions {
118
+ /** Specific row ID to subscribe to (optional) */
119
+ rowId?: number;
120
+ /** Specific columns to filter updates (optional) */
121
+ columns?: string[];
122
+ /** Callback function triggered on data updates */
123
+ onChange?: (data: any, message: UpdateMessage) => void;
124
+ }
125
+ /**
126
+ * Subscription request sent to the server
127
+ */
128
+ interface Subscription {
129
+ table: string;
130
+ row_id?: number;
131
+ columns?: string[];
132
+ jwt: string;
133
+ }
134
+ /**
135
+ * Message sent from client to server
136
+ */
137
+ interface SubscriptionMessage {
138
+ action: "subscribe" | "unsubscribe";
139
+ subscription: Subscription;
140
+ }
141
+ /**
142
+ * Update message received from server
143
+ */
144
+ interface UpdateMessage {
145
+ type: "update";
146
+ table: string;
147
+ row_id: number;
148
+ data: any;
149
+ }
150
+ /**
151
+ * Status message received from server
152
+ */
153
+ interface StatusMessage {
154
+ status: "subscribed" | "unsubscribed" | "error";
155
+ table?: string;
156
+ row_id?: number;
157
+ error?: string;
158
+ }
159
+ /**
160
+ * Universal WebSocket client for real-time database events
161
+ *
162
+ * Connects to the database events WebSocket endpoint and manages subscriptions
163
+ * to table changes with automatic RLS authentication and reconnection.
164
+ *
165
+ * @example
166
+ * Basic usage:
167
+ * ```typescript
168
+ * const client = new EventsClient(
169
+ * 'ws://localhost:8080/api/v1/events/ws',
170
+ * 'your-jwt-token'
171
+ * );
172
+ *
173
+ * client.subscribe('tasks', {
174
+ * onChange: (data) => {
175
+ * console.log('Task updated:', data);
176
+ * }
177
+ * });
178
+ * ```
179
+ *
180
+ * @example
181
+ * Subscribe to specific row:
182
+ * ```typescript
183
+ * client.subscribe('users', {
184
+ * rowId: 123,
185
+ * onChange: (user) => {
186
+ * console.log('User 123 updated:', user);
187
+ * }
188
+ * });
189
+ * ```
190
+ *
191
+ * @example
192
+ * Subscribe to specific columns:
193
+ * ```typescript
194
+ * client.subscribe('posts', {
195
+ * rowId: 456,
196
+ * columns: ['title', 'content', 'status'],
197
+ * onChange: (post) => {
198
+ * console.log('Post columns updated:', post);
199
+ * }
200
+ * });
201
+ * ```
202
+ */
203
+ declare class EventsClient {
204
+ private url;
205
+ private jwt;
206
+ private subscriptions;
207
+ private ws;
208
+ private reconnectDelay;
209
+ private listeners;
210
+ private shouldReconnect;
211
+ /**
212
+ * Creates a new EventsClient instance
213
+ *
214
+ * @param url - WebSocket endpoint URL (e.g., 'ws://localhost:8080/api/v1/events/ws')
215
+ * @param jwt - JWT authentication token for RLS checks
216
+ */
217
+ constructor(url: string, jwt: string);
218
+ /**
219
+ * Establishes WebSocket connection with automatic reconnection
220
+ * @private
221
+ */
222
+ private connect;
223
+ /**
224
+ * Subscribe to database changes for a table
225
+ *
226
+ * @param table - Table name to subscribe to
227
+ * @param options - Subscription options (rowId, columns, onChange callback)
228
+ *
229
+ * @example
230
+ * Subscribe to entire table:
231
+ * ```typescript
232
+ * client.subscribe('tasks', {
233
+ * onChange: (task) => console.log('Task changed:', task)
234
+ * });
235
+ * ```
236
+ *
237
+ * @example
238
+ * Subscribe to specific row:
239
+ * ```typescript
240
+ * client.subscribe('users', {
241
+ * rowId: 123,
242
+ * onChange: (user) => console.log('User 123 changed:', user)
243
+ * });
244
+ * ```
245
+ */
246
+ subscribe(table: string, options?: SubscriptionOptions): void;
247
+ /**
248
+ * Unsubscribe from database changes
249
+ *
250
+ * @param table - Table name to unsubscribe from
251
+ * @param rowId - Optional row ID (if subscribing to specific row)
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * client.unsubscribe('tasks');
256
+ * client.unsubscribe('users', 123);
257
+ * ```
258
+ */
259
+ unsubscribe(table: string, rowId?: number): void;
260
+ /**
261
+ * Send message to WebSocket server
262
+ * @private
263
+ */
264
+ private send;
265
+ /**
266
+ * Handle incoming WebSocket messages
267
+ * @private
268
+ */
269
+ private handleMessage;
270
+ /**
271
+ * Update JWT token for authentication
272
+ *
273
+ * @param jwt - New JWT token
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * client.updateJWT(newToken);
278
+ * ```
279
+ */
280
+ updateJWT(jwt: string): void;
281
+ /**
282
+ * Close WebSocket connection and prevent reconnection
283
+ *
284
+ * @example
285
+ * ```typescript
286
+ * client.close();
287
+ * ```
288
+ */
289
+ close(): void;
290
+ /**
291
+ * Check if WebSocket is currently connected
292
+ *
293
+ * @returns true if connected, false otherwise
294
+ */
295
+ isConnected(): boolean;
296
+ }
297
+
298
+ export { EventsClient, type StatusMessage, type Subscription, type SubscriptionMessage, type SubscriptionOptions, type UpdateMessage, createClient };
@@ -102,4 +102,197 @@ import { PostgrestClient } from '@supabase/postgrest-js';
102
102
  */
103
103
  declare const createClient: <T = any>(url: string, anonKey: string, getCookie: (cookie: string) => string) => PostgrestClient<T>;
104
104
 
105
- export { createClient };
105
+ /**
106
+ * Real-time database events client for WebSocket subscriptions
107
+ *
108
+ * This module provides a universal WebSocket client for subscribing to real-time
109
+ * database changes with Row-Level Security (RLS) authentication. Works in both
110
+ * browser and Node.js environments.
111
+ *
112
+ * @module Database Events
113
+ */
114
+ /**
115
+ * Subscription options for database events
116
+ */
117
+ interface SubscriptionOptions {
118
+ /** Specific row ID to subscribe to (optional) */
119
+ rowId?: number;
120
+ /** Specific columns to filter updates (optional) */
121
+ columns?: string[];
122
+ /** Callback function triggered on data updates */
123
+ onChange?: (data: any, message: UpdateMessage) => void;
124
+ }
125
+ /**
126
+ * Subscription request sent to the server
127
+ */
128
+ interface Subscription {
129
+ table: string;
130
+ row_id?: number;
131
+ columns?: string[];
132
+ jwt: string;
133
+ }
134
+ /**
135
+ * Message sent from client to server
136
+ */
137
+ interface SubscriptionMessage {
138
+ action: "subscribe" | "unsubscribe";
139
+ subscription: Subscription;
140
+ }
141
+ /**
142
+ * Update message received from server
143
+ */
144
+ interface UpdateMessage {
145
+ type: "update";
146
+ table: string;
147
+ row_id: number;
148
+ data: any;
149
+ }
150
+ /**
151
+ * Status message received from server
152
+ */
153
+ interface StatusMessage {
154
+ status: "subscribed" | "unsubscribed" | "error";
155
+ table?: string;
156
+ row_id?: number;
157
+ error?: string;
158
+ }
159
+ /**
160
+ * Universal WebSocket client for real-time database events
161
+ *
162
+ * Connects to the database events WebSocket endpoint and manages subscriptions
163
+ * to table changes with automatic RLS authentication and reconnection.
164
+ *
165
+ * @example
166
+ * Basic usage:
167
+ * ```typescript
168
+ * const client = new EventsClient(
169
+ * 'ws://localhost:8080/api/v1/events/ws',
170
+ * 'your-jwt-token'
171
+ * );
172
+ *
173
+ * client.subscribe('tasks', {
174
+ * onChange: (data) => {
175
+ * console.log('Task updated:', data);
176
+ * }
177
+ * });
178
+ * ```
179
+ *
180
+ * @example
181
+ * Subscribe to specific row:
182
+ * ```typescript
183
+ * client.subscribe('users', {
184
+ * rowId: 123,
185
+ * onChange: (user) => {
186
+ * console.log('User 123 updated:', user);
187
+ * }
188
+ * });
189
+ * ```
190
+ *
191
+ * @example
192
+ * Subscribe to specific columns:
193
+ * ```typescript
194
+ * client.subscribe('posts', {
195
+ * rowId: 456,
196
+ * columns: ['title', 'content', 'status'],
197
+ * onChange: (post) => {
198
+ * console.log('Post columns updated:', post);
199
+ * }
200
+ * });
201
+ * ```
202
+ */
203
+ declare class EventsClient {
204
+ private url;
205
+ private jwt;
206
+ private subscriptions;
207
+ private ws;
208
+ private reconnectDelay;
209
+ private listeners;
210
+ private shouldReconnect;
211
+ /**
212
+ * Creates a new EventsClient instance
213
+ *
214
+ * @param url - WebSocket endpoint URL (e.g., 'ws://localhost:8080/api/v1/events/ws')
215
+ * @param jwt - JWT authentication token for RLS checks
216
+ */
217
+ constructor(url: string, jwt: string);
218
+ /**
219
+ * Establishes WebSocket connection with automatic reconnection
220
+ * @private
221
+ */
222
+ private connect;
223
+ /**
224
+ * Subscribe to database changes for a table
225
+ *
226
+ * @param table - Table name to subscribe to
227
+ * @param options - Subscription options (rowId, columns, onChange callback)
228
+ *
229
+ * @example
230
+ * Subscribe to entire table:
231
+ * ```typescript
232
+ * client.subscribe('tasks', {
233
+ * onChange: (task) => console.log('Task changed:', task)
234
+ * });
235
+ * ```
236
+ *
237
+ * @example
238
+ * Subscribe to specific row:
239
+ * ```typescript
240
+ * client.subscribe('users', {
241
+ * rowId: 123,
242
+ * onChange: (user) => console.log('User 123 changed:', user)
243
+ * });
244
+ * ```
245
+ */
246
+ subscribe(table: string, options?: SubscriptionOptions): void;
247
+ /**
248
+ * Unsubscribe from database changes
249
+ *
250
+ * @param table - Table name to unsubscribe from
251
+ * @param rowId - Optional row ID (if subscribing to specific row)
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * client.unsubscribe('tasks');
256
+ * client.unsubscribe('users', 123);
257
+ * ```
258
+ */
259
+ unsubscribe(table: string, rowId?: number): void;
260
+ /**
261
+ * Send message to WebSocket server
262
+ * @private
263
+ */
264
+ private send;
265
+ /**
266
+ * Handle incoming WebSocket messages
267
+ * @private
268
+ */
269
+ private handleMessage;
270
+ /**
271
+ * Update JWT token for authentication
272
+ *
273
+ * @param jwt - New JWT token
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * client.updateJWT(newToken);
278
+ * ```
279
+ */
280
+ updateJWT(jwt: string): void;
281
+ /**
282
+ * Close WebSocket connection and prevent reconnection
283
+ *
284
+ * @example
285
+ * ```typescript
286
+ * client.close();
287
+ * ```
288
+ */
289
+ close(): void;
290
+ /**
291
+ * Check if WebSocket is currently connected
292
+ *
293
+ * @returns true if connected, false otherwise
294
+ */
295
+ isConnected(): boolean;
296
+ }
297
+
298
+ export { EventsClient, type StatusMessage, type Subscription, type SubscriptionMessage, type SubscriptionOptions, type UpdateMessage, createClient };