@pontasockets/baileys 0.3.4 → 1.0.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/README.md +1317 -643
- package/lib/Defaults/index.js +1 -1
- package/lib/Signal/libsignal.js +18 -0
- package/lib/Socket/messages-recv.js +91 -24
- package/lib/Socket/newsletter.js +2 -13
- package/lib/Utils/generics.js +1 -1
- package/lib/Utils/messages.js +145 -1
- package/lib/Utils/rich-message-utils.js +466 -11
- package/lib/Utils/use-multi-file-auth-state.js +41 -26
- package/package.json +1 -1
|
@@ -23,13 +23,19 @@ const fileLocks = new Map()
|
|
|
23
23
|
const getFileLock = (path) => {
|
|
24
24
|
let mutex = fileLocks.get(path)
|
|
25
25
|
if (!mutex) {
|
|
26
|
-
mutex = new async_mutex_1.Mutex()
|
|
26
|
+
mutex = new async_mutex_1.Mutex()
|
|
27
27
|
fileLocks.set(path, mutex)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
return mutex
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// Lepas mutex dari Map begitu tidak dipakai lagi supaya tidak numpuk terus (memory leak)
|
|
34
|
+
// selama proses hidup lama (bot jalan berbulan-bulan dengan ribuan file sesi berbeda).
|
|
35
|
+
const releaseFileLock = (path) => {
|
|
36
|
+
fileLocks.delete(path)
|
|
37
|
+
}
|
|
38
|
+
|
|
33
39
|
/**
|
|
34
40
|
* stores the full authentication state in a single folder.
|
|
35
41
|
* Far more efficient than singlefileauthstate
|
|
@@ -38,51 +44,56 @@ const getFileLock = (path) => {
|
|
|
38
44
|
* Would recommend writing an auth state for use with a proper SQL or No-SQL DB
|
|
39
45
|
* */
|
|
40
46
|
const useMultiFileAuthState = async (folder) => {
|
|
41
|
-
// Debounce timers per file to avoid rapid successive writes hammering disk
|
|
42
|
-
const writeDebounceTimers = new Map()
|
|
43
|
-
const WRITE_DEBOUNCE_MS = 300
|
|
44
|
-
|
|
45
47
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
48
|
const writeData = async (data, file) => {
|
|
47
49
|
const filePath = path_1.join(folder, fixFileName(file))
|
|
48
50
|
const mutex = getFileLock(filePath)
|
|
49
51
|
return mutex.acquire().then(async (release) => {
|
|
50
52
|
try {
|
|
51
|
-
// Atomic write: write to temp file then rename
|
|
53
|
+
// Atomic write: write to temp file then rename, agar file tidak pernah
|
|
54
|
+
// kebaca dalam kondisi setengah tertulis kalau proses mati di tengah jalan.
|
|
52
55
|
const tmpPath = filePath + '.tmp'
|
|
53
56
|
await promises_1.writeFile(tmpPath, JSON.stringify(data, generics_1.BufferJSON.replacer))
|
|
54
57
|
await fsRename(tmpPath, filePath)
|
|
55
58
|
} finally {
|
|
56
59
|
release()
|
|
60
|
+
releaseFileLock(filePath)
|
|
57
61
|
}
|
|
58
62
|
})
|
|
59
63
|
}
|
|
60
64
|
const readData = async (file) => {
|
|
65
|
+
const filePath = path_1.join(folder, fixFileName(file))
|
|
61
66
|
try {
|
|
62
|
-
const filePath = path_1.join(folder, fixFileName(file))
|
|
63
67
|
const mutex = getFileLock(filePath)
|
|
64
68
|
const data = await mutex.acquire().then(async (release) => {
|
|
65
69
|
try {
|
|
66
70
|
return await promises_1.readFile(filePath, { encoding: 'utf-8' })
|
|
67
71
|
} finally {
|
|
68
72
|
release()
|
|
73
|
+
releaseFileLock(filePath)
|
|
69
74
|
}
|
|
70
75
|
})
|
|
71
76
|
|
|
72
77
|
return JSON.parse(data, generics_1.BufferJSON.reviver)
|
|
73
78
|
} catch (error) {
|
|
79
|
+
// ENOENT (file belum ada) itu normal, tapi kalau isinya rusak/corrupt (JSON parse
|
|
80
|
+
// gagal) itu wajib kelihatan di log, bukan diam-diam dianggap "null"/hilang.
|
|
81
|
+
if (error?.code !== 'ENOENT') {
|
|
82
|
+
console.warn(`[useMultiFileAuthState] Gagal membaca/parse ${filePath}:`, error?.message || error)
|
|
83
|
+
}
|
|
74
84
|
return null
|
|
75
85
|
}
|
|
76
86
|
}
|
|
77
87
|
const removeData = async (file) => {
|
|
88
|
+
const filePath = path_1.join(folder, fixFileName(file))
|
|
78
89
|
try {
|
|
79
|
-
const filePath = path_1.join(folder, fixFileName(file))
|
|
80
90
|
const mutex = getFileLock(filePath)
|
|
81
91
|
await mutex.acquire().then(async (release) => {
|
|
82
92
|
try {
|
|
83
93
|
await promises_1.unlink(filePath)
|
|
84
94
|
} finally {
|
|
85
95
|
release()
|
|
96
|
+
releaseFileLock(filePath)
|
|
86
97
|
}
|
|
87
98
|
})
|
|
88
99
|
} catch {}
|
|
@@ -96,9 +107,22 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
96
107
|
else {
|
|
97
108
|
await promises_1.mkdir(folder, { recursive: true })
|
|
98
109
|
}
|
|
99
|
-
const fixFileName = (file) => {
|
|
100
|
-
return file?.replace(/\//g, '__')?.replace(/:/g, '-')
|
|
110
|
+
const fixFileName = (file) => {
|
|
111
|
+
return file?.replace(/\//g, '__')?.replace(/:/g, '-')
|
|
101
112
|
}
|
|
113
|
+
|
|
114
|
+
// Bersihkan file .tmp "yatim" yang tertinggal dari proses sebelumnya yang mati
|
|
115
|
+
// di tengah proses rename (atomic write). File-file ini tidak berguna dan kalau
|
|
116
|
+
// dibiarkan menumpuk, cuma buang-buang disk.
|
|
117
|
+
try {
|
|
118
|
+
const entries = await promises_1.readdir(folder)
|
|
119
|
+
await Promise.all(
|
|
120
|
+
entries
|
|
121
|
+
.filter((name) => name.endsWith('.tmp'))
|
|
122
|
+
.map((name) => promises_1.unlink(path_1.join(folder, name)).catch(() => {}))
|
|
123
|
+
)
|
|
124
|
+
} catch {}
|
|
125
|
+
|
|
102
126
|
const creds = await readData('creds.json') || auth_utils_1.initAuthCreds()
|
|
103
127
|
return {
|
|
104
128
|
state: {
|
|
@@ -128,24 +152,15 @@ const useMultiFileAuthState = async (folder) => {
|
|
|
128
152
|
}
|
|
129
153
|
}
|
|
130
154
|
},
|
|
131
|
-
// saveCreds
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const timer = setTimeout(() => {
|
|
137
|
-
writeDebounceTimers.delete('creds.json')
|
|
138
|
-
writeData(creds, 'creds.json').catch(err => {
|
|
139
|
-
console.error('[useMultiFileAuthState] Failed to save creds.json:', err)
|
|
140
|
-
})
|
|
141
|
-
}, WRITE_DEBOUNCE_MS)
|
|
142
|
-
writeDebounceTimers.set('creds.json', timer)
|
|
155
|
+
// saveCreds sekarang selalu langsung menulis (tidak didebounce). creds.json adalah
|
|
156
|
+
// file paling kritis — kalau proses mati tepat di jendela debounce, sesi bisa hilang
|
|
157
|
+
// atau balik ke state lama sehingga semua pesan gagal didekripsi setelah reconnect.
|
|
158
|
+
saveCreds: async () => {
|
|
159
|
+
return writeData(creds, 'creds.json')
|
|
143
160
|
},
|
|
144
|
-
//
|
|
161
|
+
// Tetap disediakan sebagai alias untuk kompatibilitas kode lama yang memanggil
|
|
162
|
+
// saveCredsNow() secara eksplisit (misal di handler disconnect/cleanup).
|
|
145
163
|
saveCredsNow: async () => {
|
|
146
|
-
const existing = writeDebounceTimers.get('creds.json')
|
|
147
|
-
if (existing) clearTimeout(existing)
|
|
148
|
-
writeDebounceTimers.delete('creds.json')
|
|
149
164
|
return writeData(creds, 'creds.json')
|
|
150
165
|
}
|
|
151
166
|
}
|