-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrealm.js
135 lines (109 loc) · 3.51 KB
/
realm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* eslint-disable import/no-mutable-exports */
import Realm from 'realm';
import RNFS from 'react-native-fs';
import config from './config';
import {BackHandler} from 'react-native';
import {cartesSchema} from './schemas';
const {realmPath, appConfig, LOG_TO_FILE, TRACE_LOG, schemaName} = config;
export const app = new Realm.App(appConfig);
export let realm;
function errorSync(session, error) {
console.log('realm', realm);
if (realm !== undefined) {
console.log('error.name', error.name);
if (error.name === 'ClientReset') {
const oldRealmPath = realm.path;
realm.close();
console.log(`Error ${error.message}, need to reset ${oldRealmPath}…`);
Realm.App.Sync.initiateClientReset(app, oldRealmPath);
console.log(`Creating backup from ${error.config.path}…`);
// Move backup file to a known location for a restore
// (it's async, but we don't care much to wait at this point)
RNFS.moveFile(error.config.path, `${oldRealmPath}~`).finally(() => {
// realm = null;
BackHandler.exitApp();
});
} else {
console.log(`Received realm error ${error.message}`);
}
}
}
async function restoreRealm() {
if (!realm) {
return;
}
const backupPath = `${realm.path}~`;
console.log('backupPath', backupPath);
const backupExists = await RNFS.exists(backupPath);
console.log('backupExists', backupExists);
if (backupExists) {
const backupRealm = await Realm.open({path: backupPath, readOnly: true});
const backupObjects = backupRealm
.objects(schemaName)
.filtered('updatedAt != null AND synced = null');
console.log(
`Found ${backupObjects.length} ${schemaName} objects in ${backupPath}, proceeding to merge…`,
);
if (backupObjects.length > 0) {
realm.beginTransaction();
backupObjects.forEach(element => {
realm.create(schemaName, element, 'modified');
});
realm.commitTransaction();
}
const rand = String(Math.floor(100000 + Math.random() * 900000));
await RNFS.moveFile(backupPath, `${backupPath}~~${rand}`);
console.log(`Merge completed, deleting ${backupPath}…`);
await RNFS.unlink(backupPath);
}
}
async function openRealm(user, phone) {
if (Realm.App && Realm.App.Sync) {
console.log('LOGGING REALM');
if (LOG_TO_FILE) {
Realm.App.Sync.setLogger(app, (level, message) =>
console.log(`(${level}) ${message}`),
);
}
if (TRACE_LOG) {
Realm.App.Sync.setLogLevel(app, 'trace');
} else {
Realm.App.Sync.setLogLevel(app, 'off');
}
}
console.log('user.id', user.id);
console.log('phone openRealm', phone);
const path = `${realmPath}-${phone}`;
const realmConfig = {
schema: [cartesSchema],
schemaVersion: 1,
path,
sync: {
user,
partitionValue: phone,
newRealmFileBehavior: {
type: 'openImmediately',
timeOutBehavior: 'throwException',
timeout: 5000,
},
existingRealmFileBehavior: {
type: 'openImmediately',
timeOutBehavior: 'openLocalRealm',
timeout: 5000,
},
downloadBeforeOpenBehavior: {
type: 'openImmediately',
timeOutBehavior: 'openLocalRealm',
timeout: 5000,
},
timeout: 5000,
error: errorSync,
},
timeout: 5000,
};
realm = await Realm.open(realmConfig);
console.log('Opened realm successfully');
// If a backup file exists, restore to the current realm, and delete file afterwards
await restoreRealm();
}
export default openRealm;