@fluxbase/sdk 2026.1.7 → 2026.1.9-rc.1
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/dist/index.cjs +237 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +252 -4
- package/dist/index.d.ts +252 -4
- package/dist/index.js +237 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1428,8 +1428,9 @@ var RealtimeChannel = class {
|
|
|
1428
1428
|
this.presenceCallbacks = /* @__PURE__ */ new Map();
|
|
1429
1429
|
this.broadcastCallbacks = /* @__PURE__ */ new Map();
|
|
1430
1430
|
this.executionLogCallbacks = /* @__PURE__ */ new Set();
|
|
1431
|
-
this.
|
|
1432
|
-
this.
|
|
1431
|
+
this.subscriptionConfigs = [];
|
|
1432
|
+
this.subscriptionIds = /* @__PURE__ */ new Map();
|
|
1433
|
+
// "schema.table" -> subscription_id
|
|
1433
1434
|
this.executionLogConfig = null;
|
|
1434
1435
|
this._presenceState = {};
|
|
1435
1436
|
this.myPresenceKey = null;
|
|
@@ -1458,13 +1459,15 @@ var RealtimeChannel = class {
|
|
|
1458
1459
|
on(event, configOrCallback, callback) {
|
|
1459
1460
|
if (event === "postgres_changes" && typeof configOrCallback !== "function") {
|
|
1460
1461
|
const config = configOrCallback;
|
|
1461
|
-
this.subscriptionConfig = config;
|
|
1462
1462
|
const actualCallback = callback;
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1463
|
+
let entry = this.subscriptionConfigs.find(
|
|
1464
|
+
(e) => e.config.schema === config.schema && e.config.table === config.table && e.config.event === config.event && e.config.filter === config.filter
|
|
1465
|
+
);
|
|
1466
|
+
if (!entry) {
|
|
1467
|
+
entry = { config, callbacks: /* @__PURE__ */ new Set() };
|
|
1468
|
+
this.subscriptionConfigs.push(entry);
|
|
1466
1469
|
}
|
|
1467
|
-
|
|
1470
|
+
entry.callbacks.add(actualCallback);
|
|
1468
1471
|
} else if (event === "broadcast" && typeof configOrCallback !== "function") {
|
|
1469
1472
|
const config = configOrCallback;
|
|
1470
1473
|
const actualCallback = callback;
|
|
@@ -1535,11 +1538,20 @@ var RealtimeChannel = class {
|
|
|
1535
1538
|
this.shouldReconnect = false;
|
|
1536
1539
|
return new Promise((resolve) => {
|
|
1537
1540
|
if (this.ws) {
|
|
1538
|
-
this.
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1541
|
+
if (this.subscriptionIds.size > 0) {
|
|
1542
|
+
for (const subId of this.subscriptionIds.values()) {
|
|
1543
|
+
this.sendMessage({
|
|
1544
|
+
type: "unsubscribe",
|
|
1545
|
+
channel: this.channelName,
|
|
1546
|
+
subscription_id: subId
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1549
|
+
} else {
|
|
1550
|
+
this.sendMessage({
|
|
1551
|
+
type: "unsubscribe",
|
|
1552
|
+
channel: this.channelName
|
|
1553
|
+
});
|
|
1554
|
+
}
|
|
1543
1555
|
const startTime = Date.now();
|
|
1544
1556
|
const maxWait = timeout || 5e3;
|
|
1545
1557
|
const checkDisconnect = () => {
|
|
@@ -1774,14 +1786,20 @@ var RealtimeChannel = class {
|
|
|
1774
1786
|
}
|
|
1775
1787
|
};
|
|
1776
1788
|
this.sendMessage(logSubscribeMessage);
|
|
1789
|
+
} else if (this.subscriptionConfigs.length > 0) {
|
|
1790
|
+
for (const entry of this.subscriptionConfigs) {
|
|
1791
|
+
const subscribeMessage = {
|
|
1792
|
+
type: "subscribe",
|
|
1793
|
+
channel: this.channelName,
|
|
1794
|
+
config: entry.config
|
|
1795
|
+
};
|
|
1796
|
+
this.sendMessage(subscribeMessage);
|
|
1797
|
+
}
|
|
1777
1798
|
} else {
|
|
1778
1799
|
const subscribeMessage = {
|
|
1779
1800
|
type: "subscribe",
|
|
1780
1801
|
channel: this.channelName
|
|
1781
1802
|
};
|
|
1782
|
-
if (this.subscriptionConfig) {
|
|
1783
|
-
subscribeMessage.config = this.subscriptionConfig;
|
|
1784
|
-
}
|
|
1785
1803
|
this.sendMessage(subscribeMessage);
|
|
1786
1804
|
}
|
|
1787
1805
|
this.startHeartbeat();
|
|
@@ -1861,18 +1879,29 @@ var RealtimeChannel = class {
|
|
|
1861
1879
|
this.pendingAcks.delete("access_token");
|
|
1862
1880
|
}
|
|
1863
1881
|
console.log("[Fluxbase Realtime] Token updated successfully");
|
|
1864
|
-
} else {
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1882
|
+
} else if (payload.subscription_id) {
|
|
1883
|
+
const schema = payload.schema || "public";
|
|
1884
|
+
const table = payload.table || "";
|
|
1885
|
+
if (table) {
|
|
1886
|
+
this.subscriptionIds.set(`${schema}.${table}`, payload.subscription_id);
|
|
1887
|
+
console.log("[Fluxbase Realtime] Subscription ID received for", `${schema}.${table}:`, payload.subscription_id);
|
|
1868
1888
|
} else {
|
|
1869
|
-
console.log("[Fluxbase Realtime]
|
|
1889
|
+
console.log("[Fluxbase Realtime] Subscription ID received:", payload.subscription_id);
|
|
1870
1890
|
}
|
|
1891
|
+
} else {
|
|
1892
|
+
console.log("[Fluxbase Realtime] Acknowledged:", message);
|
|
1871
1893
|
}
|
|
1872
1894
|
} else {
|
|
1873
1895
|
if (message.payload && typeof message.payload === "object" && "subscription_id" in message.payload) {
|
|
1874
|
-
|
|
1875
|
-
|
|
1896
|
+
const payload = message.payload;
|
|
1897
|
+
const schema = payload.schema || "public";
|
|
1898
|
+
const table = payload.table || "";
|
|
1899
|
+
if (table) {
|
|
1900
|
+
this.subscriptionIds.set(`${schema}.${table}`, payload.subscription_id);
|
|
1901
|
+
console.log("[Fluxbase Realtime] Subscription ID received for", `${schema}.${table}:`, payload.subscription_id);
|
|
1902
|
+
} else {
|
|
1903
|
+
console.log("[Fluxbase Realtime] Subscription ID received:", payload.subscription_id);
|
|
1904
|
+
}
|
|
1876
1905
|
} else {
|
|
1877
1906
|
console.log("[Fluxbase Realtime] Acknowledged:", message);
|
|
1878
1907
|
}
|
|
@@ -1966,6 +1995,21 @@ var RealtimeChannel = class {
|
|
|
1966
1995
|
old: payload.old_record || payload.old || {},
|
|
1967
1996
|
errors: payload.errors || null
|
|
1968
1997
|
};
|
|
1998
|
+
for (const entry of this.subscriptionConfigs) {
|
|
1999
|
+
const c = entry.config;
|
|
2000
|
+
const schemaMatch = !c.schema || c.schema === supabasePayload.schema;
|
|
2001
|
+
const tableMatch = !c.table || c.table === supabasePayload.table;
|
|
2002
|
+
const eventMatch = c.event === "*" || c.event === supabasePayload.eventType;
|
|
2003
|
+
if (schemaMatch && tableMatch && eventMatch) {
|
|
2004
|
+
entry.callbacks.forEach((cb) => {
|
|
2005
|
+
try {
|
|
2006
|
+
cb(supabasePayload);
|
|
2007
|
+
} catch (err) {
|
|
2008
|
+
console.error("[Fluxbase Realtime] Error in postgres_changes callback:", err);
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
1969
2013
|
const callbacks = this.callbacks.get(supabasePayload.eventType);
|
|
1970
2014
|
if (callbacks) {
|
|
1971
2015
|
callbacks.forEach((callback) => callback(supabasePayload));
|
|
@@ -3716,9 +3760,7 @@ var FluxbaseRPC = class {
|
|
|
3716
3760
|
async list(namespace) {
|
|
3717
3761
|
try {
|
|
3718
3762
|
const params = namespace ? `?namespace=${encodeURIComponent(namespace)}` : "";
|
|
3719
|
-
const response = await this.fetch.get(
|
|
3720
|
-
`/api/v1/rpc/procedures${params}`
|
|
3721
|
-
);
|
|
3763
|
+
const response = await this.fetch.get(`/api/v1/rpc/procedures${params}`);
|
|
3722
3764
|
return { data: response.procedures || [], error: null };
|
|
3723
3765
|
} catch (error) {
|
|
3724
3766
|
return { data: null, error };
|
|
@@ -3756,7 +3798,8 @@ var FluxbaseRPC = class {
|
|
|
3756
3798
|
{
|
|
3757
3799
|
params,
|
|
3758
3800
|
async: options?.async
|
|
3759
|
-
}
|
|
3801
|
+
},
|
|
3802
|
+
{ timeout: options?.timeout }
|
|
3760
3803
|
);
|
|
3761
3804
|
return { data: response, error: null };
|
|
3762
3805
|
} catch (error) {
|
|
@@ -3855,7 +3898,10 @@ var FluxbaseRPC = class {
|
|
|
3855
3898
|
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
3856
3899
|
interval = Math.min(interval * 1.5, maxInterval);
|
|
3857
3900
|
}
|
|
3858
|
-
return {
|
|
3901
|
+
return {
|
|
3902
|
+
data: null,
|
|
3903
|
+
error: new Error("Timeout waiting for execution to complete")
|
|
3904
|
+
};
|
|
3859
3905
|
}
|
|
3860
3906
|
};
|
|
3861
3907
|
|
|
@@ -8888,6 +8934,168 @@ var FluxbaseAdminStorage = class {
|
|
|
8888
8934
|
}
|
|
8889
8935
|
};
|
|
8890
8936
|
|
|
8937
|
+
// src/admin-realtime.ts
|
|
8938
|
+
var FluxbaseAdminRealtime = class {
|
|
8939
|
+
constructor(fetch2) {
|
|
8940
|
+
this.fetch = fetch2;
|
|
8941
|
+
}
|
|
8942
|
+
/**
|
|
8943
|
+
* Enable realtime on a table
|
|
8944
|
+
*
|
|
8945
|
+
* Creates the necessary database triggers to broadcast changes to WebSocket subscribers.
|
|
8946
|
+
* Also sets REPLICA IDENTITY FULL to include old values in UPDATE/DELETE events.
|
|
8947
|
+
*
|
|
8948
|
+
* @param table - Table name to enable realtime on
|
|
8949
|
+
* @param options - Optional configuration
|
|
8950
|
+
* @returns Promise resolving to EnableRealtimeResponse
|
|
8951
|
+
*
|
|
8952
|
+
* @example
|
|
8953
|
+
* ```typescript
|
|
8954
|
+
* // Enable realtime on products table (all events)
|
|
8955
|
+
* await client.admin.realtime.enableRealtime('products')
|
|
8956
|
+
*
|
|
8957
|
+
* // Enable on a specific schema
|
|
8958
|
+
* await client.admin.realtime.enableRealtime('orders', {
|
|
8959
|
+
* schema: 'sales'
|
|
8960
|
+
* })
|
|
8961
|
+
*
|
|
8962
|
+
* // Enable specific events only
|
|
8963
|
+
* await client.admin.realtime.enableRealtime('audit_log', {
|
|
8964
|
+
* events: ['INSERT'] // Only broadcast inserts
|
|
8965
|
+
* })
|
|
8966
|
+
*
|
|
8967
|
+
* // Exclude large columns from notifications
|
|
8968
|
+
* await client.admin.realtime.enableRealtime('posts', {
|
|
8969
|
+
* exclude: ['content', 'raw_html'] // Skip these in payload
|
|
8970
|
+
* })
|
|
8971
|
+
* ```
|
|
8972
|
+
*/
|
|
8973
|
+
async enableRealtime(table, options) {
|
|
8974
|
+
const request = {
|
|
8975
|
+
schema: options?.schema ?? "public",
|
|
8976
|
+
table,
|
|
8977
|
+
events: options?.events,
|
|
8978
|
+
exclude: options?.exclude
|
|
8979
|
+
};
|
|
8980
|
+
return await this.fetch.post(
|
|
8981
|
+
"/api/v1/admin/realtime/tables",
|
|
8982
|
+
request
|
|
8983
|
+
);
|
|
8984
|
+
}
|
|
8985
|
+
/**
|
|
8986
|
+
* Disable realtime on a table
|
|
8987
|
+
*
|
|
8988
|
+
* Removes the realtime trigger from a table. Existing subscribers will stop
|
|
8989
|
+
* receiving updates for this table.
|
|
8990
|
+
*
|
|
8991
|
+
* @param schema - Schema name
|
|
8992
|
+
* @param table - Table name
|
|
8993
|
+
* @returns Promise resolving to success message
|
|
8994
|
+
*
|
|
8995
|
+
* @example
|
|
8996
|
+
* ```typescript
|
|
8997
|
+
* await client.admin.realtime.disableRealtime('public', 'products')
|
|
8998
|
+
* console.log('Realtime disabled')
|
|
8999
|
+
* ```
|
|
9000
|
+
*/
|
|
9001
|
+
async disableRealtime(schema, table) {
|
|
9002
|
+
return await this.fetch.delete(
|
|
9003
|
+
`/api/v1/admin/realtime/tables/${encodeURIComponent(schema)}/${encodeURIComponent(table)}`
|
|
9004
|
+
);
|
|
9005
|
+
}
|
|
9006
|
+
/**
|
|
9007
|
+
* List all realtime-enabled tables
|
|
9008
|
+
*
|
|
9009
|
+
* Returns a list of all tables that have realtime enabled, along with their
|
|
9010
|
+
* configuration (events, excluded columns, etc.).
|
|
9011
|
+
*
|
|
9012
|
+
* @param options - Optional filter options
|
|
9013
|
+
* @returns Promise resolving to ListRealtimeTablesResponse
|
|
9014
|
+
*
|
|
9015
|
+
* @example
|
|
9016
|
+
* ```typescript
|
|
9017
|
+
* // List all enabled tables
|
|
9018
|
+
* const { tables, count } = await client.admin.realtime.listTables()
|
|
9019
|
+
* console.log(`${count} tables have realtime enabled`)
|
|
9020
|
+
*
|
|
9021
|
+
* tables.forEach(t => {
|
|
9022
|
+
* console.log(`${t.schema}.${t.table}: ${t.events.join(', ')}`)
|
|
9023
|
+
* })
|
|
9024
|
+
*
|
|
9025
|
+
* // Include disabled tables
|
|
9026
|
+
* const all = await client.admin.realtime.listTables({ includeDisabled: true })
|
|
9027
|
+
* ```
|
|
9028
|
+
*/
|
|
9029
|
+
async listTables(options) {
|
|
9030
|
+
const params = options?.includeDisabled ? "?enabled=false" : "";
|
|
9031
|
+
return await this.fetch.get(
|
|
9032
|
+
`/api/v1/admin/realtime/tables${params}`
|
|
9033
|
+
);
|
|
9034
|
+
}
|
|
9035
|
+
/**
|
|
9036
|
+
* Get realtime status for a specific table
|
|
9037
|
+
*
|
|
9038
|
+
* Returns the realtime configuration for a table, including whether it's enabled,
|
|
9039
|
+
* which events are tracked, and which columns are excluded.
|
|
9040
|
+
*
|
|
9041
|
+
* @param schema - Schema name
|
|
9042
|
+
* @param table - Table name
|
|
9043
|
+
* @returns Promise resolving to RealtimeTableStatus
|
|
9044
|
+
*
|
|
9045
|
+
* @example
|
|
9046
|
+
* ```typescript
|
|
9047
|
+
* const status = await client.admin.realtime.getStatus('public', 'products')
|
|
9048
|
+
*
|
|
9049
|
+
* if (status.realtime_enabled) {
|
|
9050
|
+
* console.log('Events:', status.events.join(', '))
|
|
9051
|
+
* console.log('Excluded:', status.excluded_columns?.join(', ') || 'none')
|
|
9052
|
+
* } else {
|
|
9053
|
+
* console.log('Realtime not enabled')
|
|
9054
|
+
* }
|
|
9055
|
+
* ```
|
|
9056
|
+
*/
|
|
9057
|
+
async getStatus(schema, table) {
|
|
9058
|
+
return await this.fetch.get(
|
|
9059
|
+
`/api/v1/admin/realtime/tables/${encodeURIComponent(schema)}/${encodeURIComponent(table)}`
|
|
9060
|
+
);
|
|
9061
|
+
}
|
|
9062
|
+
/**
|
|
9063
|
+
* Update realtime configuration for a table
|
|
9064
|
+
*
|
|
9065
|
+
* Modifies the events or excluded columns for a realtime-enabled table
|
|
9066
|
+
* without recreating the trigger.
|
|
9067
|
+
*
|
|
9068
|
+
* @param schema - Schema name
|
|
9069
|
+
* @param table - Table name
|
|
9070
|
+
* @param config - New configuration
|
|
9071
|
+
* @returns Promise resolving to success message
|
|
9072
|
+
*
|
|
9073
|
+
* @example
|
|
9074
|
+
* ```typescript
|
|
9075
|
+
* // Change which events are tracked
|
|
9076
|
+
* await client.admin.realtime.updateConfig('public', 'products', {
|
|
9077
|
+
* events: ['INSERT', 'UPDATE'] // Stop tracking deletes
|
|
9078
|
+
* })
|
|
9079
|
+
*
|
|
9080
|
+
* // Update excluded columns
|
|
9081
|
+
* await client.admin.realtime.updateConfig('public', 'posts', {
|
|
9082
|
+
* exclude: ['raw_content', 'search_vector']
|
|
9083
|
+
* })
|
|
9084
|
+
*
|
|
9085
|
+
* // Clear excluded columns
|
|
9086
|
+
* await client.admin.realtime.updateConfig('public', 'posts', {
|
|
9087
|
+
* exclude: [] // Include all columns again
|
|
9088
|
+
* })
|
|
9089
|
+
* ```
|
|
9090
|
+
*/
|
|
9091
|
+
async updateConfig(schema, table, config) {
|
|
9092
|
+
return await this.fetch.patch(
|
|
9093
|
+
`/api/v1/admin/realtime/tables/${encodeURIComponent(schema)}/${encodeURIComponent(table)}`,
|
|
9094
|
+
config
|
|
9095
|
+
);
|
|
9096
|
+
}
|
|
9097
|
+
};
|
|
9098
|
+
|
|
8891
9099
|
// src/admin.ts
|
|
8892
9100
|
var FluxbaseAdmin = class {
|
|
8893
9101
|
constructor(fetch2) {
|
|
@@ -8905,6 +9113,7 @@ var FluxbaseAdmin = class {
|
|
|
8905
9113
|
this.ai = new FluxbaseAdminAI(fetch2);
|
|
8906
9114
|
this.rpc = new FluxbaseAdminRPC(fetch2);
|
|
8907
9115
|
this.storage = new FluxbaseAdminStorage(fetch2);
|
|
9116
|
+
this.realtime = new FluxbaseAdminRealtime(fetch2);
|
|
8908
9117
|
}
|
|
8909
9118
|
/**
|
|
8910
9119
|
* Set admin authentication token
|
|
@@ -11933,6 +12142,7 @@ exports.FluxbaseAdminFunctions = FluxbaseAdminFunctions;
|
|
|
11933
12142
|
exports.FluxbaseAdminJobs = FluxbaseAdminJobs;
|
|
11934
12143
|
exports.FluxbaseAdminMigrations = FluxbaseAdminMigrations;
|
|
11935
12144
|
exports.FluxbaseAdminRPC = FluxbaseAdminRPC;
|
|
12145
|
+
exports.FluxbaseAdminRealtime = FluxbaseAdminRealtime;
|
|
11936
12146
|
exports.FluxbaseAdminStorage = FluxbaseAdminStorage;
|
|
11937
12147
|
exports.FluxbaseAuth = FluxbaseAuth;
|
|
11938
12148
|
exports.FluxbaseBranching = FluxbaseBranching;
|