supastash 0.1.13 → 0.1.15
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/supastashData/fetchCalls.d.ts.map +1 -1
- package/dist/hooks/supastashData/fetchCalls.js +3 -0
- package/dist/hooks/supastashData/index.d.ts.map +1 -1
- package/dist/hooks/supastashData/index.js +13 -10
- package/dist/hooks/supastashLogic.d.ts.map +1 -1
- package/dist/hooks/supastashLogic.js +15 -5
- package/dist/utils/fetchData/fetchLocalData.d.ts.map +1 -1
- package/dist/utils/fetchData/fetchLocalData.js +1 -2
- package/dist/utils/fetchData/realTimeCall.d.ts.map +1 -1
- package/dist/utils/fetchData/realTimeCall.js +5 -2
- package/dist/utils/schema/createSyncStatus.js +3 -3
- package/dist/utils/sync/pullFromRemote/pullData.d.ts +2 -0
- package/dist/utils/sync/pullFromRemote/pullData.d.ts.map +1 -1
- package/dist/utils/sync/pullFromRemote/pullData.js +51 -19
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchCalls.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/fetchCalls.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAKjE,wBAAgB,UAAU,CAAC,CAAC,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAC3B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;
|
|
1
|
+
{"version":3,"file":"fetchCalls.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/fetchCalls.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAKjE,wBAAgB,UAAU,CAAC,CAAC,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAC3B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;EAyEtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/supastashData/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;AAUxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,GAAG,EACtC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,eAAoB,GAC5B,mBAAmB,CAAC,CAAC,CAAC,CA+ExB"}
|
|
@@ -6,7 +6,6 @@ import useRealtimeData from "../../utils/fetchData/realTimeCall";
|
|
|
6
6
|
import useDataState from "./dataState";
|
|
7
7
|
import useEventQueues from "./eventQueues";
|
|
8
8
|
import { fetchCalls } from "./fetchCalls";
|
|
9
|
-
import { unregisterSub } from "./registerSub";
|
|
10
9
|
const tableSubscriptions = new Map();
|
|
11
10
|
/**
|
|
12
11
|
* @description
|
|
@@ -64,31 +63,35 @@ const tableSubscriptions = new Map();
|
|
|
64
63
|
export function useSupastashData(table, options = {}) {
|
|
65
64
|
const { filter, lazy = false, flushIntervalMs = 100, shouldFetch = true, realtime = true, } = options;
|
|
66
65
|
const hasTriggeredRef = useRef(false);
|
|
66
|
+
const unsub = useRef(null);
|
|
67
67
|
const { dataMap, data, groupedBy, } = useDataState(table);
|
|
68
68
|
const queueHandler = useEventQueues(table, options, flushIntervalMs);
|
|
69
69
|
const { triggerRefresh, trigger, cancel, initialFetchAndSync } = fetchCalls(table, options, hasTriggeredRef);
|
|
70
|
+
const subKey = useMemo(() => `${table}:${buildFilterString(filter)}`, [table, filter]);
|
|
70
71
|
useEffect(() => {
|
|
71
72
|
if (!shouldFetch || (lazy && !hasTriggeredRef.current))
|
|
72
73
|
return;
|
|
73
|
-
const subKey = `${table}:${buildFilterString(filter)}`;
|
|
74
74
|
if (!tableSubscriptions.get(subKey)) {
|
|
75
75
|
tableSubscriptions.set(subKey, true);
|
|
76
76
|
initialFetchAndSync();
|
|
77
|
-
|
|
77
|
+
unsub.current = AppState.addEventListener("change", (state) => {
|
|
78
78
|
if (state === "active") {
|
|
79
79
|
initialFetchAndSync();
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
supastashEventBus.on(`refresh:${table}`, triggerRefresh);
|
|
83
83
|
supastashEventBus.on(`refresh:all`, triggerRefresh);
|
|
84
|
-
return () => {
|
|
85
|
-
supastashEventBus.off?.(`refresh:${table}`, triggerRefresh);
|
|
86
|
-
supastashEventBus.off?.(`refresh:all`, triggerRefresh);
|
|
87
|
-
unsub.remove();
|
|
88
|
-
unregisterSub(table, filter);
|
|
89
|
-
};
|
|
90
84
|
}
|
|
91
|
-
|
|
85
|
+
else {
|
|
86
|
+
initialFetchAndSync();
|
|
87
|
+
}
|
|
88
|
+
return () => {
|
|
89
|
+
supastashEventBus.off?.(`refresh:${table}`, triggerRefresh);
|
|
90
|
+
supastashEventBus.off?.(`refresh:all`, triggerRefresh);
|
|
91
|
+
unsub.current?.remove();
|
|
92
|
+
tableSubscriptions.delete(subKey);
|
|
93
|
+
};
|
|
94
|
+
}, [lazy, shouldFetch, subKey]);
|
|
92
95
|
// TEMP
|
|
93
96
|
useRealtimeData(table, queueHandler, options, hasTriggeredRef.current, realtime);
|
|
94
97
|
return useMemo(() => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supastashLogic.d.ts","sourceRoot":"","sources":["../../src/hooks/supastashLogic.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAQrE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,IAAI,mBAAmB,
|
|
1
|
+
{"version":3,"file":"supastashLogic.d.ts","sourceRoot":"","sources":["../../src/hooks/supastashLogic.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAQrE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,IAAI,mBAAmB,CAsElD"}
|
|
@@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from "react";
|
|
|
2
2
|
import { getSupastashConfig } from "../core/config";
|
|
3
3
|
import { supastashDbErrorMsg } from "../db/dbErrorMsg";
|
|
4
4
|
import { useSyncEngine } from "../hooks/syncEngine";
|
|
5
|
-
import { logError } from "../utils/logs";
|
|
5
|
+
import { logError, logWarn } from "../utils/logs";
|
|
6
6
|
import { createDeletedStatusTable, createSyncStatusTable, } from "../utils/schema/createSyncStatus";
|
|
7
7
|
import { supabaseClientErr } from "../utils/supabaseClientErr";
|
|
8
8
|
/**
|
|
@@ -25,6 +25,7 @@ export function useSupastash() {
|
|
|
25
25
|
const [dbReady, setDbReady] = useState(false);
|
|
26
26
|
const initialized = useRef(false);
|
|
27
27
|
const config = getSupastashConfig();
|
|
28
|
+
const { startSync, stopSync } = useSyncEngine();
|
|
28
29
|
if (!config.sqliteClient || !config.sqliteClientType) {
|
|
29
30
|
logError(`
|
|
30
31
|
[Supastash] ${supastashDbErrorMsg}`);
|
|
@@ -48,25 +49,34 @@ export function useSupastash() {
|
|
|
48
49
|
initialized.current = true;
|
|
49
50
|
async function init() {
|
|
50
51
|
try {
|
|
51
|
-
// Create tables
|
|
52
|
+
// Create supastash metadata tables
|
|
52
53
|
await createSyncStatusTable();
|
|
53
54
|
await createDeletedStatusTable();
|
|
54
55
|
// On schema init
|
|
55
56
|
if (config.onSchemaInit) {
|
|
56
57
|
await config.onSchemaInit();
|
|
57
58
|
}
|
|
58
|
-
setDbReady(true);
|
|
59
59
|
}
|
|
60
60
|
catch (error) {
|
|
61
61
|
logError(`[Supastash] Error initializing: ${error}`);
|
|
62
62
|
}
|
|
63
|
+
finally {
|
|
64
|
+
setDbReady(true);
|
|
65
|
+
}
|
|
63
66
|
}
|
|
64
67
|
init();
|
|
68
|
+
return () => {
|
|
69
|
+
initialized.current = false;
|
|
70
|
+
};
|
|
65
71
|
}, []);
|
|
66
|
-
const { startSync, stopSync } = useSyncEngine();
|
|
67
72
|
useEffect(() => {
|
|
68
73
|
if (dbReady) {
|
|
69
|
-
|
|
74
|
+
try {
|
|
75
|
+
startSync();
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
logWarn(`[Supastash] Error starting sync: ${error}`);
|
|
79
|
+
}
|
|
70
80
|
}
|
|
71
81
|
return () => {
|
|
72
82
|
stopSync();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchLocalData.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/fetchLocalData.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"fetchLocalData.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/fetchLocalData.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAyDtD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,KAAK,EAAE,MAAM,EACb,WAAW,GAAE,OAAc,EAC3B,KAAK,GAAE,MAAY,EACnB,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IACT,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,SAAS,EAAE;SACR,CAAC,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;KAC9C,CAAC;CACH,GAAG,IAAI,CAAC,CA6ER"}
|
|
@@ -36,7 +36,6 @@ function getNewVersion(table) {
|
|
|
36
36
|
debounceMap.set(table, timeout);
|
|
37
37
|
}
|
|
38
38
|
const timesFetched = new Map();
|
|
39
|
-
let lastFetched = new Map();
|
|
40
39
|
/**
|
|
41
40
|
* Fetches the local data from the database
|
|
42
41
|
* @param table - The table name to fetch from
|
|
@@ -48,7 +47,7 @@ export async function fetchLocalData(table, shouldFetch = true, limit = 200, ext
|
|
|
48
47
|
if (!shouldFetch || fetchingPromises.has(table))
|
|
49
48
|
return null;
|
|
50
49
|
timesFetched.set(table, (timesFetched.get(table) || 0) + 1);
|
|
51
|
-
if ((timesFetched.get(table) || 0) >
|
|
50
|
+
if ((timesFetched.get(table) || 0) > 150) {
|
|
52
51
|
log(`[Supastash] Fetching data for ${table} (times fetched: ${timesFetched.get(table)})`);
|
|
53
52
|
timesFetched.delete(table);
|
|
54
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realTimeCall.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/realTimeCall.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAOjE,QAAA,MAAM,eAAe,GACnB,OAAO,MAAM,EACb,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,EAC5D,SAAS,eAAe,EACxB,aAAa,OAAO,EACpB,UAAU,OAAO,
|
|
1
|
+
{"version":3,"file":"realTimeCall.d.ts","sourceRoot":"","sources":["../../../src/utils/fetchData/realTimeCall.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAOjE,QAAA,MAAM,eAAe,GACnB,OAAO,MAAM,EACb,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,EAC5D,SAAS,eAAe,EACxB,aAAa,OAAO,EACpB,UAAU,OAAO,SA6ClB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -30,8 +30,11 @@ const useRealtimeData = (table, queueHandler, options, initialized, realtime) =>
|
|
|
30
30
|
})
|
|
31
31
|
.subscribe();
|
|
32
32
|
return () => {
|
|
33
|
-
|
|
33
|
+
hasRegistered.delete(subKey);
|
|
34
|
+
if (subscription) {
|
|
35
|
+
supabase.removeChannel(subscription);
|
|
36
|
+
}
|
|
34
37
|
};
|
|
35
|
-
}, [table, lazy, initialized, realtime, shouldFetch]);
|
|
38
|
+
}, [table, lazy, initialized, realtime, shouldFetch, subKey]);
|
|
36
39
|
};
|
|
37
40
|
export default useRealtimeData;
|
|
@@ -5,11 +5,11 @@ import { getSupastashDb } from "../../db/dbInitializer";
|
|
|
5
5
|
export async function createSyncStatusTable() {
|
|
6
6
|
const db = await getSupastashDb();
|
|
7
7
|
const sql = `CREATE TABLE IF NOT EXISTS supastash_sync_status (
|
|
8
|
-
table_name TEXT
|
|
8
|
+
table_name TEXT PRIMARY KEY,
|
|
9
9
|
last_synced_at TEXT NOT NULL
|
|
10
10
|
);`;
|
|
11
11
|
const sql2 = `CREATE TABLE IF NOT EXISTS supastash_last_created (
|
|
12
|
-
table_name TEXT
|
|
12
|
+
table_name TEXT PRIMARY KEY,
|
|
13
13
|
last_created_at TEXT NOT NULL
|
|
14
14
|
);`;
|
|
15
15
|
await db.execAsync(sql);
|
|
@@ -21,7 +21,7 @@ export async function createSyncStatusTable() {
|
|
|
21
21
|
export async function createDeletedStatusTable() {
|
|
22
22
|
const db = await getSupastashDb();
|
|
23
23
|
const sql = `CREATE TABLE IF NOT EXISTS supastash_deleted_status (
|
|
24
|
-
table_name TEXT
|
|
24
|
+
table_name TEXT PRIMARY KEY,
|
|
25
25
|
last_deleted_at TEXT DEFAULT NULL
|
|
26
26
|
);`;
|
|
27
27
|
await db.execAsync(sql);
|
|
@@ -6,4 +6,6 @@ import { RealtimeFilter } from "../../../types/realtimeData.types";
|
|
|
6
6
|
* @returns The data from the table
|
|
7
7
|
*/
|
|
8
8
|
export declare function pullData(table: string, filter?: RealtimeFilter): Promise<PayloadData[] | null>;
|
|
9
|
+
export declare function getMaxCreatedDate(data: PayloadData[]): string | null;
|
|
10
|
+
export declare function getMaxUpdatedDate(data: PayloadData[]): string | null;
|
|
9
11
|
//# sourceMappingURL=pullData.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pullData.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/pullData.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AA2BnE;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"pullData.d.ts","sourceRoot":"","sources":["../../../../src/utils/sync/pullFromRemote/pullData.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AA2BnE;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CAqH/B;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,GAAG,IAAI,CAgBpE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,GAAG,IAAI,CAgBpE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getSupastashConfig } from "../../../core/config";
|
|
2
|
-
import log from "../../logs";
|
|
2
|
+
import log, { logWarn } from "../../logs";
|
|
3
3
|
import { supabaseClientErr } from "../../supabaseClientErr";
|
|
4
4
|
import { getLastCreatedInfo, updateLastCreatedInfo, } from "./getLastCreatedInfo";
|
|
5
5
|
import { getLastPulledInfo, updateLastPulledInfo } from "./getLastPulledInfo";
|
|
@@ -30,10 +30,16 @@ export async function pullData(table, filter) {
|
|
|
30
30
|
const supabase = getSupastashConfig().supabaseClient;
|
|
31
31
|
if (!supabase)
|
|
32
32
|
throw new Error(`No supabase client found: ${supabaseClientErr}`);
|
|
33
|
-
let
|
|
33
|
+
let filteredLastCreatedQuery = supabase
|
|
34
34
|
.from(table)
|
|
35
35
|
.select("*")
|
|
36
|
-
.
|
|
36
|
+
.gte("created_at", lastCreatedAt || RANDOM_OLD_DATE)
|
|
37
|
+
.is("deleted_at", null)
|
|
38
|
+
.order("updated_at", { ascending: false, nullsFirst: false });
|
|
39
|
+
let filteredLastSyncedQuery = supabase
|
|
40
|
+
.from(table)
|
|
41
|
+
.select("*")
|
|
42
|
+
.gte("updated_at", lastSyncedAt || RANDOM_OLD_DATE)
|
|
37
43
|
.is("deleted_at", null)
|
|
38
44
|
.order("updated_at", { ascending: false, nullsFirst: false });
|
|
39
45
|
if (filter &&
|
|
@@ -51,14 +57,27 @@ export async function pullData(table, filter) {
|
|
|
51
57
|
validOperators.has(filter.operator) &&
|
|
52
58
|
filter.column &&
|
|
53
59
|
isValidValue) {
|
|
54
|
-
|
|
60
|
+
filteredLastCreatedQuery = filteredLastCreatedQuery[filter.operator](filter.column, filter.value);
|
|
61
|
+
filteredLastSyncedQuery = filteredLastSyncedQuery[filter.operator](filter.column, filter.value);
|
|
55
62
|
}
|
|
56
63
|
// Fetch records where created_at >= lastCreatedAt OR updated_at >= lastSyncedAt
|
|
57
|
-
const { data, error } = await
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
const { data: lastCreatedData, error: lastCreatedError, } = await filteredLastCreatedQuery;
|
|
65
|
+
const { data: lastSyncedData, error: lastSyncedError, } = await filteredLastSyncedQuery;
|
|
66
|
+
if (lastCreatedError || lastSyncedError) {
|
|
67
|
+
log(`[Supastash] Error fetching from ${table}:`, lastCreatedError?.message || lastSyncedError?.message);
|
|
60
68
|
return null;
|
|
61
69
|
}
|
|
70
|
+
const allRows = [...(lastCreatedData ?? []), ...(lastSyncedData ?? [])];
|
|
71
|
+
const merged = {};
|
|
72
|
+
for (const row of allRows) {
|
|
73
|
+
if (!row.id) {
|
|
74
|
+
logWarn(`[Supastash] Skipped row without id from "${table}":`, row);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const id = row.id;
|
|
78
|
+
merged[id] = row;
|
|
79
|
+
}
|
|
80
|
+
const data = Object.values(merged);
|
|
62
81
|
if (!data || data.length === 0) {
|
|
63
82
|
timesPulled.set(table, (timesPulled.get(table) || 0) + 1);
|
|
64
83
|
if ((timesPulled.get(table) || 0) >= DEFAULT_MAX_PULL_ATTEMPTS) {
|
|
@@ -71,7 +90,8 @@ export async function pullData(table, filter) {
|
|
|
71
90
|
}
|
|
72
91
|
log(`Received ${data.length} updates for ${table}`);
|
|
73
92
|
// Update the sync status tables with the latest timestamps
|
|
74
|
-
const
|
|
93
|
+
const createdMaxDate = getMaxCreatedDate(lastCreatedData ?? []);
|
|
94
|
+
const updatedMaxDate = getMaxUpdatedDate(lastSyncedData ?? []);
|
|
75
95
|
if (updatedMaxDate) {
|
|
76
96
|
await updateLastPulledInfo(table, updatedMaxDate);
|
|
77
97
|
}
|
|
@@ -80,23 +100,35 @@ export async function pullData(table, filter) {
|
|
|
80
100
|
}
|
|
81
101
|
return data;
|
|
82
102
|
}
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
103
|
+
export function getMaxCreatedDate(data) {
|
|
104
|
+
if (!data || data.length === 0)
|
|
105
|
+
return null;
|
|
86
106
|
const createdColumn = "created_at";
|
|
87
|
-
|
|
107
|
+
let maxDate = RANDOM_OLD_DATE;
|
|
88
108
|
for (const item of data) {
|
|
89
109
|
const createdValue = item[createdColumn];
|
|
90
|
-
const updatedValue = item[updatedColumn];
|
|
91
110
|
if (typeof createdValue === "string" && !isNaN(Date.parse(createdValue))) {
|
|
92
|
-
|
|
111
|
+
const createdTime = new Date(createdValue).getTime();
|
|
112
|
+
if (createdTime > new Date(maxDate).getTime()) {
|
|
113
|
+
maxDate = new Date(createdTime).toISOString();
|
|
114
|
+
}
|
|
93
115
|
}
|
|
116
|
+
}
|
|
117
|
+
return maxDate === RANDOM_OLD_DATE ? null : maxDate;
|
|
118
|
+
}
|
|
119
|
+
export function getMaxUpdatedDate(data) {
|
|
120
|
+
if (!data || data.length === 0)
|
|
121
|
+
return null;
|
|
122
|
+
const updatedColumn = "updated_at";
|
|
123
|
+
let maxDate = RANDOM_OLD_DATE;
|
|
124
|
+
for (const item of data) {
|
|
125
|
+
const updatedValue = item[updatedColumn];
|
|
94
126
|
if (typeof updatedValue === "string" && !isNaN(Date.parse(updatedValue))) {
|
|
95
|
-
|
|
127
|
+
const updatedTime = new Date(updatedValue).getTime();
|
|
128
|
+
if (updatedTime > new Date(maxDate).getTime()) {
|
|
129
|
+
maxDate = new Date(updatedTime).toISOString();
|
|
130
|
+
}
|
|
96
131
|
}
|
|
97
132
|
}
|
|
98
|
-
return
|
|
99
|
-
createdMaxDate: createdMaxDate === RANDOM_OLD_DATE ? null : createdMaxDate,
|
|
100
|
-
updatedMaxDate: updatedMaxDate === RANDOM_OLD_DATE ? null : updatedMaxDate,
|
|
101
|
-
};
|
|
133
|
+
return maxDate === RANDOM_OLD_DATE ? null : maxDate;
|
|
102
134
|
}
|