| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | import * as tfrpc from '/tfrpc.js'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let g_hash; | 
					
						
							|  |  |  | let g_collection_notifies = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function getOwnerIdentities() { | 
					
						
							|  |  |  | 	return ssb.getOwnerIdentities(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function getIdentities() { | 
					
						
							|  |  |  | 	return ssb.getIdentities(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function query(sql, args) { | 
					
						
							|  |  |  | 	let result = []; | 
					
						
							|  |  |  | 	await ssb.sqlAsync(sql, args, function callback(row) { | 
					
						
							|  |  |  | 		result.push(row); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function localStorageGet(key) { | 
					
						
							|  |  |  | 	return app.localStorageGet(key); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function localStorageSet(key, value) { | 
					
						
							|  |  |  | 	return app.localStorageSet(key, value); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function following(ids, depth) { | 
					
						
							|  |  |  | 	return ssb.following(ids, depth); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function appendMessage(id, message) { | 
					
						
							|  |  |  | 	return ssb.appendMessageWithIdentity(id, message); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function store_blob(blob) { | 
					
						
							|  |  |  | 	if (Array.isArray(blob)) { | 
					
						
							|  |  |  | 		blob = Uint8Array.from(blob); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return await ssb.blobStore(blob); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function get_blob(id) { | 
					
						
							|  |  |  | 	return utf8Decode(await ssb.blobGet(id)); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let g_new_message_resolve; | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | let g_new_message_promise = new Promise(function (resolve, reject) { | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 	g_new_message_resolve = resolve; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function new_message() { | 
					
						
							|  |  |  | 	return g_new_message_promise; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-22 18:51:21 -04:00
										 |  |  | core.register('onMessage', function (id) { | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 	let resolve = g_new_message_resolve; | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | 	g_new_message_promise = new Promise(function (resolve, reject) { | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 		g_new_message_resolve = resolve; | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	if (resolve) { | 
					
						
							|  |  |  | 		resolve(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | core.register('message', async function message_handler(message) { | 
					
						
							|  |  |  | 	if (message.event == 'hashChange') { | 
					
						
							|  |  |  | 		print('hash change', message.hash); | 
					
						
							|  |  |  | 		g_hash = message.hash; | 
					
						
							|  |  |  | 		await tfrpc.rpc.hash_changed(message.hash); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(function set_hash(hash) { | 
					
						
							|  |  |  | 	if (g_hash != hash) { | 
					
						
							|  |  |  | 		return app.setHash(hash); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(function get_hash(id, message) { | 
					
						
							|  |  |  | 	return g_hash; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function try_decrypt(id, content) { | 
					
						
							|  |  |  | 	return await ssb.privateMessageDecrypt(id, content); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | tfrpc.register(async function encrypt(id, recipients, content) { | 
					
						
							|  |  |  | 	return await ssb.privateMessageEncrypt(id, recipients, content); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function process_message(whoami, collection, message, kind, parent) { | 
					
						
							|  |  |  | 	let content = JSON.parse(message.content); | 
					
						
							|  |  |  | 	if (typeof content == 'string') { | 
					
						
							|  |  |  | 		let x; | 
					
						
							|  |  |  | 		for (let id of whoami) { | 
					
						
							|  |  |  | 			x = await ssb.privateMessageDecrypt(id, content); | 
					
						
							|  |  |  | 			if (x) { | 
					
						
							|  |  |  | 				content = JSON.parse(x); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!x) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | 		if (content.type !== kind || (parent && content.parent !== parent)) { | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (content?.key) { | 
					
						
							|  |  |  | 		if (content?.tombstone) { | 
					
						
							|  |  |  | 			delete collection[content.key]; | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | 			collection[content.key] = Object.assign( | 
					
						
							|  |  |  | 				collection[content.key] || {}, | 
					
						
							|  |  |  | 				content | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		collection[message.id] = Object.assign(content, {id: message.id}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tfrpc.register(async function collection(ids, kind, parent, max_rowid, data) { | 
					
						
							|  |  |  | 	let whoami = await ssb.getIdentities(); | 
					
						
							|  |  |  | 	data = data ?? {}; | 
					
						
							|  |  |  | 	let rowid = 0; | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | 	await ssb.sqlAsync( | 
					
						
							|  |  |  | 		'SELECT MAX(rowid) AS rowid FROM messages', | 
					
						
							|  |  |  | 		[], | 
					
						
							|  |  |  | 		function (row) { | 
					
						
							|  |  |  | 			rowid = row.rowid; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 	while (true) { | 
					
						
							|  |  |  | 		if (rowid == max_rowid) { | 
					
						
							|  |  |  | 			await new_message(); | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | 			await ssb.sqlAsync( | 
					
						
							|  |  |  | 				'SELECT MAX(rowid) AS rowid FROM messages', | 
					
						
							|  |  |  | 				[], | 
					
						
							|  |  |  | 				function (row) { | 
					
						
							|  |  |  | 					rowid = row.rowid; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		let modified = false; | 
					
						
							|  |  |  | 		let rows = []; | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | 		await ssb.sqlAsync( | 
					
						
							|  |  |  | 			`
 | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 			SELECT messages.id, author, content, timestamp | 
					
						
							|  |  |  | 			FROM messages | 
					
						
							|  |  |  | 			JOIN json_each(?1) AS id ON messages.author = id.value | 
					
						
							|  |  |  | 			WHERE | 
					
						
							|  |  |  | 				messages.rowid > ?2 AND | 
					
						
							|  |  |  | 				messages.rowid <= ?3 AND | 
					
						
							|  |  |  | 				((json_extract(messages.content, '$.type') = ?4 AND | 
					
						
							|  |  |  | 				(?5 IS NULL OR json_extract(messages.content, '$.parent') = ?5)) OR | 
					
						
							|  |  |  | 				content LIKE '"%') | 
					
						
							|  |  |  | 			`,
 | 
					
						
							|  |  |  | 			[JSON.stringify(ids), max_rowid ?? -1, rowid, kind, parent], | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | 			function (row) { | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 				rows.push(row); | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2023-11-05 23:26:54 +00:00
										 |  |  | 		max_rowid = rowid; | 
					
						
							| 
									
										
										
										
											2023-11-04 18:15:58 +00:00
										 |  |  | 		for (let row of rows) { | 
					
						
							|  |  |  | 			if (await process_message(whoami, data, row, kind, parent)) { | 
					
						
							|  |  |  | 				modified = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (modified) { | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return [rowid, data]; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function main() { | 
					
						
							|  |  |  | 	await app.setDocument(utf8Decode(await getFile('index.html'))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-24 11:09:34 -05:00
										 |  |  | main(); |