Something went wrong. Try again.
Two-way sync Firefox bookmarks with an AT Protocol PDS using network.cosmik.* lexicons.
Something went wrong. Try again.
2.1 kB · 69 lines
JavaScript
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970const BASE32 = "234567abcdefghijklmnopqrstuvwxyz";
/** * Generates a TID (timestamp-based identifier) matching AT Protocol format. * 13 chars timestamp base32-encoded + 4 random chars. * @returns {string} A 17-character TID string */function generateTid() { const now = Date.now(); let tid = ""; let t = now; for (let i = 0; i < 13; i++) { tid = BASE32[t % 32] + tid; t = Math.floor(t / 32); } for (let i = 0; i < 4; i++) { tid += BASE32[Math.floor(Math.random() * 32)]; } return tid;}
/** * Returns a promise that resolves after the given delay. * @param {number} ms - Delay in milliseconds * @returns {Promise<void>} */function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms));}
/** * Creates a debounced version of the provided function. * The debounced function has a `.cancel()` method to clear pending invocations. * @param {Function} fn - The function to debounce * @param {number} delay - Debounce delay in milliseconds * @returns {Function & { cancel: () => void }} Debounced function with cancel */function debounce(fn, delay) { let timer = null; function debounced(...args) { if (timer) clearTimeout(timer); timer = setTimeout(() => { timer = null; fn(...args); }, delay); } debounced.cancel = () => { if (timer) clearTimeout(timer); timer = null; }; return debounced;}
/** * Checks whether a bookmark node is (or is inside) a folder with the given parent ID. * Walks up the parent chain of the bookmark node using parentId fields. * @param {bookmarks.BookmarkTreeNode} bookmarkNode - The bookmark node to check * @param {string} targetParentId - The folder ID to test against * @returns {boolean} True if the node is inside the target folder */function isBookmarkInsideFolder(bookmarkNode, targetParentId) { let node = bookmarkNode; while (node) { if (node.parentId === targetParentId) return true; if (node.parentId === undefined || node.parentId === null) return false; node = { parentId: node.parentId }; } return false;}