Add HTMLMetadataCache to RSWeb.

This commit is contained in:
Brent Simmons
2024-12-13 08:57:31 -08:00
parent 25c54a4c1d
commit c38e5d6abe
2 changed files with 72 additions and 15 deletions

View File

@@ -3,23 +3,33 @@
import PackageDescription
let package = Package(
name: "RSWeb",
name: "RSWeb",
platforms: [.macOS(.v13), .iOS(.v16)],
products: [
.library(
name: "RSWeb",
type: .dynamic,
targets: ["RSWeb"]),
],
dependencies: [
],
targets: [
.target(
name: "RSWeb",
.library(
name: "RSWeb",
type: .dynamic,
targets: ["RSWeb"]),
],
dependencies: [
.package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMinor(from: "2.0.2")),
.package(path: "../Core")
],
targets: [
.target(
name: "RSWeb",
dependencies: [
"RSParser",
"Core"
],
resources: [.copy("UTS46/uts46")],
swiftSettings: [.define("SWIFT_PACKAGE")]),
.testTarget(
name: "RSWebTests",
dependencies: ["RSWeb"]),
]
.testTarget(
name: "RSWebTests",
dependencies: [
"RSWeb",
"RSParser",
"Core"
]),
]
)

View File

@@ -0,0 +1,47 @@
//
// HTMLMetadataCache.swift
//
//
// Created by Brent Simmons on 10/13/24.
//
import Foundation
import Core
@preconcurrency import RSParser
extension Notification.Name {
// Sent when HTMLMetadata is cached. Posted on any thread.
static let htmlMetadataAvailable = Notification.Name("htmlMetadataAvailable")
}
final class HTMLMetadataCache: Sendable {
static let shared = HTMLMetadataCache()
// Sent along with .htmlMetadataAvailable notification
struct UserInfoKey {
static let htmlMetadata = "htmlMetadata"
static let url = "url" // String value
}
private struct HTMLMetadataCacheRecord: CacheRecord {
let metadata: RSHTMLMetadata
let dateCreated = Date()
}
private let cache = Cache<HTMLMetadataCacheRecord>(timeToLive: TimeInterval(21 * 60 * 60), timeBetweenCleanups: TimeInterval(10 * 60 * 60))
subscript(_ url: String) -> RSHTMLMetadata? {
get {
return cache[url]?.metadata
}
set {
guard let htmlMetadata = newValue else {
return
}
let cacheRecord = HTMLMetadataCacheRecord(metadata: htmlMetadata)
cache[url] = cacheRecord
NotificationCenter.default.post(name: .htmlMetadataAvailable, object: self, userInfo: [UserInfoKey.htmlMetadata: htmlMetadata, UserInfoKey.url: url])
}
}
}