@lazyneoaz/metachat 5.0.0 → 5.1.0
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/index.cjs +313 -102
- package/dist/index.d.mts +50 -5
- package/dist/index.d.ts +50 -5
- package/dist/index.mjs +305 -103
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -25450,7 +25450,11 @@ function looksLikeCheckpoint(res) {
|
|
|
25450
25450
|
return true;
|
|
25451
25451
|
}
|
|
25452
25452
|
const body = typeof res?.body === "string" ? res.body : "";
|
|
25453
|
-
|
|
25453
|
+
if (!body) return false;
|
|
25454
|
+
if (/"isNotCritical"\s*:\s*1/.test(body.slice(0, 400))) return false;
|
|
25455
|
+
return /account has been (?:disabled|suspended)|confirm your identity|security check|we (?:suspended|disabled) your account/i.test(
|
|
25456
|
+
body.slice(0, 400)
|
|
25457
|
+
);
|
|
25454
25458
|
}
|
|
25455
25459
|
async function requestWithRetry(requestFunction, retries = 3, baseDelay = 1e3, ctx) {
|
|
25456
25460
|
const emit2 = (event, payload) => {
|
|
@@ -75554,6 +75558,7 @@ __export(utils_exports2, {
|
|
|
75554
75558
|
BASE_COOLDOWN_MS: () => BASE_COOLDOWN_MS,
|
|
75555
75559
|
BRAND: () => BRAND,
|
|
75556
75560
|
CHROME_MAJORS: () => CHROME_MAJORS,
|
|
75561
|
+
CORE_REACTIONS: () => CORE_REACTIONS,
|
|
75557
75562
|
ConfigurationError: () => ConfigurationError,
|
|
75558
75563
|
DESKTOP_PLATFORMS: () => DESKTOP_PLATFORMS,
|
|
75559
75564
|
FCAError: () => FCAError,
|
|
@@ -75565,6 +75570,7 @@ __export(utils_exports2, {
|
|
|
75565
75570
|
NotFoundError: () => NotFoundError,
|
|
75566
75571
|
PING_GRACE_MS: () => PING_GRACE_MS,
|
|
75567
75572
|
PermissionError: () => PermissionError,
|
|
75573
|
+
REACTION_ALIASES: () => REACTION_ALIASES,
|
|
75568
75574
|
RateLimitError: () => RateLimitError,
|
|
75569
75575
|
RealtimeHealth: () => RealtimeHealth,
|
|
75570
75576
|
RecoverySupervisor: () => RecoverySupervisor,
|
|
@@ -75646,6 +75652,8 @@ __export(utils_exports2, {
|
|
|
75646
75652
|
isAuthFailure: () => isAuthFailure,
|
|
75647
75653
|
isBreakerOpen: () => isBreakerOpen,
|
|
75648
75654
|
isLoggedOutDocument: () => isLoggedOutDocument,
|
|
75655
|
+
isNonCriticalError: () => isNonCriticalError,
|
|
75656
|
+
isReactionEmoji: () => isReactionEmoji,
|
|
75649
75657
|
isReadableStream: () => isReadableStream2,
|
|
75650
75658
|
isStaleTokenError: () => isStaleTokenError,
|
|
75651
75659
|
json: () => json2,
|
|
@@ -75656,6 +75664,7 @@ __export(utils_exports2, {
|
|
|
75656
75664
|
meta: () => meta,
|
|
75657
75665
|
missingSessionCookies: () => missingSessionCookies,
|
|
75658
75666
|
normalizeBrowserProfile: () => normalizeBrowserProfile,
|
|
75667
|
+
normalizeReaction: () => normalizeReaction,
|
|
75659
75668
|
noteAction: () => noteAction,
|
|
75660
75669
|
noteAuthFailure: () => noteAuthFailure,
|
|
75661
75670
|
noteCheckpoint: () => noteCheckpoint,
|
|
@@ -75677,6 +75686,7 @@ __export(utils_exports2, {
|
|
|
75677
75686
|
resetBreaker: () => resetBreaker,
|
|
75678
75687
|
resolveProfile: () => resolveProfile,
|
|
75679
75688
|
retryDelay: () => retryDelay,
|
|
75689
|
+
retryOnNonCritical: () => retryOnNonCritical,
|
|
75680
75690
|
safetySnapshot: () => safetySnapshot,
|
|
75681
75691
|
saveCookies: () => saveCookies,
|
|
75682
75692
|
scheduleSessionKeepAlive: () => scheduleSessionKeepAlive,
|
|
@@ -90753,6 +90763,30 @@ function buildWsTaskContent(ctx, tasks, versionId) {
|
|
|
90753
90763
|
var import_form_data3 = __toESM(require_form_data2());
|
|
90754
90764
|
init_constants();
|
|
90755
90765
|
init_user_agents();
|
|
90766
|
+
|
|
90767
|
+
// src/utils/transient.ts
|
|
90768
|
+
var NON_CRITICAL_CODES = /* @__PURE__ */ new Set([1357004, 1357001, 1357031]);
|
|
90769
|
+
function isNonCriticalError(value) {
|
|
90770
|
+
if (!value || typeof value !== "object") return false;
|
|
90771
|
+
const body = value.body && typeof value.body === "object" ? value.body : value;
|
|
90772
|
+
if (body.isNotCritical === 1 || body.is_not_critical === 1) return true;
|
|
90773
|
+
const num = Number(body.error ?? body.errorCode ?? body.code);
|
|
90774
|
+
if (NON_CRITICAL_CODES.has(num)) return true;
|
|
90775
|
+
const text3 = String(body.errorDescription || body.errorSummary || body.message || "");
|
|
90776
|
+
return /re-?open(ing)? your browser|try again(?: later)?|temporarily unavailable/i.test(text3);
|
|
90777
|
+
}
|
|
90778
|
+
async function retryOnNonCritical(operation, refresh) {
|
|
90779
|
+
try {
|
|
90780
|
+
const first2 = await operation();
|
|
90781
|
+
if (!isNonCriticalError(first2)) return first2;
|
|
90782
|
+
} catch (error2) {
|
|
90783
|
+
if (!isNonCriticalError(error2)) throw error2;
|
|
90784
|
+
}
|
|
90785
|
+
await refresh();
|
|
90786
|
+
return operation();
|
|
90787
|
+
}
|
|
90788
|
+
|
|
90789
|
+
// src/utils/attachments.ts
|
|
90756
90790
|
function cleanJsonResponse(value) {
|
|
90757
90791
|
if (typeof value !== "string") return value;
|
|
90758
90792
|
const normalized = value.replace(/^for\s*\(;;\);\s*/i, "");
|
|
@@ -90845,18 +90879,76 @@ function buildUploadQuery(ctx) {
|
|
|
90845
90879
|
return qs2;
|
|
90846
90880
|
}
|
|
90847
90881
|
var EXTENSION_BY_MIME = {
|
|
90882
|
+
// video
|
|
90848
90883
|
"video/mp4": "mp4",
|
|
90884
|
+
"video/quicktime": "mov",
|
|
90885
|
+
"video/webm": "webm",
|
|
90886
|
+
"video/x-matroska": "mkv",
|
|
90887
|
+
"video/x-msvideo": "avi",
|
|
90888
|
+
"video/mpeg": "mpeg",
|
|
90889
|
+
"video/3gpp": "3gp",
|
|
90890
|
+
// audio
|
|
90849
90891
|
"audio/mp4": "m4a",
|
|
90892
|
+
"audio/x-m4a": "m4a",
|
|
90850
90893
|
"audio/mpeg": "mp3",
|
|
90851
90894
|
"audio/mp3": "mp3",
|
|
90852
90895
|
"audio/aac": "aac",
|
|
90853
90896
|
"audio/ogg": "ogg",
|
|
90897
|
+
"audio/opus": "opus",
|
|
90854
90898
|
"audio/wav": "wav",
|
|
90899
|
+
"audio/x-wav": "wav",
|
|
90900
|
+
"audio/webm": "weba",
|
|
90901
|
+
"audio/flac": "flac",
|
|
90902
|
+
"audio/x-flac": "flac",
|
|
90903
|
+
"audio/3gpp": "3gp",
|
|
90904
|
+
// image
|
|
90855
90905
|
"image/jpeg": "jpg",
|
|
90906
|
+
"image/jpg": "jpg",
|
|
90856
90907
|
"image/png": "png",
|
|
90857
90908
|
"image/gif": "gif",
|
|
90858
|
-
"image/webp": "webp"
|
|
90909
|
+
"image/webp": "webp",
|
|
90910
|
+
"image/bmp": "bmp",
|
|
90911
|
+
"image/tiff": "tiff",
|
|
90912
|
+
"image/svg+xml": "svg",
|
|
90913
|
+
"image/heic": "heic",
|
|
90914
|
+
"image/heif": "heif",
|
|
90915
|
+
"image/avif": "avif",
|
|
90916
|
+
// documents / archives
|
|
90917
|
+
"application/pdf": "pdf",
|
|
90918
|
+
"application/zip": "zip",
|
|
90919
|
+
"application/x-zip-compressed": "zip",
|
|
90920
|
+
"application/x-rar-compressed": "rar",
|
|
90921
|
+
"application/vnd.rar": "rar",
|
|
90922
|
+
"application/x-7z-compressed": "7z",
|
|
90923
|
+
"application/gzip": "gz",
|
|
90924
|
+
"application/x-tar": "tar",
|
|
90925
|
+
"text/plain": "txt",
|
|
90926
|
+
"text/csv": "csv",
|
|
90927
|
+
"text/html": "html",
|
|
90928
|
+
"text/calendar": "ics",
|
|
90929
|
+
"application/json": "json",
|
|
90930
|
+
"application/xml": "xml",
|
|
90931
|
+
"text/xml": "xml",
|
|
90932
|
+
"application/msword": "doc",
|
|
90933
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
90934
|
+
"application/vnd.ms-excel": "xls",
|
|
90935
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
90936
|
+
"application/vnd.ms-powerpoint": "ppt",
|
|
90937
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx",
|
|
90938
|
+
"application/vnd.android.package-archive": "apk",
|
|
90939
|
+
"application/x-msdownload": "exe",
|
|
90940
|
+
"application/octet-stream": "bin"
|
|
90859
90941
|
};
|
|
90942
|
+
function extensionForMime(mime) {
|
|
90943
|
+
if (!mime) return "";
|
|
90944
|
+
const normalized = String(mime).toLowerCase().split(";")[0].trim();
|
|
90945
|
+
if (EXTENSION_BY_MIME[normalized]) return EXTENSION_BY_MIME[normalized];
|
|
90946
|
+
const subtype = normalized.split("/")[1] || "";
|
|
90947
|
+
if (!subtype) return "";
|
|
90948
|
+
if (/\+([a-z0-9]+)$/.test(subtype)) return subtype.replace(/.*\+/, "");
|
|
90949
|
+
const cleaned = subtype.replace(/^vnd\./, "").replace(/^x-/, "").replace(/[-.]/g, "");
|
|
90950
|
+
return /^[a-z0-9]{1,10}$/.test(cleaned) ? cleaned : "";
|
|
90951
|
+
}
|
|
90860
90952
|
function sniffMime(buffer) {
|
|
90861
90953
|
if (buffer.length < 12) return "";
|
|
90862
90954
|
const b = buffer;
|
|
@@ -90881,11 +90973,11 @@ function sniffMime(buffer) {
|
|
|
90881
90973
|
}
|
|
90882
90974
|
function normalizeFilename(filename, mime) {
|
|
90883
90975
|
const base = filename && String(filename).trim() ? String(filename).trim() : `file-${Date.now()}`;
|
|
90884
|
-
const ext =
|
|
90885
|
-
const match = /\.[a-z0-9]{1,
|
|
90976
|
+
const ext = extensionForMime(mime);
|
|
90977
|
+
const match = /\.[a-z0-9]{1,6}$/i.exec(base);
|
|
90886
90978
|
const currentExt = match ? match[0].slice(1).toLowerCase() : "";
|
|
90887
90979
|
if (ext && currentExt !== ext) {
|
|
90888
|
-
const audioOverride = (ext === "m4a" || ext === "mp3" || ext === "aac" || ext === "ogg" || ext === "wav") && (currentExt === "mp4" || currentExt === "m4v" || currentExt === "");
|
|
90980
|
+
const audioOverride = (ext === "m4a" || ext === "mp3" || ext === "aac" || ext === "ogg" || ext === "wav" || ext === "opus" || ext === "flac") && (currentExt === "mp4" || currentExt === "m4v" || currentExt === "");
|
|
90889
90981
|
if (audioOverride || !currentExt) {
|
|
90890
90982
|
return currentExt ? `${base.slice(0, base.length - currentExt.length - 1)}.${ext}` : `${base}.${ext}`;
|
|
90891
90983
|
}
|
|
@@ -90895,16 +90987,45 @@ function normalizeFilename(filename, mime) {
|
|
|
90895
90987
|
}
|
|
90896
90988
|
async function uploadMercuryAttachment(ctx, defaultFuncs, attachment) {
|
|
90897
90989
|
const normalized = await normalizeAttachmentInput(attachment, ctx);
|
|
90990
|
+
const buffer = await readAll(normalized.stream);
|
|
90898
90991
|
const url2 = "https://www.facebook.com/ajax/mercury/upload.php";
|
|
90992
|
+
let lastError;
|
|
90993
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
90994
|
+
if (attempt > 0) await refreshUploadTokens(ctx, defaultFuncs);
|
|
90995
|
+
await ensureUploadTokens(ctx, defaultFuncs);
|
|
90996
|
+
const formData = new import_form_data3.default();
|
|
90997
|
+
formData.append("farr", stream3.Readable.from(buffer), {
|
|
90998
|
+
filename: normalized.filename,
|
|
90999
|
+
contentType: normalized.contentType || void 0
|
|
91000
|
+
});
|
|
91001
|
+
let data2;
|
|
91002
|
+
try {
|
|
91003
|
+
const res = await defaultFuncs.postMultipart(url2, ctx.jar, formData, buildUploadQuery(ctx));
|
|
91004
|
+
data2 = cleanJsonResponse(res && res.body !== void 0 ? res.body : res);
|
|
91005
|
+
} catch (error2) {
|
|
91006
|
+
lastError = error2;
|
|
91007
|
+
if (attempt === 0 && isNonCriticalError(error2)) continue;
|
|
91008
|
+
throw error2;
|
|
91009
|
+
}
|
|
91010
|
+
if (extractAttachmentIds(data2).length) return finalizeUpload(data2);
|
|
91011
|
+
lastError = buildNoMetadataError(data2);
|
|
91012
|
+
if (attempt === 0 && isNonCriticalError(lastError)) continue;
|
|
91013
|
+
throw lastError;
|
|
91014
|
+
}
|
|
91015
|
+
throw lastError || buildNoMetadataError(null);
|
|
91016
|
+
}
|
|
91017
|
+
function buildNoMetadataError(data2) {
|
|
91018
|
+
const err = new Error("UploadFb returned no metadata/ids");
|
|
91019
|
+
err.code = "NO_METADATA";
|
|
91020
|
+
err.body = data2;
|
|
91021
|
+
return err;
|
|
91022
|
+
}
|
|
91023
|
+
async function refreshUploadTokens(ctx, defaultFuncs) {
|
|
91024
|
+
ctx.lsd = void 0;
|
|
91025
|
+
ctx.master = ctx.master || {};
|
|
91026
|
+
ctx.master.__rev = void 0;
|
|
91027
|
+
if (typeof ctx.__cometTokens === "object") ctx.__cometTokens = void 0;
|
|
90899
91028
|
await ensureUploadTokens(ctx, defaultFuncs);
|
|
90900
|
-
const formData = new import_form_data3.default();
|
|
90901
|
-
formData.append("farr", normalized.stream, {
|
|
90902
|
-
filename: normalized.filename,
|
|
90903
|
-
contentType: normalized.contentType || void 0
|
|
90904
|
-
});
|
|
90905
|
-
const res = await defaultFuncs.postMultipart(url2, ctx.jar, formData, buildUploadQuery(ctx));
|
|
90906
|
-
const data2 = cleanJsonResponse(res && res.body !== void 0 ? res.body : res);
|
|
90907
|
-
return finalizeUpload(data2);
|
|
90908
91029
|
}
|
|
90909
91030
|
async function normalizeAttachmentInput(attachment, ctx) {
|
|
90910
91031
|
if (Buffer.isBuffer(attachment)) {
|
|
@@ -91011,6 +91132,68 @@ async function uploadGroupImage(ctx, defaultFuncs, image) {
|
|
|
91011
91132
|
return cleanJsonResponse(res && res.body !== void 0 ? res.body : res);
|
|
91012
91133
|
}
|
|
91013
91134
|
|
|
91135
|
+
// src/utils/reactions.ts
|
|
91136
|
+
var CORE_REACTIONS = [
|
|
91137
|
+
"\u{1F60D}",
|
|
91138
|
+
"\u{1F606}",
|
|
91139
|
+
"\u{1F62E}",
|
|
91140
|
+
"\u{1F622}",
|
|
91141
|
+
"\u{1F620}",
|
|
91142
|
+
"\u{1F44D}",
|
|
91143
|
+
"\u{1F44E}",
|
|
91144
|
+
"\u2764",
|
|
91145
|
+
"\u{1F497}",
|
|
91146
|
+
""
|
|
91147
|
+
];
|
|
91148
|
+
var REACTION_ALIASES = {
|
|
91149
|
+
":heart_eyes:": "\u{1F60D}",
|
|
91150
|
+
":love:": "\u{1F60D}",
|
|
91151
|
+
":laughing:": "\u{1F606}",
|
|
91152
|
+
":haha:": "\u{1F606}",
|
|
91153
|
+
":open_mouth:": "\u{1F62E}",
|
|
91154
|
+
":wow:": "\u{1F62E}",
|
|
91155
|
+
":cry:": "\u{1F622}",
|
|
91156
|
+
":sad:": "\u{1F622}",
|
|
91157
|
+
":angry:": "\u{1F620}",
|
|
91158
|
+
":thumbsup:": "\u{1F44D}",
|
|
91159
|
+
":like:": "\u{1F44D}",
|
|
91160
|
+
":thumbsdown:": "\u{1F44E}",
|
|
91161
|
+
":dislike:": "\u{1F44E}",
|
|
91162
|
+
":heart:": "\u2764",
|
|
91163
|
+
":glowingheart:": "\u{1F497}"
|
|
91164
|
+
};
|
|
91165
|
+
function isReactionEmoji(value) {
|
|
91166
|
+
if (value == null) return false;
|
|
91167
|
+
const text3 = String(value).trim();
|
|
91168
|
+
if (!text3) return false;
|
|
91169
|
+
if (CORE_REACTIONS.indexOf(text3) !== -1) return true;
|
|
91170
|
+
let clusters;
|
|
91171
|
+
try {
|
|
91172
|
+
const seg = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
91173
|
+
clusters = Array.from(seg.segment(text3), (s) => s.segment);
|
|
91174
|
+
} catch {
|
|
91175
|
+
clusters = Array.from(text3);
|
|
91176
|
+
}
|
|
91177
|
+
if (clusters.length !== 1) return false;
|
|
91178
|
+
const only = clusters[0];
|
|
91179
|
+
if (!new RegExp("\\p{Extended_Pictographic}", "u").test(only) && !/\uFE0F|\u20E3/u.test(only)) return false;
|
|
91180
|
+
if (!/[\p{Extended_Pictographic}\uFE0F\u20E3]/u.test(only)) return false;
|
|
91181
|
+
if (/[\u0000-\u001F\u007F]/.test(only)) return false;
|
|
91182
|
+
return true;
|
|
91183
|
+
}
|
|
91184
|
+
function normalizeReaction(value, options = {}) {
|
|
91185
|
+
const raw = value == null ? "" : String(value).trim();
|
|
91186
|
+
if (raw === "") {
|
|
91187
|
+
if (options.allowRemove) return "";
|
|
91188
|
+
throw new Error("Reaction is not a valid emoji.");
|
|
91189
|
+
}
|
|
91190
|
+
const resolved = REACTION_ALIASES[raw] !== void 0 ? REACTION_ALIASES[raw] : raw;
|
|
91191
|
+
if (!options.forceCustom && !isReactionEmoji(resolved)) {
|
|
91192
|
+
throw new Error(`Reaction is not a valid emoji: ${JSON.stringify(raw)}`);
|
|
91193
|
+
}
|
|
91194
|
+
return resolved;
|
|
91195
|
+
}
|
|
91196
|
+
|
|
91014
91197
|
// src/utils/lsd.ts
|
|
91015
91198
|
var TOKEN_TTL_MS = 10 * 60 * 1e3;
|
|
91016
91199
|
var STALE_TOKEN_ERRORS = /* @__PURE__ */ new Set([
|
|
@@ -91805,10 +91988,10 @@ function startRecovery(ctx, runtime, options = {}) {
|
|
|
91805
91988
|
|
|
91806
91989
|
// src/utils/realtime-health.ts
|
|
91807
91990
|
init_pacing();
|
|
91808
|
-
var SILENT_WINDOW_MS =
|
|
91809
|
-
var PING_GRACE_MS =
|
|
91991
|
+
var SILENT_WINDOW_MS = 30 * 60 * 1e3;
|
|
91992
|
+
var PING_GRACE_MS = 60 * 1e3;
|
|
91810
91993
|
var RealtimeHealth = class {
|
|
91811
|
-
constructor(now = () => Date.now()) {
|
|
91994
|
+
constructor(now = () => Date.now(), options = {}) {
|
|
91812
91995
|
this.now = now;
|
|
91813
91996
|
this.frames = 0;
|
|
91814
91997
|
this.lastFrameAt = 0;
|
|
@@ -91817,17 +92000,23 @@ var RealtimeHealth = class {
|
|
|
91817
92000
|
this.forcedReconnects = 0;
|
|
91818
92001
|
this.lastPingAt = 0;
|
|
91819
92002
|
this.startedAt = Date.now();
|
|
92003
|
+
/** Consecutive pings sent without any resulting frame. */
|
|
92004
|
+
this.silentPings = 0;
|
|
91820
92005
|
this.startedAt = this.now();
|
|
92006
|
+
this.silentWindowMs = options.silentWindowMs ?? SILENT_WINDOW_MS;
|
|
92007
|
+
this.pingGraceMs = options.pingGraceMs ?? PING_GRACE_MS;
|
|
91821
92008
|
}
|
|
91822
92009
|
/** Record any inbound frame (message, pong, anything from the broker). */
|
|
91823
92010
|
noteFrame() {
|
|
91824
92011
|
this.frames += 1;
|
|
91825
92012
|
this.lastFrameAt = this.now();
|
|
92013
|
+
this.silentPings = 0;
|
|
91826
92014
|
}
|
|
91827
92015
|
/** Record a successful connect. */
|
|
91828
92016
|
noteConnected() {
|
|
91829
92017
|
this.connectedAt = this.now();
|
|
91830
92018
|
this.lastFrameAt = this.now();
|
|
92019
|
+
this.silentPings = 0;
|
|
91831
92020
|
}
|
|
91832
92021
|
/** Record that the transport reports itself disconnected. */
|
|
91833
92022
|
noteDisconnected() {
|
|
@@ -91836,6 +92025,7 @@ var RealtimeHealth = class {
|
|
|
91836
92025
|
/** Record an active ping being sent. */
|
|
91837
92026
|
notePing() {
|
|
91838
92027
|
this.lastPingAt = this.now();
|
|
92028
|
+
this.silentPings += 1;
|
|
91839
92029
|
}
|
|
91840
92030
|
sinceLastFrame() {
|
|
91841
92031
|
const base = this.lastFrameAt || this.connectedAt || this.startedAt;
|
|
@@ -91845,8 +92035,8 @@ var RealtimeHealth = class {
|
|
|
91845
92035
|
* Decide what to do about the current socket.
|
|
91846
92036
|
*
|
|
91847
92037
|
* - `disconnected` — the transport already knows it is down; reconnect.
|
|
91848
|
-
* - `dead` — connected on paper, silent past the window, and
|
|
91849
|
-
*
|
|
92038
|
+
* - `dead` — connected on paper, silent well past the window, and repeated
|
|
92039
|
+
* pings raised no traffic at all; reconnect.
|
|
91850
92040
|
* - `suspect` — silent past the window but a ping was only just sent; wait.
|
|
91851
92041
|
* - `quiet` — silent but inside the window; normal.
|
|
91852
92042
|
* - `healthy` — recent traffic.
|
|
@@ -91854,9 +92044,10 @@ var RealtimeHealth = class {
|
|
|
91854
92044
|
verdict(connected) {
|
|
91855
92045
|
if (!connected) return "disconnected";
|
|
91856
92046
|
const silent = this.sinceLastFrame();
|
|
91857
|
-
if (silent <
|
|
91858
|
-
if (silent <
|
|
91859
|
-
if (this.lastPingAt && this.now() - this.lastPingAt <
|
|
92047
|
+
if (silent < this.silentWindowMs / 2) return "healthy";
|
|
92048
|
+
if (silent < this.silentWindowMs) return "quiet";
|
|
92049
|
+
if (this.lastPingAt && this.now() - this.lastPingAt < this.pingGraceMs) return "suspect";
|
|
92050
|
+
if (this.silentPings < 3) return "suspect";
|
|
91860
92051
|
return "dead";
|
|
91861
92052
|
}
|
|
91862
92053
|
/** A snapshot for diagnostics. */
|
|
@@ -91878,8 +92069,11 @@ var RealtimeHealth = class {
|
|
|
91878
92069
|
}
|
|
91879
92070
|
};
|
|
91880
92071
|
function startRealtimeSupervisor(options) {
|
|
91881
|
-
const health = new RealtimeHealth(
|
|
91882
|
-
|
|
92072
|
+
const health = options.health || new RealtimeHealth(void 0, {
|
|
92073
|
+
silentWindowMs: options.silentWindowMs,
|
|
92074
|
+
pingGraceMs: options.pingGraceMs
|
|
92075
|
+
});
|
|
92076
|
+
const interval = options.intervalMs ?? 10 * 60 * 1e3;
|
|
91883
92077
|
let stopped = false;
|
|
91884
92078
|
let timer = null;
|
|
91885
92079
|
const evaluate = () => {
|
|
@@ -93596,7 +93790,8 @@ var allowedProperties = {
|
|
|
93596
93790
|
emojiSize: true,
|
|
93597
93791
|
body: true,
|
|
93598
93792
|
mentions: true,
|
|
93599
|
-
location: true
|
|
93793
|
+
location: true,
|
|
93794
|
+
edit: true
|
|
93600
93795
|
};
|
|
93601
93796
|
var sendMessage_default = (defaultFuncs, api, ctx) => {
|
|
93602
93797
|
async function uploadAttachment(attachments) {
|
|
@@ -93718,6 +93913,18 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
|
|
|
93718
93913
|
if (msgType === "String") {
|
|
93719
93914
|
msg = { body: msg };
|
|
93720
93915
|
}
|
|
93916
|
+
if (Array.isArray(msg.edit) && msg.edit.length > 0) {
|
|
93917
|
+
let body = String(msg.body || "");
|
|
93918
|
+
const edits = [...msg.edit].sort((a, b) => Number(b?.[1] ?? 0) - Number(a?.[1] ?? 0));
|
|
93919
|
+
for (const entry of edits) {
|
|
93920
|
+
const text3 = Array.isArray(entry) ? String(entry[0] ?? "") : String(entry ?? "");
|
|
93921
|
+
const rawOffset = Array.isArray(entry) ? Number(entry[1]) : NaN;
|
|
93922
|
+
const offset = Number.isFinite(rawOffset) ? Math.max(0, Math.min(body.length, rawOffset)) : body.length;
|
|
93923
|
+
body = body.slice(0, offset) + text3 + body.slice(offset);
|
|
93924
|
+
}
|
|
93925
|
+
msg.body = body;
|
|
93926
|
+
delete msg.edit;
|
|
93927
|
+
}
|
|
93721
93928
|
const finish = (err, data2) => {
|
|
93722
93929
|
settle2(err, data2);
|
|
93723
93930
|
return data2;
|
|
@@ -93991,45 +94198,6 @@ function sendTypingIndicator_default(defaultFuncs, api, ctx) {
|
|
|
93991
94198
|
}
|
|
93992
94199
|
|
|
93993
94200
|
// src/deltas/apis/messaging/setMessageReaction.ts
|
|
93994
|
-
var VALID_REACTIONS = [
|
|
93995
|
-
"\u{1F60D}",
|
|
93996
|
-
// :heart_eyes:
|
|
93997
|
-
"\u{1F606}",
|
|
93998
|
-
// :laughing:
|
|
93999
|
-
"\u{1F62E}",
|
|
94000
|
-
// :open_mouth:
|
|
94001
|
-
"\u{1F622}",
|
|
94002
|
-
// :cry:
|
|
94003
|
-
"\u{1F620}",
|
|
94004
|
-
// :angry:
|
|
94005
|
-
"\u{1F44D}",
|
|
94006
|
-
// :thumbsup:
|
|
94007
|
-
"\u{1F44E}",
|
|
94008
|
-
// :thumbsdown:
|
|
94009
|
-
"\u2764",
|
|
94010
|
-
// :heart:
|
|
94011
|
-
"\u{1F497}",
|
|
94012
|
-
// :glowingheart:
|
|
94013
|
-
""
|
|
94014
|
-
// remove
|
|
94015
|
-
];
|
|
94016
|
-
var ALIASES = {
|
|
94017
|
-
":heart_eyes:": "\u{1F60D}",
|
|
94018
|
-
":love:": "\u{1F60D}",
|
|
94019
|
-
":laughing:": "\u{1F606}",
|
|
94020
|
-
":haha:": "\u{1F606}",
|
|
94021
|
-
":open_mouth:": "\u{1F62E}",
|
|
94022
|
-
":wow:": "\u{1F62E}",
|
|
94023
|
-
":cry:": "\u{1F622}",
|
|
94024
|
-
":sad:": "\u{1F622}",
|
|
94025
|
-
":angry:": "\u{1F620}",
|
|
94026
|
-
":thumbsup:": "\u{1F44D}",
|
|
94027
|
-
":like:": "\u{1F44D}",
|
|
94028
|
-
":thumbsdown:": "\u{1F44E}",
|
|
94029
|
-
":dislike:": "\u{1F44E}",
|
|
94030
|
-
":heart:": "\u2764",
|
|
94031
|
-
":glowingheart:": "\u{1F497}"
|
|
94032
|
-
};
|
|
94033
94201
|
function setMessageReaction_default(defaultFuncs, _api, ctx) {
|
|
94034
94202
|
return async function setMessageReaction(reaction, messageID, callback, forceCustomReaction) {
|
|
94035
94203
|
const cb = typeof callback === "function" ? callback : void 0;
|
|
@@ -94046,11 +94214,14 @@ function setMessageReaction_default(defaultFuncs, _api, ctx) {
|
|
|
94046
94214
|
if (!messageID) {
|
|
94047
94215
|
throw { error: "setMessageReaction: messageID is required." };
|
|
94048
94216
|
}
|
|
94049
|
-
let value
|
|
94050
|
-
|
|
94051
|
-
value =
|
|
94052
|
-
|
|
94053
|
-
|
|
94217
|
+
let value;
|
|
94218
|
+
try {
|
|
94219
|
+
value = normalizeReaction(reaction, {
|
|
94220
|
+
allowRemove: true,
|
|
94221
|
+
forceCustom: !!forceCustomReaction
|
|
94222
|
+
});
|
|
94223
|
+
} catch (validationError) {
|
|
94224
|
+
throw { error: validationError?.message || "Reaction is not a valid emoji." };
|
|
94054
94225
|
}
|
|
94055
94226
|
const variables = {
|
|
94056
94227
|
data: {
|
|
@@ -94842,33 +95013,35 @@ function searchMusic_default(defaultFuncs, _api, ctx) {
|
|
|
94842
95013
|
}
|
|
94843
95014
|
const page = collectTracks(parsed);
|
|
94844
95015
|
const tracks = page.tracks.slice(0, count);
|
|
94845
|
-
if (tracks.length
|
|
95016
|
+
if (tracks.length) {
|
|
95017
|
+
const result = tracks.slice();
|
|
95018
|
+
result.tracks = tracks;
|
|
95019
|
+
result.endCursor = page.endCursor;
|
|
95020
|
+
result.hasNextPage = page.hasNextPage;
|
|
95021
|
+
result.query = text3;
|
|
95022
|
+
return result;
|
|
95023
|
+
}
|
|
95024
|
+
for (let retry = 0; retry < 3; retry++) {
|
|
94846
95025
|
invalidateCometTokens(ctx);
|
|
95026
|
+
await sleep(600 + retry * 900);
|
|
94847
95027
|
const retried = await attempt(true);
|
|
94848
|
-
if (
|
|
94849
|
-
|
|
94850
|
-
|
|
94851
|
-
|
|
94852
|
-
|
|
94853
|
-
|
|
94854
|
-
|
|
94855
|
-
|
|
94856
|
-
|
|
94857
|
-
|
|
94858
|
-
}
|
|
95028
|
+
if (isStaleTokenError(retried) || retried?.error || (retried?.errors || []).length) continue;
|
|
95029
|
+
const retryPage = collectTracks(retried);
|
|
95030
|
+
const retryTracks = retryPage.tracks.slice(0, count);
|
|
95031
|
+
if (retryTracks.length) {
|
|
95032
|
+
const result = retryTracks.slice();
|
|
95033
|
+
result.tracks = retryTracks;
|
|
95034
|
+
result.endCursor = retryPage.endCursor;
|
|
95035
|
+
result.hasNextPage = retryPage.hasNextPage;
|
|
95036
|
+
result.query = text3;
|
|
95037
|
+
return result;
|
|
94859
95038
|
}
|
|
94860
|
-
throw {
|
|
94861
|
-
error: `No music results found for "${text3}". The Facebook music catalog may be unavailable for this account or region.`,
|
|
94862
|
-
code: "NO_RESULTS",
|
|
94863
|
-
query: text3
|
|
94864
|
-
};
|
|
94865
95039
|
}
|
|
94866
|
-
|
|
94867
|
-
|
|
94868
|
-
|
|
94869
|
-
|
|
94870
|
-
|
|
94871
|
-
return result;
|
|
95040
|
+
throw {
|
|
95041
|
+
error: `No music results found for "${text3}". The Facebook music catalog may be unavailable for this account or region.`,
|
|
95042
|
+
code: "NO_RESULTS",
|
|
95043
|
+
query: text3
|
|
95044
|
+
};
|
|
94872
95045
|
}
|
|
94873
95046
|
return function searchMusic(query = "", options = {}, callback) {
|
|
94874
95047
|
const selectedOptions = typeof options === "function" ? {} : options || {};
|
|
@@ -99025,15 +99198,22 @@ function story_default(defaultFuncs, api, ctx) {
|
|
|
99025
99198
|
}
|
|
99026
99199
|
async function sendStoryReply(storyIdOrUrl, message, isReaction) {
|
|
99027
99200
|
try {
|
|
99028
|
-
const allowedReactions = ["\u2764\uFE0F", "\u{1F44D}", "\u{1F917}", "\u{1F606}", "\u{1F621}", "\u{1F622}", "\u{1F62E}"];
|
|
99029
99201
|
if (!storyIdOrUrl) throw new Error("Story ID or URL is required.");
|
|
99030
99202
|
if (!message) throw new Error("A message or reaction is required.");
|
|
99203
|
+
let reactionValue = message;
|
|
99204
|
+
if (isReaction) {
|
|
99205
|
+
try {
|
|
99206
|
+
reactionValue = normalizeReaction(message);
|
|
99207
|
+
} catch (validationError) {
|
|
99208
|
+
throw new Error(validationError?.message || "Reaction is not a valid emoji.");
|
|
99209
|
+
}
|
|
99210
|
+
}
|
|
99031
99211
|
let storyID = getStoryIDFromURL(storyIdOrUrl);
|
|
99032
99212
|
if (!storyID) storyID = storyIdOrUrl;
|
|
99033
99213
|
const variables = {
|
|
99034
99214
|
input: {
|
|
99035
99215
|
attribution_id_v2: "StoriesCometSuspenseRoot.react,comet.stories.viewer,via_cold_start",
|
|
99036
|
-
message,
|
|
99216
|
+
message: reactionValue,
|
|
99037
99217
|
story_id: storyID,
|
|
99038
99218
|
story_reply_type: isReaction ? "LIGHT_WEIGHT" : "TEXT",
|
|
99039
99219
|
actor_id: ctx.userID,
|
|
@@ -99041,12 +99221,9 @@ function story_default(defaultFuncs, api, ctx) {
|
|
|
99041
99221
|
}
|
|
99042
99222
|
};
|
|
99043
99223
|
if (isReaction) {
|
|
99044
|
-
if (!allowedReactions.includes(message)) {
|
|
99045
|
-
throw new Error(`Invalid reaction. Please use one of: ${allowedReactions.join(" ")}`);
|
|
99046
|
-
}
|
|
99047
99224
|
variables.input.lightweight_reaction_actions = {
|
|
99048
99225
|
offsets: [0],
|
|
99049
|
-
reaction:
|
|
99226
|
+
reaction: reactionValue
|
|
99050
99227
|
};
|
|
99051
99228
|
}
|
|
99052
99229
|
const form = {
|
|
@@ -99455,14 +99632,32 @@ function getThreadInfo_default(defaultFuncs, api, ctx) {
|
|
|
99455
99632
|
throw new Error("getThreadInfo: malformed response from GraphQL.");
|
|
99456
99633
|
}
|
|
99457
99634
|
const threadInfos = {};
|
|
99458
|
-
|
|
99635
|
+
let matched = 0;
|
|
99636
|
+
for (let i2 = 0; i2 < resData.length; i2++) {
|
|
99459
99637
|
const res = resData[i2];
|
|
99460
|
-
if (!res || res
|
|
99461
|
-
const
|
|
99638
|
+
if (!res || typeof res !== "object" || res.error_results) continue;
|
|
99639
|
+
const keys = Object.keys(res);
|
|
99640
|
+
const queryKey = keys.find((k) => /^o\d+$/.test(k));
|
|
99641
|
+
let index3;
|
|
99642
|
+
if (queryKey) {
|
|
99643
|
+
index3 = Number(queryKey.slice(1));
|
|
99644
|
+
} else if (typeof res.__ar === "number" || res.error !== void 0) {
|
|
99645
|
+
continue;
|
|
99646
|
+
} else {
|
|
99647
|
+
index3 = i2;
|
|
99648
|
+
}
|
|
99649
|
+
if (index3 < 0 || index3 >= threadIDs.length) continue;
|
|
99650
|
+
const data2 = res[queryKey || keys[0]];
|
|
99651
|
+
if (!data2 || !data2.data) continue;
|
|
99652
|
+
const threadInfo = formatThreadGraphQLResponse(data2.data);
|
|
99462
99653
|
if (threadInfo) {
|
|
99463
|
-
threadInfos[threadInfo.threadID || threadIDs[
|
|
99654
|
+
threadInfos[threadInfo.threadID || threadIDs[index3]] = threadInfo;
|
|
99655
|
+
matched++;
|
|
99464
99656
|
}
|
|
99465
99657
|
}
|
|
99658
|
+
if (matched === 0) {
|
|
99659
|
+
throw new Error("getThreadInfo: malformed response from GraphQL.");
|
|
99660
|
+
}
|
|
99466
99661
|
return Array.isArray(threadID) ? threadInfos : Object.values(threadInfos)[0] || null;
|
|
99467
99662
|
} catch (err) {
|
|
99468
99663
|
error("getThreadInfo", err);
|
|
@@ -100001,7 +100196,10 @@ var getUserInfo_default = (defaultFuncs, api, ctx) => {
|
|
|
100001
100196
|
form[`ids[${i2}]`] = v;
|
|
100002
100197
|
});
|
|
100003
100198
|
const getGenderString = (code) => code === 1 ? "male" : code === 2 ? "female" : "no specific gender";
|
|
100004
|
-
defaultFuncs.post("https://www.facebook.com/chat/user_info/", ctx.jar, form).then((resData) => parseAndCheckLogin(ctx, defaultFuncs)(resData))
|
|
100199
|
+
const performFetch = () => defaultFuncs.post("https://www.facebook.com/chat/user_info/", ctx.jar, form).then((resData) => parseAndCheckLogin(ctx, defaultFuncs)(resData));
|
|
100200
|
+
retryOnNonCritical(performFetch, () => {
|
|
100201
|
+
invalidateCometTokens?.(ctx);
|
|
100202
|
+
}).then((resData) => {
|
|
100005
100203
|
if (resData?.error && resData?.error !== 3252001) throw resData;
|
|
100006
100204
|
const retObj = {};
|
|
100007
100205
|
const profiles = resData?.payload?.profiles;
|
|
@@ -101127,6 +101325,9 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
|
|
|
101127
101325
|
}
|
|
101128
101326
|
lifecycle.healthSupervisor = startRealtimeSupervisor({
|
|
101129
101327
|
isConnected: () => generation === lifecycle.generation && client2.connected,
|
|
101328
|
+
// Share the per-connection tracker so this supervisor sees
|
|
101329
|
+
// every inbound frame the listener records.
|
|
101330
|
+
health,
|
|
101130
101331
|
reconnect: (reason) => {
|
|
101131
101332
|
if (generation !== lifecycle.generation) return;
|
|
101132
101333
|
if (lifecycle.stopped || ctx.loggedIn === false) return;
|
|
@@ -101509,6 +101710,7 @@ async function loginHelper(credentials, globalOptions, callback, setOptionsFunc,
|
|
|
101509
101710
|
}
|
|
101510
101711
|
if (listenMqtt_default) {
|
|
101511
101712
|
api["listenMqtt"] = listenMqtt_default(defaultFuncs, api, ctx);
|
|
101713
|
+
api["listen"] = api["listenMqtt"];
|
|
101512
101714
|
}
|
|
101513
101715
|
};
|
|
101514
101716
|
api.getCurrentUserID = () => ctx.userID;
|
|
@@ -101833,7 +102035,9 @@ lodash/lodash.js:
|
|
|
101833
102035
|
*)
|
|
101834
102036
|
*/
|
|
101835
102037
|
|
|
102038
|
+
exports.CORE_REACTIONS = CORE_REACTIONS;
|
|
101836
102039
|
exports.PING_GRACE_MS = PING_GRACE_MS;
|
|
102040
|
+
exports.REACTION_ALIASES = REACTION_ALIASES;
|
|
101837
102041
|
exports.RealtimeHealth = RealtimeHealth;
|
|
101838
102042
|
exports.RecoverySupervisor = RecoverySupervisor;
|
|
101839
102043
|
exports.SILENT_WINDOW_MS = SILENT_WINDOW_MS;
|
|
@@ -101841,6 +102045,7 @@ exports.acquireCookies = acquireCookies;
|
|
|
101841
102045
|
exports.applySetCookie = applySetCookie;
|
|
101842
102046
|
exports.awaitProactiveSlot = awaitProactiveSlot;
|
|
101843
102047
|
exports.canActProactively = canActProactively;
|
|
102048
|
+
exports.cleanJsonResponse = cleanJsonResponse;
|
|
101844
102049
|
exports.collectSessionCookies = collectSessionCookies;
|
|
101845
102050
|
exports.default = index_default;
|
|
101846
102051
|
exports.ensureCometTokens = ensureCometTokens;
|
|
@@ -101858,10 +102063,13 @@ exports.invalidateCometTokens = invalidateCometTokens;
|
|
|
101858
102063
|
exports.isAuthFailure = isAuthFailure;
|
|
101859
102064
|
exports.isBreakerOpen = isBreakerOpen;
|
|
101860
102065
|
exports.isLoggedOutDocument = isLoggedOutDocument;
|
|
102066
|
+
exports.isNonCriticalError = isNonCriticalError;
|
|
102067
|
+
exports.isReactionEmoji = isReactionEmoji;
|
|
101861
102068
|
exports.isStaleTokenError = isStaleTokenError;
|
|
101862
102069
|
exports.login = login;
|
|
101863
102070
|
exports.missingSessionCookies = missingSessionCookies;
|
|
101864
102071
|
exports.normalizeBrowserProfile = normalizeBrowserProfile;
|
|
102072
|
+
exports.normalizeReaction = normalizeReaction;
|
|
101865
102073
|
exports.noteAction = noteAction;
|
|
101866
102074
|
exports.noteAuthFailure = noteAuthFailure;
|
|
101867
102075
|
exports.noteCheckpoint = noteCheckpoint;
|
|
@@ -101875,12 +102083,15 @@ exports.reserveRequest = reserveRequest;
|
|
|
101875
102083
|
exports.resetBreaker = resetBreaker;
|
|
101876
102084
|
exports.resolveProfile = resolveProfile;
|
|
101877
102085
|
exports.retryDelay = retryDelay;
|
|
102086
|
+
exports.retryOnNonCritical = retryOnNonCritical;
|
|
101878
102087
|
exports.safetySnapshot = safetySnapshot;
|
|
101879
102088
|
exports.sleep = sleep;
|
|
101880
102089
|
exports.startLiveness = startLiveness;
|
|
101881
102090
|
exports.startRealtimeSupervisor = startRealtimeSupervisor;
|
|
101882
102091
|
exports.startRecovery = startRecovery;
|
|
101883
102092
|
exports.tripBreaker = tripBreaker;
|
|
102093
|
+
exports.uploadGroupImage = uploadGroupImage;
|
|
102094
|
+
exports.uploadMercuryAttachment = uploadMercuryAttachment;
|
|
101884
102095
|
exports.warmUpSession = warmUpSession;
|
|
101885
102096
|
exports.withCometTokens = withCometTokens;
|
|
101886
102097
|
exports.withSessionRetry = withSessionRetry;
|