supastash 0.2.9 → 0.2.11
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/desktop/hooks/syncEngine.d.ts.map +1 -1
- package/dist/desktop/hooks/syncEngine.js +7 -2
- package/dist/desktop/index.d.ts +3 -2
- package/dist/desktop/index.d.ts.map +1 -1
- package/dist/desktop/index.js +1 -0
- package/dist/desktop/utils/sync/pullFromRemote/index.d.ts +2 -1
- package/dist/desktop/utils/sync/pullFromRemote/index.d.ts.map +1 -1
- package/dist/desktop/utils/sync/pullFromRemote/index.js +3 -2
- package/dist/desktop/utils/sync/pullFromRemote/pullFromRemoteBatch.d.ts +9 -0
- package/dist/desktop/utils/sync/pullFromRemote/pullFromRemoteBatch.d.ts.map +1 -0
- package/dist/desktop/utils/sync/pullFromRemote/pullFromRemoteBatch.js +202 -0
- package/dist/desktop/utils/sync/pushLocal/uploadChunk.d.ts.map +1 -1
- package/dist/desktop/utils/sync/pushLocal/uploadChunk.js +54 -11
- package/dist/desktop/utils/sync/pushLocal/uploadHelpers.d.ts +1 -1
- package/dist/desktop/utils/sync/pushLocal/uploadHelpers.d.ts.map +1 -1
- package/dist/desktop/utils/sync/pushLocal/uploadHelpers.js +24 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/native/hooks/syncEngine.d.ts.map +1 -1
- package/dist/native/hooks/syncEngine.js +7 -2
- package/dist/native/index.d.ts +1 -0
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +1 -0
- package/dist/native/utils/sync/pullFromRemote/index.d.ts +2 -1
- package/dist/native/utils/sync/pullFromRemote/index.d.ts.map +1 -1
- package/dist/native/utils/sync/pullFromRemote/index.js +7 -1
- package/dist/native/utils/sync/pullFromRemote/pullFromRemoteBatch.d.ts +9 -0
- package/dist/native/utils/sync/pullFromRemote/pullFromRemoteBatch.d.ts.map +1 -0
- package/dist/native/utils/sync/pullFromRemote/pullFromRemoteBatch.js +183 -0
- package/dist/native/utils/sync/pushLocal/uploadChunk.d.ts.map +1 -1
- package/dist/native/utils/sync/pushLocal/uploadChunk.js +53 -11
- package/dist/native/utils/sync/pushLocal/uploadHelpers.d.ts +1 -1
- package/dist/native/utils/sync/pushLocal/uploadHelpers.d.ts.map +1 -1
- package/dist/native/utils/sync/pushLocal/uploadHelpers.js +24 -2
- package/dist/shared/core/config/index.d.ts.map +1 -1
- package/dist/shared/core/config/index.js +2 -0
- package/dist/shared/hooks/supastashFilters/index.d.ts +9 -4
- package/dist/shared/hooks/supastashFilters/index.d.ts.map +1 -1
- package/dist/shared/hooks/supastashFilters/index.js +13 -5
- package/dist/shared/store/rpcTableFilters.d.ts +7 -0
- package/dist/shared/store/rpcTableFilters.d.ts.map +1 -0
- package/dist/shared/store/rpcTableFilters.js +5 -0
- package/dist/shared/types/rpcFilter.types.d.ts +23 -0
- package/dist/shared/types/supastashConfig.types.d.ts +38 -10
- package/dist/shared/utils/schema/createSyncStatus.d.ts.map +1 -1
- package/dist/shared/utils/schema/createSyncStatus.js +5 -1
- package/dist/shared/utils/sync/pullFromRemote/postgrestToRpc.d.ts +9 -0
- package/dist/shared/utils/sync/pullFromRemote/postgrestToRpc.d.ts.map +1 -0
- package/dist/shared/utils/sync/pullFromRemote/postgrestToRpc.js +50 -0
- package/dist/shared/utils/sync/pullFromRemote/updateFilter.d.ts +8 -5
- package/dist/shared/utils/sync/pullFromRemote/updateFilter.d.ts.map +1 -1
- package/dist/shared/utils/sync/pullFromRemote/updateFilter.js +11 -5
- package/dist/shared/utils/sync/pullFromRemote/updateRpcFilters.d.ts +12 -0
- package/dist/shared/utils/sync/pullFromRemote/updateRpcFilters.d.ts.map +1 -0
- package/dist/shared/utils/sync/pullFromRemote/updateRpcFilters.js +36 -0
- package/dist/shared/utils/sync/status/remoteSchema.d.ts +12 -0
- package/dist/shared/utils/sync/status/remoteSchema.d.ts.map +1 -1
- package/dist/shared/utils/sync/status/remoteSchema.js +46 -0
- package/package.json +1 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a single PostgREST Filter to an RpcFilterNode.
|
|
3
|
+
* Used so that tableFilters registered via useSupastashFilters are
|
|
4
|
+
* automatically applied in the batch pull RPC path.
|
|
5
|
+
*/
|
|
6
|
+
function convertFilter(f) {
|
|
7
|
+
const col = String(f.column);
|
|
8
|
+
if (f.operator === "is") {
|
|
9
|
+
return f.value === null
|
|
10
|
+
? { col, op: "is_null" }
|
|
11
|
+
: { col, op: "is_not_null" };
|
|
12
|
+
}
|
|
13
|
+
// For "in", the SQL compiler expects a comma-separated string
|
|
14
|
+
if (f.operator === "in") {
|
|
15
|
+
const val = Array.isArray(f.value)
|
|
16
|
+
? f.value.join(",")
|
|
17
|
+
: String(f.value ?? "");
|
|
18
|
+
return { col, op: "in", val };
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
col,
|
|
22
|
+
op: f.operator,
|
|
23
|
+
val: f.value,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Converts PostgREST-style SupastashFilter[] to RpcFilterNode[].
|
|
28
|
+
* Supports simple filters and { or: [...] } groups.
|
|
29
|
+
* Returns an empty array for an empty/undefined input.
|
|
30
|
+
*/
|
|
31
|
+
export function postgrestFiltersToRpc(filters) {
|
|
32
|
+
if (!filters?.length)
|
|
33
|
+
return [];
|
|
34
|
+
const result = [];
|
|
35
|
+
for (const f of filters) {
|
|
36
|
+
if ("or" in f) {
|
|
37
|
+
const nodes = f.or
|
|
38
|
+
.map(convertFilter)
|
|
39
|
+
.filter((n) => n !== null);
|
|
40
|
+
if (nodes.length)
|
|
41
|
+
result.push({ or: nodes });
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const node = convertFilter(f);
|
|
45
|
+
if (node)
|
|
46
|
+
result.push(node);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { SupastashFilter } from "../../../types/realtimeData.types";
|
|
2
|
+
import { RpcTableFilters } from "../../../types/rpcFilter.types";
|
|
2
3
|
/**
|
|
3
|
-
* Updates the filter for the given table
|
|
4
|
-
* Non-hook version of useSupastashFilters
|
|
4
|
+
* Updates the filter for the given table.
|
|
5
|
+
* Non-hook version of useSupastashFilters.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
7
|
+
* @param filters - PostgREST filters for the standard pull path. Automatically converted
|
|
8
|
+
* and applied in the batch RPC pull path too.
|
|
9
|
+
* @param rpcFilters - Optional supplemental RPC filter nodes. Only needed for `and` groups
|
|
10
|
+
* or other constructs SupastashFilter can't express.
|
|
8
11
|
*/
|
|
9
|
-
export declare function updateFilters(filters: SupastashFilter): Promise<void>;
|
|
12
|
+
export declare function updateFilters(filters: SupastashFilter, rpcFilters?: RpcTableFilters): Promise<void>;
|
|
10
13
|
//# sourceMappingURL=updateFilter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateFilter.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/sync/pullFromRemote/updateFilter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"updateFilter.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/sync/pullFromRemote/updateFilter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAOjE;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,eAAe,EACxB,UAAU,CAAC,EAAE,eAAe,iBA6C7B"}
|
|
@@ -2,15 +2,21 @@ import { filterTracker, tableFilters, tableFiltersUsed, } from "../../../store/t
|
|
|
2
2
|
import { logWarn } from "../../logs";
|
|
3
3
|
import { ReusedHelpers } from "../../reusedHelpers";
|
|
4
4
|
import { checkIfTableExist } from "../../tableValidator";
|
|
5
|
+
import { updateRpcFilters } from "./updateRpcFilters";
|
|
5
6
|
import { warnOnMisMatch } from "./validateFilters";
|
|
6
7
|
/**
|
|
7
|
-
* Updates the filter for the given table
|
|
8
|
-
* Non-hook version of useSupastashFilters
|
|
8
|
+
* Updates the filter for the given table.
|
|
9
|
+
* Non-hook version of useSupastashFilters.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* @param filters - PostgREST filters for the standard pull path. Automatically converted
|
|
12
|
+
* and applied in the batch RPC pull path too.
|
|
13
|
+
* @param rpcFilters - Optional supplemental RPC filter nodes. Only needed for `and` groups
|
|
14
|
+
* or other constructs SupastashFilter can't express.
|
|
12
15
|
*/
|
|
13
|
-
export async function updateFilters(filters) {
|
|
16
|
+
export async function updateFilters(filters, rpcFilters) {
|
|
17
|
+
if (rpcFilters) {
|
|
18
|
+
await updateRpcFilters(rpcFilters);
|
|
19
|
+
}
|
|
14
20
|
const incoming = Object.keys(filters ?? {});
|
|
15
21
|
// Remove stale tables
|
|
16
22
|
for (const t of Array.from(tableFilters.keys())) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { RpcTableFilters } from "../../../types/rpcFilter.types";
|
|
2
|
+
/**
|
|
3
|
+
* Registers explicit RPC filter nodes for the batch pull path (useBatchPullSync: true).
|
|
4
|
+
*
|
|
5
|
+
* Only needed for constructs SupastashFilter can't express (e.g. `and` groups).
|
|
6
|
+
* Filters registered via useSupastashFilters / updateFilters are automatically
|
|
7
|
+
* converted and applied in the batch path — no separate call needed for those.
|
|
8
|
+
*
|
|
9
|
+
* Called automatically by useSupastashFilters / updateFilters.
|
|
10
|
+
*/
|
|
11
|
+
export declare function updateRpcFilters(filters?: RpcTableFilters): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=updateRpcFilters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateRpcFilters.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/sync/pullFromRemote/updateRpcFilters.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAIhF;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B/E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { rpcTableFilters } from "../../../store/rpcTableFilters";
|
|
2
|
+
import { logWarn } from "../../logs";
|
|
3
|
+
import { checkIfTableExist } from "../../tableValidator";
|
|
4
|
+
/**
|
|
5
|
+
* Registers explicit RPC filter nodes for the batch pull path (useBatchPullSync: true).
|
|
6
|
+
*
|
|
7
|
+
* Only needed for constructs SupastashFilter can't express (e.g. `and` groups).
|
|
8
|
+
* Filters registered via useSupastashFilters / updateFilters are automatically
|
|
9
|
+
* converted and applied in the batch path — no separate call needed for those.
|
|
10
|
+
*
|
|
11
|
+
* Called automatically by useSupastashFilters / updateFilters.
|
|
12
|
+
*/
|
|
13
|
+
export async function updateRpcFilters(filters) {
|
|
14
|
+
const incoming = Object.keys(filters ?? {});
|
|
15
|
+
// Remove stale tables no longer in the incoming set
|
|
16
|
+
for (const t of Array.from(rpcTableFilters.keys())) {
|
|
17
|
+
if (!incoming.includes(t)) {
|
|
18
|
+
rpcTableFilters.delete(t);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (!incoming.length)
|
|
22
|
+
return;
|
|
23
|
+
const existence = await Promise.all(incoming.map(async (t) => [t, await checkIfTableExist(t)]));
|
|
24
|
+
for (const [table, exists] of existence) {
|
|
25
|
+
if (!exists) {
|
|
26
|
+
logWarn(`[Supastash] Table '${table}' does not exist; skipping RPC filters`);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const nodes = (filters[table] ?? []);
|
|
30
|
+
if (!nodes.length) {
|
|
31
|
+
rpcTableFilters.delete(table);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
rpcTableFilters.set(table, nodes.map((n) => ({ ...n })));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { TableSchema } from "../../../types/realtimeData.types";
|
|
2
2
|
export declare function appendSyncedAt(schema: TableSchema[]): TableSchema[];
|
|
3
|
+
/**
|
|
4
|
+
* Fetches column metadata for all supplied tables in a single RPC call
|
|
5
|
+
* and warms both the in-memory cache and the SQLite fallback store.
|
|
6
|
+
*
|
|
7
|
+
* Requires `useBatchSchemaFetch: true` in config and the
|
|
8
|
+
* `get_table_schemas` Postgres function to be deployed.
|
|
9
|
+
*
|
|
10
|
+
* Tables already in the memory cache are skipped.
|
|
11
|
+
* Validation errors for individual tables are logged and skipped —
|
|
12
|
+
* they will surface as normal errors when that table is first used.
|
|
13
|
+
*/
|
|
14
|
+
export declare function prefetchRemoteTableSchemas(tables: string[]): Promise<void>;
|
|
3
15
|
export declare function getRemoteTableSchema(table: string): Promise<TableSchema[] | null>;
|
|
4
16
|
//# sourceMappingURL=remoteSchema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteSchema.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/sync/status/remoteSchema.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AA4HhE,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,iBASnD;AAID,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CAkD/B"}
|
|
1
|
+
{"version":3,"file":"remoteSchema.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/sync/status/remoteSchema.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AA4HhE,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,iBASnD;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CAkD/B"}
|
|
@@ -98,6 +98,52 @@ export function appendSyncedAt(schema) {
|
|
|
98
98
|
];
|
|
99
99
|
}
|
|
100
100
|
const localSchemaCache = new Map();
|
|
101
|
+
/**
|
|
102
|
+
* Fetches column metadata for all supplied tables in a single RPC call
|
|
103
|
+
* and warms both the in-memory cache and the SQLite fallback store.
|
|
104
|
+
*
|
|
105
|
+
* Requires `useBatchSchemaFetch: true` in config and the
|
|
106
|
+
* `get_table_schemas` Postgres function to be deployed.
|
|
107
|
+
*
|
|
108
|
+
* Tables already in the memory cache are skipped.
|
|
109
|
+
* Validation errors for individual tables are logged and skipped —
|
|
110
|
+
* they will surface as normal errors when that table is first used.
|
|
111
|
+
*/
|
|
112
|
+
export async function prefetchRemoteTableSchemas(tables) {
|
|
113
|
+
const config = getSupastashConfig();
|
|
114
|
+
const supabase = config?.supabaseClient;
|
|
115
|
+
if (!supabase)
|
|
116
|
+
return;
|
|
117
|
+
const online = await isOnline();
|
|
118
|
+
if (!online)
|
|
119
|
+
return;
|
|
120
|
+
const toFetch = tables.filter((t) => !tableSchemaData.has(t));
|
|
121
|
+
if (!toFetch.length)
|
|
122
|
+
return;
|
|
123
|
+
const { data, error } = await supabase.rpc("get_table_schemas", {
|
|
124
|
+
p_tables: toFetch,
|
|
125
|
+
});
|
|
126
|
+
if (error || !data) {
|
|
127
|
+
if (error && !isNetworkError(error)) {
|
|
128
|
+
log(`[Supastash] Error batch-fetching table schemas: ${error.message}
|
|
129
|
+
You can find more information in the Supastash docs: ${SERVER_SIDE_DOCS_URL}`);
|
|
130
|
+
}
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
await ensureRemoteSchemaTableExists();
|
|
134
|
+
for (const [table, schema] of Object.entries(data)) {
|
|
135
|
+
if (!Array.isArray(schema))
|
|
136
|
+
continue;
|
|
137
|
+
try {
|
|
138
|
+
validatePayloadForTable(schema, table);
|
|
139
|
+
await upsertRemoteSchema(table, schema);
|
|
140
|
+
tableSchemaData.set(table, schema);
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
logWarn(`[Supastash] Schema validation failed for "${table}" during batch fetch: ${e?.message}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
101
147
|
export async function getRemoteTableSchema(table) {
|
|
102
148
|
const config = getSupastashConfig();
|
|
103
149
|
const supabase = config?.supabaseClient;
|