@fluxbase/sdk 2026.1.8 → 2026.1.9-rc.2
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 +230 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +247 -3
- package/dist/index.d.ts +247 -3
- package/dist/index.js +230 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1426,8 +1426,9 @@ var RealtimeChannel = class {
|
|
|
1426
1426
|
this.presenceCallbacks = /* @__PURE__ */ new Map();
|
|
1427
1427
|
this.broadcastCallbacks = /* @__PURE__ */ new Map();
|
|
1428
1428
|
this.executionLogCallbacks = /* @__PURE__ */ new Set();
|
|
1429
|
-
this.
|
|
1430
|
-
this.
|
|
1429
|
+
this.subscriptionConfigs = [];
|
|
1430
|
+
this.subscriptionIds = /* @__PURE__ */ new Map();
|
|
1431
|
+
// "schema.table" -> subscription_id
|
|
1431
1432
|
this.executionLogConfig = null;
|
|
1432
1433
|
this._presenceState = {};
|
|
1433
1434
|
this.myPresenceKey = null;
|
|
@@ -1456,13 +1457,15 @@ var RealtimeChannel = class {
|
|
|
1456
1457
|
on(event, configOrCallback, callback) {
|
|
1457
1458
|
if (event === "postgres_changes" && typeof configOrCallback !== "function") {
|
|
1458
1459
|
const config = configOrCallback;
|
|
1459
|
-
this.subscriptionConfig = config;
|
|
1460
1460
|
const actualCallback = callback;
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1461
|
+
let entry = this.subscriptionConfigs.find(
|
|
1462
|
+
(e) => e.config.schema === config.schema && e.config.table === config.table && e.config.event === config.event && e.config.filter === config.filter
|
|
1463
|
+
);
|
|
1464
|
+
if (!entry) {
|
|
1465
|
+
entry = { config, callbacks: /* @__PURE__ */ new Set() };
|
|
1466
|
+
this.subscriptionConfigs.push(entry);
|
|
1464
1467
|
}
|
|
1465
|
-
|
|
1468
|
+
entry.callbacks.add(actualCallback);
|
|
1466
1469
|
} else if (event === "broadcast" && typeof configOrCallback !== "function") {
|
|
1467
1470
|
const config = configOrCallback;
|
|
1468
1471
|
const actualCallback = callback;
|
|
@@ -1533,11 +1536,20 @@ var RealtimeChannel = class {
|
|
|
1533
1536
|
this.shouldReconnect = false;
|
|
1534
1537
|
return new Promise((resolve) => {
|
|
1535
1538
|
if (this.ws) {
|
|
1536
|
-
this.
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1539
|
+
if (this.subscriptionIds.size > 0) {
|
|
1540
|
+
for (const subId of this.subscriptionIds.values()) {
|
|
1541
|
+
this.sendMessage({
|
|
1542
|
+
type: "unsubscribe",
|
|
1543
|
+
channel: this.channelName,
|
|
1544
|
+
subscription_id: subId
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
} else {
|
|
1548
|
+
this.sendMessage({
|
|
1549
|
+
type: "unsubscribe",
|
|
1550
|
+
channel: this.channelName
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1541
1553
|
const startTime = Date.now();
|
|
1542
1554
|
const maxWait = timeout || 5e3;
|
|
1543
1555
|
const checkDisconnect = () => {
|
|
@@ -1772,14 +1784,20 @@ var RealtimeChannel = class {
|
|
|
1772
1784
|
}
|
|
1773
1785
|
};
|
|
1774
1786
|
this.sendMessage(logSubscribeMessage);
|
|
1787
|
+
} else if (this.subscriptionConfigs.length > 0) {
|
|
1788
|
+
for (const entry of this.subscriptionConfigs) {
|
|
1789
|
+
const subscribeMessage = {
|
|
1790
|
+
type: "subscribe",
|
|
1791
|
+
channel: this.channelName,
|
|
1792
|
+
config: entry.config
|
|
1793
|
+
};
|
|
1794
|
+
this.sendMessage(subscribeMessage);
|
|
1795
|
+
}
|
|
1775
1796
|
} else {
|
|
1776
1797
|
const subscribeMessage = {
|
|
1777
1798
|
type: "subscribe",
|
|
1778
1799
|
channel: this.channelName
|
|
1779
1800
|
};
|
|
1780
|
-
if (this.subscriptionConfig) {
|
|
1781
|
-
subscribeMessage.config = this.subscriptionConfig;
|
|
1782
|
-
}
|
|
1783
1801
|
this.sendMessage(subscribeMessage);
|
|
1784
1802
|
}
|
|
1785
1803
|
this.startHeartbeat();
|
|
@@ -1859,18 +1877,29 @@ var RealtimeChannel = class {
|
|
|
1859
1877
|
this.pendingAcks.delete("access_token");
|
|
1860
1878
|
}
|
|
1861
1879
|
console.log("[Fluxbase Realtime] Token updated successfully");
|
|
1862
|
-
} else {
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1880
|
+
} else if (payload.subscription_id) {
|
|
1881
|
+
const schema = payload.schema || "public";
|
|
1882
|
+
const table = payload.table || "";
|
|
1883
|
+
if (table) {
|
|
1884
|
+
this.subscriptionIds.set(`${schema}.${table}`, payload.subscription_id);
|
|
1885
|
+
console.log("[Fluxbase Realtime] Subscription ID received for", `${schema}.${table}:`, payload.subscription_id);
|
|
1866
1886
|
} else {
|
|
1867
|
-
console.log("[Fluxbase Realtime]
|
|
1887
|
+
console.log("[Fluxbase Realtime] Subscription ID received:", payload.subscription_id);
|
|
1868
1888
|
}
|
|
1889
|
+
} else {
|
|
1890
|
+
console.log("[Fluxbase Realtime] Acknowledged:", message);
|
|
1869
1891
|
}
|
|
1870
1892
|
} else {
|
|
1871
1893
|
if (message.payload && typeof message.payload === "object" && "subscription_id" in message.payload) {
|
|
1872
|
-
|
|
1873
|
-
|
|
1894
|
+
const payload = message.payload;
|
|
1895
|
+
const schema = payload.schema || "public";
|
|
1896
|
+
const table = payload.table || "";
|
|
1897
|
+
if (table) {
|
|
1898
|
+
this.subscriptionIds.set(`${schema}.${table}`, payload.subscription_id);
|
|
1899
|
+
console.log("[Fluxbase Realtime] Subscription ID received for", `${schema}.${table}:`, payload.subscription_id);
|
|
1900
|
+
} else {
|
|
1901
|
+
console.log("[Fluxbase Realtime] Subscription ID received:", payload.subscription_id);
|
|
1902
|
+
}
|
|
1874
1903
|
} else {
|
|
1875
1904
|
console.log("[Fluxbase Realtime] Acknowledged:", message);
|
|
1876
1905
|
}
|
|
@@ -1964,6 +1993,21 @@ var RealtimeChannel = class {
|
|
|
1964
1993
|
old: payload.old_record || payload.old || {},
|
|
1965
1994
|
errors: payload.errors || null
|
|
1966
1995
|
};
|
|
1996
|
+
for (const entry of this.subscriptionConfigs) {
|
|
1997
|
+
const c = entry.config;
|
|
1998
|
+
const schemaMatch = !c.schema || c.schema === supabasePayload.schema;
|
|
1999
|
+
const tableMatch = !c.table || c.table === supabasePayload.table;
|
|
2000
|
+
const eventMatch = c.event === "*" || c.event === supabasePayload.eventType;
|
|
2001
|
+
if (schemaMatch && tableMatch && eventMatch) {
|
|
2002
|
+
entry.callbacks.forEach((cb) => {
|
|
2003
|
+
try {
|
|
2004
|
+
cb(supabasePayload);
|
|
2005
|
+
} catch (err) {
|
|
2006
|
+
console.error("[Fluxbase Realtime] Error in postgres_changes callback:", err);
|
|
2007
|
+
}
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
1967
2011
|
const callbacks = this.callbacks.get(supabasePayload.eventType);
|
|
1968
2012
|
if (callbacks) {
|
|
1969
2013
|
callbacks.forEach((callback) => callback(supabasePayload));
|
|
@@ -8888,6 +8932,168 @@ var FluxbaseAdminStorage = class {
|
|
|
8888
8932
|
}
|
|
8889
8933
|
};
|
|
8890
8934
|
|
|
8935
|
+
// src/admin-realtime.ts
|
|
8936
|
+
var FluxbaseAdminRealtime = class {
|
|
8937
|
+
constructor(fetch2) {
|
|
8938
|
+
this.fetch = fetch2;
|
|
8939
|
+
}
|
|
8940
|
+
/**
|
|
8941
|
+
* Enable realtime on a table
|
|
8942
|
+
*
|
|
8943
|
+
* Creates the necessary database triggers to broadcast changes to WebSocket subscribers.
|
|
8944
|
+
* Also sets REPLICA IDENTITY FULL to include old values in UPDATE/DELETE events.
|
|
8945
|
+
*
|
|
8946
|
+
* @param table - Table name to enable realtime on
|
|
8947
|
+
* @param options - Optional configuration
|
|
8948
|
+
* @returns Promise resolving to EnableRealtimeResponse
|
|
8949
|
+
*
|
|
8950
|
+
* @example
|
|
8951
|
+
* ```typescript
|
|
8952
|
+
* // Enable realtime on products table (all events)
|
|
8953
|
+
* await client.admin.realtime.enableRealtime('products')
|
|
8954
|
+
*
|
|
8955
|
+
* // Enable on a specific schema
|
|
8956
|
+
* await client.admin.realtime.enableRealtime('orders', {
|
|
8957
|
+
* schema: 'sales'
|
|
8958
|
+
* })
|
|
8959
|
+
*
|
|
8960
|
+
* // Enable specific events only
|
|
8961
|
+
* await client.admin.realtime.enableRealtime('audit_log', {
|
|
8962
|
+
* events: ['INSERT'] // Only broadcast inserts
|
|
8963
|
+
* })
|
|
8964
|
+
*
|
|
8965
|
+
* // Exclude large columns from notifications
|
|
8966
|
+
* await client.admin.realtime.enableRealtime('posts', {
|
|
8967
|
+
* exclude: ['content', 'raw_html'] // Skip these in payload
|
|
8968
|
+
* })
|
|
8969
|
+
* ```
|
|
8970
|
+
*/
|
|
8971
|
+
async enableRealtime(table, options) {
|
|
8972
|
+
const request = {
|
|
8973
|
+
schema: options?.schema ?? "public",
|
|
8974
|
+
table,
|
|
8975
|
+
events: options?.events,
|
|
8976
|
+
exclude: options?.exclude
|
|
8977
|
+
};
|
|
8978
|
+
return await this.fetch.post(
|
|
8979
|
+
"/api/v1/admin/realtime/tables",
|
|
8980
|
+
request
|
|
8981
|
+
);
|
|
8982
|
+
}
|
|
8983
|
+
/**
|
|
8984
|
+
* Disable realtime on a table
|
|
8985
|
+
*
|
|
8986
|
+
* Removes the realtime trigger from a table. Existing subscribers will stop
|
|
8987
|
+
* receiving updates for this table.
|
|
8988
|
+
*
|
|
8989
|
+
* @param schema - Schema name
|
|
8990
|
+
* @param table - Table name
|
|
8991
|
+
* @returns Promise resolving to success message
|
|
8992
|
+
*
|
|
8993
|
+
* @example
|
|
8994
|
+
* ```typescript
|
|
8995
|
+
* await client.admin.realtime.disableRealtime('public', 'products')
|
|
8996
|
+
* console.log('Realtime disabled')
|
|
8997
|
+
* ```
|
|
8998
|
+
*/
|
|
8999
|
+
async disableRealtime(schema, table) {
|
|
9000
|
+
return await this.fetch.delete(
|
|
9001
|
+
`/api/v1/admin/realtime/tables/${encodeURIComponent(schema)}/${encodeURIComponent(table)}`
|
|
9002
|
+
);
|
|
9003
|
+
}
|
|
9004
|
+
/**
|
|
9005
|
+
* List all realtime-enabled tables
|
|
9006
|
+
*
|
|
9007
|
+
* Returns a list of all tables that have realtime enabled, along with their
|
|
9008
|
+
* configuration (events, excluded columns, etc.).
|
|
9009
|
+
*
|
|
9010
|
+
* @param options - Optional filter options
|
|
9011
|
+
* @returns Promise resolving to ListRealtimeTablesResponse
|
|
9012
|
+
*
|
|
9013
|
+
* @example
|
|
9014
|
+
* ```typescript
|
|
9015
|
+
* // List all enabled tables
|
|
9016
|
+
* const { tables, count } = await client.admin.realtime.listTables()
|
|
9017
|
+
* console.log(`${count} tables have realtime enabled`)
|
|
9018
|
+
*
|
|
9019
|
+
* tables.forEach(t => {
|
|
9020
|
+
* console.log(`${t.schema}.${t.table}: ${t.events.join(', ')}`)
|
|
9021
|
+
* })
|
|
9022
|
+
*
|
|
9023
|
+
* // Include disabled tables
|
|
9024
|
+
* const all = await client.admin.realtime.listTables({ includeDisabled: true })
|
|
9025
|
+
* ```
|
|
9026
|
+
*/
|
|
9027
|
+
async listTables(options) {
|
|
9028
|
+
const params = options?.includeDisabled ? "?enabled=false" : "";
|
|
9029
|
+
return await this.fetch.get(
|
|
9030
|
+
`/api/v1/admin/realtime/tables${params}`
|
|
9031
|
+
);
|
|
9032
|
+
}
|
|
9033
|
+
/**
|
|
9034
|
+
* Get realtime status for a specific table
|
|
9035
|
+
*
|
|
9036
|
+
* Returns the realtime configuration for a table, including whether it's enabled,
|
|
9037
|
+
* which events are tracked, and which columns are excluded.
|
|
9038
|
+
*
|
|
9039
|
+
* @param schema - Schema name
|
|
9040
|
+
* @param table - Table name
|
|
9041
|
+
* @returns Promise resolving to RealtimeTableStatus
|
|
9042
|
+
*
|
|
9043
|
+
* @example
|
|
9044
|
+
* ```typescript
|
|
9045
|
+
* const status = await client.admin.realtime.getStatus('public', 'products')
|
|
9046
|
+
*
|
|
9047
|
+
* if (status.realtime_enabled) {
|
|
9048
|
+
* console.log('Events:', status.events.join(', '))
|
|
9049
|
+
* console.log('Excluded:', status.excluded_columns?.join(', ') || 'none')
|
|
9050
|
+
* } else {
|
|
9051
|
+
* console.log('Realtime not enabled')
|
|
9052
|
+
* }
|
|
9053
|
+
* ```
|
|
9054
|
+
*/
|
|
9055
|
+
async getStatus(schema, table) {
|
|
9056
|
+
return await this.fetch.get(
|
|
9057
|
+
`/api/v1/admin/realtime/tables/${encodeURIComponent(schema)}/${encodeURIComponent(table)}`
|
|
9058
|
+
);
|
|
9059
|
+
}
|
|
9060
|
+
/**
|
|
9061
|
+
* Update realtime configuration for a table
|
|
9062
|
+
*
|
|
9063
|
+
* Modifies the events or excluded columns for a realtime-enabled table
|
|
9064
|
+
* without recreating the trigger.
|
|
9065
|
+
*
|
|
9066
|
+
* @param schema - Schema name
|
|
9067
|
+
* @param table - Table name
|
|
9068
|
+
* @param config - New configuration
|
|
9069
|
+
* @returns Promise resolving to success message
|
|
9070
|
+
*
|
|
9071
|
+
* @example
|
|
9072
|
+
* ```typescript
|
|
9073
|
+
* // Change which events are tracked
|
|
9074
|
+
* await client.admin.realtime.updateConfig('public', 'products', {
|
|
9075
|
+
* events: ['INSERT', 'UPDATE'] // Stop tracking deletes
|
|
9076
|
+
* })
|
|
9077
|
+
*
|
|
9078
|
+
* // Update excluded columns
|
|
9079
|
+
* await client.admin.realtime.updateConfig('public', 'posts', {
|
|
9080
|
+
* exclude: ['raw_content', 'search_vector']
|
|
9081
|
+
* })
|
|
9082
|
+
*
|
|
9083
|
+
* // Clear excluded columns
|
|
9084
|
+
* await client.admin.realtime.updateConfig('public', 'posts', {
|
|
9085
|
+
* exclude: [] // Include all columns again
|
|
9086
|
+
* })
|
|
9087
|
+
* ```
|
|
9088
|
+
*/
|
|
9089
|
+
async updateConfig(schema, table, config) {
|
|
9090
|
+
return await this.fetch.patch(
|
|
9091
|
+
`/api/v1/admin/realtime/tables/${encodeURIComponent(schema)}/${encodeURIComponent(table)}`,
|
|
9092
|
+
config
|
|
9093
|
+
);
|
|
9094
|
+
}
|
|
9095
|
+
};
|
|
9096
|
+
|
|
8891
9097
|
// src/admin.ts
|
|
8892
9098
|
var FluxbaseAdmin = class {
|
|
8893
9099
|
constructor(fetch2) {
|
|
@@ -8905,6 +9111,7 @@ var FluxbaseAdmin = class {
|
|
|
8905
9111
|
this.ai = new FluxbaseAdminAI(fetch2);
|
|
8906
9112
|
this.rpc = new FluxbaseAdminRPC(fetch2);
|
|
8907
9113
|
this.storage = new FluxbaseAdminStorage(fetch2);
|
|
9114
|
+
this.realtime = new FluxbaseAdminRealtime(fetch2);
|
|
8908
9115
|
}
|
|
8909
9116
|
/**
|
|
8910
9117
|
* Set admin authentication token
|
|
@@ -11917,6 +12124,6 @@ function assertType(value, validator, errorMessage = "Type assertion failed") {
|
|
|
11917
12124
|
}
|
|
11918
12125
|
}
|
|
11919
12126
|
|
|
11920
|
-
export { APIKeysManager, AppSettingsManager, AuthSettingsManager, ClientKeysManager, DDLManager, EmailSettingsManager, EmailTemplateManager, ExecutionLogsChannel, FluxbaseAI, FluxbaseAIChat, FluxbaseAdmin, FluxbaseAdminAI, FluxbaseAdminFunctions, FluxbaseAdminJobs, FluxbaseAdminMigrations, FluxbaseAdminRPC, FluxbaseAdminStorage, FluxbaseAuth, FluxbaseBranching, FluxbaseClient, FluxbaseFetch, FluxbaseFunctions, FluxbaseGraphQL, FluxbaseJobs, FluxbaseManagement, FluxbaseOAuth, FluxbaseRPC, FluxbaseRealtime, FluxbaseSettings, FluxbaseStorage, FluxbaseVector, ImpersonationManager, InvitationsManager, OAuthProviderManager, QueryBuilder, RealtimeChannel, SchemaQueryBuilder, SettingsClient, StorageBucket, SystemSettingsManager, WebhooksManager, assertType, bundleCode, createClient, denoExternalPlugin, hasPostgrestError, isArray, isAuthError, isAuthSuccess, isBoolean, isFluxbaseError, isFluxbaseSuccess, isNumber, isObject, isPostgrestSuccess, isString, loadImportMap };
|
|
12127
|
+
export { APIKeysManager, AppSettingsManager, AuthSettingsManager, ClientKeysManager, DDLManager, EmailSettingsManager, EmailTemplateManager, ExecutionLogsChannel, FluxbaseAI, FluxbaseAIChat, FluxbaseAdmin, FluxbaseAdminAI, FluxbaseAdminFunctions, FluxbaseAdminJobs, FluxbaseAdminMigrations, FluxbaseAdminRPC, FluxbaseAdminRealtime, FluxbaseAdminStorage, FluxbaseAuth, FluxbaseBranching, FluxbaseClient, FluxbaseFetch, FluxbaseFunctions, FluxbaseGraphQL, FluxbaseJobs, FluxbaseManagement, FluxbaseOAuth, FluxbaseRPC, FluxbaseRealtime, FluxbaseSettings, FluxbaseStorage, FluxbaseVector, ImpersonationManager, InvitationsManager, OAuthProviderManager, QueryBuilder, RealtimeChannel, SchemaQueryBuilder, SettingsClient, StorageBucket, SystemSettingsManager, WebhooksManager, assertType, bundleCode, createClient, denoExternalPlugin, hasPostgrestError, isArray, isAuthError, isAuthSuccess, isBoolean, isFluxbaseError, isFluxbaseSuccess, isNumber, isObject, isPostgrestSuccess, isString, loadImportMap };
|
|
11921
12128
|
//# sourceMappingURL=index.js.map
|
|
11922
12129
|
//# sourceMappingURL=index.js.map
|