supastash 0.1.35 → 0.1.36
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/hooks/supastashFilters/index.d.ts +1 -1
- package/dist/hooks/supastashFilters/index.d.ts.map +1 -1
- package/dist/hooks/supastashFilters/index.js +7 -6
- package/dist/hooks/supastashLogic.d.ts.map +1 -1
- package/dist/hooks/supastashLogic.js +1 -4
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/types/realtimeData.types.d.ts +1 -1
- package/dist/types/syncEngine.types.d.ts +15 -0
- package/dist/utils/fetchData/buildFilter.d.ts +3 -11
- package/dist/utils/fetchData/buildFilter.d.ts.map +1 -1
- package/dist/utils/fetchData/buildFilter.js +2 -0
- package/dist/utils/query/helpers/localDb/upsertMany.d.ts.map +1 -1
- package/dist/utils/query/helpers/localDb/upsertMany.js +4 -2
- package/dist/utils/query/remoteQuery/supabaseQuery.js +1 -1
- package/dist/utils/schema/createSyncStatus.d.ts +11 -4
- package/dist/utils/schema/createSyncStatus.d.ts.map +1 -1
- package/dist/utils/schema/createSyncStatus.js +27 -20
- package/dist/utils/schema/wipeTables.d.ts.map +1 -1
- package/dist/utils/schema/wipeTables.js +1 -3
- package/dist/utils/sync/pullFromRemote/getLastCreatedInfo.d.ts +2 -4
- package/dist/utils/sync/pullFromRemote/getLastCreatedInfo.d.ts.map +1 -1
- package/dist/utils/sync/pullFromRemote/getLastCreatedInfo.js +4 -23
- package/dist/utils/sync/pullFromRemote/getLastDeletedInfo.d.ts +2 -4
- package/dist/utils/sync/pullFromRemote/getLastDeletedInfo.d.ts.map +1 -1
- package/dist/utils/sync/pullFromRemote/getLastDeletedInfo.js +4 -23
- package/dist/utils/sync/pullFromRemote/getLastPulledInfo.d.ts +2 -4
- package/dist/utils/sync/pullFromRemote/getLastPulledInfo.d.ts.map +1 -1
- package/dist/utils/sync/pullFromRemote/getLastPulledInfo.js +4 -22
- package/dist/utils/sync/pullFromRemote/helpers.d.ts +13 -0
- package/dist/utils/sync/pullFromRemote/helpers.d.ts.map +1 -0
- package/dist/utils/sync/pullFromRemote/helpers.js +82 -0
- package/dist/utils/sync/pullFromRemote/pullData.d.ts +4 -3
- package/dist/utils/sync/pullFromRemote/pullData.d.ts.map +1 -1
- package/dist/utils/sync/pullFromRemote/pullData.js +41 -91
- package/dist/utils/sync/pullFromRemote/updateFilter.d.ts +10 -0
- package/dist/utils/sync/pullFromRemote/updateFilter.d.ts.map +1 -0
- package/dist/utils/sync/pullFromRemote/updateFilter.js +42 -0
- package/dist/utils/sync/pullFromRemote/updateLocalDb.d.ts.map +1 -1
- package/dist/utils/sync/pullFromRemote/updateLocalDb.js +9 -8
- package/dist/utils/sync/pushLocal/uploadHelpers.d.ts +1 -2
- package/dist/utils/sync/pushLocal/uploadHelpers.d.ts.map +1 -1
- package/dist/utils/sync/pushLocal/uploadHelpers.js +7 -25
- package/dist/utils/sync/status/filterKey.d.ts +15 -0
- package/dist/utils/sync/status/filterKey.d.ts.map +1 -0
- package/dist/utils/sync/status/filterKey.js +59 -0
- package/dist/utils/sync/status/repo.d.ts +10 -0
- package/dist/utils/sync/status/repo.d.ts.map +1 -0
- package/dist/utils/sync/status/repo.js +78 -0
- package/dist/utils/sync/status/services.d.ts +31 -0
- package/dist/utils/sync/status/services.d.ts.map +1 -0
- package/dist/utils/sync/status/services.js +111 -0
- package/dist/utils/sync/status/syncStatus.d.ts +110 -0
- package/dist/utils/sync/status/syncStatus.d.ts.map +1 -0
- package/dist/utils/sync/status/syncStatus.js +153 -0
- package/dist/utils/sync/status/syncUpdate.d.ts +7 -0
- package/dist/utils/sync/status/syncUpdate.d.ts.map +1 -0
- package/dist/utils/sync/status/syncUpdate.js +18 -0
- package/package.json +2 -1
|
@@ -32,5 +32,5 @@ import { SupastashFilter } from "../../types/supastashFilters.types";
|
|
|
32
32
|
* @note This hook does not re-run unless the `filters` object reference changes.
|
|
33
33
|
* To force re-evaluation, pass a fresh object (not just mutated data).
|
|
34
34
|
*/
|
|
35
|
-
export
|
|
35
|
+
export declare function useSupastashFilters(filters?: SupastashFilter): void;
|
|
36
36
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashFilters/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashFilters/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAOrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,eAAe,QAuD5D"}
|
|
@@ -3,9 +3,6 @@ import { filterTracker, tableFilters, tableFiltersUsed, } from "../../store/tabl
|
|
|
3
3
|
import { logWarn } from "../../utils/logs";
|
|
4
4
|
import isValidFilter, { warnOnMisMatch, } from "../../utils/sync/pullFromRemote/validateFilters";
|
|
5
5
|
import { checkIfTableExist } from "../../utils/tableValidator";
|
|
6
|
-
function warnInvalidFilter(filter, table) {
|
|
7
|
-
logWarn(`[Supastash] Invalid filter: ${JSON.stringify(filter)} for table ${table}`);
|
|
8
|
-
}
|
|
9
6
|
/**
|
|
10
7
|
* useSupastashFilters
|
|
11
8
|
*
|
|
@@ -39,13 +36,17 @@ function warnInvalidFilter(filter, table) {
|
|
|
39
36
|
* @note This hook does not re-run unless the `filters` object reference changes.
|
|
40
37
|
* To force re-evaluation, pass a fresh object (not just mutated data).
|
|
41
38
|
*/
|
|
42
|
-
export
|
|
39
|
+
export function useSupastashFilters(filters) {
|
|
43
40
|
useEffect(() => {
|
|
44
41
|
let cancelled = false;
|
|
45
42
|
async function run() {
|
|
46
|
-
|
|
43
|
+
if (!filters)
|
|
44
|
+
return;
|
|
45
|
+
const incoming = Object.keys(filters);
|
|
46
|
+
if (!incoming.length)
|
|
47
|
+
return;
|
|
47
48
|
// Remove stale tables
|
|
48
|
-
for (const t of Array.from(tableFilters.keys())) {
|
|
49
|
+
for (const t of Array.from(tableFilters.keys()) || []) {
|
|
49
50
|
if (!incoming.includes(t)) {
|
|
50
51
|
tableFilters.delete(t);
|
|
51
52
|
tableFiltersUsed.delete(t);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supastashLogic.d.ts","sourceRoot":"","sources":["../../src/hooks/supastashLogic.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"supastashLogic.d.ts","sourceRoot":"","sources":["../../src/hooks/supastashLogic.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAKrE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,OAAe,GAAG,mBAAmB,CA0EvE"}
|
|
@@ -4,9 +4,8 @@ import { supastashDbErrorMsg } from "../db/dbErrorMsg";
|
|
|
4
4
|
import { useSyncEngine } from "../hooks/syncEngine";
|
|
5
5
|
import { localCache } from "../store/localCache";
|
|
6
6
|
import { filterTracker, tableFilters, tableFiltersUsed, } from "../store/tableFilters";
|
|
7
|
-
import { createIdIndexes } from "../utils/createIndexes";
|
|
8
7
|
import { logError, logWarn } from "../utils/logs";
|
|
9
|
-
import {
|
|
8
|
+
import { createSyncStatusTable } from "../utils/schema/createSyncStatus";
|
|
10
9
|
import { supabaseClientErr } from "../utils/supabaseClientErr";
|
|
11
10
|
/**
|
|
12
11
|
* React hook to initialize and manage Supastash.
|
|
@@ -54,8 +53,6 @@ export function useSupastash(lazy = false) {
|
|
|
54
53
|
try {
|
|
55
54
|
// Create supastash metadata tables
|
|
56
55
|
await createSyncStatusTable();
|
|
57
|
-
await createDeletedStatusTable();
|
|
58
|
-
await createIdIndexes();
|
|
59
56
|
// On schema init
|
|
60
57
|
if (config.onSchemaInit) {
|
|
61
58
|
await config.onSchemaInit();
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { configureSupastash, getSupastashConfig } from "./core/config";
|
|
|
2
2
|
export { defineLocalSchema } from "./core/schemaManager";
|
|
3
3
|
export { getSupastashDb } from "./db/dbInitializer";
|
|
4
4
|
export { useSupastashData } from "./hooks/supastashData";
|
|
5
|
+
export { useSupastashFilters } from "./hooks/supastashFilters";
|
|
5
6
|
export { useSupastash } from "./hooks/supastashLogic";
|
|
6
7
|
export { syncAllTables, syncTable } from "./hooks/syncEngine";
|
|
7
8
|
export { useSupastashSyncStatus } from "./hooks/syncStatus";
|
|
@@ -9,9 +10,10 @@ export { supastashEventBus } from "./utils/events/eventBus";
|
|
|
9
10
|
export { supastash } from "./utils/query/builder";
|
|
10
11
|
export { dropAllTables, dropTable, wipeAllTables, wipeOldDataForAllTables, wipeOldDataForATable, wipeTable, } from "./utils/schema/wipeTables";
|
|
11
12
|
export { getAllTables } from "./utils/sync/getAllTables";
|
|
13
|
+
export { updateFilters } from "./utils/sync/pullFromRemote/updateFilter";
|
|
12
14
|
export { refreshAllTables, refreshTable, refreshTableWithPayload, } from "./utils/sync/refreshTables";
|
|
13
15
|
export { clearSyncCalls, getAllSyncTables, getSyncCall, registerSyncCall, unregisterSyncCall, } from "./utils/sync/registration/syncCalls";
|
|
14
|
-
export { clearAllLocalDeleteLog, clearAllLocalSyncLog, clearLocalDeleteLog, clearLocalSyncLog, getLocalDeleteLog,
|
|
16
|
+
export { clearAllLocalDeleteLog, clearAllLocalSyncLog, clearLocalDeleteLog, clearLocalSyncLog, clearSyncLog, getLocalDeleteLog, getSyncLog, resetSyncLog, setLocalDeleteLog, setLocalSyncLog, setSyncLog, } from "./utils/sync/status/syncStatus";
|
|
15
17
|
export type { CrudMethods } from "./types/query.types";
|
|
16
18
|
export type { RealtimeOptions, SupastashDataResult, SupastashFilter, } from "./types/realtimeData.types";
|
|
17
19
|
export type { SupastashConfig, SupastashHookReturn, SupastashSQLiteClientTypes, SupastashSQLiteDatabase, } from "./types/supastashConfig.types";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EACL,aAAa,EACb,SAAS,EACT,aAAa,EACb,uBAAuB,EACvB,oBAAoB,EACpB,SAAS,GACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EACL,aAAa,EACb,SAAS,EACT,aAAa,EACb,uBAAuB,EACvB,oBAAoB,EACpB,SAAS,GACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AACzE,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,UAAU,GACX,MAAM,gCAAgC,CAAC;AAExC,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,eAAe,GAChB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,+BAA+B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { defineLocalSchema } from "./core/schemaManager";
|
|
|
3
3
|
export { getSupastashDb } from "./db/dbInitializer";
|
|
4
4
|
export { useSupastashData } from "./hooks/supastashData";
|
|
5
5
|
//export { useSupastashLiteQuery } from "./hooks/supastashLiteQuery";
|
|
6
|
+
export { useSupastashFilters } from "./hooks/supastashFilters";
|
|
6
7
|
export { useSupastash } from "./hooks/supastashLogic";
|
|
7
8
|
export { syncAllTables, syncTable } from "./hooks/syncEngine";
|
|
8
9
|
export { useSupastashSyncStatus } from "./hooks/syncStatus";
|
|
@@ -10,6 +11,7 @@ export { supastashEventBus } from "./utils/events/eventBus";
|
|
|
10
11
|
export { supastash } from "./utils/query/builder";
|
|
11
12
|
export { dropAllTables, dropTable, wipeAllTables, wipeOldDataForAllTables, wipeOldDataForATable, wipeTable, } from "./utils/schema/wipeTables";
|
|
12
13
|
export { getAllTables } from "./utils/sync/getAllTables";
|
|
14
|
+
export { updateFilters } from "./utils/sync/pullFromRemote/updateFilter";
|
|
13
15
|
export { refreshAllTables, refreshTable, refreshTableWithPayload, } from "./utils/sync/refreshTables";
|
|
14
16
|
export { clearSyncCalls, getAllSyncTables, getSyncCall, registerSyncCall, unregisterSyncCall, } from "./utils/sync/registration/syncCalls";
|
|
15
|
-
export { clearAllLocalDeleteLog, clearAllLocalSyncLog, clearLocalDeleteLog, clearLocalSyncLog, getLocalDeleteLog,
|
|
17
|
+
export { clearAllLocalDeleteLog, clearAllLocalSyncLog, clearLocalDeleteLog, clearLocalSyncLog, clearSyncLog, getLocalDeleteLog, getSyncLog, resetSyncLog, setLocalDeleteLog, setLocalSyncLog, setSyncLog, } from "./utils/sync/status/syncStatus";
|
|
@@ -11,7 +11,7 @@ export type FilterOperator =
|
|
|
11
11
|
export type RealtimeFilter<R = any> = {
|
|
12
12
|
column: keyof R;
|
|
13
13
|
operator: FilterOperator;
|
|
14
|
-
value: string | number | null | (string | number)[];
|
|
14
|
+
value: string | number | null | boolean | (string | number)[];
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
export type SupastashFilter<R = any> = RealtimeFilter<R>;
|
|
@@ -25,3 +25,18 @@ export type SyncEntry = {
|
|
|
25
25
|
push?: PushFn;
|
|
26
26
|
pull?: PullFn;
|
|
27
27
|
};
|
|
28
|
+
|
|
29
|
+
export type SupastashSyncStatus = {
|
|
30
|
+
table_name: string;
|
|
31
|
+
filter_key: string;
|
|
32
|
+
filter_json: string;
|
|
33
|
+
last_created_at: string;
|
|
34
|
+
last_synced_at: string;
|
|
35
|
+
last_deleted_at: string;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type PublicScope =
|
|
39
|
+
| "all"
|
|
40
|
+
| "last_synced_at"
|
|
41
|
+
| "last_created_at"
|
|
42
|
+
| "last_deleted_at";
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function buildFilterString<R = any>(filters:
|
|
3
|
-
|
|
4
|
-
operator: FilterOperator;
|
|
5
|
-
value: string | number | null | (string | number)[];
|
|
6
|
-
} | undefined): string | undefined;
|
|
7
|
-
export declare function buildFilterForSql<R = any>(filter: {
|
|
8
|
-
column: keyof R | string;
|
|
9
|
-
operator: FilterOperator;
|
|
10
|
-
value: string | number | null | (string | number)[];
|
|
11
|
-
} | undefined): string | undefined;
|
|
1
|
+
import { RealtimeFilter } from "../../types/realtimeData.types";
|
|
2
|
+
export declare function buildFilterString<R = any>(filters: RealtimeFilter<R> | undefined): string | undefined;
|
|
3
|
+
export declare function buildFilterForSql<R = any>(filter: RealtimeFilter<R> | undefined | undefined): string | undefined;
|
|
12
4
|
//# sourceMappingURL=buildFilter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildFilter.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/buildFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,GAAG,EACvC,OAAO,
|
|
1
|
+
{"version":3,"file":"buildFilter.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/buildFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEhE,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,GAAG,EACvC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,GACrC,MAAM,GAAG,SAAS,CAepB;AAED,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,GAAG,EACvC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,SAAS,GAChD,MAAM,GAAG,SAAS,CAiCpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upsertMany.d.ts","sourceRoot":"","sources":["../../../../../src/utils/query/helpers/localDb/upsertMany.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,WAAW,EACX,cAAc,EACd,QAAQ,EACT,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"upsertMany.d.ts","sourceRoot":"","sources":["../../../../../src/utils/query/helpers/localDb/upsertMany.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,WAAW,EACX,cAAc,EACd,QAAQ,EACT,MAAM,+BAA+B,CAAC;AAKvC,UAAU,aAAa,CAAC,CAAC,GAAG,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,wBAAsB,UAAU,CAAC,CAAC,GAAG,GAAG,EACtC,KAAK,EAAE,CAAC,EAAE,EACV,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,EACtB,KAAK,EAAE,cAAc,CAAC,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC,GAC7C,OAAO,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAuLrB"}
|
|
@@ -3,8 +3,8 @@ import { getSupastashDb } from "../../../../db/dbInitializer";
|
|
|
3
3
|
import { generateUUIDv4 } from "../../../genUUID";
|
|
4
4
|
import { parseStringifiedFields as parseRow } from "../../../sync/pushLocal/parseFields";
|
|
5
5
|
import { queueRemoteCall } from "../queueRemote";
|
|
6
|
-
const DEFAULT_DATE = "1970-01-01T00:00:00.000Z";
|
|
7
6
|
const CHECK_BATCH = 900; // param headroom under 999
|
|
7
|
+
const remoteCalls = ["localFirst", "remoteFirst", "remoteOnly"];
|
|
8
8
|
export async function upsertMany(items, opts, state) {
|
|
9
9
|
const db = await getSupastashDb();
|
|
10
10
|
const { table, syncMode, nowISO, preserveTimestamp = false, yieldEvery = 500, } = opts;
|
|
@@ -123,7 +123,9 @@ export async function upsertMany(items, opts, state) {
|
|
|
123
123
|
try {
|
|
124
124
|
await run();
|
|
125
125
|
const newState = { ...state, payload: remotePayload };
|
|
126
|
-
|
|
126
|
+
if (remoteCalls.includes(newState.type)) {
|
|
127
|
+
queueRemoteCall(newState);
|
|
128
|
+
}
|
|
127
129
|
await db.runAsync("COMMIT");
|
|
128
130
|
}
|
|
129
131
|
catch (e) {
|
|
@@ -5,7 +5,7 @@ import { supastashEventBus } from "../../events/eventBus";
|
|
|
5
5
|
import { normalizeForSupabase } from "../../getSafeValues";
|
|
6
6
|
import { refreshScreen } from "../../refreshScreenCalls";
|
|
7
7
|
import { getSafeValue } from "../../serializer";
|
|
8
|
-
import { updateLocalSyncedAt } from "../../syncUpdate";
|
|
8
|
+
import { updateLocalSyncedAt } from "../../sync/status/syncUpdate";
|
|
9
9
|
import { buildWhereClause } from "../helpers/remoteDb/queryFilterBuilder";
|
|
10
10
|
import { operatorMap } from "../helpers/remoteDb/queryUtils";
|
|
11
11
|
import { permanentlyDeleteData } from "../localDbQuery/delete";
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates the supastash_sync_status table if it doesn't exist
|
|
3
|
-
*/
|
|
4
|
-
export declare function createSyncStatusTable(): Promise<void>;
|
|
5
1
|
/**
|
|
6
2
|
* Creates the supastash_deleted_status table if it doesn't exist
|
|
3
|
+
*
|
|
4
|
+
* Deprecated table for deleted status
|
|
5
|
+
* @deprecated Use createSyncStatusTable instead
|
|
7
6
|
*/
|
|
8
7
|
export declare function createDeletedStatusTable(): Promise<void>;
|
|
8
|
+
export declare const SYNC_STATUS_TABLES_SQL = "\n CREATE TABLE IF NOT EXISTS supastash_sync_marks (\n table_name TEXT NOT NULL,\n filter_key TEXT NOT NULL, \n filter_json TEXT NULL, \n last_created_at TEXT NULL, \n last_synced_at TEXT NULL, \n last_deleted_at TEXT NULL, \n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n PRIMARY KEY (table_name, filter_key)\n);";
|
|
9
|
+
export declare const INDEX_SYNC_MARKS_SQL = "\n CREATE INDEX IF NOT EXISTS idx_supastash_marks_updated\n ON supastash_sync_marks(updated_at);\n";
|
|
10
|
+
/**
|
|
11
|
+
* Creates the supastash_sync_marks table if it doesn't exist
|
|
12
|
+
*
|
|
13
|
+
* New table for sync marks
|
|
14
|
+
*/
|
|
15
|
+
export declare function createSyncStatusTable(): Promise<void>;
|
|
9
16
|
//# sourceMappingURL=createSyncStatus.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSyncStatus.d.ts","sourceRoot":"","sources":["../../../src/utils/schema/createSyncStatus.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"createSyncStatus.d.ts","sourceRoot":"","sources":["../../../src/utils/schema/createSyncStatus.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAsB,wBAAwB,kBAE7C;AAED,eAAO,MAAM,sBAAsB,kaAUhC,CAAC;AAEJ,eAAO,MAAM,oBAAoB,2GAGhC,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,qBAAqB,kBAK1C"}
|
|
@@ -1,28 +1,35 @@
|
|
|
1
1
|
import { getSupastashDb } from "../../db/dbInitializer";
|
|
2
2
|
/**
|
|
3
|
-
* Creates the
|
|
3
|
+
* Creates the supastash_deleted_status table if it doesn't exist
|
|
4
|
+
*
|
|
5
|
+
* Deprecated table for deleted status
|
|
6
|
+
* @deprecated Use createSyncStatusTable instead
|
|
4
7
|
*/
|
|
5
|
-
export async function
|
|
6
|
-
|
|
7
|
-
const sql = `CREATE TABLE IF NOT EXISTS supastash_sync_status (
|
|
8
|
-
table_name TEXT PRIMARY KEY,
|
|
9
|
-
last_synced_at TEXT NOT NULL
|
|
10
|
-
);`;
|
|
11
|
-
const sql2 = `CREATE TABLE IF NOT EXISTS supastash_last_created (
|
|
12
|
-
table_name TEXT PRIMARY KEY,
|
|
13
|
-
last_created_at TEXT NOT NULL
|
|
14
|
-
);`;
|
|
15
|
-
await db.execAsync(sql);
|
|
16
|
-
await db.execAsync(sql2);
|
|
8
|
+
export async function createDeletedStatusTable() {
|
|
9
|
+
return;
|
|
17
10
|
}
|
|
11
|
+
export const SYNC_STATUS_TABLES_SQL = `
|
|
12
|
+
CREATE TABLE IF NOT EXISTS supastash_sync_marks (
|
|
13
|
+
table_name TEXT NOT NULL,
|
|
14
|
+
filter_key TEXT NOT NULL,
|
|
15
|
+
filter_json TEXT NULL,
|
|
16
|
+
last_created_at TEXT NULL,
|
|
17
|
+
last_synced_at TEXT NULL,
|
|
18
|
+
last_deleted_at TEXT NULL,
|
|
19
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
20
|
+
PRIMARY KEY (table_name, filter_key)
|
|
21
|
+
);`;
|
|
22
|
+
export const INDEX_SYNC_MARKS_SQL = `
|
|
23
|
+
CREATE INDEX IF NOT EXISTS idx_supastash_marks_updated
|
|
24
|
+
ON supastash_sync_marks(updated_at);
|
|
25
|
+
`;
|
|
18
26
|
/**
|
|
19
|
-
* Creates the
|
|
27
|
+
* Creates the supastash_sync_marks table if it doesn't exist
|
|
28
|
+
*
|
|
29
|
+
* New table for sync marks
|
|
20
30
|
*/
|
|
21
|
-
export async function
|
|
31
|
+
export async function createSyncStatusTable() {
|
|
22
32
|
const db = await getSupastashDb();
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
last_deleted_at TEXT DEFAULT NULL
|
|
26
|
-
);`;
|
|
27
|
-
await db.execAsync(sql);
|
|
33
|
+
await db.execAsync(SYNC_STATUS_TABLES_SQL);
|
|
34
|
+
await db.execAsync(INDEX_SYNC_MARKS_SQL);
|
|
28
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wipeTables.d.ts","sourceRoot":"","sources":["../../../src/utils/schema/wipeTables.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"wipeTables.d.ts","sourceRoot":"","sources":["../../../src/utils/schema/wipeTables.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,iBAWhD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,iBAWhD;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,kBAalC;AAED;;;;;;;;;;;;;GAaG;AAEH,wBAAsB,aAAa,kBAalC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,iBAyBpB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,aAAa,GAAE,MAAM,EAAO,iBAiB7B"}
|
|
@@ -2,7 +2,7 @@ import { getSupastashDb } from "../../db/dbInitializer";
|
|
|
2
2
|
import { clearSchemaCache } from "../getTableSchema";
|
|
3
3
|
import log from "../logs";
|
|
4
4
|
import { getAllTables } from "../sync/getAllTables";
|
|
5
|
-
import {
|
|
5
|
+
import { clearLocalSyncLog } from "../sync/status/syncStatus";
|
|
6
6
|
/**
|
|
7
7
|
* Wipes a specific table from the local SQLite database and removes its sync metadata.
|
|
8
8
|
*
|
|
@@ -24,7 +24,6 @@ export async function wipeTable(tableName) {
|
|
|
24
24
|
const db = await getSupastashDb();
|
|
25
25
|
await db.runAsync(`DELETE FROM ${tableName}`);
|
|
26
26
|
await clearLocalSyncLog(tableName);
|
|
27
|
-
await clearLocalDeleteLog(tableName);
|
|
28
27
|
clearSchemaCache(tableName);
|
|
29
28
|
log(`[Supastash] Wiped table "${tableName}" and cleared sync metadata.`);
|
|
30
29
|
}
|
|
@@ -53,7 +52,6 @@ export async function dropTable(tableName) {
|
|
|
53
52
|
const db = await getSupastashDb();
|
|
54
53
|
await db.runAsync(`DROP TABLE IF EXISTS ${tableName}`);
|
|
55
54
|
await clearLocalSyncLog(tableName);
|
|
56
|
-
await clearLocalDeleteLog(tableName);
|
|
57
55
|
clearSchemaCache(tableName);
|
|
58
56
|
log(`[Supastash] Dropped table "${tableName}" and cleared sync metadata.`);
|
|
59
57
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Gets the last synced timestamp for a given table
|
|
3
|
-
* @
|
|
4
|
-
* @returns The last synced timestamp
|
|
3
|
+
* @deprecated Use getSupastashSyncStatus instead
|
|
5
4
|
*/
|
|
6
5
|
export declare function getLastCreatedInfo(table: string): Promise<string>;
|
|
7
6
|
/**
|
|
8
7
|
* Updates the last synced timestamp for a given table
|
|
9
|
-
* @
|
|
10
|
-
* @param lastCreatedAt - The last created timestamp
|
|
8
|
+
* @deprecated Use setSupastashSyncStatus instead
|
|
11
9
|
*/
|
|
12
10
|
export declare function updateLastCreatedInfo(table: string, lastCreatedAt: string): Promise<void>;
|
|
13
11
|
//# sourceMappingURL=getLastCreatedInfo.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLastCreatedInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastCreatedInfo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getLastCreatedInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastCreatedInfo.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEvE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,iBAGtB"}
|
|
@@ -1,34 +1,15 @@
|
|
|
1
|
-
import { getSupastashDb } from "../../../db/dbInitializer";
|
|
2
|
-
import { logWarn } from "../../logs";
|
|
3
1
|
const DEFAULT_LAST_CREATED_AT = "2000-01-01T00:00:00Z";
|
|
4
|
-
const LAST_CREATED_TABLE = "supastash_last_created";
|
|
5
2
|
/**
|
|
6
3
|
* Gets the last synced timestamp for a given table
|
|
7
|
-
* @
|
|
8
|
-
* @returns The last synced timestamp
|
|
4
|
+
* @deprecated Use getSupastashSyncStatus instead
|
|
9
5
|
*/
|
|
10
6
|
export async function getLastCreatedInfo(table) {
|
|
11
|
-
|
|
12
|
-
// Add table name to supastash_last_created if it doesn't exist
|
|
13
|
-
await db.runAsync(`INSERT OR IGNORE INTO supastash_last_created (table_name, last_created_at) VALUES (?, ?)`, [table, DEFAULT_LAST_CREATED_AT]);
|
|
14
|
-
// Get the latest sync timestamp for this table
|
|
15
|
-
const result = await db.getFirstAsync(`SELECT last_created_at FROM ${LAST_CREATED_TABLE} WHERE table_name = ?`, [table]);
|
|
16
|
-
const original = result?.last_created_at || DEFAULT_LAST_CREATED_AT;
|
|
17
|
-
const timestamp = Date.parse(original);
|
|
18
|
-
if (isNaN(timestamp)) {
|
|
19
|
-
logWarn(`[Supastash] Invalid date string found on created_at column for ${table}: ${original}`);
|
|
20
|
-
return original;
|
|
21
|
-
}
|
|
22
|
-
const lastSyncedAt = new Date(timestamp + 1);
|
|
23
|
-
const lastSyncedAtISOString = lastSyncedAt.toISOString();
|
|
24
|
-
return lastSyncedAtISOString;
|
|
7
|
+
return DEFAULT_LAST_CREATED_AT;
|
|
25
8
|
}
|
|
26
9
|
/**
|
|
27
10
|
* Updates the last synced timestamp for a given table
|
|
28
|
-
* @
|
|
29
|
-
* @param lastCreatedAt - The last created timestamp
|
|
11
|
+
* @deprecated Use setSupastashSyncStatus instead
|
|
30
12
|
*/
|
|
31
13
|
export async function updateLastCreatedInfo(table, lastCreatedAt) {
|
|
32
|
-
|
|
33
|
-
await db.runAsync(`UPDATE ${LAST_CREATED_TABLE} SET last_created_at = ? WHERE table_name = ?`, [lastCreatedAt, table]);
|
|
14
|
+
return;
|
|
34
15
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Gets the last deleted timestamp for a given table
|
|
3
|
-
* @
|
|
4
|
-
* @returns The last deleted timestamp
|
|
3
|
+
* @deprecated Use getSupastashSyncStatus instead
|
|
5
4
|
*/
|
|
6
5
|
export declare function getLastDeletedInfo(table: string): Promise<string>;
|
|
7
6
|
/**
|
|
8
7
|
* Updates the last deleted timestamp for a given table
|
|
9
|
-
* @
|
|
10
|
-
* @param lastDeletedAt - The last deleted timestamp
|
|
8
|
+
* @deprecated Use setSupastashSyncStatus instead
|
|
11
9
|
*/
|
|
12
10
|
export declare function updateLastDeletedInfo(table: string, lastDeletedAt: string): Promise<void>;
|
|
13
11
|
//# sourceMappingURL=getLastDeletedInfo.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLastDeletedInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastDeletedInfo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getLastDeletedInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastDeletedInfo.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEvE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,iBAGtB"}
|
|
@@ -1,34 +1,15 @@
|
|
|
1
|
-
import { getSupastashDb } from "../../../db/dbInitializer";
|
|
2
|
-
import { logWarn } from "../../logs";
|
|
3
1
|
const DEFAULT_LAST_DELETED_AT = "2000-01-01T00:00:00Z";
|
|
4
|
-
const DELETED_STATUS_TABLE = "supastash_deleted_status";
|
|
5
2
|
/**
|
|
6
3
|
* Gets the last deleted timestamp for a given table
|
|
7
|
-
* @
|
|
8
|
-
* @returns The last deleted timestamp
|
|
4
|
+
* @deprecated Use getSupastashSyncStatus instead
|
|
9
5
|
*/
|
|
10
6
|
export async function getLastDeletedInfo(table) {
|
|
11
|
-
|
|
12
|
-
// Add table name to supastash_deleted_status if it doesn't exist
|
|
13
|
-
await db.runAsync(`INSERT OR IGNORE INTO ${DELETED_STATUS_TABLE} (table_name, last_deleted_at) VALUES (?, ?)`, [table, DEFAULT_LAST_DELETED_AT]);
|
|
14
|
-
// Get the latest deleted timestamp for this table
|
|
15
|
-
const result = await db.getFirstAsync(`SELECT last_deleted_at FROM ${DELETED_STATUS_TABLE} WHERE table_name = ?`, [table]);
|
|
16
|
-
const original = result?.last_deleted_at || DEFAULT_LAST_DELETED_AT;
|
|
17
|
-
const timestamp = Date.parse(original);
|
|
18
|
-
if (isNaN(timestamp)) {
|
|
19
|
-
logWarn(`[Supastash] Invalid date string found on deleted_at column for ${table}: ${original}`);
|
|
20
|
-
return original;
|
|
21
|
-
}
|
|
22
|
-
const lastDeletedAt = new Date(timestamp + 1);
|
|
23
|
-
const lastDeletedAtISOString = lastDeletedAt.toISOString();
|
|
24
|
-
return lastDeletedAtISOString;
|
|
7
|
+
return DEFAULT_LAST_DELETED_AT;
|
|
25
8
|
}
|
|
26
9
|
/**
|
|
27
10
|
* Updates the last deleted timestamp for a given table
|
|
28
|
-
* @
|
|
29
|
-
* @param lastDeletedAt - The last deleted timestamp
|
|
11
|
+
* @deprecated Use setSupastashSyncStatus instead
|
|
30
12
|
*/
|
|
31
13
|
export async function updateLastDeletedInfo(table, lastDeletedAt) {
|
|
32
|
-
|
|
33
|
-
await db.runAsync(`UPDATE ${DELETED_STATUS_TABLE} SET last_deleted_at = ? WHERE table_name = ?`, [lastDeletedAt, table]);
|
|
14
|
+
return;
|
|
34
15
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Gets the last synced timestamp for a given table
|
|
3
|
-
* @
|
|
4
|
-
* @returns The last synced timestamp
|
|
3
|
+
* @deprecated Use getSupastashSyncStatus instead
|
|
5
4
|
*/
|
|
6
5
|
export declare function getLastPulledInfo(table: string): Promise<string>;
|
|
7
6
|
/**
|
|
8
7
|
* Updates the last synced timestamp for a given table
|
|
9
|
-
* @
|
|
10
|
-
* @param lastSyncedAt - The last synced timestamp
|
|
8
|
+
* @deprecated Use setSupastashSyncStatus instead
|
|
11
9
|
*/
|
|
12
10
|
export declare function updateLastPulledInfo(table: string, lastSyncedAt: string): Promise<void>;
|
|
13
11
|
//# sourceMappingURL=getLastPulledInfo.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLastPulledInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastPulledInfo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getLastPulledInfo.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/getLastPulledInfo.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,iBAGrB"}
|
|
@@ -1,34 +1,16 @@
|
|
|
1
|
-
import { getSupastashDb } from "../../../db/dbInitializer";
|
|
2
|
-
import { logWarn } from "../../logs";
|
|
3
1
|
const DEFAULT_LAST_PULLED_AT = "2000-01-01T00:00:00Z";
|
|
4
2
|
const SYNC_STATUS_TABLE = "supastash_sync_status";
|
|
5
3
|
/**
|
|
6
4
|
* Gets the last synced timestamp for a given table
|
|
7
|
-
* @
|
|
8
|
-
* @returns The last synced timestamp
|
|
5
|
+
* @deprecated Use getSupastashSyncStatus instead
|
|
9
6
|
*/
|
|
10
7
|
export async function getLastPulledInfo(table) {
|
|
11
|
-
|
|
12
|
-
// Add table name to supastash_sync_status if it doesn't exist
|
|
13
|
-
await db.runAsync(`INSERT OR IGNORE INTO supastash_sync_status (table_name, last_synced_at) VALUES (?, ?)`, [table, DEFAULT_LAST_PULLED_AT]);
|
|
14
|
-
// Get the latest sync timestamp for this table
|
|
15
|
-
const result = await db.getFirstAsync(`SELECT last_synced_at FROM ${SYNC_STATUS_TABLE} WHERE table_name = ?`, [table]);
|
|
16
|
-
const original = result?.last_synced_at || DEFAULT_LAST_PULLED_AT;
|
|
17
|
-
const timestamp = Date.parse(original);
|
|
18
|
-
if (isNaN(timestamp)) {
|
|
19
|
-
logWarn(`[Supastash] Invalid date string found on updated_at column for ${table}: ${original}`);
|
|
20
|
-
return original;
|
|
21
|
-
}
|
|
22
|
-
const lastSyncedAt = new Date(timestamp + 1);
|
|
23
|
-
const lastSyncedAtISOString = lastSyncedAt.toISOString();
|
|
24
|
-
return lastSyncedAtISOString;
|
|
8
|
+
return DEFAULT_LAST_PULLED_AT;
|
|
25
9
|
}
|
|
26
10
|
/**
|
|
27
11
|
* Updates the last synced timestamp for a given table
|
|
28
|
-
* @
|
|
29
|
-
* @param lastSyncedAt - The last synced timestamp
|
|
12
|
+
* @deprecated Use setSupastashSyncStatus instead
|
|
30
13
|
*/
|
|
31
14
|
export async function updateLastPulledInfo(table, lastSyncedAt) {
|
|
32
|
-
|
|
33
|
-
await db.runAsync(`UPDATE ${SYNC_STATUS_TABLE} SET last_synced_at = ? WHERE table_name = ?`, [lastSyncedAt, table]);
|
|
15
|
+
return;
|
|
34
16
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PayloadData } from "../../../types/query.types";
|
|
2
|
+
import { RealtimeFilter } from "../../../types/realtimeData.types";
|
|
3
|
+
export declare function pageThrough(base: {
|
|
4
|
+
tsCol: "created_at" | "updated_at" | "deleted_at";
|
|
5
|
+
since: string;
|
|
6
|
+
table: string;
|
|
7
|
+
select?: string;
|
|
8
|
+
filters?: RealtimeFilter[];
|
|
9
|
+
includeDeleted?: boolean;
|
|
10
|
+
}): Promise<any[]>;
|
|
11
|
+
export declare function getMaxDate(rows: PayloadData[], col: "created_at" | "updated_at" | "deleted_at"): string | null;
|
|
12
|
+
export declare function logNoUpdates(table: string): void;
|
|
13
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAqBnE,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,kBAiDA;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,WAAW,EAAE,EACnB,GAAG,EAAE,YAAY,GAAG,YAAY,GAAG,YAAY,GAC9C,MAAM,GAAG,IAAI,CAUf;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,QAczC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { getSupastashConfig } from "../../../core/config";
|
|
2
|
+
import log from "../../logs";
|
|
3
|
+
import { supabaseClientErr } from "../../supabaseClientErr";
|
|
4
|
+
import isValidFilter from "./validateFilters";
|
|
5
|
+
const RANDOM_OLD_DATE = "2000-01-01T00:00:00Z";
|
|
6
|
+
const PAGE_SIZE = 1000;
|
|
7
|
+
const timesPulled = new Map();
|
|
8
|
+
const lastPulled = new Map();
|
|
9
|
+
const DEFAULT_MAX_PULL_ATTEMPTS = 150;
|
|
10
|
+
function applyFilters(q, filters, table) {
|
|
11
|
+
for (const f of filters) {
|
|
12
|
+
if (!isValidFilter([f])) {
|
|
13
|
+
throw new Error(`Invalid syncFilter: ${JSON.stringify(f)} for ${table}`);
|
|
14
|
+
}
|
|
15
|
+
q = q[f.operator](f.column, f.value);
|
|
16
|
+
}
|
|
17
|
+
return q;
|
|
18
|
+
}
|
|
19
|
+
export async function pageThrough(base) {
|
|
20
|
+
const supabase = getSupastashConfig().supabaseClient;
|
|
21
|
+
if (!supabase)
|
|
22
|
+
throw new Error(`No supabase client found: ${supabaseClientErr}`);
|
|
23
|
+
const results = [];
|
|
24
|
+
let cursorTs = base.since || RANDOM_OLD_DATE;
|
|
25
|
+
let cursorId = "";
|
|
26
|
+
const { table, filters = [], select = "*" } = base;
|
|
27
|
+
while (true) {
|
|
28
|
+
let q = supabase
|
|
29
|
+
.from(table)
|
|
30
|
+
.select(select)
|
|
31
|
+
.gte(base.tsCol, cursorTs)
|
|
32
|
+
.order(base.tsCol, { ascending: true })
|
|
33
|
+
.order("id", { ascending: true })
|
|
34
|
+
.limit(PAGE_SIZE);
|
|
35
|
+
if (!base.includeDeleted)
|
|
36
|
+
q = q.is("deleted_at", null);
|
|
37
|
+
if (filters) {
|
|
38
|
+
q = applyFilters(q, filters, table);
|
|
39
|
+
}
|
|
40
|
+
const { data, error } = await q;
|
|
41
|
+
if (error)
|
|
42
|
+
throw error;
|
|
43
|
+
if (!data || data.length === 0)
|
|
44
|
+
break;
|
|
45
|
+
const page = results.length === 0
|
|
46
|
+
? data.filter((r) => !(r[base.tsCol] === cursorTs &&
|
|
47
|
+
typeof r.id === "string" &&
|
|
48
|
+
r.id === cursorId))
|
|
49
|
+
: data;
|
|
50
|
+
results.push(...page);
|
|
51
|
+
if (data.length < PAGE_SIZE)
|
|
52
|
+
break;
|
|
53
|
+
const last = data[data.length - 1];
|
|
54
|
+
cursorTs = last[base.tsCol];
|
|
55
|
+
cursorId = last.id;
|
|
56
|
+
}
|
|
57
|
+
return results;
|
|
58
|
+
}
|
|
59
|
+
export function getMaxDate(rows, col) {
|
|
60
|
+
if (!rows?.length)
|
|
61
|
+
return null;
|
|
62
|
+
let max = RANDOM_OLD_DATE;
|
|
63
|
+
for (const r of rows) {
|
|
64
|
+
const v = r[col];
|
|
65
|
+
if (typeof v === "string" && !isNaN(Date.parse(v))) {
|
|
66
|
+
if (Date.parse(v) > Date.parse(max))
|
|
67
|
+
max = new Date(v).toISOString();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return max === RANDOM_OLD_DATE ? null : max;
|
|
71
|
+
}
|
|
72
|
+
export function logNoUpdates(table) {
|
|
73
|
+
const pulled = timesPulled.get(table) || 0;
|
|
74
|
+
const last = lastPulled.get(table) || 0;
|
|
75
|
+
timesPulled.set(table, pulled + 1);
|
|
76
|
+
if (pulled >= DEFAULT_MAX_PULL_ATTEMPTS) {
|
|
77
|
+
const timeSinceLastPull = Date.now() - last;
|
|
78
|
+
lastPulled.set(table, Date.now());
|
|
79
|
+
log(`[Supastash] No updates for ${table} from ${last} (times pulled: ${pulled}) in the last ${timeSinceLastPull / 1000}s`);
|
|
80
|
+
timesPulled.set(table, 0);
|
|
81
|
+
}
|
|
82
|
+
}
|