Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/Haystack/API/HisItem.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// A timestamp/value pair.
public struct HisItem {
public struct HisItem: Sendable {
public let ts: DateTime
public let val: any Val

Expand Down
2 changes: 1 addition & 1 deletion Sources/Haystack/API/HisReadRange.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Query-able DateTime ranges, which support relative and absolute values.
public enum HisReadRange {
public enum HisReadRange: Sendable {
case today
case yesterday
case date(Haystack.Date)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Haystack/DateTime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public struct DateTime: Val {
}
}

var calendar = Calendar(identifier: .gregorian)
let calendar = Calendar(identifier: .gregorian)

// DateTime + Codable
extension DateTime {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Haystack/IO/ZincTokenizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ZincTokenizer {
try consume()
}

public convenience init(_ string: String) throws {
convenience init(_ string: String) throws {
guard let data = string.data(using: .utf8) else {
throw ZincTokenizerError.inputIsNotUtf8
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Haystack/Val.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extension Val {
}
}

public enum ValType: String, CaseIterable {
public enum ValType: String, CaseIterable, Sendable {
case Bool
case Coord
case Date
Expand Down
2 changes: 1 addition & 1 deletion Sources/HaystackClient/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class Client: API {
let fetcher: Fetcher

/// Set when `open` is called.
private var authToken: String? = nil
private var authToken: String?

private let jsonEncoder = JSONEncoder()
private let jsonDecoder = JSONDecoder()
Expand Down
10 changes: 5 additions & 5 deletions Sources/HaystackServer/HaystackServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ import Haystack

/// A HaystackServer is a server that implements the Haystack API.
/// It translates API calls into operations on the underlying data stores.
public class HaystackServer: API {
public final class HaystackServer: API, Sendable {
let recordStore: RecordStore
let historyStore: HistoryStore
let watchStore: WatchStore

let onInvokeAction: (Haystack.Ref, String, [String: any Haystack.Val]) async throws -> Haystack.Grid
let onEval: (String) async throws -> Haystack.Grid
let onInvokeAction: @Sendable (Haystack.Ref, String, [String: any Haystack.Val]) async throws -> Haystack.Grid
let onEval: @Sendable (String) async throws -> Haystack.Grid

public init(
recordStore: RecordStore,
historyStore: HistoryStore,
watchStore: WatchStore,
onInvokeAction: @escaping (Haystack.Ref, String, [String: any Haystack.Val]) async throws -> Haystack.Grid = { _, _, _ in
onInvokeAction: @escaping @Sendable (Haystack.Ref, String, [String: any Haystack.Val]) async throws -> Haystack.Grid = { _, _, _ in
GridBuilder().toGrid()
},
onEval: @escaping (String) async throws -> Haystack.Grid = { _ in
onEval: @escaping @Sendable (String) async throws -> Haystack.Grid = { _ in
GridBuilder().toGrid()
}
) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/HaystackServer/Stores/HistoryStore.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Haystack

/// Defines a storage system that allows reading and writing of Haystack history data.
public protocol HistoryStore {
public protocol HistoryStore: Sendable {
/// Reads history data for a given ID and time range.
func hisRead(id: Haystack.Ref, range: Haystack.HisReadRange) async throws -> [Haystack.Dict]

Expand Down
4 changes: 2 additions & 2 deletions Sources/HaystackServer/Stores/RecordStore.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Haystack

/// Defines a storage system that allows reading and writing of Haystack records.
public protocol RecordStore {
public protocol RecordStore: Sendable {
/// Reads records from the store based on a list of IDs.
func read(ids: [Haystack.Ref]) async throws -> [Haystack.Dict]

Expand All @@ -12,7 +12,7 @@ public protocol RecordStore {
func commitAll(diffs: [RecordDiff]) async throws -> [RecordDiff]
}

public struct RecordDiff {
public struct RecordDiff: Sendable {
public init(
id: Haystack.Ref,
old: Haystack.Dict?,
Expand Down
4 changes: 2 additions & 2 deletions Sources/HaystackServer/Stores/WatchStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
import Haystack

/// Defines a storage system that allows stateful storage of system watches.
public protocol WatchStore {
public protocol WatchStore: Sendable {
func read(watchId: String) async throws -> WatchResponse
func create(ids: [Haystack.Ref], lease: Haystack.Number?) async throws -> String
func addIds(watchId: String, ids: [Haystack.Ref]) async throws
Expand All @@ -11,7 +11,7 @@ public protocol WatchStore {
func delete(watchId: String) async throws
}

public struct WatchResponse {
public struct WatchResponse: Sendable {
public let ids: [Haystack.Ref]
public let lease: Haystack.Number
public let lastReported: Foundation.Date?
Expand Down
26 changes: 26 additions & 0 deletions Sources/HaystackServerVapor/Application+Haystack.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Haystack
import Vapor

extension Application {
struct HaystackServerKey: StorageKey {
typealias Value = API & Sendable
}

public var haystack: (API & Sendable)? {
get {
storage[HaystackServerKey.self]
}
set {
storage[HaystackServerKey.self] = newValue
}
}
}

extension Request {
func haystack() throws -> any API {
guard let haystack = application.haystack else {
fatalError("HaystackServer is not configured in the Vapor application.")
}
return haystack
}
}
Loading
Loading